222 lines
4.7 KiB
C

/*!
* \file hal.c
*
* Author: Christos Choutouridis AEM: 8997
* email : <cchoutou@ece.auth.gr>
*
*/
#include "hal.h"
/*
* Public data types / classes
*/
alcd_t alcd;
ow_uart_t ow;
proximity_t prox;
/*!
* Initialize all hardware
*/
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);
}
//! lcd enable wrapper
__INLINE void lcd_enable (uint8_t en) {
alcd_enable(&alcd, en);
}
//!< lcd putchar wrapper
__INLINE int lcd_putchar (char c) {
return alcd_putchar(&alcd, c);
}
//! lcd puts wrapper
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 ===========
*/
/*!
* Create pulses to re-state reay coil
*/
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};
/*!
* Initialize temperature measurement system
*/
int temp_init (uint8_t resolution) {
if (!IS_TEMP_RESOLUTION(resolution))
return 1;
// link with hardware
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); // init
ow_uart_search(&ow, ds18b20_rom);// do a search
if (!memcmp ((const void*)ds18b20_rom, (const void*)zero_rom, 8))
return 1; // if there is no DS18b20 error
// 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;
}
/*!
* Temperature read functionality
*/
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 ===========
*/
/*!
* Initialize proximity system
* \param p Which proximity object to initialize
*/
void proximity_init (proximity_t* p){
for (int i =0 ; i<PROX_READINGS ; ++i)
proximity(p);
}
/*!
* Read proximity value in [cm]
* \note
* This function also implements an embedded averaging filter
* @param p Which proximity object to use
* @return The measured distance
*/
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());
// Calculate distance
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 (moving average filter FIR)
ret =0;
for (int i=0 ; i<PROX_READINGS ; ++i)
ret += p->readings[i];
return ret/PROX_READINGS;
}