1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126 |
- /**
- * @file hv_drv_Uart.c
- * @brief uart driver layer file.
- *
- * @author HiView SoC Software Team
- * @version 1.0.0
- * @date 2023-06-14
- * @copyright Copyright(c),2023-6, Hiview Software. All rights reserved.
- * </table>
- */
- #include "hv_vos_Comm.h"
- #include "hv_cal_Dma.h"
- #include "hv_chip_Config.h"
- #include "hv_comm_Define.h"
- #include "hv_drv_Uart.h"
- #include "hv_comm_Assert.h"
- #define UART_LCR_MASK 0xE0
- #define UART_PARITY_MASK 0x03
- #define UART_PARITY_EVEN_MASK 0x18
- #define UART_PARITY_ODD_MASK 0x08
- #define UART_PARITY_NONE_MASK 0x00
- #define UART_DATALEN_MASK 0x03
- #define UART_STOP_POS 2U
- #define UART_STOP_MASK (0x01UL << UART_STOP_POS)
- /*!< Received Data Available */
- #define UART_RECV_INT_EN 0x01
- /*!< Transmit Holding Register Empty Interrupt */
- #define UART_TRANEMPTY_INT_EN 0x02
- /*!< Receiver Line Status Interrupt */
- #define UART_RECVSTATUS_INT_EN 0x04
- /*!< Modem Status */
- #define UART_MODEMSTATUS_INT_EN 0x08
- #define UART_FIFO_MASK 0x06
- /* Interrupt Type */
- #define UART_INT_MODEM_STATUS 0x00
- #define UART_INT_NO_INTERRUPT_PENDING 0x01
- #define UART_INT_THR_EMPTY 0x02
- #define UART_INT_RECEIVED_DATA_AVAILABLE 0x04
- #define UART_INT_RECEIVER_LINE_STATUS 0x06
- #define UART_INT_BUSY_DETECT 0x07
- #define UART_INT_CHARACTER_TIMEOUT 0x0c
- struct _UartSelf
- {
- UartInitParam stInitParam;
- UINT32 uiBaseOffset;
- /*!< Pointer to UART Tx transfer Buffer */
- const UCHAR8 *pucTxBuffPtr;
- /*!< UART Tx Transfer size */
- USHORT16 usTxXferSize;
- /*!< UART Tx Transfer Counter */
- USHORT16 usTxXferCount;
- /*!< Pointer to UART Rx transfer Buffer */
- UCHAR8 *pucRxBuffPtr;
- /*!< UART Rx Transfer size */
- USHORT16 usRxXferSize;
- /*!< UART Rx Transfer Counter */
- USHORT16 usRxXferCount;
- /*!< UART Tx DMA Handle parameters */
- DmaSelf *pstHdmaTx;
- /*!< UART Rx DMA Handle parameters */
- DmaSelf *pstHdmaRx;
- /*!< UART communication state */
- UartStateType enState;
- /*!< UART Error code */
- UINT32 errorCode;
- /*!< UART Binary Semaphore */
- HV_VOS_SEMAPHORE_S* pstUartBinarySema;
- };
- static UartSelf s_astUart[UART_PORT_MAX];
- #define UART_BUFF_SIZE 32
- static UCHAR8 g_aucUartRxBuf[UART_BUFF_SIZE] = {0};
- static UCHAR8 g_ucUartBufIndex = 0;
- static Status Uart_IntReceive(UartSelf *pstSelf)
- {
- UINT32 uiValue = 0;
- rs_cpu_sys_uart0_dlh_ier ier = {0};
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
- while (uiValue & 0x1)
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL);
- if (pstSelf->stInitParam.bNewInterface == HV_TRUE)
- {
- g_aucUartRxBuf[(g_ucUartBufIndex++)%UART_BUFF_SIZE] = uiValue;
- }
- else
- {
- *pstSelf->pucRxBuffPtr++ = (UCHAR8)uiValue;
- if (--pstSelf->usRxXferCount == 0)
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
- /* Disable Received Data Available Interrupt */
- ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER & ~UART_RECV_INT_EN;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- if (pstSelf->stInitParam.fCallback)
- {
- pstSelf->stInitParam.fCallback(UART_INT_RX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
- }
- return HV_SUCCESS;
- }
- }
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
- }
- if (pstSelf->stInitParam.bNewInterface == HV_TRUE)
- {
- pstSelf->stInitParam.fCallback(UART_INT_RX_COMPLETE, g_aucUartRxBuf, g_ucUartBufIndex);
- g_ucUartBufIndex = 0;
- }
- return HV_SUCCESS;
- }
- static Status Uart_IntTransmit(UartSelf *pstSelf)
- {
- UINT32 uiValue = 0;
- rs_cpu_sys_uart0_dlh_ier ier = {0};
- if (pstSelf->usTxXferCount == 0)
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
- /* Disable Transmit Holding Register Empty Interrupt */
- ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER & ~UART_TRANEMPTY_INT_EN;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- if (pstSelf->stInitParam.fCallback)
- {
- pstSelf->stInitParam.fCallback(UART_INT_TX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
- }
- return HV_SUCCESS;
- }
- do
- {
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, *pstSelf->pucTxBuffPtr);
- pstSelf->pucTxBuffPtr += 1;
- if (--pstSelf->usTxXferCount == 0)
- {
- return HV_SUCCESS;
- }
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_USR);
- uiValue = cpu_sys_uart0_usr(uiValue)->reg_TFNF;
- }
- while (pstSelf->stInitParam.bFifoEnable && (uiValue & 0x1));
- return HV_SUCCESS;
- }
- static Status Uart_DmaRxCpltCallback(DmaSelf* pstArg)
- {
- UartSelf *pstSelf = (UartSelf *)Hv_Cal_Dma_GetParent(pstArg);
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- if (pstSelf->stInitParam.fCallback)
- {
- pstSelf->stInitParam.fCallback(UART_DMA_RX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
- }
- return HV_SUCCESS;
- }
- static Status Uart_DmaTxCpltCallback(DmaSelf* pstArg)
- {
- UartSelf *pstSelf = (UartSelf *)Hv_Cal_Dma_GetParent(pstArg);
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- if (pstSelf->stInitParam.fCallback)
- {
- pstSelf->stInitParam.fCallback(UART_DMA_TX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
- }
- return HV_SUCCESS;
- }
- static HV_VOS_ISR_RESULT_E Uart_IrqHandler(UINT32 uiIrqNum, void *pArg)
- {
- UartSelf *pstSelf = (UartSelf *)pArg;
- UINT32 uiValue = 0;
- HV_UNUSED(uiIrqNum);
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR);
- switch (uiValue & 0xf)
- {
- case UART_INT_MODEM_STATUS:
- {
- break;
- }
- case UART_INT_NO_INTERRUPT_PENDING:
- {
- break;
- }
- case UART_INT_THR_EMPTY:
- {
- Uart_IntTransmit(pstSelf);
- break;
- }
- case UART_INT_RECEIVED_DATA_AVAILABLE:
- {
- Uart_IntReceive(pstSelf);
- Hv_Vos_ReleaseSemaphoreFromISR(pstSelf->pstUartBinarySema);
- break;
- }
- case UART_INT_RECEIVER_LINE_STATUS:
- {
- pstSelf->errorCode = UART_ERROR_NONE;
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- if (cpu_sys_uart0_lsr(uiValue)->reg_BI & 0x1)
- {
- pstSelf->errorCode |= UART_ERROR_BI;
- }
- if (cpu_sys_uart0_lsr(uiValue)->reg_FE & 0x1)
- {
- pstSelf->errorCode |= UART_ERROR_FE;
- }
- if (cpu_sys_uart0_lsr(uiValue)->reg_PE & 0x1)
- {
- pstSelf->errorCode |= UART_ERROR_PE;
- }
- if (cpu_sys_uart0_lsr(uiValue)->reg_OE & 0x1)
- {
- pstSelf->errorCode |= UART_ERROR_ORE;
- }
- if (cpu_sys_uart0_lsr(uiValue)->reg_RFE & 0x1)
- {
- pstSelf->errorCode |= UART_ERROR_RFE;
- }
- //HV_LOGI("error errorCode = 0x%x\n", pstSelf->errorCode);
- break;
- }
- case UART_INT_BUSY_DETECT:
- {
- //HV_LOGI("busy detect\n");
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_USR);
- HV_UNUSED(uiValue);
- break;
- }
- case UART_INT_CHARACTER_TIMEOUT:
- {
- //HV_LOGI("character timeout\n");
- break;
- }
- default:
- {
- break;
- }
- }
- return HV_VOS_ISR_HANDLED;
- }
- void Hv_Drv_Uart_SetDmaTx(UartSelf *pstSelf, DmaSelf *pstHdmaTx)
- {
- pstSelf->pstHdmaTx = pstHdmaTx;
- Hv_Cal_Dma_SetParent(pstHdmaTx,(void*)pstSelf);
- Hv_Cal_Dma_SetDstAddr(pstHdmaTx,CPU_SYS_UART0_THR_DLL + pstSelf->uiBaseOffset);
- return;
- }
- void Hv_Drv_Uart_SetDmaRx(UartSelf *pstSelf, DmaSelf *pstHdmaRx)
- {
- pstSelf->pstHdmaRx = pstHdmaRx;
- Hv_Cal_Dma_SetParent(pstHdmaRx,(void*)pstSelf);
- Hv_Cal_Dma_SetSrcAddr(pstHdmaRx,CPU_SYS_UART0_THR_DLL + pstSelf->uiBaseOffset);
- return;
- }
- /** Initialize uart
- * @param initParam pointer to uart configure parameters
- * @return uart structure pointer
- */
- UartSelf *Hv_Drv_Uart_Init(UartInitParam *pstInitParam)
- {
- rs_cpu_sys_uart0_fcr fcr = {0};
- rs_cpu_sys_uart0_lcr_ext lcr_ext = {0};
- UartSelf *pstSelf;
- UINT32 uiIrqNum = 0;
- HV_ASSERT_TRUE_RET(pstInitParam != NULL,NULL);
- HV_ASSERT_PEEK_TRUE(pstInitParam->enPort < UART_PORT_MAX);
- pstSelf = &s_astUart[pstInitParam->enPort];
- HV_MEMCPY(&s_astUart[pstInitParam->enPort], pstInitParam, sizeof(UartInitParam));
- if (pstInitParam->enPort == UART_PORT_0)
- {
- pstSelf->uiBaseOffset = 0;
- uiIrqNum = HV_CHIP_IRQ_UART0;
- }
- else if (pstInitParam->enPort == UART_PORT_1)
- {
- pstSelf->uiBaseOffset = HV_UART1_BASE_ADDRESS - HV_UART0_BASE_ADDRESS;
- uiIrqNum = HV_CHIP_IRQ_UART1;
- }
- else
- {
- }
- if (pstInitParam->bFifoEnable)
- {
- fcr.reg_FIFOE = 1;
- fcr.reg_RFIFOR = 1;
- fcr.reg_XFIFOR = 1;
- fcr.TET = pstInitParam->enTxFiFoTrig;
- fcr.RT = pstInitParam->enRxFiFoTrig;
- }
- if (pstInitParam->b9BitMode)
- {
- lcr_ext.reg_DLS_E = 1;
- lcr_ext.reg_ADDR_MATCH = 0;
- lcr_ext.reg_SEND_ADDR = 0;
- lcr_ext.reg_TRANSMIT_MODE = 1;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_LCR_EXT, lcr_ext);
- }
- if (pstInitParam->bNewInterface)
- {
- if (pstInitParam->fCallback == NULL)
- {
- HV_LOGE("no callback regisstered\n");
- }
- }
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR, fcr);
- Hv_Drv_Uart_SetBaudrate(pstSelf, pstInitParam->uiBaudrate);
- Hv_Drv_Uart_SetFormat(pstSelf, pstInitParam->enParity, pstInitParam->enStopbit, pstInitParam->enWordlen);
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, UART_RECVSTATUS_INT_EN | UART_MODEMSTATUS_INT_EN);
- Hv_Vos_AttachIsr(uiIrqNum, Uart_IrqHandler, pstSelf);
- //Hv_Vos_SetIrqPrio(uiIrqNum,pstInitParam->uiPriority);
- Hv_Vos_UnmaskIrq(uiIrqNum);
- Hv_Vos_ConfigIrq(uiIrqNum, HV_TRUE, 0);
- pstSelf->errorCode = UART_ERROR_NONE;
- pstSelf->enState = UART_STATE_READY;
- pstSelf->pstUartBinarySema = Hv_Vos_InitSemaphore(1, 0);
- return pstSelf;
- }
- /** brief De-initialize uart
- * @param self uart pointer
- */
- void Hv_Drv_Uart_Cleanup(UartSelf *pstSelf)
- {
- HV_ASSERT(pstSelf->stInitParam.enPort < UART_PORT_MAX);
- Hv_Drv_Uart_CleanFifo(pstSelf);
- if (pstSelf->stInitParam.enPort == UART_PORT_0)
- {
- Hv_Vos_ConfigIrq(HV_CHIP_IRQ_UART0, HV_FALSE, 0);
- Hv_Vos_MaskIrq(HV_CHIP_IRQ_UART0);
- Hv_Vos_DetachIsr(HV_CHIP_IRQ_UART0, Uart_IrqHandler);
- }
- else if (pstSelf->stInitParam.enPort == UART_PORT_1)
- {
- Hv_Vos_ConfigIrq(HV_CHIP_IRQ_UART1, HV_FALSE, 0);
- Hv_Vos_MaskIrq(HV_CHIP_IRQ_UART1);
- Hv_Vos_DetachIsr(HV_CHIP_IRQ_UART1, Uart_IrqHandler);
- }
- else
- {
- }
- pstSelf->stInitParam.fCallback = NULL;
- pstSelf->stInitParam.pCallbackArg = NULL;
- pstSelf->enState = UART_STATE_RESET;
- return;
- }
- /** brief De-initialize uart
- * @param self uart pointer
- */
- void Hv_Drv_Uart_CleanFifo(UartSelf *pstSelf)
- {
- UINT32 uiValue = 0;
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR);
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR, uiValue | UART_FIFO_MASK);
- return;
- }
- /** Detection puiBaudrate of uart
- * @param enPort uart enPort
- * @param puiBaudrate detection puiBaudrate value
- * @return result
- */
- Status Hv_Drv_Uart_BaudrateDetection(UartPortIndex enPort, UINT32 *puiBaudrate)
- {
- UINT32 uiValue = 0;
- UINT32 uiBaseOffset = 0;
- HV_ASSERT(enPort < UART_PORT_MAX);
- if (enPort == UART_PORT_0)
- {
- uiBaseOffset = 0;
- }
- else if (enPort == UART_PORT_1)
- {
- uiBaseOffset = HV_UART1_BASE_ADDRESS - HV_UART0_BASE_ADDRESS;
- }
- else
- {
- }
- /* auto baud rate enable */
- HV_W32_FIELD_EX(CPU_SYS_UART0_UART_CTL0, uiBaseOffset, reg_abr_en, 1);
- while(1)
- {
- uiValue = HV_R32(uiBaseOffset + CPU_SYS_UART0_UART_CTL0);
- if (cpu_sys_uart0_uart_ctl0(uiValue)->reg_abrf == 1
- && cpu_sys_uart0_uart_ctl0(uiValue)->reg_bit_num != 0)
- {
- *puiBaudrate = HV_CHIP_CLK_APB / cpu_sys_uart0_uart_ctl0(uiValue)->reg_bit_num;
- HV_LOGI("get Baudrate = %d\n", *puiBaudrate);
- break;
- }
- }
- /* auto baud rate disable */
- HV_W32_FIELD_EX(CPU_SYS_UART0_UART_CTL0, uiBaseOffset, reg_abr_en, 0);
- return HV_SUCCESS;
- }
- /** Set baudrate of uart
- * @param self uart pointer
- * @param baudrate baudrate
- * @return result
- */
- Status Hv_Drv_Uart_SetBaudrate(UartSelf *pstSelf, UINT32 uiBaudrate)
- {
- UINT32 uiDivider = 0;
- FLOAT32 fBrd = 0;
- fBrd = (HV_CHIP_CLK_APB >> 4) / (FLOAT32)uiBaudrate + 1 / 2;
- uiDivider = (UINT32)fBrd;
- /* Enable setup uiBaudrate */
- HV_W32_FIELD_EX(CPU_SYS_UART0_LCR, pstSelf->uiBaseOffset, reg_DLAB, 1);
- HV_W32_FIELD_EX(CPU_SYS_UART0_THR_DLL, pstSelf->uiBaseOffset, reg_THR_DLL, uiDivider & 0xff);
- HV_W32_FIELD_EX(CPU_SYS_UART0_DLH_IER, pstSelf->uiBaseOffset, reg_DLH_IER, (uiDivider >> 8) & 0xff);
- /* Disable setup uiBaudrate */
- HV_W32_FIELD_EX(CPU_SYS_UART0_LCR, pstSelf->uiBaseOffset, reg_DLAB, 0);
- return HV_SUCCESS;
- }
- /** Set serial format of homebus
- * @param self uart pointer
- * @param parity parity
- * @param stopbit stop bit
- * @param wordlen word length
- * @return result
- */
- Status Hv_Drv_Uart_SetFormat(UartSelf *pstSelf, UartParity enParity, UartStopBit enStopbit, UartWordLen enWordlen)
- {
- UINT32 uiData = 0;
- UINT32 uiValue = 0;
- pstSelf->stInitParam.enParity = enParity;
- pstSelf->stInitParam.enStopbit = enStopbit;
- pstSelf->stInitParam.enWordlen = enWordlen;
- uiData = (((pstSelf->stInitParam.enStopbit << UART_STOP_POS) & UART_STOP_MASK) | (pstSelf->stInitParam.enWordlen & UART_DATALEN_MASK));
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LCR);
- switch (pstSelf->stInitParam.enParity & UART_PARITY_MASK)
- {
- case UART_PARITY_EVEN:
- {
- uiValue = (uiValue & UART_LCR_MASK) | UART_PARITY_EVEN_MASK | uiData;
- break;
- }
- case UART_PARITY_ODD:
- {
- uiValue = (uiValue & UART_LCR_MASK) | UART_PARITY_ODD_MASK | uiData;
- break;
- }
- default:
- {
- uiValue = (uiValue & UART_LCR_MASK) | UART_PARITY_NONE_MASK | uiData;
- break;
- }
- }
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LCR, uiValue);
- return HV_SUCCESS;
- }
- /** Receives an amount of data in polling mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be received
- * @param timeout timeout duration ms
- * @return result
- */
- Status Hv_Drv_Uart_Receive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout)
- {
- UINT32 uiValue = 0;
- UINT64 ulStartTick = 0;
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_TX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- pstSelf->usRxXferSize = usSize;
- pstSelf->usRxXferCount = usSize;
- ulStartTick = Hv_Vos_GetTick();
- while (pstSelf->usRxXferCount > 0)
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
- if (uiValue == 1)
- {
- pstSelf->usRxXferCount--;
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL);
- *pucData++ = (UCHAR8)uiValue;
- }
- else
- {
- if (uiTimeout != 0 && Hv_Vos_GetTick() - ulStartTick >= uiTimeout)
- {
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- HV_LOGE("Receive timeout!\n");
- return HV_FAILURE;
- }
- }
- }
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** enable uart receive int��
- * @param ucPort uart port
- * @return result
- */
- Status Hv_Drv_Uart_EnableReceive(UCHAR8 ucPort)
- {
- UINT32 uiValue = 0;
- rs_cpu_sys_uart0_dlh_ier ier = {0};
- UartSelf *pstSelf = &s_astUart[ucPort];
- if (pstSelf == NULL)
- {
- HV_LOGE("port not inited\n");
- return HV_FAILURE;
- }
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
- /* Enable Received Data Available Interrupt */
- ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_RECV_INT_EN;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
- return HV_SUCCESS;
- }
- /** Receives an amount of data in non blocking mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be received
- * @return result
- */
- Status Hv_Drv_Uart_IntReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize)
- {
- UINT32 uiValue = 0;
- rs_cpu_sys_uart0_dlh_ier ier = {0};
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_TX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- pstSelf->pucRxBuffPtr = pucData;
- pstSelf->usRxXferSize = usSize;
- pstSelf->usRxXferCount = usSize;
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
- /* Enable Received Data Available Interrupt */
- ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_RECV_INT_EN;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Receives an amount of data in blocking mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be received
- * @return result
- */
- Status Hv_Drv_Uart_BlockReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize)
- {
- while (1)
- {
- /* Due to UART_RECV_INT_EN is set in Hv_Drv_Uart_IntReceive,
- so must run it before P operation.*/
- if (Hv_Drv_Uart_IntReceive(pstSelf, pucData, usSize) == HV_SUCCESS)
- {
- break;
- }
- else
- {
- /* P operation */
- Hv_Vos_AcquireSemaphore(pstSelf->pstUartBinarySema);
- }
- }
- return HV_SUCCESS;
- }
- /** Receives an amount of data in non blocking mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be received
- * @return result
- */
- Status Hv_Drv_Uart_DmaReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize)
- {
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_TX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- pstSelf->pucRxBuffPtr = pucData;
- pstSelf->usRxXferSize = usSize;
- pstSelf->usRxXferCount = usSize;
- Hv_Cal_Dma_XferCallbackBond(pstSelf->pstHdmaRx, Uart_DmaRxCpltCallback);
- Hv_Cal_Dma_SetBlockSize(pstSelf->pstHdmaRx, usSize);
- Hv_Cal_Dma_SetDstAddr(pstSelf->pstHdmaRx, (UINT32)pucData);
- Hv_Cal_Dma_ChannelEn(pstSelf->pstHdmaRx);
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Get character by UART
- * @param self uart pointer
- * @param data pointer to data buffer
- * @return result
- */
- Status Hv_Drv_Uart_GetChar(UartSelf *pstSelf, UCHAR8 *pucData)
- {
- UINT32 uiValue = 0;
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_TX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- do
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
- }while(uiValue == 0);
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL);
- *pucData = (UCHAR8)uiValue;
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Output address by UART with 9bit mode
- * @param self uart pointer
- * @param data device address
- * @return result
- */
- Status Hv_Drv_Uart_PutAddr(UartSelf *pstSelf, UCHAR8 ucAddr)
- {
- UINT32 uiValue = 0;
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- do
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_THRE;
- } while(uiValue == 0);
- uiValue = (1 << 8) | ucAddr;
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, uiValue);
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Output character by UART
- * @param self uart pointer
- * @param data outputed character
- * @return result
- */
- Status Hv_Drv_Uart_PutChar(UartSelf *pstSelf, UCHAR8 ucData)
- {
- UINT32 uiValue = 0;
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- do
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_THRE;
- } while(uiValue == 0);
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, ucData);
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Sends an amount of data in blocking mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be sent
- * @param timeout timeout duration ms
- * @return result
- */
- Status Hv_Drv_Uart_Transmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout)
- {
- UINT32 uiValue = 0;
- UINT64 ulStartTick = 0;
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- pstSelf->usTxXferSize = usSize;
- pstSelf->usTxXferCount = usSize;
- ulStartTick = Hv_Vos_GetTick();
- while (pstSelf->usTxXferCount > 0)
- {
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
- uiValue = cpu_sys_uart0_lsr(uiValue)->reg_THRE;
- if (uiValue == 1)
- {
- pstSelf->usTxXferCount--;
- HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, *pucData);
- pucData += 1;
- }
- else
- {
- if (uiTimeout != 0 && Hv_Vos_GetTick() - ulStartTick >= uiTimeout)
- {
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- HV_LOGE("Transmit timeout!\n");
- return HV_FAILURE;
- }
- }
- }
- if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_READY;
- }
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Sends an amount of data
- * @param ucPort uart port
- * @param data pointer to data buffer
- * @param size amount of data to be sent
- * @return result
- */
- Status Hv_Drv_Uart_Send(UCHAR8 ucPort, const UCHAR8 *pucData, USHORT16 usSize)
- {
- UINT32 uiValue = 0;
- UartSelf *pstSelf = &s_astUart[ucPort];
- if (pstSelf == NULL)
- {
- HV_LOGE("port not inited\n");
- return HV_FAILURE;
- }
- rs_cpu_sys_uart0_dlh_ier ier = {0};
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- pstSelf->pucTxBuffPtr = pucData;
- pstSelf->usTxXferSize = usSize;
- pstSelf->usTxXferCount = usSize;
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
- /* Enable Transmit Holding Register Empty Interrupt */
- ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_TRANEMPTY_INT_EN;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Sends an amount of data in non blocking mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be sent
- * @return result
- */
- Status Hv_Drv_Uart_IntTransmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize)
- {
- UINT32 uiValue = 0;
- rs_cpu_sys_uart0_dlh_ier ier = {0};
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- pstSelf->pucTxBuffPtr = pucData;
- pstSelf->usTxXferSize = usSize;
- pstSelf->usTxXferCount = usSize;
- uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
- /* Enable Transmit Holding Register Empty Interrupt */
- ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_TRANEMPTY_INT_EN;
- HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Sends an amount of data in non blocking mode
- * @param self uart pointer
- * @param data pointer to data buffer
- * @param size amount of data to be sent
- * @return result
- */
- Status Hv_Drv_Uart_DmaTransmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize)
- {
- if (pucData == NULL || usSize == 0)
- {
- return HV_INVALID;
- }
- if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
- {
- if (pstSelf->enState == UART_STATE_BUSY_RX)
- {
- pstSelf->enState = UART_STATE_BUSY_TX_RX;
- }
- else
- {
- pstSelf->enState = UART_STATE_BUSY_TX;
- }
- pstSelf->pucTxBuffPtr = pucData;
- pstSelf->usTxXferSize = usSize;
- pstSelf->usTxXferCount = usSize;
- Hv_Cal_Dma_XferCallbackBond(pstSelf->pstHdmaTx, Uart_DmaTxCpltCallback);
- Hv_Cal_Dma_SetBlockSize(pstSelf->pstHdmaTx, usSize);
- Hv_Cal_Dma_SetSrcAddr(pstSelf->pstHdmaTx, (UINT32)pucData);
- Hv_Cal_Dma_ChannelEn(pstSelf->pstHdmaTx);
- return HV_SUCCESS;
- }
- else
- {
- return HV_FAILURE;
- }
- }
- /** Get errorCode of uart
- * @param self uart pointer
- * @return errorCode result
- */
- UINT32 Hv_Drv_Uart_GetErrorCode(UartSelf *pstSelf)
- {
- HV_LOGI("error errorCode = 0x%x\n", pstSelf->errorCode);
- return pstSelf->errorCode;
- }
- /** Get empty of uart
- * @param self uart pointer
- * @return result empty or not
- */
- BOOL Hv_Drv_Uart_IsEmpty(UartSelf *pstSelf)
- {
- rs_cpu_sys_uart0_lsr lsr = {0};
- HV_R32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR, lsr);
- return !lsr.reg_DR;
- }
- /**
- * @brief uart enable for log.
- * @param[in] bEnble: on/off
- */
- VOID Hv_Drv_EnableUart(BOOL bEnble)
- {
- HV_LOGI("EnableUart %d",bEnble);
- /* uart0_tx swtich */
- if (bEnble)
- {
- HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_tx_func_sel , 1);
- //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_rx_func_sel , 1);
- //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_8, reg_uart0_sin_in_sel , 0);
- }
- else
- {
- HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_tx_func_sel , 0);
- //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_rx_func_sel , 0);
- //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_8, reg_uart0_sin_in_sel , 2;
- }
- return;
- }
|