commit 55c191d2cbd2a50d62ab1395c157cd8c7ca179b9
parent 1aa759560465bbb9747fa33d377aebd9db64e768
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Mon, 30 Mar 2026 00:12:34 -0300
Agregar submenu para modificar la temperatura deseada
Diffstat:
10 files changed, 166 insertions(+), 82 deletions(-)
diff --git a/firmware/app/inc/app.h b/firmware/app/inc/app.h
@@ -12,14 +12,17 @@
extern "C" {
#endif
+#include <stdbool.h>
+
extern uint32_t g_app_runtime_us;
extern uint32_t g_app_WCET_us;
extern volatile uint32_t g_app_tick_cnt;
typedef struct {
- uint16_t temp_set_point; // Desired temp
- uint16_t temp_sensor; // Actual temp
- uint8_t temp_controller_pwm_dc; // Duty cycle of output [0, 100]
+ uint16_t temp_set_point; // Desired temp
+ int16_t temp_sensor; // Actual temp
+ uint8_t temp_ctrl_pwm_dc; // Duty cycle of output [0, 100]
+ bool temp_ctrl_enabled;
} shared_data_type;
extern void app_init(void);
diff --git a/firmware/app/inc/display_i2c.h b/firmware/app/inc/display_i2c.h
@@ -14,6 +14,8 @@
extern "C" {
#endif
+#define G_DISPLAY_CHAR_DEGREE_CODE 0xDF
+
void display_i2c_init();
void display_i2c_set_cursor_pos(uint8_t x, uint8_t y);
void display_i2c_write_string(const char *str);
diff --git a/firmware/app/inc/task_menu_attribute.h b/firmware/app/inc/task_menu_attribute.h
@@ -29,7 +29,8 @@ extern "C" {
/* Events to excite Task Menu */
typedef enum {
EV_MEN_ST_IDLE,
- EV_MEN_ST_CLOCK,
+ EV_MEN_ST_CLOCK_SET,
+ EV_MEN_ST_TEMP_SET,
EV_MEN_DISPLAY_UPDATE,
EV_MEN_INACTIVE_TIMEOUT
} task_menu_ev_t;
@@ -37,7 +38,8 @@ typedef enum {
/* State of Task Menu */
typedef enum {
ST_MEN_IDLE,
- ST_MEN_CLOCK
+ ST_MEN_CLOCK_SET,
+ ST_MEN_TEMP_SET
} task_menu_st_t;
typedef struct {
diff --git a/firmware/app/inc/task_system_attribute.h b/firmware/app/inc/task_system_attribute.h
@@ -40,7 +40,8 @@ typedef enum task_system_ev {
typedef enum task_system_st {
ST_SYS_IDLE,
- ST_SYS_CLOCK,
+ ST_SYS_CLOCK_SET,
+ ST_SYS_TEMP_SET,
} task_system_st_t;
typedef struct {
diff --git a/firmware/app/src/app.c b/firmware/app/src/app.c
@@ -34,21 +34,21 @@ typedef struct {
} task_cfg_t;
typedef struct {
- uint32_t WCET; // Task worst-case execution time (microseconds)
- uint32_t WCET_interval; // WCET in last `WCET_sample_ticks` sample time in ms
+ uint32_t WCET; // Task worst-case execution time in microseconds
+ uint32_t WCET_interval; // WCET in last `TASK_X_WCET_SAMPLE_TIME_MS` ms
} task_dta_t;
shared_data_type shared_data;
uint32_t g_app_runtime_us;
uint32_t g_app_WCET_us; // Worst case execution time historically
-uint32_t g_app_WCET_sample_ms; // Worst case execution time in sample
+uint32_t g_app_WCET_sample_us; // Worst case execution time in sample time
volatile uint32_t g_app_tick_cnt;
const task_cfg_t task_cfg_list[] = {
{task_system_init, task_system_update, &shared_data},
{task_buttons_init, task_buttons_update, NULL},
{task_leds_init, task_leds_update, NULL},
- {task_menu_init, task_menu_update, NULL},
+ {task_menu_init, task_menu_update, &shared_data},
{task_temp_ctrl_init, task_temp_ctrl_update, &shared_data},
{task_temp_sensor_init, task_temp_sensor_update, &shared_data},
};
@@ -69,11 +69,21 @@ void app_init(void)
task_dta_list[index].WCET = TASK_X_WCET_INI;
}
+ shared_data_type *p_shared_data = &shared_data;
+
+ p_shared_data->temp_set_point = 0;
+ p_shared_data->temp_sensor = -20;
+ p_shared_data->temp_ctrl_pwm_dc = 0;
+ p_shared_data->temp_ctrl_enabled = false;
+
__asm("CPSID i");
g_app_tick_cnt = G_APP_TICK_CNT_INI;
+ g_task_system_tick_cnt = G_APP_TICK_CNT_INI;
g_task_buttons_tick_cnt = G_APP_TICK_CNT_INI;
+ g_task_leds_tick_cnt = G_APP_TICK_CNT_INI;
+ g_task_menu_tick_cnt = G_APP_TICK_CNT_INI;
+ g_task_temp_ctrl_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;
__asm("CPSIE i");
LOGGER_INFO("Done initializing `app`");
@@ -102,14 +112,14 @@ void app_update(void)
{
cycle_counter_reset();
- if (0 == g_app_WCET_sample_ms)
+ if (0 == g_app_WCET_sample_us)
{
- g_app_WCET_sample_ms = TASK_X_WCET_SAMPLE_TIME_MS;
+ g_app_WCET_sample_us = TASK_X_WCET_SAMPLE_TIME_MS;
task_dta_list[index].WCET_interval = 0;
}
else
{
- g_app_WCET_sample_ms--;
+ g_app_WCET_sample_us--;
}
(*task_cfg_list[index].task_update)(task_cfg_list[index].parameters);
@@ -119,7 +129,7 @@ void app_update(void)
if (g_app_WCET_us < g_app_runtime_us) {
g_app_WCET_us = g_app_runtime_us;
- LOGGER_INFO("app worst execution time (WCET): %lu us", g_app_WCET_us);
+ LOGGER_INFO("App worst execution time (WCET): %lu us", g_app_WCET_us);
}
if (task_dta_list[index].WCET < cycle_counter_time_us)
diff --git a/firmware/app/src/display_i2c.c b/firmware/app/src/display_i2c.c
@@ -15,7 +15,7 @@
#define DISPLAY_I2C_ADDRESS 0x27
#define DISPLAY_ASYNC_QUEUE_LEN 256
-#define DISPLAY_ASYNC_CLEAR_DEL_MS 1ul
+#define DISPLAY_ASYNC_CLEAR_DEL_MS 2ul
#define DISPLAY_TICK_CNT_INI 0ul
#define DISPLAY_CMD_CLEAR_DISPLAY 0b00000001
@@ -89,41 +89,41 @@ void display_i2c_init(void)
display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
DISPLAY_CMD_FUNCTION_SET_8BITS);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
DISPLAY_CMD_FUNCTION_SET_8BITS);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
DISPLAY_CMD_FUNCTION_SET_4BITS);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
DISPLAY_CMD_FUNCTION_SET_4BITS |
DISPLAY_CMD_FUNCTION_SET_2LINES |
DISPLAY_CMD_FUNCTION_SET_5x8DOTS);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_DISPLAY_CONTROL |
DISPLAY_CMD_DISPLAY_CONTROL_DISPLAY_OFF |
DISPLAY_CMD_DISPLAY_CONTROL_CURSOR_OFF |
DISPLAY_CMD_DISPLAY_CONTROL_BLINK_OFF);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_CLEAR_DISPLAY);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_ENTRY_MODE_SET |
DISPLAY_CMD_ENTRY_MODE_SET_INCREMENT_CURSOR |
DISPLAY_CMD_ENTRY_MODE_SET_NO_SHIFT);
- HAL_Delay(1);
+ HAL_Delay(2);
display_i2c_send_cmd(DISPLAY_CMD_DISPLAY_CONTROL |
DISPLAY_CMD_DISPLAY_CONTROL_DISPLAY_ON |
DISPLAY_CMD_DISPLAY_CONTROL_CURSOR_OFF |
DISPLAY_CMD_DISPLAY_CONTROL_BLINK_OFF);
- HAL_Delay(1);
+ HAL_Delay(2);
b_display_i2c_dma_done = true;
g_display_i2c_tick = DISPLAY_TICK_CNT_INI;
diff --git a/firmware/app/src/task_menu.c b/firmware/app/src/task_menu.c
@@ -19,14 +19,14 @@
#define G_TASK_MEN_TICK_INI 0ul
#define G_TASK_MEN_TICK_CNT_INI 0ul
-#define G_TASK_MEN_ST_CLOCK_UPDATE_RATE_MS 1000ul
+#define G_TASK_MEN_DISPLAY_UPDATE_RATE_MS 1000ul
task_menu_dta_t task_menu_dta = {
G_TASK_MEN_TICK_INI, ST_MEN_IDLE, EV_MEN_ST_IDLE, false
};
// Private functions declaration
-void task_menu_statechart(void);
+void task_menu_statechart(void *parameters);
// Private variables
bool g_display_update = false;
@@ -79,7 +79,7 @@ void task_menu_update(void *parameters)
while (b_time_update_required)
{
display_i2c_async_tick();
- task_menu_statechart();
+ task_menu_statechart(parameters);
__asm("CPSID i");
if (G_TASK_MEN_TICK_CNT_INI < g_task_menu_tick_cnt)
@@ -107,16 +107,31 @@ void menu_set_state(task_menu_st_t new_state)
switch(new_state)
{
- case ST_MEN_CLOCK:
- p_task_menu_dta->tick = G_TASK_MEN_ST_CLOCK_UPDATE_RATE_MS;
+ case ST_MEN_CLOCK_SET:
+ p_task_menu_dta->tick = G_TASK_MEN_DISPLAY_UPDATE_RATE_MS;
break;
default: break;
}
}
-void task_menu_statechart(void)
+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 *parameters)
{
task_menu_dta_t *p_task_menu_dta;
+ shared_data_type *p_shared_data = (shared_data_type *)parameters;
char menu_row_str[16 + 4];
p_task_menu_dta = &task_menu_dta;
@@ -127,54 +142,73 @@ void task_menu_statechart(void)
p_task_menu_dta->event = task_menu_interface_get_event();
}
- 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))
+ if (true == p_task_menu_dta->event_flag)
{
p_task_menu_dta->event_flag = false;
- menu_set_state(ST_MEN_IDLE);
- }
+ switch (p_task_menu_dta->event)
+ {
+ case EV_MEN_ST_IDLE:
+ case EV_MEN_INACTIVE_TIMEOUT:
+ menu_set_state(ST_MEN_IDLE);
+ break;
- if ((true == p_task_menu_dta->event_flag)
- && (p_task_menu_dta->event == EV_MEN_DISPLAY_UPDATE))
- {
- p_task_menu_dta->event_flag = false;
- g_display_update = true;
+ case EV_MEN_DISPLAY_UPDATE:
+ g_display_update = true;
+ break;
+
+ case EV_MEN_ST_CLOCK_SET:
+ menu_set_state(ST_MEN_CLOCK_SET);
+ break;
+
+ case EV_MEN_ST_TEMP_SET:
+ menu_set_state(ST_MEN_TEMP_SET);
+ break;
+
+ default: break;
+ }
}
switch (p_task_menu_dta->state)
{
case ST_MEN_IDLE:
+ if (0 == p_task_menu_dta->tick)
+ {
+ g_display_update = true;
+ p_task_menu_dta->tick = G_TASK_MEN_DISPLAY_UPDATE_RATE_MS;
+ }
+ else
+ {
+ p_task_menu_dta->tick--;
+ }
+
if (g_display_update)
{
g_display_update = false;
display_i2c_async_clear();
memset(menu_row_str, '\0', sizeof(menu_row_str));
- snprintf(menu_row_str, 20, "Idle%10d%cC", g_ds18b20_temp, 0xDF);
+ snprintf(menu_row_str, 20, "Idle %3s",
+ p_shared_data->temp_ctrl_enabled ? "ON" : "");
display_i2c_async_write_string(menu_row_str);
- }
- if (true == p_task_menu_dta->event_flag)
- {
- p_task_menu_dta->event_flag = false;
- switch (p_task_menu_dta->event)
- {
- case EV_MEN_ST_CLOCK:
- menu_set_state(ST_MEN_CLOCK);
- break;
- default: break;
- }
+ display_i2c_async_set_cursor_pos(4, 1);
+ memset(menu_row_str, '\0', sizeof(menu_row_str));
+ snprintf(menu_row_str, 20, "%*d(%d)%cC",
+ (8 - count_digits(p_shared_data->temp_set_point)),
+ p_shared_data->temp_sensor,
+ p_shared_data->temp_set_point,
+ G_DISPLAY_CHAR_DEGREE_CODE);
+ display_i2c_async_write_string(menu_row_str);
}
break;
- case ST_MEN_CLOCK:
+ case ST_MEN_CLOCK_SET:
if (0 == p_task_menu_dta->tick)
{
g_display_update = true;
- p_task_menu_dta->tick = G_TASK_MEN_ST_CLOCK_UPDATE_RATE_MS;
+ p_task_menu_dta->tick = G_TASK_MEN_DISPLAY_UPDATE_RATE_MS;
}
else
{
@@ -185,25 +219,31 @@ void task_menu_statechart(void)
{
g_display_update = false;
display_i2c_async_clear();
- memset(menu_row_str, '\0', sizeof(menu_row_str));
+ display_i2c_async_write_string("Clock>");
+ display_i2c_async_set_cursor_pos(8, 0);
HAL_RTC_GetTime(&hrtc, &s_time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &s_date, RTC_FORMAT_BIN);
- sprintf(menu_row_str, "%02d:%02d:%02d",
+
+ memset(menu_row_str, '\0', sizeof(menu_row_str));
+ sprintf(menu_row_str, "%2d:%02d:%02d",
s_time.Hours, s_time.Minutes, s_time.Seconds);
display_i2c_async_write_string(menu_row_str);
}
- if (true == p_task_menu_dta->event_flag)
+ break;
+
+ case ST_MEN_TEMP_SET:
+
+ if (g_display_update)
{
- p_task_menu_dta->event_flag = false;
- switch (p_task_menu_dta->event)
- {
- case EV_MEN_ST_IDLE:
- menu_set_state(ST_MEN_IDLE);
- break;
- default: break;
- }
+ g_display_update = false;
+ display_i2c_async_clear();
+ display_i2c_async_write_string("Temp>");
+ memset(menu_row_str, '\0', sizeof(menu_row_str));
+ sprintf(menu_row_str, "%9d%cC",
+ p_shared_data->temp_set_point, G_DISPLAY_CHAR_DEGREE_CODE);
+ display_i2c_async_write_string(menu_row_str);
}
break;
diff --git a/firmware/app/src/task_system.c b/firmware/app/src/task_system.c
@@ -150,23 +150,23 @@ void task_system_statechart(void *parameters)
switch (p_task_system_dta->event)
{
case EV_SYS_BTN_C_ACTIVE:
- p_shared_data->temp_controller_pwm_dc =
- ((p_shared_data->temp_controller_pwm_dc + 5) % 100);
+ p_shared_data->temp_ctrl_enabled = !p_shared_data->temp_ctrl_enabled;
+ task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
break;
case EV_SYS_BTN_A_ACTIVE:
case EV_SYS_BTN_B_ACTIVE:
case EV_SYS_BTN_D_ACTIVE:
- p_task_system_dta->state = ST_SYS_CLOCK;
- task_menu_interface_put_event(EV_MEN_ST_CLOCK);
+ p_task_system_dta->state = ST_SYS_CLOCK_SET;
+ task_menu_interface_put_event(EV_MEN_ST_CLOCK_SET);
task_leds_interface_put_event(EV_LED_XX_BLINK, ID_LED_A);
task_leds_interface_put_event(EV_LED_XX_BLINK, ID_LED_B);
break;
default: break;
}
}
- break;
+ break;
- case ST_SYS_CLOCK:
+ case ST_SYS_CLOCK_SET:
if (true == p_task_system_dta->event_flag)
{
p_task_system_dta->event_flag = false;
@@ -174,8 +174,8 @@ void task_system_statechart(void *parameters)
{
case EV_SYS_BTN_A_ACTIVE:
case EV_SYS_BTN_D_ACTIVE:
- p_task_system_dta->state = ST_SYS_IDLE;
- task_menu_interface_put_event(EV_MEN_ST_IDLE);
+ p_task_system_dta->state = ST_SYS_TEMP_SET;
+ task_menu_interface_put_event(EV_MEN_ST_TEMP_SET);
task_leds_interface_put_event(EV_LED_XX_OFF, ID_LED_A);
task_leds_interface_put_event(EV_LED_XX_OFF, ID_LED_B);
break;
@@ -190,13 +190,43 @@ void task_system_statechart(void *parameters)
default: break;
}
}
- break;
+ break;
+
+ case ST_SYS_TEMP_SET:
+ if (true == p_task_system_dta->event_flag)
+ {
+ p_task_system_dta->event_flag = false;
+ switch (p_task_system_dta->event)
+ {
+ case EV_SYS_BTN_A_ACTIVE:
+ case EV_SYS_BTN_D_ACTIVE:
+ p_task_system_dta->state = ST_SYS_IDLE;
+ task_menu_interface_put_event(EV_MEN_ST_IDLE);
+ break;
+
+ case EV_SYS_BTN_B_ACTIVE:
+ p_shared_data->temp_set_point =
+ ((p_shared_data->temp_set_point - 5) % 85);
+ task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
+ break;
+
+ case EV_SYS_BTN_C_ACTIVE:
+ p_shared_data->temp_set_point =
+ ((p_shared_data->temp_set_point + 5) % 85);
+
+ task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
+ break;
+
+ default: break;
+ }
+ }
+ break;
default:
if (true == p_task_system_dta->event_flag)
{
p_task_system_dta->event_flag = false;
}
- break;
+ break;
}
}
diff --git a/firmware/app/src/task_temp_ctrl.c b/firmware/app/src/task_temp_ctrl.c
@@ -28,8 +28,7 @@ void task_temp_ctrl_init(void *parameters)
g_task_temp_ctrl_tick = G_TASK_CTRL_TICK_CNT_INI;
shared_data_type *p_shared_data = (shared_data_type *)parameters;
- p_shared_data->temp_controller_pwm_dc = 0;
- TIM1->CCR1 = p_shared_data->temp_controller_pwm_dc;
+ TIM1->CCR1 = p_shared_data->temp_ctrl_pwm_dc;
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
LOGGER_INFO("Done initializing `task_temp_ctrl`");
@@ -62,9 +61,9 @@ void task_temp_ctrl_update(void *parameters)
}
__asm("CPSIE i");
- if (p_shared_data->temp_controller_pwm_dc != TIM1->CCR1)
+ if (p_shared_data->temp_ctrl_pwm_dc != TIM1->CCR1)
{
- TIM1->CCR1 = p_shared_data->temp_controller_pwm_dc;
+ TIM1->CCR1 = p_shared_data->temp_ctrl_pwm_dc;
}
}
}
diff --git a/firmware/app/src/task_temp_sensor.c b/firmware/app/src/task_temp_sensor.c
@@ -27,9 +27,6 @@ volatile uint32_t g_task_temp_sensor_tick_cnt;
void task_temp_sensor_init(void *parameters)
{
- shared_data_type *p_shared_data = (shared_data_type *)parameters;
- p_shared_data->temp_sensor = 0;
-
LOGGER_INFO("Initializing `task_temp_sensor`...");
g_task_temp_sensor_tick = G_TASK_TEMP_SEN_TICK_INI;