commit c56f4dc8cb9e975865ad9eafc330720bfb7f85eb
parent a7e832df87102107bc7285404c0af909db9ad576
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Sun, 12 Apr 2026 23:48:42 -0300
Usar DMA para comunicarse con el modulo remoto
Diffstat:
8 files changed, 189 insertions(+), 60 deletions(-)
diff --git a/firmware-nucleo/App/Inc/task_system_attribute.h b/firmware-nucleo/App/Inc/task_system_attribute.h
@@ -38,6 +38,7 @@ typedef enum task_system_ev {
EV_SYS_BTN_D_ACTIVE,
EV_SYS_REM_TEMP_CTRL_ENABLED,
+ EV_SYS_REM_TIMER_TOGGLE,
} task_system_ev_t;
typedef enum task_system_st {
diff --git a/firmware-nucleo/App/Src/task_remote.c b/firmware-nucleo/App/Src/task_remote.c
@@ -21,19 +21,14 @@
#define G_TASK_REMOTE_TICK_INI 0ul
#define G_TASK_REMOTE_TEMP_UPDATE_RATE_MS 1000ul
-uint32_t g_task_remote_tick;
-
// Public variables
//// this variable is incremented by 1 on every ms by HAL_SysTick
volatile uint32_t g_task_remote_tick_cnt;
queue_t task_remote_rx_queue;
uint8_t task_remote_uart_rx_byte;
+uint8_t task_remote_uart_tx_dma_buffer[G_TASK_REMOTE_QUEUE_LEN];
-queue_t task_remote_tx_queue;
-// uint8_t task_remote_uart_tx_byte;
-
-
-// Private variables definition
+// Private types declaration
typedef enum {
TX_DATA_STATUS_OK = 'A',
TX_DATA_MAIN_OUTPUT_TOGGLE_OK = 'B',
@@ -52,15 +47,20 @@ typedef enum {
RX_DATA_TEMP_SET = 'F'
} uart_rx_data_e;
+// Private variables definition
+uint32_t g_task_remote_tick;
+time_t system_time;
+static queue_t task_remote_tx_queue;
+
// Public functions declaration
void task_remote_queue_enqueue(queue_t *queue, uint8_t value);
// Private functions declaration
static void task_remote_rx_data_handler(void *parameters);
static void task_remote_queue_init(queue_t *queue);
-static uint8_t task_remote_queue_dequeue(queue_t *queue);
static uint8_t task_remote_queue_peek(queue_t *queue);
static uint8_t task_remote_queue_count(queue_t *queue);
+static uint8_t task_remote_queue_dequeue(queue_t *queue);
static uint8_t task_remote_queue_is_empty(queue_t *queue);
// Public funtions implementation
@@ -109,13 +109,17 @@ void task_remote_update(void *parameters)
task_remote_rx_data_handler(parameters);
}
- // TODO: Send bytes on tx_queue asynchronously
- while (!task_remote_queue_is_empty(&task_remote_tx_queue))
+ if(!task_remote_queue_is_empty(&task_remote_tx_queue))
{
- uint8_t byte = task_remote_queue_dequeue(&task_remote_tx_queue);
- HAL_UART_Transmit(&huart3, &byte, 1, 100);
+ uint8_t i;
+ for (i = 0; !task_remote_queue_is_empty(&task_remote_tx_queue); ++i)
+ {
+ task_remote_uart_tx_dma_buffer[i] = task_remote_queue_dequeue(&task_remote_tx_queue);
+ }
+ HAL_UART_Transmit_DMA(&huart3, task_remote_uart_tx_dma_buffer, i);
}
+ /*
if (0 == g_task_remote_tick)
{
g_task_remote_tick = G_TASK_REMOTE_TEMP_UPDATE_RATE_MS;
@@ -124,6 +128,7 @@ void task_remote_update(void *parameters)
{
g_task_remote_tick--;
}
+ */
}
}
@@ -137,9 +142,10 @@ void task_remote_queue_enqueue(queue_t *queue, uint8_t value)
static void task_remote_rx_data_handler(void *parameters)
{
- uint8_t query_type = task_remote_queue_peek(&task_remote_rx_queue);
shared_data_type *p_shared_data = (shared_data_type *)parameters;
+ uint8_t query_type = task_remote_queue_peek(&task_remote_rx_queue);
+
switch(query_type)
{
case RX_DATA_STATUS:
@@ -152,7 +158,7 @@ static void task_remote_rx_data_handler(void *parameters)
HAL_RTC_GetTime(&hrtc, &s_time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &s_date, RTC_FORMAT_BIN);
- struct tm t = {
+ struct tm time_tm = {
.tm_year = s_date.Year + 100,
.tm_mon = s_date.Month - 1,
.tm_mday = s_date.Date,
@@ -161,7 +167,7 @@ static void task_remote_rx_data_handler(void *parameters)
.tm_sec = s_time.Seconds,
};
- uint32_t system_time = (uint32_t)mktime(&t);
+ system_time = mktime(&time_tm);
// LSB first
task_remote_queue_enqueue(&task_remote_tx_queue,
@@ -179,10 +185,8 @@ static void task_remote_rx_data_handler(void *parameters)
task_remote_queue_enqueue(&task_remote_tx_queue, p_shared_data->timer->end_hour);
task_remote_queue_enqueue(&task_remote_tx_queue, p_shared_data->timer->end_min);
- task_remote_queue_enqueue(&task_remote_tx_queue,
- p_shared_data->temp_sensor);
- task_remote_queue_enqueue(&task_remote_tx_queue,
- p_shared_data->temp_set_point);
+ task_remote_queue_enqueue(&task_remote_tx_queue, p_shared_data->temp_sensor);
+ task_remote_queue_enqueue(&task_remote_tx_queue, p_shared_data->temp_set_point);
break;
@@ -196,10 +200,9 @@ static void task_remote_rx_data_handler(void *parameters)
break;
case RX_DATA_TIMER_TOGGLE:
- task_remote_queue_dequeue(&task_remote_rx_queue); // skip query type
-
- // TODO: Do something...
+ task_remote_queue_dequeue(&task_remote_rx_queue); // skip query type
+ task_system_interface_put_event(EV_SYS_REM_TIMER_TOGGLE);
task_remote_queue_enqueue(&task_remote_tx_queue,
TX_DATA_TIMER_TOGGLE_OK);
@@ -215,18 +218,12 @@ static void task_remote_rx_data_handler(void *parameters)
task_remote_queue_dequeue(&task_remote_rx_queue); // skip query type
- // TODO: Do something...
- // timer.from_hour = task_remote_queue_dequeue(&task_remote_rx_queue);
- // timer.from_minute = task_remote_queue_dequeue(&task_remote_rx_queue);
- // timer.to_hour = task_remote_queue_dequeue(&task_remote_rx_queue);
- // timer.to_minute = task_remote_queue_dequeue(&task_remote_rx_queue);
+ p_shared_data->timer->start_hour = task_remote_queue_dequeue(&task_remote_rx_queue);
+ p_shared_data->timer->start_min = task_remote_queue_dequeue(&task_remote_rx_queue);
+ p_shared_data->timer->end_hour = task_remote_queue_dequeue(&task_remote_rx_queue);
+ p_shared_data->timer->end_min = task_remote_queue_dequeue(&task_remote_rx_queue);
- task_remote_queue_dequeue(&task_remote_rx_queue);
- task_remote_queue_dequeue(&task_remote_rx_queue);
- task_remote_queue_dequeue(&task_remote_rx_queue);
- task_remote_queue_dequeue(&task_remote_rx_queue);
- task_remote_queue_enqueue(&task_remote_tx_queue,
- TX_DATA_TIMER_SET_VALUES_OK);
+ task_remote_queue_enqueue(&task_remote_tx_queue, TX_DATA_TIMER_SET_VALUES_OK);
break;
@@ -272,6 +269,16 @@ static void task_remote_queue_init(queue_t *queue)
}
}
+static uint8_t task_remote_queue_peek(queue_t *queue)
+{
+ return queue->data[queue->tail];
+}
+
+static uint8_t task_remote_queue_count(queue_t *queue)
+{
+ return queue->count;
+}
+
static uint8_t task_remote_queue_dequeue(queue_t *queue)
{
if(task_remote_queue_is_empty(queue))
@@ -283,17 +290,8 @@ static uint8_t task_remote_queue_dequeue(queue_t *queue)
return queue->data[queue->tail++];
}
-static uint8_t task_remote_queue_peek(queue_t *queue)
-{
- return queue->data[queue->tail];
-}
-
-static uint8_t task_remote_queue_count(queue_t *queue)
-{
- return queue->count;
-}
-
static uint8_t task_remote_queue_is_empty(queue_t *queue)
{
return (queue->count == 0);
}
+
diff --git a/firmware-nucleo/App/Src/task_system.c b/firmware-nucleo/App/Src/task_system.c
@@ -56,6 +56,7 @@ static task_system_timer_t task_system_timer = {
// Private function declaration
static void task_system_statechart(void *parameters);
+static void task_system_temp_ctrl_enable(void *parameters);
static void task_system_timer_update(void *parameters);
static void task_system_rtc_init(void);
static void task_system_rtc_increment_hour(void);
@@ -252,6 +253,26 @@ static void task_system_eeprom_write_param(void *parameters)
return;
}
+static void task_system_temp_ctrl_enable(void *parameters)
+{
+ shared_data_type *p_shared_data = (shared_data_type *)parameters;
+
+ p_shared_data->temp_ctrl_enabled = !p_shared_data->temp_ctrl_enabled;
+ task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
+ task_buzzer_interface_put_event(EV_BUZ_XX_LONG_BEEP, ID_BUZ_A);
+
+ if (true == p_shared_data->temp_ctrl_enabled)
+ {
+ task_leds_interface_put_event(EV_LED_XX_BLINK, ID_LED_A);
+ task_leds_interface_put_event(EV_LED_XX_BLINK, ID_LED_B);
+ }
+ else
+ {
+ task_leds_interface_put_event(EV_LED_XX_OFF, ID_LED_A);
+ task_leds_interface_put_event(EV_LED_XX_OFF, ID_LED_B);
+ }
+}
+
static void task_system_statechart(void *parameters)
{
task_system_dta_t *p_task_system_dta = &task_system_dta;
@@ -261,6 +282,26 @@ static void task_system_statechart(void *parameters)
{
p_task_system_dta->event_flag = true;
p_task_system_dta->event = task_system_interface_get_event();
+
+ // Events which are common to every state
+ switch (p_task_system_dta->event)
+ {
+
+ case EV_SYS_REM_TIMER_TOGGLE:
+ p_task_system_dta->event_flag = false;
+ p_shared_data->timer->enabled = !p_shared_data->timer->enabled;
+ task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
+ break;
+
+ case EV_SYS_REM_TEMP_CTRL_ENABLED:
+ p_task_system_dta->event_flag = false;
+ task_system_temp_ctrl_enable(parameters);
+ task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
+ break;
+
+ default:
+ break;
+ }
}
switch (p_task_system_dta->state)
@@ -275,23 +316,9 @@ static void task_system_statechart(void *parameters)
break;
case EV_SYS_BTN_C_ACTIVE:
- case EV_SYS_REM_TEMP_CTRL_ENABLED:
- p_shared_data->temp_ctrl_enabled = !p_shared_data->temp_ctrl_enabled;
- task_menu_interface_put_event(EV_MEN_DISPLAY_UPDATE);
- task_buzzer_interface_put_event(EV_BUZ_XX_LONG_BEEP, ID_BUZ_A);
-
- if (true == p_shared_data->temp_ctrl_enabled)
- {
- task_leds_interface_put_event(EV_LED_XX_BLINK, ID_LED_A);
- task_leds_interface_put_event(EV_LED_XX_BLINK, ID_LED_B);
- }
- else
- {
- task_leds_interface_put_event(EV_LED_XX_OFF, ID_LED_A);
- task_leds_interface_put_event(EV_LED_XX_OFF, ID_LED_B);
- }
-
+ task_system_temp_ctrl_enable(parameters);
break;
+
case EV_SYS_BTN_A_ACTIVE:
case EV_SYS_BTN_D_ACTIVE:
p_task_system_dta->state = ST_SYS_CLOCK_SET;
diff --git a/firmware-nucleo/Core/Inc/stm32f1xx_it.h b/firmware-nucleo/Core/Inc/stm32f1xx_it.h
@@ -55,6 +55,8 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
+void DMA1_Channel2_IRQHandler(void);
+void DMA1_Channel3_IRQHandler(void);
void DMA1_Channel4_IRQHandler(void);
void DMA1_Channel5_IRQHandler(void);
void DMA1_Channel6_IRQHandler(void);
diff --git a/firmware-nucleo/Core/Src/main.c b/firmware-nucleo/Core/Src/main.c
@@ -56,6 +56,8 @@ UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart1_rx;
+DMA_HandleTypeDef hdma_usart3_rx;
+DMA_HandleTypeDef hdma_usart3_tx;
/* USER CODE BEGIN PV */
@@ -499,6 +501,12 @@ static void MX_DMA_Init(void)
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
+ /* DMA1_Channel2_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
+ /* DMA1_Channel3_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
diff --git a/firmware-nucleo/Core/Src/stm32f1xx_hal_msp.c b/firmware-nucleo/Core/Src/stm32f1xx_hal_msp.c
@@ -29,6 +29,10 @@ extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart1_rx;
+extern DMA_HandleTypeDef hdma_usart3_rx;
+
+extern DMA_HandleTypeDef hdma_usart3_tx;
+
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
@@ -432,6 +436,39 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
__HAL_AFIO_REMAP_USART3_PARTIAL();
+ /* USART3 DMA Init */
+ /* USART3_RX Init */
+ hdma_usart3_rx.Instance = DMA1_Channel3;
+ hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ hdma_usart3_rx.Init.Mode = DMA_NORMAL;
+ hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
+ if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(huart,hdmarx,hdma_usart3_rx);
+
+ /* USART3_TX Init */
+ hdma_usart3_tx.Instance = DMA1_Channel2;
+ hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ hdma_usart3_tx.Init.Mode = DMA_NORMAL;
+ hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
+ if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(huart,hdmatx,hdma_usart3_tx);
+
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
@@ -487,6 +524,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
+ /* USART3 DMA DeInit */
+ HAL_DMA_DeInit(huart->hdmarx);
+ HAL_DMA_DeInit(huart->hdmatx);
+
/* USART3 interrupt DeInit */
HAL_NVIC_DisableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspDeInit 1 */
diff --git a/firmware-nucleo/Core/Src/stm32f1xx_it.c b/firmware-nucleo/Core/Src/stm32f1xx_it.c
@@ -59,6 +59,8 @@ extern DMA_HandleTypeDef hdma_i2c1_tx;
extern I2C_HandleTypeDef hi2c1;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart1_rx;
+extern DMA_HandleTypeDef hdma_usart3_rx;
+extern DMA_HandleTypeDef hdma_usart3_tx;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN EV */
@@ -206,6 +208,34 @@ void SysTick_Handler(void)
/******************************************************************************/
/**
+ * @brief This function handles DMA1 channel2 global interrupt.
+ */
+void DMA1_Channel2_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
+
+ /* USER CODE END DMA1_Channel2_IRQn 0 */
+ HAL_DMA_IRQHandler(&hdma_usart3_tx);
+ /* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
+
+ /* USER CODE END DMA1_Channel2_IRQn 1 */
+}
+
+/**
+ * @brief This function handles DMA1 channel3 global interrupt.
+ */
+void DMA1_Channel3_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Channel3_IRQn 0 */
+
+ /* USER CODE END DMA1_Channel3_IRQn 0 */
+ HAL_DMA_IRQHandler(&hdma_usart3_rx);
+ /* USER CODE BEGIN DMA1_Channel3_IRQn 1 */
+
+ /* USER CODE END DMA1_Channel3_IRQn 1 */
+}
+
+/**
* @brief This function handles DMA1 channel4 global interrupt.
*/
void DMA1_Channel4_IRQHandler(void)
diff --git a/firmware-nucleo/tdse-tf_3-02.ioc b/firmware-nucleo/tdse-tf_3-02.ioc
@@ -14,7 +14,9 @@ Dma.I2C1_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAl
Dma.Request0=I2C1_TX
Dma.Request1=USART1_TX
Dma.Request2=USART1_RX
-Dma.RequestsNb=3
+Dma.Request3=USART3_RX
+Dma.Request4=USART3_TX
+Dma.RequestsNb=5
Dma.USART1_RX.2.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.2.Instance=DMA1_Channel5
Dma.USART1_RX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
@@ -33,6 +35,24 @@ Dma.USART1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_TX.1.Priority=DMA_PRIORITY_HIGH
Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
+Dma.USART3_RX.3.Direction=DMA_PERIPH_TO_MEMORY
+Dma.USART3_RX.3.Instance=DMA1_Channel3
+Dma.USART3_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
+Dma.USART3_RX.3.MemInc=DMA_MINC_ENABLE
+Dma.USART3_RX.3.Mode=DMA_NORMAL
+Dma.USART3_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
+Dma.USART3_RX.3.PeriphInc=DMA_PINC_DISABLE
+Dma.USART3_RX.3.Priority=DMA_PRIORITY_LOW
+Dma.USART3_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
+Dma.USART3_TX.4.Direction=DMA_MEMORY_TO_PERIPH
+Dma.USART3_TX.4.Instance=DMA1_Channel2
+Dma.USART3_TX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
+Dma.USART3_TX.4.MemInc=DMA_MINC_ENABLE
+Dma.USART3_TX.4.Mode=DMA_NORMAL
+Dma.USART3_TX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
+Dma.USART3_TX.4.PeriphInc=DMA_PINC_DISABLE
+Dma.USART3_TX.4.Priority=DMA_PRIORITY_LOW
+Dma.USART3_TX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
@@ -86,6 +106,8 @@ Mcu.UserName=STM32F103RBTx
MxCube.Version=6.15.0
MxDb.Version=DB.6.0.150
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.DMA1_Channel2_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
+NVIC.DMA1_Channel3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Channel4_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Channel6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true