Microprocessor and peripheral 2 assignments for AUTH
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

222 lines
4.7 KiB

  1. /*!
  2. * \file hal.c
  3. *
  4. * Author: Christos Choutouridis AEM: 8997
  5. * email : <cchoutou@ece.auth.gr>
  6. *
  7. */
  8. #include "hal.h"
  9. /*
  10. * Public data types / classes
  11. */
  12. alcd_t alcd;
  13. ow_uart_t ow;
  14. proximity_t prox;
  15. /*!
  16. * Initialize all hardware
  17. */
  18. int hal_hw_init (void) {
  19. // Init base board
  20. NUCLEO_Init(1000);
  21. SHIELD_Init ();
  22. // Start Jiffy functionality
  23. jf_link_setfreq (JF_setfreq);
  24. jf_link_value ((jiffy_t*)&JF_TIM_VALUE);
  25. jf_init (JF_TIM_CLOCK_FREQ, 1000);
  26. return 0;
  27. }
  28. /*
  29. * ========== LCD ===========
  30. */
  31. /*!
  32. * \brief
  33. * Initialize the lcd data. Not the LCD module
  34. */
  35. void lcd_init (void) {
  36. alcd_link_db4 (&alcd, SHIELD_LCD_DB4);
  37. alcd_link_db5 (&alcd, SHIELD_LCD_DB5);
  38. alcd_link_db6 (&alcd, SHIELD_LCD_DB6);
  39. alcd_link_db7 (&alcd, SHIELD_LCD_DB7);
  40. alcd_link_rs (&alcd, SHIELD_LCD_RS);
  41. alcd_link_en (&alcd, SHIELD_LCD_EN);
  42. alcd_link_bl (&alcd, SHIELD_LCD_BL);
  43. alcd_set_lines (&alcd, 2);
  44. alcd_set_columns (&alcd, 16);
  45. alcd_init (&alcd, (alcd_funset_en)LCD_FUNSET_2L8);
  46. }
  47. //! lcd enable wrapper
  48. __INLINE void lcd_enable (uint8_t en) {
  49. alcd_enable(&alcd, en);
  50. }
  51. //!< lcd putchar wrapper
  52. __INLINE int lcd_putchar (char c) {
  53. return alcd_putchar(&alcd, c);
  54. }
  55. //! lcd puts wrapper
  56. int lcd_puts (const char *s) {
  57. int i =0;
  58. while (alcd_putchar(&alcd, *s++))
  59. ++i;
  60. return i;
  61. }
  62. /*
  63. * ========== Led interface ==========
  64. */
  65. __INLINE void led_red (uint8_t en) { LED_RED (en); }
  66. __INLINE void led_green (uint8_t en) { LED_GREEN (en); }
  67. /*
  68. * ========= Relay ===========
  69. */
  70. /*!
  71. * Create pulses to re-state reay coil
  72. */
  73. void relay (uint8_t on) {
  74. switch (on) {
  75. case 0:
  76. SHIELD_BR1(1);
  77. HAL_Delay(100);
  78. SHIELD_BR1(0);
  79. break;
  80. default:
  81. SHIELD_BR2(1);
  82. HAL_Delay(100);
  83. SHIELD_BR2(0);
  84. break;
  85. }
  86. }
  87. /*
  88. * ========= Temperature ===========
  89. */
  90. uint8_t ds18b20_rom[8];
  91. uint8_t zero_rom[8] = {0};
  92. /*!
  93. * Initialize temperature measurement system
  94. */
  95. int temp_init (uint8_t resolution) {
  96. if (!IS_TEMP_RESOLUTION(resolution))
  97. return 1;
  98. // link with hardware
  99. ow_uart_link_rw (&ow, (ow_uart_rw_ft)SHIELD_1W_RW);
  100. ow_uart_link_br (&ow, (ow_uart_br_ft)SHIELD_1W_UART_BR);
  101. ow_uart_set_timing (&ow, OW_UART_T_STANDARD);
  102. ow_uart_init (&ow); // init
  103. ow_uart_search(&ow, ds18b20_rom);// do a search
  104. if (!memcmp ((const void*)ds18b20_rom, (const void*)zero_rom, 8))
  105. return 1; // if there is no DS18b20 error
  106. // set resolution to 9-bit
  107. ow_uart_reset(&ow);
  108. ow_uart_tx (&ow, SKIPROM); // Skip rom
  109. ow_uart_tx (&ow, WRITESCRATCH); // write scratchpad
  110. ow_uart_tx (&ow, (byte_t)127); // Th
  111. ow_uart_tx (&ow, (byte_t)-128); // Tl
  112. ow_uart_tx (&ow, resolution); // Configuration 9 bit
  113. HAL_Delay(100);
  114. return 0;
  115. }
  116. /*!
  117. * Temperature read functionality
  118. */
  119. float temp_read (void) {
  120. uint8_t t[2];
  121. ow_uart_reset(&ow);
  122. ow_uart_tx (&ow, SKIPROM); // Skip rom
  123. ow_uart_tx (&ow, STARTCONV); // convert temperature
  124. while (ow_uart_rx(&ow) == 0) // Wait for slave to free the bus
  125. ;
  126. //HAL_Delay (100);
  127. ow_uart_reset(&ow);
  128. ow_uart_tx (&ow, SKIPROM); // Skip rom
  129. ow_uart_tx (&ow, READSCRATCH); // read scratchpad
  130. t[0] = ow_uart_rx(&ow); // LSB
  131. t[1] = ow_uart_rx(&ow); // MSB
  132. ow_uart_reset(&ow);
  133. t[1] <<= 4;
  134. t[1] |= (t[0] >> 4);
  135. t[0] &= 0x0F;
  136. return t[1] + t[0]/16.0;
  137. }
  138. /*
  139. * ========= Proximity ===========
  140. */
  141. /*!
  142. * Initialize proximity system
  143. * \param p Which proximity object to initialize
  144. */
  145. void proximity_init (proximity_t* p){
  146. for (int i =0 ; i<PROX_READINGS ; ++i)
  147. proximity(p);
  148. }
  149. /*!
  150. * Read proximity value in [cm]
  151. * \note
  152. * This function also implements an embedded averaging filter
  153. * @param p Which proximity object to use
  154. * @return The measured distance
  155. */
  156. float_t proximity (proximity_t* p){
  157. float_t ret;
  158. clock_t t1, t2, mark;
  159. SHIELD_TRIG(1); // send pulse and mark cycles
  160. jf_delay_us(10);
  161. SHIELD_TRIG(0);
  162. // wait for response with timeout
  163. mark = clock();
  164. do {
  165. t1 = CYCLE_Get();
  166. if (clock() - mark >= PROX_TIME_MAX)
  167. return -1;
  168. } while (!SHIELD_ECHO());
  169. mark = clock();
  170. do {
  171. t2 = CYCLE_Get();
  172. if (clock() - mark >= PROX_TIME_MAX)
  173. return -1;
  174. } while (SHIELD_ECHO());
  175. // Calculate distance
  176. SystemCoreClockUpdate();
  177. uint32_t c_usec = SystemCoreClock / 1000000;
  178. // Load value
  179. p->readings[p->iter++] = (c_usec) ? ((t2 - t1)/c_usec) / 58.2 : PROX_MAX_DISTANSE;
  180. p->iter %= PROX_READINGS;
  181. // Return filtered distance (moving average filter FIR)
  182. ret =0;
  183. for (int i=0 ; i<PROX_READINGS ; ++i)
  184. ret += p->readings[i];
  185. return ret/PROX_READINGS;
  186. }