commit 42285ecbb1797194e5151185da17a976f9eef4f9
parent 9cd78f02e661327460626f0c0e74c44fc97ff1ea
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Wed, 18 Mar 2026 14:42:21 -0300
Separar `task_sensor` en tareas para cada conjunto de sensores
Antes `task_sensor` incluia los cuatro botones y el sensor de
temperatura, con este commit se separa esta tarea "grande" en dos tareas
mas "pequeñas": `task_temp_sensor` y `task_buttons`. La primera se encarga
de leer periodicamente la temperatura del sensor, mientras que la
segunda se encarga de leer y acuatlizar el estado de los cuatro botones.
Diffstat:
12 files changed, 761 insertions(+), 729 deletions(-)
diff --git a/firmware/app/inc/ds18b20.h b/firmware/app/inc/ds18b20.h
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
- *
- * See file `LICENSE` for full details
- */
-
-#ifndef DS18B20_H_
-#define DS18B20_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void UART1_SetBaud(uint32_t baud);
-void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
-
-void DS18B20_Init(void);
-void DS18B20_Write(uint8_t data);
-void DS18B20_Read_temp(void);
-uint8_t DS18B20_Read(void);
-uint8_t DS18B20_Reset(void);
-
-void DS18B20_Update(void);
-void DS18B20_Read_temp_non_blocking(void);
-
-/* DS18B20 Non Blocking State Machine - Transition Table
- *
- * +------------------------------+-------+------------------------+------------------------------+---------------------------+
- * | Current state | Event | [Guard] | Next state | Actions |
- * +==============================+=======+========================+==============================+===========================+
- * | | | [tick == 0] | ST_DS18B20_BUSY_WAITING_CONV | Send start conversion cmd |
- * + ST_DS18B20_READY +-------+------------------------+------------------------------+---------------------------+
- * | | | | ST_DS18B20_READY | tick-- |
- * +------------------------------+-------+------------------------+------------------------------+---------------------------+
- * | | | [tick == 0] | ST_DS18B20_BUSY_WAITING_DMA | Transmit/Receive DMA |
- * | | | | | tick = DMA_TIMEOUT_MAX |
- * | | | | | Data_LSB = 1 |
- * | ST_DS18B20_BUSY_WAITING_CONV +-------+------------------------+------------------------------+---------------------------+
- * | | | | ST_DS18B20_BUSY_WAITING_CONV | tick-- |
- * | | | | | |
- * +------------------------------+-------+------------------------+------------------------------+---------------------------+
- * | | | [tick == 0] | ST_DS18B20_READY | tick = TEMP_PERIOD |
- * | | | | | |
- * | ST_DS18B20_BUSY_WAITING_DMA +-------+------------------------+------------------------------+---------------------------+
- * | | | [tick != 0 && | ST_DS18B20_BUSY_WAITING_DMA | tick-- |
- * | | | Received_data == 0] | | |
- * + +-------+------------------------+------------------------------+---------------------------+
- * | | | [tick != 0 && | ST_DS18B20_BUSY_WAITING_DMA | tick = DMA_TIMEOUT_MAX |
- * | | | Received_data == 1 && | | Data_LSB = 0 |
- * | | | Data_LSB == 1] | | Save received LSB data |
- * | +-------+------------------------+------------------------------+---------------------------+
- * | | | [tick != 0 && | ST_DS18B20_READY | tick = TEMP_PERIOD |
- * | | | Received_data == 0 && | | Save received MSB data |
- * | | | Data_LSB == 0] | | |
- * +------------------------------+-------+------------------------+------------------------------+---------------------------+
- *
- *
- */
-
-typedef enum {
- ST_DS18B20_READY,
- ST_DS18B20_BUSY_WAITING_CONV,
- ST_DS18B20_BUSY_WAITING_DMA
-} DS18B20_st_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* DS18B20_H_ */
diff --git a/firmware/app/inc/task_buttons.h b/firmware/app/inc/task_buttons.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef TASK_INC_TASK_BUTTONS_H_
+#define TASK_INC_TASK_BUTTONS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint32_t g_task_buttons_cnt;
+extern volatile uint32_t g_task_buttons_tick_cnt;
+
+extern void task_buttons_init(void *parameters);
+extern void task_buttons_update(void *parameters);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TASK_INC_TASK_SENSOR_H_ */
diff --git a/firmware/app/inc/task_buttons_attribute.h b/firmware/app/inc/task_buttons_attribute.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef TASK_INC_TASK_BUTTONS_ATTRIBUTE_H_
+#define TASK_INC_TASK_BUTTONS_ATTRIBUTE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// TODO: Move every button related code to a separate generic button module
+
+/*
+ * Sensor Statechart - State Transition Table
+ *
+ * +-------------------+----------------+-------------+-------------------+-----------------------+
+ * | Current | Event | | Next | |
+ * | State | (Parameters) | [Guard] | State | Actions |
+ * |===================+================+=============+===================+=======================|
+ * | INICIAL | | | ST_BTN_XX_UP | |
+ * |-------------------+----------------+-------------+-------------------+-----------------------|
+ * | ST_BTN_XX_UP | EV_BTN_XX_UP | | ST_BTN_XX_UP | |
+ * | +----------------+-------------+-------------------+-----------------------|
+ * | | EV_BTN_XX_DOWN | | ST_BTN_XX_FALLING | tick = TICK_MAX |
+ * |-------------------+----------------+-------------+-------------------+-----------------------|
+ * | ST_BTN_XX_FALLING | EV_BTN_XX_UP | [tick == 0] | ST_BTN_XX_UP | |
+ * | | +-------------+-------------------+-----------------------|
+ * | | | [tick > 0] | ST_BTN_XX_FALLING | tick-- |
+ * | +----------------+-------------+-------------------+-----------------------|
+ * | | EV_BTN_XX_DOWN | [tick == 0] | ST_BTN_XX_DOWN | put_event_task_system |
+ * | | | | | (event) |
+ * | | +-------------+-------------------+-----------------------|
+ * | | | [tick > 0] | ST_BTN_XX_FALLING | tick-- |
+ * |-------------------+----------------+-------------+-------------------+-----------------------|
+ * | ST_BTN_XX_DOWN | EV_BTN_XX_UP | | ST_BTN_XX_RISING | tick = TICK_MAX |
+ * | +----------------+-------------+-------------------+-----------------------|
+ * | | EV_BTN_XX_DOWN | | ST_BTN_XX_DOWN | |
+ * |-------------------+----------------+-------------+-------------------+-----------------------|
+ * | ST_BTN_XX_RISING | EV_BTN_XX_UP | [tick == 0] | ST_BTN_XX_UP | put_event_task_system |
+ * | | | | | (event) |
+ * | | +-------------+-------------------+-----------------------|
+ * | | | [tick > 0] | ST_BTN_XX_RISING | tick-- |
+ * | +----------------+-------------+-------------------+-----------------------|
+ * | | EV_BTN_XX_DOWN | [tick == 0] | ST_BTN_XX_DOWN | |
+ * | | +-------------+-------------------+-----------------------|
+ * | | | [tick > 0] | ST_BTN_XX_RISING | tick-- |
+ * +-------------------+----------------+-------------+-------------------+-----------------------+
+ *
+ */
+
+/* Events to excite Task Sensor */
+typedef enum {
+ EV_BTN_XX_UP,
+ EV_BTN_XX_DOWN
+} task_buttons_ev_t;
+
+/* States of Task Sensor */
+typedef enum {
+ ST_BTN_XX_UP,
+ ST_BTN_XX_FALLING,
+ ST_BTN_XX_DOWN,
+ ST_BTN_XX_RISING,
+ ST_SEN_READY
+} task_buttons_st_t;
+
+/* Identifier of Task Sensor */
+typedef enum {
+ ID_BTN_A,
+ ID_BTN_B,
+ ID_BTN_C,
+ ID_BTN_D,
+} task_buttons_id_t;
+
+typedef struct {
+ task_buttons_id_t identifier;
+ GPIO_TypeDef *gpio_port;
+ uint16_t pin;
+ GPIO_PinState pressed;
+ uint32_t tick_max;
+ task_buttons_ev_t signal_up;
+ task_buttons_ev_t signal_down;
+} task_buttons_cfg_t;
+
+typedef struct {
+ uint32_t tick;
+ task_buttons_st_t state;
+ task_buttons_ev_t event;
+} task_buttons_dta_t;
+
+extern task_buttons_dta_t task_buttons_dta_list[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TASK_INC_TASK_SENSOR_ATTRIBUTE_H_ */
diff --git a/firmware/app/inc/task_sensor.h b/firmware/app/inc/task_sensor.h
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
- * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
- *
- * See file `LICENSE` for full details
- */
-
-#ifndef TASK_INC_TASK_SENSOR_H_
-#define TASK_INC_TASK_SENSOR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern uint32_t g_task_sensor_cnt;
-extern volatile uint32_t g_task_sensor_tick_cnt;
-
-extern void task_sensor_init(void *parameters);
-extern void task_sensor_update(void *parameters);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TASK_INC_TASK_SENSOR_H_ */
diff --git a/firmware/app/inc/task_sensor_attribute.h b/firmware/app/inc/task_sensor_attribute.h
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
- * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
- *
- * See file `LICENSE` for full details
- */
-
-#ifndef TASK_INC_TASK_SENSOR_ATTRIBUTE_H_
-#define TASK_INC_TASK_SENSOR_ATTRIBUTE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// TODO: Move every button related code to a separate generic button module
-
-/*
- * Sensor Statechart - State Transition Table
- *
- * +-------------------+----------------+-------------+-------------------+-----------------------+
- * | Current | Event | | Next | |
- * | State | (Parameters) | [Guard] | State | Actions |
- * |===================+================+=============+===================+=======================|
- * | INICIAL | | | ST_BTN_XX_UP | |
- * |-------------------+----------------+-------------+-------------------+-----------------------|
- * | ST_BTN_XX_UP | EV_BTN_XX_UP | | ST_BTN_XX_UP | |
- * | +----------------+-------------+-------------------+-----------------------|
- * | | EV_BTN_XX_DOWN | | ST_BTN_XX_FALLING | tick = TICK_MAX |
- * |-------------------+----------------+-------------+-------------------+-----------------------|
- * | ST_BTN_XX_FALLING | EV_BTN_XX_UP | [tick == 0] | ST_BTN_XX_UP | |
- * | | +-------------+-------------------+-----------------------|
- * | | | [tick > 0] | ST_BTN_XX_FALLING | tick-- |
- * | +----------------+-------------+-------------------+-----------------------|
- * | | EV_BTN_XX_DOWN | [tick == 0] | ST_BTN_XX_DOWN | put_event_task_system |
- * | | | | | (event) |
- * | | +-------------+-------------------+-----------------------|
- * | | | [tick > 0] | ST_BTN_XX_FALLING | tick-- |
- * |-------------------+----------------+-------------+-------------------+-----------------------|
- * | ST_BTN_XX_DOWN | EV_BTN_XX_UP | | ST_BTN_XX_RISING | tick = TICK_MAX |
- * | +----------------+-------------+-------------------+-----------------------|
- * | | EV_BTN_XX_DOWN | | ST_BTN_XX_DOWN | |
- * |-------------------+----------------+-------------+-------------------+-----------------------|
- * | ST_BTN_XX_RISING | EV_BTN_XX_UP | [tick == 0] | ST_BTN_XX_UP | put_event_task_system |
- * | | | | | (event) |
- * | | +-------------+-------------------+-----------------------|
- * | | | [tick > 0] | ST_BTN_XX_RISING | tick-- |
- * | +----------------+-------------+-------------------+-----------------------|
- * | | EV_BTN_XX_DOWN | [tick == 0] | ST_BTN_XX_DOWN | |
- * | | +-------------+-------------------+-----------------------|
- * | | | [tick > 0] | ST_BTN_XX_RISING | tick-- |
- * +-------------------+----------------+-------------+-------------------+-----------------------+
- *
- */
-
-/* Events to excite Task Sensor */
-typedef enum {
- EV_BTN_XX_UP,
- EV_BTN_XX_DOWN
-} task_sensor_ev_t;
-
-/* States of Task Sensor */
-typedef enum {
- ST_BTN_XX_UP,
- ST_BTN_XX_FALLING,
- ST_BTN_XX_DOWN,
- ST_BTN_XX_RISING,
- ST_SEN_READY
-} task_sensor_st_t;
-
-/* Identifier of Task Sensor */
-typedef enum {
- ID_BTN_A,
- ID_BTN_B,
- ID_BTN_C,
- ID_BTN_D,
- ID_DS18B20
-} task_sensor_id_t;
-
-typedef struct {
- task_sensor_id_t identifier;
- GPIO_TypeDef *gpio_port;
- uint16_t pin;
- GPIO_PinState pressed;
- uint32_t tick_max;
- task_sensor_ev_t signal_up;
- task_sensor_ev_t signal_down;
-} task_sensor_cfg_t;
-
-typedef struct {
- uint32_t tick;
- task_sensor_st_t state;
- task_sensor_ev_t event;
-} task_sensor_dta_t;
-
-extern task_sensor_dta_t task_sensor_dta_list[];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TASK_INC_TASK_SENSOR_ATTRIBUTE_H_ */
diff --git a/firmware/app/inc/task_temp_sensor.h b/firmware/app/inc/task_temp_sensor.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef DS18B20_H_
+#define DS18B20_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint32_t g_task_temp_sensor_cnt;
+extern volatile uint32_t g_task_temp_sensor_tick_cnt;
+
+void task_temp_sensor_init(void *parameters);
+void task_temp_sensor_update(void *parameters);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DS18B20_H_ */
diff --git a/firmware/app/inc/task_temp_sensor_attribute.h b/firmware/app/inc/task_temp_sensor_attribute.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef TASK_INC_TASK_TEMP_SENSOR_ATTRIBUTE_H_
+#define TASK_INC_TASK_TEMP_SENSOR_ATTRIBUTE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* DS18B20 Non Blocking State Machine - Transition Table
+ *
+ * +------------------------------+-------+------------------------+------------------------------+---------------------------+
+ * | Current state | Event | [Guard] | Next state | Actions |
+ * +==============================+=======+========================+==============================+===========================+
+ * | | | [tick == 0] | ST_DS18B20_BUSY_WAITING_CONV | Send start conversion cmd |
+ * + ST_DS18B20_READY +-------+------------------------+------------------------------+---------------------------+
+ * | | | | ST_DS18B20_READY | tick-- |
+ * +------------------------------+-------+------------------------+------------------------------+---------------------------+
+ * | | | [tick == 0] | ST_DS18B20_BUSY_WAITING_DMA | Transmit/Receive DMA |
+ * | | | | | tick = DMA_TIMEOUT_MAX |
+ * | | | | | Data_LSB = 1 |
+ * | ST_DS18B20_BUSY_WAITING_CONV +-------+------------------------+------------------------------+---------------------------+
+ * | | | | ST_DS18B20_BUSY_WAITING_CONV | tick-- |
+ * | | | | | |
+ * +------------------------------+-------+------------------------+------------------------------+---------------------------+
+ * | | | [tick == 0] | ST_DS18B20_READY | tick = TEMP_PERIOD |
+ * | | | | | |
+ * | ST_DS18B20_BUSY_WAITING_DMA +-------+------------------------+------------------------------+---------------------------+
+ * | | | [tick != 0 && | ST_DS18B20_BUSY_WAITING_DMA | tick-- |
+ * | | | Received_data == 0] | | |
+ * + +-------+------------------------+------------------------------+---------------------------+
+ * | | | [tick != 0 && | ST_DS18B20_BUSY_WAITING_DMA | tick = DMA_TIMEOUT_MAX |
+ * | | | Received_data == 1 && | | Data_LSB = 0 |
+ * | | | Data_LSB == 1] | | Save received LSB data |
+ * | +-------+------------------------+------------------------------+---------------------------+
+ * | | | [tick != 0 && | ST_DS18B20_READY | tick = TEMP_PERIOD |
+ * | | | Received_data == 0 && | | Save received MSB data |
+ * | | | Data_LSB == 0] | | |
+ * +------------------------------+-------+------------------------+------------------------------+---------------------------+
+ *
+ *
+ */
+
+typedef enum {
+ ST_DS18B20_READY,
+ ST_DS18B20_BUSY_WAITING_CONV,
+ ST_DS18B20_BUSY_WAITING_DMA
+} DS18B20_st_t;
+
+/* Identifier of Task Sensor */
+typedef enum {
+ ID_DS18B20_A,
+} task_temp_sensor_id_t;
+
+typedef struct {
+ task_temp_sensor_id_t identifier;
+} task_temp_sensor_cfg_t;
+
+typedef struct {
+ uint32_t tick;
+ DS18B20_st_t state;
+ // task_temp_sensor_ev_t event;
+} task_temp_sensor_dta_t;
+
+extern task_temp_sensor_dta_t task_temp_sensor_dta_list[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TASK_INC_TASK_SENSOR_ATTRIBUTE_H_ */
diff --git a/firmware/app/src/app.c b/firmware/app/src/app.c
@@ -13,7 +13,8 @@
#include "board.h"
#include "task_system.h"
#include "task_actuator.h"
-#include "task_sensor.h"
+#include "task_temp_sensor.h"
+#include "task_buttons.h"
#define G_APP_CNT_INI 0ul
#define G_APP_TICK_CNT_INI 0ul
@@ -33,9 +34,10 @@ typedef struct {
} task_dta_t;
const task_cfg_t task_cfg_list[] = {
- {task_sensor_init, task_sensor_update, NULL},
- {task_system_init, task_system_update, NULL},
- {task_actuator_init, task_actuator_update, NULL}
+ {task_buttons_init, task_buttons_update, NULL},
+ {task_temp_sensor_init, task_temp_sensor_update, NULL},
+ {task_system_init, task_system_update, NULL},
+ {task_actuator_init, task_actuator_update, NULL}
};
#define TASK_QTY (sizeof(task_cfg_list)/sizeof(task_cfg_t))
@@ -52,8 +54,6 @@ void app_init(void)
{
LOGGER_INFO("Initializing `app`...");
- g_app_WCET_us = G_APP_WCET_INI;
-
cycle_counter_init();
for (uint32_t index = 0; TASK_QTY > index; index++)
@@ -64,12 +64,14 @@ void app_init(void)
__asm("CPSID i");
g_app_tick_cnt = G_APP_TICK_CNT_INI;
- g_task_sensor_tick_cnt = G_APP_TICK_CNT_INI;
+ g_task_buttons_tick_cnt = G_APP_TICK_CNT_INI;
+ g_task_temp_sensor_tick_cnt = G_APP_TICK_CNT_INI;
g_task_system_tick_cnt = G_APP_TICK_CNT_INI;
g_task_actuator_tick_cnt = G_APP_TICK_CNT_INI;
__asm("CPSIE i");
LOGGER_INFO("Done initializing `app`");
+ g_app_WCET_us = G_APP_WCET_INI;
}
void app_update(void)
@@ -130,7 +132,8 @@ void app_update(void)
void HAL_SYSTICK_Callback(void)
{
g_app_tick_cnt++;
- g_task_sensor_tick_cnt++;
+ g_task_buttons_tick_cnt++;
+ g_task_temp_sensor_tick_cnt++;
g_task_system_tick_cnt++;
g_task_actuator_tick_cnt++;
}
diff --git a/firmware/app/src/ds18b20.c b/firmware/app/src/ds18b20.c
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
- *
- * See file `LICENSE` for full details
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-
-#include "main.h"
-
-#include "ds18b20.h"
-#include "logger.h"
-
-#define G_DS18B20_CONV_TIME_MS 180ul // ~188ms for 10 bit resolution
-#define G_DS18B20_DMA_TIMEOUT_MS 5000ul
-#define G_TEMP_PERIOD_MS 2000ul
-
-volatile bool b_DS18B20_Received_data;
-uint8_t g_DS18B20_Received_data_buffer[8];
-float g_DS18B20_temp;
-
-DS18B20_st_t g_DS18B20_state;
-uint32_t g_DS18B20_tick;
-
-uint8_t Temp_LSB;
-uint8_t Temp_MSB;
-static const uint8_t buffer[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-static bool b_DS18B20_Received_data_LSB;
-
-void UART1_SetBaud(uint32_t baud)
-{
- huart1.Instance = USART1;
- huart1.Init.BaudRate = baud;
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
- huart1.Init.StopBits = UART_STOPBITS_1;
- huart1.Init.Parity = UART_PARITY_NONE;
- huart1.Init.Mode = UART_MODE_TX_RX;
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
- if (HAL_HalfDuplex_Init(&huart1) != HAL_OK)
- {
- Error_Handler();
- };
-}
-
-uint8_t DS18B20_Reset(void)
-{
- uint8_t data = 0xF0;
- UART1_SetBaud(9600);
- HAL_UART_Transmit(&huart1, &data, 1, 100);
-
- if ((HAL_UART_Receive(&huart1, &data, 1, 1000) != HAL_OK) || (data == 0xF0))
- {
- // initialization failed
- LOGGER_ERROR("Couldn't read temperature sensor");
- return 1;
- }
-
- UART1_SetBaud(115200);
- return 0;
-}
-
-void DS18B20_SetResolution(uint8_t resolution)
-{
- uint8_t config;
-
- switch(resolution)
- {
- case 9: config = 0x1F; break;
- case 10: config = 0x3F; break;
- case 11: config = 0x5F; break;
- case 12: config = 0x7F; break;
- default: config = 0x7F;
- }
-
- DS18B20_Reset();
- DS18B20_Write(0xCC); // Send 'Skip ROM' command
- DS18B20_Write(0x4E); // Send 'write scratchpad' command
-
- DS18B20_Write(0x00); // TH
- DS18B20_Write(0x00); // TL
- DS18B20_Write(config);
-
- DS18B20_Reset();
-
- DS18B20_Write(0xCC); // Skip ROM
- DS18B20_Write(0x48); // Write scratchpad to EEPROM
-}
-
-void DS18B20_Init(void)
-{
- if (DS18B20_Reset() == 0)
- {
- LOGGER_INFO("Temperature sensor initialized successfully");
- }
- DS18B20_SetResolution(10);
- g_DS18B20_state = ST_DS18B20_READY;
- g_DS18B20_tick = G_TEMP_PERIOD_MS;
-}
-
-void DS18B20_Write(uint8_t data)
-{
- uint8_t buffer[8];
-
- for (uint8_t i = 0; i < 8; ++i)
- {
- if (data & (1 << i))
- {
- buffer[i] = 0xFF;
- }
- else
- {
- buffer[i] = 0x00;
- }
- }
-
- // This is a blocking call and can wait at most 100ms
- HAL_UART_Transmit(&huart1, buffer, 8, 100);
-}
-
-// Blocking version
-uint8_t DS18B20_Read(void)
-{
- uint8_t buffer[8];
- uint8_t received_value = 0;
-
- for (uint8_t i = 0; i < 8; ++i)
- {
- buffer[i] = 0xFF;
- }
-
- HAL_UART_Transmit_DMA(&huart1, buffer, 8);
- HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8);
-
- while(b_DS18B20_Received_data == false)
- ;
-
- b_DS18B20_Received_data = false;
-
- for (uint8_t i = 0; i < 8; ++i)
- {
- if (g_DS18B20_Received_data_buffer[i] == 0xFF)
- {
- received_value |= (1 << i);
- }
- }
-
- return received_value;
-}
-
-void DS18B20_Read_temp(void)
-{
- DS18B20_Reset();
- DS18B20_Write(0xCC); // Send 'Skip ROM' command
- DS18B20_Write(0x44); // Send 'Convert T' command
-
- DS18B20_Reset();
- DS18B20_Write(0xCC); // Send 'Skip ROM' command
- DS18B20_Write(0xBE); // Send 'read scratchpad' command
-
- Temp_LSB = DS18B20_Read();
- Temp_MSB = DS18B20_Read();
-
- uint16_t temp = (Temp_MSB << 8) | Temp_LSB;
- g_DS18B20_temp = (float) temp / 16.0;
-}
-
-void DS18B20_Read_temp_non_blocking(void)
-{
- switch (g_DS18B20_state)
- {
- case ST_DS18B20_READY:
- if (0 == g_DS18B20_tick)
- {
- // Send start temp conversion command
- // this needs 96ms to 750ms depending on resolution
- DS18B20_Reset();
- DS18B20_Write(0xCC); // Send 'Skip ROM' command
- DS18B20_Write(0x44); // Send 'Convert T' command
-
- g_DS18B20_state = ST_DS18B20_BUSY_WAITING_CONV;
- g_DS18B20_tick = G_DS18B20_CONV_TIME_MS;
- }
- else
- {
- g_DS18B20_tick--;
- }
- break;
-
- case ST_DS18B20_BUSY_WAITING_CONV:
- if (0 == g_DS18B20_tick)
- {
- DS18B20_Reset();
- DS18B20_Write(0xCC); // Send 'Skip ROM' command
- DS18B20_Write(0xBE); // Send 'read scratchpad' command
-
- if (HAL_OK == HAL_UART_Transmit_DMA(&huart1, buffer, 8))
- {
- if (HAL_OK == HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8))
- {
- b_DS18B20_Received_data_LSB = true;
- g_DS18B20_state = ST_DS18B20_BUSY_WAITING_DMA;
- g_DS18B20_tick = G_DS18B20_DMA_TIMEOUT_MS;
- }
- }
- }
- else
- {
- g_DS18B20_tick--;
- }
-
- break;
-
- case ST_DS18B20_BUSY_WAITING_DMA:
-
- if (0 == g_DS18B20_tick)
- {
- // DMA Timeout, reset conversion
- g_DS18B20_state = ST_DS18B20_READY;
- g_DS18B20_tick = G_TEMP_PERIOD_MS;
- break;
- }
- else
- {
- g_DS18B20_tick--;
- }
-
- if (true == b_DS18B20_Received_data)
- {
- b_DS18B20_Received_data = false;
-
- uint8_t received_value = 0;
- for (uint8_t i = 0; i < 8; ++i)
- {
- if (g_DS18B20_Received_data_buffer[i] == 0xFF)
- {
- received_value |= (1 << i);
- }
- }
-
-
-
- if (true == b_DS18B20_Received_data_LSB)
- {
- if (HAL_OK == HAL_UART_Transmit_DMA(&huart1, buffer, 8))
- {
- if (HAL_OK == HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8))
- {
- b_DS18B20_Received_data_LSB = false;
- Temp_LSB = received_value;
- g_DS18B20_tick = G_DS18B20_DMA_TIMEOUT_MS;
- }
- }
- }
- else
- {
- Temp_MSB = received_value;
- uint16_t temp = ((Temp_MSB << 8) | Temp_LSB);
- g_DS18B20_temp = (float) temp / 16.0;
- g_DS18B20_state = ST_DS18B20_READY;
- g_DS18B20_tick = G_TEMP_PERIOD_MS;
- }
- }
-
- break;
-
- default: break;
- }
-}
-
-void DS18B20_Update(void)
-{
- DS18B20_Read_temp_non_blocking();
-}
-
-void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
-{
- b_DS18B20_Received_data = true;
-}
diff --git a/firmware/app/src/task_buttons.c b/firmware/app/src/task_buttons.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#include "main.h"
+
+#include "logger.h"
+#include "dwt.h"
+
+#include "board.h"
+#include "app.h"
+#include "task_buttons_attribute.h"
+#include "task_system_attribute.h"
+#include "task_system_interface.h"
+
+#define G_TASK_SEN_TICK_CNT_INI 0ul
+
+#define DEL_BTN_XX_MIN 0ul
+#define DEL_BTN_XX_MED 25ul
+#define DEL_BTN_XX_MAX 50ul
+
+const task_buttons_cfg_t task_buttons_cfg_list[] = {
+ {ID_BTN_A, BTN_A_GPIO_Port, BTN_A_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
+ {ID_BTN_B, BTN_B_GPIO_Port, BTN_B_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
+ {ID_BTN_C, BTN_C_GPIO_Port, BTN_C_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
+ {ID_BTN_D, BTN_D_GPIO_Port, BTN_D_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
+};
+
+#define BUTTONS_CFG_QTY (sizeof(task_buttons_cfg_list)/sizeof(task_buttons_cfg_t))
+
+task_buttons_dta_t task_buttons_dta_list[] = {
+ {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
+ {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
+ {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
+ {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
+};
+
+#define BUTTONS_DTA_QTY (sizeof(task_buttons_dta_list)/sizeof(task_buttons_dta_t))
+
+// this variable is incremented by 1 on every ms by HAL_SysTick
+volatile uint32_t g_task_buttons_tick_cnt;
+
+void task_buttons_init(void *parameters)
+{
+ const task_buttons_cfg_t *p_task_buttons_cfg;
+ task_buttons_dta_t *p_task_buttons_dta;
+
+ LOGGER_INFO("Initializing `task_buttons`...");
+
+ for (uint32_t index = 0; BUTTONS_DTA_QTY > index; index++)
+ {
+ p_task_buttons_cfg = &task_buttons_cfg_list[index];
+ p_task_buttons_dta = &task_buttons_dta_list[index];
+
+ p_task_buttons_dta->state = ST_BTN_XX_UP;
+ p_task_buttons_dta->event = EV_BTN_XX_UP;
+ }
+
+ LOGGER_INFO("Done initializing `task_buttons`");
+}
+
+void task_buttons_update(void *parameters)
+{
+ const task_buttons_cfg_t *p_task_buttons_cfg;
+ task_buttons_dta_t *p_task_buttons_dta;
+
+ bool b_time_update_required = false;
+
+ __asm("CPSID i");
+ if (G_TASK_SEN_TICK_CNT_INI < g_task_buttons_tick_cnt)
+ {
+ g_task_buttons_tick_cnt--;
+ b_time_update_required = true;
+ }
+ __asm("CPSIE i");
+
+ while (b_time_update_required)
+ {
+ task_buttons_statechart();
+
+ __asm("CPSID i");
+ if (G_TASK_SEN_TICK_CNT_INI < g_task_buttons_tick_cnt)
+ {
+ g_task_buttons_tick_cnt--;
+ b_time_update_required = true;
+ }
+ else
+ {
+ b_time_update_required = false;
+ }
+ __asm("CPSIE i");
+
+ }
+}
+
+void task_buttons_statechart(void)
+{
+ uint32_t index;
+ const task_buttons_cfg_t *p_task_buttons_cfg;
+ task_buttons_dta_t *p_task_buttons_dta;
+ uint8_t button_pin_status;
+
+ for (index = 0; BUTTONS_DTA_QTY > index; index++)
+ {
+ p_task_buttons_cfg = &task_buttons_cfg_list[index];
+ p_task_buttons_dta = &task_buttons_dta_list[index];
+
+ button_pin_status = HAL_GPIO_ReadPin(p_task_buttons_cfg->gpio_port, p_task_buttons_cfg->pin);
+
+ if (button_pin_status == p_task_buttons_cfg->pressed)
+ {
+ p_task_buttons_dta->event = EV_BTN_XX_DOWN;
+ }
+ else
+ {
+ p_task_buttons_dta->event = EV_BTN_XX_UP;
+ }
+
+ switch (p_task_buttons_dta->state)
+ {
+ case ST_BTN_XX_UP:
+ if (EV_BTN_XX_DOWN == p_task_buttons_dta->event)
+ {
+ p_task_buttons_dta->state = ST_BTN_XX_FALLING;
+ p_task_buttons_dta->tick = DEL_BTN_XX_MAX;
+ }
+ break;
+
+ case ST_BTN_XX_FALLING:
+ if (EV_BTN_XX_UP == p_task_buttons_dta->event)
+ {
+ if (0 == p_task_buttons_dta->tick) {
+ p_task_buttons_dta->state = ST_BTN_XX_UP;
+ }
+
+ if (p_task_buttons_dta->tick > 0) {
+ p_task_buttons_dta->state = ST_BTN_XX_FALLING;
+ p_task_buttons_dta->tick--;
+ }
+ }
+
+ if (EV_BTN_XX_DOWN == p_task_buttons_dta->event)
+ {
+ if (0 == p_task_buttons_dta->tick) {
+ p_task_buttons_dta->state = ST_BTN_XX_DOWN;
+ put_event_task_system(p_task_buttons_cfg->signal_down);
+ }
+
+ if (p_task_buttons_dta->tick > 0) {
+ p_task_buttons_dta->tick--;
+ }
+ }
+ break;
+
+ case ST_BTN_XX_DOWN:
+ if (EV_BTN_XX_UP == p_task_buttons_dta->event)
+ {
+ p_task_buttons_dta->state = ST_BTN_XX_RISING;
+ p_task_buttons_dta->tick = DEL_BTN_XX_MAX;
+ }
+ break;
+
+ case ST_BTN_XX_RISING:
+ if (EV_BTN_XX_UP == p_task_buttons_dta->event)
+ {
+ if (0 == p_task_buttons_dta->tick) {
+ put_event_task_system(p_task_buttons_cfg->signal_up);
+ p_task_buttons_dta->state = ST_BTN_XX_UP;
+ }
+
+ if (p_task_buttons_dta->tick > 0) {
+ p_task_buttons_dta->tick--;
+ }
+ }
+
+ if (EV_BTN_XX_DOWN == p_task_buttons_dta->event)
+ {
+ if (0 == p_task_buttons_dta->tick) {
+ p_task_buttons_dta->state = ST_BTN_XX_DOWN;
+ }
+
+ if (p_task_buttons_dta->tick > 0) {
+ p_task_buttons_dta->tick--;
+ }
+ }
+ break;
+
+ default: break;
+ }
+ }
+}
diff --git a/firmware/app/src/task_sensor.c b/firmware/app/src/task_sensor.c
@@ -1,243 +0,0 @@
-/*
- * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
- * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
- *
- * See file `LICENSE` for full details
- */
-
-#include "main.h"
-
-#include "logger.h"
-#include "dwt.h"
-
-#include "board.h"
-#include "app.h"
-#include "task_sensor_attribute.h"
-#include "task_system_attribute.h"
-#include "task_system_interface.h"
-#include "ds18b20.h"
-
-#define G_TASK_SEN_TICK_CNT_INI 0ul
-#define G_TASK_SEN_TEMP_PERIOD_MS 1000ul
-
-#define DEL_BTN_XX_MIN 0ul
-#define DEL_BTN_XX_MED 25ul
-#define DEL_BTN_XX_MAX 50ul
-
-const task_sensor_cfg_t task_sensor_cfg_list[] = {
- {ID_BTN_A, BTN_A_GPIO_Port, BTN_A_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_BTN_B, BTN_B_GPIO_Port, BTN_B_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_BTN_C, BTN_C_GPIO_Port, BTN_C_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_BTN_D, BTN_D_GPIO_Port, BTN_D_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_DS18B20}
-};
-
-#define SENSOR_CFG_QTY (sizeof(task_sensor_cfg_list)/sizeof(task_sensor_cfg_t))
-
-task_sensor_dta_t task_sensor_dta_list[] = {
- {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
- {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
- {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
- {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP},
- {G_TASK_SEN_TEMP_PERIOD_MS, ST_SEN_READY}
-};
-
-#define SENSOR_DTA_QTY (sizeof(task_sensor_dta_list)/sizeof(task_sensor_dta_t))
-
-// void task_sensor_statechart(void);
-
-// local global variables
-uint32_t g_task_sensor_tick;
-
-// this variable is incremented by 1 on every ms by HAL_SysTick
-volatile uint32_t g_task_sensor_tick_cnt;
-
-void task_sensor_init(void *parameters)
-{
- const task_sensor_cfg_t *p_task_sensor_cfg;
- task_sensor_dta_t *p_task_sensor_dta;
-
- LOGGER_INFO("Initializing `task_sensor`...");
-
- g_task_sensor_tick = G_TASK_SEN_TEMP_PERIOD_MS;
-
- for (uint32_t index = 0; SENSOR_DTA_QTY > index; index++)
- {
- p_task_sensor_cfg = &task_sensor_cfg_list[index];
- p_task_sensor_dta = &task_sensor_dta_list[index];
-
- switch (p_task_sensor_cfg->identifier) {
- case ID_DS18B20:
- DS18B20_Init();
- break;
-
- default:
-
- p_task_sensor_dta = &task_sensor_dta_list[index];
-
- p_task_sensor_dta->state = ST_BTN_XX_UP;
- p_task_sensor_dta->event = EV_BTN_XX_UP;
-
- break;
- }
-
- }
-
- LOGGER_INFO("Done initializing `task_sensor`");
-}
-
-uint8_t sensor_pin_status;
-void task_sensor_update(void *parameters)
-{
- const task_sensor_cfg_t *p_task_sensor_cfg;
- task_sensor_dta_t *p_task_sensor_dta;
-
- bool b_time_update_required = false;
-
- __asm("CPSID i");
- if (G_TASK_SEN_TICK_CNT_INI < g_task_sensor_tick_cnt)
- {
- g_task_sensor_tick_cnt--;
- b_time_update_required = true;
- }
- __asm("CPSIE i");
-
- while (b_time_update_required)
- {
- for (uint32_t index = 0; SENSOR_DTA_QTY > index; index++)
- {
- p_task_sensor_cfg = &task_sensor_cfg_list[index];
- p_task_sensor_dta = &task_sensor_dta_list[index];
-
- switch (p_task_sensor_cfg->identifier)
- {
- case ID_DS18B20:
- DS18B20_Update();
- break;
-
- default:
- sensor_pin_status = HAL_GPIO_ReadPin(p_task_sensor_cfg->gpio_port, p_task_sensor_cfg->pin);
-
- if (sensor_pin_status == p_task_sensor_cfg->pressed)
- {
- p_task_sensor_dta->event = EV_BTN_XX_DOWN;
- }
- else
- {
- p_task_sensor_dta->event = EV_BTN_XX_UP;
- }
-
- switch (p_task_sensor_dta->state)
- {
- case ST_BTN_XX_UP:
- if (EV_BTN_XX_DOWN == p_task_sensor_dta->event)
- {
- p_task_sensor_dta->state = ST_BTN_XX_FALLING;
- p_task_sensor_dta->tick = DEL_BTN_XX_MAX;
- }
- break;
-
- case ST_BTN_XX_FALLING:
- if (EV_BTN_XX_UP == p_task_sensor_dta->event)
- {
- if (0 == p_task_sensor_dta->tick) {
- p_task_sensor_dta->state = ST_BTN_XX_UP;
- }
-
- if (p_task_sensor_dta->tick > 0) {
- p_task_sensor_dta->state = ST_BTN_XX_FALLING;
- p_task_sensor_dta->tick--;
- }
- }
-
- if (EV_BTN_XX_DOWN == p_task_sensor_dta->event)
- {
- if (0 == p_task_sensor_dta->tick) {
- p_task_sensor_dta->state = ST_BTN_XX_DOWN;
- put_event_task_system(p_task_sensor_cfg->signal_down);
- }
-
- if (p_task_sensor_dta->tick > 0) {
- p_task_sensor_dta->tick--;
- }
- }
- break;
-
- case ST_BTN_XX_DOWN:
- if (EV_BTN_XX_UP == p_task_sensor_dta->event)
- {
- p_task_sensor_dta->state = ST_BTN_XX_RISING;
- p_task_sensor_dta->tick = DEL_BTN_XX_MAX;
- }
- break;
-
- case ST_BTN_XX_RISING:
- if (EV_BTN_XX_UP == p_task_sensor_dta->event)
- {
- if (0 == p_task_sensor_dta->tick) {
- put_event_task_system(p_task_sensor_cfg->signal_up);
- p_task_sensor_dta->state = ST_BTN_XX_UP;
- }
-
- if (p_task_sensor_dta->tick > 0) {
- p_task_sensor_dta->tick--;
- }
- }
-
- if (EV_BTN_XX_DOWN == p_task_sensor_dta->event)
- {
- if (0 == p_task_sensor_dta->tick) {
- p_task_sensor_dta->state = ST_BTN_XX_DOWN;
- }
-
- if (p_task_sensor_dta->tick > 0) {
- p_task_sensor_dta->tick--;
- }
- }
- break;
-
- default: break;
- }
- break;
- }
- }
-
- __asm("CPSID i");
- if (G_TASK_SEN_TICK_CNT_INI < g_task_sensor_tick_cnt)
- {
- g_task_sensor_tick_cnt--;
- b_time_update_required = true;
- }
- else
- {
- b_time_update_required = false;
- }
- __asm("CPSIE i");
-
- }
-}
-
-/*
-void task_sensor_statechart(void)
-{
- uint32_t index;
- const task_sensor_cfg_t *p_task_sensor_cfg;
- // task_sensor_dta_t *p_task_sensor_dta;
-
-
- for (index = 0; SENSOR_DTA_QTY > index; index++)
- {
- p_task_sensor_cfg = &task_sensor_cfg_list[index];
- // p_task_sensor_dta = &task_sensor_dta_list[index];
-
- switch (p_task_sensor_cfg->identifier)
- {
- case ID_DS18B20:
- DS18B20_Update();
- break;
-
- default: break;
- }
- }
-}
-*/
diff --git a/firmware/app/src/task_temp_sensor.c b/firmware/app/src/task_temp_sensor.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "main.h"
+
+#include "task_temp_sensor_attribute.h"
+#include "task_temp_sensor.h"
+#include "logger.h"
+
+#define G_TASK_SEN_TICK_CNT_INI 0ul
+#define G_DS18B20_CONV_TIME_MS 180ul // ~188ms for 10 bit resolution
+#define G_DS18B20_DMA_TIMEOUT_MS 2000ul
+#define G_TEMP_PERIOD_MS 1000ul
+
+// local global variables
+volatile bool b_DS18B20_Received_data;
+uint8_t g_DS18B20_Received_data_buffer[8];
+float g_DS18B20_temp;
+
+DS18B20_st_t g_DS18B20_state;
+uint32_t g_task_temp_sensor_tick;
+
+uint8_t Temp_LSB;
+uint8_t Temp_MSB;
+static const uint8_t buffer[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static bool b_DS18B20_Received_data_LSB;
+
+// this variable is incremented by 1 on every ms by HAL_SysTick
+volatile uint32_t g_task_temp_sensor_tick_cnt;
+
+// private functions declaration
+void UART1_SetBaud(uint32_t baud);
+void DS18B20_Write(uint8_t data);
+void DS18B20_Read_temp(void);
+void DS18B20_Read_temp_non_blocking(void);
+void DS18B20_Init(void);
+uint8_t DS18B20_Read(void);
+uint8_t DS18B20_Reset(void);
+
+void UART1_SetBaud(uint32_t baud)
+{
+ huart1.Instance = USART1;
+ huart1.Init.BaudRate = baud;
+ huart1.Init.WordLength = UART_WORDLENGTH_8B;
+ huart1.Init.StopBits = UART_STOPBITS_1;
+ huart1.Init.Parity = UART_PARITY_NONE;
+ huart1.Init.Mode = UART_MODE_TX_RX;
+ huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart1.Init.OverSampling = UART_OVERSAMPLING_16;
+ if (HAL_HalfDuplex_Init(&huart1) != HAL_OK)
+ {
+ Error_Handler();
+ };
+}
+
+uint8_t DS18B20_Reset(void)
+{
+ uint8_t data = 0xF0;
+ UART1_SetBaud(9600);
+ HAL_UART_Transmit(&huart1, &data, 1, 10);
+
+ if ((HAL_UART_Receive(&huart1, &data, 1, 10) != HAL_OK) || (data == 0xF0))
+ {
+ // initialization failed
+ LOGGER_ERROR("Couldn't read temperature sensor");
+ return 1;
+ }
+
+ UART1_SetBaud(115200);
+ return 0;
+}
+
+void DS18B20_SetResolution(uint8_t resolution)
+{
+ uint8_t config;
+
+ switch(resolution)
+ {
+ case 9: config = 0x1F; break;
+ case 10: config = 0x3F; break;
+ case 11: config = 0x5F; break;
+ case 12: config = 0x7F; break;
+ default: config = 0x7F;
+ }
+
+ DS18B20_Reset();
+ DS18B20_Write(0xCC); // Send 'Skip ROM' command
+ DS18B20_Write(0x4E); // Send 'write scratchpad' command
+
+ DS18B20_Write(0x00); // TH
+ DS18B20_Write(0x00); // TL
+ DS18B20_Write(config);
+
+ DS18B20_Reset();
+
+ DS18B20_Write(0xCC); // Skip ROM
+ DS18B20_Write(0x48); // Write scratchpad to EEPROM
+}
+
+void DS18B20_Init(void)
+{
+ if (DS18B20_Reset() == 0)
+ {
+ LOGGER_INFO("Temperature sensor initialized successfully");
+ }
+ DS18B20_SetResolution(10);
+ g_DS18B20_state = ST_DS18B20_READY;
+ g_task_temp_sensor_tick = G_TEMP_PERIOD_MS;
+}
+
+void DS18B20_Write(uint8_t data)
+{
+ uint8_t buffer[8];
+
+ for (uint8_t i = 0; i < 8; ++i)
+ {
+ if (data & (1 << i))
+ {
+ buffer[i] = 0xFF;
+ }
+ else
+ {
+ buffer[i] = 0x00;
+ }
+ }
+
+ // This is a blocking call and can wait at most 100ms
+ // TODO: convert to non-blocking call using DMA
+ HAL_UART_Transmit(&huart1, buffer, 8, 10);
+}
+
+// Blocking version
+uint8_t DS18B20_Read(void)
+{
+ uint8_t buffer[8];
+ uint8_t received_value = 0;
+
+ for (uint8_t i = 0; i < 8; ++i)
+ {
+ buffer[i] = 0xFF;
+ }
+
+ HAL_UART_Transmit_DMA(&huart1, buffer, 8);
+ HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8);
+
+ while(b_DS18B20_Received_data == false)
+ ;
+
+ b_DS18B20_Received_data = false;
+
+ for (uint8_t i = 0; i < 8; ++i)
+ {
+ if (g_DS18B20_Received_data_buffer[i] == 0xFF)
+ {
+ received_value |= (1 << i);
+ }
+ }
+
+ return received_value;
+}
+
+void DS18B20_Read_temp(void)
+{
+ DS18B20_Reset();
+ DS18B20_Write(0xCC); // Send 'Skip ROM' command
+ DS18B20_Write(0x44); // Send 'Convert T' command
+
+ DS18B20_Reset();
+ DS18B20_Write(0xCC); // Send 'Skip ROM' command
+ DS18B20_Write(0xBE); // Send 'read scratchpad' command
+
+ Temp_LSB = DS18B20_Read();
+ Temp_MSB = DS18B20_Read();
+
+ uint16_t temp = (Temp_MSB << 8) | Temp_LSB;
+ g_DS18B20_temp = (float) temp / 16.0;
+}
+
+void DS18B20_Read_temp_non_blocking(void)
+{
+ switch (g_DS18B20_state)
+ {
+ case ST_DS18B20_READY:
+ if (0 == g_task_temp_sensor_tick)
+ {
+ // Send start temp conversion command
+ // this needs 96ms to 750ms depending on resolution
+ DS18B20_Reset();
+ DS18B20_Write(0xCC); // Send 'Skip ROM' command
+ DS18B20_Write(0x44); // Send 'Convert T' command
+
+ g_DS18B20_state = ST_DS18B20_BUSY_WAITING_CONV;
+ g_task_temp_sensor_tick = G_DS18B20_CONV_TIME_MS;
+ }
+ else
+ {
+ g_task_temp_sensor_tick--;
+ }
+ break;
+
+ case ST_DS18B20_BUSY_WAITING_CONV:
+ if (0 == g_task_temp_sensor_tick)
+ {
+ DS18B20_Reset();
+ DS18B20_Write(0xCC); // Send 'Skip ROM' command
+ DS18B20_Write(0xBE); // Send 'read scratchpad' command
+
+ if (HAL_OK == HAL_UART_Transmit_DMA(&huart1, buffer, 8))
+ {
+ if (HAL_OK == HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8))
+ {
+ b_DS18B20_Received_data_LSB = true;
+ g_DS18B20_state = ST_DS18B20_BUSY_WAITING_DMA;
+ g_task_temp_sensor_tick = G_DS18B20_DMA_TIMEOUT_MS;
+ }
+ }
+ }
+ else
+ {
+ g_task_temp_sensor_tick--;
+ }
+
+ break;
+
+ case ST_DS18B20_BUSY_WAITING_DMA:
+
+ if (0 == g_task_temp_sensor_tick)
+ {
+ // DMA Timeout, reset conversion
+ g_DS18B20_state = ST_DS18B20_READY;
+ g_task_temp_sensor_tick = G_TEMP_PERIOD_MS;
+ break;
+ }
+ else
+ {
+ g_task_temp_sensor_tick--;
+ }
+
+ if (true == b_DS18B20_Received_data)
+ {
+ b_DS18B20_Received_data = false;
+
+ uint8_t received_value = 0;
+ for (uint8_t i = 0; i < 8; ++i)
+ {
+ if (g_DS18B20_Received_data_buffer[i] == 0xFF)
+ {
+ received_value |= (1 << i);
+ }
+ }
+
+ if (true == b_DS18B20_Received_data_LSB)
+ {
+ if (HAL_OK == HAL_UART_Transmit_DMA(&huart1, buffer, 8))
+ {
+ if (HAL_OK == HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8))
+ {
+ b_DS18B20_Received_data_LSB = false;
+ Temp_LSB = received_value;
+ g_task_temp_sensor_tick = G_DS18B20_DMA_TIMEOUT_MS;
+ }
+ }
+ }
+ else
+ {
+ Temp_MSB = received_value;
+ uint16_t temp = ((Temp_MSB << 8) | Temp_LSB);
+ g_DS18B20_temp = (float) temp / 16.0;
+ g_DS18B20_state = ST_DS18B20_READY;
+ g_task_temp_sensor_tick = G_TEMP_PERIOD_MS;
+ }
+ }
+
+ break;
+
+ default: break;
+ }
+}
+
+void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ b_DS18B20_Received_data = true;
+}
+
+void task_temp_sensor_init(void *parameters)
+{
+ LOGGER_INFO("Initializing `task_temp_sensor`...");
+
+ g_task_temp_sensor_tick = G_TASK_SEN_TICK_CNT_INI;
+ DS18B20_Init();
+
+ LOGGER_INFO("Done initializing `task_temp_sensor`");
+}
+
+void task_temp_sensor_update(void *parameters)
+{
+ bool b_time_update_required = false;
+
+ __asm("CPSID i");
+ if (G_TASK_SEN_TICK_CNT_INI < g_task_temp_sensor_tick_cnt)
+ {
+ g_task_temp_sensor_tick_cnt--;
+ b_time_update_required = true;
+ }
+ __asm("CPSIE i");
+
+ while (b_time_update_required)
+ {
+ DS18B20_Read_temp_non_blocking();
+
+ __asm("CPSID i");
+ if (G_TASK_SEN_TICK_CNT_INI < g_task_temp_sensor_tick_cnt)
+ {
+ g_task_temp_sensor_tick_cnt--;
+ b_time_update_required = true;
+ }
+ else
+ {
+ b_time_update_required = false;
+ }
+ __asm("CPSIE i");
+
+ }
+}