397 lines
9.6 KiB
C
397 lines
9.6 KiB
C
#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);
|
||
}
|
||
}
|
||
|