/*!
* \file hal.c
*
* Copyright (C) 2020 Choutouridis Christos (http://www.houtouridis.net)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
*/
#include "hal.h"
/*
* Public data types / classes
*/
alcd_t alcd;
ow_uart_t ow;
proximity_t prox;
/*!
* Initialize all hardware
* @return
*/
int hal_hw_init (void) {
// Init base board
NUCLEO_Init(1000);
SHIELD_Init ();
// Start Jiffy functionality
jf_link_setfreq (JF_setfreq);
jf_link_value ((jiffy_t*)&JF_TIM_VALUE);
jf_init (JF_TIM_CLOCK_FREQ, 1000);
return 0;
}
/*
* ========== LCD ===========
*/
/*!
* \brief
* Initialize the lcd data. Not the LCD module
*/
void lcd_init (void) {
alcd_link_db4 (&alcd, SHIELD_LCD_DB4);
alcd_link_db5 (&alcd, SHIELD_LCD_DB5);
alcd_link_db6 (&alcd, SHIELD_LCD_DB6);
alcd_link_db7 (&alcd, SHIELD_LCD_DB7);
alcd_link_rs (&alcd, SHIELD_LCD_RS);
alcd_link_en (&alcd, SHIELD_LCD_EN);
alcd_link_bl (&alcd, SHIELD_LCD_BL);
alcd_set_lines (&alcd, 2);
alcd_set_columns (&alcd, 16);
alcd_init (&alcd, (alcd_funset_en)LCD_FUNSET_2L8);
}
__INLINE void lcd_enable (uint8_t en) {
alcd_enable(&alcd, en);
}
__INLINE int lcd_putchar (char c) {
return alcd_putchar(&alcd, c);
}
int lcd_puts (const char *s) {
int i =0;
while (alcd_putchar(&alcd, *s++))
++i;
return i;
}
/*
* ========== Led interface ==========
*/
__INLINE void led_red (uint8_t en) { LED_RED (en); }
__INLINE void led_green (uint8_t en) { LED_GREEN (en); }
/*
* ========= Relay ===========
*/
void relay (uint8_t on) {
switch (on) {
case 0:
SHIELD_BR1(1);
HAL_Delay(100);
SHIELD_BR1(0);
break;
default:
SHIELD_BR2(1);
HAL_Delay(100);
SHIELD_BR2(0);
break;
}
}
/*
* ========= Temperature ===========
*/
uint8_t ds18b20_rom[8];
uint8_t zero_rom[8] = {0};
int temp_init (uint8_t resolution) {
if (!IS_TEMP_RESOLUTION(resolution))
return 1;
ow_uart_link_rw (&ow, (ow_uart_rw_ft)SHIELD_1W_RW);
ow_uart_link_br (&ow, (ow_uart_br_ft)SHIELD_1W_UART_BR);
ow_uart_set_timing (&ow, OW_UART_T_STANDARD);
ow_uart_init (&ow);
ow_uart_search(&ow, ds18b20_rom);
if (!memcmp ((const void*)ds18b20_rom, (const void*)zero_rom, 8))
return 1;
// set resolution to 9-bit
ow_uart_reset(&ow);
ow_uart_tx (&ow, SKIPROM); // Skip rom
ow_uart_tx (&ow, WRITESCRATCH); // write scratchpad
ow_uart_tx (&ow, (byte_t)127); // Th
ow_uart_tx (&ow, (byte_t)-128); // Tl
ow_uart_tx (&ow, resolution); // Configuration 9 bit
HAL_Delay(100);
return 0;
}
float temp_read (void) {
uint8_t t[2];
ow_uart_reset(&ow);
ow_uart_tx (&ow, SKIPROM); // Skip rom
ow_uart_tx (&ow, STARTCONV); // convert temperature
while (ow_uart_rx(&ow) == 0) // Wait for slave to free the bus
;
//HAL_Delay (100);
ow_uart_reset(&ow);
ow_uart_tx (&ow, SKIPROM); // Skip rom
ow_uart_tx (&ow, READSCRATCH); // read scratchpad
t[0] = ow_uart_rx(&ow); // LSB
t[1] = ow_uart_rx(&ow); // MSB
ow_uart_reset(&ow);
t[1] <<= 4;
t[1] |= (t[0] >> 4);
t[0] &= 0x0F;
return t[1] + t[0]/16.0;
}
/*
* ========= Proximity ===========
*/
void proximity_init (proximity_t* p){
for (int i =0 ; i= PROX_TIME_MAX)
return -1;
} while (!SHIELD_ECHO());
mark = clock();
do {
t2 = CYCLE_Get();
if (clock() - mark >= PROX_TIME_MAX)
return -1;
} while (SHIELD_ECHO());
SystemCoreClockUpdate();
uint32_t c_usec = SystemCoreClock / 1000000;
// Load value
p->readings[p->iter++] = (c_usec) ? ((t2 - t1)/c_usec) / 58.2 : PROX_MAX_DISTANSE;
p->iter %= PROX_READINGS;
// Return filtered distance
ret =0;
for (int i=0 ; ireadings[i];
return ret/PROX_READINGS;
}