From 387d1ffc16ce9e050403baee0ed07f3d9accf632 Mon Sep 17 00:00:00 2001
From: chen <15335560115@163.com>
Date: 星期五, 04 七月 2025 14:55:15 +0800
Subject: [PATCH] 初步移植完成0.6.8SDK,但发送有len太长未找到原因

---
 keil/include/drivers/mk_uart.c |  244 +++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 185 insertions(+), 59 deletions(-)

diff --git a/keil/include/drivers/mk_uart.c b/keil/include/drivers/mk_uart.c
index d101fe8..f29ccb0 100644
--- a/keil/include/drivers/mk_uart.c
+++ b/keil/include/drivers/mk_uart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and
+ * Copyright (c) 2019-2025 Beijing Hanwei Innovation Technology Ltd. Co. and
  * its subsidiaries and affiliates (collectly called MKSEMI).
  *
  * All rights reserved.
@@ -59,55 +59,55 @@
         .dma_tx_ch = DMA_CH7,
     },
 };
-//脪脝脰虏
-uint32_t SerialKeyPressed(uint8_t *key)//脜脨露脧脢媒戮脻脢脟路帽脢脮碌陆碌脛 MK8000脨脼赂脛
+//ò??2
+uint32_t SerialKeyPressed(uint8_t *key)//?D??êy?Yê?·?ê?μ?μ? MK8000DT??
 {
     uint32_t status = uart_handle[1].base->STATUS;
-  if (status & UART_STATUS_DR_MSK)
-  { 
-        //Serial0PutString("鲁脡鹿娄陆脫脢脮ing");
+    if (status & UART_STATUS_DR_MSK)
+    {
+        //Serial0PutString("3é1|?óê?ing");
         //uart_receive(UART_ID1,test_buf,10,NULL);
-    *key = (uint8_t)uart_handle[1].base->RX_DATA;
+        *key = (uint8_t)uart_handle[1].base->RX_DATA;
         //uart_rx_fifo_clear(UART_ID1);
-    return 1;
-  }
-  else
-  {
-    return 0;
-  }
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
 }
 void SerialPutChar(uint8_t c)
 {
     while (uart_handle[0].base->TX_FL)
-        {
-        }
-uart_send(UART_ID1, &c, 1, NULL);
+    {
+    }
+    uart_send(UART_ID1, &c, 1, NULL);
 }
 
 void Serial_PutString(uint8_t *s)
 {
-  while (*s != '\0')
-  {
-    SerialPutChar(*s);
-    s++;
-  }
+    while (*s != '\0')
+    {
+        SerialPutChar(*s);
+        s++;
+    }
 }
 void Serial0PutChar(uint8_t c)
-    {//脜脨露脧脢媒戮脻禄潞麓忙脟酶脦陋驴脮录麓脡脧脪禄赂枚脳脰陆脷脢媒戮脻脪脩戮颅卤禄脣脥碌陆路垄脣脥录脛麓忙脝梅路垄脣脥鲁枚脠楼脕脣
-        // wait TX FIFO empty
-        while (uart_handle[0].base->TX_FL)
-        {
-        }
-uart_send(UART_ID0, &c, 1, NULL);
+{   //?D??êy?Y?o′????a???′é?ò???×??úêy?Yò??-±??íμ?·¢?í??′??÷·¢?í3?è¥á?
+    // wait TX FIFO empty
+    while (uart_handle[0].base->TX_FL)
+    {
+    }
+    uart_send(UART_ID0, &c, 1, NULL);
 }
 
 void Serial0_PutString(uint8_t *s)
 {
-  while (*s != '\0')
-  {
-    Serial0PutChar(*s);
-    s++;
-  }
+    while (*s != '\0')
+    {
+        Serial0PutChar(*s);
+        s++;
+    }
 }
 static const struct UART_DIVISOR_T baud_table[] = {
     {89, 6, 32},  // 1200
@@ -193,15 +193,24 @@
     return uart_handle[id].state;
 }
 
-bool uart_tx_in_progress(enum UART_DEV_T id)
+bool uart_is_busy(enum UART_DEV_T id)
 {
-    return ((uart_handle[id].state & UART_STATE_BUSY_TX) && (uart_handle[id].base->STATUS & UART_STATUS_BUSY_MSK));
+    // - Transmission in progress on serial interface
+    // - Transmit data present in TX FIFO
+    // - Reception in progress on the interface
+    // - Receive data present in RX FIFO
+    // - [Patch] UART is not enabled but RX is pulled low
+    return ((uart_handle[id].state != UART_STATE_RESET) && (uart_handle[id].base->STATUS & UART_STATUS_BUSY_MSK));
 }
 
-bool uart_fifo_busy(enum UART_DEV_T id)
+bool uart_tx_in_progress(enum UART_DEV_T id)
 {
-    // UART is not enabled but RX is pulled low
-    return ((uart_handle[id].state != UART_STATE_RESET) && (uart_handle[id].base->STATUS & UART_STATUS_BUSY_MSK));
+    return ((uart_handle[id].state & UART_STATE_BUSY_TX) || !(uart_handle[id].base->STATUS & UART_STATUS_TEMT_MSK));
+}
+
+bool uart_tx_fifo_is_empty(enum UART_DEV_T id)
+{
+    return (uart_handle[id].base->STATUS & UART_STATUS_TEMT_MSK);
 }
 
 void uart_rx_fifo_clear(enum UART_DEV_T id)
@@ -210,6 +219,13 @@
     while (uart_handle[id].base->STATUS & UART_STATUS_RFNE_MSK)
     {
         uart_handle[id].base->RX_DATA;
+    }
+
+    if (uart_handle[id].dma_en)
+    {
+        // reset RX FIFO, clear DMA request for rx fifo
+        // Note: It is not recommended to use UART DMA software ack, as this may affect the actively working TX unless in half-duplex mode
+        uart_handle[id].base->CTRL0 = uart_handle[id].ctrl0 | UART_CTRL0_RX_FIFO_RESET_MSK;
     }
 }
 
@@ -432,14 +448,6 @@
         while (uart_handle[id].tx_count < uart_handle[id].tx_size)
         {
             status = uart_handle[id].base->STATUS;
-            if (status & (UART_STATUS_OE_MSK | UART_STATUS_PE_MSK | UART_STATUS_FE_MSK | UART_STATUS_BI_MSK | UART_STATUS_RFE_MSK))
-            {
-                // TODO: user handle the error case
-                uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK;
-                status |= UART_ERR_LINE;
-                ret = DRV_ERROR;
-                break;
-            }
 
             if (uart_handle[id].base->STATUS & UART_STATUS_TFNF_MSK)
             {
@@ -544,8 +552,6 @@
             if (status & (UART_STATUS_OE_MSK | UART_STATUS_PE_MSK | UART_STATUS_FE_MSK | UART_STATUS_BI_MSK | UART_STATUS_RFE_MSK))
             {
                 // TODO: user handle the error case
-                // Clear error bits
-                uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK;
                 status |= UART_ERR_LINE;
                 ret = DRV_ERROR;
                 break;
@@ -569,6 +575,91 @@
     }
 
     return ret;
+}
+
+int uart_dma_receive_with_llp(enum UART_DEV_T id, uint8_t *rx_buf, uint32_t len, struct DMA_LINK_DESC_T *desc, drv_callback_t callback)
+{
+    if ((rx_buf == 0) || (len == 0) || !(uart_handle[id].dma_en) || (desc == NULL))
+    {
+        return DRV_ERROR;
+    }
+
+    // update state
+    int ret = uart_state_set(id, UART_STATE_BUSY_RX);
+    if (ret != DRV_OK)
+    {
+        return ret;
+    }
+
+    uart_handle[id].rx_callback = callback;
+
+    // fix TX output low level when host MCU reset
+    uint32_t err_code = uart_handle[id].base->STATUS;
+    if (err_code & (UART_STATUS_FE_MSK | UART_STATUS_BI_MSK | UART_STATUS_RFE_MSK))
+    {
+        // reset FIFO
+        uart_handle[id].base->CTRL0 = UART_CTRL0_RX_FIFO_RESET_MSK | UART_CTRL0_TX_FIFO_RESET_MSK;
+        // clear STATUS
+        uart_handle[id].base->INTR_CLR =
+            UART_INTR_CLR_THRE_INT_CLR_MSK | UART_INTR_CLR_BUSY_INT_CLR_MSK | UART_INTR_CLR_LSR_INT_CLR_MSK | UART_INTR_CLR_MSR_INT_CLR_MSK;
+        uart_handle[id].base->CTRL0 = uart_handle[id].ctrl0;
+    }
+
+    struct DMA_CH_CFG_T uart_rx_dma_cfg = {
+        .fifo_th = DMA_FIFO_TH_1,
+        .src_burst_size = DMA_SRC_BURST_SIZE_1,
+        .src_width = DMA_WIDTH_1B,
+        .dst_width = DMA_WIDTH_1B,
+        .src_addr_ctrl = DMA_ADDR_FIXED,
+        .dst_addr_ctrl = DMA_ADDR_INC,
+        .src_req_sel = (id == UART_ID1 ? DMA_REQ_UART1_RX : DMA_REQ_UART0_RX),
+        .dst_req_sel = DMA_REQ_MEM,
+    };
+    uart_handle[id].dma_rx_err_state = 0;
+
+    NVIC_ClearPendingIRQ(uart_handle[id].irq);
+    // Enable Receiver Line Status Interrupt, used to obtain the error interrupt event triggered by the receiver
+    uart_handle[id].base->INTR_EN = (UART_INTR_EN_ELCOLR_MSK | UART_INTR_EN_ELSI_MSK);
+
+    dma_open(uart_handle[id].dma_rx_ch, &uart_rx_dma_cfg);
+    DMA->CH[uart_handle[id].dma_rx_ch].CHAIN_PTR = (uint32_t)desc;
+    while (desc)
+    {
+        desc->src_addr = (uint32_t)&uart_handle[id].base->RX_DATA;
+        desc->ctrl = uart_rx_dma_cfg.fifo_th << 29 | uart_rx_dma_cfg.src_width << 25 | uart_rx_dma_cfg.dst_width << 22 | uart_rx_dma_cfg.src_addr_ctrl << 20 |
+                     uart_rx_dma_cfg.dst_addr_ctrl << 18;
+        desc = desc->nxt;
+    }
+    dma_transfer(uart_handle[id].dma_rx_ch, (uint8_t *)&uart_handle[id].base->RX_DATA, rx_buf, len, uart_dma_callback);
+
+    return ret;
+}
+
+void uart_send_over_fifo(enum UART_DEV_T id, uint8_t *tx_buf, uint32_t len)
+{
+    for (uint32_t i = 0; i < len; i++)
+    {
+        uart_handle[id].base->TX_DATA = tx_buf[i];
+    }
+}
+
+uint32_t uart_receive_from_fifo(enum UART_DEV_T id, uint8_t *rx_buf, uint32_t len)
+{
+    for (uint32_t i = 0; i < len; i++)
+    {
+        uint32_t status = uart_handle[id].base->STATUS;
+
+        if (status & UART_STATUS_RFNE_MSK)
+        {
+            rx_buf[i] = (uint8_t)uart_handle[id].base->RX_DATA;
+        }
+        else
+        {
+            return i;
+        }
+    }
+
+    return len;
 }
 
 int uart_tx_abort_dma(enum UART_DEV_T id, drv_callback_t abort_tx_callback)
@@ -598,6 +689,24 @@
         uart_handle[id].base->CTRL0 = uart_handle[id].ctrl0 | UART_CTRL0_RX_FIFO_RESET_MSK;
         uart_handle[id].rx_abort_callback = abort_rx_callback;
         ret = dma_abort(uart_handle[id].dma_rx_ch, uart_dma_abort_callback);
+    }
+#endif
+    return ret;
+}
+
+int uart_rx_force_abort_dma(enum UART_DEV_T id, drv_callback_t abort_rx_callback)
+{
+    int ret = DRV_ERROR;
+#if UART_DMA_MODE_EN
+    if (uart_handle[id].dma_en)
+    {
+        // RX err - disable interrupts
+        uart_handle[id].base->INTR_EN &= ~(UART_INTR_EN_ELCOLR_MSK | UART_INTR_EN_ELSI_MSK);
+        // reset rx FIFO, de-assert the DMA RX request
+        uart_handle[id].base->CTRL0 = uart_handle[id].ctrl0 | UART_CTRL0_RX_FIFO_RESET_MSK;
+        uart_handle[id].rx_abort_callback = abort_rx_callback;
+        dma_force_abort(uart_handle[id].dma_rx_ch, uart_dma_abort_callback);
+        ret = DRV_OK;
     }
 #endif
     return ret;
@@ -710,6 +819,16 @@
             // RX done
             usr_callback = uart_handle[id].rx_callback;
 
+            if ((DMA->CH[uart_handle[id].dma_rx_ch].CFG & 0x000F0000) != 0)
+            {
+                if (usr_callback)
+                {
+                    usr_callback(&id, err_code);
+                }
+
+                return;
+            }
+
             // update state
             uart_state_clear(id, UART_STATE_BUSY_RX);
         }
@@ -747,26 +866,22 @@
 void uart_irq_handler(enum UART_DEV_T id)
 {
     drv_callback_t usr_callback = NULL;
-    uint32_t err_code = 0;
-
-    // read interrupt ID
-    uint8_t iid = uart_handle[id].base->INTR_STATUS & 0x0f;
+    uint32_t err_code = uart_handle[id].base->STATUS;
 
     // If DMA is enabled, the uart interrupt handler is only used to handle the error events reported by the receiver
     if (uart_handle[id].dma_en)
     {
 #if UART_DMA_MODE_EN
-        err_code = uart_handle[id].base->STATUS;
         // iid == 0xC: The precondition that the timeout event will not be triggered is that the length of
         // the received data is an integer multiple of the RX FIFO level
-        if ((err_code & UART_STATUS_ERROR_MSK) || (iid == 0x0C) || (iid == 0x01))
+        if (err_code & UART_STATUS_ERROR_MSK)
         {
             // RX err - disable interrupts
             uart_handle[id].base->INTR_EN &= ~UART_INTR_EN_ELSI_MSK;
             uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK;
-            uart_handle[id].dma_rx_err_state = UART_ERR_LINE | iid;
+            uart_handle[id].dma_rx_err_state = UART_ERR_LINE;
             usr_callback = uart_handle[id].rx_callback;
-            err_code = UART_ERR_LINE | iid;
+            err_code |= UART_ERR_LINE;
 
             // update state
             uart_state_clear(id, UART_STATE_BUSY_RX);
@@ -781,13 +896,16 @@
     else
     {
 #if UART_INT_MODE_EN
+        // read interrupt ID
+        uint8_t iid = uart_handle[id].base->INTR_STATUS & 0x0f;
+
         switch (iid)
         {
             // modem status
             case 0x0:
                 // clear int
                 uart_handle[id].base->INTR_CLR = UART_INTR_CLR_MSR_INT_CLR_MSK;
-                err_code = UART_ERR_MODEM | iid;
+                err_code |= UART_ERR_MODEM;
                 break;
 
             // no interrupt pending
@@ -869,16 +987,24 @@
 
             // receiver line status
             case 0x6:
-                // clear int
+                // clear int (Overrun/parity/framing errors, break interrupt, or address received interrupt)
+                // RX err - disable interrupts
+                uart_handle[id].base->INTR_EN &= ~UART_INTR_EN_ELSI_MSK;
                 uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK;
-                err_code = UART_ERR_LINE | iid;
+                usr_callback = uart_handle[id].rx_callback;
+                err_code |= UART_ERR_LINE;
+
+                uart_handle[id].rx_buff = NULL;
+                uart_handle[id].rx_callback = NULL;
+                uart_handle[id].rx_count = 0;
+                uart_handle[id].rx_size = 0;
                 break;
 
             // busy detect
             case 0x7:
                 // clear int
                 uart_handle[id].base->INTR_CLR = UART_INTR_CLR_BUSY_INT_CLR_MSK;
-                err_code = UART_ERR_BUSY | iid;
+                err_code |= UART_ERR_BUSY;
                 break;
 
             default:

--
Gitblit v1.9.3