/******************************************************************************* * File Name : Uart.c * Description : * Created on : 2018Äê4ÔÂ24ÈÕ * Author : ¶Å¼ü *******************************************************************************/ /******************************************************************************* * Include Files * *******************************************************************************/ #include "string.h" #include "stm32l0xx_hal.h" #ifdef _USE_OS_ #include "cmsis_os.h" #endif #include "HIDO_Util.h" #include "HIDO_VLQueue.h" #include "HIDO_ArraryQueue.h" #include "HIDO_Lock.h" #include "HIDO_ATLite.h" #include "Uart.h" /******************************************************************************* * Macro * *******************************************************************************/ /******************************************************************************* * Type Definition * *******************************************************************************/ typedef struct { #ifdef _USE_OS_ osMutexId m_mutexLock; #endif E_UartID m_eUartID; E_UartTxMode m_eTxMode; E_UartRxMode m_eRxMode; UART_HandleTypeDef *m_pstUart; HIDO_UINT8 *m_pu8RxBuf; HIDO_UINT32 m_u32RxBufSize; HIDO_UINT8 *m_pu8RxLastPos; HIDO_UINT8 *m_pu8RxBufEnd; HIDO_ArraryQueueStruct m_stRxArraryQueue; HIDO_UINT8 *m_pu8TxBuf; HIDO_UINT32 m_u32TxBufSize; HIDO_UINT32 m_u32TxQueueMemberCnt; HIDO_VLQStruct m_stTxVLQueue; HIDO_UINT32 m_u32RxValue; HIDO_UINT32 m_u32Flag; FN_RxISR m_fnRxISR; } ST_UartInfo; /******************************************************************************* * Local Variable * *******************************************************************************/ static ST_UartInfo l_astUartInfo[UART_ID_LAST]; /******************************************************************************* * Local Function Declaration * *******************************************************************************/ /******************************************************************************* * Local Function * *******************************************************************************/ /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ static HIDO_VOID Uart_RXDMAEnable(E_UartID _eUartID) { /* µ±²úÉúÒç³ö´íÎóʱ£¬ÐèÒª½«Êý¾Ý¶Á¿Õ */ while(l_astUartInfo[_eUartID].m_pstUart->Instance->ISR & USART_ISR_ORE) { volatile HIDO_UINT16 u16Data = l_astUartInfo[_eUartID].m_pstUart->Instance->RDR; u16Data = u16Data + 0; } l_astUartInfo[_eUartID].m_pu8RxLastPos= l_astUartInfo[_eUartID].m_pu8RxBuf; l_astUartInfo[_eUartID].m_pu8RxBufEnd = l_astUartInfo[_eUartID].m_pu8RxBuf + l_astUartInfo[_eUartID].m_u32RxBufSize - 1; /* Æô¶¯DMA½ÓÊÕ */ HAL_UART_Receive_DMA(l_astUartInfo[_eUartID].m_pstUart, l_astUartInfo[_eUartID].m_pu8RxBuf, l_astUartInfo[_eUartID].m_u32RxBufSize); } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ static HIDO_VOID Uart_RXINTEnable(E_UartID _eUartID) { /* Æô¶¯INT½ÓÊÕ */ HAL_UART_Receive_IT(l_astUartInfo[_eUartID].m_pstUart, (HIDO_UINT8 *)&l_astUartInfo[_eUartID].m_u32RxValue, sizeof(HIDO_UINT8)); } /******************************************************************************* * Global Function * *******************************************************************************/ /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_GetHandle(E_UartID _eUartID, HIDO_VOID **_ppUart) { if((HIDO_NULL == _ppUart) || (_eUartID >= UART_ID_LAST)) { return HIDO_ERR; } *((UART_HandleTypeDef **)_ppUart) = l_astUartInfo[_eUartID].m_pstUart; return HIDO_OK; } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_Register(E_UartID _eUartID, HIDO_VOID *_pUart) { if((HIDO_NULL == _pUart) || (_eUartID >= UART_ID_LAST)) { return HIDO_ERR; } /* ³õʼ»¯²ÎÊý */ HIDO_UtilBzero(&l_astUartInfo[_eUartID], sizeof(ST_UartInfo)); l_astUartInfo[_eUartID].m_pstUart = (UART_HandleTypeDef *)_pUart; return HIDO_OK; } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_Init(E_UartID _eUartID, ST_UartInit *_pstInit) { if((HIDO_NULL == _pstInit) || (_eUartID >= UART_ID_LAST)) { return HIDO_ERR; } #ifdef _USE_OS_ l_astUartInfo[_eUartID].m_mutexLock = osMutexCreate(HIDO_NULL); #endif l_astUartInfo[_eUartID].m_eUartID = _eUartID; l_astUartInfo[_eUartID].m_eTxMode = _pstInit->m_eTxMode; l_astUartInfo[_eUartID].m_eRxMode = _pstInit->m_eRxMode; l_astUartInfo[_eUartID].m_pu8RxBuf = _pstInit->m_pu8RxBuf; l_astUartInfo[_eUartID].m_u32RxBufSize = _pstInit->m_u32RxBufSize; if(UART_RX_MODE_DMA == _pstInit->m_eRxMode) { l_astUartInfo[_eUartID].m_pu8RxLastPos= l_astUartInfo[_eUartID].m_pu8RxBuf; l_astUartInfo[_eUartID].m_pu8RxBufEnd = l_astUartInfo[_eUartID].m_pu8RxBuf + l_astUartInfo[_eUartID].m_u32RxBufSize - 1; } else if(UART_RX_MODE_INT == _pstInit->m_eRxMode) { HIDO_ArraryQueueInit( &l_astUartInfo[_eUartID].m_stRxArraryQueue, _pstInit->m_pu8RxBuf, _pstInit->m_u32RxBufSize, sizeof(HIDO_UINT8)); } l_astUartInfo[_eUartID].m_pu8TxBuf = _pstInit->m_pu8TxBuf; l_astUartInfo[_eUartID].m_u32TxBufSize = _pstInit->m_u32TxBufSize; l_astUartInfo[_eUartID].m_fnRxISR = _pstInit->m_fnRxISR; l_astUartInfo[_eUartID].m_u32TxQueueMemberCnt = _pstInit->m_u32TxQueueMemberCnt; if((UART_TX_MODE_DMA == _pstInit->m_eTxMode) || (UART_TX_MODE_INT == _pstInit->m_eTxMode)) { HIDO_VLQInit( &(l_astUartInfo[_eUartID].m_stTxVLQueue), _pstInit->m_pu8TxBuf, _pstInit->m_u32TxBufSize, _pstInit->m_u32TxQueueMemberCnt); } if (UART_RX_MODE_DMA == _pstInit->m_eRxMode) { /* Æô¶¯DMA½ÓÊÕ */ Uart_RXDMAEnable(_eUartID); } else if (UART_RX_MODE_INT == _pstInit->m_eRxMode || UART_RX_MODE_INT_ISR == _pstInit->m_eRxMode) { /* Æô¶¯INT½ÓÊÕ */ Uart_RXINTEnable(_eUartID); } return HIDO_OK; } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_ReInit(E_UartID _eUartID) { if(UART_RX_MODE_DMA == l_astUartInfo[_eUartID].m_eRxMode) { l_astUartInfo[_eUartID].m_pu8RxLastPos= l_astUartInfo[_eUartID].m_pu8RxBuf; l_astUartInfo[_eUartID].m_pu8RxBufEnd = l_astUartInfo[_eUartID].m_pu8RxBuf + l_astUartInfo[_eUartID].m_u32RxBufSize - 1; } else if(UART_RX_MODE_INT == l_astUartInfo[_eUartID].m_eRxMode) { HIDO_ArraryQueueInit( &l_astUartInfo[_eUartID].m_stRxArraryQueue, l_astUartInfo[_eUartID].m_pu8RxBuf, l_astUartInfo[_eUartID].m_u32RxBufSize, sizeof(HIDO_UINT8)); } if((UART_TX_MODE_DMA == l_astUartInfo[_eUartID].m_eTxMode) || (UART_TX_MODE_INT == l_astUartInfo[_eUartID].m_eTxMode)) { HIDO_VLQInit( &(l_astUartInfo[_eUartID].m_stTxVLQueue), l_astUartInfo[_eUartID].m_pu8TxBuf, l_astUartInfo[_eUartID].m_u32TxBufSize, l_astUartInfo[_eUartID].m_u32TxQueueMemberCnt); } if (UART_RX_MODE_DMA == l_astUartInfo[_eUartID].m_eRxMode) { /* Æô¶¯DMA½ÓÊÕ */ Uart_RXDMAEnable(_eUartID); } else if (UART_RX_MODE_INT == l_astUartInfo[_eUartID].m_eRxMode || UART_RX_MODE_INT_ISR == l_astUartInfo[_eUartID].m_eRxMode) { /* Æô¶¯INT½ÓÊÕ */ Uart_RXINTEnable(_eUartID); } return HIDO_OK; } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_ReConfigBaudRate(E_UartID _eUartID, HIDO_UINT32 _u32BaudRate) { HAL_UART_DeInit(l_astUartInfo[_eUartID].m_pstUart); l_astUartInfo[_eUartID].m_pstUart->Init.BaudRate = _u32BaudRate; if (HAL_UART_Init(l_astUartInfo[_eUartID].m_pstUart) != HAL_OK) { return HIDO_ERR; } Uart_ReInit(_eUartID); return HIDO_OK; } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_VOID Uart_RxErrorFromISR(HIDO_VOID *_pUart) { E_UartID eUartID = (E_UartID) 0; for (eUartID = (E_UartID) 0; eUartID < UART_ID_LAST; eUartID++) { if (l_astUartInfo[eUartID].m_pstUart == (UART_HandleTypeDef *) _pUart) { if (UART_RX_MODE_DMA == l_astUartInfo[eUartID].m_eRxMode) { /* Æô¶¯DMA½ÓÊÕ */ Uart_RXDMAEnable(eUartID); } else if (UART_RX_MODE_INT == l_astUartInfo[eUartID].m_eRxMode || UART_RX_MODE_INT_ISR == l_astUartInfo[eUartID].m_eRxMode) { /* Æô¶¯INT½ÓÊÕ */ Uart_RXINTEnable(eUartID); } break; } } } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_VOID Uart_TxOverFromISR(HIDO_VOID *_pUart) { E_UartID eUartID = (E_UartID) 0; for (eUartID = (E_UartID) 0; eUartID < UART_ID_LAST; eUartID++) { if (l_astUartInfo[eUartID].m_pstUart == _pUart) { if(UART_TX_MODE_DMA == l_astUartInfo[eUartID].m_eTxMode) { HIDO_VLQMemberStruct *pstMember = HIDO_NULL; pstMember = HIDO_VLQGetDequeueMember(&(l_astUartInfo[eUartID].m_stTxVLQueue)); HIDO_VLQDequeue(&(l_astUartInfo[eUartID].m_stTxVLQueue), pstMember); pstMember = HIDO_VLQGetDequeueMember(&(l_astUartInfo[eUartID].m_stTxVLQueue)); if (pstMember) { HAL_UART_Transmit_DMA(l_astUartInfo[eUartID].m_pstUart, pstMember->m_pDataAddr, pstMember->m_u32DataLen); } } else if(UART_TX_MODE_INT == l_astUartInfo[eUartID].m_eTxMode) { HIDO_VLQMemberStruct *pstMember = HIDO_NULL; pstMember = HIDO_VLQGetDequeueMember(&(l_astUartInfo[eUartID].m_stTxVLQueue)); HIDO_VLQDequeue(&(l_astUartInfo[eUartID].m_stTxVLQueue), pstMember); pstMember = HIDO_VLQGetDequeueMember(&(l_astUartInfo[eUartID].m_stTxVLQueue)); if (pstMember) { HAL_UART_Transmit_IT(l_astUartInfo[eUartID].m_pstUart, pstMember->m_pDataAddr, pstMember->m_u32DataLen); } } break; } } } /******************************************************************************* * Function Name : Uart_RxOverFromISR * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_VOID Uart_RxOverFromISR(HIDO_VOID *_pUart) { E_UartID eUartID = (E_UartID) 0; for (eUartID = (E_UartID) 0; eUartID < UART_ID_LAST; eUartID++) { if (l_astUartInfo[eUartID].m_pstUart == _pUart) { if(UART_RX_MODE_INT == l_astUartInfo[eUartID].m_eRxMode) { HIDO_UINT8 u8RecvByte = l_astUartInfo[eUartID].m_u32RxValue; HIDO_ArraryQueueIn(&l_astUartInfo[eUartID].m_stRxArraryQueue, &u8RecvByte); /* Æô¶¯INT½ÓÊÕ */ Uart_RXINTEnable(eUartID); } else if(UART_RX_MODE_INT_ISR == l_astUartInfo[eUartID].m_eRxMode) { if(l_astUartInfo[eUartID].m_fnRxISR != HIDO_NULL) { l_astUartInfo[eUartID].m_fnRxISR(l_astUartInfo[eUartID].m_u32RxValue); } /* Æô¶¯INT½ÓÊÕ */ Uart_RXINTEnable(eUartID); } break; } } } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_GetChar(E_UartID _eUartID, HIDO_UINT8 *_pu8Char) { HIDO_INT32 i32Result = HIDO_ERR; if (HIDO_NULL == _pu8Char || _eUartID >= UART_ID_LAST) { return HIDO_ERR; } #ifdef _USE_OS_ osMutexWait(l_astUartInfo[_eUartID].m_mutexLock, osWaitForever); #endif if (UART_RX_MODE_DMA == l_astUartInfo[_eUartID].m_eRxMode) { HIDO_UINT8 *pu8CurPos = HIDO_NULL; HIDO_UINT32 u32CurCnt = 0; pu8CurPos = l_astUartInfo[_eUartID].m_pu8RxBuf + l_astUartInfo[_eUartID].m_u32RxBufSize - l_astUartInfo[_eUartID].m_pstUart->hdmarx->Instance->CNDTR; u32CurCnt = (pu8CurPos + l_astUartInfo[_eUartID].m_u32RxBufSize - l_astUartInfo[_eUartID].m_pu8RxLastPos) % l_astUartInfo[_eUartID].m_u32RxBufSize; if ((u32CurCnt > 1) || (u32CurCnt == 1 && ((l_astUartInfo[_eUartID].m_pstUart->Instance->ISR & UART_FLAG_RXNE) == 0))) { *_pu8Char = *l_astUartInfo[_eUartID].m_pu8RxLastPos; if (l_astUartInfo[_eUartID].m_pu8RxLastPos == l_astUartInfo[_eUartID].m_pu8RxBufEnd) { l_astUartInfo[_eUartID].m_pu8RxLastPos = l_astUartInfo[_eUartID].m_pu8RxBuf; } else { l_astUartInfo[_eUartID].m_pu8RxLastPos++; } i32Result = HIDO_OK; } } else if (UART_RX_MODE_INT == l_astUartInfo[_eUartID].m_eRxMode) { if (HIDO_ArraryQueueOut(&l_astUartInfo[_eUartID].m_stRxArraryQueue, _pu8Char) == HIDO_OK) { i32Result = HIDO_OK; } } #ifdef _USE_OS_ osMutexRelease(l_astUartInfo[_eUartID].m_mutexLock); #endif return i32Result; } /******************************************************************************* * Function Name : * Description : * Input : * Output : * Return : * Author : ¶Å¼ü * Modified Date: : 2018Äê4ÔÂ24ÈÕ *******************************************************************************/ HIDO_INT32 Uart_Send(E_UartID _eUartID, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len) { HIDO_INT32 i32Result = HIDO_OK; if (HIDO_NULL == _pu8Data || 0 == _u32Len || _eUartID >= UART_ID_LAST) { return HIDO_ERR; } #ifdef _USE_OS_ osMutexWait(l_astUartInfo[_eUartID].m_mutexLock, osWaitForever); #endif if (UART_TX_MODE_DMA == l_astUartInfo[_eUartID].m_eTxMode) { HIDO_VLQMemberStruct *pstMember = HIDO_NULL; HIDO_Lock(); pstMember = HIDO_VLQGetEnqueueMember(&(l_astUartInfo[_eUartID].m_stTxVLQueue), _u32Len); if (HIDO_NULL == pstMember) { HIDO_UnLock(); i32Result = HIDO_ERR; } else { HIDO_VLQEnqueue(&(l_astUartInfo[_eUartID].m_stTxVLQueue), pstMember); memcpy(pstMember->m_pDataAddr, _pu8Data, _u32Len); pstMember = HIDO_VLQGetDequeueMember(&(l_astUartInfo[_eUartID].m_stTxVLQueue)); HIDO_UnLock(); HAL_UART_Transmit_DMA(l_astUartInfo[_eUartID].m_pstUart, pstMember->m_pDataAddr, pstMember->m_u32DataLen); } } else if (UART_TX_MODE_INT == l_astUartInfo[_eUartID].m_eTxMode) { HIDO_VLQMemberStruct *pstMember = HIDO_NULL; HIDO_Lock(); pstMember = HIDO_VLQGetEnqueueMember(&(l_astUartInfo[_eUartID].m_stTxVLQueue), _u32Len); if (HIDO_NULL == pstMember) { HIDO_UnLock(); i32Result = HIDO_ERR; } else { HIDO_VLQEnqueue(&(l_astUartInfo[_eUartID].m_stTxVLQueue), pstMember); memcpy(pstMember->m_pDataAddr, _pu8Data, _u32Len); pstMember = HIDO_VLQGetDequeueMember(&(l_astUartInfo[_eUartID].m_stTxVLQueue)); HIDO_UnLock(); HAL_UART_Transmit_IT(l_astUartInfo[_eUartID].m_pstUart, pstMember->m_pDataAddr, pstMember->m_u32DataLen); } } else if (UART_TX_MODE_POLL == l_astUartInfo[_eUartID].m_eTxMode) { HAL_UART_Transmit(l_astUartInfo[_eUartID].m_pstUart, _pu8Data, _u32Len, _u32Len * 100); } #ifdef _USE_OS_ osMutexRelease(l_astUartInfo[_eUartID].m_mutexLock); #endif return i32Result; }