1 /* 2 * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>. 3 * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar> 4 * 5 * See file `LICENSE` for full details 6 */ 7 8 #include "main.h" 9 10 #include "logger.h" 11 #include "dwt.h" 12 13 #include "board.h" 14 #include "app.h" 15 #include "task_sensor_attribute.h" 16 #include "task_system_attribute.h" 17 #include "task_system_interface.h" 18 #include "ds18b20.h" 19 20 #define G_TASK_SEN_TICK_CNT_INI 0ul 21 #define G_TASK_SEN_TEMP_PERIOD_MS 1000ul 22 #define G_DS18B20_CONV_TIME_MS 200ul // ~188ms for 10 bit resolution 23 #define G_DS18B20_DMA_TIMEOUT_MS 5000ul 24 25 const task_sensor_cfg_t task_sensor_cfg_list[] = { 26 {ID_DS18B20} 27 }; 28 29 #define SENSOR_CFG_QTY (sizeof(task_sensor_cfg_list)/sizeof(task_sensor_cfg_t)) 30 31 task_sensor_dta_t task_sensor_dta_list[] = { 32 {G_TASK_SEN_TEMP_PERIOD_MS, ST_SEN_READY, EV_DS18B20_CONV_DONE} 33 }; 34 35 #define SENSOR_DTA_QTY (sizeof(task_sensor_dta_list)/sizeof(task_sensor_dta_t)) 36 37 void task_sensor_statechart(void); 38 39 // external variables 40 volatile extern bool b_DS18B20_Received_data; 41 extern uint8_t g_DS18B20_Received_data_buffer[8]; 42 43 // local global variables 44 volatile float g_DS18B20_temp; 45 uint32_t g_task_sensor_tick; 46 uint8_t Temp_LSB, Temp_MSB; 47 static bool b_DS18B20_Received_data_LSB; 48 static const uint8_t buffer[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 49 50 void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) 51 { 52 b_DS18B20_Received_data = true; 53 } 54 55 // this variable is incremented by 1 on every ms by HAL_SysTick 56 volatile uint32_t g_task_sensor_tick_cnt; 57 58 void task_sensor_init(void *parameters) 59 { 60 const task_sensor_cfg_t *p_task_sensor_cfg; 61 // task_sensor_dta_t *p_task_sensor_dta; 62 63 LOGGER_INFO("Initializing `task_sensor`..."); 64 65 g_task_sensor_tick = G_TASK_SEN_TEMP_PERIOD_MS; 66 67 for (uint32_t index = 0; SENSOR_DTA_QTY > index; index++) 68 { 69 p_task_sensor_cfg = &task_sensor_cfg_list[index]; 70 // p_task_sensor_dta = &task_sensor_dta_list[index]; 71 72 switch (p_task_sensor_cfg->identifier) { 73 case ID_DS18B20: 74 DS18B20_Init(); 75 break; 76 77 default: break; 78 } 79 80 } 81 82 LOGGER_INFO("Done initializing `task_sensor`"); 83 } 84 85 void task_sensor_update(void *parameters) 86 { 87 bool b_time_update_required = false; 88 89 __asm("CPSID i"); 90 if (G_TASK_SEN_TICK_CNT_INI < g_task_sensor_tick_cnt) 91 { 92 g_task_sensor_tick_cnt--; 93 b_time_update_required = true; 94 } 95 __asm("CPSIE i"); 96 97 while (b_time_update_required) 98 { 99 task_sensor_statechart(); 100 101 __asm("CPSID i"); 102 if (G_TASK_SEN_TICK_CNT_INI < g_task_sensor_tick_cnt) 103 { 104 g_task_sensor_tick_cnt--; 105 b_time_update_required = true; 106 } 107 else 108 { 109 b_time_update_required = false; 110 } 111 __asm("CPSIE i"); 112 } 113 } 114 115 void task_sensor_statechart(void) 116 { 117 uint32_t index; 118 const task_sensor_cfg_t *p_task_sensor_cfg; 119 task_sensor_dta_t *p_task_sensor_dta; 120 121 for (index = 0; SENSOR_DTA_QTY > index; index++) 122 { 123 p_task_sensor_cfg = &task_sensor_cfg_list[index]; 124 p_task_sensor_dta = &task_sensor_dta_list[index]; 125 126 switch (p_task_sensor_cfg->identifier) 127 { 128 case ID_DS18B20: 129 switch (p_task_sensor_dta->state) 130 { 131 case ST_SEN_READY: 132 if (0 == g_task_sensor_tick) 133 { 134 // Send start temp conversion command 135 // this needs 96ms to 750ms depending on resolution 136 DS18B20_Reset(); 137 DS18B20_Write(0xCC); // send 'Skip ROM' command 138 DS18B20_Write(0x44); // send 'Convert T' command 139 140 p_task_sensor_dta->state = ST_SEN_BUSY_WAITING_CONV; 141 g_task_sensor_tick = G_DS18B20_CONV_TIME_MS; 142 } 143 else 144 { 145 g_task_sensor_tick--; 146 } 147 break; 148 149 case ST_SEN_BUSY_WAITING_CONV: 150 if (0 == g_task_sensor_tick) 151 { 152 DS18B20_Reset(); 153 DS18B20_Write(0xCC); // send 'Skip ROM' command 154 DS18B20_Write(0xBE); // send 'read scratchpad' command 155 156 if (HAL_OK == HAL_UART_Transmit_DMA(&huart1, buffer, 8)) 157 { 158 if (HAL_OK == HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8)) 159 { 160 b_DS18B20_Received_data_LSB = true; 161 p_task_sensor_dta->state = ST_SEN_BUSY_WAITING_DMA; 162 g_task_sensor_tick = G_DS18B20_DMA_TIMEOUT_MS; 163 } 164 } 165 } 166 else 167 { 168 g_task_sensor_tick--; 169 } 170 171 break; 172 173 case ST_SEN_BUSY_WAITING_DMA: 174 175 if (0 == g_task_sensor_tick) 176 { 177 // DMA Timeout, reset conversion 178 p_task_sensor_dta->state = ST_SEN_READY; 179 g_task_sensor_tick = G_TASK_SEN_TEMP_PERIOD_MS; 180 break; 181 } 182 else 183 { 184 g_task_sensor_tick--; 185 } 186 187 if (true == b_DS18B20_Received_data) 188 { 189 b_DS18B20_Received_data = false; 190 191 uint8_t received_value = 0; 192 for (uint8_t i = 0; i < 8; ++i) 193 { 194 if (g_DS18B20_Received_data_buffer[i] == 0xFF) 195 { 196 received_value |= (1 << i); 197 } 198 } 199 200 if (true == b_DS18B20_Received_data_LSB) 201 { 202 if (HAL_OK == HAL_UART_Transmit_DMA(&huart1, buffer, 8)) 203 { 204 if (HAL_OK == HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8)) 205 { 206 b_DS18B20_Received_data_LSB = false; 207 Temp_LSB = received_value; 208 g_task_sensor_tick = G_DS18B20_DMA_TIMEOUT_MS; 209 } 210 } 211 } 212 else 213 { 214 Temp_MSB = received_value; 215 uint16_t temp = ((Temp_MSB << 8) | Temp_LSB); 216 g_DS18B20_temp = (float) temp / 16.0; 217 p_task_sensor_dta->state = ST_SEN_READY; 218 g_task_sensor_tick = G_TASK_SEN_TEMP_PERIOD_MS; 219 } 220 } 221 222 break; 223 224 default: break; 225 } 226 break; 227 228 default: break; 229 } 230 } 231 }
