/** * @file bsp_uart.c * @brief UART1 DMA + IDLE interrupt driver */ #include "bsp_uart.h" #include "bsp_cmd.h" #include "usart.h" #include /* 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); }