/*! * \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; }