可用的文件,全部
This commit is contained in:
131
Core/Bsp/bsp_uart.c
Normal file
131
Core/Bsp/bsp_uart.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
Reference in New Issue
Block a user