¶Ô±ÈÐÂÎļþ |
| | |
| | | /******************************************************************************* |
| | | * File Name : Uart.c |
| | | * Description : |
| | | * Created on : 2018å¹´4æ24æ¥ |
| | | * Author : æé® |
| | | *******************************************************************************/ |
| | | |
| | | /******************************************************************************* |
| | | * Include Files * |
| | | *******************************************************************************/ |
| | | #include "string.h" |
| | | #ifdef _USE_OS_ |
| | | #include "cmsis_os.h" |
| | | #endif |
| | | #include <stdio.h> |
| | | #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; |
| | | enum UART_DEV_T m_eUartPort; |
| | | |
| | | E_UartTxMode m_eTxMode; |
| | | E_UartRxMode m_eRxMode; |
| | | |
| | | 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_UINT8 m_u8RxValue; |
| | | HIDO_UINT32 m_u32Flag; |
| | | FN_RxISR m_fnRxISR; |
| | | } ST_UartInfo; |
| | | |
| | | /******************************************************************************* |
| | | * Local Variable * |
| | | *******************************************************************************/ |
| | | static ST_UartInfo l_astUartInfo[UART_ID_LAST]; |
| | | |
| | | /******************************************************************************* |
| | | * Local Function Declaration * |
| | | *******************************************************************************/ |
| | | static void uart_receive_callback(void *dev, uint32_t err_code); |
| | | |
| | | const static struct baud_map |
| | | { |
| | | enum UART_BAUD_T baud; |
| | | HIDO_UINT32 u32Baud; |
| | | } baud_map[] = |
| | | { |
| | | {BAUD_1200, 1200}, |
| | | {BAUD_2400, 2400}, |
| | | {BAUD_4800, 4800}, |
| | | {BAUD_9600, 9600}, |
| | | {BAUD_19200, 19200}, |
| | | {BAUD_38400, 38400}, |
| | | {BAUD_57600, 57600}, |
| | | {BAUD_115200, 115200}, |
| | | {BAUD_230400, 230400}, |
| | | {BAUD_460800, 460800}, |
| | | {BAUD_921600, 921600}, |
| | | {BAUD_1843200, 1843200}, |
| | | {BAUD_1000000, 1000000}, |
| | | {BAUD_2000000, 2000000}, |
| | | }; |
| | | |
| | | /******************************************************************************* |
| | | * Local Function * |
| | | *******************************************************************************/ |
| | | static enum UART_BAUD_T get_baud(HIDO_UINT32 u32Baud) |
| | | { |
| | | for(HIDO_UINT32 i = 0; i < HIDO_ARRARY_COUNT(baud_map); i++) |
| | | { |
| | | if(u32Baud == baud_map[i].u32Baud) |
| | | { |
| | | return baud_map[i].baud; |
| | | } |
| | | } |
| | | |
| | | return BAUD_115200; |
| | | } |
| | | |
| | | /******************************************************************************* |
| | | * Global Function * |
| | | *******************************************************************************/ |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : |
| | | * Description : |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : æé® |
| | | * Modified Date: : 2018å¹´4æ24æ¥ |
| | | *******************************************************************************/ |
| | | HIDO_INT32 Uart_Register(E_UartID _eUartID, enum UART_DEV_T _ePort) |
| | | { |
| | | /* åå§ååæ° */ |
| | | HIDO_UtilBzero(&l_astUartInfo[_eUartID], sizeof(ST_UartInfo)); |
| | | |
| | | l_astUartInfo[_eUartID].m_eUartPort = _ePort; |
| | | |
| | | 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 |
| | | |
| | | struct UART_CFG_T uart_cfg = |
| | | { |
| | | .parity = UART_PARITY_NONE, |
| | | .stop = UART_STOP_BITS_1, |
| | | .data = UART_DATA_BITS_8, |
| | | .flow = UART_FLOW_CONTROL_NONE, |
| | | .rx_level = UART_RXFIFO_CHAR_1, |
| | | .tx_level = UART_TXFIFO_EMPTY, |
| | | .baud = get_baud(_pstInit->m_u32BaudRate), |
| | | .dma_en = false, |
| | | .int_rx = true, |
| | | .int_tx = false, |
| | | }; |
| | | |
| | | 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; |
| | | |
| | | uart_open(l_astUartInfo[_eUartID].m_eUartPort, &uart_cfg); |
| | | |
| | | 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_INT == _pstInit->m_eRxMode) |
| | | { |
| | | uart_receive(l_astUartInfo[_eUartID].m_eUartPort, &l_astUartInfo[_eUartID].m_u8RxValue, 1, uart_receive_callback); |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | | uart_receive(l_astUartInfo[_eUartID].m_eUartPort, &l_astUartInfo[_eUartID].m_u8RxValue, 1, uart_receive_callback); |
| | | |
| | | 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) |
| | | { |
| | | uart_close(l_astUartInfo[_eUartID].m_eUartPort); |
| | | |
| | | struct UART_CFG_T uart_cfg = |
| | | { |
| | | .parity = UART_PARITY_NONE, |
| | | .stop = UART_STOP_BITS_1, |
| | | .data = UART_DATA_BITS_8, |
| | | .flow = UART_FLOW_CONTROL_NONE, |
| | | .rx_level = UART_RXFIFO_CHAR_1, |
| | | .tx_level = UART_TXFIFO_EMPTY, |
| | | .baud = get_baud(_u32BaudRate), |
| | | .dma_en = false, |
| | | .int_rx = true, |
| | | .int_tx = false, |
| | | }; |
| | | |
| | | uart_open(l_astUartInfo[_eUartID].m_eUartPort, &uart_cfg); |
| | | |
| | | return HIDO_OK; |
| | | } |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : |
| | | * Description : |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : æé® |
| | | * Modified Date: : 2018å¹´4æ24æ¥ |
| | | *******************************************************************************/ |
| | | static void uart_send_callback(void *dev, uint32_t err_code) |
| | | { |
| | | E_UartID eUartID = (E_UartID) 0; |
| | | |
| | | for (eUartID = (E_UartID) 0; eUartID < UART_ID_LAST; eUartID++) |
| | | { |
| | | if (l_astUartInfo[eUartID].m_eUartPort == *(enum UART_DEV_T *)dev) |
| | | { |
| | | 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) |
| | | { |
| | | uart_send(l_astUartInfo[eUartID].m_eUartPort, pstMember->m_pDataAddr, pstMember->m_u32DataLen, uart_send_callback); |
| | | } |
| | | } |
| | | 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) |
| | | { |
| | | uart_send(l_astUartInfo[eUartID].m_eUartPort, pstMember->m_pDataAddr, pstMember->m_u32DataLen, uart_send_callback); |
| | | } |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : Uart_RxOverFromISR |
| | | * Description : |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : æé® |
| | | * Modified Date: : 2018å¹´4æ24æ¥ |
| | | *******************************************************************************/ |
| | | static void uart_receive_callback(void *dev, uint32_t err_code) |
| | | { |
| | | E_UartID eUartID = UART_ID_4G; |
| | | |
| | | HIDO_UINT8 u8RecvByte = l_astUartInfo[eUartID].m_u8RxValue; |
| | | |
| | | HIDO_ArraryQueueIn(&l_astUartInfo[eUartID].m_stRxArraryQueue, &u8RecvByte); |
| | | |
| | | /* å¯å¨INTæ¥æ¶ */ |
| | | uart_receive(l_astUartInfo[eUartID].m_eUartPort, &l_astUartInfo[eUartID].m_u8RxValue, 1, uart_receive_callback); |
| | | } |
| | | |
| | | /******************************************************************************* |
| | | * 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_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(); |
| | | |
| | | uart_send(l_astUartInfo[_eUartID].m_eUartPort, pstMember->m_pDataAddr, pstMember->m_u32DataLen, uart_send_callback); |
| | | } |
| | | } |
| | | 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(); |
| | | |
| | | uart_send(l_astUartInfo[_eUartID].m_eUartPort, pstMember->m_pDataAddr, pstMember->m_u32DataLen, uart_send_callback); |
| | | } |
| | | } |
| | | else if (UART_TX_MODE_POLL == l_astUartInfo[_eUartID].m_eTxMode) |
| | | { |
| | | uart_send(l_astUartInfo[_eUartID].m_eUartPort, _pu8Data, _u32Len, NULL); |
| | | } |
| | | |
| | | #ifdef _USE_OS_ |
| | | osMutexRelease(l_astUartInfo[_eUartID].m_mutexLock); |
| | | #endif |
| | | |
| | | return i32Result; |
| | | } |
| | | HIDO_VOID HIDO_Lock(void) |
| | | { |
| | | int_lock(); |
| | | } |
| | | HIDO_VOID HIDO_UnLock(void) |
| | | { |
| | | uint32_t lock = int_lock(); |
| | | int_unlock(lock); |
| | | } |