From ae079c1fc5d990ba55714d4b3a51b19f96edaec4 Mon Sep 17 00:00:00 2001
From: WXK <287788329@qq.com>
Date: 星期四, 24 四月 2025 16:01:43 +0800
Subject: [PATCH] 改为中断来低电平触发发送当前扫描数据,3s内扫描不到的会退出,串口来55 AA 75 70 64 61 74 65,进入升级模式

---
 01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_hal_uart.c |  892 +++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 649 insertions(+), 243 deletions(-)

diff --git a/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_hal_uart.c b/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_hal_uart.c
index ec40d7a..e71ce10 100644
--- a/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_hal_uart.c
+++ b/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_hal_uart.c
@@ -7,81 +7,91 @@
 * @note
 * Copyright (C) 2023 Panchip Technology Corp. All rights reserved.
 *****************************************************************************/
-
 #include "pan_hal.h"
 
+#if (BLE_EN == 1)
+#define PAN_HAL_BLE_IRQ_SPLIT_CALLBACK      1
+#endif
 
-UART_HandleTypeDef UART_Handle_Array[2] =
-    {
-        {.pUartx = UART0,
-         .initObj = {0},
-         .interruptObj = {0},
-         .pTxBuffPtr = NULL,
-         .txXferSize = 0,
-         .txXferCount = 0,
-         .pRxBuffPtr = NULL,
-         .rxXferSize = 0,
-         .rxXferCount = 0,
-         .IRQn = UART0_IRQn,
-         .rxIntCallback = NULL,
-         .txIntCallback = NULL,
-         .dmaSrc = DMAC_Peripheral_UART0_Rx,
-         .dmaDst = DMAC_Peripheral_UART0_Tx,
-         .errorCode = 0},
-        {.pUartx = UART1,
-         .initObj = {0},
-         .interruptObj = {0},
-         .pTxBuffPtr = NULL,
-         .txXferSize = 0,
-         .txXferCount = 0,
-         .pRxBuffPtr = NULL,
-         .rxXferSize = 0,
-         .rxXferCount = 0,
-         .IRQn = UART1_IRQn,
-         .rxIntCallback = NULL,
-         .txIntCallback = NULL,
-         .dmaSrc = DMAC_Peripheral_UART1_Rx,
-         .dmaDst = DMAC_Peripheral_UART1_Tx,
-         .errorCode = 0}};
-
-void HAL_DelayMs(uint32_t t)
+HAL_UART_HandleTypeDef UART_Handle_Array[PAN_HAL_UART_INST_COUNT] =
 {
-    for (uint32_t i = 0; i < t; i++)
     {
-        SYS_delay_10nop(0x1080);
+        .pUartx = UART0,
+        .initObj = {0},
+        .interruptObj =
+        {
+            .txTrigLevel = HAL_UART_TX_FIFO_HALF_FULL,
+            .rxTrigLevel = HAL_UART_RX_FIFO_HALF_FULL,
+            .IrqPriority = 2,
+            .IRQn = UART0_IRQn,
+        },
+        .pTxBuffPtr = NULL,
+        .txXferSize = 0,
+        .txXferCount = 0,
+        .pRxBuffPtr = NULL,
+        .rxXferSize = 0,
+        .rxXferCount = 0,
+        .isTxBusy = false,
+        .isRxBusy = false,
+        .dmaSrc = DMAC_Peripheral_UART0_Rx,
+        .dmaDst = DMAC_Peripheral_UART0_Tx,
+    },
+    {
+        .pUartx = UART1,
+        .initObj = {0},
+        .interruptObj =
+        {
+            .txTrigLevel = HAL_UART_TX_FIFO_HALF_FULL,
+            .rxTrigLevel = HAL_UART_RX_FIFO_HALF_FULL,
+            .IrqPriority = 2,
+            .IRQn = UART1_IRQn,
+        },
+        .pTxBuffPtr = NULL,
+        .txXferSize = 0,
+        .txXferCount = 0,
+        .pRxBuffPtr = NULL,
+        .rxXferSize = 0,
+        .rxXferCount = 0,
+        .isTxBusy = false,
+        .isRxBusy = false,
+        .dmaSrc = DMAC_Peripheral_UART1_Rx,
+        .dmaDst = DMAC_Peripheral_UART1_Tx,
     }
-}
+};
 
-
-
-bool HAL_UART_Init(UART_HandleTypeDef *pUart)
+HAL_Status HAL_UART_Init(HAL_UART_HandleTypeDef *pUart)
 {
+    if (pUart == NULL)
+    {
+        return HAL_ERROR;
+    }
+
     uint32_t tmpreg = 0x00;
     uint32_t integerdivider = 0x00;
     uint32_t fractionaldivider = 0x00;
     uint64_t apbclock = 0x00;
 
-	if(pUart->pUartx == UART0)
-	{
-		CLK_APB1PeriphClockCmd(CLK_APB1Periph_UART0, ENABLE);
-	}
-	else if(pUart->pUartx == UART1)
-	{
-		CLK_APB2PeriphClockCmd(CLK_APB2Periph_UART1, ENABLE);
-	}
-	
+    if(pUart->pUartx == UART0)
+    {
+        CLK_APB1PeriphClockCmd(CLK_APB1Periph_UART0, ENABLE);
+    }
+    else if(pUart->pUartx == UART1)
+    {
+        CLK_APB2PeriphClockCmd(CLK_APB2Periph_UART1, ENABLE);
+    }
+
     /*---------------------------- UART BRR Configuration -----------------------*/
     /* Configure the UART Baud Rate */
     apbclock = CLK_GetPeripheralFreq((void *)pUart->pUartx);
-    /*unlock to enable write & read divisor register*/
+    /* Unlock to enable write & read divisor register */
     pUart->pUartx->LCR |= UART_LCR_DLAB_Msk;
-    /* Determine the integer part baud_rate_divisor =  PCLK*100 / (16*required_baud_rate)*/
+    /* Determine the integer part baud_rate_divisor =  PCLK*100 / (16*required_baud_rate) */
     integerdivider = ((25 * apbclock) / (4 * (pUart->initObj.baudRate)));
 
     // Too high baudrate (too small divider) would cause DLL/DLH be all 0 which means UART disabled,
     // thus return false if this happens.
     if (integerdivider < 100)
-        return false;
+        return HAL_ERROR;
 
     tmpreg = (integerdivider / 100);
     pUart->pUartx->RBR_THR_DLL = tmpreg & 0xFF;
@@ -101,239 +111,621 @@
     pUart->pUartx->LCR = tmpreg;
 
     /*-------------------------------enable fifo----------------------------------*/
-    pUart->pUartx->SCR |= UART_FCR_FIFOE_Msk;
-    pUart->pUartx->IIR_FCR = pUart->pUartx->SCR;
     UART_EnableFifo(pUart->pUartx);
 
-    return true;
+    return HAL_OK;
 }
 
-void HAL_UART_SendData(UART_HandleTypeDef *pUart, uint8_t *pbuf, size_t size)
+HAL_Status HAL_UART_SendData(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t size, uint32_t timeout)
 {
-    pUart->pTxBuffPtr = pbuf;
+    if (pUart->isTxBusy)
+    {
+        return HAL_BUSY;
+    }
+
+    if ((pUart == NULL) || (pBuf == NULL) || (size == 0U))
+    {
+        return HAL_ERROR;
+    }
+
+    uint32_t timeout_tick = HAL_TimeConvMsToTick(timeout);
+    uint32_t uptime_ref = HAL_TimeGetCurrTick();
+
+    pUart->isTxBusy = true;
+    pUart->pTxBuffPtr = pBuf;
     pUart->txXferSize = size;
     pUart->txXferCount = 0;
+
     while (pUart->txXferCount < pUart->txXferSize)
     {
-        UART_SendData(pUart->pUartx, pUart->pTxBuffPtr[pUart->txXferCount++]);
+        // Wait until Transmitter Shift Register and Tx FIFO are both empty
         while (!(UART_GetLineStatus(pUart->pUartx) & UART_LSR_TEMT_Msk))
-            ;
+        {
+            if (timeout_tick != HAL_TIME_FOREVER)
+            {
+                if (HAL_TimeGetCurrTick() - uptime_ref >= timeout_tick)
+                {
+                    pUart->isTxBusy = false;
+                    return HAL_TIMEOUT;
+                }
+            }
+        }
+        // Put a byte to Tx FIFO
+        UART_SendData(pUart->pUartx, pUart->pTxBuffPtr[pUart->txXferCount++]);
     }
+
+    pUart->isTxBusy = false;
+
+    return HAL_OK;
 }
 
-void HAL_UART_ReceiveData(UART_HandleTypeDef *pUart, uint8_t *pbuf, size_t size, uint32_t timeout)
+HAL_Status HAL_UART_ReceiveData(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t size, uint32_t timeout)
 {
-    UART_SetRxTrigger(pUart->pUartx, UART_RX_FIFO_HALF_FULL);
+    if (pUart->isRxBusy)
+    {
+        return HAL_BUSY;
+    }
 
-    pUart->pRxBuffPtr = pbuf;
+    if ((pUart == NULL) || (pBuf == NULL) || (size == 0U))
+    {
+        return HAL_ERROR;
+    }
+
+    uint32_t timeout_tick = HAL_TimeConvMsToTick(timeout);
+    uint32_t uptime_ref = HAL_TimeGetCurrTick();
+
+    pUart->isRxBusy = true;
+    pUart->pRxBuffPtr = pBuf;
     pUart->rxXferSize = size;
     pUart->rxXferCount = 0;
+
     while (pUart->rxXferCount < pUart->rxXferSize)
     {
-        while ((UART_GetLineStatus(pUart->pUartx) & UART_LSR_DR_Msk))
+        // Check if there is at least one byte in Rx Data Register or Rx FIFO
+        if (UART_GetLineStatus(pUart->pUartx) & UART_LSR_DR_Msk)
         {
+            // Get a byte from Rx FIFO
             pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
+        }
+        if (timeout_tick != HAL_TIME_FOREVER)
+        {
+            if (HAL_TimeGetCurrTick() - uptime_ref >= timeout_tick)
+            {
+                pUart->isRxBusy = false;
+                return HAL_TIMEOUT;
+            }
+        }
+    }
+
+    pUart->isRxBusy = false;
+
+    return HAL_OK;
+}
+
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+#include "pan_ble_stack.h"
+void ble_irq_split_callback(void)
+{
+    HAL_UART_HandleTypeDef *pUart;
+
+    for (size_t i = 0; i < PAN_HAL_UART_INST_COUNT; i++)
+    {
+        pUart = &UART_Handle_Array[i];
+        if (pUart->isRxBusy)
+        {
+            __disable_irq(); // To avoid swiching to the possible higher priority UART ISR
+            if (pUart->interruptObj.continuousRxMode)
+            {
+                while (UART_GetRxFifoLevel(pUart->pUartx) > 1)
+                {
+                    if (pUart->rxXferCount < pUart->rxXferSize)
+                    {
+                        pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
+                    }
+                    else
+                    {
+                        // Set UART pending irq manually to trigger uart rx continuous buff full error callback
+                        NVIC_SetPendingIRQ(pUart->interruptObj.IRQn);
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                while (!UART_IsRxFifoEmpty(pUart->pUartx))
+                {
+                    if (pUart->rxXferCount < pUart->rxXferSize)
+                    {
+                        pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+
+                if (pUart->rxXferCount == pUart->rxXferSize)
+                {
+                    // Set UART pending irq manually to trigger uart rx finish callback
+                    NVIC_SetPendingIRQ(pUart->interruptObj.IRQn);
+                }
+            }
+            __enable_irq();
         }
     }
 }
+#endif // PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
 
-void HAL_UART_SendData_INT(UART_HandleTypeDef *pUart, uint8_t *pbuf, size_t size, UART_CallbackFunc callback)
+HAL_Status HAL_UART_Init_INT(HAL_UART_HandleTypeDef *pUart)
 {
-    pUart->pTxBuffPtr = pbuf;
-    pUart->txXferSize = size;
-    pUart->txXferCount = 0;
-    pUart->txIntCallback = callback;
-    UART_SetTxTrigger(pUart->pUartx, UART_TX_FIFO_EMPTY);
+    if (pUart == NULL)
+    {
+        return HAL_ERROR;
+    }
 
-    pUart->interruptObj.switchFlag = ENABLE;
-    pUart->interruptObj.interruptMode = HAL_UART_INT_THR_EMPTY;
-    HAL_UART_Init_INT(pUart);
-    NVIC_EnableIRQ(pUart->IRQn);
-}
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+    pan_misc_register_app_irq_handler_cb(ble_irq_split_callback);
+#endif // PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
 
-void HAL_UART_ReceiveData_INT(UART_HandleTypeDef *pUart, uint8_t *pbuf, size_t size,uint32_t timeout,UART_CallbackFunc callback)
-{
-    pUart->pRxBuffPtr = pbuf;
-    pUart->rxXferSize = size;
-    pUart->rxXferCount = 0;
-    pUart->rxIntCallback = callback;
-	UART_SetRxTrigger(pUart->pUartx, UART_RX_FIFO_TWO_LESS_THAN_FULL);
-
-    pUart->interruptObj.switchFlag = ENABLE;
-    pUart->interruptObj.interruptMode = HAL_UART_INT_RECV_DATA_AVL;
-    HAL_UART_Init_INT(pUart);
-    pUart->interruptObj.interruptMode = HAL_UART_INT_LINE_STATUS;
-    HAL_UART_Init_INT(pUart);
-    pUart->interruptObj.interruptMode = HAL_UART_INT_ALL;
-    HAL_UART_Init_INT(pUart);
-    NVIC_EnableIRQ(pUart->IRQn);
-}
-
-
-
-void HAL_UART_SendData_DMA(UART_HandleTypeDef *pUart, uint8_t *pbuf, size_t size, UART_CallbackFunc callback)
-{
-    pUart->interruptObj.switchFlag = ENABLE;
-    pUart->interruptObj.interruptMode = HAL_UART_INT_THR_EMPTY;
-    HAL_UART_Init_INT(pUart);
-
-    pUart->pTxBuffPtr = pbuf;
-    pUart->txXferSize = size;
-    pUart->txXferCount = 0;
-
+    // Flush UART FIFOs
     UART_ResetTxFifo(pUart->pUartx);
-    UART_SetTxTrigger(pUart->pUartx, UART_TX_FIFO_HALF_FULL);
-    UART_EnablePtime(pUart->pUartx); //Enable Programmable THRE Interrupt Mode
-
-    uint32_t txChNum = 0xFF;
-    // Initialize the DMA controller
-    DMAC_Init(DMA);
-    NVIC_EnableIRQ(DMA_IRQn);
-
-    /* Get free DMA channel */
-    txChNum = DMAC_AcquireChannel(DMA);
-    /* Enable DMA transfer interrupt */
-    DMAC_ClrIntFlagMsk(DMA, txChNum, DMAC_FLAG_INDEX_TFR);
-    DMAC_ClrIntFlagMsk(DMA, txChNum, DMAC_FLAG_INDEX_DSTTFR);
-    DMAC_ClrIntFlagMsk(DMA, txChNum, DMAC_FLAG_INDEX_BLK);
-    DMAC_ClrIntFlagMsk(DMA, txChNum, DMAC_FLAG_INDEX_ERR);
-    dma_mem2uart_config.PeripheralDst = pUart->dmaDst;
-    DMAC_Channel_Array[txChNum].ConfigTmp = dma_mem2uart_config;
-    DMAC_Channel_Array[txChNum].CallbackUart = callback;
-    DMAC_Channel_Array[txChNum].PeriMode = DMAC_Peri_UART;
-    DMAC_Channel_Array[txChNum].pBuffPtr = (uint32_t*)pUart->pTxBuffPtr;
-    DMAC_Channel_Array[txChNum].XferSize = pUart->txXferSize;
-    DMAC_SetChannelConfig(DMA, txChNum, &DMAC_Channel_Array[txChNum].ConfigTmp);
-
-    /* Condition check */
-    uint32_t DataWidthInByteSrc = 1 << DMAC_Channel_Array[txChNum].ConfigTmp.DataWidthSrc;
-    uint32_t BlockSize = size / DataWidthInByteSrc; // BlockSize = DataLen / DataWidthInByteSrc
-
-    /* Start DMA Tx channel */
-    DMAC_StartChannel(DMA, txChNum, pbuf, (void *)&(pUart->pUartx->RBR_THR_DLL), BlockSize);
-}
-
-void HAL_UART_ReceiveData_DMA(UART_HandleTypeDef *pUart, uint8_t *pbuf, size_t size, uint32_t timeout,UART_CallbackFunc callback)
-{
-    pUart->pRxBuffPtr = pbuf;
-    pUart->rxXferSize = size;
-    pUart->rxXferCount = 0;
     UART_ResetRxFifo(pUart->pUartx);
 
-    UART_SetRxTrigger(pUart->pUartx, UART_RX_FIFO_HALF_FULL);
-    uint32_t rxChNum = 0xFF;
-    // Initialize the DMA controller
-    DMAC_Init(DMA);
-    NVIC_EnableIRQ(DMA_IRQn);
-    rxChNum = DMAC_AcquireChannel(DMA);
-    /* Enable DMA transfer interrupt */
-    DMAC_ClrIntFlagMsk(DMA, rxChNum, DMAC_FLAG_INDEX_TFR);
-    DMAC_ClrIntFlagMsk(DMA, rxChNum, DMAC_FLAG_INDEX_SRCTFR);
-    DMAC_ClrIntFlagMsk(DMA, rxChNum, DMAC_FLAG_INDEX_BLK);
-    DMAC_ClrIntFlagMsk(DMA, rxChNum, DMAC_FLAG_INDEX_ERR);
+    // Set UART IRQ trigger level
+    UART_SetTxTrigger(pUart->pUartx, (UART_TxTriggerDef)pUart->interruptObj.txTrigLevel);
+    UART_SetRxTrigger(pUart->pUartx, (UART_RxTriggerDef)pUart->interruptObj.rxTrigLevel);
 
-    // dma_uart2mem_config.PeripheralDst = pUart->dmaSrc;
-    DMAC_Channel_Array[rxChNum].ConfigTmp = dma_uart2mem_config;
-    DMAC_Channel_Array[rxChNum].ConfigTmp.PeripheralSrc = pUart->dmaSrc;
-    DMAC_Channel_Array[rxChNum].CallbackUart = callback;
-    DMAC_Channel_Array[rxChNum].PeriMode = DMAC_Peri_UART;
-    DMAC_Channel_Array[rxChNum].pBuffPtr = (uint32_t*)pUart->pRxBuffPtr;
-    DMAC_Channel_Array[rxChNum].XferSize = pUart->rxXferSize;
-    DMAC_SetChannelConfig(DMA, rxChNum, &DMAC_Channel_Array[rxChNum].ConfigTmp);
+    // Enable THRE Interrupt Mode
+    UART_EnablePtime(pUart->pUartx);
 
-    /* Condition check */
-    uint32_t dataWidthInByteSrc = 1 <<DMAC_Channel_Array[rxChNum].ConfigTmp.DataWidthSrc;
-    uint32_t blockSize = size / dataWidthInByteSrc;    //blockSize = DataLen / dataWidthInByteSrc
-    /* Start DMA Rx channel */
-    DMAC_StartChannel(DMA, rxChNum, (void*)&(pUart->pUartx->RBR_THR_DLL), pUart->pRxBuffPtr, blockSize);
+    // Set UART IRQ Priority and enable UART IRQ
+    NVIC_SetPriority(pUart->interruptObj.IRQn, pUart->interruptObj.IrqPriority);
+    NVIC_EnableIRQ(pUart->interruptObj.IRQn);
+
+    return HAL_OK;
 }
 
-
-void HAL_UART_Init_INT(UART_HandleTypeDef *pUart)
+HAL_Status HAL_UART_SendData_INT(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t size)
 {
-    if (pUart->interruptObj.switchFlag == ENABLE)
+    if (pUart->isTxBusy)
     {
-        pUart->pUartx->IER_DLH |= ((pUart->interruptObj.interruptMode << UART_IER_ALL_IRQ_Pos) & UART_IER_ALL_IRQ_Msk);
+        return HAL_BUSY;
     }
-    else if (pUart->interruptObj.switchFlag == DISABLE)
+
+    if ((pUart == NULL) || (pBuf == NULL) || (size == 0U))
     {
-        pUart->pUartx->IER_DLH &= ~((pUart->interruptObj.interruptMode << UART_IER_ALL_IRQ_Pos) & UART_IER_ALL_IRQ_Msk);
+        return HAL_ERROR;
     }
+
+    pUart->isTxBusy = true;
+    pUart->pTxBuffPtr = pBuf;
+    pUart->txXferSize = size;
+    pUart->txXferCount = 0;
+
+    // Enable Transmit Trigger interupt to start sending
+    UART_EnableIrq(pUart->pUartx, UART_IRQ_THR_EMPTY);
+
+    return HAL_OK;
 }
 
-static void UART_HandleLineStatus(UART_HandleTypeDef *pUart)
+HAL_Status HAL_UART_ReceiveData_INT(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t size)
+{
+    if (pUart->isRxBusy)
+    {
+        return HAL_BUSY;
+    }
+
+    if ((pUart == NULL) || (pBuf == NULL) || (size == 0U))
+    {
+        return HAL_ERROR;
+    }
+
+    pUart->isRxBusy = true;
+    pUart->pRxBuffPtr = pBuf;
+    pUart->rxXferSize = size;
+    pUart->rxXferCount = 0;
+
+    // Enable Data Available and Rx Line Status interrupt to start receiving
+    UART_EnableIrq(pUart->pUartx, UART_IRQ_RECV_DATA_AVL);
+    UART_EnableIrq(pUart->pUartx, UART_IRQ_LINE_STATUS);
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_ReceiveDataContinuously_INT(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t bufSize)
+{
+    if (pUart->isRxBusy)
+    {
+        return HAL_BUSY;
+    }
+
+    if ((pUart == NULL) || (pBuf == NULL) || (bufSize == 0U))
+    {
+        return HAL_ERROR;
+    }
+
+    // The continuous Rx mode does not support Rx FIFO trigger level set to 1 char
+    if ((UART_RxTriggerDef)pUart->interruptObj.rxTrigLevel == UART_RX_FIFO_ONE_CHAR)
+    {
+        return HAL_ERROR;
+    }
+
+    pUart->interruptObj.continuousRxMode = true;
+    pUart->isRxBusy = true;
+    pUart->pRxBuffPtr = pBuf;
+    pUart->rxXferSize = bufSize;
+    pUart->rxXferCount = 0;
+
+    // Enable Data Available and Rx Line Status interrupt to start receiving
+    UART_EnableIrq(pUart->pUartx, UART_IRQ_RECV_DATA_AVL);
+    UART_EnableIrq(pUart->pUartx, UART_IRQ_LINE_STATUS);
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_SendDataAbort_INT(HAL_UART_HandleTypeDef *pUart)
+{
+    if (pUart == NULL)
+    {
+        return HAL_ERROR;
+    }
+
+    // Disable Transmit Trigger interupt to abort sending
+    UART_DisableIrq(pUart->pUartx, UART_IRQ_THR_EMPTY);
+
+    // Flush Tx FIFO
+    UART_ResetTxFifo(pUart->pUartx);
+
+    pUart->isTxBusy = false;
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_ReceiveDataAbort_INT(HAL_UART_HandleTypeDef *pUart)
+{
+    if (pUart == NULL)
+    {
+        return HAL_ERROR;
+    }
+
+    // Disable Data Available and Rx Line Status interrupt to abort receiving
+    UART_DisableIrq(pUart->pUartx, UART_IRQ_RECV_DATA_AVL);
+    UART_DisableIrq(pUart->pUartx, UART_IRQ_LINE_STATUS);
+
+    // Flush Rx FIFO
+    UART_ResetRxFifo(pUart->pUartx);
+
+    pUart->isRxBusy = false;
+    pUart->interruptObj.continuousRxMode = false;
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_Init_DMA(HAL_UART_HandleTypeDef *pUart, HAL_UART_DmaDirOpt dmaDir, UART_CallbackFunc callback)
+{
+    uint32_t dmaCh;
+
+    if ((pUart == NULL) || (callback == NULL))
+    {
+        return HAL_ERROR;
+    }
+
+    if (dmaDir == HAL_UART_DMA_TX)
+    {
+        // Configure UART Tx FIFO
+        UART_ResetTxFifo(pUart->pUartx);
+        UART_SetTxTrigger(pUart->pUartx, UART_TX_FIFO_HALF_FULL);
+        UART_EnablePtime(pUart->pUartx); //Enable Programmable THRE Interrupt Mode
+
+        /* Get free DMA channel */
+        dmaCh = DMAC_AcquireChannel(DMA);
+        if (dmaCh == DMA_INVLID_CHANNEL)
+        {
+            return HAL_ERROR;
+        }
+
+        pUart->txDmaCh = dmaCh;
+        DMAC_Channel_Array[dmaCh].ConfigTmp = dma_mem2uart_config;
+        DMAC_Channel_Array[dmaCh].ConfigTmp.PeripheralDst = pUart->dmaDst;
+    }
+    else if (dmaDir == HAL_UART_DMA_RX)
+    {
+        // Configure UART Rx FIFO
+        UART_ResetRxFifo(pUart->pUartx);
+        UART_SetRxTrigger(pUart->pUartx, UART_RX_FIFO_HALF_FULL);
+
+        /* Get free DMA channel */
+        dmaCh = DMAC_AcquireChannel(DMA);
+        if (dmaCh == DMA_INVLID_CHANNEL)
+        {
+            return HAL_ERROR;
+        }
+
+        pUart->rxDmaCh = dmaCh;
+        DMAC_Channel_Array[dmaCh].ConfigTmp = dma_uart2mem_config;
+        DMAC_Channel_Array[dmaCh].ConfigTmp.PeripheralSrc = pUart->dmaSrc;
+    }
+
+    /* Enable DMA transfer interrupt */
+    DMAC_ClrIntFlagMsk(DMA, dmaCh, DMAC_FLAG_INDEX_TFR);
+//    DMAC_ClrIntFlagMsk(DMA, dmaCh, DMAC_FLAG_INDEX_ERR);
+
+    DMAC_Channel_Array[dmaCh].periph = pUart;
+    DMAC_Channel_Array[dmaCh].CallbackUart = callback;
+    DMAC_Channel_Array[dmaCh].PeriMode = DMAC_Peri_UART;
+    DMAC_SetChannelConfig(DMA, dmaCh, &DMAC_Channel_Array[dmaCh].ConfigTmp);
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_SendData_DMA(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t size)
+{
+    if (pUart->isTxBusy)
+    {
+        return HAL_BUSY;
+    }
+
+    if ((pUart == NULL) || (pBuf == NULL) || (size == 0U))
+    {
+        return HAL_ERROR;
+    }
+
+    pUart->isTxBusy = true;
+    DMAC_Channel_Array[pUart->txDmaCh].pBuffPtr = (uint32_t*)pBuf;
+    DMAC_Channel_Array[pUart->txDmaCh].XferSize = size;
+    DMAC_Channel_Array[pUart->txDmaCh].XferCount = 0;
+
+    if (size < 1024)
+    {
+        DMAC_StartChannel(DMA, pUart->txDmaCh, pBuf, (void *)&(pUart->pUartx->RBR_THR_DLL), size);
+    }
+    else
+    {
+        DMAC_StartChannel(DMA, pUart->txDmaCh, pBuf, (void *)&(pUart->pUartx->RBR_THR_DLL), 1023);
+    }
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_ReceiveData_DMA(HAL_UART_HandleTypeDef *pUart, uint8_t *pBuf, uint16_t size)
+{
+    if (pUart->isRxBusy)
+    {
+        return HAL_BUSY;
+    }
+
+    if ((pUart == NULL) || (pBuf == NULL) || (size == 0U))
+    {
+        return HAL_ERROR;
+    }
+
+    pUart->isRxBusy = true;
+    DMAC_Channel_Array[pUart->rxDmaCh].pBuffPtr = (uint32_t*)pBuf;
+    DMAC_Channel_Array[pUart->rxDmaCh].XferSize = size;
+    DMAC_Channel_Array[pUart->rxDmaCh].XferCount = 0;
+
+    if (size < 1024)
+    {
+        DMAC_StartChannel(DMA, pUart->rxDmaCh, (void*)&(pUart->pUartx->RBR_THR_DLL), pBuf, size);
+    }
+    else
+    {
+        DMAC_StartChannel(DMA, pUart->rxDmaCh, (void*)&(pUart->pUartx->RBR_THR_DLL), pBuf, 1023);
+    }
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_SendDataAbort_DMA(HAL_UART_HandleTypeDef *pUart)
+{
+    if (pUart == NULL)
+    {
+        return HAL_ERROR;
+    }
+
+    // Stop current DMA channel
+    DMAC_StopChannel(DMA, pUart->txDmaCh);
+
+    // Flush Tx FIFO
+    UART_ResetTxFifo(pUart->pUartx);
+
+    pUart->isTxBusy = false;
+
+    return HAL_OK;
+}
+
+HAL_Status HAL_UART_ReceiveDataAbort_DMA(HAL_UART_HandleTypeDef *pUart)
+{
+    if (pUart == NULL)
+    {
+        return HAL_ERROR;
+    }
+
+    // Stop current DMA channel
+    DMAC_StopChannel(DMA, pUart->rxDmaCh);
+
+    // Flush Rx FIFO
+    UART_ResetRxFifo(pUart->pUartx);
+
+    pUart->isRxBusy = false;
+
+    return HAL_OK;
+}
+
+static void UART_HandleLineStatus(HAL_UART_HandleTypeDef *pUart)
 {
     uint32_t lineStatus = UART_GetLineStatus(pUart->pUartx);
 
-    // Filter line error
-    if ((lineStatus & (UART_LINE_OVERRUN_ERR | UART_LINE_PARITY_ERR | UART_LINE_FRAME_ERR | UART_LINE_RECV_FIFO_EMPTY)) != 0x0)
+    if (pUart->isRxBusy)
     {
-
-    }
-
-    // Handle THRE event
-    if (lineStatus & UART_LINE_THRE)
-    {
-        if ((pUart->pUartx->IER_DLH & UART_IER_EPTI_Msk) == 0)
+        // Report Rx error event
+        if (pUart->interruptObj.callbackFunc != NULL)
         {
-
-        }
-
-        else if ((pUart->pUartx->IIR_FCR & UART_IIR_FIFOSE_Msk) != 0)
-        {
-
-        }
-    }
-}
-
-static void UART_HandleModemStatus(UART_HandleTypeDef *pUart)
-{
-    uint32_t modemStatus = UART_GetModemStatus(pUart->pUartx);
-}
-
-static void UART_HandleReceivedData(UART_HandleTypeDef *pUart,UART_Cb_Flag_Opt flag)
-{
-    while (!UART_IsRxFifoEmpty(pUart->pUartx))
-    {
-        pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
-    }
-    
-    if (flag == UART_CB_FLAG_RX_TIMEOUT)
-    {
-		if(pUart->rxXferCount >= pUart->rxXferSize)
-		{
-			pUart->rxXferCount = pUart->rxXferSize;
-		}
-
-        if (pUart->rxIntCallback != NULL)
-        {
-            pUart->rxIntCallback(flag,pUart->pRxBuffPtr,pUart->rxXferCount);
-        }
-        pUart->rxXferCount = 0;
-    }
-}
-
-static void UART_HandleTransmittingData(UART_HandleTypeDef *pUart)
-{
-    while (!UART_IsTxFifoFull(pUart->pUartx))
-    {
-        if (pUart->txXferCount < pUart->txXferSize)
-        {
-            UART_SendData(pUart->pUartx, pUart->pTxBuffPtr[pUart->txXferCount++]);
-        }
-        else
-        {
-            UART_DisableIrq(pUart->pUartx, UART_IRQ_THR_EMPTY); // Disable THRE Interrupt after transmitting done
-            if (pUart->txIntCallback != NULL)
+            if (lineStatus & UART_LINE_PARITY_ERR)
             {
-                pUart->txIntCallback(UART_CB_FLAG_TX_FINISH, pUart->pTxBuffPtr,pUart->txXferCount);
+                pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_RX_ERR_PARITY, pUart->pRxBuffPtr, pUart->rxXferCount);
             }
-            break;
+            if (lineStatus & UART_LINE_FRAME_ERR)
+            {
+                pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_RX_ERR_FRAME, pUart->pRxBuffPtr, pUart->rxXferCount);
+            }
+            if (lineStatus & UART_LINE_OVERRUN_ERR)
+            {
+                pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_RX_ERR_OVERRUN, pUart->pRxBuffPtr, pUart->rxXferCount);
+            }
         }
-    }   
+    }
 }
 
-static void UART_HandleProc(UART_HandleTypeDef *pUart)
+static void UART_HandleReceivedData(HAL_UART_HandleTypeDef *pUart, UART_EventDef flag)
+{
+    if (pUart->isRxBusy)
+    {
+        if (pUart->interruptObj.continuousRxMode)
+        {
+            if (flag != UART_EVENT_TIMEOUT)
+            {
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                __disable_irq(); // To avoid swiching to higher priority LL IRQ
+#endif
+                // Read data from UART Rx FIFO and remains 1 byte in it
+                while (UART_GetRxFifoLevel(pUart->pUartx) > 1)
+                {
+                    if (pUart->rxXferCount < pUart->rxXferSize)
+                    {
+                        pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                __enable_irq();
+#endif
+            }
+            else
+            {
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                __disable_irq(); // To avoid swiching to higher priority LL IRQ
+#endif
+                // Read all data from UART Rx FIFO due to timeout occurred
+                while (!UART_IsRxFifoEmpty(pUart->pUartx))
+                {
+                    if (pUart->rxXferCount < pUart->rxXferSize)
+                    {
+                        pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                __enable_irq();
+#endif
+                // End current rx flow and trigger Continuous Rx Timeout callback if Rx FIFO is already empty
+                if (UART_IsRxFifoEmpty(pUart->pUartx))
+                {
+                    // Disable Data Available and Rx Line Status interrupt to abort receiving
+                    UART_DisableIrq(pUart->pUartx, UART_IRQ_RECV_DATA_AVL);
+                    UART_DisableIrq(pUart->pUartx, UART_IRQ_LINE_STATUS);
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                    __disable_irq(); // To avoid swiching to higher priority LL IRQ
+#endif
+                    pUart->isRxBusy = false;
+                    pUart->interruptObj.continuousRxMode = false;
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                    __enable_irq();
+#endif
+                    // Trigger Continuous Rx Timeout callback
+                    if (pUart->interruptObj.callbackFunc != NULL)
+                    {
+                        pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_CONTI_RX_TIMEOUT, pUart->pRxBuffPtr, pUart->rxXferCount);
+                    }
+                }
+            }
+            if (pUart->rxXferCount >= pUart->rxXferSize)
+            {
+                // Trigger Rx Buffer Full callback
+                if (pUart->interruptObj.callbackFunc != NULL)
+                {
+                    pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_CONTI_RX_BUFF_FULL, pUart->pRxBuffPtr, pUart->rxXferCount);
+                }
+            }
+        }
+        else // Normal Rx Mode (Not Continuous Rx Mode)
+        {
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+            __disable_irq(); // To avoid swiching to higher priority LL IRQ
+#endif
+            while (!UART_IsRxFifoEmpty(pUart->pUartx))
+            {
+                if (pUart->rxXferCount < pUart->rxXferSize)
+                {
+                    pUart->pRxBuffPtr[pUart->rxXferCount++] = UART_ReceiveData(pUart->pUartx);
+                }
+                else
+                {
+                    break;
+                }
+            }
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+            __enable_irq();
+#endif
+            if (pUart->rxXferCount == pUart->rxXferSize)
+            {
+                // Disable Data Available and Rx Line Status interrupt to abort receiving
+                UART_DisableIrq(pUart->pUartx, UART_IRQ_RECV_DATA_AVL);
+                UART_DisableIrq(pUart->pUartx, UART_IRQ_LINE_STATUS);
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                __disable_irq(); // To avoid swiching to higher priority LL IRQ
+#endif
+                pUart->isRxBusy = false;
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+                __enable_irq();
+#endif
+                // Report Rx finish event
+                if (pUart->interruptObj.callbackFunc != NULL)
+                {
+                    pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_RX_FINISH, pUart->pRxBuffPtr, pUart->rxXferCount);
+                }
+            }
+        }
+    }
+}
+
+static void UART_HandleTransmittingData(HAL_UART_HandleTypeDef *pUart)
+{
+    if (pUart->isTxBusy)
+    {
+        while (!UART_IsTxFifoFull(pUart->pUartx))
+        {
+            if (pUart->txXferCount < pUart->txXferSize)
+            {
+                UART_SendData(pUart->pUartx, pUart->pTxBuffPtr[pUart->txXferCount++]);
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        if (pUart->txXferCount == pUart->txXferSize)
+        {
+            // Disable Transmit Trigger interupt after transmitting done
+            UART_DisableIrq(pUart->pUartx, UART_IRQ_THR_EMPTY);
+            pUart->isTxBusy = false;
+            // Report Tx finish event
+            if (pUart->interruptObj.callbackFunc != NULL)
+            {
+                pUart->interruptObj.callbackFunc(pUart, HAL_UART_EVT_TX_FINISH, pUart->pTxBuffPtr, pUart->txXferCount);
+            }
+        }
+    }
+}
+
+static void UART_HandleProc(HAL_UART_HandleTypeDef *pUart)
 {
     UART_EventDef event = UART_GetActiveEvent(pUart->pUartx);
 
@@ -343,34 +735,48 @@
         UART_HandleLineStatus(pUart);
         break;
     case UART_EVENT_DATA:
-        UART_HandleReceivedData(pUart,UART_CB_FLAG_RX_FINISH);
+        UART_HandleReceivedData(pUart, UART_EVENT_DATA);
         break;
     case UART_EVENT_TIMEOUT:
-        UART_HandleReceivedData(pUart,UART_CB_FLAG_RX_TIMEOUT);
+        UART_HandleReceivedData(pUart, UART_EVENT_TIMEOUT);
         break;
     case UART_EVENT_THR_EMPTY:
         UART_HandleTransmittingData(pUart);
         break;
-    case UART_EVENT_MODEM:
-        UART_HandleModemStatus(pUart);
-        break;
     case UART_EVENT_NONE:
-        /* Just ignore this event. */
+#if PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
+        UART_HandleReceivedData(pUart, UART_EVENT_NONE);
+#endif // PAN_HAL_BLE_IRQ_SPLIT_CALLBACK
         break;
     default:
         break;
     }
 }
 
-void UART0_IRQHandler(void)
+__WEAK void UART0_IRQHandlerOverlay(void)
 {
     UART_HandleProc(&UART_Handle_Array[0]);
 }
 
-void UART1_IRQHandler(void)
+__WEAK void UART1_IRQHandlerOverlay(void)
 {
     UART_HandleProc(&UART_Handle_Array[1]);
 }
 
+void UART0_IRQHandler(void)
+{
+    PAN_IO_TIMING_TRACK_LEVEL(CONFIG_TRACK_PIN_UART0_IRQ, 1);
 
-/*** (C) COPYRIGHT 2023 Panchip Technology Corp. ***/
+    UART0_IRQHandlerOverlay();
+
+    PAN_IO_TIMING_TRACK_LEVEL(CONFIG_TRACK_PIN_UART0_IRQ, 0);
+}
+
+void UART1_IRQHandler(void)
+{
+    PAN_IO_TIMING_TRACK_LEVEL(CONFIG_TRACK_PIN_UART1_IRQ, 1);
+
+    UART1_IRQHandlerOverlay();
+
+    PAN_IO_TIMING_TRACK_LEVEL(CONFIG_TRACK_PIN_UART1_IRQ, 0);
+}

--
Gitblit v1.9.3