210 lines
4.7 KiB
C
210 lines
4.7 KiB
C
/*!
|
|
* \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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
#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_READINGS ; ++i)
|
|
proximity(p);
|
|
}
|
|
|
|
float_t proximity (proximity_t* p){
|
|
float_t ret;
|
|
clock_t t1, t2, mark;
|
|
|
|
SHIELD_TRIG(1); // send pulse and mark cycles
|
|
jf_delay_us(10);
|
|
SHIELD_TRIG(0);
|
|
// wait for response with timeout
|
|
mark = clock();
|
|
do {
|
|
t1 = CYCLE_Get();
|
|
if (clock() - mark >= 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 ; i<PROX_READINGS ; ++i)
|
|
ret += p->readings[i];
|
|
return ret/PROX_READINGS;
|
|
}
|
|
|
|
|
|
|
|
|