Browse Source

[Nuvoton] Update drivers.

1. ARM9 EHCI timeout issue.
2. Sync mainstream.
Wayne Lin 3 years ago
parent
commit
c07b2b0a07

+ 0 - 19
bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c

@@ -43,23 +43,6 @@
     static uint8_t _SDH1_ucSDHCBuffer[512] __attribute__((aligned(32)));
 #endif
 
-void dump_sdh_regs(SDH_T *sdh)
-{
-    rt_kprintf("\n+++++++++++++++++++++++\n");
-    rt_kprintf("    %s\n", sdh->CTL & SDH_CTL_SDPORT_Msk ? "SD1" : "SD0");
-    rt_kprintf("    DMACTL   = 0x%08x\n", sdh->DMACTL);
-    rt_kprintf("    GCTL   = 0x%08x\n", sdh->GCTL);
-    rt_kprintf("    GINTEN   = 0x%08x\n", sdh->GINTEN);
-    rt_kprintf("    GINTSTS   = 0x%08x\n", sdh->GINTSTS);
-    rt_kprintf("    CTL   = 0x%08x\n", sdh->CTL);
-    rt_kprintf("    INTEN   = 0x%08x\n", sdh->INTEN);
-    rt_kprintf("    INTSTS   = 0x%08x\n", sdh->INTSTS);
-    rt_kprintf("    BLEN   = 0x%08x\n", sdh->BLEN);
-    rt_kprintf("    TOUT   = 0x%08x\n", sdh->TOUT);
-    rt_kprintf("    ECTL   = 0x%08x\n", sdh->ECTL);
-    rt_kprintf("\n+++++++++++++++++++++++\n");
-}
-
 void SDH_CheckRB(SDH_T *sdh)
 {
     while (1)
@@ -405,8 +388,6 @@ uint32_t SDH_Init(SDH_T *sdh, SDH_INFO_T *pSD)
     pSD->R7Flag = 1ul;
     u32CmdTimeOut = 0xFFFFFul;
 
-    //dump_sdh_regs(sdh);
-
     i = SDH_SDCmdAndRsp(sdh, pSD, 8ul, 0x00000155ul, u32CmdTimeOut);
     if (i == Successful)
     {

+ 2 - 3
bsp/nuvoton/libraries/n9h30/UsbHostLib/src/ehci.c

@@ -907,7 +907,7 @@ static int visit_qtd(qTD_T *qtd)
     return 0;
 }
 
-static void scan_asynchronous_list()
+void scan_asynchronous_list()
 {
     QH_T    *qh, *qh_tmp;
     qTD_T   *q_pre, *qtd, *qtd_tmp;
@@ -1096,9 +1096,8 @@ void iaad_remove_qh()
 //void EHCI_IRQHandler(void)
 void nu_ehci_isr(int vector, void *param)
 {
-    uint32_t  intsts;
+    volatile uint32_t  intsts = _ehci->USTSR;
 
-    intsts = _ehci->USTSR;
     _ehci->USTSR = intsts;                  /* clear interrupt status                     */
 
     //USB_debug("ehci int_sts = 0x%x\n", intsts);

+ 21 - 41
bsp/nuvoton/libraries/n9h30/rtt_port/drv_usbhost.c

@@ -324,11 +324,7 @@ static rt_err_t nu_open_pipe(upipe_t pipe)
     {
         void *paddr = rt_malloc_align(512ul, CACHE_LINE_SIZE);
         RT_ASSERT(paddr != RT_NULL);
-#if defined(BSP_USING_MMU)
         psPortDev->asPipePktBuf[pipe->pipe_index] = (void *)((uint32_t)paddr | NON_CACHE_MASK);
-#else
-        psPortDev->asPipePktBuf[pipe->pipe_index] = paddr;
-#endif
     }
 #endif
 
@@ -380,9 +376,7 @@ static rt_err_t nu_close_pipe(upipe_t pipe)
         if (psPortDev->asPipePktBuf[pipe->pipe_index])
         {
             void *paddr = psPortDev->asPipePktBuf[pipe->pipe_index];
-#if defined(BSP_USING_MMU)
             paddr = (void *)((uint32_t)paddr & ~NON_CACHE_MASK);
-#endif
             rt_free_align(paddr);
             psPortDev->asPipePktBuf[pipe->pipe_index] = RT_NULL;
         }
@@ -431,55 +425,41 @@ static int nu_bulk_xfer(
     UTR_T *psUTR,
     int timeouts)
 {
+    #define TIMEOUT_RETRY 3
 
-#define TIMEOUT_RETRY 10
-
-    UTR_T *psUTR_tmp = NULL;
     int retry = TIMEOUT_RETRY;
-    int ret;
-    int new_timeouts = timeouts / TIMEOUT_RETRY;
-    new_timeouts = (new_timeouts < 200) ? 200 : new_timeouts;
-
-    psUTR_tmp = alloc_utr(psPortDev->pUDev);
-    if (!psUTR_tmp)
+    int ret = usbh_bulk_xfer(psUTR);
+    if (ret < 0)
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_bulk_xfer ERROR: unable alloc UTR\n"));
-        return -1;
+        rt_kprintf("usbh_bulk_xfer %x\n", ret);
+        return ret;
     }
 
-    rt_memcpy((void *)psUTR_tmp, psUTR, sizeof(UTR_T));
-
-    while (retry > 0)
+    while ( retry > 0 )
     {
-        ret = usbh_bulk_xfer(psUTR);
-        if (ret < 0)
+        if ( rt_completion_wait(&(psPortDev->utr_completion), timeouts) != 0 )
         {
-            rt_kprintf("usbh_bulk_xfer %x\n", ret);
-            return ret;
-        }
+            rt_uint32_t level;
 
-        rt_thread_mdelay(1);
+            rt_kprintf("Request %d Timeout in %d ms!!\n", psUTR->data_len, timeouts);
 
-        //wait transfer done
-        if (rt_completion_wait(&(psPortDev->utr_completion), new_timeouts) == 0)
-        {
-            break;
+            rt_completion_init(&(psPortDev->utr_completion));
+            rt_thread_mdelay(1);
+
+            // Workaround: To fix timeout case, this way is traveling qh's linking-list again.
+            level = rt_hw_interrupt_disable();
+            extern void scan_asynchronous_list();
+            extern void iaad_remove_qh();
+            scan_asynchronous_list();
+            iaad_remove_qh();
+            rt_hw_interrupt_enable(level);
         }
         else
-        {
-            // Timeout, let's retry.
-            retry--;
-            rt_kprintf("[%d/%d]Request Timeout in %d ms!! (bulk_xfer %d)\n", retry, TIMEOUT_RETRY, new_timeouts, psUTR->data_len);
+            break;
 
-            // Unlink
-            ret = usbh_quit_utr(psUTR);
-            rt_memcpy(psUTR, (void *)psUTR_tmp, sizeof(UTR_T));
-            rt_completion_init(&(psPortDev->utr_completion));
-        }
+        retry--;
     }
 
-    free_utr(psUTR_tmp);
-
     return (retry > 0) ? 0 : -1;
 }
 

+ 4 - 3
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ehci.c

@@ -297,6 +297,8 @@ static int  ehci_init(void)
     _ehci->UCFGR = 0x1;                          /* enable port routing to EHCI           */
     _ehci->UIENR = HSUSBH_UIENR_USBIEN_Msk | HSUSBH_UIENR_UERRIEN_Msk | HSUSBH_UIENR_HSERREN_Msk | HSUSBH_UIENR_IAAEN_Msk;
 
+    _ehci->UASSTR = 0xfff;
+
     usbh_delay_ms(1);                              /* delay 1 ms                            */
 
     _ehci->UPSCR[0] = HSUSBH_UPSCR_PP_Msk;      /* enable port 1 port power               */
@@ -905,7 +907,7 @@ static int visit_qtd(qTD_T *qtd)
     return 0;
 }
 
-static void scan_asynchronous_list()
+void scan_asynchronous_list()
 {
     QH_T    *qh, *qh_tmp;
     qTD_T   *q_pre, *qtd, *qtd_tmp;
@@ -1094,9 +1096,8 @@ void iaad_remove_qh()
 //void EHCI_IRQHandler(void)
 void nu_ehci_isr(int vector, void *param)
 {
-    uint32_t  intsts;
+    volatile uint32_t  intsts = _ehci->USTSR;
 
-    intsts = _ehci->USTSR;
     _ehci->USTSR = intsts;                  /* clear interrupt status                     */
 
     //USB_debug("ehci int_sts = 0x%x\n", intsts);

+ 45 - 21
bsp/nuvoton/libraries/nuc980/rtt_port/drv_usbhost.c

@@ -181,12 +181,16 @@ static EP_INFO_T *GetFreePipe(
 
         if (i < NU_MAX_USBH_PIPE)
         {
-            EP_INFO_T *psEPInfo = rt_malloc(sizeof(EP_INFO_T));
+            EP_INFO_T *psEPInfo = (EP_INFO_T *)rt_malloc_align(sizeof(EP_INFO_T), CACHE_LINE_SIZE);
             if (psEPInfo != RT_NULL)
             {
+#if defined(BSP_USING_MMU)
+                psPortDev->apsEPInfo[i] = (EP_INFO_T *)((uint32_t)psEPInfo | NON_CACHE_MASK);
+#else
                 psPortDev->apsEPInfo[i] = psEPInfo;
+#endif
                 *pu8PipeIndex = i;
-                return psEPInfo;
+                return psPortDev->apsEPInfo[i];
             }
         }
     }
@@ -202,7 +206,11 @@ static void FreePipe(
             (u8PipeIndex < NU_MAX_USBH_PIPE) &&
             (psPortDev->apsEPInfo[u8PipeIndex] != RT_NULL))
     {
-        rt_free(psPortDev->apsEPInfo[u8PipeIndex]);
+        EP_INFO_T *psEPInfo = psPortDev->apsEPInfo[u8PipeIndex];
+#if defined(BSP_USING_MMU)
+        psEPInfo = (EP_INFO_T *)((uint32_t)psEPInfo & ~NON_CACHE_MASK);
+#endif
+        rt_free_align(psEPInfo);
         psPortDev->apsEPInfo[u8PipeIndex] = RT_NULL;
     }
 }
@@ -314,8 +322,9 @@ static rt_err_t nu_open_pipe(upipe_t pipe)
 #if defined(BSP_USING_MMU)
     if (!psPortDev->asPipePktBuf[pipe->pipe_index])
     {
-        psPortDev->asPipePktBuf[pipe->pipe_index] = rt_malloc_align(512ul, CACHE_LINE_SIZE);
-        RT_ASSERT(psPortDev->asPipePktBuf[pipe->pipe_index] != RT_NULL);
+        void *paddr = rt_malloc_align(512ul, CACHE_LINE_SIZE);
+        RT_ASSERT(paddr != RT_NULL);
+        psPortDev->asPipePktBuf[pipe->pipe_index] = (void *)((uint32_t)paddr | NON_CACHE_MASK);
     }
 #endif
 
@@ -366,7 +375,9 @@ static rt_err_t nu_close_pipe(upipe_t pipe)
 #if defined(BSP_USING_MMU)
         if (psPortDev->asPipePktBuf[pipe->pipe_index])
         {
-            rt_free_align(psPortDev->asPipePktBuf[pipe->pipe_index]);
+            void *paddr = psPortDev->asPipePktBuf[pipe->pipe_index];
+            paddr = (void *)((uint32_t)paddr & ~NON_CACHE_MASK);
+            rt_free_align(paddr);
             psPortDev->asPipePktBuf[pipe->pipe_index] = RT_NULL;
         }
 #endif
@@ -414,26 +425,42 @@ static int nu_bulk_xfer(
     UTR_T *psUTR,
     int timeouts)
 {
+    #define TIMEOUT_RETRY 3
+
+    int retry = TIMEOUT_RETRY;
     int ret = usbh_bulk_xfer(psUTR);
     if (ret < 0)
+    {
+        rt_kprintf("usbh_bulk_xfer %x\n", ret);
         return ret;
+    }
 
-    //wait transfer done
-    if (rt_completion_wait(&(psPortDev->utr_completion), timeouts) < 0)
+    while ( retry > 0 )
     {
-        rt_kprintf("Request Timeout in %d ms!! (bulk_xfer)\n", timeouts);
+        if ( rt_completion_wait(&(psPortDev->utr_completion), timeouts) != 0 )
+        {
+            rt_uint32_t level;
 
-        rt_kprintf("psUTR->buff: %08x\n", psUTR->buff);
-        rt_kprintf("psUTR->data_len: %d\n", psUTR->data_len);
-        rt_kprintf("psUTR->xfer_len: %d\n", psUTR->xfer_len);
-        rt_kprintf("psUTR->ep: %08x\n", psUTR->ep);
-        rt_kprintf("psUTR->bIsTransferDone: %08x\n", psUTR->bIsTransferDone);
-        rt_kprintf("psUTR->status: %08x\n", psUTR->status);
-        rt_kprintf("psUTR->td_cnt: %08x\n", psUTR->td_cnt);
+            rt_kprintf("Request %d Timeout in %d ms!!\n", psUTR->data_len, timeouts);
 
-        return -1;
+            rt_completion_init(&(psPortDev->utr_completion));
+            rt_thread_mdelay(1);
+
+            // Workaround: To fix timeout case, this way is traveling qh's linking-list again.
+            level = rt_hw_interrupt_disable();
+            extern void scan_asynchronous_list();
+            extern void iaad_remove_qh();
+            scan_asynchronous_list();
+            iaad_remove_qh();
+            rt_hw_interrupt_enable(level);
+        }
+        else
+            break;
+
+        retry--;
     }
-    return 0;
+
+    return (retry > 0) ? 0 : -1;
 }
 
 static int nu_int_xfer(
@@ -525,7 +552,6 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
         if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_OUT)
         {
             rt_memcpy(buffer_nonch, buffer, nbytes);
-            mmu_clean_dcache((uint32_t)buffer_nonch, nbytes);
         }
     }
 #endif
@@ -678,7 +704,6 @@ exit2_nu_pipe_xfer:
     {
         if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
         {
-            mmu_invalidate_dcache((uint32_t)buffer_nonch, nbytes);
             rt_memcpy(buffer, buffer_nonch, nbytes);
         }
     }
@@ -808,7 +833,6 @@ static rt_err_t nu_hcd_init(rt_device_t device)
 
     //install connect/disconnect callback
     usbh_install_conn_callback(nu_hcd_connect_callback, nu_hcd_disconnect_callback);
-    usbh_polling_root_hubs();
 
     //create thread for polling usbh port status
     /* create usb hub thread */

+ 2 - 0
bsp/nuvoton/nk-980iot/board/nu_pin_init.c

@@ -17,8 +17,10 @@ static void nu_pin_uart_init(void)
     /* UART0: GPF11, GPF12 */
     outpw(REG_SYS_GPF_MFPH, (inpw(REG_SYS_GPF_MFPH) & 0xfff00fff) | 0x11000);
 
+#if !defined(BOARD_USING_LCD_ILI9341)
     /* UART1: GPF9, GPF10 */
     outpw(REG_SYS_GPF_MFPH, (inpw(REG_SYS_GPF_MFPH) & 0xfffff00f) | 0x00220);
+#endif
 }
 
 static void nu_pin_emac_init(void)