Files
3d_contorl/Core/Bsp/bsp_uart.c
2026-03-21 01:49:41 +08:00

132 lines
2.8 KiB
C

/**
* @file bsp_uart.c
* @brief UART1 DMA + IDLE interrupt driver
*/
#include "bsp_uart.h"
#include "bsp_cmd.h"
#include "usart.h"
#include <string.h>
/* External DMA handle */
extern DMA_HandleTypeDef hdma_usart1_rx;
/* DMA receive buffer */
uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE];
/* IDLE interrupt sets this flag, main loop checks and processes */
static volatile uint16_t idle_rx_len = 0;
/**
* @brief Init UART1 for MQTT module with DMA
*/
void BSP_UART1_Init(void)
{
/* Start DMA reception */
HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE);
/* Enable IDLE line detection interrupt */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
}
/**
* @brief Send data via UART1 (blocking)
*/
uint16_t BSP_UART1_Send(uint8_t *data, uint16_t len)
{
return HAL_UART_Transmit(&huart1, data, len, 1000);
}
/**
* @brief Send string via UART1
*/
uint16_t BSP_UART1_SendString(const char *str)
{
return BSP_UART1_Send((uint8_t*)str, strlen(str));
}
/**
* @brief Get received data length in DMA buffer
*/
uint16_t BSP_UART1_GetRxLen(void)
{
return UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
}
/**
* @brief Read data from DMA rx buffer (non-destructive copy)
*/
uint16_t BSP_UART1_Read(uint8_t *buf, uint16_t len)
{
uint16_t head = UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
uint16_t cnt = 0;
while (cnt < len && cnt < head)
{
buf[cnt] = uart1_rx_buf[cnt];
cnt++;
}
return cnt;
}
/**
* @brief Clear rx buffer (restart DMA)
*/
void BSP_UART1_ClearRxBuf(void)
{
HAL_UART_AbortReceive(&huart1);
HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE);
}
/**
* @brief Check if data received
*/
bool BSP_UART1_IsDataReceived(void)
{
return (idle_rx_len > 0);
}
/**
* @brief Process received data (call in main loop)
* Copies data, parses JSON command, sends JSON response via UART1
*/
void BSP_UART1_Process(void)
{
if (idle_rx_len == 0)
return;
/* Copy length and clear flag */
uint16_t rx_len = idle_rx_len;
idle_rx_len = 0;
/* Copy data to local buffer so DMA restart won't overwrite */
uint8_t local_buf[UART1_RX_BUF_SIZE];
if (rx_len > sizeof(local_buf))
rx_len = sizeof(local_buf);
memcpy(local_buf, uart1_rx_buf, rx_len);
/* Process JSON command */
BSP_Cmd_ProcessJSON(local_buf, rx_len);
/* Restart DMA for next frame */
BSP_UART1_ClearRxBuf();
}
/**
* @brief Called from USART1 IDLE interrupt - saves length and restarts DMA
*/
void BSP_UART1_IDLE_IRQHandler(void)
{
uint16_t rx_len = UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
if (rx_len > 0)
{
idle_rx_len = rx_len;
}
/* Restart DMA immediately */
HAL_UART_AbortReceive(&huart1);
HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE);
}