Files
Leakage-Control/calib_board/usr/bsp/bsp_Uart.c
2026-01-22 19:24:33 +08:00

397 lines
9.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_Uart.h"
#include "string.h"
//#define RS485_RX HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_RESET)
#define RS485_RX HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_SET)
#define RS485_TX HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_SET)
/*»º³åÊÕ·¢Çø*/
#define RX_TEMP_BUFF_NUM (3000U)
u8 Rx_Temp_Buff[RX_TEMP_BUFF_NUM];
#define UART1_TX_LEN (3000U)
#define UART1_RX_LEN (3000U)
#define UART2_TX_LEN (3000U)
#define UART2_RX_LEN (3000U)
#define UART4_TX_LEN (3000U)
#define UART4_RX_LEN (3000U)
u8 Uart1_TX_Buff[UART1_TX_LEN];
u8 Uart1_Rx_Buff[UART1_RX_LEN];
u8 Uart2_TX_Buff[UART2_TX_LEN];
u8 Uart2_Rx_Buff[UART2_RX_LEN];
u8 Uart4_TX_Buff[UART4_TX_LEN];
u8 Uart4_Rx_Buff[UART4_RX_LEN];
static void bsp_Uart_Init(bsp_Uart_t *p_Uart);
static void bsp_Uart_Send(bsp_Uart_t *p_Uart,u8 *pData, u16 Len);
static void bsp_Uart_Rx_IdleInt(bsp_Uart_t *p_Uart);
static void bsp_Uart_Rx_TimeIncrement(bsp_Uart_t *p_Uart,u16 Time);
static void bsp_Uart_Rx_Task(bsp_Uart_t *p_Uart);
static void bsp_Uart_Rx_TimeStart(bsp_Uart_t *p_Uart);
static void bsp_Uart_Tx_DMA_TCInt(bsp_Uart_t *p_Uart);
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart4;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_uart4_rx;
extern DMA_HandleTypeDef hdma_uart4_tx;
bsp_Uart_t COM_Uart1 =
{
.RxQueue = queue(u8,UART1_RX_LEN),
.Uart =&huart1,
.Tx_DMA = &hdma_usart1_tx,
.Rx_DMA = &hdma_usart1_rx,
.Tx_DMA_Len = UART1_TX_LEN,
.Rx_DMA_Len = UART1_RX_LEN,
.Tx_Addr = &Uart1_TX_Buff[0],
.Rx_Addr = &Uart1_Rx_Buff[0],
.Tx_DMA_CompleteFlag = 1,
.Rx_TimeOver = 0,
.relay.uart = NULL,
.Init = bsp_Uart_Init,
.Send = bsp_Uart_Send,
.Tx_DMA_TCInt = bsp_Uart_Tx_DMA_TCInt,
.Rx_IdleInt = bsp_Uart_Rx_IdleInt,
.Rx_TimeIncrementInt = bsp_Uart_Rx_TimeIncrement,
.Rx_DataAnalysis = NULL,
.Rx_Task = bsp_Uart_Rx_Task,
};
bsp_Uart_t COM_Uart2 =
{
.RxQueue = queue(u8,UART2_RX_LEN),
.Uart =&huart2,
.Tx_DMA = &hdma_usart2_tx,
.Rx_DMA = &hdma_usart2_rx,
.Tx_DMA_Len = UART2_TX_LEN,
.Rx_DMA_Len = UART2_RX_LEN,
.Tx_Addr = &Uart2_TX_Buff[0],
.Rx_Addr = &Uart2_Rx_Buff[0],
.Tx_DMA_CompleteFlag = 1,
.Rx_TimeOver = 0,
.relay.uart = &COM_Uart4,
.Init = bsp_Uart_Init,
.Send = bsp_Uart_Send,
.Tx_DMA_TCInt = bsp_Uart_Tx_DMA_TCInt,
.Rx_IdleInt = bsp_Uart_Rx_IdleInt,
.Rx_TimeIncrementInt = bsp_Uart_Rx_TimeIncrement,
.Rx_DataAnalysis = NULL,
.Rx_Task = bsp_Uart_Rx_Task,
};
bsp_Uart_t COM_Uart4 =
{
.RxQueue = queue(u8,UART4_RX_LEN),
.Uart =&huart4,
.Tx_DMA = &hdma_uart4_tx,
.Rx_DMA = &hdma_uart4_rx,
.Tx_DMA_Len = UART4_TX_LEN,
.Rx_DMA_Len = UART4_RX_LEN,
.Tx_Addr = &Uart4_TX_Buff[0],
.Rx_Addr = &Uart4_Rx_Buff[0],
.Tx_DMA_CompleteFlag = 1,
.Rx_TimeOver = 0,
.relay.uart = NULL,
.Init = bsp_Uart_Init,
.Send = bsp_Uart_Send,
.Tx_DMA_TCInt = bsp_Uart_Tx_DMA_TCInt,
.Rx_IdleInt = bsp_Uart_Rx_IdleInt,
.Rx_TimeIncrementInt = bsp_Uart_Rx_TimeIncrement,
.Rx_DataAnalysis = NULL,
.Rx_Task = bsp_Uart_Rx_Task,
};
/* ³õʼ»¯º¯Êý */
static void bsp_Uart_Init(bsp_Uart_t *p_Uart)
{
/*ÅäÖÃÊý¾Ý½âÎöº¯Êý*/
//p_Uart->Rx_DataAnalysis = NULL;
/* ÆôÓÿÕÏÐÖÐ¶Ï */
__HAL_UART_ENABLE_IT(p_Uart->Uart, UART_IT_IDLE);
/* Æô¶¯DMA½ÓÊÕ */
//HAL_UART_Receive_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
/* ÖØÐÂÆô¶¯½ÓÊÕ */
HAL_UARTEx_ReceiveToIdle_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
}
static void bsp_Uart_DMASend(bsp_Uart_t *p_Uart,u8 *pData, u16 Len)
{
u32 tickstart,tick;
p_Uart->Tx_DMA_CompleteFlag = 0;
if(p_Uart->Tx_DMA_Len < Len)
Len = p_Uart->Tx_DMA_Len;
memcpy(p_Uart->Tx_Addr, pData, Len); /*¿½±´Êý¾Ýµ½·¢ËÍ»º³å*/
// /*×èÈûʽ·¢ËÍ£¬·Ç×èÈûʽ·¢ËÍ£¬»áµ¼ÖÂÊÕ·¢Êý¾ÝʱÕýºÃÇл»Í¨µÀµÄÇé¿ö*/
// HAL_UART_Transmit(p_Uart->Uart,p_Uart->Tx_Addr,Len,500);
HAL_UART_Transmit_DMA(p_Uart->Uart,p_Uart->Tx_Addr,Len);
tickstart = HAL_GetTick();
while( !p_Uart->Tx_DMA_CompleteFlag)
{
tick = HAL_GetTick();
if((tick - tickstart) > 200) // 1000ms ³¬Ê±
{
p_Uart->Tx_DMA_CompleteFlag = 1;
break;
}
}
}
/*´óÊý¾ÝÁ¿·¢ËÍ*/
static void bsp_Uart_Send(bsp_Uart_t *p_Uart,u8 *pData, u16 Len)
{
u16 i,SendNum;
if(p_Uart == &COM_Uart4)
RS485_TX;
SendNum = Len / p_Uart->Tx_DMA_Len;
for(i=0;i<SendNum;i++)
{
bsp_Uart_DMASend(p_Uart,&pData[p_Uart->Tx_DMA_Len * i], p_Uart->Tx_DMA_Len);
}
/*·¢ËÍÊ£ÓàÊý¾Ý*/
Len -= p_Uart->Tx_DMA_Len * i;
if(0 == Len)
{
return ;
}
else
{
bsp_Uart_DMASend(p_Uart,&pData[p_Uart->Tx_DMA_Len * i],Len);
}
}
static void bsp_Uart_Tx_DMA_TCInt(bsp_Uart_t *p_Uart)
{
p_Uart->Tx_DMA_CompleteFlag = 1;
}
/*¿ÕÏнÓÊÕÖжÏ*/
static void bsp_Uart_Rx_IdleInt(bsp_Uart_t *p_Uart)
{
u16 Rx_Length, i;
/*Í£Ö¹½ÓÊÕ*/
HAL_UART_DMAStop(p_Uart->Uart);
/* ¼ÆËã½ÓÊÕµ½µÄÊý¾Ý³¤¶È */
Rx_Length = p_Uart->Rx_DMA_Len - __HAL_DMA_GET_COUNTER(p_Uart->Rx_DMA);
/* Èç¹û³¤¶ÈΪ0£¬Ö±½Ó·µ»Ø */
if (Rx_Length == 0) {
return;
}
/* Èë¶Ó */
for (i = 0; i < Rx_Length; i++)
{
queue_push_back(p_Uart->RxQueue, (void *)&p_Uart->Rx_Addr[i]);
}
/* ¿ªÊ¼¼ÆÊý */
bsp_Uart_Rx_TimeStart(p_Uart);
// HAL_UART_Receive_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
HAL_UARTEx_ReceiveToIdle_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
}
/*ÖжϼÆÊý*/
static void bsp_Uart_Rx_TimeIncrement(bsp_Uart_t *p_Uart,u16 Time)
{
/*¿ªÊ¼¼ÆÊý*/
if(1 == p_Uart->Rx_StartFlag)
{
p_Uart->Rx_TimeCount += Time;
}
}
/*¿ªÊ¼¼ÆÊý*/
static void bsp_Uart_Rx_TimeStart(bsp_Uart_t *p_Uart)
{
p_Uart->Rx_StartFlag = 1;
p_Uart->Rx_TimeCount = 0;
}
/*Í£Ö¹¼ÆÊý*/
static void bsp_Uart_Rx_TimeStop(bsp_Uart_t *p_Uart)
{
p_Uart->Rx_StartFlag = 0;
p_Uart->Rx_TimeCount = 0;
}
static void bsp_Uart_Rx_Task(bsp_Uart_t *p_Uart)
{
/*³¬Ê±¼ÆÊýÍê³É£¬½ÓÊÕµ½Ò»Ö¡Êý¾Ý*/
if(p_Uart->Rx_TimeOver < p_Uart->Rx_TimeCount)
{
p_Uart->Rx_Len = queue_size(p_Uart->RxQueue);
/*Í£Ö¹¼ÆÊý*/
bsp_Uart_Rx_TimeStop(p_Uart);
if(p_Uart->Rx_Len <= p_Uart->Rx_DMA_Len && (0 != p_Uart->Rx_Len))
{
if(RX_TEMP_BUFF_NUM < p_Uart->Rx_Len)
{
queue_clear(p_Uart->RxQueue);
}
else
{
for(u16 i = 0;i < p_Uart->Rx_Len;i++)
{
queue_pop(p_Uart->RxQueue,&Rx_Temp_Buff[i]);
}
if(NULL != p_Uart->Rx_DataAnalysis)
{
p_Uart->Rx_DataAnalysis(Rx_Temp_Buff,p_Uart->Rx_Len,p_Uart); /*½âÎöÊý¾Ý*/
}
// p_Uart->Send(p_Uart,Rx_Temp_Buff,p_Uart->Rx_Len);
}
}
}
}
// ´íÎ󻨵÷º¯ÊýÖд¦ÀíORE
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
bsp_Uart_t *p_Uart = NULL;
if (huart->Instance == USART1)
{
p_Uart = &COM_Uart1;
}
else if (huart->Instance == USART2)
{
p_Uart = &COM_Uart2;
}
else if (huart->Instance == UART4)
{
p_Uart = &COM_Uart4;
}
// ¼ì²é¾ßÌå´íÎóÀàÐÍ
if(huart->ErrorCode & HAL_UART_ERROR_NE)
{
// ´¦ÀíÔëÉù´íÎó
__HAL_UART_CLEAR_NEFLAG(huart);
}
if(huart->ErrorCode & HAL_UART_ERROR_FE)
{
// ´¦ÀíÖ¡´íÎó
__HAL_UART_CLEAR_FEFLAG(huart);
}
// ÆäËû´íÎó´¦Àí...
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET)
{
__HAL_UART_CLEAR_OREFLAG(huart); // Çå³ýORE±êÖ¾
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET)
{
__HAL_UART_CLEAR_FEFLAG(huart); // Çå³ýORE±êÖ¾
}
//
if(p_Uart != NULL)
{
// HAL_UART_DeInit(huart);
// HAL_UART_Init(huart);
// HAL_UART_DMAStop(p_Uart->Uart);
HAL_UARTEx_ReceiveToIdle_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
}
}
// ʵÏÖ¿ÕÏÐÖжϻص÷
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
bsp_Uart_Rx_IdleInt(&COM_Uart1);
}
else if (huart->Instance == USART2)
{
bsp_Uart_Rx_IdleInt(&COM_Uart2);
}
else if (huart->Instance == UART4)
{
bsp_Uart_Rx_IdleInt(&COM_Uart4);
}
}
/* ´®¿Ú½ÓÊÕÍê³É»Øµ÷º¯Êý - ´¦Àí¿ÕÏÐÖÐ¶Ï */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
// {
// __HAL_UART_CLEAR_IDLEFLAG(huart);
// if (huart->Instance == USART1)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart1);
// }
// else if (huart->Instance == USART2)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart2);
// }
// else if (huart->Instance == UART4)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart4);
// }
// }
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
COM_Uart1.Tx_DMA_TCInt(&COM_Uart1);
}
else if (huart->Instance == USART2)
{
COM_Uart2.Tx_DMA_TCInt(&COM_Uart2);
}
else if (huart->Instance == UART4)
{
RS485_RX;
COM_Uart4.Tx_DMA_TCInt(&COM_Uart4);
}
}