commit 3482a2cce4b4715c4c2bdf287152fa7f24bd5f07
parent fb48410853668478a318f34fb326e41320af08f4
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Sun, 22 Mar 2026 12:24:46 -0300
Mover funciones `DS18B20_` de `task_temp_sensor.*` a archivos `ds18b20.*`
Diffstat:
13 files changed, 414 insertions(+), 365 deletions(-)
diff --git a/firmware/.cproject b/firmware/.cproject
@@ -23,6 +23,7 @@
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1578684016" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-F103RB" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.137200207" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-F103RB || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Device/ST/STM32F1xx/Include | ../Drivers/CMSIS/Include | ../Core/Inc | ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy | ../Drivers/STM32F1xx_HAL_Driver/Inc || || || USE_HAL_DRIVER | STM32F103xB || || Drivers | Core/Startup | Core || || || ${workspace_loc:/${ProjName}/STM32F103RBTX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || || || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.718213595" name="Cpu clock frequence" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="64" valueType="string"/>
+ <option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.1243536684" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1359183697" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
<builder buildPath="${workspace_loc:/tdse-tp2_01-model_integration}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.1277475106" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1808103261" name="MCU/MPU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
@@ -337,5 +338,12 @@
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
- <storageModule moduleId="refreshScope"/>
+ <storageModule moduleId="refreshScope" versionNumber="2">
+ <configuration configurationName="Debug">
+ <resource resourceType="PROJECT" workspacePath="/tdse-tf_3-02"/>
+ </configuration>
+ <configuration configurationName="Release">
+ <resource resourceType="PROJECT" workspacePath="/tdse-tf_3-02"/>
+ </configuration>
+ </storageModule>
</cproject>
\ No newline at end of file
diff --git a/firmware/Core/Inc/main.h b/firmware/Core/Inc/main.h
@@ -75,8 +75,6 @@ void Error_Handler(void);
#define BTN_B_GPIO_Port GPIOB
#define D4_Pin GPIO_PIN_7
#define D4_GPIO_Port GPIOC
-#define BUZZER_Pin GPIO_PIN_8
-#define BUZZER_GPIO_Port GPIOA
#define TMS_Pin GPIO_PIN_13
#define TMS_GPIO_Port GPIOA
#define TCK_Pin GPIO_PIN_14
diff --git a/firmware/Core/Src/main.c b/firmware/Core/Src/main.c
@@ -314,12 +314,6 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(D4_GPIO_Port, &GPIO_InitStruct);
- /*Configure GPIO pin : BUZZER_Pin */
- GPIO_InitStruct.Pin = BUZZER_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(BUZZER_GPIO_Port, &GPIO_InitStruct);
-
/*Configure GPIO pins : D5_Pin D9_Pin D8_Pin */
GPIO_InitStruct.Pin = D5_Pin|D9_Pin|D8_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
diff --git a/firmware/Core/Src/stm32f1xx_hal_msp.c b/firmware/Core/Src/stm32f1xx_hal_msp.c
@@ -119,7 +119,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
- hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
+ hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
@@ -135,7 +135,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
- hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
+ hdma_usart1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
diff --git a/firmware/app/inc/app.h b/firmware/app/inc/app.h
@@ -12,7 +12,6 @@
extern "C" {
#endif
-extern uint32_t g_app_cnt;
extern uint32_t g_app_runtime_us;
extern uint32_t g_app_WCET_us;
extern volatile uint32_t g_app_tick_cnt;
diff --git a/firmware/app/inc/ds18b20.h b/firmware/app/inc/ds18b20.h
@@ -0,0 +1,65 @@
+/*
+ * 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 _DS18B20_H_
+#define _DS18B20_H_
+
+#include <stdbool.h>
+#include <stdint.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;
+
+void DS18B20_Init(void);
+void DS18B20_Update(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DS18B20_H_ */
diff --git a/firmware/app/inc/task_menu_attribute.h b/firmware/app/inc/task_menu_attribute.h
@@ -34,6 +34,7 @@ typedef enum {
EV_MEN_NEX_ACTIVE,
EV_MEN_ESC_IDLE,
EV_MEN_ESC_ACTIVE,
+ EV_MEN_DISPLAY_UPDATE,
EV_MEN_INACTIVE_TIMEOUT
} task_menu_ev_t;
diff --git a/firmware/app/inc/task_temp_sensor_attribute.h b/firmware/app/inc/task_temp_sensor_attribute.h
@@ -11,47 +11,6 @@
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;
@@ -62,7 +21,7 @@ typedef struct {
typedef struct {
uint32_t tick;
- DS18B20_st_t state;
+ // task_temp_sensor_st_t state;
// task_temp_sensor_ev_t event;
} task_temp_sensor_dta_t;
diff --git a/firmware/app/src/app.c b/firmware/app/src/app.c
@@ -44,7 +44,6 @@ const task_cfg_t task_cfg_list[] = {
#define TASK_QTY (sizeof(task_cfg_list)/sizeof(task_cfg_t))
-uint32_t g_app_cnt;
uint32_t g_app_runtime_us;
uint32_t g_app_WCET_us; // Worst case execution time historically
@@ -92,7 +91,6 @@ void app_update(void)
while (b_time_update_required)
{
- g_app_cnt++;
g_app_runtime_us = 0;
for (index = 0; TASK_QTY > index; index++)
diff --git a/firmware/app/src/ds18b20.c b/firmware/app/src/ds18b20.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#include <stdbool.h>
+
+#include "main.h"
+#include "systick.h"
+#include "ds18b20.h"
+#include "stm32f1xx_ll_usart.h"
+#include "logger.h"
+
+#include "task_menu_attribute.h"
+#include "task_menu_interface.h"
+
+#define G_DS18B20_CONV_TIME_MS 180ul // ~188ms for 10 bit resolution
+#define G_DS18B20_DMA_TIMEOUT_MS 50ul
+#define G_TEMP_PERIOD_MS 1000ul
+
+// Private global variables
+volatile bool b_DS18B20_Received_data;
+static uint8_t g_DS18B20_Received_data_buffer[8];
+const uint8_t g_buffer[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static bool b_DS18B20_Received_data_LSB;
+DS18B20_st_t g_DS18B20_state;
+uint32_t g_DS18B20_tick;
+uint16_t g_DS18B20_temp;
+
+uint8_t Temp_LSB, Temp_MSB;
+
+// Public global variables
+uint16_t g_DS18B20_update_count;
+uint16_t g_DS18B20_DMA_error_count;
+
+// Private functions declaration
+void DS18B20_Write(uint8_t data);
+void DS18B20_Read_temp(void);
+uint8_t DS18B20_Read(void);
+uint8_t DS18B20_Reset(void);
+
+uint8_t DS18B20_Reset(void)
+{
+ uint8_t data = 0xF0;
+
+ __HAL_UART_DISABLE(&huart1);
+ LL_USART_SetBaudRate(USART1, HAL_RCC_GetPCLK2Freq(), 9600);
+ __HAL_UART_ENABLE(&huart1);
+ HAL_UART_Transmit(&huart1, &data, 1, 100);
+
+ if ((HAL_UART_Receive(&huart1, &data, 1, 100) != HAL_OK) || (data == 0xF0))
+ {
+ // initialization failed
+ LOGGER_ERROR("Couldn't read temperature sensor");
+ return 1;
+ }
+
+ __HAL_UART_DISABLE(&huart1);
+ LL_USART_SetBaudRate(USART1, HAL_RCC_GetPCLK2Freq(), 115200);
+ __HAL_UART_ENABLE(&huart1);
+ 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(9);
+ g_DS18B20_state = ST_DS18B20_READY;
+ g_DS18B20_tick = G_TEMP_PERIOD_MS;
+ g_DS18B20_update_count = 0;
+ g_DS18B20_DMA_error_count = 0;
+
+ Temp_LSB = Temp_MSB = 0xFF;
+}
+
+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, 100);
+}
+
+void DS18B20_Start_conv(void)
+{
+ // Send start temp conversion command
+ // the sensor needs 96ms to 750ms to complete temp conversion depending on
+ // resolution
+ DS18B20_Reset();
+ DS18B20_Write(0xCC); // Send 'Skip ROM' command
+ DS18B20_Write(0x44); // Send 'Convert T' command
+}
+
+static uint8_t l_DS18B20_DMA_error_count = 0;
+void DS18B20_Update(void)
+{
+ switch (g_DS18B20_state)
+ {
+ case ST_DS18B20_READY:
+ if (0 == g_DS18B20_tick)
+ {
+ DS18B20_Start_conv();
+ g_DS18B20_state = ST_DS18B20_BUSY_WAITING_CONV;
+ g_DS18B20_tick = G_DS18B20_CONV_TIME_MS;
+ l_DS18B20_DMA_error_count = 0;
+ }
+ 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
+
+ HAL_UART_Transmit_DMA(&huart1, g_buffer, 8);
+ 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:
+ // Process received byte if any
+ 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)
+ {
+ b_DS18B20_Received_data_LSB = false;
+ // LSB
+ // g_DS18B20_temp = (0x00FF & received_value);
+ Temp_LSB = received_value;
+ g_DS18B20_tick = G_DS18B20_DMA_TIMEOUT_MS;
+
+ HAL_UART_Transmit_DMA(&huart1, g_buffer, 8);
+ HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8);
+ }
+ else
+ {
+ // MSB
+ // g_DS18B20_temp = ((g_DS18B20_temp | (0xFF00 & (received_value << 8))) / 16.0);
+ Temp_MSB = received_value;
+ g_DS18B20_temp = ((Temp_MSB << 8) | Temp_LSB) / 16;
+ g_DS18B20_state = ST_DS18B20_READY;
+ g_DS18B20_tick = G_TEMP_PERIOD_MS;
+
+ g_DS18B20_update_count++;
+ put_event_task_menu(EV_MEN_DISPLAY_UPDATE);
+ }
+ }
+ else if (0 == g_DS18B20_tick) // Error handling
+ {
+ if (0 == l_DS18B20_DMA_error_count)
+ {
+ // Try again readying scratchpad (only once)
+ g_DS18B20_DMA_error_count++;
+ l_DS18B20_DMA_error_count++;
+ put_event_task_menu(EV_MEN_DISPLAY_UPDATE);
+
+ /*
+ HAL_UART_DMAStop(&huart1);
+ __HAL_UART_DISABLE(&huart1);
+ __HAL_UART_CLEAR_PEFLAG(&huart1);
+ __HAL_UART_CLEAR_FEFLAG(&huart1);
+ __HAL_UART_CLEAR_NEFLAG(&huart1);
+ __HAL_UART_CLEAR_OREFLAG(&huart1);
+ __HAL_UART_ENABLE(&huart1);
+ memset(g_DS18B20_Received_data_buffer, 0, sizeof(g_DS18B20_Received_data_buffer));
+
+ HAL_UART_Transmit_DMA(&huart1, g_buffer, 8);
+ HAL_UART_Receive_DMA(&huart1, g_DS18B20_Received_data_buffer, 8);
+
+ g_DS18B20_tick = G_DS18B20_DMA_TIMEOUT_MS;
+ */
+
+ g_DS18B20_state = ST_DS18B20_BUSY_WAITING_CONV;
+ }
+ else
+ {
+ // DMA Timeout, start conversion again
+ __HAL_UART_DISABLE(&huart1);
+ __HAL_UART_ENABLE(&huart1);
+ g_DS18B20_state = ST_DS18B20_READY;
+ g_DS18B20_tick = G_TEMP_PERIOD_MS;
+ }
+ }
+ else
+ {
+ g_DS18B20_tick--;
+ }
+
+ break;
+
+ default: break;
+ }
+}
+
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ if (huart->Instance == USART1)
+ {
+ b_DS18B20_Received_data = true;
+ }
+}
diff --git a/firmware/app/src/task_menu.c b/firmware/app/src/task_menu.c
@@ -18,12 +18,13 @@
#include "task_menu_interface.h"
#include "display.h"
-#define G_TASK_MEN_CNT_INI 0ul
-#define G_TASK_MEN_TICK_CNT_INI 0ul
-#define DEL_MEN_XX_MIN 0ul
+#define G_TASK_MEN_CNT_INI 0ul
+#define G_TASK_MEN_TICK_CNT_INI 0ul
+
+#define G_TASK_MEN_UPDATE_RATE_INI 0ul
task_menu_dta_t task_menu_dta = {
- DEL_MEN_XX_MIN, ST_MEN_IDLE, EV_MEN_ENT_IDLE, false
+ G_TASK_MEN_UPDATE_RATE_INI, ST_MEN_IDLE, EV_MEN_ENT_IDLE, false
};
#define MENU_DTA_QTY (sizeof(task_menu_dta)/sizeof(task_menu_dta_t))
@@ -44,12 +45,15 @@ task_menu_st_t g_menu_prev_state;
uint32_t g_task_menu_cnt;
volatile uint32_t g_task_menu_tick_cnt;
+// External variables
+extern uint16_t g_DS18B20_temp;
+extern uint16_t g_DS18B20_update_count;
+extern uint16_t g_DS18B20_DMA_error_count;
+
// Public functions
void task_menu_init(void *parameters)
{
task_menu_dta_t *p_task_menu_dta;
- task_menu_st_t state;
- task_menu_ev_t event;
LOGGER_INFO("Initializing `task_menu`...");
@@ -59,9 +63,8 @@ void task_menu_init(void *parameters)
p_task_menu_dta = &task_menu_dta;
- state = ST_MEN_IDLE;
- p_task_menu_dta->state = state;
- g_menu_prev_state = state;
+ p_task_menu_dta->state = ST_MEN_IDLE;
+ g_menu_prev_state = ST_MEN_IDLE;
p_task_menu_dta->event = EV_MEN_ENT_IDLE;
p_task_menu_dta->event_flag = false;
@@ -116,6 +119,20 @@ void menu_set_state(task_menu_st_t new_state)
g_display_update = true;
}
+int count_digits(int n) {
+ int count = 0;
+
+ if (n == 0) return 1;
+ if (n < 0) n = -n;
+
+ while (n > 0) {
+ n /= 10;
+ count++;
+ }
+
+ return count;
+}
+
void task_menu_statechart(void)
{
task_menu_dta_t *p_task_menu_dta;
@@ -129,7 +146,6 @@ void task_menu_statechart(void)
p_task_menu_dta->event = get_event_task_menu();
}
-
if ((true == p_task_menu_dta->event_flag)
&& (p_task_menu_dta->event == EV_MEN_INACTIVE_TIMEOUT)
&& (p_task_menu_dta->state != ST_MEN_IDLE))
@@ -141,14 +157,6 @@ void task_menu_statechart(void)
{
case ST_MEN_IDLE:
- if (g_display_update)
- {
- g_display_update = false;
- display_clear();
- sprintf(menu_row_str, "Hello%cC", 0xDF);
- display_write_string(menu_row_str);
- }
-
if (true == p_task_menu_dta->event_flag)
{
p_task_menu_dta->event_flag = false;
@@ -159,16 +167,35 @@ void task_menu_statechart(void)
case EV_MEN_ESC_ACTIVE:
menu_set_state(ST_MEN_IDLE);
break;
+ case EV_MEN_DISPLAY_UPDATE:
+ g_display_update = true;
+ break;
default:
- break;
+ break;
}
}
+ if (g_display_update)
+ {
+ g_display_update = false;
+ display_clear();
+ uint8_t temp_digits = count_digits(g_DS18B20_temp);
+ snprintf(menu_row_str, 20, "%-*d%cC%*d",
+ temp_digits, g_DS18B20_temp, 0xDF,
+ 16-temp_digits-2, g_DS18B20_update_count);
+ display_write_string(menu_row_str);
+
+ display_set_cursor_pos(16-4, 1);
+ memset(menu_row_str, '\0', sizeof(menu_row_str));
+ snprintf(menu_row_str, 20, "%4d", g_DS18B20_DMA_error_count);
+ display_write_string(menu_row_str);
+ }
+
break;
default:
- p_task_menu_dta->tick = DEL_MEN_XX_MIN;
+ p_task_menu_dta->tick = G_TASK_MEN_UPDATE_RATE_INI;
p_task_menu_dta->state = ST_MEN_IDLE;
p_task_menu_dta->event = EV_MEN_ENT_IDLE;
p_task_menu_dta->event_flag = false;
diff --git a/firmware/app/src/task_temp_sensor.c b/firmware/app/src/task_temp_sensor.c
@@ -15,281 +15,15 @@
#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
+#include "ds18b20.h"
-// local global variables
-volatile bool b_DS18B20_Received_data;
-uint8_t g_DS18B20_Received_data_buffer[8];
-float g_DS18B20_temp;
+#define G_TASK_SEN_TICK_CNT_INI 0ul
-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`...");
@@ -314,8 +48,6 @@ void task_temp_sensor_update(void *parameters)
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)
{
@@ -328,5 +60,6 @@ void task_temp_sensor_update(void *parameters)
}
__asm("CPSIE i");
+ DS18B20_Update();
}
}
diff --git a/firmware/tdse-tf_3-02.ioc b/firmware/tdse-tf_3-02.ioc
@@ -12,7 +12,7 @@ Dma.USART1_RX.0.MemInc=DMA_MINC_ENABLE
Dma.USART1_RX.0.Mode=DMA_NORMAL
Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE
-Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW
+Dma.USART1_RX.0.Priority=DMA_PRIORITY_VERY_HIGH
Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.USART1_TX.1.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART1_TX.1.Instance=DMA1_Channel4
@@ -21,9 +21,10 @@ Dma.USART1_TX.1.MemInc=DMA_MINC_ENABLE
Dma.USART1_TX.1.Mode=DMA_NORMAL
Dma.USART1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE
-Dma.USART1_TX.1.Priority=DMA_PRIORITY_LOW
+Dma.USART1_TX.1.Priority=DMA_PRIORITY_VERY_HIGH
Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
File.Version=6
+GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
Mcu.CPN=STM32F103RBT6
Mcu.Family=STM32F1
@@ -40,18 +41,17 @@ Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PC14-OSC32_IN
Mcu.Pin10=PB10
Mcu.Pin11=PC7
-Mcu.Pin12=PA8
-Mcu.Pin13=PA9
-Mcu.Pin14=PA13
-Mcu.Pin15=PA14
-Mcu.Pin16=PB3
-Mcu.Pin17=PB4
-Mcu.Pin18=PB5
-Mcu.Pin19=PB6
+Mcu.Pin12=PA9
+Mcu.Pin13=PA13
+Mcu.Pin14=PA14
+Mcu.Pin15=PB3
+Mcu.Pin16=PB4
+Mcu.Pin17=PB5
+Mcu.Pin18=PB6
+Mcu.Pin19=PB8
Mcu.Pin2=PC15-OSC32_OUT
-Mcu.Pin20=PB8
-Mcu.Pin21=PB9
-Mcu.Pin22=VP_SYS_VS_Systick
+Mcu.Pin20=PB9
+Mcu.Pin21=VP_SYS_VS_Systick
Mcu.Pin3=PD0-OSC_IN
Mcu.Pin4=PD1-OSC_OUT
Mcu.Pin5=PA2
@@ -59,7 +59,7 @@ Mcu.Pin6=PA3
Mcu.Pin7=PA5
Mcu.Pin8=PA6
Mcu.Pin9=PA7
-Mcu.PinsNb=23
+Mcu.PinsNb=22
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103RBTx
@@ -123,10 +123,8 @@ PA7.GPIO_Label=D6
PA7.GPIO_PuPd=GPIO_PULLUP
PA7.Locked=true
PA7.Signal=GPIO_Output
-PA8.GPIOParameters=GPIO_Label
-PA8.GPIO_Label=BUZZER
-PA8.Locked=true
-PA8.Signal=GPIO_Input
+PA9.GPIOParameters=GPIO_Mode
+PA9.GPIO_Mode=GPIO_MODE_AF_OD
PA9.Mode=Half_duplex(single_wire_mode)
PA9.Signal=USART1_TX
PB10.GPIOParameters=GPIO_PuPd,GPIO_Label
@@ -245,8 +243,9 @@ RCC.VCOOutput2Freq_Value=4000000
SH.GPXTI13.0=GPIO_EXTI13
SH.GPXTI13.ConfNb=1
USART1.BaudRate=115200
-USART1.IPParameters=VirtualMode,BaudRate
+USART1.IPParameters=VirtualMode,BaudRate,WordLength
USART1.VirtualMode=VM_ASYNC
+USART1.WordLength=WORDLENGTH_8B
USART2.IPParameters=VirtualMode
USART2.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick