Browse Source

Merge pull request #5319 from RT-Thread/master

【PSE分支】同步master到PSE分支
guo 3 years ago
parent
commit
fda37d55f8
94 changed files with 2894 additions and 1815 deletions
  1. 38 10
      bsp/bluetrum/ab32vg1-ab-prougen/.config
  2. BIN
      bsp/bluetrum/ab32vg1-ab-prougen/.settings/.rtmenus
  3. 1 1
      bsp/bluetrum/ab32vg1-ab-prougen/.settings/language.settings.xml
  4. 6 6
      bsp/bluetrum/ab32vg1-ab-prougen/.settings/projcfg.ini
  5. 3 3
      bsp/bluetrum/ab32vg1-ab-prougen/README.md
  6. 3 2
      bsp/bluetrum/ab32vg1-ab-prougen/applications/blehr_app.c
  7. 1 1
      bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c
  8. 12 17
      bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig
  9. 4 0
      bsp/bluetrum/ab32vg1-ab-prougen/board/SConscript
  10. 80 8
      bsp/bluetrum/ab32vg1-ab-prougen/board/board.c
  11. 43 0
      bsp/bluetrum/ab32vg1-ab-prougen/board/ports/fal_cfg.h
  12. 21 0
      bsp/bluetrum/ab32vg1-ab-prougen/board/ports/on_chip_flash_init.c
  13. 9 5
      bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h
  14. 1 1
      bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py
  15. 3 0
      bsp/bluetrum/libraries/hal_drivers/SConscript
  16. 140 0
      bsp/bluetrum/libraries/hal_drivers/drv_flash.c
  17. 42 0
      bsp/bluetrum/libraries/hal_drivers/drv_flash.h
  18. 2 4
      bsp/bluetrum/libraries/hal_drivers/drv_gpio.c
  19. 0 1
      bsp/bluetrum/libraries/hal_drivers/drv_rtc.c
  20. 3 38
      bsp/bluetrum/libraries/hal_drivers/drv_soft_i2c.c
  21. 2 1
      bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal.h
  22. BIN
      bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/libhal.a
  23. 7 9
      bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal.c
  24. 2 1
      bsp/bluetrum/libraries/hal_libraries/bmsis/source/startup.S
  25. 1 1
      bsp/ck802/libraries/include/drv_rtc.h
  26. 1 1
      bsp/ft2004/libraries/bsp/ft_i2c/ft_i2c_selftest.c
  27. 1 1
      bsp/imxrt/libraries/drivers/drv_rtc.c
  28. 1 1
      bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.h
  29. 33 14
      bsp/nrf5x/libraries/drivers/drv_i2c.c
  30. 58 0
      bsp/nrf5x/nrf52840/board/Kconfig
  31. 28 12
      bsp/nuvoton/libraries/m031/rtt_port/drv_i2c.c
  32. 7 0
      bsp/nuvoton/libraries/m2354/USBHostLib/src/ohci.c
  33. 33 16
      bsp/nuvoton/libraries/m2354/rtt_port/drv_i2c.c
  34. 345 307
      bsp/nuvoton/libraries/m2354/rtt_port/drv_usbhost.c
  35. 6 0
      bsp/nuvoton/libraries/m480/USBHostLib/src/ehci.c
  36. 6 0
      bsp/nuvoton/libraries/m480/USBHostLib/src/ohci.c
  37. 33 19
      bsp/nuvoton/libraries/m480/rtt_port/drv_i2c.c
  38. 244 208
      bsp/nuvoton/libraries/m480/rtt_port/drv_usbhost.c
  39. 22 15
      bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h
  40. 188 198
      bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c
  41. 4 3
      bsp/nuvoton/libraries/n9h30/UsbHostLib/src/ehci.c
  42. 61 103
      bsp/nuvoton/libraries/n9h30/UsbHostLib/src/support.c
  43. 2 2
      bsp/nuvoton/libraries/n9h30/UsbHostLib/src/usb_core.c
  44. 6 2
      bsp/nuvoton/libraries/n9h30/rtt_port/Kconfig
  45. 1 1
      bsp/nuvoton/libraries/n9h30/rtt_port/drv_ge2d.c
  46. 5 5
      bsp/nuvoton/libraries/n9h30/rtt_port/drv_i2s.c
  47. 220 31
      bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c
  48. 12 8
      bsp/nuvoton/libraries/n9h30/rtt_port/drv_sys.c
  49. 93 30
      bsp/nuvoton/libraries/n9h30/rtt_port/drv_usbhost.c
  50. 47 12
      bsp/nuvoton/libraries/nu_packages/AudioCodec/acodec_nau8822.c
  51. 1 0
      bsp/nuvoton/libraries/nu_packages/BMX055/sensor_bmx055.c
  52. 5 0
      bsp/nuvoton/libraries/nu_packages/Kconfig
  53. 1 0
      bsp/nuvoton/libraries/nu_packages/MAX31875/sensor_max31875.c
  54. 2 1
      bsp/nuvoton/libraries/nu_packages/SPINAND/drv_spinand.c
  55. 104 21
      bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.c
  56. 30 27
      bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.h
  57. 6 3
      bsp/nuvoton/libraries/nuc980/Driver/Include/nu_emac.h
  58. 15 3
      bsp/nuvoton/libraries/nuc980/Driver/Source/nu_emac.c
  59. 39 86
      bsp/nuvoton/libraries/nuc980/Driver/Source/nu_pdma.c
  60. 2 2
      bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/config.h
  61. 4 3
      bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ehci.c
  62. 52 102
      bsp/nuvoton/libraries/nuc980/UsbHostLib/src/support.c
  63. 107 44
      bsp/nuvoton/libraries/nuc980/rtt_port/drv_emac.c
  64. 21 6
      bsp/nuvoton/libraries/nuc980/rtt_port/drv_i2c.c
  65. 5 5
      bsp/nuvoton/libraries/nuc980/rtt_port/drv_i2s.c
  66. 0 1
      bsp/nuvoton/libraries/nuc980/rtt_port/drv_sys.c
  67. 93 30
      bsp/nuvoton/libraries/nuc980/rtt_port/drv_usbhost.c
  68. 65 59
      bsp/nuvoton/nk-980iot/.config
  69. 2 0
      bsp/nuvoton/nk-980iot/board/nu_pin_init.c
  70. 29 51
      bsp/nuvoton/nk-n9h30/.config
  71. 2 2
      bsp/nuvoton/nk-n9h30/board/Kconfig
  72. 95 64
      bsp/nuvoton/nk-rtu980/.config
  73. 1 1
      bsp/qemu-virt64-aarch64/link.lds
  74. 1 1
      bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h
  75. 1 1
      bsp/raspberry-pi/raspi3-64/link.lds
  76. 1 1
      bsp/raspberry-pi/raspi4-64/link.lds
  77. 38 0
      bsp/stm32/stm32l496-st-nucleo/board/Kconfig
  78. 1 1
      bsp/swm320-lq100/applications/main.c
  79. 1 1
      bsp/swm320/applications/main.c
  80. 2 1
      components/drivers/include/drivers/alarm.h
  81. 1 1
      components/drivers/rtc/rtc.c
  82. 84 0
      components/drivers/src/dataqueue.c
  83. 8 4
      components/finsh/cmd.c
  84. 1 1
      components/net/at/at_socket/at_socket.c
  85. 1 1
      examples/kernel/event_simple.c
  86. 14 25
      libcpu/aarch64/common/context_gcc.S
  87. 4 3
      libcpu/aarch64/common/stack.c
  88. 1 1
      libcpu/aarch64/common/vector_gcc.S
  89. 10 9
      libcpu/aarch64/cortex-a/entry_point.S
  90. 111 111
      src/Kconfig
  91. 13 31
      src/kservice.c
  92. 1 0
      src/thread.c
  93. 2 2
      src/timer.c
  94. 36 11
      tools/building.py

+ 38 - 10
bsp/bluetrum/ab32vg1-ab-prougen/.config

@@ -23,7 +23,7 @@ CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
 CONFIG_IDLE_THREAD_STACK_SIZE=512
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
-CONFIG_RT_TIMER_THREAD_STACK_SIZE=256
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=1024
 
 #
 # kservice optimization
@@ -31,6 +31,9 @@ CONFIG_RT_TIMER_THREAD_STACK_SIZE=256
 # CONFIG_RT_KSERVICE_USING_STDLIB is not set
 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
 # CONFIG_RT_USING_ASM_MEMCPY is not set
+# CONFIG_RT_USING_ASM_MEMSET is not set
+# CONFIG_RT_USING_TINY_FFS is not set
+# CONFIG_RT_PRINTF_LONGLONG is not set
 CONFIG_RT_DEBUG=y
 # CONFIG_RT_DEBUG_COLOR is not set
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -76,8 +79,7 @@ CONFIG_RT_USING_DEVICE_OPS=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=128
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
-# CONFIG_RT_PRINTF_LONGLONG is not set
-CONFIG_RT_VER_NUM=0x40004
+CONFIG_RT_VER_NUM=0x40100
 # CONFIG_RT_USING_CPU_FFS is not set
 # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 
@@ -88,6 +90,7 @@ CONFIG_RT_USING_COMPONENTS_INIT=y
 CONFIG_RT_USING_USER_MAIN=y
 CONFIG_RT_MAIN_THREAD_STACK_SIZE=1024
 CONFIG_RT_MAIN_THREAD_PRIORITY=10
+# CONFIG_RT_USING_LEGACY is not set
 
 #
 # C++ features
@@ -117,6 +120,14 @@ CONFIG_FINSH_ARG_MAX=10
 # Device virtual file system
 #
 # CONFIG_RT_USING_DFS is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_0 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
 
 #
 # Device Drivers
@@ -163,10 +174,13 @@ CONFIG_RT_USING_PIN=y
 #
 # POSIX layer and C standard library
 #
-# CONFIG_RT_USING_LIBC is not set
-# CONFIG_RT_USING_PTHREADS is not set
+CONFIG_RT_USING_LIBC=y
 CONFIG_RT_LIBC_USING_TIME=y
+# CONFIG_RT_LIBC_USING_FILEIO is not set
+# CONFIG_RT_USING_MODULE is not set
 CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
+# CONFIG_RT_USING_POSIX is not set
+# CONFIG_RT_USING_PTHREADS is not set
 
 #
 # Network
@@ -304,6 +318,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
 # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
 # CONFIG_PKG_USING_HM is not set
+# CONFIG_PKG_USING_SMALL_MODBUS is not set
 
 #
 # security packages
@@ -351,6 +366,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_U8G2_OFFICIAL is not set
 # CONFIG_PKG_USING_U8G2 is not set
 
+#
+# PainterEngine: A cross-platform graphics application framework written in C language
+#
+# CONFIG_PKG_USING_PAINTERENGINE is not set
+# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
+
 #
 # tools packages
 #
@@ -392,6 +413,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_MEM_SANDBOX is not set
 # CONFIG_PKG_USING_SOLAR_TERMS is not set
 # CONFIG_PKG_USING_GAN_ZHI is not set
+# CONFIG_PKG_USING_FDT is not set
 
 #
 # system packages
@@ -405,6 +427,13 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
 # CONFIG_PKG_USING_QFPLIB_M3 is not set
 
+#
+# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
+#
+# CONFIG_PKG_USING_CMSIS_5 is not set
+# CONFIG_PKG_USING_CMSIS_5_AUX is not set
+# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
+
 #
 # Micrium: Micrium software products porting for RT-Thread
 #
@@ -422,7 +451,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_FLASHDB is not set
 # CONFIG_PKG_USING_SQLITE is not set
 # CONFIG_PKG_USING_RTI is not set
-# CONFIG_PKG_USING_CMSIS is not set
 # CONFIG_PKG_USING_DFS_YAFFS is not set
 # CONFIG_PKG_USING_LITTLEFS is not set
 # CONFIG_PKG_USING_DFS_JFFS2 is not set
@@ -439,6 +467,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_QBOOT is not set
 # CONFIG_PKG_USING_PPOOL is not set
 # CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
 # CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
 # CONFIG_PKG_USING_LPM is not set
 # CONFIG_PKG_USING_TLSF is not set
@@ -599,12 +628,14 @@ CONFIG_PKG_BLUETRUM_SDK_VER="latest"
 # Hardware Drivers Config
 #
 CONFIG_SOC_AB32VG1=y
+# CONFIG_PKG_USING_BLUETRUM_NIMBLE is not set
 
 #
 # Onboard Peripheral Drivers
 #
 # CONFIG_BSP_USING_AUDIO is not set
 # CONFIG_BSP_USING_SDCARD is not set
+# CONFIG_BSP_USING_NIMBLE is not set
 
 #
 # On-chip Peripheral Drivers
@@ -622,8 +653,5 @@ CONFIG_BSP_UART0_FIFO_SIZE=10
 # CONFIG_BSP_USING_ONCHIP_RTC is not set
 # CONFIG_BSP_USING_ADC is not set
 # CONFIG_BSP_USING_IRRX is not set
-
-#
-# Board extended module Drivers
-#
+# CONFIG_BSP_USING_ON_CHIP_FLASH is not set
 CONFIG_BOARD_BLUETRUM_EVB=y

BIN
bsp/bluetrum/ab32vg1-ab-prougen/.settings/.rtmenus


+ 1 - 1
bsp/bluetrum/ab32vg1-ab-prougen/.settings/language.settings.xml

@@ -5,7 +5,7 @@
 			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
-			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-309903127852947962" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="530397848961880773" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 				<language-scope id="org.eclipse.cdt.core.gcc"/>
 				<language-scope id="org.eclipse.cdt.core.g++"/>
 			</provider>

+ 6 - 6
bsp/bluetrum/ab32vg1-ab-prougen/.settings/projcfg.ini

@@ -1,19 +1,19 @@
 #RT-Thread Studio Project Configuration
-#Wed Dec 16 14:30:21 CST 2020
+#Wed Nov 24 11:34:07 CST 2021
 cfg_version=v3.0
 board_name=AB32VG1-AB-PROUGEN
 example_name=
-hardware_adapter=DAP-LINK
-project_type=rt-thread
+hardware_adapter=ST-LINK
 board_base_nano_proj=False
+project_type=rt-thread
 chip_name=AB32VG1
 selected_rtt_version=latest
-bsp_version=1.0.0
+bsp_version=1.1.0
 os_branch=full
-output_project_path=D\:/Softwares/RT-ThreadStudio/workspace
+output_project_path=D\:\\code\\rt_thread\\studio\\ab32vg1
 is_base_example_project=False
 is_use_scons_build=True
 project_base_bsp=true
 project_name=ab32vg1
 os_version=latest
-bsp_path=repo/Local/Board_Support_Packages/Bluetrum/AB32VG1-AB-PROUGEN/1.0.0
+bsp_path=repo/Extract/Board_Support_Packages/Bluetrum/AB32VG1-AB-PROUGEN/1.1.0

+ 3 - 3
bsp/bluetrum/ab32vg1-ab-prougen/README.md

@@ -70,12 +70,12 @@ ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核
 | GPIO         |     支持     | PA PB PE PF                               |
 | UART         |     支持     | UART0/1/2                                 |
 | SDIO         |     支持     |                                           |
-| ADC          |     支持     | 10bit ADC                                 |
-| SPI          |   即将支持   | 软件 SPI                                  |
+| ADC          |     支持     | 10bit SRADC  16bit SDADC                  |
+| SPI          |   即将支持   |                                           |
 | I2C          |     支持     | 软件 I2C                                  |
 | RTC          |     支持     |                                           |
 | WDT          |     支持     |                                           |
-| FLASH        |   即将支持   | 对接 FAL                                  |
+| FLASH        |     支持     | 对接 FAL                                  |
 | TIMER        |     支持     |                                           |
 | PWM          |     支持     | LPWM 的 G1 G2 G3 之间是互斥的,只能三选一 |
 | FM receive   |     支持     |                                           |

+ 3 - 2
bsp/bluetrum/ab32vg1-ab-prougen/applications/blehr_app.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, Bluetrum Development Team
+ * Copyright (c) 2021-2021, Bluetrum Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -64,7 +64,8 @@ static int blehr_sample(void)
         15,
         1);
 
-    if (tid != RT_NULL) {
+    if (tid != RT_NULL)
+    {
         rt_thread_startup(tid);
     }
 }

+ 1 - 1
bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c

@@ -26,7 +26,7 @@ void sd_mount(void *parameter)
     while (1)
     {
         rt_thread_mdelay(500);
-        if(rt_device_find("sd0") != RT_NULL)
+        if (rt_device_find("sd0") != RT_NULL)
         {
             if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK)
             {

+ 12 - 17
bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig

@@ -1,12 +1,12 @@
 menu "Hardware Drivers Config"
 
-config SOC_AB32VG1
-    bool
+menuconfig SOC_AB32VG1
+    bool "SOC_AB32VG1"
     select PKG_USING_BLUETRUM_SDK
     default y
 
-config PKG_USING_BLUETRUM_NIMBLE
-    bool
+menuconfig PKG_USING_BLUETRUM_NIMBLE
+    bool "PKG_USING_BLUETRUM_NIMBLE"
     default n
 
 menu "Onboard Peripheral Drivers"
@@ -34,6 +34,11 @@ menu "Onboard Peripheral Drivers"
         default 24000000
     endif
 
+    config BSP_USING_NIMBLE
+        bool "use nimble stack(iot)"
+        select PKG_USING_BLUETRUM_NIMBLE
+        default n
+
 endmenu
 
 menu "On-chip Peripheral Drivers"
@@ -233,20 +238,10 @@ menu "On-chip Peripheral Drivers"
                 default n
         endif
 
+    config BSP_USING_ON_CHIP_FLASH
+        bool "Enable on-chip FLASH"
+        default n
 endmenu
 
-choice
-    prompt "BLE STACK"
-    default BLE_STACK_USING_NULL
-    help
-        Select the ble stack
-
-    config BLE_STACK_USING_NULL
-        bool "not use the ble stack"
-
-    config BSP_USING_NIMBLE
-        bool "use nimble stack(iot)"
-        select PKG_USING_BLUETRUM_NIMBLE
-endchoice
 
 endmenu

+ 4 - 0
bsp/bluetrum/ab32vg1-ab-prougen/board/SConscript

@@ -8,10 +8,14 @@ board.c
 ab32vg1_hal_msp.c
 ''')
 CPPPATH = [cwd]
+CPPPATH += [cwd + '/ports']
 
 if GetDepend(['RT_USING_AUDIO']):
     src += Glob('ports/audio/drv_sound.c')
 
+if GetDepend(['BSP_USING_ON_CHIP_FLASH']):
+    src += Glob('ports/on_chip_flash_init.c')
+
 group = DefineGroup('Board', src, depend = [''], CPPPATH = CPPPATH)
 
 objs = [group]

+ 80 - 8
bsp/bluetrum/ab32vg1-ab-prougen/board/board.c

@@ -68,6 +68,28 @@ void hal_printf(const char *fmt, ...)
 }
 #endif
 
+RT_SECTION(".irq")
+void os_interrupt_enter(void)
+{
+    rt_interrupt_enter();
+}
+
+RT_SECTION(".irq")
+void os_interrupt_leave(void)
+{
+    rt_interrupt_leave();
+}
+
+typedef void (*isr_t)(void);
+RT_SECTION(".irq")
+isr_t register_isr(int vector, isr_t isr)
+{
+    char buf[8] = {0};
+    rt_snprintf(buf, sizeof(buf), "sys%d", vector);
+    rt_isr_handler_t handle = (rt_isr_handler_t)isr;
+    rt_hw_interrupt_install(vector, handle, RT_NULL, buf);
+}
+
 RT_SECTION(".irq.timer")
 void timer0_isr(int vector, void *param)
 {
@@ -94,9 +116,55 @@ void timer0_cfg(uint32_t ticks)
     TMR0CON |= BIT(0); // EN
 }
 
-void hal_mdelay(uint32_t ms)
+uint32_t hal_get_ticks(void)
+{
+    return rt_tick_get();
+}
+
+void hal_mdelay(uint32_t nms)
+{
+    rt_thread_mdelay(nms);
+}
+
+void hal_udelay(uint32_t nus)
 {
-    rt_thread_mdelay(ms);
+    rt_hw_us_delay(nus);
+}
+
+/**
+ * The time delay function.
+ *
+ * @param us microseconds.
+ */
+RT_SECTION(".com_text")
+void rt_hw_us_delay(rt_uint32_t us)
+{
+    rt_uint32_t ticks;
+    rt_uint32_t told, tnow, tcnt = 0;
+    rt_uint32_t reload = TMR0PR;
+
+    ticks = us * reload / (1000 / RT_TICK_PER_SECOND);
+    told = TMR0CNT;
+    while (1)
+    {
+        tnow = TMR0CNT;
+        if (tnow != told)
+        {
+            if (tnow < told)
+            {
+                tcnt += told - tnow;
+            }
+            else
+            {
+                tcnt += reload - tnow + told;
+            }
+            told = tnow;
+            if (tcnt >= ticks)
+            {
+                break;
+            }
+        }
+    }
 }
 
 void rt_hw_systick_init(void)
@@ -114,7 +182,7 @@ void rt_hw_systick_init(void)
 
     timer0_init();
     hal_set_tick_hook(timer0_cfg);
-    hal_set_ticks(get_sysclk_nhz()/RT_TICK_PER_SECOND);
+    hal_set_ticks(get_sysclk_nhz() / RT_TICK_PER_SECOND);
 
     PICCON |= 0x10002;
 }
@@ -156,7 +224,8 @@ void cache_init(void)
 RT_SECTION(".irq.cache")
 void os_spiflash_lock(void)
 {
-    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0)) {
+    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0))
+    {
         rt_mutex_take(&mutex_spiflash, RT_WAITING_FOREVER);
     }
 }
@@ -164,7 +233,8 @@ void os_spiflash_lock(void)
 RT_SECTION(".irq.cache")
 void os_spiflash_unlock(void)
 {
-    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0)) {
+    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0))
+    {
         rt_mutex_release(&mutex_spiflash);
     }
 }
@@ -172,7 +242,8 @@ void os_spiflash_unlock(void)
 RT_SECTION(".irq.cache")
 void os_cache_lock(void)
 {
-    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0)) {
+    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0))
+    {
         rt_mutex_take(&mutex_cache, RT_WAITING_FOREVER);
     }
 }
@@ -180,7 +251,8 @@ void os_cache_lock(void)
 RT_SECTION(".irq.cache")
 void os_cache_unlock(void)
 {
-    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0)) {
+    if ((rt_thread_self() != RT_NULL) && (rt_interrupt_nest == 0))
+    {
         rt_mutex_release(&mutex_cache);
     }
 }
@@ -212,5 +284,5 @@ void exception_isr(void)
     rt_kprintf(stack_info, rt_thread_self()->sp, rt_thread_self()->name);
 #endif
 
-    while(1);
+    while (1);
 }

+ 43 - 0
bsp/bluetrum/ab32vg1-ab-prougen/board/ports/fal_cfg.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-11-16     greedyhao    first version
+ */
+
+#ifndef __FAL_CFG_H__
+#define __FAL_CFG_H__
+
+#include <rtthread.h>
+
+#if defined(BSP_USING_ON_CHIP_FLASH)
+extern const struct fal_flash_dev ab32_onchip_flash;
+
+/* flash device table */
+#define FAL_FLASH_DEV_TABLE                                          \
+{                                                                    \
+    &ab32_onchip_flash,                                             \
+}
+/* ====================== Partition Configuration ========================== */
+#ifdef FAL_PART_HAS_TABLE_CFG
+
+/* partition table */
+#define FAL_PART_TABLE                                                                      \
+{                                                                                           \
+    {FAL_PART_MAGIC_WROD,       "boot",     "onchip_flash",     0,              8 * 1024,   0}, \
+    {FAL_PART_MAGIC_WROD,       "app",      "onchip_flash",     8 * 1024,       996 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD,       "param",    "onchip_flash",     1004 * 1024,    20 * 1024,  0},  \
+}
+#endif /* FAL_PART_HAS_TABLE_CFG */
+
+#else
+
+#define FAL_FLASH_DEV_TABLE { 0 }
+#define FAL_PART_TABLE  { 0 }
+
+#endif
+
+#endif /* __FAL_CFG_H__ */

+ 21 - 0
bsp/bluetrum/ab32vg1-ab-prougen/board/ports/on_chip_flash_init.c

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2006-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-11-16     greedyhao    first version
+ */
+
+#include <rtthread.h>
+#include "fal.h"
+
+#if defined(BSP_USING_ON_CHIP_FLASH)
+static int rt_hw_on_chip_flash_init(void)
+{
+    fal_init();
+    return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(rt_hw_on_chip_flash_init);
+#endif

+ 9 - 5
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h

@@ -18,7 +18,7 @@
 #define IDLE_THREAD_STACK_SIZE 512
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
-#define RT_TIMER_THREAD_STACK_SIZE 256
+#define RT_TIMER_THREAD_STACK_SIZE 1024
 
 /* kservice optimization */
 
@@ -46,7 +46,7 @@
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 128
 #define RT_CONSOLE_DEVICE_NAME "uart0"
-#define RT_VER_NUM 0x40004
+#define RT_VER_NUM 0x40100
 
 /* RT-Thread Components */
 
@@ -91,6 +91,7 @@
 
 /* POSIX layer and C standard library */
 
+#define RT_USING_LIBC
 #define RT_LIBC_USING_TIME
 #define RT_LIBC_DEFAULT_TIMEZONE 8
 
@@ -147,6 +148,9 @@
 /* u8g2: a monochrome graphic library */
 
 
+/* PainterEngine: A cross-platform graphics application framework written in C language */
+
+
 /* tools packages */
 
 
@@ -155,6 +159,9 @@
 /* acceleration: Assembly language or algorithmic acceleration packages */
 
 
+/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
+
+
 /* Micrium: Micrium software products porting for RT-Thread */
 
 
@@ -186,9 +193,6 @@
 #define BSP_USING_UART
 #define BSP_USING_UART0
 #define BSP_UART0_FIFO_SIZE 10
-
-/* Board extended module Drivers */
-
 #define BOARD_BLUETRUM_EVB
 
 #endif

+ 1 - 1
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py

@@ -40,7 +40,7 @@ if PLATFORM == 'gcc':
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY  = PREFIX + 'objcopy'
 
-    DEVICE  = ' -mcmodel=medany -march=rv32imc -mabi=ilp32 -msave-restore'
+    DEVICE  = ' -mcmodel=medany -march=rv32imc -mabi=ilp32 -msave-restore -ffunction-sections'
     CFLAGS = DEVICE + ' -D_USE_LONG_TIME_T'
     AFLAGS  = ' -c' + DEVICE + ' -x assembler-with-cpp'
     LFLAGS  = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds'

+ 3 - 0
bsp/bluetrum/libraries/hal_drivers/SConscript

@@ -38,6 +38,9 @@ if GetDepend('RT_USING_ADC'):
 if GetDepend('BSP_USING_IRRX'):
     src += ['drv_irrx.c']
 
+if GetDepend('BSP_USING_ON_CHIP_FLASH'):
+    src += ['drv_flash.c']
+
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
 
 objs = [group]

+ 140 - 0
bsp/bluetrum/libraries/hal_drivers/drv_flash.c

@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2006-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-11-16     greedyhao    first version
+ */
+
+#include "board.h"
+#include "drv_flash.h"
+
+#ifdef BSP_USING_ON_CHIP_FLASH
+
+#if defined(PKG_USING_FAL)
+#include "fal.h"
+#endif
+
+//#define DRV_DEBUG
+#define LOG_TAG                "drv.flash"
+#include <drv_log.h>
+
+#if defined(PKG_USING_FAL)
+
+#define AB32_FLASH_START_ADDRESS    0x00000000
+#define AB32_FLASH_SIZE             (1024 * 1024)
+#define AB32_FLASH_PAGE_SIZE        (0x1000)
+
+static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
+static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
+static int fal_flash_erase(long offset, size_t size);
+
+const struct fal_flash_dev ab32_onchip_flash =
+{
+    "onchip_flash",
+    AB32_FLASH_START_ADDRESS,
+    AB32_FLASH_SIZE,
+    AB32_FLASH_PAGE_SIZE,
+    {NULL, fal_flash_read, fal_flash_write, fal_flash_erase},
+    256 * 8
+};
+
+static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
+{
+    return os_spiflash_read(buf, offset, size);
+}
+
+static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
+{
+    if (size % 256)
+    {
+        rt_kprintf("Flash write requires 256 byte alignment\n");
+        return -1;
+    }
+    os_spiflash_program(buf, offset, size);
+    return 0;
+}
+
+static int fal_flash_erase(long offset, size_t size)
+{
+    if (size % 4096)
+    {
+        rt_kprintf("Flash erase requires 4096 byte alignment\n");
+        return -1;
+    }
+    while (size > 0)
+    {
+        os_spiflash_erase(offset);
+        offset += 4096;
+        size -= 4096;
+    }
+    return 0;
+}
+
+int fal_ops_test(void)
+{
+    int result;
+    const struct fal_partition *part_dev = fal_partition_find("param");
+    uint8_t *data = rt_malloc(256);
+    int i;
+    int size = 256;
+    int addr = 0;
+
+    for (int i = 0; i < 256; i++)
+    {
+        data[i] = i;
+    }
+
+    result = fal_partition_write(part_dev, 0, data, 256);
+    if (result >= 0)
+    {
+        rt_kprintf("Write data success. Start from 0x%08X, size is %ld.\n", addr, size);
+        rt_kprintf("Write data: ");
+        for (i = 0; i < size; i++)
+        {
+            rt_kprintf("%d ", data[i]);
+        }
+        rt_kprintf(".\n");
+    }
+
+    rt_memset(data, 0, 256);
+    result = fal_partition_read(part_dev, 0, data, 256);
+    if (result >= 0)
+    {
+        rt_kprintf("Read data success. Start from 0x%08X, size is %ld.\n", addr, size);
+        rt_kprintf("Read data: ");
+        for (i = 0; i < size; i++)
+        {
+            rt_kprintf("%d ", data[i]);
+        }
+        rt_kprintf(".\n");
+    }
+
+    result = fal_partition_erase(part_dev, 0, 4096);
+    if (result >= 0)
+    {
+        rt_kprintf("Erase data success.\n");
+    }
+
+    rt_memset(data, 0, 256);
+    result = fal_partition_read(part_dev, 0, data, 256);
+    if (result >= 0)
+    {
+        rt_kprintf("Read data success. Start from 0x%08X, size is %ld.\n", addr, size);
+        rt_kprintf("Read data: ");
+        for (i = 0; i < size; i++)
+        {
+            rt_kprintf("%d ", data[i]);
+        }
+        rt_kprintf(".\n");
+    }
+    rt_free(data);
+
+    return 0;
+}
+MSH_CMD_EXPORT(fal_ops_test, "fal_ops_test");
+
+#endif
+#endif

+ 42 - 0
bsp/bluetrum/libraries/hal_drivers/drv_flash.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-11-16     greedyhao    first version
+ */
+
+#ifndef __DRV_FLASH_H__
+#define __DRV_FLASH_H__
+
+#include <stdint.h>
+
+/**
+ * @brief Read a block of data
+ *
+ * @param buf output data
+ * @param addr
+ * @param len less than 512
+ * @return uint16_t
+ */
+uint16_t os_spiflash_read(void *buf, uint32_t addr, uint16_t len);
+
+/**
+ * @brief Write a block of data
+ *
+ * @param buf input data
+ * @param addr 256 alignment
+ * @param len 256 alignment
+ */
+void os_spiflash_program(const void *buf, uint32_t addr, uint16_t len);
+
+/**
+ * @brief Erases a block of data
+ *
+ * @param addr 4k alignment
+ */
+void os_spiflash_erase(uint32_t addr);
+
+#endif /* __DRV_FLASH_H__ */

+ 2 - 4
bsp/bluetrum/libraries/hal_drivers/drv_gpio.c

@@ -27,9 +27,9 @@ struct port_info
 static const struct port_info port_table[] =
 {
     {0, 8, 0},      /* PA0-PA7 */
-    {0, 5, 8},      /* PB0-PB5 */
+    {0, 5, 8},      /* PB0-PB4 */
     {0, 8, 13},     /* PE0-PE7 */
-    {0, 6, 21},     /* PF0-PF6 */
+    {0, 6, 21},     /* PF0-PF5 */
 };
 
 static const hal_sfr_t port_sfr[] =
@@ -56,8 +56,6 @@ static rt_uint8_t _pin_port(rt_uint32_t pin)
 #define PORT_SFR(port)          (port_sfr[(port)])
 #define PIN_NO(pin)             (rt_uint8_t)((pin) & 0xFu)
 
-// #define PIN_ABPIN(pin)  (rt_uint8_t)(port_table[PIN_PORT(pin)].total_pin + PIN_NO(pin))
-
 static rt_base_t ab32_pin_get(const char *name)
 {
     rt_base_t pin = 0;

+ 0 - 1
bsp/bluetrum/libraries/hal_drivers/drv_rtc.c

@@ -11,7 +11,6 @@
  */
 
 #include "board.h"
-#include <time.h>
 #include <sys/time.h>
 
 #ifdef BSP_USING_ONCHIP_RTC

+ 3 - 38
bsp/bluetrum/libraries/hal_drivers/drv_soft_i2c.c

@@ -142,41 +142,6 @@ static rt_int32_t ab32_get_scl(void *data)
     return rt_pin_read(cfg->scl);
 }
 
-/**
- * The time delay function.
- *
- * @param us microseconds.
- */
-static void ab32_udelay(rt_uint32_t us)
-{
-    rt_uint32_t ticks;
-    rt_uint32_t told, tnow, tcnt = 0;
-    rt_uint32_t reload = TMR0PR;
-
-    ticks = us * reload / (1000 / RT_TICK_PER_SECOND);
-    told = TMR0CNT;
-    while (1)
-    {
-        tnow = TMR0CNT;
-        if (tnow != told)
-        {
-            if (tnow < told)
-            {
-                tcnt += told - tnow;
-            }
-            else
-            {
-                tcnt += reload - tnow + told;
-            }
-            told = tnow;
-            if (tcnt >= ticks)
-            {
-                break;
-            }
-        }
-    }
-}
-
 static const struct rt_i2c_bit_ops ab32_bit_ops_default =
 {
     .data     = RT_NULL,
@@ -184,7 +149,7 @@ static const struct rt_i2c_bit_ops ab32_bit_ops_default =
     .set_scl  = ab32_set_scl,
     .get_sda  = ab32_get_sda,
     .get_scl  = ab32_get_scl,
-    .udelay   = ab32_udelay,
+    .udelay   = rt_hw_us_delay,
     .delay_us = 1,
     .timeout  = 100
 };
@@ -205,9 +170,9 @@ static rt_err_t ab32_i2c_bus_unlock(const struct ab32_soft_i2c_config *cfg)
         while (i++ < 9)
         {
             rt_pin_write(cfg->scl, PIN_HIGH);
-            ab32_udelay(100);
+            rt_hw_us_delay(100);
             rt_pin_write(cfg->scl, PIN_LOW);
-            ab32_udelay(100);
+            rt_hw_us_delay(100);
         }
     }
     if (PIN_LOW == rt_pin_read(cfg->sda))

+ 2 - 1
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal.h

@@ -11,8 +11,9 @@
 
 void hal_set_tick_hook(void (*hook)(uint32_t ticks));
 void hal_set_ticks(uint32_t ticks);
+uint32_t hal_get_ticks(void);
 void hal_mdelay(uint32_t nms);
-void hal_udelay(uint16_t nus);
+void hal_udelay(uint32_t nus);
 void hal_printf(const char *fmt, ...);
 
 #endif

BIN
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/libhal.a


+ 7 - 9
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal.c

@@ -11,26 +11,24 @@ void hal_set_tick_hook(void (*hook)(uint32_t ticks))
 
 void hal_set_ticks(uint32_t ticks)
 {
-    if (ticks != hw_ticks) {
+    if (ticks != hw_ticks)
+    {
         hw_ticks = ticks;
     }
-    if (tick_cfg_hook != HAL_NULL) {
+    if (tick_cfg_hook != HAL_NULL)
+    {
         tick_cfg_hook(hw_ticks);
     }
 }
 
 WEAK void hal_mdelay(uint32_t nms)
 {
-
 }
 
-void hal_udelay(uint16_t nus)
+WEAK void hal_udelay(uint32_t nus)
 {
-   int i;
-   for (i = 0; i < nus*10; i++) {
-        asm("nop");
-   }
 }
 
 WEAK void hal_printf(const char *fmt, ...)
-{}
+{
+}

+ 2 - 1
bsp/bluetrum/libraries/hal_libraries/bmsis/source/startup.S

@@ -6,7 +6,6 @@
 
 #include "ab32vg1.h"
 
-.set _memcpy,    0x84044
 .global _start
 .section .reset, "ax"
 _start:
@@ -111,3 +110,5 @@ cpu_irq_comm:
 
     .global _tp
     .set    _tp,        0x84800
+
+    .set    _memcpy,    0x84044

+ 1 - 1
bsp/ck802/libraries/include/drv_rtc.h

@@ -29,7 +29,7 @@ extern "C" {
 
 #include <stdint.h>
 #include <drv_common.h>
-#include <time.h>
+#include <sys/time.h>
 
 /// definition for rtc handle.
 typedef void *rtc_handle_t;

+ 1 - 1
bsp/ft2004/libraries/bsp/ft_i2c/ft_i2c_selftest.c

@@ -12,7 +12,7 @@
  * ----- ------     --------    --------------------------------------
  */
 
-#include <time.h>
+#include <sys/time.h>
 #include <string.h>
 #include "ft_i2c_hw.h"
 #include "ft_i2c.h"

+ 1 - 1
bsp/imxrt/libraries/drivers/drv_rtc.c

@@ -20,7 +20,7 @@
 
 #include "drv_rtc.h"
 #include "fsl_snvs_hp.h"
-#include <time.h>
+#include <sys/time.h>
 
 #if defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL
 #error "Please don't define 'FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL'!"

+ 1 - 1
bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.h

@@ -36,7 +36,7 @@
 
 #include "chip.h"
 #include <stdlib.h>
-#include <time.h>
+#include <sys/time.h>
 
 #ifdef __cplusplus
 extern "C" {

+ 33 - 14
bsp/nrf5x/libraries/drivers/drv_i2c.c

@@ -6,6 +6,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2020-11-15     xckhmf       First Verison
+ * 2021-11-27     chenyingchun fix _master_xfer bug
  *
  */
 
@@ -56,36 +57,54 @@ static int twi_master_init(struct rt_i2c_bus_device *bus)
     nrfx_twi_twim_bus_recover(config.scl,config.sda);
 
     rtn = nrfx_twim_init(p_instance,&config,NULL,NULL);
+    if (rtn != NRFX_SUCCESS)
+    {
+        return rtn;
+    }
     nrfx_twim_enable(p_instance);
     return 0;
 }
 
 static rt_size_t _master_xfer(struct rt_i2c_bus_device *bus,
-                                struct rt_i2c_msg msgs[],
-                                rt_uint32_t num)
+                              struct rt_i2c_msg msgs[],
+                              rt_uint32_t num)
 {
-    nrfx_twim_t const * p_instance = &((drv_i2c_cfg_t *)bus->priv)->twi_instance;
+    struct rt_i2c_msg *msg;
+    nrfx_twim_t const *p_instance = &((drv_i2c_cfg_t *)bus->priv)->twi_instance;
     nrfx_err_t ret = NRFX_ERROR_INTERNAL;
     uint32_t no_stop_flag = 0;
+    rt_int32_t i = 0;
 
-    nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_TX(msgs->addr,msgs->buf, msgs->len);
-    if((msgs->flags & 0x01) == RT_I2C_WR)
+    for (i = 0; i < num; i++)
     {
-        xfer.type = NRFX_TWIM_XFER_TX;
-        if((msgs->flags & 0x40) == RT_I2C_NO_READ_ACK)
+        msg = &msgs[i];
+        nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_TX(msg->addr, msg->buf, msg->len);
+
+        if (msg->flags & RT_I2C_RD)
         {
-            no_stop_flag = NRFX_TWIM_FLAG_TX_NO_STOP;
+            xfer.type = NRFX_TWIM_XFER_RX;
+        }
+        else
+        {
+            xfer.type = NRFX_TWIM_XFER_TX;
+            if (msg->flags & RT_I2C_NO_READ_ACK)
+            {
+                no_stop_flag = NRFX_TWIM_FLAG_TX_NO_STOP;
+            }
+        }
+
+        ret = nrfx_twim_xfer(p_instance, &xfer, no_stop_flag);
+        if (ret != NRFX_SUCCESS)
+        {
+            goto out;
         }
     }
-    else if((msgs->flags & 0x01) == RT_I2C_RD)
-    {
-        xfer.type = NRFX_TWIM_XFER_RX;
-    }
-    ret = nrfx_twim_xfer(p_instance,&xfer,no_stop_flag);
-    return (ret == NRFX_SUCCESS) ? msgs->len : 0;
 
+out:
+    return i;
 }
 
+
 static const struct rt_i2c_bus_device_ops _i2c_ops =
 {
      _master_xfer,

+ 58 - 0
bsp/nrf5x/nrf52840/board/Kconfig

@@ -405,6 +405,64 @@ menu "On-chip Peripheral Drivers"
             hex "MCU FLASH PAGE SIZE, please not change,nrfx default is 0x1000"
             default 0x1000
 	endmenu
+	
+	config BSP_USING_TIM
+        bool "Enable TIMER"
+        select RT_USING_HWTIMER
+        default n
+        if BSP_USING_TIM
+            config NRFX_TIMER_ENABLED
+            int 
+            default 1
+            config BSP_USING_TIM0
+                bool "Enable TIMER0"
+                default n
+            if BSP_USING_TIM0
+                config NRFX_TIMER0_ENABLED
+                int 
+                default 1
+            endif
+            config BSP_USING_TIM1
+                bool "Enable TIMER1"
+                default n
+            if BSP_USING_TIM1
+                config NRFX_TIMER1_ENABLED
+                int 
+                default 1
+            endif
+            config BSP_USING_TIM2
+                bool "Enable TIMER2"
+                default n
+            if BSP_USING_TIM2
+                config NRFX_TIMER2_ENABLED
+                int 
+                default 1
+            endif
+            config BSP_USING_TIM3
+                bool "Enable TIMER3"
+                default n
+            if BSP_USING_TIM3
+                config NRFX_TIMER3_ENABLED
+                int 
+                default 1
+            endif
+
+            config BSP_USING_TIM4
+                bool "Enable TIMER4"
+                default n
+            if BSP_USING_TIM4
+                config NRFX_TIMER4_ENABLED
+                int 
+                default 1
+            endif
+        endif
+
+
+    if PKG_USING_TINYUSB
+        config NRFX_POWER_ENABLED
+        int 
+        default 1
+    endif
 
 endmenu
 

+ 28 - 12
bsp/nuvoton/libraries/m031/rtt_port/drv_i2c.c

@@ -72,20 +72,32 @@ static nu_i2c_bus_t nu_i2c1 =
 static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
                                  struct rt_i2c_msg msgs[],
                                  rt_uint32_t num);
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                   rt_uint32_t u32Cmd,
+                                   rt_uint32_t u32Value);
 
 static const struct rt_i2c_bus_device_ops nu_i2c_ops =
 {
     .master_xfer        = nu_i2c_mst_xfer,
     .slave_xfer         = NULL,
-    .i2c_bus_control    = NULL,
+    .i2c_bus_control    = nu_i2c_bus_control
 };
 
-static rt_err_t nu_i2c_configure(nu_i2c_bus_t *bus)
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t u32Cmd, rt_uint32_t u32Value)
 {
+    nu_i2c_bus_t *nu_i2c;
+
     RT_ASSERT(bus != RT_NULL);
+    nu_i2c = (nu_i2c_bus_t *) bus;
 
-    bus->parent.ops = &nu_i2c_ops;
-    I2C_Open(bus->I2C, 100000);
+    switch (RT_I2C_DEV_CTRL_CLK)
+    {
+    case RT_I2C_DEV_CTRL_CLK:
+        I2C_SetBusClockFreq(nu_i2c->I2C, u32Value);
+        break;
+    default:
+        return -RT_EIO;
+    }
 
     return RT_EOK;
 }
@@ -290,24 +302,28 @@ static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
 int rt_hw_i2c_init(void)
 {
     rt_err_t ret = RT_ERROR;
-#if   defined(BSP_USING_I2C0)
+
     SYS_UnlockReg();
-    SYS_ResetModule(I2C0_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c0);
+
+#if   defined(BSP_USING_I2C0)
+    I2C_Close(nu_i2c0.I2C);
+    I2C_Open(nu_i2c0.I2C, 100000);
+    nu_i2c0.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c0.parent, nu_i2c0.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C0 */
 
 #if   defined(BSP_USING_I2C1)
-    SYS_UnlockReg();
-    SYS_ResetModule(I2C1_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c1);
+    I2C_Close(nu_i2c1.I2C);
+    I2C_Open(nu_i2c1.I2C, 100000);
+    nu_i2c1.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c1.parent, nu_i2c1.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C1 */
 
+    SYS_LockReg();
     return ret;
 }
 

+ 7 - 0
bsp/nuvoton/libraries/m2354/USBHostLib/src/ohci.c

@@ -1144,6 +1144,9 @@ void USBH_IRQHandler(void)
     TD_T       *td, *td_prev, *td_next;
     uint32_t   int_sts;
 
+    /* enter interrupt */
+    rt_interrupt_enter();
+
     int_sts = _ohci->HcInterruptStatus;
 
     //USB_debug("ohci int_sts = 0x%x\n", int_sts);
@@ -1199,6 +1202,10 @@ void USBH_IRQHandler(void)
     }
 
     _ohci->HcInterruptStatus = int_sts;
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+
 }
 
 #ifdef ENABLE_DEBUG_MSG

+ 33 - 16
bsp/nuvoton/libraries/m2354/rtt_port/drv_i2c.c

@@ -81,20 +81,32 @@ static nu_i2c_bus_t nu_i2c2 =
 static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
                                  struct rt_i2c_msg msgs[],
                                  rt_uint32_t num);
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                   rt_uint32_t u32Cmd,
+                                   rt_uint32_t u32Value);
 
 static const struct rt_i2c_bus_device_ops nu_i2c_ops =
 {
     .master_xfer        = nu_i2c_mst_xfer,
     .slave_xfer         = NULL,
-    .i2c_bus_control    = NULL,
+    .i2c_bus_control    = nu_i2c_bus_control
 };
 
-static rt_err_t nu_i2c_configure(nu_i2c_bus_t *bus)
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t u32Cmd, rt_uint32_t u32Value)
 {
+    nu_i2c_bus_t *nu_i2c;
+
     RT_ASSERT(bus != RT_NULL);
+    nu_i2c = (nu_i2c_bus_t *) bus;
 
-    bus->parent.ops = &nu_i2c_ops;
-    I2C_Open(bus->I2C, 100000);
+    switch (RT_I2C_DEV_CTRL_CLK)
+    {
+    case RT_I2C_DEV_CTRL_CLK:
+        I2C_SetBusClockFreq(nu_i2c->I2C, u32Value);
+        break;
+    default:
+        return -RT_EIO;
+    }
 
     return RT_EOK;
 }
@@ -354,33 +366,38 @@ static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
 int rt_hw_i2c_init(void)
 {
     rt_err_t ret = RT_ERROR;
-#if   defined(BSP_USING_I2C0)
+
     SYS_UnlockReg();
-    SYS_ResetModule(I2C0_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c0);
+
+#if   defined(BSP_USING_I2C0)
+    I2C_Close(nu_i2c0.I2C);
+    I2C_Open(nu_i2c0.I2C, 100000);
+    nu_i2c0.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c0.parent, nu_i2c0.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C0 */
 
 #if   defined(BSP_USING_I2C1)
-    SYS_UnlockReg();
-    SYS_ResetModule(I2C1_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c1);
+    I2C_Close(nu_i2c1.I2C);
+    I2C_Open(nu_i2c1.I2C, 100000);
+    nu_i2c1.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c1.parent, nu_i2c1.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C1 */
 
 #if   defined(BSP_USING_I2C2)
-    SYS_UnlockReg();
-    SYS_ResetModule(I2C2_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c2);
+    I2C_Close(nu_i2c2.I2C);
+    I2C_Open(nu_i2c2.I2C, 100000);
+    nu_i2c2.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c2.parent, nu_i2c2.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C2 */
 
+    SYS_LockReg();
+
     return ret;
 }
 

+ 345 - 307
bsp/nuvoton/libraries/m2354/rtt_port/drv_usbhost.c

@@ -7,6 +7,7 @@
 * Change Logs:
 * Date            Author           Notes
 * 2020-5-4        CHChen           First version
+* 2021-11-5       Wayne            Revise
 *
 ******************************************************************************/
 #include <rtconfig.h>
@@ -30,6 +31,28 @@
 
 #define NU_MAX_USBH_HUB_PORT_DEV    USB_HUB_PORT_NUM
 
+#define NU_USBHOST_HUB_POLLING_LOCK
+#if defined(NU_USBHOST_HUB_POLLING_LOCK)
+#define NU_USBHOST_MUTEX_INIT()      { \
+                                s_sUSBHDev.lock = rt_mutex_create("usbhost_lock", RT_IPC_FLAG_PRIO); \
+                                RT_ASSERT(s_sUSBHDev.lock != RT_NULL); \
+                            }
+
+#define NU_USBHOST_LOCK()      { \
+                                rt_err_t result = rt_mutex_take(s_sUSBHDev.lock, RT_WAITING_FOREVER); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+
+#define NU_USBHOST_UNLOCK()    { \
+                                rt_err_t result = rt_mutex_release(s_sUSBHDev.lock); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+#else
+#define NU_USBHOST_MUTEX_INIT()
+#define NU_USBHOST_LOCK()
+#define NU_USBHOST_UNLOCK()
+#endif
+
 /* Private typedef --------------------------------------------------------------*/
 typedef struct nu_port_dev
 {
@@ -52,21 +75,18 @@ typedef struct nu_port_ctrl
 
 struct nu_usbh_dev
 {
-    uhcd_t uhcd;
+    struct uhcd uhcd;
     rt_thread_t polling_thread;
+    rt_mutex_t  lock;
     S_NU_RH_PORT_CTRL asPortCtrl[NU_MAX_USBH_PORT];
 };
 
 /* Private variables ------------------------------------------------------------*/
-static struct nu_usbh_dev s_sUSBHDev =
-{
-    .uhcd = RT_NULL,
-};
+static struct nu_usbh_dev s_sUSBHDev;
 
 static S_NU_RH_PORT_CTRL *
 GetRHPortControlFromPipe(
-    upipe_t pipe
-)
+    upipe_t pipe)
 {
     uinst_t inst;
     int port;
@@ -94,8 +114,7 @@ GetRHPortControlFromPipe(
 
 static S_NU_PORT_DEV *
 GetPortDevFromPipe(
-    upipe_t pipe
-)
+    upipe_t pipe)
 {
     S_NU_RH_PORT_CTRL *psRHPortCtrl = GetRHPortControlFromPipe(pipe);
     int i;
@@ -118,97 +137,226 @@ GetPortDevFromPipe(
 
     if (i >= NU_MAX_USBH_HUB_PORT_DEV)
         return RT_NULL;
+
     return &psRHPortCtrl->asHubPortDev[i];
 }
 
-static  S_NU_PORT_DEV *
-AllocateNewUDev(
-    S_NU_RH_PORT_CTRL *psRHPortCtrl
-)
+static rt_err_t nu_reset_port(rt_uint8_t port)
 {
-    int i;
-    for (i = 0 ; i < NU_MAX_USBH_HUB_PORT_DEV; i ++)
+    S_NU_RH_PORT_CTRL *psPortCtrl;
+
+    if (port > NU_MAX_USBH_PORT)
     {
-        if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
-            break;
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: port index over NU_MAX_USBH_PORT\n", __func__));
+        return RT_EIO;
     }
 
-    if (i >= NU_MAX_USBH_HUB_PORT_DEV)
-        return RT_NULL;
-
-    psRHPortCtrl->asHubPortDev[i].pUDev = alloc_device();
+    psPortCtrl = &s_sUSBHDev.asPortCtrl[port - 1];
+    if (psPortCtrl->sRHPortDev.pUDev == NULL)
+    {
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: udev not found\n", __func__));
+        return RT_EIO;
+    }
 
-    if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
-        return RT_NULL;
+    usbh_reset_port(psPortCtrl->sRHPortDev.pUDev);
 
-    return &psRHPortCtrl->asHubPortDev[i];
+    return RT_EOK;
 }
 
 static EP_INFO_T *GetFreePipe(
     S_NU_RH_PORT_CTRL *psPortCtrl,
     S_NU_PORT_DEV *psPortDev,
-    rt_uint8_t *pu8PipeIndex
-)
+    rt_uint8_t *pu8PipeIndex)
 {
-    rt_uint8_t i;
-    if (psPortCtrl == NULL)
-        return NULL;
-
-    for (i = 1; i < NU_MAX_USBH_PIPE; i ++)
+    if (psPortCtrl != NULL)
     {
-        if (psPortDev->apsEPInfo[i] == NULL)
-            break;
-    }
-
-    if (i >= NU_MAX_USBH_PIPE)
-        return RT_NULL;
-
-    EP_INFO_T *psEPInfo = rt_malloc(sizeof(EP_INFO_T));
+        int i;
+        /* Find free Pipe */
+        for (i = 0; i < NU_MAX_USBH_PIPE; i ++)
+        {
+            if (psPortDev->apsEPInfo[i] == NULL)
+                break;
+        }
 
-    psPortDev->apsEPInfo[i] = psEPInfo;
-    *pu8PipeIndex = i;
-    return psEPInfo;
+        if (i < NU_MAX_USBH_PIPE)
+        {
+            EP_INFO_T *psEPInfo = rt_malloc(sizeof(EP_INFO_T));
+            if (psEPInfo != RT_NULL)
+            {
+                psPortDev->apsEPInfo[i] = psEPInfo;
+                *pu8PipeIndex = i;
+                return psEPInfo;
+            }
+        }
+    }
+    return RT_NULL;
 }
 
 static void FreePipe(
     S_NU_RH_PORT_CTRL *psPortCtrl,
     S_NU_PORT_DEV *psPortDev,
-    rt_uint8_t u8PipeIndex
-)
+    rt_uint8_t u8PipeIndex)
 {
-    if (psPortCtrl == NULL)
-        return;
-
-    if (u8PipeIndex >= NU_MAX_USBH_PIPE)
-        return;
-
-    if (psPortDev->apsEPInfo[u8PipeIndex])
+    if ((psPortCtrl != RT_NULL) &&
+            (u8PipeIndex < NU_MAX_USBH_PIPE) &&
+            (psPortDev->apsEPInfo[u8PipeIndex] != RT_NULL))
     {
         rt_free(psPortDev->apsEPInfo[u8PipeIndex]);
         psPortDev->apsEPInfo[u8PipeIndex] = RT_NULL;
     }
 }
 
-static rt_err_t nu_reset_port(rt_uint8_t port)
+static  S_NU_PORT_DEV *
+AllocateNewUDev(
+    S_NU_RH_PORT_CTRL *psRHPortCtrl)
+{
+    if (psRHPortCtrl != RT_NULL)
+    {
+        int i;
+        /* Find free Dev */
+        for (i = 0 ; i < NU_MAX_USBH_HUB_PORT_DEV; i ++)
+        {
+            if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
+                break;
+        }
+
+        if (i < NU_MAX_USBH_HUB_PORT_DEV)
+        {
+            psRHPortCtrl->asHubPortDev[i].pUDev = alloc_device();
+            if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
+            {
+                return RT_NULL;
+            }
+            else
+            {
+                return &psRHPortCtrl->asHubPortDev[i];
+            }
+        }
+    }
+    return RT_NULL;
+}
+
+static rt_err_t nu_open_pipe(upipe_t pipe)
 {
     S_NU_RH_PORT_CTRL *psPortCtrl;
+    S_NU_PORT_DEV *psPortDev;
 
-    RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_reset_port\n"));
-    if (port > NU_MAX_USBH_PORT)
+    psPortCtrl = GetRHPortControlFromPipe(pipe);
+    if (psPortCtrl == RT_NULL)
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_reset_port ERROR: port index over NU_MAX_USBH_PORT\n"));
-        return RT_EIO;
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: RHPort not found\n", __func__));
+        goto exit_nu_open_pipe;
     }
 
-    psPortCtrl = &s_sUSBHDev.asPortCtrl[port - 1];
     if (psPortCtrl->sRHPortDev.pUDev == NULL)
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_reset_port ERROR: udev not found\n"));
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: udev not found\n", __func__));
+        goto exit_nu_open_pipe;
+    }
+
+    psPortDev = GetPortDevFromPipe(pipe);
+
+    if ((psPortDev == NULL) || (psPortDev->pUDev == NULL))
+    {
+        //allocate new dev for hub device
+        psPortDev = AllocateNewUDev(psPortCtrl);
+
+        if (psPortDev == RT_NULL)
+        {
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: udev allocate failed\n"));
+            goto exit_nu_open_pipe;
+        }
+
+        if (pipe->inst->speed)
+        {
+            psPortDev->pUDev->speed = SPEED_FULL;
+        }
+        else
+        {
+            psPortDev->pUDev->speed = SPEED_HIGH;
+        }
+
+        psPortDev->pUDev->parent = NULL;
+        psPortDev->pUDev->hc_driver = psPortCtrl->sRHPortDev.pUDev->hc_driver;
+        psPortDev->port_num = pipe->inst->port;
+        psPortDev->pUDev->port_num = pipe->inst->port;
+        psPortDev->bEnumDone = FALSE;
+    }
+
+    //For ep0 control transfer
+    if ((pipe->ep.bEndpointAddress & 0x7F) == 0)
+    {
+        pipe->pipe_index = 0;
+    }
+    else
+    {
+        int  pksz;
+        EP_INFO_T *psEPInfo = GetFreePipe(psPortCtrl, psPortDev, &pipe->pipe_index);
+        if (psEPInfo == RT_NULL)
+        {
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: get free pipe failed\n", __func__));
+            goto exit_nu_open_pipe;
+        }
+
+        psEPInfo->bEndpointAddress = pipe->ep.bEndpointAddress;
+        psEPInfo->bmAttributes = pipe->ep.bmAttributes;
+
+        pksz = pipe->ep.wMaxPacketSize;
+        pksz = (pksz & 0x07ff) * (1 + ((pksz >> 11) & 3));
+        psEPInfo->wMaxPacketSize = pksz;
+
+        psEPInfo->bInterval = pipe->ep.bInterval;
+        psEPInfo->hw_pipe = NULL;
+        psEPInfo->bToggle = 0;
+    }
+
+
+    return RT_EOK;
+
+exit_nu_open_pipe:
+
+    return -RT_ERROR;
+}
+
+static rt_err_t nu_close_pipe(upipe_t pipe)
+{
+    S_NU_RH_PORT_CTRL *psPortCtrl;
+    S_NU_PORT_DEV *psPortDev;
+
+    psPortCtrl = GetRHPortControlFromPipe(pipe);
+    if (psPortCtrl == RT_NULL)
+    {
         return RT_EIO;
     }
 
-    usbh_reset_port(psPortCtrl->sRHPortDev.pUDev);
+    psPortDev = GetPortDevFromPipe(pipe);
 
+    //For ep0 control transfer
+    if ((pipe->ep.bEndpointAddress & 0x7F) == 0)
+    {
+        if ((psPortDev) && (psPortDev->bRHParent == FALSE) && (psPortDev->bEnumDone == TRUE))
+        {
+            if (psPortDev->pUDev)
+            {
+                int i;
+                for (i = 0; i < NU_MAX_USBH_PIPE; i++)
+                {
+                    if (psPortDev->apsEPInfo[i] != NULL)
+                    {
+                        usbh_quit_xfer(psPortDev->pUDev, psPortDev->apsEPInfo[i]);
+                    }
+                }
+
+                free_device(psPortDev->pUDev);
+                psPortDev->pUDev = NULL;
+            }
+        }
+    }
+
+    if (psPortDev != NULL)
+    {
+        FreePipe(psPortCtrl, psPortDev, pipe->pipe_index);
+    }
     return RT_EOK;
 }
 
@@ -216,14 +364,12 @@ static int nu_ctrl_xfer(
     S_NU_PORT_DEV *psPortDev,
     struct urequest *psSetup,
     void *buffer,
-    int timeouts
-)
+    int timeouts)
 {
-    uint32_t  xfer_len;
+    uint32_t  xfer_len = 0;
     int    ret;
 
     ret = usbh_ctrl_xfer(psPortDev->pUDev, psSetup->request_type, psSetup->bRequest, psSetup->wValue, psSetup->wIndex, psSetup->wLength, buffer, &xfer_len, timeouts * 10);
-
     if (ret < 0)
     {
         RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_ctrl_xfer ERROR: xfer failed %d\n", ret));
@@ -250,18 +396,26 @@ static int nu_ctrl_xfer(
 static int nu_bulk_xfer(
     S_NU_PORT_DEV *psPortDev,
     UTR_T *psUTR,
-    int timeouts
-)
+    int timeouts)
 {
-    int ret;
-
-    ret = usbh_bulk_xfer(psUTR);
-
+    int ret = usbh_bulk_xfer(psUTR);
     if (ret < 0)
         return ret;
 
     //wait transfer done
-    rt_completion_wait(&(psPortDev->utr_completion), timeouts);
+    if (rt_completion_wait(&(psPortDev->utr_completion), timeouts) < 0)
+    {
+        rt_kprintf("Request Timeout in %d ms!! (bulk_xfer)\n", timeouts);
+
+        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);
+        return -1;
+    }
     return 0;
 }
 
@@ -269,8 +423,7 @@ static int nu_int_xfer(
     upipe_t pipe,
     S_NU_PORT_DEV *psPortDev,
     UTR_T *psUTR,
-    int timeouts
-)
+    int timeouts)
 {
     int ret;
     int retry = 3;
@@ -306,9 +459,8 @@ static void int_xfer_done_cb(UTR_T *psUTR)
 
     if (psUTR->status != 0)
     {
-        rt_kprintf("Interrupt xfer failed %d\n", psUTR->status);
-        free_utr(psUTR);
-        return;
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("Interrupt xfer failed %d\n", psUTR->status));
+        goto exit_int_xfer_done_cb;
     }
 
     if (pipe->callback != RT_NULL)
@@ -320,6 +472,8 @@ static void int_xfer_done_cb(UTR_T *psUTR)
         rt_usbh_event_signal(&msg);
     }
 
+exit_int_xfer_done_cb:
+
     free_utr(psUTR);
 }
 
@@ -327,29 +481,37 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
 {
     S_NU_RH_PORT_CTRL *psPortCtrl;
     S_NU_PORT_DEV *psPortDev;
+    UTR_T *psUTR = NULL;
+    int i32XferLen = -1;
+
+    void *buffer_nonch = buffer;
+
+    NU_USBHOST_LOCK();
 
     psPortCtrl = GetRHPortControlFromPipe(pipe);
     if (psPortCtrl == RT_NULL)
     {
-        return RT_EIO;
+        goto exit_nu_pipe_xfer;
     }
 
     psPortDev = GetPortDevFromPipe(pipe);
-
     if (psPortDev->pUDev == NULL)
     {
         RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: udev not found\n"));
-        return -RT_ERROR;
+        goto exit_nu_pipe_xfer;
     }
 
     //ctrl xfer
     if (pipe->ep.bmAttributes == USB_EP_ATTR_CONTROL)
     {
+        int ret;
+
         if (token == USBH_PID_SETUP)
         {
-            struct urequest *psSetup;
-            psSetup = (struct urequest *)buffer;
+            struct urequest *psSetup = (struct urequest *)buffer_nonch;
+            RT_ASSERT(buffer_nonch != RT_NULL);
 
+            /* Read data from USB device. */
             if (psSetup->request_type & USB_REQ_TYPE_DIR_IN)
             {
                 //Store setup request
@@ -357,85 +519,90 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             }
             else
             {
-                //Trigger USBHostLib Ctril_Xfer
-                nu_ctrl_xfer(psPortDev, psSetup, NULL, timeouts);
+                /* Write data to USB device. */
+                //Trigger USBHostLib Ctrl_Xfer
+                ret = nu_ctrl_xfer(psPortDev, psSetup, NULL, timeouts);
+                if (ret != psSetup->wLength)
+                    goto exit_nu_pipe_xfer;
             }
-            return nbytes;
         }
         else
         {
             //token == USBH_PID_DATA
-            if (buffer == RT_NULL)
-                return nbytes;
-
-            if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
+            if (buffer_nonch && ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN))
             {
+                /* Read data from USB device. */
                 //Trigger USBHostLib Ctril_Xfer
-                nu_ctrl_xfer(psPortDev, &psPortCtrl->asHubPortDev->asSetupReq[pipe->pipe_index], buffer, timeouts);
+                ret = nu_ctrl_xfer(psPortDev, &psPortCtrl->asHubPortDev->asSetupReq[pipe->pipe_index], buffer_nonch, timeouts);
+                if (ret != nbytes)
+                    goto exit_nu_pipe_xfer;
             }
             else
             {
-                RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: can not handle ctrl xfer case: buffer!=NULL and USB_DIR_OUT\n"));
+                RT_DEBUG_LOG(RT_DEBUG_USB, ("%d == USBH_PID_DATA, nil buf-%d \n", token, nbytes));
             }
-            return nbytes;
-        }
-    }
-
-    //others xfer
-    rt_completion_init(&(psPortDev->utr_completion));
 
-    //setup UTR
-    UTR_T *psUTR;
-    int i32XferLen;
-
-    psUTR = alloc_utr(psPortDev->pUDev);
-    if (!psUTR)
+        } //else
+        i32XferLen = nbytes;
+        goto exit_nu_pipe_xfer;
+    } // if ( pipe->ep.bmAttributes == USB_EP_ATTR_CONTROL )
+    else
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: unable alloc UTR\n"));
-        return -(RT_ERROR);
-    }
 
-    psUTR->ep = psPortDev->apsEPInfo[pipe->pipe_index];
-    psUTR->buff = buffer;
-    psUTR->data_len = nbytes;
-    psUTR->xfer_len = 0;
-    psUTR->func = xfer_done_cb;
-    psUTR->context = psPortDev;
-    psUTR->bIsTransferDone = 0;
-    psUTR->status = 0;
+        psUTR = alloc_utr(psPortDev->pUDev);
 
-    if (pipe->ep.bmAttributes == USB_EP_ATTR_BULK)
-    {
-        if (nu_bulk_xfer(psPortDev, psUTR, timeouts) < 0)
+        if (!psUTR)
         {
-            free_utr(psUTR);
-            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: bulk transfer failed\n"));
-            return -(RT_ERROR);
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: unable alloc UTR\n"));
+            goto exit_nu_pipe_xfer;
         }
-    }
 
-    if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
-    {
-        psUTR->func = int_xfer_done_cb;
-        psUTR->context = pipe;
+        psUTR->ep = psPortDev->apsEPInfo[pipe->pipe_index];
+        psUTR->buff = buffer_nonch;
+        psUTR->data_len = nbytes;
+        psUTR->xfer_len = 0;
+        psUTR->func = xfer_done_cb;
+        psUTR->context = psPortDev;
+        psUTR->bIsTransferDone = 0;
+        psUTR->status = 0;
+
+        //others xfer
+        rt_completion_init(&(psPortDev->utr_completion));
 
-        if (nu_int_xfer(pipe, psPortDev, psUTR, timeouts) < 0)
+        if (pipe->ep.bmAttributes == USB_EP_ATTR_BULK)
         {
-            free_utr(psUTR);
-            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: int transfer failed\n"));
-            return -(RT_ERROR);
+            if (nu_bulk_xfer(psPortDev, psUTR, timeouts) < 0)
+            {
+                RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: bulk transfer failed\n"));
+                goto failreport_nu_pipe_xfer;
+            }
         }
+        else if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
+        {
+            psUTR->func = int_xfer_done_cb;
+            psUTR->context = pipe;
 
-        return nbytes;
-    }
+            if (nu_int_xfer(pipe, psPortDev, psUTR, timeouts) < 0)
+            {
+                RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: int transfer failed\n"));
+                //goto exit_nu_pipe_xfer;
+            }
+            else
+            {
+                i32XferLen = nbytes;
+            }
+            goto exit2_nu_pipe_xfer;
+        }
+        else if (pipe->ep.bmAttributes == USB_EP_ATTR_ISOC)
+        {
+            //TODO: ISO transfer
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: isoc transfer not support\n"));
+            goto exit_nu_pipe_xfer;
+        }
 
-    //TODO: ISO transfer
-    if (pipe->ep.bmAttributes == USB_EP_ATTR_ISOC)
-    {
-        free_utr(psUTR);
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: isoc transfer not support\n"));
-        return -1;
-    }
+    } //else
+
+failreport_nu_pipe_xfer:
 
     if (psUTR->bIsTransferDone == 0)
     {
@@ -462,169 +629,42 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     }
 
     i32XferLen = psUTR->xfer_len;
-    free_utr(psUTR);
 
     //Call callback
     if (pipe->callback != RT_NULL)
     {
-        struct uhost_msg msg;
-        msg.type = USB_MSG_CALLBACK;
-        msg.content.cb.function = pipe->callback;
-        msg.content.cb.context = pipe->user_data;
-        rt_usbh_event_signal(&msg);
-    }
-
-    if (pipe->status != UPIPE_STATUS_OK)
-        return -(RT_ERROR);
-
-    if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
-    {
-        return i32XferLen;
+        pipe->callback(pipe);
     }
-    else if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_OUT)
-    {
-        return i32XferLen;
-    }
-
-    return nbytes;
-}
-
-static rt_err_t nu_open_pipe(upipe_t pipe)
-{
-    S_NU_RH_PORT_CTRL *psPortCtrl;
-    S_NU_PORT_DEV *psPortDev;
-
-    psPortCtrl = GetRHPortControlFromPipe(pipe);
-    if (psPortCtrl == RT_NULL)
-    {
-        return RT_EIO;
-    }
-
-    if (psPortCtrl->sRHPortDev.pUDev == NULL)
-    {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: udev not found\n"));
-        return RT_EIO;
-    }
-
-    psPortDev = GetPortDevFromPipe(pipe);
 
-    if ((psPortDev == NULL) || (psPortDev->pUDev == NULL))
-    {
-        //allocate new dev for hub device
-        psPortDev = AllocateNewUDev(psPortCtrl);
+exit_nu_pipe_xfer:
 
-        if (psPortDev == RT_NULL)
-        {
-            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: udev allocate failed\n"));
-            return RT_EIO;
-        }
-
-        if (pipe->inst->speed)
-        {
-            psPortDev->pUDev->speed = SPEED_FULL;
-        }
-        else
-        {
-            psPortDev->pUDev->speed = SPEED_HIGH;
-        }
-
-        psPortDev->pUDev->parent = NULL;
-        psPortDev->pUDev->hc_driver = psPortCtrl->sRHPortDev.pUDev->hc_driver;
-        psPortDev->port_num = pipe->inst->port;
-        psPortDev->pUDev->port_num = pipe->inst->port;
-        psPortDev->bEnumDone = FALSE;
-    }
-
-    //For ep0 control transfer
-    if ((pipe->ep.bEndpointAddress & 0x7F) == 0)
-    {
-        pipe->pipe_index = 0;
-        return RT_EOK;
-    }
-
-    EP_INFO_T *psEPInfo = GetFreePipe(psPortCtrl, psPortDev, &pipe->pipe_index);
-
-    if (psEPInfo == RT_NULL)
-    {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: get free pipe failed\n"));
-        return RT_ENOMEM;
-    }
-
-    int  pksz;
+    if (psUTR)
+        free_utr(psUTR);
 
-    psEPInfo->bEndpointAddress = pipe->ep.bEndpointAddress;
-    psEPInfo->bmAttributes = pipe->ep.bmAttributes;
+exit2_nu_pipe_xfer:
 
-    pksz = pipe->ep.wMaxPacketSize;
-    pksz = (pksz & 0x07ff) * (1 + ((pksz >> 11) & 3));
-    psEPInfo->wMaxPacketSize = pksz;
 
-    psEPInfo->bInterval = pipe->ep.bInterval;
-    psEPInfo->hw_pipe = NULL;
-    psEPInfo->bToggle = 0;
+    NU_USBHOST_UNLOCK();
 
-    return RT_EOK;
+    return i32XferLen;
 }
 
-static rt_err_t nu_close_pipe(upipe_t pipe)
-{
-    S_NU_RH_PORT_CTRL *psPortCtrl;
-    S_NU_PORT_DEV *psPortDev;
-
-    RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_close_pipe\n"));
-    psPortCtrl = GetRHPortControlFromPipe(pipe);
-    if (psPortCtrl == RT_NULL)
-    {
-        return RT_EIO;
-    }
-
-
-    psPortDev = GetPortDevFromPipe(pipe);
-
-    //For ep0 control transfer
-    if ((pipe->ep.bEndpointAddress & 0x7F) == 0)
-    {
-        if ((psPortDev) && (psPortDev->bRHParent == FALSE) && (psPortDev->bEnumDone == TRUE))
-        {
-            if (psPortDev->pUDev)
-            {
-                int i;
-                for (i = 0; i < NU_MAX_USBH_PIPE; i++)
-                {
-                    if (psPortDev->apsEPInfo[i] != NULL)
-                    {
-                        usbh_quit_xfer(psPortDev->pUDev, psPortDev->apsEPInfo[i]);
-                    }
-                }
-
-                free_device(psPortDev->pUDev);
-                psPortDev->pUDev = NULL;
-            }
-        }
-    }
-
-    if (psPortDev != NULL)
-    {
-        FreePipe(psPortCtrl, psPortDev, pipe->pipe_index);
-    }
-
-    return RT_EOK;
-}
-
-//Pooling USB root hub status task
+/* Polling USB root hub status task */
 static void nu_usbh_rh_thread_entry(void *parameter)
 {
     while (1)
     {
+        NU_USBHOST_LOCK();
         usbh_polling_root_hubs();
+        NU_USBHOST_UNLOCK();
+
         rt_thread_mdelay(NU_USBHOST_HUB_POLLING_INTERVAL);
     }
 }
 
 static void nu_hcd_connect_callback(
     struct udev_t *udev,
-    int param
-)
+    int param)
 {
     int i;
     int port_index;
@@ -646,14 +686,18 @@ static void nu_hcd_connect_callback(
     port_index = i + 1;
     psPortCtrl->sRHPortDev.pUDev = udev;
     psPortCtrl->sRHPortDev.bRHParent = TRUE;
+
     RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
-    rt_usbh_root_hub_connect_handler(s_sUSBHDev.uhcd, port_index, RT_FALSE);
+
+    if (udev->speed == SPEED_HIGH)
+        rt_usbh_root_hub_connect_handler(&s_sUSBHDev.uhcd, port_index, RT_TRUE);
+    else
+        rt_usbh_root_hub_connect_handler(&s_sUSBHDev.uhcd, port_index, RT_FALSE);
 }
 
 static void nu_hcd_disconnect_callback(
     struct udev_t *udev,
-    int param
-)
+    int param)
 {
     int i;
     int port_index;
@@ -685,9 +729,11 @@ static void nu_hcd_disconnect_callback(
     psPortCtrl->sRHPortDev.pUDev = NULL;
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnect\n"));
-    rt_usbh_root_hub_disconnect_handler(s_sUSBHDev.uhcd, port_index);
+
+    rt_usbh_root_hub_disconnect_handler(&s_sUSBHDev.uhcd, port_index);
 }
 
+
 /* USB host operations -----------------------------------------------------------*/
 static struct uhcd_ops nu_uhcd_ops =
 {
@@ -700,25 +746,20 @@ static struct uhcd_ops nu_uhcd_ops =
 static rt_err_t nu_hcd_init(rt_device_t device)
 {
     struct nu_usbh_dev *pNuUSBHDev = (struct nu_usbh_dev *)device;
+
     usbh_core_init();
 
     //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 */
     pNuUSBHDev->polling_thread = rt_thread_create("usbh_drv", nu_usbh_rh_thread_entry, RT_NULL,
                                  NU_USBH_THREAD_STACK_SIZE, 8, 20);
-    if (pNuUSBHDev->polling_thread != RT_NULL)
-    {
-        /* startup usb host thread */
-        rt_thread_startup(pNuUSBHDev->polling_thread);
-    }
-    else
-    {
-        return -(RT_EEMPTY);
-    }
+    RT_ASSERT(pNuUSBHDev->polling_thread != RT_NULL);
+
+    /* startup usb host thread */
+    rt_thread_startup(pNuUSBHDev->polling_thread);
 
     return RT_EOK;
 }
@@ -797,7 +838,17 @@ static struct rt_device_pm_ops device_pm_ops =
 
 int nu_usbh_register(void)
 {
-    rt_err_t res = -RT_ERROR;
+    rt_err_t res;
+    uhcd_t psUHCD;
+
+    psUHCD = (uhcd_t)&s_sUSBHDev.uhcd;
+
+    psUHCD->parent.type       = RT_Device_Class_USBHost;
+    psUHCD->parent.init       = nu_hcd_init;
+    psUHCD->parent.user_data  = &s_sUSBHDev;
+
+    psUHCD->ops               = &nu_uhcd_ops;
+    psUHCD->num_ports         = NU_MAX_USBH_PORT;
 
 #if !defined(BSP_USING_OTG)
     SYS_UnlockReg();
@@ -809,22 +860,9 @@ int nu_usbh_register(void)
 #endif
 
 
-    rt_memset(&s_sUSBHDev, 0x0, sizeof(struct nu_usbh_dev));
-
-    uhcd_t uhcd = (uhcd_t)rt_malloc(sizeof(struct uhcd));
-    RT_ASSERT(res != RT_NULL);
+    NU_USBHOST_MUTEX_INIT();
 
-    rt_memset((void *)uhcd, 0, sizeof(struct uhcd));
-
-    uhcd->parent.type = RT_Device_Class_USBHost;
-    uhcd->parent.init = nu_hcd_init;
-    uhcd->parent.user_data = &s_sUSBHDev;
-
-    uhcd->ops = &nu_uhcd_ops;
-    uhcd->num_ports = NU_MAX_USBH_PORT;
-    s_sUSBHDev.uhcd = uhcd;
-
-    res = rt_device_register(&uhcd->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
+    res = rt_device_register(&psUHCD->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
     RT_ASSERT(res == RT_EOK);
 
     /*initialize the usb host function */
@@ -832,10 +870,10 @@ int nu_usbh_register(void)
     RT_ASSERT(res == RT_EOK);
 
 #if defined(RT_USING_PM)
-    rt_pm_device_register(&uhcd->parent, &device_pm_ops);
+    rt_pm_device_register(&psUHCD->parent, &device_pm_ops);
 #endif
 
-    return RT_EOK;
+    return 0;
 }
 INIT_DEVICE_EXPORT(nu_usbh_register);
 

+ 6 - 0
bsp/nuvoton/libraries/m480/USBHostLib/src/ehci.c

@@ -1113,6 +1113,9 @@ void EHCI_IRQHandler(void)
 {
     uint32_t  intsts;
 
+    /* enter interrupt */
+    rt_interrupt_enter();
+
     intsts = _ehci->USTSR;
     _ehci->USTSR = intsts;                  /* clear interrupt status                     */
 
@@ -1136,6 +1139,9 @@ void EHCI_IRQHandler(void)
     {
         iaad_remove_qh();
     }
+
+    /* leave interrupt */
+    rt_interrupt_leave();
 }
 
 static UDEV_T *ehci_find_device_by_port(int port)

+ 6 - 0
bsp/nuvoton/libraries/m480/USBHostLib/src/ohci.c

@@ -1154,6 +1154,9 @@ void OHCI_IRQHandler(void)
     TD_T       *td, *td_prev, *td_next;
     uint32_t   int_sts;
 
+    /* enter interrupt */
+    rt_interrupt_enter();
+
     int_sts = _ohci->HcInterruptStatus;
 
     //USB_debug("ohci int_sts = 0x%x\n", int_sts);
@@ -1209,6 +1212,9 @@ void OHCI_IRQHandler(void)
     }
 
     _ohci->HcInterruptStatus = int_sts;
+
+    /* leave interrupt */
+    rt_interrupt_leave();
 }
 
 #ifdef ENABLE_DEBUG_MSG

+ 33 - 19
bsp/nuvoton/libraries/m480/rtt_port/drv_i2c.c

@@ -81,20 +81,32 @@ static nu_i2c_bus_t nu_i2c2 =
 static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
                                  struct rt_i2c_msg msgs[],
                                  rt_uint32_t num);
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                   rt_uint32_t u32Cmd,
+                                   rt_uint32_t u32Value);
 
 static const struct rt_i2c_bus_device_ops nu_i2c_ops =
 {
     .master_xfer        = nu_i2c_mst_xfer,
     .slave_xfer         = NULL,
-    .i2c_bus_control    = NULL,
+    .i2c_bus_control    = nu_i2c_bus_control
 };
 
-static rt_err_t nu_i2c_configure(nu_i2c_bus_t *bus)
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t u32Cmd, rt_uint32_t u32Value)
 {
+    nu_i2c_bus_t *nu_i2c;
+
     RT_ASSERT(bus != RT_NULL);
+    nu_i2c = (nu_i2c_bus_t *) bus;
 
-    bus->parent.ops = &nu_i2c_ops;
-    I2C_Open(bus->I2C, 100000);
+    switch (RT_I2C_DEV_CTRL_CLK)
+    {
+    case RT_I2C_DEV_CTRL_CLK:
+        I2C_SetBusClockFreq(nu_i2c->I2C, u32Value);
+        break;
+    default:
+        return -RT_EIO;
+    }
 
     return RT_EOK;
 }
@@ -354,36 +366,38 @@ static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
 int rt_hw_i2c_init(void)
 {
     rt_err_t ret = RT_ERROR;
-#if   defined(BSP_USING_I2C0)
+
     SYS_UnlockReg();
-    /* Enable I2C0 clock */
-    SYS_ResetModule(I2C0_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c0);
+
+#if   defined(BSP_USING_I2C0)
+    I2C_Close(nu_i2c0.I2C);
+    I2C_Open(nu_i2c0.I2C, 100000);
+    nu_i2c0.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c0.parent, nu_i2c0.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C0 */
 
 #if   defined(BSP_USING_I2C1)
-    SYS_UnlockReg();
-    /* Enable I2C1 clock */
-    SYS_ResetModule(I2C1_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c1);
+    I2C_Close(nu_i2c1.I2C);
+    I2C_Open(nu_i2c1.I2C, 100000);
+    nu_i2c1.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c1.parent, nu_i2c1.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C1 */
 
 #if   defined(BSP_USING_I2C2)
-    SYS_UnlockReg();
-    /* Enable I2C2 clock */
-    SYS_ResetModule(I2C2_RST);
-    SYS_LockReg();
-    nu_i2c_configure(&nu_i2c2);
+    I2C_Close(nu_i2c2.I2C);
+    I2C_Open(nu_i2c2.I2C, 100000);
+    nu_i2c2.parent.ops = &nu_i2c_ops;
+
     ret = rt_i2c_bus_device_register(&nu_i2c2.parent, nu_i2c2.device_name);
     RT_ASSERT(RT_EOK == ret);
 #endif  /* BSP_USING_I2C2 */
 
+    SYS_LockReg();
+
     return ret;
 }
 

+ 244 - 208
bsp/nuvoton/libraries/m480/rtt_port/drv_usbhost.c

@@ -7,6 +7,7 @@
 * Change Logs:
 * Date            Author           Notes
 * 2020-5-4        CHChen           First version
+* 2021-11-5       Wayne            Revise
 *
 ******************************************************************************/
 #include <rtconfig.h>
@@ -32,6 +33,28 @@
 
 #define NU_MAX_USBH_HUB_PORT_DEV    USB_HUB_PORT_NUM
 
+#define NU_USBHOST_HUB_POLLING_LOCK
+#if defined(NU_USBHOST_HUB_POLLING_LOCK)
+#define NU_USBHOST_MUTEX_INIT()      { \
+                                s_sUSBHDev.lock = rt_mutex_create("usbhost_lock", RT_IPC_FLAG_PRIO); \
+                                RT_ASSERT(s_sUSBHDev.lock != RT_NULL); \
+                            }
+
+#define NU_USBHOST_LOCK()      { \
+                                rt_err_t result = rt_mutex_take(s_sUSBHDev.lock, RT_WAITING_FOREVER); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+
+#define NU_USBHOST_UNLOCK()    { \
+                                rt_err_t result = rt_mutex_release(s_sUSBHDev.lock); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+#else
+#define NU_USBHOST_MUTEX_INIT()
+#define NU_USBHOST_LOCK()
+#define NU_USBHOST_UNLOCK()
+#endif
+
 /* Private typedef --------------------------------------------------------------*/
 typedef struct nu_port_dev
 {
@@ -54,21 +77,18 @@ typedef struct nu_port_ctrl
 
 struct nu_usbh_dev
 {
-    uhcd_t uhcd;
+    struct uhcd uhcd;
     rt_thread_t polling_thread;
+    rt_mutex_t  lock;
     S_NU_RH_PORT_CTRL asPortCtrl[NU_MAX_USBH_PORT];
 };
 
 /* Private variables ------------------------------------------------------------*/
-static struct nu_usbh_dev s_sUSBHDev =
-{
-    .uhcd = RT_NULL,
-};
+static struct nu_usbh_dev s_sUSBHDev;
 
 static S_NU_RH_PORT_CTRL *
 GetRHPortControlFromPipe(
-    upipe_t pipe
-)
+    upipe_t pipe)
 {
     uinst_t inst;
     int port;
@@ -96,8 +116,7 @@ GetRHPortControlFromPipe(
 
 static S_NU_PORT_DEV *
 GetPortDevFromPipe(
-    upipe_t pipe
-)
+    upipe_t pipe)
 {
     S_NU_RH_PORT_CTRL *psRHPortCtrl = GetRHPortControlFromPipe(pipe);
     int i;
@@ -120,25 +139,24 @@ GetPortDevFromPipe(
 
     if (i >= NU_MAX_USBH_HUB_PORT_DEV)
         return RT_NULL;
+
     return &psRHPortCtrl->asHubPortDev[i];
 }
 
-
-
 static rt_err_t nu_reset_port(rt_uint8_t port)
 {
     S_NU_RH_PORT_CTRL *psPortCtrl;
 
     if (port > NU_MAX_USBH_PORT)
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_reset_port ERROR: port index over NU_MAX_USBH_PORT\n"));
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: port index over NU_MAX_USBH_PORT\n", __func__));
         return RT_EIO;
     }
 
     psPortCtrl = &s_sUSBHDev.asPortCtrl[port - 1];
     if (psPortCtrl->sRHPortDev.pUDev == NULL)
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_reset_port ERROR: udev not found\n"));
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: udev not found\n", __func__));
         return RT_EIO;
     }
 
@@ -150,42 +168,40 @@ static rt_err_t nu_reset_port(rt_uint8_t port)
 static EP_INFO_T *GetFreePipe(
     S_NU_RH_PORT_CTRL *psPortCtrl,
     S_NU_PORT_DEV *psPortDev,
-    rt_uint8_t *pu8PipeIndex
-)
+    rt_uint8_t *pu8PipeIndex)
 {
-    rt_uint8_t i;
-    if (psPortCtrl == NULL)
-        return NULL;
-
-    for (i = 1; i < NU_MAX_USBH_PIPE; i ++)
+    if (psPortCtrl != NULL)
     {
-        if (psPortDev->apsEPInfo[i] == NULL)
-            break;
-    }
-
-    if (i >= NU_MAX_USBH_PIPE)
-        return RT_NULL;
-
-    EP_INFO_T *psEPInfo = rt_malloc(sizeof(EP_INFO_T));
+        int i;
+        /* Find free Pipe */
+        for (i = 0; i < NU_MAX_USBH_PIPE; i ++)
+        {
+            if (psPortDev->apsEPInfo[i] == NULL)
+                break;
+        }
 
-    psPortDev->apsEPInfo[i] = psEPInfo;
-    *pu8PipeIndex = i;
-    return psEPInfo;
+        if (i < NU_MAX_USBH_PIPE)
+        {
+            EP_INFO_T *psEPInfo = rt_malloc(sizeof(EP_INFO_T));
+            if (psEPInfo != RT_NULL)
+            {
+                psPortDev->apsEPInfo[i] = psEPInfo;
+                *pu8PipeIndex = i;
+                return psEPInfo;
+            }
+        }
+    }
+    return RT_NULL;
 }
 
 static void FreePipe(
     S_NU_RH_PORT_CTRL *psPortCtrl,
     S_NU_PORT_DEV *psPortDev,
-    rt_uint8_t u8PipeIndex
-)
+    rt_uint8_t u8PipeIndex)
 {
-    if (psPortCtrl == NULL)
-        return;
-
-    if (u8PipeIndex >= NU_MAX_USBH_PIPE)
-        return;
-
-    if (psPortDev->apsEPInfo[u8PipeIndex])
+    if ((psPortCtrl != RT_NULL) &&
+            (u8PipeIndex < NU_MAX_USBH_PIPE) &&
+            (psPortDev->apsEPInfo[u8PipeIndex] != RT_NULL))
     {
         rt_free(psPortDev->apsEPInfo[u8PipeIndex]);
         psPortDev->apsEPInfo[u8PipeIndex] = RT_NULL;
@@ -194,28 +210,34 @@ static void FreePipe(
 
 static  S_NU_PORT_DEV *
 AllocateNewUDev(
-    S_NU_RH_PORT_CTRL *psRHPortCtrl
-)
+    S_NU_RH_PORT_CTRL *psRHPortCtrl)
 {
-    int i;
-    for (i = 0 ; i < NU_MAX_USBH_HUB_PORT_DEV; i ++)
+    if (psRHPortCtrl != RT_NULL)
     {
-        if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
-            break;
-    }
-
-    if (i >= NU_MAX_USBH_HUB_PORT_DEV)
-        return RT_NULL;
-
-    psRHPortCtrl->asHubPortDev[i].pUDev = alloc_device();
-
-    if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
-        return RT_NULL;
+        int i;
+        /* Find free Dev */
+        for (i = 0 ; i < NU_MAX_USBH_HUB_PORT_DEV; i ++)
+        {
+            if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
+                break;
+        }
 
-    return &psRHPortCtrl->asHubPortDev[i];
+        if (i < NU_MAX_USBH_HUB_PORT_DEV)
+        {
+            psRHPortCtrl->asHubPortDev[i].pUDev = alloc_device();
+            if (psRHPortCtrl->asHubPortDev[i].pUDev == NULL)
+            {
+                return RT_NULL;
+            }
+            else
+            {
+                return &psRHPortCtrl->asHubPortDev[i];
+            }
+        }
+    }
+    return RT_NULL;
 }
 
-
 static rt_err_t nu_open_pipe(upipe_t pipe)
 {
     S_NU_RH_PORT_CTRL *psPortCtrl;
@@ -224,13 +246,14 @@ static rt_err_t nu_open_pipe(upipe_t pipe)
     psPortCtrl = GetRHPortControlFromPipe(pipe);
     if (psPortCtrl == RT_NULL)
     {
-        return RT_EIO;
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: RHPort not found\n", __func__));
+        goto exit_nu_open_pipe;
     }
 
     if (psPortCtrl->sRHPortDev.pUDev == NULL)
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: udev not found\n"));
-        return RT_EIO;
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: udev not found\n", __func__));
+        goto exit_nu_open_pipe;
     }
 
     psPortDev = GetPortDevFromPipe(pipe);
@@ -243,7 +266,7 @@ static rt_err_t nu_open_pipe(upipe_t pipe)
         if (psPortDev == RT_NULL)
         {
             RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: udev allocate failed\n"));
-            return RT_EIO;
+            goto exit_nu_open_pipe;
         }
 
         if (pipe->inst->speed)
@@ -266,31 +289,35 @@ static rt_err_t nu_open_pipe(upipe_t pipe)
     if ((pipe->ep.bEndpointAddress & 0x7F) == 0)
     {
         pipe->pipe_index = 0;
-        return RT_EOK;
     }
-
-    EP_INFO_T *psEPInfo = GetFreePipe(psPortCtrl, psPortDev, &pipe->pipe_index);
-
-    if (psEPInfo == RT_NULL)
+    else
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_open_pipe ERROR: get free pipe failed\n"));
-        return RT_ENOMEM;
-    }
+        int  pksz;
+        EP_INFO_T *psEPInfo = GetFreePipe(psPortCtrl, psPortDev, &pipe->pipe_index);
+        if (psEPInfo == RT_NULL)
+        {
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("%s ERROR: get free pipe failed\n", __func__));
+            goto exit_nu_open_pipe;
+        }
 
-    int  pksz;
+        psEPInfo->bEndpointAddress = pipe->ep.bEndpointAddress;
+        psEPInfo->bmAttributes = pipe->ep.bmAttributes;
 
-    psEPInfo->bEndpointAddress = pipe->ep.bEndpointAddress;
-    psEPInfo->bmAttributes = pipe->ep.bmAttributes;
+        pksz = pipe->ep.wMaxPacketSize;
+        pksz = (pksz & 0x07ff) * (1 + ((pksz >> 11) & 3));
+        psEPInfo->wMaxPacketSize = pksz;
 
-    pksz = pipe->ep.wMaxPacketSize;
-    pksz = (pksz & 0x07ff) * (1 + ((pksz >> 11) & 3));
-    psEPInfo->wMaxPacketSize = pksz;
+        psEPInfo->bInterval = pipe->ep.bInterval;
+        psEPInfo->hw_pipe = NULL;
+        psEPInfo->bToggle = 0;
+    }
 
-    psEPInfo->bInterval = pipe->ep.bInterval;
-    psEPInfo->hw_pipe = NULL;
-    psEPInfo->bToggle = 0;
 
     return RT_EOK;
+
+exit_nu_open_pipe:
+
+    return -RT_ERROR;
 }
 
 static rt_err_t nu_close_pipe(upipe_t pipe)
@@ -339,14 +366,12 @@ static int nu_ctrl_xfer(
     S_NU_PORT_DEV *psPortDev,
     struct urequest *psSetup,
     void *buffer,
-    int timeouts
-)
+    int timeouts)
 {
-    uint32_t  xfer_len;
+    uint32_t  xfer_len = 0;
     int    ret;
 
     ret = usbh_ctrl_xfer(psPortDev->pUDev, psSetup->request_type, psSetup->bRequest, psSetup->wValue, psSetup->wIndex, psSetup->wLength, buffer, &xfer_len, timeouts * 10);
-
     if (ret < 0)
     {
         RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_ctrl_xfer ERROR: xfer failed %d\n", ret));
@@ -373,18 +398,27 @@ static int nu_ctrl_xfer(
 static int nu_bulk_xfer(
     S_NU_PORT_DEV *psPortDev,
     UTR_T *psUTR,
-    int timeouts
-)
+    int timeouts)
 {
-    int ret;
-
-    ret = usbh_bulk_xfer(psUTR);
-
+    int ret = usbh_bulk_xfer(psUTR);
     if (ret < 0)
         return ret;
 
     //wait transfer done
-    rt_completion_wait(&(psPortDev->utr_completion), timeouts);
+    if (rt_completion_wait(&(psPortDev->utr_completion), timeouts) < 0)
+    {
+        rt_kprintf("Request Timeout in %d ms!! (bulk_xfer)\n", timeouts);
+
+        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);
+
+        return -1;
+    }
     return 0;
 }
 
@@ -392,8 +426,7 @@ static int nu_int_xfer(
     upipe_t pipe,
     S_NU_PORT_DEV *psPortDev,
     UTR_T *psUTR,
-    int timeouts
-)
+    int timeouts)
 {
     int ret;
     int retry = 3;
@@ -429,9 +462,8 @@ static void int_xfer_done_cb(UTR_T *psUTR)
 
     if (psUTR->status != 0)
     {
-        rt_kprintf("Interrupt xfer failed %d\n", psUTR->status);
-        free_utr(psUTR);
-        return;
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("Interrupt xfer failed %d\n", psUTR->status));
+        goto exit_int_xfer_done_cb;
     }
 
     if (pipe->callback != RT_NULL)
@@ -443,6 +475,8 @@ static void int_xfer_done_cb(UTR_T *psUTR)
         rt_usbh_event_signal(&msg);
     }
 
+exit_int_xfer_done_cb:
+
     free_utr(psUTR);
 }
 
@@ -450,29 +484,37 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
 {
     S_NU_RH_PORT_CTRL *psPortCtrl;
     S_NU_PORT_DEV *psPortDev;
+    UTR_T *psUTR = NULL;
+    int i32XferLen = -1;
+
+    void *buffer_nonch = buffer;
+
+    NU_USBHOST_LOCK();
 
     psPortCtrl = GetRHPortControlFromPipe(pipe);
     if (psPortCtrl == RT_NULL)
     {
-        return RT_EIO;
+        goto exit_nu_pipe_xfer;
     }
 
     psPortDev = GetPortDevFromPipe(pipe);
-
     if (psPortDev->pUDev == NULL)
     {
         RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: udev not found\n"));
-        return -RT_ERROR;
+        goto exit_nu_pipe_xfer;
     }
 
     //ctrl xfer
     if (pipe->ep.bmAttributes == USB_EP_ATTR_CONTROL)
     {
+        int ret;
+
         if (token == USBH_PID_SETUP)
         {
-            struct urequest *psSetup;
-            psSetup = (struct urequest *)buffer;
+            struct urequest *psSetup = (struct urequest *)buffer_nonch;
+            RT_ASSERT(buffer_nonch != RT_NULL);
 
+            /* Read data from USB device. */
             if (psSetup->request_type & USB_REQ_TYPE_DIR_IN)
             {
                 //Store setup request
@@ -480,85 +522,90 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             }
             else
             {
-                //Trigger USBHostLib Ctril_Xfer
-                nu_ctrl_xfer(psPortDev, psSetup, NULL, timeouts);
+                /* Write data to USB device. */
+                //Trigger USBHostLib Ctrl_Xfer
+                ret = nu_ctrl_xfer(psPortDev, psSetup, NULL, timeouts);
+                if (ret != psSetup->wLength)
+                    goto exit_nu_pipe_xfer;
             }
-            return nbytes;
         }
         else
         {
             //token == USBH_PID_DATA
-            if (buffer == RT_NULL)
-                return nbytes;
-
-            if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
+            if (buffer_nonch && ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN))
             {
+                /* Read data from USB device. */
                 //Trigger USBHostLib Ctril_Xfer
-                nu_ctrl_xfer(psPortDev, &psPortCtrl->asHubPortDev->asSetupReq[pipe->pipe_index], buffer, timeouts);
+                ret = nu_ctrl_xfer(psPortDev, &psPortCtrl->asHubPortDev->asSetupReq[pipe->pipe_index], buffer_nonch, timeouts);
+                if (ret != nbytes)
+                    goto exit_nu_pipe_xfer;
             }
             else
             {
-                RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: can not handle ctrl xfer case: buffer!=NULL and USB_DIR_OUT\n"));
+                RT_DEBUG_LOG(RT_DEBUG_USB, ("%d == USBH_PID_DATA, nil buf-%d \n", token, nbytes));
             }
-            return nbytes;
-        }
-    }
-
-    //others xfer
-    rt_completion_init(&(psPortDev->utr_completion));
 
-    //setup UTR
-    UTR_T *psUTR;
-    int i32XferLen;
-
-    psUTR = alloc_utr(psPortDev->pUDev);
-    if (!psUTR)
+        } //else
+        i32XferLen = nbytes;
+        goto exit_nu_pipe_xfer;
+    } // if ( pipe->ep.bmAttributes == USB_EP_ATTR_CONTROL )
+    else
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: unable alloc UTR\n"));
-        return -(RT_ERROR);
-    }
 
-    psUTR->ep = psPortDev->apsEPInfo[pipe->pipe_index];
-    psUTR->buff = buffer;
-    psUTR->data_len = nbytes;
-    psUTR->xfer_len = 0;
-    psUTR->func = xfer_done_cb;
-    psUTR->context = psPortDev;
-    psUTR->bIsTransferDone = 0;
-    psUTR->status = 0;
+        psUTR = alloc_utr(psPortDev->pUDev);
 
-    if (pipe->ep.bmAttributes == USB_EP_ATTR_BULK)
-    {
-        if (nu_bulk_xfer(psPortDev, psUTR, timeouts) < 0)
+        if (!psUTR)
         {
-            free_utr(psUTR);
-            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: bulk transfer failed\n"));
-            return -(RT_ERROR);
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: unable alloc UTR\n"));
+            goto exit_nu_pipe_xfer;
         }
-    }
 
-    if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
-    {
-        psUTR->func = int_xfer_done_cb;
-        psUTR->context = pipe;
+        psUTR->ep = psPortDev->apsEPInfo[pipe->pipe_index];
+        psUTR->buff = buffer_nonch;
+        psUTR->data_len = nbytes;
+        psUTR->xfer_len = 0;
+        psUTR->func = xfer_done_cb;
+        psUTR->context = psPortDev;
+        psUTR->bIsTransferDone = 0;
+        psUTR->status = 0;
 
-        if (nu_int_xfer(pipe, psPortDev, psUTR, timeouts) < 0)
+        //others xfer
+        rt_completion_init(&(psPortDev->utr_completion));
+
+        if (pipe->ep.bmAttributes == USB_EP_ATTR_BULK)
         {
-            free_utr(psUTR);
-            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: int transfer failed\n"));
-            return -(RT_ERROR);
+            if (nu_bulk_xfer(psPortDev, psUTR, timeouts) < 0)
+            {
+                RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: bulk transfer failed\n"));
+                goto failreport_nu_pipe_xfer;
+            }
         }
+        else if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
+        {
+            psUTR->func = int_xfer_done_cb;
+            psUTR->context = pipe;
 
-        return nbytes;
-    }
+            if (nu_int_xfer(pipe, psPortDev, psUTR, timeouts) < 0)
+            {
+                RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: int transfer failed\n"));
+                //goto exit_nu_pipe_xfer;
+            }
+            else
+            {
+                i32XferLen = nbytes;
+            }
+            goto exit2_nu_pipe_xfer;
+        }
+        else if (pipe->ep.bmAttributes == USB_EP_ATTR_ISOC)
+        {
+            //TODO: ISO transfer
+            RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: isoc transfer not support\n"));
+            goto exit_nu_pipe_xfer;
+        }
 
-    //TODO: ISO transfer
-    if (pipe->ep.bmAttributes == USB_EP_ATTR_ISOC)
-    {
-        free_utr(psUTR);
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: isoc transfer not support\n"));
-        return -1;
-    }
+    } //else
+
+failreport_nu_pipe_xfer:
 
     if (psUTR->bIsTransferDone == 0)
     {
@@ -585,47 +632,42 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     }
 
     i32XferLen = psUTR->xfer_len;
-    free_utr(psUTR);
 
     //Call callback
     if (pipe->callback != RT_NULL)
     {
-        struct uhost_msg msg;
-        msg.type = USB_MSG_CALLBACK;
-        msg.content.cb.function = pipe->callback;
-        msg.content.cb.context = pipe->user_data;
-        rt_usbh_event_signal(&msg);
+        pipe->callback(pipe);
     }
 
-    if (pipe->status != UPIPE_STATUS_OK)
-        return -(RT_ERROR);
+exit_nu_pipe_xfer:
+
+    if (psUTR)
+        free_utr(psUTR);
+
+exit2_nu_pipe_xfer:
 
-    if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
-    {
-        return i32XferLen;
-    }
-    else if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_OUT)
-    {
-        return i32XferLen;
-    }
 
-    return nbytes;
+    NU_USBHOST_UNLOCK();
+
+    return i32XferLen;
 }
 
-//Pooling USB root hub status task
+/* Polling USB root hub status task */
 static void nu_usbh_rh_thread_entry(void *parameter)
 {
     while (1)
     {
+        NU_USBHOST_LOCK();
         usbh_polling_root_hubs();
+        NU_USBHOST_UNLOCK();
+
         rt_thread_mdelay(NU_USBHOST_HUB_POLLING_INTERVAL);
     }
 }
 
 static void nu_hcd_connect_callback(
     struct udev_t *udev,
-    int param
-)
+    int param)
 {
     int i;
     int port_index;
@@ -647,17 +689,18 @@ static void nu_hcd_connect_callback(
     port_index = i + 1;
     psPortCtrl->sRHPortDev.pUDev = udev;
     psPortCtrl->sRHPortDev.bRHParent = TRUE;
+
     RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
+
     if (udev->speed == SPEED_HIGH)
-        rt_usbh_root_hub_connect_handler(s_sUSBHDev.uhcd, port_index, RT_TRUE);
+        rt_usbh_root_hub_connect_handler(&s_sUSBHDev.uhcd, port_index, RT_TRUE);
     else
-        rt_usbh_root_hub_connect_handler(s_sUSBHDev.uhcd, port_index, RT_FALSE);
+        rt_usbh_root_hub_connect_handler(&s_sUSBHDev.uhcd, port_index, RT_FALSE);
 }
 
 static void nu_hcd_disconnect_callback(
     struct udev_t *udev,
-    int param
-)
+    int param)
 {
     int i;
     int port_index;
@@ -689,9 +732,11 @@ static void nu_hcd_disconnect_callback(
     psPortCtrl->sRHPortDev.pUDev = NULL;
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnect\n"));
-    rt_usbh_root_hub_disconnect_handler(s_sUSBHDev.uhcd, port_index);
+
+    rt_usbh_root_hub_disconnect_handler(&s_sUSBHDev.uhcd, port_index);
 }
 
+
 /* USB host operations -----------------------------------------------------------*/
 static struct uhcd_ops nu_uhcd_ops =
 {
@@ -704,25 +749,20 @@ static struct uhcd_ops nu_uhcd_ops =
 static rt_err_t nu_hcd_init(rt_device_t device)
 {
     struct nu_usbh_dev *pNuUSBHDev = (struct nu_usbh_dev *)device;
+
     usbh_core_init();
 
     //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 */
     pNuUSBHDev->polling_thread = rt_thread_create("usbh_drv", nu_usbh_rh_thread_entry, RT_NULL,
                                  NU_USBH_THREAD_STACK_SIZE, 8, 20);
-    if (pNuUSBHDev->polling_thread != RT_NULL)
-    {
-        /* startup usb host thread */
-        rt_thread_startup(pNuUSBHDev->polling_thread);
-    }
-    else
-    {
-        return -(RT_EEMPTY);
-    }
+    RT_ASSERT(pNuUSBHDev->polling_thread != RT_NULL);
+
+    /* startup usb host thread */
+    rt_thread_startup(pNuUSBHDev->polling_thread);
 
     return RT_EOK;
 }
@@ -801,8 +841,17 @@ static struct rt_device_pm_ops device_pm_ops =
 
 int nu_usbh_register(void)
 {
-    rt_err_t res = -RT_ERROR;
+    rt_err_t res;
+    uhcd_t psUHCD;
 
+    psUHCD = (uhcd_t)&s_sUSBHDev.uhcd;
+
+    psUHCD->parent.type       = RT_Device_Class_USBHost;
+    psUHCD->parent.init       = nu_hcd_init;
+    psUHCD->parent.user_data  = &s_sUSBHDev;
+
+    psUHCD->ops               = &nu_uhcd_ops;
+    psUHCD->num_ports         = NU_MAX_USBH_PORT;
 #if !defined(BSP_USING_HSOTG)
     SYS_UnlockReg();
 
@@ -825,22 +874,9 @@ int nu_usbh_register(void)
 #endif
 
 
-    rt_memset(&s_sUSBHDev, 0x0, sizeof(struct nu_usbh_dev));
-
-    uhcd_t uhcd = (uhcd_t)rt_malloc(sizeof(struct uhcd));
-    RT_ASSERT(res != RT_NULL);
-
-    rt_memset((void *)uhcd, 0, sizeof(struct uhcd));
+    NU_USBHOST_MUTEX_INIT();
 
-    uhcd->parent.type = RT_Device_Class_USBHost;
-    uhcd->parent.init = nu_hcd_init;
-    uhcd->parent.user_data = &s_sUSBHDev;
-
-    uhcd->ops = &nu_uhcd_ops;
-    uhcd->num_ports = NU_MAX_USBH_PORT;
-    s_sUSBHDev.uhcd = uhcd;
-
-    res = rt_device_register(&uhcd->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
+    res = rt_device_register(&psUHCD->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
     RT_ASSERT(res == RT_EOK);
 
     /*initialize the usb host function */
@@ -848,10 +884,10 @@ int nu_usbh_register(void)
     RT_ASSERT(res == RT_EOK);
 
 #if defined(RT_USING_PM)
-    rt_pm_device_register(&uhcd->parent, &device_pm_ops);
+    rt_pm_device_register(&psUHCD->parent, &device_pm_ops);
 #endif
 
-    return RT_EOK;
+    return 0;
 }
 INIT_DEVICE_EXPORT(nu_usbh_register);
 

+ 22 - 15
bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h

@@ -376,6 +376,7 @@ typedef struct
     __IO uint32_t BLEN;                  /*!< [0x0838] SD Block Length Register                                         */
     __IO uint32_t TOUT;                  /*!< [0x083c] SD Response/Data-in Time-out Register                            */
 
+    __IO uint32_t ECTL;                  /*!< [0x0840] SD Host Extend Control Register                                  */
 } SDH_T;
 
 
@@ -450,8 +451,8 @@ typedef struct
 #define SDH_CTL_CLK8OEN_Pos              (6)                                               /*!< SDH_T::CTL: CLK8OEN Position           */
 #define SDH_CTL_CLK8OEN_Msk              (0x1ul << SDH_CTL_CLK8OEN_Pos)                    /*!< SDH_T::CTL: CLK8OEN Mask               */
 
-#define SDH_CTL_CLKKEEP_Pos              (7)                                               /*!< SDH_T::CTL: CLKKEEP Position          */
-#define SDH_CTL_CLKKEEP_Msk              (0x1ul << SDH_CTL_CLKKEEP_Pos)                    /*!< SDH_T::CTL: CLKKEEP Mask              */
+#define SDH_CTL_CLKKEEP0_Pos              (7)                                               /*!< SDH_T::CTL: CLKKEEP Position          */
+#define SDH_CTL_CLKKEEP0_Msk              (0x1ul << SDH_CTL_CLKKEEP0_Pos)                    /*!< SDH_T::CTL: CLKKEEP Mask              */
 
 #define SDH_CTL_CMDCODE_Pos              (8)                                               /*!< SDH_T::CTL: CMDCODE Position           */
 #define SDH_CTL_CMDCODE_Msk              (0x3ful << SDH_CTL_CMDCODE_Pos)                   /*!< SDH_T::CTL: CMDCODE Mask               */
@@ -567,6 +568,12 @@ typedef struct
 #define SDH_TOUT_TOUT_Pos                (0)                                               /*!< SDH_T::TOUT: TOUT Position             */
 #define SDH_TOUT_TOUT_Msk                (0xfffffful << SDH_TOUT_TOUT_Pos)                 /*!< SDH_T::TOUT: TOUT Mask                 */
 
+#define SDH_ECTL_POWEROFF0_Pos           (0)                                               /*!< SDH_T::ECTL: POWEROFF0 Position             */
+#define SDH_ECTL_POWEROFF0_Msk           (0x1ul << SDH_ECTL_POWEROFF0_Pos)                 /*!< SDH_T::ECTL: POWEROFF0 Mask                 */
+
+#define SDH_ECTL_POWEROFF1_Pos           (1)                                               /*!< SDH_T::ECTL: POWEROFF1 Position             */
+#define SDH_ECTL_POWEROFF1_Msk           (0x1ul << SDH_ECTL_POWEROFF1_Pos)                 /*!< SDH_T::ECTL: POWEROFF1 Mask                 */
+
 /**@}*/ /* SDH_CONST */
 /**@}*/ /* end of SDH register group */
 /**@}*/ /* end of REGISTER group */
@@ -645,7 +652,6 @@ typedef struct SDH_info_t
 /*@}*/ /* end of group N9H30_SDH_EXPORTED_TYPEDEF */
 
 /// @cond HIDDEN_SYMBOLS
-extern SDH_INFO_T SD0, SD1;
 
 /// @endcond HIDDEN_SYMBOLS
 
@@ -724,7 +730,7 @@ extern SDH_INFO_T SD0, SD1;
  *            0: Card removed.
  * \hideinitializer
  */
-#define SDH_IS_CARD_PRESENT(sdh) (((sdh) == SDH0)? SD0.IsCardInsert : SD1.IsCardInsert)
+//#define SDH_IS_CARD_PRESENT(sdh) (((sdh) == SDH0)? SD0.IsCardInsert : SD1.IsCardInsert)
 
 /**
  *  @brief    Get SD Card capacity.
@@ -734,17 +740,18 @@ extern SDH_INFO_T SD0, SD1;
  *  @return   SD Card capacity. (unit: KByte)
  * \hideinitializer
  */
-#define SDH_GET_CARD_CAPACITY(sdh)  (((sdh) == SDH0)? SD0.diskSize : SD1.diskSize)
-
-
-void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc);
-uint32_t SDH_Probe(SDH_T *sdh);
-uint32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount);
-uint32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount);
-
-uint32_t SDH_CardDetection(SDH_T *sdh);
-void SDH_Open_Disk(SDH_T *sdh, uint32_t u32CardDetSrc);
-void SDH_Close_Disk(SDH_T *sdh);
+//#define SDH_GET_CARD_CAPACITY(sdh)  (((sdh) == SDH0)? SD0.diskSize : SD1.diskSize)
+
+
+void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc);
+uint32_t SDH_Probe(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num);
+uint32_t SDH_Read(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount);
+uint32_t SDH_Write(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount);
+void SDH_CardSelect(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardSrc);
+uint32_t SDH_CardDetection(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num);
+void SDH_Open_Disk(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc);
+void SDH_Close_Disk(SDH_T *sdh, SDH_INFO_T *pSD);
+uint32_t SDH_WhichCardIsSelected(SDH_T *sdh);
 
 
 /*@}*/ /* end of group N9H30_SDH_EXPORTED_FUNCTIONS */

+ 188 - 198
bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c

@@ -43,8 +43,6 @@
     static uint8_t _SDH1_ucSDHCBuffer[512] __attribute__((aligned(32)));
 #endif
 
-SDH_INFO_T SD0, SD1;
-
 void SDH_CheckRB(SDH_T *sdh)
 {
     while (1)
@@ -61,19 +59,9 @@ void SDH_CheckRB(SDH_T *sdh)
 }
 
 
-uint32_t SDH_SDCommand(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
+uint32_t SDH_SDCommand(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t ucCmd, uint32_t uArg)
 {
     volatile uint32_t buf, val = 0ul;
-    SDH_INFO_T *pSD;
-
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
 
     sdh->CMDARG = uArg;
     buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk)) | (ucCmd << 8ul) | (SDH_CTL_COEN_Msk);
@@ -90,19 +78,9 @@ uint32_t SDH_SDCommand(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
 }
 
 
-uint32_t SDH_SDCmdAndRsp(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
+uint32_t SDH_SDCmdAndRsp(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t ucCmd, uint32_t uArg, uint32_t ntickCount)
 {
     volatile uint32_t buf;
-    SDH_INFO_T *pSD;
-
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
 
     sdh->CMDARG = uArg;
     buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk)) | (ucCmd << 8ul) | (SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk);
@@ -180,20 +158,10 @@ uint32_t SDH_Swap32(uint32_t val)
 }
 
 /* Get 16 bytes CID or CSD */
-uint32_t SDH_SDCmdAndRsp2(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
+uint32_t SDH_SDCmdAndRsp2(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t ucCmd, uint32_t uArg, uint32_t puR2ptr[])
 {
     uint32_t i, buf;
     uint32_t tmpBuf[5];
-    SDH_INFO_T *pSD;
-
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
 
     sdh->CMDARG = uArg;
     buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk)) | (ucCmd << 8) | (SDH_CTL_COEN_Msk | SDH_CTL_R2EN_Msk);
@@ -226,19 +194,9 @@ uint32_t SDH_SDCmdAndRsp2(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg, uint32_t pu
 }
 
 
-uint32_t SDH_SDCmdAndRspDataIn(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
+uint32_t SDH_SDCmdAndRspDataIn(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t ucCmd, uint32_t uArg)
 {
     volatile uint32_t buf;
-    SDH_INFO_T *pSD;
-
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
 
     sdh->CMDARG = uArg;
     buf = (sdh->CTL & (~SDH_CTL_CMDCODE_Msk)) | (ucCmd << 8ul) |
@@ -279,62 +237,56 @@ uint32_t SDH_SDCmdAndRspDataIn(SDH_T *sdh, uint32_t ucCmd, uint32_t uArg)
 /* there are 8 bits for divider0, maximum is 256 */
 #define SDH_CLK_DIV0_MAX     256ul
 
+
 void SDH_Set_clock(SDH_T *sdh, uint32_t sd_clock_khz)
 {
     UINT32 div;
+    UINT32 reg;
     uint32_t SDH_ReferenceClock;
 
+    if (sdh == SDH0)
+        reg = REG_CLK_DIVCTL3;
+    else
+        reg = REG_CLK_DIVCTL9;
+
     if (sd_clock_khz <= 2000)
     {
         SDH_ReferenceClock = 12000;
-        if (sdh == SDH0)
-        {
-            outpw(REG_CLK_DIVCTL9, (inpw(REG_CLK_DIVCTL9) & ~0x18) | (0x0 << 3));   // SD clock from XIN [4:3]
-        }
-        else
-        {
-            //fixme   outpw(REG_CLK_DIVCTL9, (inpw(REG_CLK_DIVCTL9) & ~0x18) | (0x0 << 3));   // SD clock from XIN [4:3]
-        }
+        outpw(reg, (inpw(reg) & ~0x18) | (0x0 << 3));   // SD clock from XIN [4:3]
     }
     else
     {
         SDH_ReferenceClock = 300000;
-        if (sdh == SDH0)
-        {
-            outpw(REG_CLK_DIVCTL9, (inpw(REG_CLK_DIVCTL9) & ~0x18) | (0x3 << 3));   // SD clock from UPLL [4:3]
-        }
-        else
-        {
-            //fixme  outpw(REG_CLK_DIVCTL9, (inpw(REG_CLK_DIVCTL9) & ~0x18) | (0x3 << 3));   // SD clock from UPLL [4:3]
-        }
+        outpw(reg, (inpw(reg) & ~0x18) | (0x3 << 3));   // SD clock from UPLL [4:3]
     }
     div = (SDH_ReferenceClock / sd_clock_khz) - 1;
-
-    if (div >= SDH_CLK_DIV0_MAX)
-    {
-        div = 0xff;
-    }
-    outpw(REG_CLK_DIVCTL9, (inpw(REG_CLK_DIVCTL9) & ~0xff00) | ((div) << 8));  // SD clock divided by CLKDIV3[SD_N] [15:8]
+    if (div >= SDH_CLK_DIV0_MAX) div = 0xff;
+    outpw(reg, (inpw(reg) & ~0xff00) | ((div) << 8));  // SD clock divided by CLKDIV3[SD_N] [15:8]
 }
 
-uint32_t SDH_CardDetection(SDH_T *sdh)
+uint32_t SDH_CardDetection(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
 {
     uint32_t i, val = TRUE;
-    SDH_INFO_T *pSD;
+    uint32_t u32INTEN_CDSRC_Msk;
+    uint32_t u32INTSTS_CDSTS_Msk;
+    uint32_t u32CTL_CLKKEEP_Msk;
 
-    if (sdh == SDH0)
+    if (card_num & SD_PORT0)
     {
-        pSD = &SD0;
+        u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC_Msk;
+        u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS_Msk;
+        u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP0_Msk;
     }
-    else
+    else if (card_num & SD_PORT1)
     {
-        pSD = &SD1;
+        u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC1_Msk;
+        u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS1_Msk;
+        u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP1_Msk;
     }
 
-
-    if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) == SDH_INTEN_CDSRC_Msk)   /* Card detect pin from GPIO */
+    if ((sdh->INTEN & u32INTEN_CDSRC_Msk) == u32INTEN_CDSRC_Msk)   /* Card detect pin from GPIO */
     {
-        if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk)   /* Card remove */
+        if ((sdh->INTSTS & u32INTSTS_CDSTS_Msk) == u32INTSTS_CDSTS_Msk)   /* Card remove */
         {
             pSD->IsCardInsert = (uint8_t)FALSE;
             val = FALSE;
@@ -343,15 +295,16 @@ uint32_t SDH_CardDetection(SDH_T *sdh)
         {
             pSD->IsCardInsert = (uint8_t)TRUE;
         }
+
     }
-    else if ((sdh->INTEN & SDH_INTEN_CDSRC_Msk) != SDH_INTEN_CDSRC_Msk)
+    else if ((sdh->INTEN & u32INTEN_CDSRC_Msk) != u32INTEN_CDSRC_Msk)
     {
-        sdh->CTL |= SDH_CTL_CLKKEEP_Msk;
+        sdh->CTL |= u32CTL_CLKKEEP_Msk;
         for (i = 0ul; i < 5000ul; i++)
         {
         }
 
-        if ((sdh->INTSTS & SDH_INTSTS_CDSTS_Msk) == SDH_INTSTS_CDSTS_Msk)   /* Card insert */
+        if ((sdh->INTSTS & u32INTSTS_CDSTS_Msk) == u32INTSTS_CDSTS_Msk)   /* Card insert */
         {
             pSD->IsCardInsert = (uint8_t)TRUE;
         }
@@ -361,29 +314,57 @@ uint32_t SDH_CardDetection(SDH_T *sdh)
             val = FALSE;
         }
 
-        sdh->CTL &= ~SDH_CTL_CLKKEEP_Msk;
+        sdh->CTL &= ~u32CTL_CLKKEEP_Msk;
     }
 
     return val;
 }
 
-uint32_t SDH_Init(SDH_T *sdh)
+uint32_t SDH_WhichCardIsSelected(SDH_T *sdh)
 {
-    uint32_t volatile i, status;
-    uint32_t resp;
-    uint32_t CIDBuffer[4];
-    uint32_t volatile u32CmdTimeOut;
-    SDH_INFO_T *pSD;
+    return (sdh->CTL & SDH_CTL_SDPORT_Msk) ? SD_PORT1 : SD_PORT0;
+}
 
-    if (sdh == SDH0)
+void SDH_CardSelect(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardSrc)
+{
+    if (u32CardSrc & SD_PORT0)
     {
-        pSD = &SD0;
+        sdh->CTL &= ~SDH_CTL_SDPORT_Msk;
     }
-    else
+    else if (u32CardSrc & SD_PORT1)
     {
-        pSD = &SD1;
+        sdh->CTL &= ~SDH_CTL_SDPORT_Msk;
+        sdh->CTL |= (1 << SDH_CTL_SDPORT_Pos);
     }
 
+    switch (pSD->CardType)
+    {
+    case SDH_TYPE_MMC:
+        sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
+        SDH_Set_clock(sdh, MMC_FREQ);
+        break;
+    case SDH_TYPE_SD_LOW:
+    case SDH_TYPE_EMMC:
+        sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
+        SDH_Set_clock(sdh, SD_FREQ);
+        break;
+    case SDH_TYPE_SD_HIGH:
+        sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
+        SDH_Set_clock(sdh, SDHC_FREQ);
+        break;
+    case SDH_TYPE_UNKNOWN:
+    default:
+        break;
+    }
+}
+
+uint32_t SDH_Init(SDH_T *sdh, SDH_INFO_T *pSD)
+{
+    uint32_t volatile i, status;
+    uint32_t resp;
+    uint32_t CIDBuffer[4];
+    uint32_t volatile u32CmdTimeOut;
+
     /* set the clock to 300KHz */
     SDH_Set_clock(sdh, 300ul);
 
@@ -398,7 +379,7 @@ uint32_t SDH_Init(SDH_T *sdh)
         }
     }
 
-    SDH_SDCommand(sdh, 0ul, 0ul);        /* reset all cards */
+    SDH_SDCommand(sdh, pSD, 0ul, 0ul);        /* reset all cards */
     for (i = 0x1000ul; i > 0ul; i--)
     {
     }
@@ -407,20 +388,20 @@ uint32_t SDH_Init(SDH_T *sdh)
     pSD->R7Flag = 1ul;
     u32CmdTimeOut = 0xFFFFFul;
 
-    i = SDH_SDCmdAndRsp(sdh, 8ul, 0x00000155ul, u32CmdTimeOut);
+    i = SDH_SDCmdAndRsp(sdh, pSD, 8ul, 0x00000155ul, u32CmdTimeOut);
     if (i == Successful)
     {
         /* SD 2.0 */
-        SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
+        SDH_SDCmdAndRsp(sdh, pSD, 55ul, 0x00ul, u32CmdTimeOut);
         pSD->R3Flag = 1ul;
-        SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 2.7v-3.6v */
+        SDH_SDCmdAndRsp(sdh, pSD, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 2.7v-3.6v */
         resp = sdh->RESP0;
 
         while ((resp & 0x00800000ul) != 0x00800000ul)        /* check if card is ready */
         {
-            SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
+            SDH_SDCmdAndRsp(sdh, pSD, 55ul, 0x00ul, u32CmdTimeOut);
             pSD->R3Flag = 1ul;
-            SDH_SDCmdAndRsp(sdh, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
+            SDH_SDCmdAndRsp(sdh, pSD, 41ul, 0x40ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
             resp = sdh->RESP0;
         }
         if ((resp & 0x00400000ul) == 0x00400000ul)
@@ -435,23 +416,23 @@ uint32_t SDH_Init(SDH_T *sdh)
     else
     {
         /* SD 1.1 */
-        SDH_SDCommand(sdh, 0ul, 0ul);        /* reset all cards */
+        SDH_SDCommand(sdh, pSD, 0ul, 0ul);        /* reset all cards */
         for (i = 0x100ul; i > 0ul; i--)
         {
         }
 
-        i = SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
+        i = SDH_SDCmdAndRsp(sdh, pSD, 55ul, 0x00ul, u32CmdTimeOut);
         if (i == 2ul)     /* MMC memory */
         {
 
-            SDH_SDCommand(sdh, 0ul, 0ul);        /* reset */
+            SDH_SDCommand(sdh, pSD, 0ul, 0ul);        /* reset */
             for (i = 0x100ul; i > 0ul; i--)
             {
             }
 
             pSD->R3Flag = 1ul;
 
-            if (SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul)    /* eMMC memory */
+            if (SDH_SDCmdAndRsp(sdh, pSD, 1ul, 0x40ff8000ul, u32CmdTimeOut) != 2ul)    /* eMMC memory */
             {
                 resp = sdh->RESP0;
                 while ((resp & 0x00800000ul) != 0x00800000ul)
@@ -459,7 +440,7 @@ uint32_t SDH_Init(SDH_T *sdh)
                     /* check if card is ready */
                     pSD->R3Flag = 1ul;
 
-                    SDH_SDCmdAndRsp(sdh, 1ul, 0x40ff8000ul, u32CmdTimeOut);      /* high voltage */
+                    SDH_SDCmdAndRsp(sdh, pSD, 1ul, 0x40ff8000ul, u32CmdTimeOut);      /* high voltage */
                     resp = sdh->RESP0;
                 }
 
@@ -481,13 +462,13 @@ uint32_t SDH_Init(SDH_T *sdh)
         else if (i == 0ul)     /* SD Memory */
         {
             pSD->R3Flag = 1ul;
-            SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
+            SDH_SDCmdAndRsp(sdh, pSD, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
             resp = sdh->RESP0;
             while ((resp & 0x00800000ul) != 0x00800000ul)        /* check if card is ready */
             {
-                SDH_SDCmdAndRsp(sdh, 55ul, 0x00ul, u32CmdTimeOut);
+                SDH_SDCmdAndRsp(sdh, pSD, 55ul, 0x00ul, u32CmdTimeOut);
                 pSD->R3Flag = 1ul;
-                SDH_SDCmdAndRsp(sdh, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
+                SDH_SDCmdAndRsp(sdh, pSD, 41ul, 0x00ff8000ul, u32CmdTimeOut); /* 3.0v-3.4v */
                 resp = sdh->RESP0;
             }
             pSD->CardType = SDH_TYPE_SD_LOW;
@@ -495,16 +476,17 @@ uint32_t SDH_Init(SDH_T *sdh)
         else
         {
             pSD->CardType = SDH_TYPE_UNKNOWN;
+
             return SDH_INIT_ERROR;
         }
     }
 
     if (pSD->CardType != SDH_TYPE_UNKNOWN)
     {
-        SDH_SDCmdAndRsp2(sdh, 2ul, 0x00ul, CIDBuffer);
+        SDH_SDCmdAndRsp2(sdh, pSD, 2ul, 0x00ul, CIDBuffer);
         if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
         {
-            if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x10000ul, 0ul)) != Successful)     /* set RCA */
+            if ((status = SDH_SDCmdAndRsp(sdh, pSD, 3ul, 0x10000ul, 0ul)) != Successful)     /* set RCA */
             {
                 return status;
             }
@@ -512,7 +494,7 @@ uint32_t SDH_Init(SDH_T *sdh)
         }
         else
         {
-            if ((status = SDH_SDCmdAndRsp(sdh, 3ul, 0x00ul, 0ul)) != Successful)       /* get RCA */
+            if ((status = SDH_SDCmdAndRsp(sdh, pSD, 3ul, 0x00ul, 0ul)) != Successful)       /* get RCA */
             {
                 return status;
             }
@@ -534,7 +516,7 @@ uint32_t SDH_SwitchToHighSpeed(SDH_T *sdh, SDH_INFO_T *pSD)
     sdh->DMASA = (uint32_t)pSD->dmabuf;
     sdh->BLEN = 63ul;
 
-    if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x00ffff01ul)) != Successful)
+    if ((status = SDH_SDCmdAndRspDataIn(sdh, pSD, 6ul, 0x00ffff01ul)) != Successful)
     {
         return Fail;
     }
@@ -554,7 +536,7 @@ uint32_t SDH_SwitchToHighSpeed(SDH_T *sdh, SDH_INFO_T *pSD)
         sdh->DMASA = (uint32_t)pSD->dmabuf;
         sdh->BLEN = 63ul;    /* 512 bit */
 
-        if ((status = SDH_SDCmdAndRspDataIn(sdh, 6ul, 0x80ffff01ul)) != Successful)
+        if ((status = SDH_SDCmdAndRspDataIn(sdh, pSD, 6ul, 0x80ffff01ul)) != Successful)
         {
             return Fail;
         }
@@ -581,22 +563,12 @@ uint32_t SDH_SwitchToHighSpeed(SDH_T *sdh, SDH_INFO_T *pSD)
 }
 
 
-uint32_t SDH_SelectCardType(SDH_T *sdh)
+uint32_t SDH_SelectCardType(SDH_T *sdh, SDH_INFO_T *pSD)
 {
     uint32_t volatile status = 0ul;
     uint32_t param;
-    SDH_INFO_T *pSD;
 
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
-
-    if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
+    if ((status = SDH_SDCmdAndRsp(sdh, pSD, 7ul, pSD->RCA, 0ul)) != Successful)
     {
         return status;
     }
@@ -611,11 +583,11 @@ uint32_t SDH_SelectCardType(SDH_T *sdh)
         sdh->DMACTL |= SDH_DMACTL_DMARST_Msk;
         while ((sdh->DMACTL & SDH_DMACTL_DMARST_Msk) == 0x2);
 
-        if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 55ul, pSD->RCA, 0ul)) != Successful)
         {
             return status;
         }
-        if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
+        if ((status = SDH_SDCmdAndRspDataIn(sdh, pSD, 51ul, 0x00ul)) != Successful)
         {
             return status;
         }
@@ -630,11 +602,11 @@ uint32_t SDH_SelectCardType(SDH_T *sdh)
             }
         }
 
-        if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 55ul, pSD->RCA, 0ul)) != Successful)
         {
             return status;
         }
-        if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful)   /* set bus width */
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 6ul, 0x02ul, 0ul)) != Successful)   /* set bus width */
         {
             return status;
         }
@@ -646,22 +618,22 @@ uint32_t SDH_SelectCardType(SDH_T *sdh)
         sdh->DMASA = (uint32_t)pSD->dmabuf;;
         sdh->BLEN = 0x07ul;
 
-        if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 55ul, pSD->RCA, 0ul)) != Successful)
         {
             return status;
         }
-        if ((status = SDH_SDCmdAndRspDataIn(sdh, 51ul, 0x00ul)) != Successful)
+        if ((status = SDH_SDCmdAndRspDataIn(sdh, pSD, 51ul, 0x00ul)) != Successful)
         {
             return status;
         }
 
         /* set data bus width. ACMD6 for SD card, SDCR_DBW for host. */
-        if ((status = SDH_SDCmdAndRsp(sdh, 55ul, pSD->RCA, 0ul)) != Successful)
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 55ul, pSD->RCA, 0ul)) != Successful)
         {
             return status;
         }
 
-        if ((status = SDH_SDCmdAndRsp(sdh, 6ul, 0x02ul, 0ul)) != Successful)
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 6ul, 0x02ul, 0ul)) != Successful)
         {
             return status;
         }
@@ -679,7 +651,7 @@ uint32_t SDH_SelectCardType(SDH_T *sdh)
         /*--- sent CMD6 to MMC card to set bus width to 4 bits mode */
         /* set CMD6 argument Access field to 3, Index to 183, Value to 1 (4-bit mode) */
         param = (3ul << 24) | (183ul << 16) | (1ul << 8);
-        if ((status = SDH_SDCmdAndRsp(sdh, 6ul, param, 0ul)) != Successful)
+        if ((status = SDH_SDCmdAndRsp(sdh, pSD, 6ul, param, 0ul)) != Successful)
         {
             return status;
         }
@@ -689,13 +661,13 @@ uint32_t SDH_SelectCardType(SDH_T *sdh)
 
     }
 
-    if ((status = SDH_SDCmdAndRsp(sdh, 16ul, SDH_BLOCK_SIZE, 0ul)) != Successful)
+    if ((status = SDH_SDCmdAndRsp(sdh, pSD, 16ul, SDH_BLOCK_SIZE, 0ul)) != Successful)
     {
         return status;
     }
     sdh->BLEN = SDH_BLOCK_SIZE - 1ul;
 
-    SDH_SDCommand(sdh, 7ul, 0ul);
+    SDH_SDCommand(sdh, pSD, 7ul, 0ul);
     sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
     while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
     {
@@ -706,23 +678,13 @@ uint32_t SDH_SelectCardType(SDH_T *sdh)
     return Successful;
 }
 
-void SDH_Get_SD_info(SDH_T *sdh)
+void SDH_Get_SD_info(SDH_T *sdh, SDH_INFO_T *pSD)
 {
     unsigned int R_LEN, C_Size, MULT, size;
     uint32_t Buffer[4];
     //unsigned char *ptr;
-    SDH_INFO_T *pSD;
-
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
 
-    SDH_SDCmdAndRsp2(sdh, 9ul, pSD->RCA, Buffer);
+    SDH_SDCmdAndRsp2(sdh, pSD, 9ul, pSD->RCA, Buffer);
 
     if ((pSD->CardType == SDH_TYPE_MMC) || (pSD->CardType == SDH_TYPE_EMMC))
     {
@@ -731,15 +693,15 @@ void SDH_Get_SD_info(SDH_T *sdh)
         {
             /* CSD_STRUCTURE [127:126] is 3 */
             /* CSD version depend on EXT_CSD register in eMMC v4.4 for card size > 2GB */
-            SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul);
+            SDH_SDCmdAndRsp(sdh, pSD, 7ul, pSD->RCA, 0ul);
 
             //ptr = (uint8_t *)((uint32_t)_SDH_ucSDHCBuffer );
             sdh->DMASA = (uint32_t)pSD->dmabuf;;
             sdh->BLEN = 511ul;  /* read 512 bytes for EXT_CSD */
 
-            if (SDH_SDCmdAndRspDataIn(sdh, 8ul, 0x00ul) == Successful)
+            if (SDH_SDCmdAndRspDataIn(sdh, pSD, 8ul, 0x00ul) == Successful)
             {
-                SDH_SDCommand(sdh, 7ul, 0ul);
+                SDH_SDCommand(sdh, pSD, 7ul, 0ul);
                 sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
                 while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
                 {
@@ -800,55 +762,97 @@ void SDH_Get_SD_info(SDH_T *sdh)
  *
  *  @return None
  */
-void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
+void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc)
 {
     volatile int i;
+
+    uint32_t u32INTEN_CDSRC_Msk = 0;
+    uint32_t u32INTSTS_CDIF_Msk = 0;
+    uint32_t u32INTEN_CDIEN_Msk = 0;
+    uint32_t u32CTL_CLKKEEP_Msk = 0;
+
+    if (u32CardDetSrc & SD_PORT0)
+    {
+        u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC_Msk;
+        u32INTSTS_CDIF_Msk = SDH_INTSTS_CDIF_Msk;
+        u32INTEN_CDIEN_Msk = SDH_INTEN_CDIEN_Msk;
+        u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP0_Msk;
+    }
+    else if (u32CardDetSrc & SD_PORT1)
+    {
+        u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC1_Msk;
+        u32INTSTS_CDIF_Msk = SDH_INTSTS_CDIF1_Msk;
+        u32INTEN_CDIEN_Msk = SDH_INTEN_CDIEN1_Msk;
+        u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP1_Msk;
+    }
+
+    // Enable DMAC
     sdh->DMACTL = SDH_DMACTL_DMARST_Msk;
     while ((sdh->DMACTL & SDH_DMACTL_DMARST_Msk) == SDH_DMACTL_DMARST_Msk)
     {
     }
-
     sdh->DMACTL = SDH_DMACTL_DMAEN_Msk;
 
+    // Reset Global
     sdh->GCTL = SDH_GCTL_GCTLRST_Msk | SDH_GCTL_SDEN_Msk;
     while ((sdh->GCTL & SDH_GCTL_GCTLRST_Msk) == SDH_GCTL_GCTLRST_Msk)
     {
     }
 
+    if (sdh == SDH1)
+    {
+        /* Enable Power, 0: Enable, 1:Disable */
+        if (u32CardDetSrc & SD_PORT0)
+        {
+            sdh->ECTL &= ~SDH_ECTL_POWEROFF0_Msk;
+        }
+        else if (u32CardDetSrc & SD_PORT1)
+        {
+            sdh->ECTL &= ~SDH_ECTL_POWEROFF1_Msk;
+        }
+        /* disable SD clock output */
+        sdh->CTL &= ~(0xFF | u32CTL_CLKKEEP_Msk);
+    }
+
+    sdh->CTL |= SDH_CTL_CTLRST_Msk;
+    while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
+    {
+    }
+
+    memset(pSD, 0, sizeof(SDH_INFO_T));
     if (sdh == SDH0)
     {
-        memset(&SD0, 0, sizeof(SDH_INFO_T));
-        SD0.dmabuf = (unsigned char *)((uint32_t)_SDH0_ucSDHCBuffer | 0x80000000);
+        pSD->dmabuf = (unsigned char *)((uint32_t)_SDH0_ucSDHCBuffer | 0x80000000);
+        pSD->IsCardInsert = 1;
     }
     else if (sdh == SDH1)
     {
-        memset(&SD1, 0, sizeof(SDH_INFO_T));
-        SD1.dmabuf = (unsigned char *)((uint32_t)_SDH1_ucSDHCBuffer | 0x80000000);
+        pSD->dmabuf = (unsigned char *)((uint32_t)_SDH1_ucSDHCBuffer | 0x80000000);
     }
     else
     {
     }
 
+    // enable SD
     sdh->GCTL = SDH_GCTL_SDEN_Msk;
 
     if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
     {
-        sdh->INTEN &= ~SDH_INTEN_CDSRC_Msk;
+        sdh->INTEN &= ~u32INTEN_CDSRC_Msk;
     }
     else
     {
-        sdh->INTEN |= SDH_INTEN_CDSRC_Msk;
+        sdh->INTEN |= u32INTEN_CDSRC_Msk;
     }
+
     for (i = 0; i < 0x100; i++);
-    sdh->INTSTS = SDH_INTSTS_CDIF_Msk;
-    sdh->INTEN |= SDH_INTEN_CDIEN_Msk;
 
-    sdh->CTL |= SDH_CTL_CTLRST_Msk;
-    while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
-    {
-    }
+    sdh->INTSTS = u32INTSTS_CDIF_Msk;
+    sdh->INTEN |= u32INTEN_CDIEN_Msk;
 }
 
+
+
 /**
  *  @brief  This function use to initial SD card.
  *
@@ -860,29 +864,34 @@ void SDH_Open(SDH_T *sdh, uint32_t u32CardDetSrc)
  *           SD initial state needs 400KHz clock output, driver will use HIRC for SD initial clock source.
  *           And then switch back to the user's setting.
  */
-uint32_t SDH_Probe(SDH_T *sdh)
+uint32_t SDH_Probe(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
 {
     uint32_t val;
 
+    // Disable SD host interrupt
     sdh->GINTEN = 0ul;
+
     sdh->CTL &= ~SDH_CTL_SDNWR_Msk;
     sdh->CTL |=  0x09ul << SDH_CTL_SDNWR_Pos;   /* set SDNWR = 9 */
     sdh->CTL &= ~SDH_CTL_BLKCNT_Msk;
     sdh->CTL |=  0x01ul << SDH_CTL_BLKCNT_Pos;  /* set BLKCNT = 1 */
     sdh->CTL &= ~SDH_CTL_DBW_Msk;               /* SD 1-bit data bus */
 
-    if (!(SDH_CardDetection(sdh)))
+    if (sdh != SDH0)   //EMMC
     {
-        return SDH_NO_SD_CARD;
+        if (!(SDH_CardDetection(sdh, pSD, card_num)))
+        {
+            return SDH_NO_SD_CARD;
+        }
     }
 
-    if ((val = SDH_Init(sdh)) != 0ul)
+    if ((val = SDH_Init(sdh, pSD)) != 0ul)
     {
         return val;
     }
 
     /* divider */
-    if ((SD0.CardType == SDH_TYPE_MMC) || (SD1.CardType == SDH_TYPE_MMC))
+    if (pSD->CardType == SDH_TYPE_MMC)
     {
         SDH_Set_clock(sdh, MMC_FREQ);
     }
@@ -890,9 +899,9 @@ uint32_t SDH_Probe(SDH_T *sdh)
     {
         SDH_Set_clock(sdh, SD_FREQ);
     }
-    SDH_Get_SD_info(sdh);
+    SDH_Get_SD_info(sdh, pSD);
 
-    if ((val = SDH_SelectCardType(sdh)) != 0ul)
+    if ((val = SDH_SelectCardType(sdh, pSD)) != 0ul)
     {
         return val;
     }
@@ -910,32 +919,23 @@ uint32_t SDH_Probe(SDH_T *sdh)
  *
  *  @return None
  */
-uint32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
+uint32_t SDH_Read(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
 {
     uint32_t volatile bIsSendCmd = FALSE, buf;
     uint32_t volatile reg;
     uint32_t volatile i, loop, status;
     uint32_t blksize = SDH_BLOCK_SIZE;
 
-    SDH_INFO_T *pSD;
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
-
     if (u32SecCount == 0ul)
     {
         return SDH_SELECT_ERROR;
     }
 
-    if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
+    if ((status = SDH_SDCmdAndRsp(sdh, pSD, 7ul, pSD->RCA, 0ul)) != Successful)
     {
         return status;
     }
+
     SDH_CheckRB(sdh);
 
     sdh->BLEN = blksize - 1ul;       /* the actual byte count is equal to (SDBLEN+1) */
@@ -1027,13 +1027,14 @@ uint32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_
         }
     }
 
-    if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))      /* stop command */
+    if (SDH_SDCmdAndRsp(sdh, pSD, 12ul, 0ul, 0ul))      /* stop command */
     {
         return SDH_CRC7_ERROR;
     }
+
     SDH_CheckRB(sdh);
 
-    SDH_SDCommand(sdh, 7ul, 0ul);
+    SDH_SDCommand(sdh, pSD, 7ul, 0ul);
     sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
     while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
     {
@@ -1057,29 +1058,18 @@ uint32_t SDH_Read(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_
  *            \ref SDH_CRC7_ERROR : CRC7 error happen. \n
  *            \ref Successful : Write data to SD card success.
  */
-uint32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
+uint32_t SDH_Write(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
 {
     uint32_t volatile bIsSendCmd = FALSE;
     uint32_t volatile reg;
     uint32_t volatile i, loop, status;
 
-    SDH_INFO_T *pSD;
-
-    if (sdh == SDH0)
-    {
-        pSD = &SD0;
-    }
-    else
-    {
-        pSD = &SD1;
-    }
-
     if (u32SecCount == 0ul)
     {
         return SDH_SELECT_ERROR;
     }
 
-    if ((status = SDH_SDCmdAndRsp(sdh, 7ul, pSD->RCA, 0ul)) != Successful)
+    if ((status = SDH_SDCmdAndRsp(sdh, pSD, 7ul, pSD->RCA, 0ul)) != Successful)
     {
         return status;
     }
@@ -1161,13 +1151,13 @@ uint32_t SDH_Write(SDH_T *sdh, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32
     }
     sdh->INTSTS = SDH_INTSTS_CRCIF_Msk;
 
-    if (SDH_SDCmdAndRsp(sdh, 12ul, 0ul, 0ul))      /* stop command */
+    if (SDH_SDCmdAndRsp(sdh, pSD, 12ul, 0ul, 0ul))      /* stop command */
     {
         return SDH_CRC7_ERROR;
     }
     SDH_CheckRB(sdh);
 
-    SDH_SDCommand(sdh, 7ul, 0ul);
+    SDH_SDCommand(sdh, pSD, 7ul, 0ul);
     sdh->CTL |= SDH_CTL_CLK8OEN_Msk;
     while ((sdh->CTL & SDH_CTL_CLK8OEN_Msk) == SDH_CTL_CLK8OEN_Msk)
     {

+ 4 - 3
bsp/nuvoton/libraries/n9h30/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);

+ 61 - 103
bsp/nuvoton/libraries/n9h30/UsbHostLib/src/support.c

@@ -50,7 +50,7 @@ static uint32_t  _MemoryPoolBase, _MemoryPoolEnd;
 
 void  USB_InitializeMemoryPool()
 {
-    _MemoryPoolBase = (UINT32)&_USBMemoryPool[0] | NON_CACHE_MASK;
+    _MemoryPoolBase = (uint32_t)&_USBMemoryPool[0] | NON_CACHE_MASK;
     _MemoryPoolEnd = _MemoryPoolBase + USB_MEMORY_POOL_SIZE;
     _FreeMemorySize = _MemoryPoolEnd - _MemoryPoolBase;
     _AllocatedMemorySize = 0;
@@ -71,41 +71,30 @@ int  USB_allocated_memory()
 }
 
 
-void  *USB_malloc(INT wanted_size, INT boundary)
+void  *USB_malloc(int wanted_size, int boundary)
 {
+#if 0
+    void   *paddr = rt_malloc_align(wanted_size, 32);
+    return (void *)((uint32_t)paddr | NON_CACHE_MASK);
+#else
     USB_MHDR_T  *pPrimitivePos = _pCurrent;
     USB_MHDR_T  *pFound;
-    INT   found_size = -1;
-    INT   i, block_count;
-    INT   wrap = 0;
-    int   disable_ohci_irq, disable_ehci_irq;
+    int   found_size = -1;
+    int   i, block_count;
+    int   wrap = 0;
+    void   *pvBuf = NULL;
+    rt_base_t level;
 
-    if (IS_OHCI_IRQ_ENABLED())
-        disable_ohci_irq = 1;
-    else
-        disable_ohci_irq = 0;
-
-    if (IS_EHCI_IRQ_ENABLED())
-        disable_ehci_irq = 1;
-    else
-        disable_ehci_irq = 0;
-
-    if (disable_ohci_irq)
-        DISABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        DISABLE_EHCI_IRQ();
+    level = rt_hw_interrupt_disable();
 
     if (wanted_size >= _FreeMemorySize)
     {
         rt_kprintf("USB_malloc - want=%d, free=%d\n", wanted_size, _FreeMemorySize);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return NULL;
+        goto exit_USB_malloc;
     }
 
-    if ((UINT32)_pCurrent >= _MemoryPoolEnd)
+
+    if ((uint32_t)_pCurrent >= _MemoryPoolEnd)
         _pCurrent = (USB_MHDR_T *)_MemoryPoolBase;   /* wrapped */
 
     do
@@ -114,26 +103,22 @@ void  *USB_malloc(INT wanted_size, INT boundary)
         {
             if (_pCurrent->magic != USB_MEM_ALLOC_MAGIC)
             {
-                rt_kprintf("\nUSB_malloc - incorrect magic number! C:%x F:%x, wanted:%d, Base:0x%x, End:0x%x\n", (UINT32)_pCurrent, _FreeMemorySize, wanted_size, (UINT32)_MemoryPoolBase, (UINT32)_MemoryPoolEnd);
-                if (disable_ohci_irq)
-                    ENABLE_OHCI_IRQ();
-                if (disable_ehci_irq)
-                    ENABLE_EHCI_IRQ();
-                return NULL;
+                rt_kprintf("\nUSB_malloc - incorrect magic number! C:%x F:%x, wanted:%d, Base:0x%x, End:0x%x\n", (uint32_t)_pCurrent, _FreeMemorySize, wanted_size, (uint32_t)_MemoryPoolBase, (uint32_t)_MemoryPoolEnd);
+                goto exit_USB_malloc;
             }
 
             if (_pCurrent->flag == 0x3)
-                _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + _pCurrent->bcnt * USB_MEM_BLOCK_SIZE);
+                _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + _pCurrent->bcnt * USB_MEM_BLOCK_SIZE);
             else
             {
                 rt_kprintf("USB_malloc warning - not the first block!\n");
-                _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
+                _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + USB_MEM_BLOCK_SIZE);
             }
 
-            if ((UINT32)_pCurrent > _MemoryPoolEnd)
+            if ((uint32_t)_pCurrent > _MemoryPoolEnd)
                 rt_kprintf("USB_malloc - behind limit!!\n");
 
-            if ((UINT32)_pCurrent == _MemoryPoolEnd)
+            if ((uint32_t)_pCurrent == _MemoryPoolEnd)
             {
                 //rt_kprintf("USB_alloc - warp!!\n");
                 wrap = 1;
@@ -161,8 +146,8 @@ void  *USB_malloc(INT wanted_size, INT boundary)
                  * used as a header only.
                  */
                 if ((boundary > BOUNDARY_WORD) &&
-                        ((((UINT32)_pCurrent) + USB_MEM_BLOCK_SIZE >= _MemoryPoolEnd) ||
-                         ((((UINT32)_pCurrent) + USB_MEM_BLOCK_SIZE) % boundary != 0)))
+                        ((((uint32_t)_pCurrent) + USB_MEM_BLOCK_SIZE >= _MemoryPoolEnd) ||
+                         ((((uint32_t)_pCurrent) + USB_MEM_BLOCK_SIZE) % boundary != 0)))
                     found_size = -1;   /* violate boundary, reset the accumlator */
             }
             else                      /* not the leading block */
@@ -181,34 +166,26 @@ void  *USB_malloc(INT wanted_size, INT boundary)
                 for (i = 0; i < block_count; i++)
                 {
                     _pCurrent->flag = 1;     /* allocate block */
-                    _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
+                    _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + USB_MEM_BLOCK_SIZE);
                 }
                 pFound->flag = 0x3;
 
                 if (boundary > BOUNDARY_WORD)
                 {
-                    if (disable_ohci_irq)
-                        ENABLE_OHCI_IRQ();
-                    if (disable_ehci_irq)
-                        ENABLE_EHCI_IRQ();
-                    //rt_kprintf("- 0x%x, %d\n", (int)pFound, wanted_size);
-                    return (void *)((UINT32)pFound + USB_MEM_BLOCK_SIZE);
+                    pvBuf = (void *)((uint32_t)pFound + USB_MEM_BLOCK_SIZE);
+                    goto exit_USB_malloc;
                 }
                 else
                 {
-                    //USB_debug("USB_malloc(%d,%d):%x\tsize:%d, C:0x%x, %d\n", wanted_size, boundary, (UINT32)pFound + sizeof(USB_MHDR_T), block_count * USB_MEM_BLOCK_SIZE, _pCurrent, block_count);
-                    if (disable_ohci_irq)
-                        ENABLE_OHCI_IRQ();
-                    if (disable_ehci_irq)
-                        ENABLE_EHCI_IRQ();
-                    //rt_kprintf("- 0x%x, %d\n", (int)pFound, wanted_size);
-                    return (void *)((UINT32)pFound + sizeof(USB_MHDR_T));
+                    //USB_debug("USB_malloc(%d,%d):%x\tsize:%d, C:0x%x, %d\n", wanted_size, boundary, (uint32_t)pFound + sizeof(USB_MHDR_T), block_count * USB_MEM_BLOCK_SIZE, _pCurrent, block_count);
+                    pvBuf = (void *)((uint32_t)pFound + sizeof(USB_MHDR_T));
+                    goto exit_USB_malloc;
                 }
             }
 
             /* advance to the next block */
-            _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
-            if ((UINT32)_pCurrent >= _MemoryPoolEnd)
+            _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + USB_MEM_BLOCK_SIZE);
+            if ((uint32_t)_pCurrent >= _MemoryPoolEnd)
             {
                 wrap = 1;
                 _pCurrent = (USB_MHDR_T *)_MemoryPoolBase;   /* wrapped */
@@ -219,49 +196,40 @@ void  *USB_malloc(INT wanted_size, INT boundary)
     while ((wrap == 0) || (_pCurrent < pPrimitivePos));
 
     rt_kprintf("USB_malloc - No free memory!\n");
-    if (disable_ohci_irq)
-        ENABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        ENABLE_EHCI_IRQ();
-    return NULL;
-}
 
+exit_USB_malloc:
+
+    rt_hw_interrupt_enable(level);
+
+    return pvBuf;
+#endif
+
+}
 
 void  USB_free(void *alloc_addr)
 {
+#if 0
+    rt_free_align((void *)((uint32_t)alloc_addr & ~NON_CACHE_MASK));
+#else
     USB_MHDR_T  *pMblk;
-    UINT32  addr = (UINT32)alloc_addr;
-    INT     i, count;
-    int     disable_ohci_irq, disable_ehci_irq;
-
-    if (IS_OHCI_IRQ_ENABLED())
-        disable_ohci_irq = 1;
-    else
-        disable_ohci_irq = 0;
-
-    if (IS_EHCI_IRQ_ENABLED())
-        disable_ehci_irq = 1;
-    else
-        disable_ehci_irq = 0;
+    uint32_t  addr = (uint32_t)alloc_addr;
+    int     i, count;
+    rt_base_t level;
 
     //rt_kprintf("USB_free: 0x%x\n", (int)alloc_addr);
 
+    level = rt_hw_interrupt_disable();
+
     if ((addr < _MemoryPoolBase) || (addr >= _MemoryPoolEnd))
     {
         if (addr)
         {
             rt_kprintf("[%s]Wrong!!\n", __func__);
-            //free(alloc_addr);
         }
-        return;
+        goto Exit_USB_free;
     }
 
-    if (disable_ohci_irq)
-        DISABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        DISABLE_EHCI_IRQ();
-
-    //rt_kprintf("USB_free:%x\n", (INT)addr+USB_MEM_BLOCK_SIZE);
+    //rt_kprintf("USB_free:%x\n", (int32_t)addr+USB_MEM_BLOCK_SIZE);
 
     /* get the leading block address */
     if (addr % USB_MEM_BLOCK_SIZE == 0)
@@ -271,32 +239,20 @@ void  USB_free(void *alloc_addr)
 
     if (addr % USB_MEM_BLOCK_SIZE != 0)
     {
-        rt_kprintf("USB_free fatal error on address: %x!!\n", (UINT32)alloc_addr);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return;
+        rt_kprintf("USB_free fatal error on address: %x!!\n", (uint32_t)alloc_addr);
+        goto Exit_USB_free;
     }
 
     pMblk = (USB_MHDR_T *)addr;
     if (pMblk->flag == 0)
     {
-        rt_kprintf("USB_free(), warning - try to free a free block: %x\n", (UINT32)alloc_addr);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return;
+        rt_kprintf("USB_free(), warning - try to free a free block: %x\n", (uint32_t)alloc_addr);
+        goto Exit_USB_free;
     }
     if (pMblk->magic != USB_MEM_ALLOC_MAGIC)
     {
         rt_kprintf("USB_free(), warning - try to free an unknow block at address:%x.\n", addr);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return;
+        goto Exit_USB_free;
     }
 
     //_pCurrent = pMblk;
@@ -307,15 +263,17 @@ void  USB_free(void *alloc_addr)
     for (i = 0; i < count; i++)
     {
         pMblk->flag = 0;     /* release block */
-        pMblk = (USB_MHDR_T *)((UINT32)pMblk + USB_MEM_BLOCK_SIZE);
+        pMblk = (USB_MHDR_T *)((uint32_t)pMblk + USB_MEM_BLOCK_SIZE);
     }
 
     _FreeMemorySize += count * USB_MEM_BLOCK_SIZE;
     _AllocatedMemorySize -= count * USB_MEM_BLOCK_SIZE;
-    if (disable_ohci_irq)
-        ENABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        ENABLE_EHCI_IRQ();
+
+
+Exit_USB_free:
+
+    rt_hw_interrupt_enable(level);
+#endif
     return;
 }
 

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

@@ -67,7 +67,7 @@ void  usbh_core_init()
 #ifdef ENABLE_OHCI
     //sysInstallISR(IRQ_LEVEL_1, IRQ_OHCI, (PVOID)OHCI_IRQHandler);
     rt_hw_interrupt_install(IRQ_OHCI, nu_ohci_isr, NULL, "ohci");
-    rt_hw_interrupt_set_priority(IRQ_OHCI, IRQ_LEVEL_1);
+    //rt_hw_interrupt_set_priority(IRQ_OHCI, IRQ_LEVEL_1);
 
     ohci_driver.init();
     ENABLE_OHCI_IRQ();
@@ -76,7 +76,7 @@ void  usbh_core_init()
 #ifdef ENABLE_EHCI
     //sysInstallISR(IRQ_LEVEL_1, IRQ_EHCI, (PVOID)EHCI_IRQHandler);
     rt_hw_interrupt_install(IRQ_EHCI, nu_ehci_isr, NULL, "ehci");
-    rt_hw_interrupt_set_priority(IRQ_EHCI, IRQ_LEVEL_1);
+    //rt_hw_interrupt_set_priority(IRQ_EHCI, IRQ_LEVEL_1);
 
     ehci_driver.init();
     ENABLE_EHCI_IRQ();

+ 6 - 2
bsp/nuvoton/libraries/n9h30/rtt_port/Kconfig

@@ -275,11 +275,15 @@ config SOC_SERIES_N9H30
         select RT_USING_DFS
 
         if BSP_USING_SDH
+
+            config BSP_USING_EMMC
+                bool "Enable FMI_EMMC"
+
             config BSP_USING_SDH0
-                bool "Enable SDH0"
+                bool "Enable SDH_PORT0"
 
             config BSP_USING_SDH1
-                bool "Enable SDH1"
+                bool "Enable SDH_PORT1"
 
             config NU_SDH_HOTPLUG
                 bool "Using HOTPLUG"

+ 1 - 1
bsp/nuvoton/libraries/n9h30/rtt_port/drv_ge2d.c

@@ -12,7 +12,7 @@
 #include <drv_sys.h>
 
 //#define DEBUG
-//#define DEF_COND_WAIT 1
+#define DEF_COND_WAIT 1
 
 static unsigned int GFX_BPP;
 static unsigned int GFX_WIDTH;

+ 5 - 5
bsp/nuvoton/libraries/n9h30/rtt_port/drv_i2s.c

@@ -244,6 +244,11 @@ static rt_err_t nu_i2s_dai_setup(nu_i2s_t psNuI2s, struct rt_audio_configure *pc
         i2sIoctl(I2S_SET_I2S_FORMAT, I2S_FORMAT_I2S, 0);
 
         if (psNuI2s->AcodecOps->role == NU_ACODEC_ROLE_MASTER)
+        {
+            // Set as slave, source clock is XIN (12MHz)
+            i2sIoctl(I2S_SET_MODE, I2S_MODE_SLAVE, 0);
+        }
+        else
         {
             if (pconfig->samplerate % 11025)
             {
@@ -284,11 +289,6 @@ static rt_err_t nu_i2s_dai_setup(nu_i2s_t psNuI2s, struct rt_audio_configure *pc
             // Set as master
             i2sIoctl(I2S_SET_MODE, I2S_MODE_MASTER, 0);
         }
-        else
-        {
-            // Set as slave, source clock is XIN (12MHz)
-            i2sIoctl(I2S_SET_MODE, I2S_MODE_SLAVE, 0);
-        }
 
         LOG_I("Open I2S.");
 

+ 220 - 31
bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c

@@ -28,8 +28,12 @@
 
 #if defined(NU_SDH_MOUNT_ON_ROOT)
 
+    #if !defined(NU_SDH_MOUNTPOINT_EMMC)
+        #define NU_SDH_MOUNTPOINT_EMMC  "/"
+    #endif
+
     #if !defined(NU_SDH_MOUNTPOINT_SDH0)
-        #define NU_SDH_MOUNTPOINT_SDH0  "/"
+        #define NU_SDH_MOUNTPOINT_SDH0  NU_SDH_MOUNTPOINT_SDH0"/sd0"
     #endif
 
     #if !defined(NU_SDH_MOUNTPOINT_SDH1)
@@ -44,6 +48,10 @@
 
 #endif
 
+#if !defined(NU_SDH_MOUNTPOINT_EMMC)
+    #define NU_SDH_MOUNTPOINT_EMMC  NU_SDH_MOUNTPOINT_ROOT"/emmc"
+#endif
+
 #if !defined(NU_SDH_MOUNTPOINT_SDH0)
     #define NU_SDH_MOUNTPOINT_SDH0  NU_SDH_MOUNTPOINT_ROOT"/sd0"
 #endif
@@ -52,9 +60,16 @@
     #define NU_SDH_MOUNTPOINT_SDH1  NU_SDH_MOUNTPOINT_ROOT"/sd1"
 #endif
 
+#if defined(BSP_USING_SDH0) && defined(BSP_USING_SDH1)
+    #define NU_SDH_SHARED 1
+#endif
+
 enum
 {
     SDH_START = -1,
+#if defined(BSP_USING_EMMC)
+    EMMC_IDX,
+#endif
 #if defined(BSP_USING_SDH0)
     SDH0_IDX,
 #endif
@@ -71,12 +86,13 @@ enum
 #endif
 
 #if defined(NU_SDH_HOTPLUG)
-enum
+typedef enum
 {
-    NU_SDH_CARD_DETECTED_SD0 = (1 << 0),
-    NU_SDH_CARD_DETECTED_SD1 = (1 << 1),
-    NU_SDH_CARD_EVENT_ALL = (NU_SDH_CARD_DETECTED_SD0 | NU_SDH_CARD_DETECTED_SD1)
-};
+    NU_SDH_CARD_DETECTED_EMMC = (1 << 0),
+    NU_SDH_CARD_DETECTED_SD0  = (1 << 1),
+    NU_SDH_CARD_DETECTED_SD1  = (1 << 2),
+    NU_SDH_CARD_EVENT_ALL = (NU_SDH_CARD_DETECTED_EMMC | NU_SDH_CARD_DETECTED_SD0 | NU_SDH_CARD_DETECTED_SD1)
+} E_CARD_EVENT;
 #endif
 
 /* Private typedef --------------------------------------------------------------*/
@@ -92,6 +108,11 @@ struct nu_sdh
     E_SYS_IPRST           rstidx;
     E_SYS_IPCLK           clkidx;
 
+#if defined(NU_SDH_HOTPLUG)
+    E_CARD_EVENT          card_detected_event;
+#endif
+    uint32_t              card_num;
+
     uint32_t              is_card_inserted;
     SDH_INFO_T           *info;
     struct rt_semaphore   lock;
@@ -123,32 +144,75 @@ static int rt_hw_sdh_init(void);
 
 
 /* Private variables ------------------------------------------------------------*/
+#if defined(BSP_USING_EMMC)
+    static SDH_INFO_T EMMC;
+#endif
+
+#if defined(BSP_USING_SDH0)
+    static SDH_INFO_T SD0;
+#endif
+
+#if defined(BSP_USING_SDH1)
+    static SDH_INFO_T SD1;
+#endif
+
+#if defined(NU_SDH_SHARED)
+    static struct rt_mutex   g_shared_lock;
+#endif
+
 static struct nu_sdh nu_sdh_arr [] =
 {
-#if defined(BSP_USING_SDH0)
+#if defined(BSP_USING_EMMC)
     {
-        .name = "sdh0",
+        .name = "emmc",
 #if defined(NU_SDH_HOTPLUG)
-        .mounted_point = NU_SDH_MOUNTPOINT_SDH0,
+        .mounted_point = NU_SDH_MOUNTPOINT_EMMC,
 #endif
         .irqn = IRQ_FMI,
         .base = SDH0,
+        .card_num = SD_PORT0,
         .rstidx = FMIRST,
         .clkidx = EMMCCKEN,
+        .info = &EMMC,
+        .card_detected_event = NU_SDH_CARD_DETECTED_EMMC,
+    },
+#endif
+
+#if defined(BSP_USING_SDH0)
+    {
+        .name = "sdh0",
+#if defined(NU_SDH_HOTPLUG)
+        .mounted_point = NU_SDH_MOUNTPOINT_SDH0,
+#endif
+        .irqn = IRQ_SDH,
+        .base = SDH1,
+        .card_num = SD_PORT0,
+        .rstidx = SDIORST,
+        .clkidx = SDHCKEN,
         .info = &SD0,
+        .card_detected_event = NU_SDH_CARD_DETECTED_SD0,
     },
 #endif
+
 #if defined(BSP_USING_SDH1)
     {
         .name = "sdh1",
 #if defined(NU_SDH_HOTPLUG)
         .mounted_point = NU_SDH_MOUNTPOINT_SDH1,
 #endif
-        .irqn = IRQ_SDH,
         .base = SDH1,
+        .card_num = SD_PORT1,
+#if defined(NU_SDH_SHARED)
+        .irqn = (IRQn_Type)0,
+        .rstidx = SYS_IPRST_NA,
+        .clkidx = SYS_IPCLK_NA,
+#else
+        .irqn = IRQ_SDH,
         .rstidx = SDIORST,
         .clkidx = SDHCKEN,
+#endif
         .info = &SD1,
+        .card_detected_event = NU_SDH_CARD_DETECTED_SD1,
     },
 #endif
 }; /* struct nu_sdh nu_sdh_arr [] */
@@ -161,6 +225,11 @@ static void SDH_IRQHandler(int vector, void *param)
     unsigned int volatile isr;
     SDH_INFO_T *pSD = sdh->info;
 
+#if defined(BSP_USING_SDH1)
+    if (SDH_WhichCardIsSelected(sdh_base) == SD_PORT1)
+        pSD = &SD1;
+#endif
+
     // FMI data abort interrupt
     if (sdh_base->GINTSTS & SDH_GINTSTS_DTAIF_Msk)
     {
@@ -177,17 +246,22 @@ static void SDH_IRQHandler(int vector, void *param)
         SDH_CLR_INT_FLAG(sdh_base, SDH_INTSTS_BLKDIF_Msk);
     }
 
-    if (isr & SDH_INTSTS_CDIF_Msk)   // card detect
+    if (isr & SDH_INTSTS_CDIF_Msk)   // card number=0 detect
     {
 #if defined(NU_SDH_HOTPLUG)
-        if (sdh->base == SDH0)
-            rt_event_send(&sdh_event, NU_SDH_CARD_DETECTED_SD0);
-        else if (sdh->base == SDH1)
-            rt_event_send(&sdh_event, NU_SDH_CARD_DETECTED_SD1);
+        rt_event_send(&sdh_event, sdh->card_detected_event);
 #endif
         /* Clear CDIF interrupt flag */
         SDH_CLR_INT_FLAG(sdh_base, SDH_INTSTS_CDIF_Msk);
     }
+    else if (isr & SDH_INTSTS_CDIF1_Msk)   // card number=1 detect
+    {
+#if defined(NU_SDH_HOTPLUG)
+        rt_event_send(&sdh_event, NU_SDH_CARD_DETECTED_SD1);
+#endif
+        /* Clear CDIF1 interrupt flag */
+        SDH_CLR_INT_FLAG(sdh_base, SDH_INTSTS_CDIF1_Msk);
+    }
 
     // CRC error interrupt
     if (isr & SDH_INTSTS_CRCIF_Msk)
@@ -231,10 +305,36 @@ static rt_err_t nu_sdh_init(rt_device_t dev)
 static rt_err_t nu_sdh_open(rt_device_t dev, rt_uint16_t oflag)
 {
     nu_sdh_t sdh = (nu_sdh_t)dev;
+    rt_err_t result = RT_EOK;
 
     RT_ASSERT(dev != RT_NULL);
 
-    return (SDH_Probe(sdh->base) == 0) ? RT_EOK :  -(RT_ERROR);
+#if defined(NU_SDH_SHARED)
+    if (sdh->base == SDH1)
+    {
+        result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
+        RT_ASSERT(result == RT_EOK);
+    }
+    SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
+#endif
+
+    if (SDH_Probe(sdh->base, sdh->info, sdh->card_num) == 0)
+    {
+        result = RT_EOK;
+    }
+    else
+    {
+        result = -RT_ERROR;
+    }
+
+#if defined(NU_SDH_SHARED)
+    if (sdh->base == SDH1)
+    {
+        rt_mutex_release(&g_shared_lock);
+    }
+#endif
+
+    return result;
 }
 
 static rt_err_t nu_sdh_close(rt_device_t dev)
@@ -251,6 +351,15 @@ static rt_size_t nu_sdh_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_siz
     RT_ASSERT(dev != RT_NULL);
     RT_ASSERT(buffer != RT_NULL);
 
+#if defined(NU_SDH_SHARED)
+    if (sdh->base == SDH1)
+    {
+        result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
+        RT_ASSERT(result == RT_EOK);
+    }
+    SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
+#endif
+
     result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
     RT_ASSERT(result == RT_EOK);
 
@@ -268,7 +377,7 @@ static rt_size_t nu_sdh_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_siz
         for (i = 0; i < blk_nb; i++)
         {
             /* Read to temp buffer from specified sector. */
-            ret = SDH_Read(sdh->base, (uint8_t *)((uint32_t)&sdh->pbuf[0] | NONCACHEABLE), pos, 1);
+            ret = SDH_Read(sdh->base, sdh->info, (uint8_t *)((uint32_t)&sdh->pbuf[0] | NONCACHEABLE), pos, 1);
             if (ret != Successful)
                 goto exit_nu_sdh_read;
 
@@ -286,7 +395,7 @@ static rt_size_t nu_sdh_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_siz
 #endif
 
         /* Read to user's buffer from specified sector. */
-        ret = SDH_Read(sdh->base, (uint8_t *)((uint32_t)buffer | NONCACHEABLE), pos, blk_nb);
+        ret = SDH_Read(sdh->base, sdh->info, (uint8_t *)((uint32_t)buffer | NONCACHEABLE), pos, blk_nb);
     }
 
 exit_nu_sdh_read:
@@ -300,6 +409,13 @@ exit_nu_sdh_read:
     result = rt_sem_release(&sdh->lock);
     RT_ASSERT(result == RT_EOK);
 
+#if defined(NU_SDH_SHARED)
+    if (sdh->base == SDH1)
+    {
+        rt_mutex_release(&g_shared_lock);
+    }
+#endif
+
     if (ret == Successful)
         return blk_nb;
 
@@ -317,6 +433,15 @@ static rt_size_t nu_sdh_write(rt_device_t dev, rt_off_t pos, const void *buffer,
     RT_ASSERT(dev != RT_NULL);
     RT_ASSERT(buffer != RT_NULL);
 
+#if defined(NU_SDH_SHARED)
+    if (sdh->base == SDH1)
+    {
+        result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
+        RT_ASSERT(result == RT_EOK);
+    }
+    SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
+#endif
+
     result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
     RT_ASSERT(result == RT_EOK);
 
@@ -339,7 +464,7 @@ static rt_size_t nu_sdh_write(rt_device_t dev, rt_off_t pos, const void *buffer,
 
             memcpy((void *)&sdh->pbuf[0], copy_buffer, SDH_BLOCK_SIZE);
 
-            ret = SDH_Write(sdh->base, (uint8_t *)((uint32_t)&sdh->pbuf[0] | NONCACHEABLE), pos, 1);
+            ret = SDH_Write(sdh->base, sdh->info, (uint8_t *)((uint32_t)&sdh->pbuf[0] | NONCACHEABLE), pos, 1);
             if (ret != Successful)
                 goto exit_nu_sdh_write;
 
@@ -354,7 +479,7 @@ static rt_size_t nu_sdh_write(rt_device_t dev, rt_off_t pos, const void *buffer,
 #endif
 
         /* Write to device directly. */
-        ret = SDH_Write(sdh->base, (uint8_t *)((uint32_t)buffer | NONCACHEABLE), pos, blk_nb);
+        ret = SDH_Write(sdh->base, sdh->info, (uint8_t *)((uint32_t)buffer | NONCACHEABLE), pos, blk_nb);
     }
 
 exit_nu_sdh_write:
@@ -368,6 +493,13 @@ exit_nu_sdh_write:
     result = rt_sem_release(&sdh->lock);
     RT_ASSERT(result == RT_EOK);
 
+#if defined(NU_SDH_SHARED)
+    if (sdh->base == SDH1)
+    {
+        rt_mutex_release(&g_shared_lock);
+    }
+#endif
+
     if (ret == Successful) return blk_nb;
 
     rt_kprintf("write failed: %d, buffer 0x%08x\n", ret, buffer);
@@ -408,6 +540,16 @@ static int rt_hw_sdh_init(void)
     ret = rt_event_init(&sdh_event, "sdh_event", RT_IPC_FLAG_FIFO);
     RT_ASSERT(ret == RT_EOK);
 
+#if defined(NU_SDH_SHARED)
+    ret = rt_mutex_init(&g_shared_lock, "sdh_share_lock", RT_IPC_FLAG_PRIO);
+    RT_ASSERT(ret == RT_EOK);
+#endif
+
+#if defined(BSP_USING_EMMC)
+    nu_sys_ipclk_enable(FMICKEN);
+    nu_sys_ipclk_enable(NANDCKEN);
+#endif
+
     for (i = (SDH_START + 1); i < SDH_CNT; i++)
     {
         /* Register sdcard device */
@@ -425,12 +567,21 @@ static int rt_hw_sdh_init(void)
         ret = rt_sem_init(&nu_sdh_arr[i].lock, "sdhlock", 1, RT_IPC_FLAG_FIFO);
         RT_ASSERT(ret == RT_EOK);
 
-        rt_hw_interrupt_install(nu_sdh_arr[i].irqn, SDH_IRQHandler, (void *)&nu_sdh_arr[i], nu_sdh_arr[i].name);
-        rt_hw_interrupt_umask(nu_sdh_arr[i].irqn);
+        if (nu_sdh_arr[i].irqn != 0)
+        {
+            rt_hw_interrupt_install(nu_sdh_arr[i].irqn, SDH_IRQHandler, (void *)&nu_sdh_arr[i], nu_sdh_arr[i].name);
+            rt_hw_interrupt_umask(nu_sdh_arr[i].irqn);
+        }
 
-        nu_sys_ipclk_enable(nu_sdh_arr[i].clkidx);
+        if (nu_sdh_arr[i].clkidx != SYS_IPCLK_NA)
+        {
+            nu_sys_ipclk_enable(nu_sdh_arr[i].clkidx);
+        }
 
-        nu_sys_ip_reset(nu_sdh_arr[i].rstidx);
+        if (nu_sdh_arr[i].rstidx != SYS_IPRST_NA)
+        {
+            nu_sys_ip_reset(nu_sdh_arr[i].rstidx);
+        }
 
         nu_sdh_arr[i].pbuf = RT_NULL;
 
@@ -559,8 +710,10 @@ exit_nu_sdh_hotplug_unmount:
 static void nu_card_detector(nu_sdh_t sdh)
 {
     SDH_T *sdh_base = sdh->base;
+    uint32_t u32INTSTS_CDSTS_Msk = (sdh->card_num == SD_PORT0) ? SDH_INTSTS_CDSTS_Msk : SDH_INTSTS_CDSTS1_Msk;
     unsigned int volatile isr = sdh_base->INTSTS;
-    if (isr & SDH_INTSTS_CDSTS_Msk)
+
+    if (isr & u32INTSTS_CDSTS_Msk)
     {
         /* Card removed */
         sdh->info->IsCardInsert = FALSE;   // SDISR_CD_Card = 1 means card remove for GPIO mode
@@ -569,12 +722,27 @@ static void nu_card_detector(nu_sdh_t sdh)
     }
     else
     {
-        SDH_Open(sdh_base, CardDetect_From_GPIO);
-        if (!SDH_Probe(sdh_base))
+#if defined(NU_SDH_SHARED)
+        if (sdh_base == SDH1)
+        {
+            rt_err_t result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
+            RT_ASSERT(result == RT_EOK);
+        }
+        SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
+#endif
+
+        SDH_Open(sdh_base, sdh->info, CardDetect_From_GPIO | sdh->card_num);
+        if (!SDH_Probe(sdh_base, sdh->info, sdh->card_num))
         {
             /* Card inserted */
             nu_sdh_hotplug_mount(sdh);
         }
+#if defined(NU_SDH_SHARED)
+        if (sdh_base == SDH1)
+        {
+            rt_mutex_release(&g_shared_lock);
+        }
+#endif
     }
 }
 
@@ -585,13 +753,29 @@ static void sdh_hotplugger(void *param)
 
     for (i = (SDH_START + 1); i < SDH_CNT; i++)
     {
+#if defined(NU_SDH_SHARED)
+        if (nu_sdh_arr[i].base == SDH1)
+        {
+            rt_err_t result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
+            RT_ASSERT(result == RT_EOK);
+        }
+        SDH_CardSelect(nu_sdh_arr[i].base, nu_sdh_arr[i].info, nu_sdh_arr[i].card_num);
+#endif
+
         /* Try to detect SD card on selected port. */
-        SDH_Open(nu_sdh_arr[i].base, CardDetect_From_GPIO);
-        if (!SDH_Probe(nu_sdh_arr[i].base) &&
-                SDH_IS_CARD_PRESENT(nu_sdh_arr[i].base))
+        SDH_Open(nu_sdh_arr[i].base, nu_sdh_arr[i].info, CardDetect_From_GPIO | nu_sdh_arr[i].card_num);
+        if (!SDH_Probe(nu_sdh_arr[i].base, nu_sdh_arr[i].info, nu_sdh_arr[i].card_num) &&
+                nu_sdh_arr[i].info->IsCardInsert)
         {
             nu_sdh_hotplug_mount(&nu_sdh_arr[i]);
         }
+
+#if defined(NU_SDH_SHARED)
+        if (nu_sdh_arr[i].base == SDH1)
+        {
+            rt_mutex_release(&g_shared_lock);
+        }
+#endif
     }
 
     while (1)
@@ -601,9 +785,14 @@ static void sdh_hotplugger(void *param)
                           RT_WAITING_FOREVER, &e) == RT_EOK)
         {
             /* Debounce */
-            rt_thread_mdelay(200);
+            rt_thread_mdelay(500);
             switch (e)
             {
+#if defined(BSP_USING_EMMC)
+            case NU_SDH_CARD_DETECTED_EMMC:
+                nu_card_detector(&nu_sdh_arr[EMMC_IDX]);
+                break;
+#endif
 #if defined(BSP_USING_SDH0)
             case NU_SDH_CARD_DETECTED_SD0:
                 nu_card_detector(&nu_sdh_arr[SDH0_IDX]);

+ 12 - 8
bsp/nuvoton/libraries/n9h30/rtt_port/drv_sys.c

@@ -48,19 +48,23 @@ void rt_interrupt_dispatch(rt_uint32_t fiq_irq)
     /* Get irq number */
     _mIPER = (inpw(REG_AIC_IPER) >> 2) & 0x3f;
     _mISNR = inpw(REG_AIC_ISNR) & 0x3f;
-    if ((_mIPER != _mISNR) || _mISNR == 0)
-        return;
 
-    /* Get interrupt service routine */
-    isr_func = irq_desc[_mISNR].handler;
-    param = irq_desc[_mISNR].param;
+    if (_mISNR != 0)
+    {
+        if (_mIPER == _mISNR)
+        {
+            /* Get interrupt service routine */
+            isr_func = irq_desc[_mISNR].handler;
+            param = irq_desc[_mISNR].param;
 
 #ifdef RT_USING_INTERRUPT_INFO
-    irq_desc[_mISNR].counter ++;
+            irq_desc[_mISNR].counter ++;
 #endif
 
-    /* Turn to interrupt service routine */
-    isr_func(_mISNR, param);
+            /* Turn to interrupt service routine */
+            isr_func(_mISNR, param);
+        }
+    }
 
     /* Handled the ISR. */
     outpw(REG_AIC_EOSCR, 1);

+ 93 - 30
bsp/nuvoton/libraries/n9h30/rtt_port/drv_usbhost.c

@@ -30,6 +30,21 @@
 
 #define NU_MAX_USBH_HUB_PORT_DEV    USB_HUB_PORT_NUM
 
+#define NU_USBHOST_MUTEX_INIT()      { \
+                                s_sUSBHDev.lock = rt_mutex_create("usbhost_lock", RT_IPC_FLAG_PRIO); \
+                                RT_ASSERT(s_sUSBHDev.lock != RT_NULL); \
+                            }
+
+#define NU_USBHOST_LOCK()      { \
+                                rt_err_t result = rt_mutex_take(s_sUSBHDev.lock, RT_WAITING_FOREVER); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+
+#define NU_USBHOST_UNLOCK()    { \
+                                rt_err_t result = rt_mutex_release(s_sUSBHDev.lock); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+
 /* Private typedef --------------------------------------------------------------*/
 typedef struct nu_port_dev
 {
@@ -59,6 +74,7 @@ struct nu_usbh_dev
     E_SYS_IPRST rstidx;
     E_SYS_IPCLK clkidx;
     rt_thread_t polling_thread;
+    rt_mutex_t  lock;
     S_NU_RH_PORT_CTRL asPortCtrl[NU_MAX_USBH_PORT];
 };
 
@@ -165,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];
             }
         }
     }
@@ -186,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;
     }
 }
@@ -298,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
 
@@ -350,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
@@ -398,16 +425,42 @@ static int nu_bulk_xfer(
     UTR_T *psUTR,
     int timeouts)
 {
-    int ret;
-
-    ret = usbh_bulk_xfer(psUTR);
+    #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
-    rt_completion_wait(&(psPortDev->utr_completion), timeouts);
-    return 0;
+    while ( retry > 0 )
+    {
+        if ( rt_completion_wait(&(psPortDev->utr_completion), timeouts) != 0 )
+        {
+            rt_uint32_t level;
+
+            rt_kprintf("Request %d Timeout in %d ms!!\n", psUTR->data_len, timeouts);
+
+            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 (retry > 0) ? 0 : -1;
 }
 
 static int nu_int_xfer(
@@ -477,6 +530,8 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
 
     void *buffer_nonch = buffer;
 
+    NU_USBHOST_LOCK();
+
     psPortCtrl = GetRHPortControlFromPipe(pipe);
     if (psPortCtrl == RT_NULL)
     {
@@ -494,8 +549,10 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     if (buffer_nonch && nbytes)
     {
         buffer_nonch = psPortDev->asPipePktBuf[pipe->pipe_index];
-        rt_memcpy(buffer_nonch, buffer, nbytes);
-        mmu_clean_invalidated_dcache((uint32_t)buffer_nonch, nbytes);
+        if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_OUT)
+        {
+            rt_memcpy(buffer_nonch, buffer, nbytes);
+        }
     }
 #endif
 
@@ -503,6 +560,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     if (pipe->ep.bmAttributes == USB_EP_ATTR_CONTROL)
     {
         int ret;
+
         if (token == USBH_PID_SETUP)
         {
             struct urequest *psSetup = (struct urequest *)buffer_nonch;
@@ -517,7 +575,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             else
             {
                 /* Write data to USB device. */
-                //Trigger USBHostLib Ctril_Xfer
+                //Trigger USBHostLib Ctrl_Xfer
                 ret = nu_ctrl_xfer(psPortDev, psSetup, NULL, timeouts);
                 if (ret != psSetup->wLength)
                     goto exit_nu_pipe_xfer;
@@ -571,7 +629,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             if (nu_bulk_xfer(psPortDev, psUTR, timeouts) < 0)
             {
                 RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: bulk transfer failed\n"));
-                goto exit_nu_pipe_xfer;
+                goto failreport_nu_pipe_xfer;
             }
         }
         else if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
@@ -588,7 +646,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             {
                 i32XferLen = nbytes;
             }
-            return i32XferLen;
+            goto exit2_nu_pipe_xfer;
         }
         else if (pipe->ep.bmAttributes == USB_EP_ATTR_ISOC)
         {
@@ -599,6 +657,8 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
 
     } //else
 
+failreport_nu_pipe_xfer:
+
     if (psUTR->bIsTransferDone == 0)
     {
         //Timeout
@@ -628,29 +688,28 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     //Call callback
     if (pipe->callback != RT_NULL)
     {
-        struct uhost_msg msg;
-        msg.type = USB_MSG_CALLBACK;
-        msg.content.cb.function = pipe->callback;
-        msg.content.cb.context = pipe->user_data;
-        rt_usbh_event_signal(&msg);
+        pipe->callback(pipe);
     }
 
-    if (pipe->status != UPIPE_STATUS_OK)
-        goto exit_nu_pipe_xfer;
-
 exit_nu_pipe_xfer:
 
+    if (psUTR)
+        free_utr(psUTR);
+
+exit2_nu_pipe_xfer:
+
 #if defined(BSP_USING_MMU)
     if ((nbytes) &&
             (buffer_nonch != buffer))
     {
-        mmu_invalidate_dcache((uint32_t)buffer_nonch, nbytes);
-        rt_memcpy(buffer, buffer_nonch, nbytes);
+        if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
+        {
+            rt_memcpy(buffer, buffer_nonch, nbytes);
+        }
     }
 #endif
 
-    if (psUTR)
-        free_utr(psUTR);
+    NU_USBHOST_UNLOCK();
 
     return i32XferLen;
 }
@@ -660,7 +719,10 @@ static void nu_usbh_rh_thread_entry(void *parameter)
 {
     while (1)
     {
+        NU_USBHOST_LOCK();
         usbh_polling_root_hubs();
+        NU_USBHOST_UNLOCK();
+
         rt_thread_mdelay(NU_USBHOST_HUB_POLLING_INTERVAL);
     }
 }
@@ -771,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 */
@@ -871,6 +932,8 @@ int nu_usbh_register(void)
     psUHCD->ops               = &nu_uhcd_ops;
     psUHCD->num_ports         = NU_MAX_USBH_PORT;
 
+    NU_USBHOST_MUTEX_INIT();
+
     res = rt_device_register(&psUHCD->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
     RT_ASSERT(res == RT_EOK);
 

+ 47 - 12
bsp/nuvoton/libraries/nu_packages/AudioCodec/acodec_nau8822.c

@@ -40,7 +40,7 @@ static rt_err_t nau8822_mixer_query(rt_uint32_t ui32Units, rt_uint32_t *ui32Valu
 nu_acodec_ops nu_acodec_ops_nau8822 =
 {
     .name = "NAU8822",
-    .role = NU_ACODEC_ROLE_SLAVE,
+    .role = NU_ACODEC_ROLE_MASTER,
     .config = { // Default settings.
         .samplerate = 16000,
         .channels = 2,
@@ -117,6 +117,20 @@ static int I2C_WriteNAU8822(uint8_t u8addr, uint16_t u16data)
     return RT_EOK;
 }
 
+static void nau8822_phonejack_set(S_NU_NAU8822_CONFIG *psCodecConfig, int bEnable)
+{
+    rt_pin_mode(psCodecConfig->pin_phonejack_en, PIN_MODE_OUTPUT);
+
+    if (bEnable)
+    {
+        rt_pin_write(psCodecConfig->pin_phonejack_en, PIN_LOW);
+    }
+    else
+    {
+        rt_pin_write(psCodecConfig->pin_phonejack_en, PIN_HIGH);
+    }
+}
+
 
 static rt_err_t nau8822_probe(void)
 {
@@ -180,8 +194,6 @@ static rt_err_t nau8822_dsp_config(rt_uint32_t ui32SamplRate, rt_uint8_t u8ChNum
     }
     u16AudIf = (u16AudIf & 0x19F) | (u8WLEN << 5);
 
-    I2C_WriteNAU8822(4,  u16AudIf);
-
     if (ui32SamplRate % 11025)
     {
         I2C_WriteNAU8822(36, 0x008);    //12.288Mhz
@@ -189,6 +201,10 @@ static rt_err_t nau8822_dsp_config(rt_uint32_t ui32SamplRate, rt_uint8_t u8ChNum
         I2C_WriteNAU8822(38, 0x093);
         I2C_WriteNAU8822(39, 0x0E9);
 
+        /* FIXME */
+        if (ui32SamplRate > 48000)
+            ui32SamplRate = 8000;
+
         mClkDiv = (48000 * 256 * u8ChNum) / (ui32SamplRate * 256);
         bClkDiv = (ui32SamplRate * 256) / (ui32SamplRate * u8ChNum * u8SamplBit);
     }
@@ -199,6 +215,10 @@ static rt_err_t nau8822_dsp_config(rt_uint32_t ui32SamplRate, rt_uint8_t u8ChNum
         I2C_WriteNAU8822(38, 0x161);
         I2C_WriteNAU8822(39, 0x026);
 
+        /* FIXME */
+        if (ui32SamplRate > 44100)
+            ui32SamplRate = 11025;
+
         mClkDiv = (44100 * 256 * u8ChNum) / (ui32SamplRate * 256);
         bClkDiv = (ui32SamplRate * 256) / (ui32SamplRate * u8ChNum * u8SamplBit);
     }
@@ -258,11 +278,16 @@ static rt_err_t nau8822_dsp_config(rt_uint32_t ui32SamplRate, rt_uint8_t u8ChNum
         return -RT_ERROR;
     }
 
-    u16ClkCtrl = (1 << 8) | (1 << 0);  //Use internal PLL, FS/BCLK
+    if (nu_acodec_ops_nau8822.role == NU_ACODEC_ROLE_MASTER)
+    {
+        u16ClkCtrl = (1 << 8) | (1 << 0);  //Use internal PLL, FS/BCLK
+    }
 
     u16ClkCtrl = (u16ClkCtrl & 0x11F) | (mClkDiv << 5);
     u16ClkCtrl = (u16ClkCtrl & 0x1E3) | (bClkDiv << 2);
 
+    I2C_WriteNAU8822(4,  u16AudIf);
+
     I2C_WriteNAU8822(6,  u16ClkCtrl);
 
     return RT_EOK;
@@ -271,28 +296,36 @@ static rt_err_t nau8822_dsp_config(rt_uint32_t ui32SamplRate, rt_uint8_t u8ChNum
 static rt_err_t nau8822_init(void)
 {
     //input source is MIC
-    I2C_WriteNAU8822(1,  0x03F);
+    if (nu_acodec_ops_nau8822.role == NU_ACODEC_ROLE_MASTER)
+    {
+        I2C_WriteNAU8822(1,  0x03F);   /* PLLEN, MICBIASEN, ABIASEN, IOBUFEN, REFIMP(3kohm)  */
+    }
+    else
+    {
+        I2C_WriteNAU8822(1,  0x01F);   /* MICBIASEN, ABIASEN, IOBUFEN, REFIMP(3kohm)  */
+    }
+
     I2C_WriteNAU8822(2,  0x1BF);   /* Enable L/R Headphone, ADC Mix/Boost, ADC */
     I2C_WriteNAU8822(3,  0x07F);   /* Enable L/R main mixer, DAC */
     I2C_WriteNAU8822(4,  0x010);   /* 16-bit word length, I2S format, Stereo */
     I2C_WriteNAU8822(5,  0x000);   /* Companding control and loop back mode (all disable) */
     nau8822_delay_ms(30);
 
-    if (nu_acodec_ops_nau8822.role == NU_ACODEC_ROLE_SLAVE)
-    {
-        I2C_WriteNAU8822(6,  0x1AD);   /* Divide by 6, 16K */
-        I2C_WriteNAU8822(7,  0x006);   /* 16K for internal filter coefficients */
-    }
-
+    I2C_WriteNAU8822(6,  0x1AD);   /* Divide by 6, 16K */
+    I2C_WriteNAU8822(7,  0x006);   /* 16K for internal filter coefficients */
     I2C_WriteNAU8822(10, 0x008);   /* DAC soft mute is disabled, DAC oversampling rate is 128x */
     I2C_WriteNAU8822(14, 0x108);   /* ADC HP filter is disabled, ADC oversampling rate is 128x */
     I2C_WriteNAU8822(15, 0x1EF);   /* ADC left digital volume control */
     I2C_WriteNAU8822(16, 0x1EF);   /* ADC right digital volume control */
     I2C_WriteNAU8822(44, 0x033);   /* LMICN/LMICP is connected to PGA */
-    I2C_WriteNAU8822(49, 0x042);
+    I2C_WriteNAU8822(47, 0x100);   /* Gain value */
+    I2C_WriteNAU8822(48, 0x100);   /* Gain value */
     I2C_WriteNAU8822(50, 0x001);   /* Left DAC connected to LMIX */
     I2C_WriteNAU8822(51, 0x001);   /* Right DAC connected to RMIX */
 
+    I2C_WriteNAU8822(0x34, 0x13F);
+    I2C_WriteNAU8822(0x35, 0x13F);
+
     nu_acodec_ops_nau8822.config.samplerate = 16000;
     nu_acodec_ops_nau8822.config.channels = 2;
     nu_acodec_ops_nau8822.config.samplebits = 16;
@@ -326,10 +359,12 @@ static rt_err_t nau8822_mixer_control(rt_uint32_t ui32Units, rt_uint32_t ui32Val
         if (ui32Value)
         {
             I2C_WriteNAU8822(10,  u16Data | (1 << 6));
+            nau8822_phonejack_set(g_psCodecConfig, 0);
         }
         else
         {
             I2C_WriteNAU8822(10,  u16Data & ~(1 << 6));
+            nau8822_phonejack_set(g_psCodecConfig, 1);
         }
     }
     break;

+ 1 - 0
bsp/nuvoton/libraries/nu_packages/BMX055/sensor_bmx055.c

@@ -14,6 +14,7 @@
 
 #if defined(NU_PKG_USING_BMX055)
 
+#include <sys/time.h>
 #include <string.h>
 #include "sensor_bmx055.h"
 

+ 5 - 0
bsp/nuvoton/libraries/nu_packages/Kconfig

@@ -29,6 +29,11 @@ menu "Nuvoton Packages Config"
         select BSP_USING_I2C
         default n
 
+    config NU_PKG_USING_DA9062
+        bool "DA9062 PMIC."
+        select BSP_USING_I2C
+        default n
+
     config NU_PKG_USING_ILI9341
         bool "ILI9341 LCD Panel"
         select BSP_USING_GPIO

+ 1 - 0
bsp/nuvoton/libraries/nu_packages/MAX31875/sensor_max31875.c

@@ -14,6 +14,7 @@
 
 #if defined(NU_PKG_USING_MAX31875)
 
+#include <sys/time.h>
 #include "sensor.h"
 #include "max31875_c.h"
 

+ 2 - 1
bsp/nuvoton/libraries/nu_packages/SPINAND/drv_spinand.c

@@ -498,7 +498,8 @@ rt_err_t rt_hw_mtd_spinand_init(void)
     RT_ASSERT(result == RT_EOK);
 
     result = spinand_flash_init(SPINAND_FLASH_QSPI);
-    RT_ASSERT(result == RT_EOK);
+    if (result != RT_EOK)
+        return -RT_ERROR;
 
     for (i = 0; i < MTD_SPINAND_PARTITION_NUM; i++)
     {

+ 104 - 21
bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.c

@@ -26,7 +26,48 @@
 const struct nu_spinand_info g_spinandflash_list[] =
 {
     /* Winbond */
-    { 0xEFAA21, 2048, 64, 0x6b, 0xff, 0xff, 0xff, 0x1, 1024, 64, 0, "Winbond 128MB: 2048+64@64@1024" }, /* Only tested */
+    /* Only tested */
+    {
+        0xEFAA21, 2048, 64, 0x6b, 0xff, 0xff, 0xff, 0x1, 1024, 64, 0, "Winbond 128MB: 2048+64@64@1024",
+#if defined(RT_USING_DFS_UFFS)
+        {
+            /* For storing Seal-byte at 0x37. Need 15-Bytes */
+            0x04, 0x04, 0x14, 0x04, 0x24, 0x04, 0x34, 0x03, 0xFF, 0x00
+        },
+        {
+            /* For storing Seal-byte at 0x37 and not report latest ECC part in Spare-3 */
+            0x08, 0x08, 0x18, 0x08, 0x28, 0x08, /*0x38, 0x08,*/ 0xFF, 0x00
+        }
+#else
+        {
+            0x04, 0x04, 0x14, 0x04, 0x24, 0x04, 0x34, 0x04, 0xFF, 0x00
+        },
+        {
+            0x08, 0x08, 0x18, 0x08, 0x28, 0x08, 0x38, 0x08, 0xFF, 0x00
+        }
+#endif
+    },
+
+    {
+        0xEFBF22, 2048, 64, 0x6b, 0xff, 0xff, 0xff, 0x1, 2048, 64, 0, "Winbond 256MB: 2048+64@64@2048",
+#if defined(RT_USING_DFS_UFFS)
+        {
+            /* For storing Seal-byte at 0x39. Need 15-Bytes */
+            0x08, 0x04, 0x18, 0x04, 0x28, 0x04, 0x38, 0x03, 0xFF, 0x00
+        },
+        {
+            /* For storing Seal-byte at 0x39 and not report latest ECC part in Spare-3 */
+            0x0C, 0x04, 0x1C, 0x04, 0x2C, 0x04, /*0x3C, 0x04,*/ 0xFF, 0x00
+        }
+#else
+        {
+            0x08, 0x04, 0x18, 0x04, 0x28, 0x04, 0x38, 0x04, 0xFF, 0x00
+        },
+        {
+            0x0C, 0x04, 0x1C, 0x04, 0x2C, 0x04, 0x3C, 0x04, 0xFF, 0x00
+        }
+#endif
+    },
 
 #if 0
     { 0xEFAA22, 2048, 64, 0x6b, 0xff, 0xff, 0xff, 0x1, 2048, 64, 0, "Winbond 256MB: 2048+64@64@1024" },
@@ -61,6 +102,7 @@ const struct nu_spinand_info g_spinandflash_list[] =
 
 
 /*
+========================================================
 For 0xEFAA21 description:
 
 Data Area(2048-Byte)
@@ -112,27 +154,66 @@ ECC Spare: ECC for spare 4-D.
 | 0 1 2 3 | 4 5 6 7 | 8 9 A B C D | E F       |
 -----------------------------------------------
 |  NO ECC |   ECC PROTECTED       | ECC 34-3D |
-*/
 
-rt_uint8_t spinand_flash_data_layout[SPINAND_SPARE_LAYOUT_SIZE] =
-{
-#if defined(RT_USING_DFS_UFFS)
-    /* For storing Seal-byte at 0x37. */
-    0x04, 0x04, 0x14, 0x04, 0x24, 0x04, 0x34, 0x03, 0xFF, 0x00
-#else
-    0x04, 0x04, 0x14, 0x04, 0x24, 0x04, 0x34, 0x04, 0xFF, 0x00
-#endif
-};
+========================================================
 
-rt_uint8_t spinand_flash_ecc_layout[SPINAND_SPARE_LAYOUT_SIZE] =
-{
-#if defined(RT_USING_DFS_UFFS)
-    /* For storing Seal-byte at 0x37 and not report latest ECC part in Spare-3 */
-    0x08, 0x08, 0x18, 0x08, 0x28, 0x08, /*0x38, 0x08,*/ 0xFF, 0x00
-#else
-    0x08, 0x08, 0x18, 0x08, 0x28, 0x08, 0x38, 0x08, 0xFF, 0x00
-#endif
-};
+========================================================
+For 0xEFBF22 description:
+
+Data Area(2048-Byte)
+-----------------------------
+|Sect-0|Sect-1|Sect-2|Sect-3|
+|(512B)|(512B)|(512B)|(512B)|
+-----------------------------
+
+         Spare Area(64-Byte)
+         ---------------------------------
+         |Spare-0|Spare-1|Spare-2|Spare-3|
+         | (16B) | (16B) | (16B) | (16B) |
+         ---------------------------------
+
+ ----------------- Spare-0 -------------------
+/                                             \
+-----------------------------------------
+| BBM |     UD2     |   UD1   | ECC UD1 |
+| 0 1 | 2 3 4 5 6 7 | 8 9 A B | C D E F |
+-----------------------------------------
+|       NO ECC      |   ECC PROTECTED   |
+
+BBM: Bad block marker.
+UD1: User Data 1.
+UD2: User Data 2.
+ECC UD1: ECC for UD1.
+
+ ---------------- Spare-1 -------------------
+/                                            \
+---------------------------------------
+|       UD2       |   UD1   | ECC UD1 |
+| 0 1 2 3 4 5 6 7 | 8 9 A B | C D E F |
+---------------------------------------
+|      NO ECC     |   ECC PROTECTED   |
+
+ ---------------- Spare-2 -------------------
+/                                            \
+---------------------------------------
+|       UD2       |   UD1   | ECC UD1 |
+| 0 1 2 3 4 5 6 7 | 8 9 A B | C D E F |
+---------------------------------------
+|      NO ECC     |   ECC PROTECTED   |
+
+ ---------------- Spare-3 -------------------
+/                                            \
+---------------------------------------
+|       UD2       |   UD1   | ECC UD1 |
+| 0 1 2 3 4 5 6 7 | 8 9 A B | C D E F |
+---------------------------------------
+|      NO ECC     |   ECC PROTECTED   |
+
+========================================================
+*/
+
+rt_uint8_t spinand_flash_data_layout[SPINAND_SPARE_LAYOUT_SIZE];
+rt_uint8_t spinand_flash_ecc_layout[SPINAND_SPARE_LAYOUT_SIZE];
 
 static rt_err_t spinand_info_read(struct rt_qspi_device *qspi);
 
@@ -186,7 +267,6 @@ static rt_err_t spinand_program_dataload(
     uint8_t *pu8SpareBuff,
     uint32_t u32SpareCount)
 {
-    uint32_t volatile i = 0;
     uint8_t u8WECmd = 0x06;
     rt_err_t result = RT_EOK;
 
@@ -667,6 +747,9 @@ static rt_err_t spinand_info_read(struct rt_qspi_device *qspi)
     {
         if (u32JedecId == g_spinandflash_list[i].u32JEDECID)   /* Match JEDECID? */
         {
+            rt_memcpy((void *)&spinand_flash_data_layout[0], (void *)&g_spinandflash_list[i].au8DataLayout[0], SPINAND_SPARE_LAYOUT_SIZE);
+            rt_memcpy((void *)&spinand_flash_ecc_layout[0], (void *)&g_spinandflash_list[i].au8EccLayout[0], SPINAND_SPARE_LAYOUT_SIZE);
+
             rt_memcpy(SPINAND_FLASH_INFO, &g_spinandflash_list[i], sizeof(struct nu_spinand_info));
             LOG_I("Found: [%08X] %s.", u32JedecId, SPINAND_FLASH_DESCRIPTION);
 

+ 30 - 27
bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.h

@@ -19,24 +19,6 @@
 #include "drv_spi.h"
 #include <board.h>
 
-/* SPI NAND flash information */
-struct nu_spinand_info
-{
-    uint32_t   u32JEDECID;
-    uint16_t   u16PageSize;
-    uint16_t   u16OOBSize;
-    uint8_t    u8QuadReadCmdId;
-    uint8_t    u8ReadStatusCmdId;
-    uint8_t    u8WriteStatusCmdid;
-    uint8_t    u8StatusValue;
-    uint8_t    u8DummyByte;
-    uint32_t   u32BlockPerFlash;
-    uint32_t   u32PagePerBlock;
-    uint8_t    u8IsDieSelect;
-    const char *szDescription;
-};
-typedef struct nu_spinand_info *nu_spinand_info_t;
-
 struct spinand_ops
 {
     rt_err_t (*block_erase)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
@@ -53,15 +35,6 @@ struct spinand_ops
 };
 typedef struct spinand_ops *nu_spinand_ops_t;
 
-struct nu_spinand
-{
-    struct nu_spinand_info info;
-    struct rt_qspi_device *qspi_device;
-    nu_spinand_ops_t       ops;
-    struct rt_mutex        lock;
-};
-typedef struct nu_spinand *nu_spinand_t;
-
 #define SPINAND_FLASH_JEDECID              g_spinandflash_dev.info.u32JEDECID
 #define SPINAND_FLASH_PAGE_SIZE            g_spinandflash_dev.info.u16PageSize
 #define SPINAND_FLASH_OOB_SIZE             g_spinandflash_dev.info.u16OOBSize
@@ -82,6 +55,36 @@ typedef struct nu_spinand *nu_spinand_t;
 
 #define SPINAND_SPARE_LAYOUT_SIZE          16
 
+/* SPI NAND flash information */
+struct nu_spinand_info
+{
+    uint32_t   u32JEDECID;
+    uint16_t   u16PageSize;
+    uint16_t   u16OOBSize;
+    uint8_t    u8QuadReadCmdId;
+    uint8_t    u8ReadStatusCmdId;
+    uint8_t    u8WriteStatusCmdid;
+    uint8_t    u8StatusValue;
+    uint8_t    u8DummyByte;
+    uint32_t   u32BlockPerFlash;
+    uint32_t   u32PagePerBlock;
+    uint8_t    u8IsDieSelect;
+    const char *szDescription;
+
+    uint8_t    au8DataLayout[SPINAND_SPARE_LAYOUT_SIZE];
+    uint8_t    au8EccLayout[SPINAND_SPARE_LAYOUT_SIZE];
+};
+typedef struct nu_spinand_info *nu_spinand_info_t;
+
+struct nu_spinand
+{
+    struct nu_spinand_info info;
+    struct rt_qspi_device *qspi_device;
+    nu_spinand_ops_t       ops;
+    struct rt_mutex        lock;
+};
+typedef struct nu_spinand *nu_spinand_t;
+
 rt_err_t rt_hw_mtd_spinand_register(const char *device_name);
 rt_size_t nu_qspi_transfer_message(struct rt_qspi_device  *device, struct rt_qspi_message *message);
 rt_err_t nu_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length);

+ 6 - 3
bsp/nuvoton/libraries/nuc980/Driver/Include/nu_emac.h

@@ -30,8 +30,8 @@ extern "C"
 */
 
 #define EMAC_PHY_ADDR      1UL    /*!<  PHY address, this address is board dependent \hideinitializer */
-#define EMAC_RX_DESC_SIZE  64UL    /*!<  Number of Rx Descriptors, should be 2 at least \hideinitializer */
-#define EMAC_TX_DESC_SIZE  32UL    /*!<  Number of Tx Descriptors, should be 2 at least \hideinitializer */
+#define EMAC_RX_DESC_SIZE  128UL  /*!<  Number of Rx Descriptors, should be 2 at least \hideinitializer */
+#define EMAC_TX_DESC_SIZE  64UL   /*!<  Number of Tx Descriptors, should be 2 at least \hideinitializer */
 #define EMAC_CAMENTRY_NB   16UL   /*!<  Number of CAM \hideinitializer */
 #define EMAC_MAX_PKT_SIZE  1536UL /*!<  Number of HDR + EXTRA + VLAN_TAG + PAYLOAD + CRC \hideinitializer */
 
@@ -53,6 +53,8 @@ typedef struct
     uint32_t u32Next;      /*!<  Pointer to next descriptor */
     uint32_t u32Backup1;   /*!<  For backup descriptor fields over written by time stamp */
     uint32_t u32Backup2;   /*!<  For backup descriptor fields over written by time stamp */
+    uint32_t u32Reserved1; /*!<  For Reserved */
+    uint32_t u32Reserved2; /*!<  For Reserved */
 } EMAC_DESCRIPTOR_T;
 
 /** Tx/Rx buffer structure */
@@ -379,7 +381,8 @@ int32_t EMAC_FillCamEntry(EMAC_T *EMAC, uint8_t pu8MacAddr[]);
 uint8_t *EMAC_ClaimFreeTXBuf(EMAC_MEMMGR_T *psMemMgr);
 uint32_t EMAC_GetAvailRXBufSize(EMAC_MEMMGR_T *psMemMgr, uint8_t **ppuDataBuf);
 uint32_t EMAC_SendPktWoCopy(EMAC_MEMMGR_T *psMemMgr, uint32_t u32Size);
-void EMAC_RecvPktDoneWoRxTrigger(EMAC_MEMMGR_T *psMemMgr);
+EMAC_DESCRIPTOR_T * EMAC_RecvPktDoneWoRxTrigger(EMAC_MEMMGR_T *psMemMgr);
+void EMAC_RxTrigger(EMAC_MEMMGR_T *psMemMgr, EMAC_DESCRIPTOR_T * rx_desc);
 
 /*@}*/ /* end of group EMAC_EXPORTED_FUNCTIONS */
 

+ 15 - 3
bsp/nuvoton/libraries/nuc980/Driver/Source/nu_emac.c

@@ -298,7 +298,7 @@ static void EMAC_RxDescInit(EMAC_MEMMGR_T *psMemMgr)
     for (i = 0UL; i < psMemMgr->u32RxDescSize; i++)
     {
         psMemMgr->psRXDescs[i].u32Status1 = EMAC_DESC_OWN_EMAC;
-        psMemMgr->psRXDescs[i].u32Data = (uint32_t)&psMemMgr->psRXFrames[i] | BIT31;
+        psMemMgr->psRXDescs[i].u32Data = (uint32_t)&psMemMgr->psRXFrames[i];
         psMemMgr->psRXDescs[i].u32Status2 = 0UL;
         psMemMgr->psRXDescs[i].u32Next = (uint32_t)(&psMemMgr->psRXDescs[(i + 1UL) % EMAC_RX_DESC_SIZE]) | BIT31;
         psMemMgr->psRXDescs[i].u32Backup1 = psMemMgr->psRXDescs[i].u32Data;
@@ -1129,25 +1129,37 @@ uint32_t EMAC_GetAvailRXBufSize(EMAC_MEMMGR_T *psMemMgr, uint8_t **ppuDataBuf)
   * @note Application can only call this function once every time \ref EMAC_RecvPkt or \ref EMAC_RecvPktTS returns 1
   * @note This function is without doing EMAC_TRIGGER_RX.
   */
-void EMAC_RecvPktDoneWoRxTrigger(EMAC_MEMMGR_T *psMemMgr)
+EMAC_DESCRIPTOR_T * EMAC_RecvPktDoneWoRxTrigger(EMAC_MEMMGR_T *psMemMgr)
 {
     /* Get Rx Frame Descriptor */
     EMAC_DESCRIPTOR_T *desc = (EMAC_DESCRIPTOR_T *)psMemMgr->psCurrentRxDesc;
+    EMAC_DESCRIPTOR_T *ret = desc;
 
     /* Restore descriptor link list and data pointer they will be overwrite if time stamp enabled */
     desc->u32Data = desc->u32Backup1;
     desc->u32Next = desc->u32Backup2;
 
     /* Change ownership to DMA for next use */
-    desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
+    // desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
 
     /* Get Next Frame Descriptor pointer to process */
     desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
 
     /* Save last processed Rx descriptor */
     psMemMgr->psCurrentRxDesc = desc;
+
+    return ret;
 }
 
+void EMAC_RxTrigger(EMAC_MEMMGR_T *psMemMgr, EMAC_DESCRIPTOR_T * rx_desc)
+{
+    EMAC_T *EMAC = psMemMgr->psEmac;
+
+    rx_desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
+
+    /* Trigger EMAC to send the packet */
+    EMAC_TRIGGER_RX(EMAC);
+}
 
 /*@}*/ /* end of group EMAC_EXPORTED_FUNCTIONS */
 

+ 39 - 86
bsp/nuvoton/libraries/nuc980/Driver/Source/nu_pdma.c

@@ -8,9 +8,6 @@
 #include "nuc980.h"
 #include "nu_pdma.h"
 
-
-static uint8_t u32ChSelect[PDMA_CH_MAX];
-
 /** @addtogroup Standard_Driver Standard Driver
   @{
 */
@@ -44,7 +41,6 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
         if ((1 << i) & u32Mask)
         {
             pdma->DSCT[i].CTL = 0UL;
-            u32ChSelect[i] = PDMA_MEM;
         }
     }
 
@@ -188,54 +184,27 @@ void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uin
  */
 void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
 {
-    u32ChSelect[u32Ch] = u32Peripheral;
-    switch (u32Ch)
+    if (u32Ch < PDMA_CH_MAX)
     {
-    case 0ul:
-        pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral;
-        break;
-    case 1ul:
-        pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
-        break;
-    case 2ul:
-        pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
-        break;
-    case 3ul:
-        pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
-        break;
-    case 4ul:
-        pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
-        break;
-    case 5ul:
-        pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
-        break;
-    case 6ul:
-        pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
-        break;
-    case 7ul:
-        pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
-        break;
-    case 8ul:
-        pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC8_Msk) | u32Peripheral;
-        break;
-    case 9ul:
-        pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC9_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC9_Pos);
-        break;
-    default:
-        break;
-    }
+        __IO uint32_t *pau32REQSEL  = (__IO uint32_t *)&pdma->REQSEL0_3;
+        uint32_t u32REQSEL_Pos, u32REQSEL_Msk;
 
-    if (u32ScatterEn)
-    {
-        pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
-        pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
-    }
-    else
-    {
-        pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
+        u32REQSEL_Pos = (u32Ch % 4) * 8 ;
+        u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
+        pau32REQSEL[u32Ch / 4] = (pau32REQSEL[u32Ch / 4] & ~u32REQSEL_Msk) | (u32Peripheral << u32REQSEL_Pos);
+
+        if (u32ScatterEn)
+        {
+            pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
+            pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
+        }
+        else
+        {
+            pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
+        }
     }
+    else {}
 }
-
 /**
  * @brief       Set PDMA Burst Type and Size
  *
@@ -310,45 +279,21 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
  */
 void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
 {
-    switch (u32Ch)
+    if (u32Ch < PDMA_CH_MAX)
     {
-    case 0ul:
-        pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt;
-        break;
-    case 1ul:
-        pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos);
-        break;
-    case 2ul:
-        pdma->TOC2_3 = (pdma->TOC2_3 & ~PDMA_TOC2_3_TOC2_Msk) | u32TimeOutCnt;
-        break;
-    case 3ul:
-        pdma->TOC2_3 = (pdma->TOC2_3 & ~PDMA_TOC2_3_TOC3_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos);
-        break;
-    case 4ul:
-        pdma->TOC4_5 = (pdma->TOC4_5 & ~PDMA_TOC4_5_TOC4_Msk) | u32TimeOutCnt;
-        break;
-    case 5ul:
-        pdma->TOC4_5 = (pdma->TOC4_5 & ~PDMA_TOC4_5_TOC5_Msk) | (u32TimeOutCnt << PDMA_TOC4_5_TOC5_Pos);
-        break;
-    case 6ul:
-        pdma->TOC6_7 = (pdma->TOC6_7 & ~PDMA_TOC6_7_TOC6_Msk) | u32TimeOutCnt;
-        break;
-    case 7ul:
-        pdma->TOC6_7 = (pdma->TOC6_7 & ~PDMA_TOC6_7_TOC7_Msk) | (u32TimeOutCnt << PDMA_TOC6_7_TOC7_Pos);
-        break;
-    case 8ul:
-        pdma->TOC8_9 = (pdma->TOC8_9 & ~PDMA_TOC8_9_TOC8_Msk) | u32TimeOutCnt;
-        break;
-    case 9ul:
-        pdma->TOC8_9 = (pdma->TOC8_9 & ~PDMA_TOC8_9_TOC9_Msk) | (u32TimeOutCnt << PDMA_TOC8_9_TOC9_Pos);
-        break;
-    default:
-        break;
+        __IO uint32_t *pau32TOC  = (__IO uint32_t *)&pdma->TOC0_1;
+        uint32_t u32TOC_Pos, u32TOC_Msk;
+
+        u32TOC_Pos = (u32Ch % 2) * 16 ;
+        u32TOC_Msk = PDMA_TOC0_1_TOC0_Msk << u32TOC_Pos;
+        pau32TOC[u32Ch / 2] = (pau32TOC[u32Ch / 2] & ~u32TOC_Msk) | (u32TimeOutCnt << u32TOC_Pos);
+
+        if (u32OnOff)
+            pdma->TOUTEN |= (1 << u32Ch);
+        else
+            pdma->TOUTEN &= ~(1 << u32Ch);
     }
-    if (u32OnOff)
-        pdma->TOUTEN |= (1 << u32Ch);
-    else
-        pdma->TOUTEN &= ~(1 << u32Ch);
+    else {}
 }
 
 /**
@@ -363,7 +308,15 @@ void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u
  */
 void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
 {
-    if (u32ChSelect[u32Ch] == PDMA_MEM)
+    __IO uint32_t *pau32REQSEL  = (__IO uint32_t *)&pdma->REQSEL0_3;
+    uint32_t u32REQSEL_Pos, u32REQSEL_Msk, u32ChReq;
+
+    u32REQSEL_Pos = (u32Ch % 4) * 8 ;
+    u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
+
+    u32ChReq = (pau32REQSEL[u32Ch / 4] & u32REQSEL_Msk) >> u32REQSEL_Pos;
+
+    if (u32ChReq == PDMA_MEM)
     {
         pdma->SWREQ = (1ul << u32Ch);
     }

+ 2 - 2
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/config.h

@@ -33,7 +33,7 @@
 #define DISABLE_EHCI_IRQ()     rt_hw_interrupt_mask(IRQ_EHCI)
 #define IS_EHCI_IRQ_ENABLED()  ((inpw(REG_AIC_INTMSK0)>>IRQ_EHCI) & 0x1)
 
-//#define ENABLE_OHCI                         /* Enable OHCI host controller                */
+#define ENABLE_OHCI                         /* Enable OHCI host controller                */
 #define ENABLE_EHCI                         /* Enable EHCI host controller                */
 
 #define EHCI_PORT_CNT          2            /* Number of EHCI roothub ports               */
@@ -50,7 +50,7 @@
                                                unconditionally reclaim iTD/isTD scheduled
                                                in just elapsed EHCI_ISO_RCLM_RANGE ms.    */
 
-#define MAX_DESC_BUFF_SIZE     1024         /* To hold the configuration descriptor, USB
+#define MAX_DESC_BUFF_SIZE     4096         /* To hold the configuration descriptor, USB
                                                core will allocate a buffer with this size
                                                for each connected device. USB core does
                                                not release it until device disconnected.  */

+ 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);

+ 52 - 102
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/support.c

@@ -50,7 +50,7 @@ static uint32_t  _MemoryPoolBase, _MemoryPoolEnd;
 
 void  USB_InitializeMemoryPool()
 {
-    _MemoryPoolBase = (UINT32)&_USBMemoryPool[0] | NON_CACHE_MASK;
+    _MemoryPoolBase = (uint32_t)&_USBMemoryPool[0] | NON_CACHE_MASK;
     _MemoryPoolEnd = _MemoryPoolBase + USB_MEMORY_POOL_SIZE;
     _FreeMemorySize = _MemoryPoolEnd - _MemoryPoolBase;
     _AllocatedMemorySize = 0;
@@ -71,41 +71,26 @@ int  USB_allocated_memory()
 }
 
 
-void  *USB_malloc(INT wanted_size, INT boundary)
+void  *USB_malloc(int wanted_size, int boundary)
 {
     USB_MHDR_T  *pPrimitivePos = _pCurrent;
     USB_MHDR_T  *pFound;
-    INT   found_size = -1;
-    INT   i, block_count;
-    INT   wrap = 0;
-    int   disable_ohci_irq, disable_ehci_irq;
+    int   found_size = -1;
+    int   i, block_count;
+    int   wrap = 0;
+    void   *pvBuf = NULL;
+    rt_base_t level;
 
-    if (IS_OHCI_IRQ_ENABLED())
-        disable_ohci_irq = 1;
-    else
-        disable_ohci_irq = 0;
-
-    if (IS_EHCI_IRQ_ENABLED())
-        disable_ehci_irq = 1;
-    else
-        disable_ehci_irq = 0;
-
-    if (disable_ohci_irq)
-        DISABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        DISABLE_EHCI_IRQ();
+    level = rt_hw_interrupt_disable();
 
     if (wanted_size >= _FreeMemorySize)
     {
         rt_kprintf("USB_malloc - want=%d, free=%d\n", wanted_size, _FreeMemorySize);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return NULL;
+        goto exit_USB_malloc;
     }
 
-    if ((UINT32)_pCurrent >= _MemoryPoolEnd)
+
+    if ((uint32_t)_pCurrent >= _MemoryPoolEnd)
         _pCurrent = (USB_MHDR_T *)_MemoryPoolBase;   /* wrapped */
 
     do
@@ -114,26 +99,22 @@ void  *USB_malloc(INT wanted_size, INT boundary)
         {
             if (_pCurrent->magic != USB_MEM_ALLOC_MAGIC)
             {
-                rt_kprintf("\nUSB_malloc - incorrect magic number! C:%x F:%x, wanted:%d, Base:0x%x, End:0x%x\n", (UINT32)_pCurrent, _FreeMemorySize, wanted_size, (UINT32)_MemoryPoolBase, (UINT32)_MemoryPoolEnd);
-                if (disable_ohci_irq)
-                    ENABLE_OHCI_IRQ();
-                if (disable_ehci_irq)
-                    ENABLE_EHCI_IRQ();
-                return NULL;
+                rt_kprintf("\nUSB_malloc - incorrect magic number! C:%x F:%x, wanted:%d, Base:0x%x, End:0x%x\n", (uint32_t)_pCurrent, _FreeMemorySize, wanted_size, (uint32_t)_MemoryPoolBase, (uint32_t)_MemoryPoolEnd);
+                goto exit_USB_malloc;
             }
 
             if (_pCurrent->flag == 0x3)
-                _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + _pCurrent->bcnt * USB_MEM_BLOCK_SIZE);
+                _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + _pCurrent->bcnt * USB_MEM_BLOCK_SIZE);
             else
             {
                 rt_kprintf("USB_malloc warning - not the first block!\n");
-                _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
+                _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + USB_MEM_BLOCK_SIZE);
             }
 
-            if ((UINT32)_pCurrent > _MemoryPoolEnd)
+            if ((uint32_t)_pCurrent > _MemoryPoolEnd)
                 rt_kprintf("USB_malloc - behind limit!!\n");
 
-            if ((UINT32)_pCurrent == _MemoryPoolEnd)
+            if ((uint32_t)_pCurrent == _MemoryPoolEnd)
             {
                 //rt_kprintf("USB_alloc - warp!!\n");
                 wrap = 1;
@@ -161,8 +142,8 @@ void  *USB_malloc(INT wanted_size, INT boundary)
                  * used as a header only.
                  */
                 if ((boundary > BOUNDARY_WORD) &&
-                        ((((UINT32)_pCurrent) + USB_MEM_BLOCK_SIZE >= _MemoryPoolEnd) ||
-                         ((((UINT32)_pCurrent) + USB_MEM_BLOCK_SIZE) % boundary != 0)))
+                        ((((uint32_t)_pCurrent) + USB_MEM_BLOCK_SIZE >= _MemoryPoolEnd) ||
+                         ((((uint32_t)_pCurrent) + USB_MEM_BLOCK_SIZE) % boundary != 0)))
                     found_size = -1;   /* violate boundary, reset the accumlator */
             }
             else                      /* not the leading block */
@@ -181,34 +162,26 @@ void  *USB_malloc(INT wanted_size, INT boundary)
                 for (i = 0; i < block_count; i++)
                 {
                     _pCurrent->flag = 1;     /* allocate block */
-                    _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
+                    _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + USB_MEM_BLOCK_SIZE);
                 }
                 pFound->flag = 0x3;
 
                 if (boundary > BOUNDARY_WORD)
                 {
-                    if (disable_ohci_irq)
-                        ENABLE_OHCI_IRQ();
-                    if (disable_ehci_irq)
-                        ENABLE_EHCI_IRQ();
-                    //rt_kprintf("- 0x%x, %d\n", (int)pFound, wanted_size);
-                    return (void *)((UINT32)pFound + USB_MEM_BLOCK_SIZE);
+                    pvBuf = (void *)((uint32_t)pFound + USB_MEM_BLOCK_SIZE);
+                    goto exit_USB_malloc;
                 }
                 else
                 {
-                    //USB_debug("USB_malloc(%d,%d):%x\tsize:%d, C:0x%x, %d\n", wanted_size, boundary, (UINT32)pFound + sizeof(USB_MHDR_T), block_count * USB_MEM_BLOCK_SIZE, _pCurrent, block_count);
-                    if (disable_ohci_irq)
-                        ENABLE_OHCI_IRQ();
-                    if (disable_ehci_irq)
-                        ENABLE_EHCI_IRQ();
-                    //rt_kprintf("- 0x%x, %d\n", (int)pFound, wanted_size);
-                    return (void *)((UINT32)pFound + sizeof(USB_MHDR_T));
+                    //USB_debug("USB_malloc(%d,%d):%x\tsize:%d, C:0x%x, %d\n", wanted_size, boundary, (uint32_t)pFound + sizeof(USB_MHDR_T), block_count * USB_MEM_BLOCK_SIZE, _pCurrent, block_count);
+                    pvBuf = (void *)((uint32_t)pFound + sizeof(USB_MHDR_T));
+                    goto exit_USB_malloc;
                 }
             }
 
             /* advance to the next block */
-            _pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
-            if ((UINT32)_pCurrent >= _MemoryPoolEnd)
+            _pCurrent = (USB_MHDR_T *)((uint32_t)_pCurrent + USB_MEM_BLOCK_SIZE);
+            if ((uint32_t)_pCurrent >= _MemoryPoolEnd)
             {
                 wrap = 1;
                 _pCurrent = (USB_MHDR_T *)_MemoryPoolBase;   /* wrapped */
@@ -219,49 +192,36 @@ void  *USB_malloc(INT wanted_size, INT boundary)
     while ((wrap == 0) || (_pCurrent < pPrimitivePos));
 
     rt_kprintf("USB_malloc - No free memory!\n");
-    if (disable_ohci_irq)
-        ENABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        ENABLE_EHCI_IRQ();
-    return NULL;
+
+exit_USB_malloc:
+
+    rt_hw_interrupt_enable(level);
+
+    return pvBuf;
 }
 
 
 void  USB_free(void *alloc_addr)
 {
     USB_MHDR_T  *pMblk;
-    UINT32  addr = (UINT32)alloc_addr;
-    INT     i, count;
-    int     disable_ohci_irq, disable_ehci_irq;
-
-    if (IS_OHCI_IRQ_ENABLED())
-        disable_ohci_irq = 1;
-    else
-        disable_ohci_irq = 0;
-
-    if (IS_EHCI_IRQ_ENABLED())
-        disable_ehci_irq = 1;
-    else
-        disable_ehci_irq = 0;
+    uint32_t  addr = (uint32_t)alloc_addr;
+    int     i, count;
+    rt_base_t level;
 
     //rt_kprintf("USB_free: 0x%x\n", (int)alloc_addr);
 
+    level = rt_hw_interrupt_disable();
+
     if ((addr < _MemoryPoolBase) || (addr >= _MemoryPoolEnd))
     {
         if (addr)
         {
             rt_kprintf("[%s]Wrong!!\n", __func__);
-            //free(alloc_addr);
         }
-        return;
+        goto Exit_USB_free;
     }
 
-    if (disable_ohci_irq)
-        DISABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        DISABLE_EHCI_IRQ();
-
-    //rt_kprintf("USB_free:%x\n", (INT)addr+USB_MEM_BLOCK_SIZE);
+    //rt_kprintf("USB_free:%x\n", (int32_t)addr+USB_MEM_BLOCK_SIZE);
 
     /* get the leading block address */
     if (addr % USB_MEM_BLOCK_SIZE == 0)
@@ -271,32 +231,20 @@ void  USB_free(void *alloc_addr)
 
     if (addr % USB_MEM_BLOCK_SIZE != 0)
     {
-        rt_kprintf("USB_free fatal error on address: %x!!\n", (UINT32)alloc_addr);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return;
+        rt_kprintf("USB_free fatal error on address: %x!!\n", (uint32_t)alloc_addr);
+        goto Exit_USB_free;
     }
 
     pMblk = (USB_MHDR_T *)addr;
     if (pMblk->flag == 0)
     {
-        rt_kprintf("USB_free(), warning - try to free a free block: %x\n", (UINT32)alloc_addr);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return;
+        rt_kprintf("USB_free(), warning - try to free a free block: %x\n", (uint32_t)alloc_addr);
+        goto Exit_USB_free;
     }
     if (pMblk->magic != USB_MEM_ALLOC_MAGIC)
     {
         rt_kprintf("USB_free(), warning - try to free an unknow block at address:%x.\n", addr);
-        if (disable_ohci_irq)
-            ENABLE_OHCI_IRQ();
-        if (disable_ehci_irq)
-            ENABLE_EHCI_IRQ();
-        return;
+        goto Exit_USB_free;
     }
 
     //_pCurrent = pMblk;
@@ -307,15 +255,17 @@ void  USB_free(void *alloc_addr)
     for (i = 0; i < count; i++)
     {
         pMblk->flag = 0;     /* release block */
-        pMblk = (USB_MHDR_T *)((UINT32)pMblk + USB_MEM_BLOCK_SIZE);
+        pMblk = (USB_MHDR_T *)((uint32_t)pMblk + USB_MEM_BLOCK_SIZE);
     }
 
     _FreeMemorySize += count * USB_MEM_BLOCK_SIZE;
     _AllocatedMemorySize -= count * USB_MEM_BLOCK_SIZE;
-    if (disable_ohci_irq)
-        ENABLE_OHCI_IRQ();
-    if (disable_ehci_irq)
-        ENABLE_EHCI_IRQ();
+
+
+Exit_USB_free:
+
+    rt_hw_interrupt_enable(level);
+
     return;
 }
 

+ 107 - 44
bsp/nuvoton/libraries/nuc980/rtt_port/drv_emac.c

@@ -12,27 +12,22 @@
 
 #include <rtconfig.h>
 
-#if defined(BSP_USING_EMAC)
-
-#if defined(RT_USING_LWIP)
+#if defined(BSP_USING_EMAC) && defined(RT_USING_LWIP)
 
 #include <rtdevice.h>
 #include "NuMicro.h"
 #include <netif/ethernetif.h>
 #include <netif/etharp.h>
 #include <lwip/icmp.h>
+#include <lwip/pbuf.h>
 #include "lwipopts.h"
 
 #include "drv_sys.h"
-#include "drv_pdma.h"
+//#include "drv_pdma.h"
 
 /* Private define ---------------------------------------------------------------*/
 // RT_DEV_NAME_PREFIX e
 
-#if !defined(NU_EMAC_PDMA_MEMCOPY_THRESHOLD)
-    #define NU_EMAC_PDMA_MEMCOPY_THRESHOLD  1024
-#endif
-
 #define NU_EMAC_DEBUG
 #if defined(NU_EMAC_DEBUG)
     //#define NU_EMAC_RX_DUMP
@@ -45,6 +40,28 @@
 #define NU_EMAC_TID_STACK_SIZE  1024
 
 /* Private typedef --------------------------------------------------------------*/
+enum
+{
+    EMAC_START = -1,
+#if defined(BSP_USING_EMAC0)
+    EMAC0_IDX,
+#endif
+#if defined(BSP_USING_EMAC1)
+    EMAC1_IDX,
+#endif
+    EMAC_CNT
+};
+
+struct nu_emac_lwip_pbuf
+{
+    struct pbuf_custom p;  // lwip pbuf
+    EMAC_FRAME_T *psPktFrameDataBuf; // gmac descriptor
+    EMAC_MEMMGR_T *psMemMgr;
+    EMAC_DESCRIPTOR_T * rx_desc;
+    const struct memp_desc *memp_rx_pool;
+};
+typedef struct nu_emac_lwip_pbuf *nu_emac_lwip_pbuf_t;
+
 struct nu_emac
 {
     struct eth_device   eth;
@@ -57,21 +74,10 @@ struct nu_emac
     rt_thread_t         link_monitor;
     rt_uint8_t          mac_addr[6];
     struct rt_semaphore eth_sem;
+    const struct memp_desc *memp_rx_pool;
 };
 typedef struct nu_emac *nu_emac_t;
 
-enum
-{
-    EMAC_START = -1,
-#if defined(BSP_USING_EMAC0)
-    EMAC0_IDX,
-#endif
-#if defined(BSP_USING_EMAC1)
-    EMAC1_IDX,
-#endif
-    EMAC_CNT
-};
-
 /* Private functions ------------------------------------------------------------*/
 #if defined(NU_EMAC_RX_DUMP) || defined(NU_EMAC_TX_DUMP)
     static void nu_emac_pkt_dump(const char *msg, const struct pbuf *p);
@@ -100,6 +106,14 @@ static void nu_emac_rx_isr(int vector, void *param);
 /* Public functions -------------------------------------------------------------*/
 
 /* Private variables ------------------------------------------------------------*/
+#if defined(BSP_USING_EMAC0)
+LWIP_MEMPOOL_DECLARE(emac0_rx, EMAC_RX_DESC_SIZE, sizeof(struct nu_emac_lwip_pbuf), "EMAC0 RX PBUF pool");
+#endif
+
+#if defined(BSP_USING_EMAC1)
+LWIP_MEMPOOL_DECLARE(emac1_rx, EMAC_RX_DESC_SIZE, sizeof(struct nu_emac_lwip_pbuf), "EMAC1 RX PBUF pool");
+#endif
+
 static struct nu_emac nu_emac_arr[] =
 {
 #if defined(BSP_USING_EMAC0)
@@ -110,6 +124,7 @@ static struct nu_emac nu_emac_arr[] =
         .irqn_rx         =  IRQ_EMC0_RX,
         .rstidx          =  EMAC0RST,
         .clkidx          =  EMAC0CKEN,
+        .memp_rx_pool    =  &memp_emac0_rx
     },
 #endif
 #if defined(BSP_USING_EMAC1)
@@ -120,6 +135,7 @@ static struct nu_emac nu_emac_arr[] =
         .irqn_rx        =  IRQ_EMC1_RX,
         .rstidx         =  EMAC1RST,
         .clkidx         =  EMAC1CKEN,
+        .memp_rx_pool   =  &memp_emac1_rx
     },
 #endif
 };
@@ -158,11 +174,7 @@ static void nu_emac_halt(nu_emac_t psNuEmac)
 
 static void *nu_emac_memcpy(void *dest, void *src, unsigned int count)
 {
-#if defined(NU_EMAC_PDMA_MEMCOPY)
-    if ((count >= NU_EMAC_PDMA_MEMCOPY_THRESHOLD))
-        return nu_pdma_memcpy(dest, src, count);
-#endif
-    return memcpy(dest, src, count);
+    return rt_memcpy(dest, src, count);
 }
 
 static void nu_emac_reinit(nu_emac_t psNuEmac)
@@ -437,12 +449,25 @@ static rt_err_t nu_emac_tx(rt_device_t dev, struct pbuf *p)
 #endif
 
     /* Return SUCCESS? */
-#if defined(BSP_USING_MMU)
-    mmu_clean_invalidated_dcache((uint32_t)psNuEmac->memmgr.psCurrentTxDesc, sizeof(EMAC_DESCRIPTOR_T));
-#endif
     return (EMAC_SendPktWoCopy(&psNuEmac->memmgr, offset) == 1) ? RT_EOK : RT_ERROR;
 }
 
+void nu_emac_pbuf_free(struct pbuf *p)
+{
+    nu_emac_lwip_pbuf_t my_buf = (nu_emac_lwip_pbuf_t)p;
+
+    SYS_ARCH_DECL_PROTECT(old_level);
+    SYS_ARCH_PROTECT(old_level);
+
+    //rt_kprintf("%08x %08x\n",my_buf, my_buf->rx_desc);
+
+    /* Update RX descriptor & trigger */
+    EMAC_RxTrigger(my_buf->psMemMgr, my_buf->rx_desc);
+
+    memp_free_pool(my_buf->memp_rx_pool, my_buf);
+    SYS_ARCH_UNPROTECT(old_level);
+}
+
 static struct pbuf *nu_emac_rx(rt_device_t dev)
 {
     nu_emac_t psNuEmac = (nu_emac_t)dev;
@@ -452,30 +477,40 @@ static struct pbuf *nu_emac_rx(rt_device_t dev)
     EMAC_T *EMAC = psNuEmac->memmgr.psEmac;
 
     /* Check available data. */
-#if defined(BSP_USING_MMU)
-    mmu_clean_invalidated_dcache((uint32_t)psNuEmac->memmgr.psCurrentRxDesc, sizeof(EMAC_DESCRIPTOR_T));
-#endif
     if ((avaialbe_size = EMAC_GetAvailRXBufSize(&psNuEmac->memmgr, &pu8DataBuf)) > 0)
     {
-        /* Allocate RX packet buffer. */
-        p = pbuf_alloc(PBUF_RAW, avaialbe_size, PBUF_RAM);
-        if (p != RT_NULL)
+        EMAC_DESCRIPTOR_T * cur_rx = EMAC_RecvPktDoneWoRxTrigger(&psNuEmac->memmgr);
+        nu_emac_lwip_pbuf_t my_pbuf  = (nu_emac_lwip_pbuf_t)memp_malloc_pool(psNuEmac->memp_rx_pool);
+        if (my_pbuf != RT_NULL)
         {
-            RT_ASSERT(p->next == RT_NULL);
 
-            nu_emac_memcpy((void *)p->payload, (void *)pu8DataBuf, avaialbe_size);
+            my_pbuf->p.custom_free_function = nu_emac_pbuf_free;
+            my_pbuf->psPktFrameDataBuf      = (EMAC_FRAME_T *)pu8DataBuf;
+            my_pbuf->rx_desc                = cur_rx;
+            my_pbuf->psMemMgr               = &psNuEmac->memmgr;
+            my_pbuf->memp_rx_pool           = psNuEmac->memp_rx_pool;
 
-#if defined(NU_EMAC_RX_DUMP)
-            nu_emac_pkt_dump("RX dump", p);
+#if defined(BSP_USING_MMU)
+            mmu_invalidate_dcache((rt_uint32_t)pu8DataBuf, (rt_uint32_t)avaialbe_size);
 #endif
+            //rt_kprintf("%08x, %08x, %d\n", my_pbuf, cur_rx, avaialbe_size);
+            p = pbuf_alloced_custom(PBUF_RAW,
+                                       avaialbe_size,
+                                       PBUF_REF,
+                                       &my_pbuf->p,
+                                       pu8DataBuf,
+                                       EMAC_MAX_PKT_SIZE);
+            if (p == RT_NULL)
+            {
+                rt_kprintf("%s : failed to alloted %08x\n", __func__, p);
+                EMAC_RxTrigger(&psNuEmac->memmgr, cur_rx);
+            }
         }
         else
         {
-            NU_EMAC_TRACE("Can't allocate memory for RX packet.(%d)\n", avaialbe_size);
+            rt_kprintf("LWIP_MEMPOOL_ALLOC < 0!!\n");
+            EMAC_RxTrigger(&psNuEmac->memmgr, cur_rx);
         }
-
-        /* Update RX descriptor & New trigger */
-        EMAC_RecvPktDone(&psNuEmac->memmgr);
     }
     else    /* If it hasn't RX packet, it will enable interrupt. */
     {
@@ -614,6 +649,9 @@ static int rt_hw_nu_emac_init(void)
         rt_hw_interrupt_install(psNuEMAC->irqn_rx, nu_emac_rx_isr, (void *)psNuEMAC, szTmp);
         rt_hw_interrupt_umask(psNuEMAC->irqn_rx);
 
+        /* Initial zero_copy rx pool */
+        memp_init_pool(psNuEMAC->memp_rx_pool);
+
         /* Register eth device */
         ret = eth_device_init(&psNuEMAC->eth, psNuEMAC->name);
         RT_ASSERT(ret == RT_EOK);
@@ -624,6 +662,31 @@ static int rt_hw_nu_emac_init(void)
 
 INIT_APP_EXPORT(rt_hw_nu_emac_init);
 
-#endif /* #if defined( RT_USING_LWIP ) */
 
-#endif /* #if defined( BSP_USING_EMAC ) */
+#if 0
+/*
+    Remeber src += lwipiperf_SRCS in components\net\lwip-*\SConscript
+*/
+#include "lwip/apps/lwiperf.h"
+
+static void
+lwiperf_report(void *arg, enum lwiperf_report_type report_type,
+               const ip_addr_t *local_addr, u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port,
+               u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
+{
+    LWIP_UNUSED_ARG(arg);
+    LWIP_UNUSED_ARG(local_addr);
+    LWIP_UNUSED_ARG(local_port);
+
+    rt_kprintf("IPERF report: type=%d, remote: %s:%d, total bytes: %"U32_F", duration in ms: %"U32_F", kbits/s: %"U32_F"\n",
+               (int)report_type, ipaddr_ntoa(remote_addr), (int)remote_port, bytes_transferred, ms_duration, bandwidth_kbitpsec);
+}
+
+void lwiperf_example_init(void)
+{
+    lwiperf_start_tcp_server_default(lwiperf_report, NULL);
+}
+MSH_CMD_EXPORT(lwiperf_example_init, start lwip tcp server);
+#endif
+
+#endif /* #if defined( BSP_USING_EMAC ) && defined( RT_USING_LWIP )*/

+ 21 - 6
bsp/nuvoton/libraries/nuc980/rtt_port/drv_i2c.c

@@ -100,20 +100,32 @@ static nu_i2c_bus_t nu_i2c_arr [ ] =
 static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
                                  struct rt_i2c_msg msgs[],
                                  rt_uint32_t num);
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                   rt_uint32_t u32Cmd,
+                                   rt_uint32_t u32Value);
 
 static const struct rt_i2c_bus_device_ops nu_i2c_ops =
 {
     .master_xfer        = nu_i2c_mst_xfer,
     .slave_xfer         = NULL,
-    .i2c_bus_control    = NULL,
+    .i2c_bus_control    = nu_i2c_bus_control
 };
 
-static rt_err_t nu_i2c_configure(nu_i2c_bus_t *bus)
+static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t u32Cmd, rt_uint32_t u32Value)
 {
+    nu_i2c_bus_t *nu_i2c;
+
     RT_ASSERT(bus != RT_NULL);
+    nu_i2c = (nu_i2c_bus_t *) bus;
 
-    bus->parent.ops = &nu_i2c_ops;
-    I2C_Open(bus->I2C, 100000);
+    switch (RT_I2C_DEV_CTRL_CLK)
+    {
+    case RT_I2C_DEV_CTRL_CLK:
+        I2C_SetBusClockFreq(nu_i2c->I2C, u32Value);
+        break;
+    default:
+        return -RT_EIO;
+    }
 
     return RT_EOK;
 }
@@ -376,11 +388,14 @@ int rt_hw_i2c_init(void)
 
     for (i = (I2C_START + 1); i < I2C_CNT; i++)
     {
-
         nu_sys_ipclk_enable(nu_i2c_arr[i].clkidx);
         nu_sys_ip_reset(nu_i2c_arr[i].rstidx);
 
-        nu_i2c_configure(&nu_i2c_arr[i]);
+        /* Reset and initial IP engine. */
+        I2C_Close(nu_i2c_arr[i].I2C);
+        I2C_Open(nu_i2c_arr[i].I2C, 100000);
+        nu_i2c_arr[i].parent.ops = &nu_i2c_ops;
+
         ret = rt_i2c_bus_device_register(&nu_i2c_arr[i].parent, nu_i2c_arr[i].device_name);
         RT_ASSERT(RT_EOK == ret);
     }

+ 5 - 5
bsp/nuvoton/libraries/nuc980/rtt_port/drv_i2s.c

@@ -244,6 +244,11 @@ static rt_err_t nu_i2s_dai_setup(nu_i2s_t psNuI2s, struct rt_audio_configure *pc
         i2sIoctl(I2S_SET_I2S_FORMAT, I2S_FORMAT_I2S, 0);
 
         if (psNuI2s->AcodecOps->role == NU_ACODEC_ROLE_MASTER)
+        {
+            // Set as slave, source clock is XIN (12MHz)
+            i2sIoctl(I2S_SET_MODE, I2S_MODE_SLAVE, 0);
+        }
+        else
         {
             if (pconfig->samplerate % 11025)
             {
@@ -284,11 +289,6 @@ static rt_err_t nu_i2s_dai_setup(nu_i2s_t psNuI2s, struct rt_audio_configure *pc
             // Set as master
             i2sIoctl(I2S_SET_MODE, I2S_MODE_MASTER, 0);
         }
-        else
-        {
-            // Set as slave, source clock is XIN (12MHz)
-            i2sIoctl(I2S_SET_MODE, I2S_MODE_SLAVE, 0);
-        }
 
         LOG_I("Open I2S.");
 

+ 0 - 1
bsp/nuvoton/libraries/nuc980/rtt_port/drv_sys.c

@@ -302,7 +302,6 @@ E_SYS_USB0_ID nu_sys_usb0_role(void)
 #ifdef RT_USING_FINSH
 
 #include <finsh.h>
-FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_cpu_reset, reset, restart the system);
 
 #ifdef FINSH_USING_MSH
 int cmd_reset(int argc, char **argv)

+ 93 - 30
bsp/nuvoton/libraries/nuc980/rtt_port/drv_usbhost.c

@@ -30,6 +30,21 @@
 
 #define NU_MAX_USBH_HUB_PORT_DEV    USB_HUB_PORT_NUM
 
+#define NU_USBHOST_MUTEX_INIT()      { \
+                                s_sUSBHDev.lock = rt_mutex_create("usbhost_lock", RT_IPC_FLAG_PRIO); \
+                                RT_ASSERT(s_sUSBHDev.lock != RT_NULL); \
+                            }
+
+#define NU_USBHOST_LOCK()      { \
+                                rt_err_t result = rt_mutex_take(s_sUSBHDev.lock, RT_WAITING_FOREVER); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+
+#define NU_USBHOST_UNLOCK()    { \
+                                rt_err_t result = rt_mutex_release(s_sUSBHDev.lock); \
+                                RT_ASSERT(result == RT_EOK); \
+                            }
+
 /* Private typedef --------------------------------------------------------------*/
 typedef struct nu_port_dev
 {
@@ -59,6 +74,7 @@ struct nu_usbh_dev
     E_SYS_IPRST rstidx;
     E_SYS_IPCLK clkidx;
     rt_thread_t polling_thread;
+    rt_mutex_t  lock;
     S_NU_RH_PORT_CTRL asPortCtrl[NU_MAX_USBH_PORT];
 };
 
@@ -165,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];
             }
         }
     }
@@ -186,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;
     }
 }
@@ -298,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
 
@@ -350,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
@@ -398,16 +425,42 @@ static int nu_bulk_xfer(
     UTR_T *psUTR,
     int timeouts)
 {
-    int ret;
-
-    ret = usbh_bulk_xfer(psUTR);
+    #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
-    rt_completion_wait(&(psPortDev->utr_completion), timeouts);
-    return 0;
+    while ( retry > 0 )
+    {
+        if ( rt_completion_wait(&(psPortDev->utr_completion), timeouts) != 0 )
+        {
+            rt_uint32_t level;
+
+            rt_kprintf("Request %d Timeout in %d ms!!\n", psUTR->data_len, timeouts);
+
+            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 (retry > 0) ? 0 : -1;
 }
 
 static int nu_int_xfer(
@@ -477,6 +530,8 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
 
     void *buffer_nonch = buffer;
 
+    NU_USBHOST_LOCK();
+
     psPortCtrl = GetRHPortControlFromPipe(pipe);
     if (psPortCtrl == RT_NULL)
     {
@@ -494,8 +549,10 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     if (buffer_nonch && nbytes)
     {
         buffer_nonch = psPortDev->asPipePktBuf[pipe->pipe_index];
-        rt_memcpy(buffer_nonch, buffer, nbytes);
-        mmu_clean_invalidated_dcache((uint32_t)buffer_nonch, nbytes);
+        if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_OUT)
+        {
+            rt_memcpy(buffer_nonch, buffer, nbytes);
+        }
     }
 #endif
 
@@ -503,6 +560,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     if (pipe->ep.bmAttributes == USB_EP_ATTR_CONTROL)
     {
         int ret;
+
         if (token == USBH_PID_SETUP)
         {
             struct urequest *psSetup = (struct urequest *)buffer_nonch;
@@ -517,7 +575,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             else
             {
                 /* Write data to USB device. */
-                //Trigger USBHostLib Ctril_Xfer
+                //Trigger USBHostLib Ctrl_Xfer
                 ret = nu_ctrl_xfer(psPortDev, psSetup, NULL, timeouts);
                 if (ret != psSetup->wLength)
                     goto exit_nu_pipe_xfer;
@@ -571,7 +629,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             if (nu_bulk_xfer(psPortDev, psUTR, timeouts) < 0)
             {
                 RT_DEBUG_LOG(RT_DEBUG_USB, ("nu_pipe_xfer ERROR: bulk transfer failed\n"));
-                goto exit_nu_pipe_xfer;
+                goto failreport_nu_pipe_xfer;
             }
         }
         else if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
@@ -588,7 +646,7 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
             {
                 i32XferLen = nbytes;
             }
-            return i32XferLen;
+            goto exit2_nu_pipe_xfer;
         }
         else if (pipe->ep.bmAttributes == USB_EP_ATTR_ISOC)
         {
@@ -599,6 +657,8 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
 
     } //else
 
+failreport_nu_pipe_xfer:
+
     if (psUTR->bIsTransferDone == 0)
     {
         //Timeout
@@ -628,29 +688,28 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
     //Call callback
     if (pipe->callback != RT_NULL)
     {
-        struct uhost_msg msg;
-        msg.type = USB_MSG_CALLBACK;
-        msg.content.cb.function = pipe->callback;
-        msg.content.cb.context = pipe->user_data;
-        rt_usbh_event_signal(&msg);
+        pipe->callback(pipe);
     }
 
-    if (pipe->status != UPIPE_STATUS_OK)
-        goto exit_nu_pipe_xfer;
-
 exit_nu_pipe_xfer:
 
+    if (psUTR)
+        free_utr(psUTR);
+
+exit2_nu_pipe_xfer:
+
 #if defined(BSP_USING_MMU)
     if ((nbytes) &&
             (buffer_nonch != buffer))
     {
-        mmu_invalidate_dcache((uint32_t)buffer_nonch, nbytes);
-        rt_memcpy(buffer, buffer_nonch, nbytes);
+        if ((pipe->ep.bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN)
+        {
+            rt_memcpy(buffer, buffer_nonch, nbytes);
+        }
     }
 #endif
 
-    if (psUTR)
-        free_utr(psUTR);
+    NU_USBHOST_UNLOCK();
 
     return i32XferLen;
 }
@@ -660,7 +719,10 @@ static void nu_usbh_rh_thread_entry(void *parameter)
 {
     while (1)
     {
+        NU_USBHOST_LOCK();
         usbh_polling_root_hubs();
+        NU_USBHOST_UNLOCK();
+
         rt_thread_mdelay(NU_USBHOST_HUB_POLLING_INTERVAL);
     }
 }
@@ -771,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 */
@@ -871,6 +932,8 @@ int nu_usbh_register(void)
     psUHCD->ops               = &nu_uhcd_ops;
     psUHCD->num_ports         = NU_MAX_USBH_PORT;
 
+    NU_USBHOST_MUTEX_INIT();
+
     res = rt_device_register(&psUHCD->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
     RT_ASSERT(res == RT_EOK);
 

+ 65 - 59
bsp/nuvoton/nk-980iot/.config

@@ -7,6 +7,7 @@
 # RT-Thread Kernel
 #
 CONFIG_RT_NAME_MAX=16
+# CONFIG_RT_USING_BIG_ENDIAN is not set
 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set
 # CONFIG_RT_USING_SMP is not set
 CONFIG_RT_ALIGN_SIZE=4
@@ -21,6 +22,13 @@ CONFIG_RT_USING_IDLE_HOOK=y
 CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
 CONFIG_IDLE_THREAD_STACK_SIZE=2048
 # CONFIG_RT_USING_TIMER_SOFT is not set
+
+#
+# kservice optimization
+#
+# CONFIG_RT_KSERVICE_USING_STDLIB is not set
+# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
+# CONFIG_RT_USING_ASM_MEMCPY is not set
 CONFIG_RT_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -66,7 +74,8 @@ CONFIG_RT_USING_DEVICE=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=256
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
-CONFIG_RT_VER_NUM=0x40003
+# CONFIG_RT_PRINTF_LONGLONG is not set
+CONFIG_RT_VER_NUM=0x40004
 CONFIG_ARCH_ARM=y
 # CONFIG_RT_USING_CPU_FFS is not set
 CONFIG_ARCH_ARM_ARM9=y
@@ -89,19 +98,19 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # Command shell
 #
 CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
 CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
 CONFIG_FINSH_USING_HISTORY=y
 CONFIG_FINSH_HISTORY_LINES=5
 CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
-CONFIG_FINSH_THREAD_PRIORITY=20
-CONFIG_FINSH_THREAD_STACK_SIZE=4096
-CONFIG_FINSH_CMD_SIZE=80
 # CONFIG_FINSH_USING_AUTH is not set
-CONFIG_FINSH_USING_MSH=y
-CONFIG_FINSH_USING_MSH_DEFAULT=y
-# CONFIG_FINSH_USING_MSH_ONLY is not set
 CONFIG_FINSH_ARG_MAX=10
 
 #
@@ -135,6 +144,7 @@ CONFIG_RT_DFS_ELM_DRIVES=8
 CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
 # CONFIG_RT_DFS_ELM_USE_ERASE is not set
 CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000
 CONFIG_RT_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
@@ -149,6 +159,8 @@ CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
 CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
 CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
 CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
 CONFIG_RT_SERIAL_USING_DMA=y
 CONFIG_RT_SERIAL_RB_BUFSZ=2048
 CONFIG_RT_USING_CAN=y
@@ -171,9 +183,6 @@ CONFIG_RT_MTD_NAND_DEBUG=y
 CONFIG_RT_USING_RTC=y
 CONFIG_RT_USING_ALARM=y
 # CONFIG_RT_USING_SOFT_RTC is not set
-CONFIG_RTC_SYNC_USING_NTP=y
-CONFIG_RTC_NTP_FIRST_SYNC_DELAY=30
-CONFIG_RTC_NTP_SYNC_PERIOD=3600
 # CONFIG_RT_USING_SDIO is not set
 CONFIG_RT_USING_SPI=y
 CONFIG_RT_USING_QSPI=y
@@ -219,6 +228,7 @@ CONFIG_RT_HWCRYPTO_USING_RNG=y
 #
 # Using USB
 #
+CONFIG_RT_USING_USB=y
 CONFIG_RT_USING_USB_HOST=y
 CONFIG_RT_USBH_MSTORAGE=y
 CONFIG_UDISK_MOUNTPOINT="/mnt/udisk"
@@ -248,13 +258,16 @@ CONFIG_RT_USB_MSTORAGE_DISK_NAME="ramdisk1"
 # POSIX layer and C standard library
 #
 CONFIG_RT_USING_LIBC=y
+CONFIG_RT_LIBC_USING_TIME=y
+# CONFIG_RT_LIBC_USING_FILEIO is not set
+# CONFIG_RT_USING_MODULE is not set
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_RT_USING_PTHREADS is not set
 CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_POSIX_MMAP is not set
 # CONFIG_RT_USING_POSIX_TERMIOS is not set
 # CONFIG_RT_USING_POSIX_GETLINE is not set
 # CONFIG_RT_USING_POSIX_AIO is not set
-# CONFIG_RT_USING_MODULE is not set
 
 #
 # Network
@@ -264,7 +277,7 @@ CONFIG_RT_USING_POSIX=y
 # Socket abstraction layer
 #
 CONFIG_RT_USING_SAL=y
-CONFIG_SAL_INTERNET_CHECK=y
+# CONFIG_SAL_INTERNET_CHECK is not set
 
 #
 # protocol stack implement
@@ -290,8 +303,9 @@ CONFIG_NETDEV_IPV6=0
 #
 CONFIG_RT_USING_LWIP=y
 # CONFIG_RT_USING_LWIP141 is not set
-CONFIG_RT_USING_LWIP202=y
-# CONFIG_RT_USING_LWIP212 is not set
+# CONFIG_RT_USING_LWIP202 is not set
+# CONFIG_RT_USING_LWIP203 is not set
+CONFIG_RT_USING_LWIP212=y
 # CONFIG_RT_USING_LWIP_IPV6 is not set
 CONFIG_RT_LWIP_MEM_ALIGNMENT=4
 CONFIG_RT_LWIP_IGMP=y
@@ -305,30 +319,30 @@ CONFIG_IP_SOF_BROADCAST_RECV=1
 #
 # Static IPv4 Address
 #
-CONFIG_RT_LWIP_IPADDR="192.168.1.30"
-CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_IPADDR="192.168.31.55"
+CONFIG_RT_LWIP_GWADDR="192.168.31.1"
 CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
 CONFIG_RT_LWIP_UDP=y
 CONFIG_RT_LWIP_TCP=y
 CONFIG_RT_LWIP_RAW=y
 # CONFIG_RT_LWIP_PPP is not set
-CONFIG_RT_MEMP_NUM_NETCONN=32
+CONFIG_RT_MEMP_NUM_NETCONN=16
 CONFIG_RT_LWIP_PBUF_NUM=256
-CONFIG_RT_LWIP_RAW_PCB_NUM=32
-CONFIG_RT_LWIP_UDP_PCB_NUM=32
-CONFIG_RT_LWIP_TCP_PCB_NUM=32
-CONFIG_RT_LWIP_TCP_SEG_NUM=256
-CONFIG_RT_LWIP_TCP_SND_BUF=32768
-CONFIG_RT_LWIP_TCP_WND=10240
+CONFIG_RT_LWIP_RAW_PCB_NUM=16
+CONFIG_RT_LWIP_UDP_PCB_NUM=16
+CONFIG_RT_LWIP_TCP_PCB_NUM=16
+CONFIG_RT_LWIP_TCP_SEG_NUM=64
+CONFIG_RT_LWIP_TCP_SND_BUF=16384
+CONFIG_RT_LWIP_TCP_WND=65535
 CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
-CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=256
 CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=4096
 # CONFIG_LWIP_NO_RX_THREAD is not set
 # CONFIG_LWIP_NO_TX_THREAD is not set
 CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
-CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
-CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
-# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=4096
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=256
+CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
 CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
 CONFIG_LWIP_NETIF_LINK_CALLBACK=1
 CONFIG_SO_REUSE=1
@@ -362,8 +376,15 @@ CONFIG_RT_LWIP_USING_PING=y
 CONFIG_RT_USING_UTEST=y
 CONFIG_UTEST_THR_STACK_SIZE=4096
 CONFIG_UTEST_THR_PRIORITY=20
+# CONFIG_RT_USING_VAR_EXPORT is not set
+# CONFIG_RT_USING_RT_LINK is not set
 # CONFIG_RT_USING_LWP is not set
 
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
+
 #
 # RT-Thread online packages
 #
@@ -490,11 +511,21 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_OPENMV is not set
 # CONFIG_PKG_USING_MUPDF is not set
 # CONFIG_PKG_USING_STEMWIN is not set
-# CONFIG_PKG_USING_WAVPLAYER is not set
+CONFIG_PKG_USING_WAVPLAYER=y
+CONFIG_PKG_WAVPLAYER_PATH="/packages/multimedia/wavplayer"
+CONFIG_PKG_WP_USING_PLAY=y
+CONFIG_PKG_WP_PLAY_DEVICE="sound0"
+CONFIG_PKG_WP_USING_RECORD=y
+CONFIG_PKG_WP_RECORD_DEVICE="sound0"
+# CONFIG_PKG_USING_WAVPLAYER_V020 is not set
+CONFIG_PKG_USING_WAVPLAYER_LATEST_VERSION=y
+CONFIG_PKG_WAVPLAYER_VER="latest"
 # CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
 # CONFIG_PKG_USING_HELIX is not set
 # CONFIG_PKG_USING_AZUREGUIX is not set
 # CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
 
 #
 # tools packages
@@ -518,19 +549,6 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_BS8116A is not set
 # CONFIG_PKG_USING_GPS_RMC is not set
 # CONFIG_PKG_USING_URLENCODE is not set
-# CONFIG_PKG_USING_UMCN is not set
-# CONFIG_PKG_USING_LWRB2RTT is not set
-# CONFIG_PKG_USING_CPU_USAGE is not set
-# CONFIG_PKG_USING_GBK2UTF8 is not set
-# CONFIG_PKG_USING_VCONSOLE is not set
-# CONFIG_PKG_USING_KDB is not set
-# CONFIG_PKG_USING_WAMR is not set
-# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
-# CONFIG_PKG_USING_LWLOG is not set
-# CONFIG_PKG_USING_ANV_TRACE is not set
-# CONFIG_PKG_USING_ANV_MEMLEAK is not set
-# CONFIG_PKG_USING_ANV_TESTSUIT is not set
-# CONFIG_PKG_USING_ANV_BENCH is not set
 
 #
 # system packages
@@ -592,6 +610,7 @@ CONFIG_PKG_RAMDISK_VER="latest"
 # CONFIG_PKG_USING_QFPLIB_M3 is not set
 # CONFIG_PKG_USING_LPM is not set
 # CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
 
 #
 # peripheral libraries and drivers
@@ -659,6 +678,7 @@ CONFIG_PKG_RAMDISK_VER="latest"
 # CONFIG_PKG_USING_LIBNFC is not set
 # CONFIG_PKG_USING_MFOC is not set
 # CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
 
 #
 # AI packages
@@ -705,23 +725,8 @@ CONFIG_PKG_OPTPARSE_VER="latest"
 # CONFIG_PKG_USING_NETWORK_SAMPLES is not set
 # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
-CONFIG_PKG_USING_VI=y
-CONFIG_PKG_VI_PATH="/packages/misc/vi"
-CONFIG_VI_MAX_LEN=4096
-# CONFIG_VI_ENABLE_8BIT is not set
-CONFIG_VI_ENABLE_COLON=y
-CONFIG_VI_ENABLE_YANKMARK=y
-CONFIG_VI_ENABLE_SEARCH=y
-CONFIG_VI_ENABLE_DOT_CMD=y
-CONFIG_VI_ENABLE_READONLY=y
-CONFIG_VI_ENABLE_SETOPTS=y
-CONFIG_VI_ENABLE_SET=y
-CONFIG_VI_ENABLE_VI_ASK_TERMINAL=y
-CONFIG_VI_ENABLE_UNDO=y
-CONFIG_VI_ENABLE_UNDO_QUEUE=y
-CONFIG_VI_UNDO_QUEUE_MAX=256
-CONFIG_PKG_USING_VI_LATEST_VERSION=y
-CONFIG_PKG_VI_VER="latest"
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_VI_LATEST_VERSION is not set
 # CONFIG_PKG_USING_KI is not set
 # CONFIG_PKG_USING_ARMv7M_DWT is not set
 # CONFIG_PKG_USING_VT100 is not set
@@ -751,6 +756,7 @@ CONFIG_NU_PKG_USING_DEMO=y
 # CONFIG_NU_PKG_USING_MAX31875 is not set
 # CONFIG_NU_PKG_USING_NAU88L25 is not set
 CONFIG_NU_PKG_USING_NAU8822=y
+# CONFIG_NU_PKG_USING_DA9062 is not set
 # CONFIG_NU_PKG_USING_ILI9341 is not set
 CONFIG_NU_PKG_USING_SPINAND=y
 
@@ -762,7 +768,7 @@ CONFIG_NU_PKG_USING_SPINAND=y
 # On-chip Peripheral Drivers
 #
 CONFIG_SOC_SERIES_NUC980=y
-# CONFIG_BSP_USE_STDDRIVER_SOURCE is not set
+CONFIG_BSP_USE_STDDRIVER_SOURCE=y
 CONFIG_BSP_USING_MMU=y
 CONFIG_BSP_USING_PDMA=y
 CONFIG_NU_PDMA_MEMFUN_ACTOR_MAX=2

+ 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)

+ 29 - 51
bsp/nuvoton/nk-n9h30/.config

@@ -7,6 +7,7 @@
 # RT-Thread Kernel
 #
 CONFIG_RT_NAME_MAX=16
+# CONFIG_RT_USING_BIG_ENDIAN is not set
 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set
 # CONFIG_RT_USING_SMP is not set
 CONFIG_RT_ALIGN_SIZE=4
@@ -27,6 +28,7 @@ CONFIG_IDLE_THREAD_STACK_SIZE=2048
 #
 # CONFIG_RT_KSERVICE_USING_STDLIB is not set
 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
+# CONFIG_RT_USING_ASM_MEMCPY is not set
 CONFIG_RT_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -72,7 +74,8 @@ CONFIG_RT_USING_INTERRUPT_INFO=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=256
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
-CONFIG_RT_VER_NUM=0x40003
+# CONFIG_RT_PRINTF_LONGLONG is not set
+CONFIG_RT_VER_NUM=0x40004
 CONFIG_ARCH_ARM=y
 # CONFIG_RT_USING_CPU_FFS is not set
 CONFIG_ARCH_ARM_ARM9=y
@@ -95,19 +98,19 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # Command shell
 #
 CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
 CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
 CONFIG_FINSH_USING_HISTORY=y
 CONFIG_FINSH_HISTORY_LINES=5
 CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
-CONFIG_FINSH_THREAD_PRIORITY=20
-CONFIG_FINSH_THREAD_STACK_SIZE=4096
-CONFIG_FINSH_CMD_SIZE=80
 # CONFIG_FINSH_USING_AUTH is not set
-CONFIG_FINSH_USING_MSH=y
-CONFIG_FINSH_USING_MSH_DEFAULT=y
-# CONFIG_FINSH_USING_MSH_ONLY is not set
 CONFIG_FINSH_ARG_MAX=10
 
 #
@@ -141,6 +144,7 @@ CONFIG_RT_DFS_ELM_DRIVES=8
 CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
 # CONFIG_RT_DFS_ELM_USE_ERASE is not set
 CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000
 CONFIG_RT_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
@@ -155,6 +159,8 @@ CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
 CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
 CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
 CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
 # CONFIG_RT_SERIAL_USING_DMA is not set
 CONFIG_RT_SERIAL_RB_BUFSZ=2048
 CONFIG_RT_USING_CAN=y
@@ -205,6 +211,7 @@ CONFIG_RT_INPUT_CAPTURE_RB_SIZE=100
 #
 # Using USB
 #
+CONFIG_RT_USING_USB=y
 CONFIG_RT_USING_USB_HOST=y
 CONFIG_RT_USBH_MSTORAGE=y
 CONFIG_UDISK_MOUNTPOINT="/mnt/udisk"
@@ -234,14 +241,16 @@ CONFIG_RT_USB_MSTORAGE_DISK_NAME="ramdisk1"
 # POSIX layer and C standard library
 #
 CONFIG_RT_USING_LIBC=y
+CONFIG_RT_LIBC_USING_TIME=y
+# CONFIG_RT_LIBC_USING_FILEIO is not set
+# CONFIG_RT_USING_MODULE is not set
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_RT_USING_PTHREADS is not set
 CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_POSIX_MMAP is not set
 # CONFIG_RT_USING_POSIX_TERMIOS is not set
 # CONFIG_RT_USING_POSIX_GETLINE is not set
 # CONFIG_RT_USING_POSIX_AIO is not set
-# CONFIG_RT_USING_MODULE is not set
-CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 
 #
 # Network
@@ -278,6 +287,7 @@ CONFIG_NETDEV_IPV6=0
 CONFIG_RT_USING_LWIP=y
 # CONFIG_RT_USING_LWIP141 is not set
 CONFIG_RT_USING_LWIP202=y
+# CONFIG_RT_USING_LWIP203 is not set
 # CONFIG_RT_USING_LWIP212 is not set
 # CONFIG_RT_USING_LWIP_IPV6 is not set
 CONFIG_RT_LWIP_MEM_ALIGNMENT=4
@@ -349,8 +359,15 @@ CONFIG_RT_LWIP_USING_PING=y
 CONFIG_RT_USING_UTEST=y
 CONFIG_UTEST_THR_STACK_SIZE=4096
 CONFIG_UTEST_THR_PRIORITY=20
+# CONFIG_RT_USING_VAR_EXPORT is not set
+# CONFIG_RT_USING_RT_LINK is not set
 # CONFIG_RT_USING_LWP is not set
 
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
+
 #
 # RT-Thread online packages
 #
@@ -507,27 +524,6 @@ CONFIG_PKG_NUEMWIN_VER_NUM=0x99999
 # CONFIG_PKG_USING_BS8116A is not set
 # CONFIG_PKG_USING_GPS_RMC is not set
 # CONFIG_PKG_USING_URLENCODE is not set
-# CONFIG_PKG_USING_UMCN is not set
-# CONFIG_PKG_USING_LWRB2RTT is not set
-# CONFIG_PKG_USING_CPU_USAGE is not set
-# CONFIG_PKG_USING_GBK2UTF8 is not set
-# CONFIG_PKG_USING_VCONSOLE is not set
-# CONFIG_PKG_USING_KDB is not set
-# CONFIG_PKG_USING_WAMR is not set
-# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
-# CONFIG_PKG_USING_LWLOG is not set
-# CONFIG_PKG_USING_ANV_TRACE is not set
-# CONFIG_PKG_USING_ANV_MEMLEAK is not set
-# CONFIG_PKG_USING_ANV_TESTSUIT is not set
-# CONFIG_PKG_USING_ANV_BENCH is not set
-# CONFIG_PKG_USING_DEVMEM is not set
-# CONFIG_PKG_USING_REGEX is not set
-CONFIG_PKG_USING_MEM_SANDBOX=y
-CONFIG_PKG_MEM_SANDBOX_PATH="/packages/tools/mem_sandbox"
-CONFIG_PKG_USING_MEM_SANDBOX_LATEST_VERSION=y
-CONFIG_PKG_MEM_SANDBOX_VER="latest"
-# CONFIG_PKG_USING_SOLAR_TERMS is not set
-# CONFIG_PKG_USING_GAN_ZHI is not set
 
 #
 # system packages
@@ -733,27 +729,8 @@ CONFIG_PKG_OPTPARSE_VER="latest"
 # CONFIG_PKG_USING_NETWORK_SAMPLES is not set
 # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
-CONFIG_PKG_USING_VI=y
-CONFIG_PKG_VI_PATH="/packages/misc/vi"
-CONFIG_VI_SANDBOX_SIZE_KB=20
-CONFIG_VI_MAX_LEN=4096
-# CONFIG_VI_ENABLE_8BIT is not set
-CONFIG_VI_ENABLE_COLON=y
-CONFIG_VI_ENABLE_COLON_EXPAND=y
-CONFIG_VI_ENABLE_YANKMARK=y
-CONFIG_VI_ENABLE_SEARCH=y
-CONFIG_VI_ENABLE_DOT_CMD=y
-CONFIG_VI_ENABLE_READONLY=y
-CONFIG_VI_ENABLE_SETOPTS=y
-CONFIG_VI_ENABLE_SET=y
-# CONFIG_VI_ENABLE_WIN_RESIZE is not set
-CONFIG_VI_ENABLE_VI_ASK_TERMINAL=y
-CONFIG_VI_ENABLE_UNDO=y
-CONFIG_VI_ENABLE_UNDO_QUEUE=y
-CONFIG_VI_UNDO_QUEUE_MAX=256
-CONFIG_VI_ENABLE_VERBOSE_STATUS=y
-CONFIG_PKG_USING_VI_LATEST_VERSION=y
-CONFIG_PKG_VI_VER="latest"
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_VI_LATEST_VERSION is not set
 # CONFIG_PKG_USING_KI is not set
 # CONFIG_PKG_USING_ARMv7M_DWT is not set
 # CONFIG_PKG_USING_VT100 is not set
@@ -783,6 +760,7 @@ CONFIG_NU_PKG_USING_UTILS=y
 # CONFIG_NU_PKG_USING_MAX31875 is not set
 # CONFIG_NU_PKG_USING_NAU88L25 is not set
 CONFIG_NU_PKG_USING_NAU8822=y
+# CONFIG_NU_PKG_USING_DA9062 is not set
 # CONFIG_NU_PKG_USING_ILI9341 is not set
 # CONFIG_NU_PKG_USING_SPINAND is not set
 

+ 2 - 2
bsp/nuvoton/nk-n9h30/board/Kconfig

@@ -28,9 +28,9 @@ menu "Hardware Drivers Config"
             default n
 
         config BOARD_USING_STORAGE_SDCARD
-            bool "SDCARD supporting(over sdh1)"
+            bool "SDCARD supporting(over sdh_p0)"
             select BSP_USING_SDH
-            select BSP_USING_SDH1
+            select BSP_USING_SDH0
             default y
 
         config BOARD_USING_STORAGE_SPIFLASH

+ 95 - 64
bsp/nuvoton/nk-rtu980/.config

@@ -7,6 +7,7 @@
 # RT-Thread Kernel
 #
 CONFIG_RT_NAME_MAX=16
+# CONFIG_RT_USING_BIG_ENDIAN is not set
 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set
 # CONFIG_RT_USING_SMP is not set
 CONFIG_RT_ALIGN_SIZE=4
@@ -21,6 +22,13 @@ CONFIG_RT_USING_IDLE_HOOK=y
 CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
 CONFIG_IDLE_THREAD_STACK_SIZE=2048
 # CONFIG_RT_USING_TIMER_SOFT is not set
+
+#
+# kservice optimization
+#
+# CONFIG_RT_KSERVICE_USING_STDLIB is not set
+# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
+# CONFIG_RT_USING_ASM_MEMCPY is not set
 CONFIG_RT_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -66,7 +74,8 @@ CONFIG_RT_USING_DEVICE=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=256
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
-CONFIG_RT_VER_NUM=0x40003
+# CONFIG_RT_PRINTF_LONGLONG is not set
+CONFIG_RT_VER_NUM=0x40004
 CONFIG_ARCH_ARM=y
 # CONFIG_RT_USING_CPU_FFS is not set
 CONFIG_ARCH_ARM_ARM9=y
@@ -89,19 +98,19 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # Command shell
 #
 CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
 CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
 CONFIG_FINSH_USING_HISTORY=y
 CONFIG_FINSH_HISTORY_LINES=5
 CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
-CONFIG_FINSH_THREAD_PRIORITY=20
-CONFIG_FINSH_THREAD_STACK_SIZE=4096
-CONFIG_FINSH_CMD_SIZE=80
 # CONFIG_FINSH_USING_AUTH is not set
-CONFIG_FINSH_USING_MSH=y
-CONFIG_FINSH_USING_MSH_DEFAULT=y
-# CONFIG_FINSH_USING_MSH_ONLY is not set
 CONFIG_FINSH_ARG_MAX=10
 
 #
@@ -135,11 +144,10 @@ CONFIG_RT_DFS_ELM_DRIVES=8
 CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
 # CONFIG_RT_DFS_ELM_USE_ERASE is not set
 CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000
 CONFIG_RT_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
-# CONFIG_RT_USING_DFS_UFFS is not set
-# CONFIG_RT_USING_DFS_JFFS2 is not set
 # CONFIG_RT_USING_DFS_NFS is not set
 
 #
@@ -151,6 +159,8 @@ CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
 CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
 CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
 CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
 CONFIG_RT_SERIAL_USING_DMA=y
 CONFIG_RT_SERIAL_RB_BUFSZ=2048
 CONFIG_RT_USING_CAN=y
@@ -179,7 +189,7 @@ CONFIG_RT_SFUD_USING_SFDP=y
 CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y
 CONFIG_RT_SFUD_USING_QSPI=y
 CONFIG_RT_SFUD_SPI_MAX_HZ=50000000
-CONFIG_RT_DEBUG_SFUD=y
+# CONFIG_RT_DEBUG_SFUD is not set
 # CONFIG_RT_USING_ENC28J60 is not set
 # CONFIG_RT_USING_SPI_WIFI is not set
 CONFIG_RT_USING_WDT=y
@@ -217,9 +227,11 @@ CONFIG_RT_HWCRYPTO_USING_RNG=y
 #
 # Using USB
 #
+CONFIG_RT_USING_USB=y
 CONFIG_RT_USING_USB_HOST=y
 CONFIG_RT_USBH_MSTORAGE=y
 CONFIG_UDISK_MOUNTPOINT="/mnt/udisk"
+# CONFIG_RT_USBH_HID is not set
 CONFIG_RT_USING_USB_DEVICE=y
 CONFIG_RT_USBD_THREAD_STACK_SZ=4096
 CONFIG_USB_VENDOR_ID=0x0FFE
@@ -245,13 +257,16 @@ CONFIG_RT_USB_MSTORAGE_DISK_NAME="ramdisk1"
 # POSIX layer and C standard library
 #
 CONFIG_RT_USING_LIBC=y
+CONFIG_RT_LIBC_USING_TIME=y
+# CONFIG_RT_LIBC_USING_FILEIO is not set
+# CONFIG_RT_USING_MODULE is not set
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_RT_USING_PTHREADS is not set
 CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_POSIX_MMAP is not set
 # CONFIG_RT_USING_POSIX_TERMIOS is not set
 # CONFIG_RT_USING_POSIX_GETLINE is not set
 # CONFIG_RT_USING_POSIX_AIO is not set
-# CONFIG_RT_USING_MODULE is not set
 
 #
 # Network
@@ -261,7 +276,7 @@ CONFIG_RT_USING_POSIX=y
 # Socket abstraction layer
 #
 CONFIG_RT_USING_SAL=y
-CONFIG_SAL_INTERNET_CHECK=y
+# CONFIG_SAL_INTERNET_CHECK is not set
 
 #
 # protocol stack implement
@@ -287,8 +302,9 @@ CONFIG_NETDEV_IPV6=0
 #
 CONFIG_RT_USING_LWIP=y
 # CONFIG_RT_USING_LWIP141 is not set
-CONFIG_RT_USING_LWIP202=y
-# CONFIG_RT_USING_LWIP212 is not set
+# CONFIG_RT_USING_LWIP202 is not set
+# CONFIG_RT_USING_LWIP203 is not set
+CONFIG_RT_USING_LWIP212=y
 # CONFIG_RT_USING_LWIP_IPV6 is not set
 CONFIG_RT_LWIP_MEM_ALIGNMENT=4
 CONFIG_RT_LWIP_IGMP=y
@@ -302,30 +318,30 @@ CONFIG_IP_SOF_BROADCAST_RECV=1
 #
 # Static IPv4 Address
 #
-CONFIG_RT_LWIP_IPADDR="192.168.1.30"
-CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_IPADDR="192.168.31.55"
+CONFIG_RT_LWIP_GWADDR="192.168.31.1"
 CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
 CONFIG_RT_LWIP_UDP=y
 CONFIG_RT_LWIP_TCP=y
 CONFIG_RT_LWIP_RAW=y
 # CONFIG_RT_LWIP_PPP is not set
-CONFIG_RT_MEMP_NUM_NETCONN=32
+CONFIG_RT_MEMP_NUM_NETCONN=16
 CONFIG_RT_LWIP_PBUF_NUM=256
-CONFIG_RT_LWIP_RAW_PCB_NUM=32
-CONFIG_RT_LWIP_UDP_PCB_NUM=32
-CONFIG_RT_LWIP_TCP_PCB_NUM=32
-CONFIG_RT_LWIP_TCP_SEG_NUM=256
-CONFIG_RT_LWIP_TCP_SND_BUF=32768
-CONFIG_RT_LWIP_TCP_WND=10240
+CONFIG_RT_LWIP_RAW_PCB_NUM=16
+CONFIG_RT_LWIP_UDP_PCB_NUM=16
+CONFIG_RT_LWIP_TCP_PCB_NUM=16
+CONFIG_RT_LWIP_TCP_SEG_NUM=64
+CONFIG_RT_LWIP_TCP_SND_BUF=16384
+CONFIG_RT_LWIP_TCP_WND=65535
 CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
-CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=256
 CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=4096
 # CONFIG_LWIP_NO_RX_THREAD is not set
 # CONFIG_LWIP_NO_TX_THREAD is not set
 CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
-CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
-CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
-# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=4096
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=256
+CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
 CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
 CONFIG_LWIP_NETIF_LINK_CALLBACK=1
 CONFIG_SO_REUSE=1
@@ -359,8 +375,15 @@ CONFIG_RT_LWIP_USING_PING=y
 CONFIG_RT_USING_UTEST=y
 CONFIG_UTEST_THR_STACK_SIZE=4096
 CONFIG_UTEST_THR_PRIORITY=20
+# CONFIG_RT_USING_VAR_EXPORT is not set
+# CONFIG_RT_USING_RT_LINK is not set
 # CONFIG_RT_USING_LWP is not set
 
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
+
 #
 # RT-Thread online packages
 #
@@ -444,8 +467,6 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_LIBRWS is not set
 # CONFIG_PKG_USING_TCPSERVER is not set
 # CONFIG_PKG_USING_PROTOBUF_C is not set
-# CONFIG_PKG_USING_ONNX_PARSER is not set
-# CONFIG_PKG_USING_ONNX_BACKEND is not set
 # CONFIG_PKG_USING_DLT645 is not set
 # CONFIG_PKG_USING_QXWZ is not set
 # CONFIG_PKG_USING_SMTP_CLIENT is not set
@@ -460,6 +481,12 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_BTSTACK is not set
 # CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
 # CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
 
 #
 # security packages
@@ -485,9 +512,11 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_STEMWIN is not set
 # CONFIG_PKG_USING_WAVPLAYER is not set
 # CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
 # CONFIG_PKG_USING_HELIX is not set
 # CONFIG_PKG_USING_AZUREGUIX is not set
 # CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
 
 #
 # tools packages
@@ -511,13 +540,6 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_BS8116A is not set
 # CONFIG_PKG_USING_GPS_RMC is not set
 # CONFIG_PKG_USING_URLENCODE is not set
-# CONFIG_PKG_USING_UMCN is not set
-# CONFIG_PKG_USING_LWRB2RTT is not set
-# CONFIG_PKG_USING_CPU_USAGE is not set
-# CONFIG_PKG_USING_GBK2UTF8 is not set
-# CONFIG_PKG_USING_VCONSOLE is not set
-# CONFIG_PKG_USING_KDB is not set
-# CONFIG_PKG_USING_WAMR is not set
 
 #
 # system packages
@@ -526,7 +548,6 @@ CONFIG_PKG_NETUTILS_VER="v1.2.0"
 # CONFIG_PKG_USING_PERSIMMON is not set
 # CONFIG_PKG_USING_CAIRO is not set
 # CONFIG_PKG_USING_PIXMAN is not set
-# CONFIG_PKG_USING_LWEXT4 is not set
 # CONFIG_PKG_USING_PARTITION is not set
 CONFIG_PKG_USING_FAL=y
 CONFIG_PKG_FAL_PATH="/packages/system/fal"
@@ -550,6 +571,9 @@ CONFIG_PKG_FAL_VER_NUM=0x99999
 # CONFIG_PKG_USING_CMSIS is not set
 # CONFIG_PKG_USING_DFS_YAFFS is not set
 # CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
 # CONFIG_PKG_USING_THREAD_POOL is not set
 # CONFIG_PKG_USING_ROBOTS is not set
 # CONFIG_PKG_USING_EV is not set
@@ -575,11 +599,14 @@ CONFIG_PKG_RAMDISK_VER="latest"
 # CONFIG_PKG_USING_UC_MODBUS is not set
 # CONFIG_PKG_USING_PPOOL is not set
 # CONFIG_PKG_USING_OPENAMP is not set
-# CONFIG_PKG_USING_RT_PRINTF is not set
+# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
 # CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
 # CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
 # CONFIG_PKG_USING_QFPLIB_M3 is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
 
 #
 # peripheral libraries and drivers
@@ -642,6 +669,25 @@ CONFIG_PKG_RAMDISK_VER="latest"
 # CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
 # CONFIG_PKG_USING_VDEVICE is not set
 # CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
 
 #
 # miscellaneous packages
@@ -649,9 +695,8 @@ CONFIG_PKG_RAMDISK_VER="latest"
 # CONFIG_PKG_USING_LIBCSV is not set
 CONFIG_PKG_USING_OPTPARSE=y
 CONFIG_PKG_OPTPARSE_PATH="/packages/misc/optparse"
-CONFIG_PKG_USING_OPTPARSE_V100=y
-# CONFIG_PKG_USING_OPTPARSE_LATEST_VERSION is not set
-CONFIG_PKG_OPTPARSE_VER="v1.0.0"
+CONFIG_PKG_USING_OPTPARSE_LATEST_VERSION=y
+CONFIG_PKG_OPTPARSE_VER="latest"
 # CONFIG_OPTPARSE_USING_DEMO is not set
 # CONFIG_PKG_USING_FASTLZ is not set
 # CONFIG_PKG_USING_MINILZO is not set
@@ -676,43 +721,27 @@ CONFIG_PKG_OPTPARSE_VER="v1.0.0"
 # CONFIG_PKG_USING_NETWORK_SAMPLES is not set
 # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
-CONFIG_PKG_USING_VI=y
-CONFIG_PKG_VI_PATH="/packages/misc/vi"
-CONFIG_VI_MAX_LEN=4096
-# CONFIG_VI_ENABLE_8BIT is not set
-CONFIG_VI_ENABLE_COLON=y
-CONFIG_VI_ENABLE_YANKMARK=y
-CONFIG_VI_ENABLE_SEARCH=y
-CONFIG_VI_ENABLE_DOT_CMD=y
-CONFIG_VI_ENABLE_READONLY=y
-CONFIG_VI_ENABLE_SETOPTS=y
-CONFIG_VI_ENABLE_SET=y
-CONFIG_VI_ENABLE_VI_ASK_TERMINAL=y
-CONFIG_VI_ENABLE_UNDO=y
-CONFIG_VI_ENABLE_UNDO_QUEUE=y
-CONFIG_VI_UNDO_QUEUE_MAX=256
-CONFIG_PKG_USING_VI_LATEST_VERSION=y
-CONFIG_PKG_VI_VER="latest"
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_VI_LATEST_VERSION is not set
 # CONFIG_PKG_USING_KI is not set
-# CONFIG_PKG_USING_NNOM is not set
-# CONFIG_PKG_USING_LIBANN is not set
-# CONFIG_PKG_USING_ELAPACK is not set
 # CONFIG_PKG_USING_ARMv7M_DWT is not set
 # CONFIG_PKG_USING_VT100 is not set
-# CONFIG_PKG_USING_ULAPACK is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
 
 #
-# games: games run on RT-Thread console
+# entertainment: terminal games and other interesting software packages
 #
 # CONFIG_PKG_USING_THREES is not set
 # CONFIG_PKG_USING_2048 is not set
 # CONFIG_PKG_USING_SNAKE is not set
 # CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_ACLOCK is not set
 # CONFIG_PKG_USING_LWGPS is not set
-# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_COWSAY is not set
 
 #
 # Nuvoton Packages Config
@@ -723,6 +752,7 @@ CONFIG_NU_PKG_USING_DEMO=y
 # CONFIG_NU_PKG_USING_MAX31875 is not set
 # CONFIG_NU_PKG_USING_NAU88L25 is not set
 # CONFIG_NU_PKG_USING_NAU8822 is not set
+# CONFIG_NU_PKG_USING_DA9062 is not set
 # CONFIG_NU_PKG_USING_ILI9341 is not set
 # CONFIG_NU_PKG_USING_SPINAND is not set
 
@@ -801,6 +831,7 @@ CONFIG_BSP_USING_SPI1_NONE=y
 # CONFIG_BSP_USING_SPI1 is not set
 # CONFIG_BSP_USING_I2S is not set
 CONFIG_BSP_USING_QSPI=y
+CONFIG_BSP_USING_QSPI_PDMA=y
 CONFIG_BSP_USING_QSPI0=y
 CONFIG_BSP_USING_QSPI0_PDMA=y
 # CONFIG_BSP_USING_SCUART is not set

+ 1 - 1
bsp/qemu-virt64-aarch64/link.lds

@@ -148,4 +148,4 @@ SECTIONS
     .debug_varnames  0 : { *(.debug_varnames) }
 }
 
-__bss_size = (__bss_end - __bss_start)>>3;
+__bss_size = SIZEOF(.bss);

+ 1 - 1
bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h

@@ -13,7 +13,7 @@
 
 #include <rtthread.h>
 #include <rtdevice.h>
-#include <time.h>
+#include <sys/time.h>
 #include "bcm283x.h"
 
 struct rt_rtc_device

+ 1 - 1
bsp/raspberry-pi/raspi3-64/link.lds

@@ -137,4 +137,4 @@ SECTIONS
     .debug_varnames  0 : { *(.debug_varnames) }
 }
 
-__bss_size = (__bss_end - __bss_start)>>3;
+__bss_size = SIZEOF(.bss);

+ 1 - 1
bsp/raspberry-pi/raspi4-64/link.lds

@@ -137,4 +137,4 @@ SECTIONS
     .debug_varnames  0 : { *(.debug_varnames) }
 }
 
-__bss_size = (__bss_end - __bss_start)>>3;
+__bss_size = SIZEOF(.bss);

+ 38 - 0
bsp/stm32/stm32l496-st-nucleo/board/Kconfig

@@ -56,6 +56,44 @@ menu "On-chip Peripheral Drivers"
                 depends on BSP_USING_LPUART1 && RT_SERIAL_USING_DMA
                 default n
         endif
+    
+    menuconfig BSP_USING_I2C
+        bool "Enable I2C BUS"
+        default n
+        select RT_USING_I2C
+        select RT_USING_I2C_BITOPS
+        select RT_USING_PIN
+        if BSP_USING_I2C
+            menuconfig BSP_USING_I2C3
+                bool "Enable I2C3 BUS"
+                default y
+                if BSP_USING_I2C3
+                    comment "Notice: PC0 --> 32; PC1 --> 33" 
+                    config BSP_I2C3_SCL_PIN
+                        int "i2c3 scl pin number"
+                        range 1 176
+                        default 32
+                    config BSP_I2C3_SDA_PIN
+                        int "I2C3 sda pin number"
+                        range 1 176
+                        default 33
+                endif
+
+            menuconfig BSP_USING_I2C4
+                bool "Enable I2C4 BUS"
+                default n
+                if BSP_USING_I2C4
+                    comment "Notice: PC1 --> 33; PD6 --> 54" 
+                    config BSP_I2C4_SCL_PIN
+                        int "i2c4 scl pin number"
+                        range 1 176
+                        default 54
+                    config BSP_I2C4_SDA_PIN
+                        int "I2C4 sda pin number"
+                        range 1 176
+                        default 33
+                endif
+        endif
 
     config BSP_USING_ON_CHIP_FLASH
         bool "Enable on-chip FLASH"

+ 1 - 1
bsp/swm320-lq100/applications/main.c

@@ -169,7 +169,7 @@ MSH_CMD_EXPORT(pwm_sample, pwm sample);
 #endif
 
 #ifdef RT_USING_RTC
-#include <time.h>
+#include <sys/time.h>
 static int rtc_sample(int argc, char *argv[])
 {
     rt_err_t ret = RT_EOK;

+ 1 - 1
bsp/swm320/applications/main.c

@@ -169,7 +169,7 @@ MSH_CMD_EXPORT(pwm_sample, pwm sample);
 #endif
 
 #ifdef RT_USING_RTC
-#include <time.h>
+#include <sys/time.h>
 static int rtc_sample(int argc, char *argv[])
 {
     rt_err_t ret = RT_EOK;

+ 2 - 1
components/drivers/include/drivers/alarm.h

@@ -13,7 +13,8 @@
 #ifndef __ALARM_H__
 #define __ALARM_H__
 
-#include <time.h>
+#include <sys/time.h>
+#include <rtdef.h>
 
 #define RT_ALARM_TM_NOW        -1    /* set the alarm tm_day,tm_mon,tm_sec,etc.
                                         to now.we also call it "don't care" value */

+ 1 - 1
components/drivers/rtc/rtc.c

@@ -14,7 +14,7 @@
  * 2021-07-30     Meco Man     move rtc_core.c to rtc.c
  */
 
-#include <time.h>
+#include <sys/time.h>
 #include <string.h>
 #include <stdlib.h>
 #include <rtthread.h>

+ 84 - 0
components/drivers/src/dataqueue.c

@@ -21,6 +21,23 @@ struct rt_data_item
     rt_size_t data_size;
 };
 
+/**
+ * @brief    This function will initialize the data queue. Calling this function will
+ *           initialize the data queue control block and set the notification callback function.
+ *
+ * @param    queue is a pointer to the data queue object.
+ *
+ * @param    size is the maximum number of data in the data queue.
+ *
+ * @param    lwm is low water mark.
+ *           When the number of data in the data queue is less than this value, this function will
+ *           wake up the thread waiting for write data.
+ *
+ * @param    evt_notify is the notification callback function.
+ *
+ * @return   Return the operation status. When the return value is RT_EOK, the initialization is successful.
+ *           When the return value is RT_ENOMEM, it means insufficient memory allocation failed.
+ */
 rt_err_t
 rt_data_queue_init(struct rt_data_queue *queue,
                    rt_uint16_t size,
@@ -54,6 +71,21 @@ rt_data_queue_init(struct rt_data_queue *queue,
 }
 RTM_EXPORT(rt_data_queue_init);
 
+/**
+ * @brief    This function will write data to the data queue. If the data queue is full,
+ *           the thread will suspend for the specified amount of time.
+ *
+ * @param    queue is a pointer to the data queue object.
+ * .
+ * @param    data_ptr is the buffer pointer of the data to be written.
+ *
+ * @param    size is the size in bytes of the data to be written.
+ *
+ * @param    timeout is the waiting time.
+ *
+ * @return   Return the operation status. When the return value is RT_EOK, the operation is successful.
+ *           When the return value is RT_ETIMEOUT, it means the specified time out.
+ */
 rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
                             const void *data_ptr,
                             rt_size_t data_size,
@@ -153,6 +185,24 @@ __exit:
 }
 RTM_EXPORT(rt_data_queue_push);
 
+/**
+ * @brief    This function will pop data from the data queue. If the data queue is empty,the thread
+ *           will suspend for the specified amount of time.
+ *
+ * @note     When the number of data in the data queue is less than lwm(low water mark), will
+ *           wake up the thread waiting for write data.
+ *
+ * @param    queue is a pointer to the data queue object.
+ *
+ * @param    data_ptr is the buffer pointer of the data to be fetched.
+ *
+ * @param    size is the size in bytes of the data to be fetched.
+ *
+ * @param    timeout is the waiting time.
+ *
+ * @return   Return the operation status. When the return value is RT_EOK, the operation is successful.
+ *           When the return value is RT_ETIMEOUT, it means the specified time out.
+ */
 rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
                            const void** data_ptr,
                            rt_size_t *size,
@@ -264,6 +314,18 @@ __exit:
 }
 RTM_EXPORT(rt_data_queue_pop);
 
+/**
+ * @brief    This function will fetch but retaining data in the data queue.
+ *
+ * @param    queue is a pointer to the data queue object.
+ *
+ * @param    data_ptr is the buffer pointer of the data to be fetched.
+ *
+ * @param    size is the size in bytes of the data to be fetched.
+ *
+ * @return   Return the operation status. When the return value is RT_EOK, the operation is successful.
+ *           When the return value is -RT_EEMPTY, it means the data queue is empty.
+ */
 rt_err_t rt_data_queue_peek(struct rt_data_queue *queue,
                             const void** data_ptr,
                             rt_size_t *size)
@@ -289,6 +351,14 @@ rt_err_t rt_data_queue_peek(struct rt_data_queue *queue,
 }
 RTM_EXPORT(rt_data_queue_peek);
 
+/**
+ * @brief    This function will reset the data queue.
+ *
+ * @note     Calling this function will wake up all threads on the data queue
+ *           that are hanging and waiting.
+ *
+ * @param    queue is a pointer to the data queue object.
+ */
 void rt_data_queue_reset(struct rt_data_queue *queue)
 {
     rt_ubase_t  level;
@@ -362,6 +432,13 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
 }
 RTM_EXPORT(rt_data_queue_reset);
 
+/**
+ * @brief    This function will deinit the data queue.
+ *
+ * @param    queue is a pointer to the data queue object.
+ *
+ * @return   Return the operation status. When the return value is RT_EOK, the operation is successful.
+ */
 rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue)
 {
     rt_ubase_t level;
@@ -382,6 +459,13 @@ rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue)
 }
 RTM_EXPORT(rt_data_queue_deinit);
 
+/**
+ * @brief    This function will get the number of data in the data queue.
+ *
+ * @param    queue is a pointer to the data queue object.
+ *
+ * @return   Return the number of data in the data queue.
+ */
 rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue)
 {
     rt_ubase_t level;

+ 8 - 4
components/finsh/cmd.c

@@ -751,9 +751,9 @@ long list_timer(void)
 
     maxlen = RT_NAME_MAX;
 
-    rt_kprintf("%-*.s  periodic   timeout       flag\n", maxlen, item_title);
+    rt_kprintf("%-*.s  periodic   timeout    activated     mode\n", maxlen, item_title);
     object_split(maxlen);
-    rt_kprintf(" ---------- ---------- -----------\n");
+    rt_kprintf(" ---------- ---------- ----------- ---------\n");
     do
     {
         next = list_get_next(next, &find_arg);
@@ -781,9 +781,13 @@ long list_timer(void)
                            timer->init_tick,
                            timer->timeout_tick);
                 if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
-                    rt_kprintf("activated\n");
+                    rt_kprintf("activated   ");
                 else
-                    rt_kprintf("deactivated\n");
+                    rt_kprintf("deactivated ");
+                if (timer->parent.flag & RT_TIMER_FLAG_PERIODIC)
+                    rt_kprintf("periodic\n");
+                else
+                    rt_kprintf("one shot\n");
 
             }
         }

+ 1 - 1
components/net/at/at_socket/at_socket.c

@@ -1107,7 +1107,7 @@ static uint32_t ipstr_to_u32(char *ipstr)
 struct hostent *at_gethostbyname(const char *name)
 {
     struct at_device *device = RT_NULL;
-    ip_addr_t addr;
+    ip_addr_t addr = {0};
     char ipstr[16] = { 0 };
     /* buffer variables for at_gethostbyname() */
     static struct hostent s_hostent;

+ 1 - 1
examples/kernel/event_simple.c

@@ -15,7 +15,7 @@
  * 一个线程定时发送事件 (事件5)
  */
 #include <rtthread.h>
-#include <time.h>
+#include <sys/time.h>
 #include "tc_comm.h"
 
 /* 指向线程控制块的指针 */

+ 14 - 25
libcpu/aarch64/common/context_gcc.S

@@ -5,10 +5,11 @@
  *
  * Change Logs:
  * Date           Author       Notes
- * 2018-10-06     ZhaoXiaowei    the first version
+ * 2018-10-06     ZhaoXiaowei  the first version
+ * 2021-11-04     GuEe-GUI     set sp with SP_ELx
  */
 
-  /*
+/*
  *enable gtimer
  */
 .globl rt_hw_gtimer_enable
@@ -17,6 +18,14 @@ rt_hw_gtimer_enable:
 	MSR CNTP_CTL_EL0,X0
 	RET
 
+/*
+ *disable gtimer
+ */
+.globl rt_hw_gtimer_disable
+rt_hw_gtimer_disable:
+    MSR CNTP_CTL_EL0,XZR
+    RET
+
 /*
  *set gtimer CNTP_TVAL_EL0 value
  */
@@ -48,10 +57,6 @@ rt_hw_get_gtimer_frq:
 	RET
 
 .macro SAVE_CONTEXT
-
-    /* Switch to use the EL0 stack pointer. */
-    MSR 	SPSEL, #0
-
     /* Save the entire context. */
     STP 	X0, X1, [SP, #-0x10]!
     STP 	X2, X3, [SP, #-0x10]!
@@ -98,16 +103,9 @@ rt_hw_get_gtimer_frq:
 
     MOV 	X0, SP   /* Move SP into X0 for saving. */
 
-    /* Switch to use the ELx stack pointer. */
-    MSR 	SPSEL, #1
-
     .endm
 
 .macro SAVE_CONTEXT_T
-
-    /* Switch to use the EL0 stack pointer. */
-    MSR 	SPSEL, #0
-
     /* Save the entire context. */
     STP 	X0, X1, [SP, #-0x10]!
     STP 	X2, X3, [SP, #-0x10]!
@@ -135,15 +133,15 @@ rt_hw_get_gtimer_frq:
     B.EQ	1f
     B 		.
 3:
-    MRS		X3, SPSR_EL3
+    MOV		X3, 0x0d
     MOV		X2, X30
     B		0f
 2:
-    MRS		X3, SPSR_EL2
+    MOV		X3, 0x09
     MOV		X2, X30
     B		0f
 1:
-    MRS		X3, SPSR_EL1
+    MOV		X3, 0x05
     MOV		X2, X30
     B		0f
 0:
@@ -152,16 +150,10 @@ rt_hw_get_gtimer_frq:
 
     MOV 	X0, SP   /* Move SP into X0 for saving. */
 
-    /* Switch to use the ELx stack pointer. */
-    MSR 	SPSEL, #1
-
     .endm
 
 .macro RESTORE_CONTEXT
 
-    /* Switch to use the EL0 stack pointer. */
-    MSR 	SPSEL, #0
-
     /* Set the SP to point to the stack of the task being restored. */
     MOV		SP, X0
 
@@ -206,9 +198,6 @@ rt_hw_get_gtimer_frq:
     LDP 	X2, X3, [SP], #0x10
     LDP 	X0, X1, [SP], #0x10
 
-    /* Switch to use the ELx stack pointer.  _RB_ Might not be required. */
-    MSR 	SPSEL, #1
-
     ERET
 
     .endm

+ 4 - 3
libcpu/aarch64/common/stack.c

@@ -7,15 +7,16 @@
  * Date           Author       Notes
  * 2011-09-23     Bernard      the first version
  * 2011-10-05     Bernard      add thumb mode
+ * 2021-11-04     GuEe-GUI     set sp with SP_ELx
  */
 #include <rtthread.h>
 #include <board.h>
 
 #include <armv8.h>
 
-#define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_EL0)
-#define INITIAL_SPSR_EL2 (PSTATE_EL2 | SP_EL0)
-#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_EL0)
+#define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_ELx)
+#define INITIAL_SPSR_EL2 (PSTATE_EL2 | SP_ELx)
+#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_ELx)
 
 /**
  * This function will initialize thread stack

+ 1 - 1
libcpu/aarch64/common/vector_gcc.S

@@ -18,7 +18,7 @@ system_vectors:
 .align 11
     .set    VBAR, system_vectors
     .org    VBAR
-    // Exception from CurrentEL (EL1) with SP_EL0 (SPSEL=1)
+    // Exception from CurrentEL (EL1) with SP_EL0 (SPSEL=0)
     .org (VBAR + 0x00 + 0)
     B vector_error      // 			Synchronous
     .org (VBAR + 0x80 + 0)

+ 10 - 9
libcpu/aarch64/cortex-a/entry_point.S

@@ -6,6 +6,7 @@
  * Date           Author       Notes
  * 2020-01-15     bigmagic     the first version
  * 2020-08-10     SummerGift   support clang compiler
+ * 2021-11-04     GuEe-GUI     set sp with SP_ELx
  */
 
 .section ".text.entrypoint","ax"
@@ -32,14 +33,15 @@ cpu_setup:
     bne     cpu_not_in_el3
 
     /* Should never be executed, just for completeness. (EL3) */
-    mov     x0, #(1 << 0)           /* EL0 and EL1 are in Non-Secure state */
-    orr     x0, x0, #(1 << 4)       /* RES1 */
-    orr     x0, x0, #(1 << 5)       /* RES1 */
-    orr     x0, x0, #(1 << 7)       /* SMC instructions are undefined at EL1 and above */
-    orr     x0, x0, #(1 << 8)       /* HVC instructions are enabled at EL1 and above */
-    orr     x0, x0, #(1 << 10)      /* The next lower level is AArch64 */
+    mov     x2, #(1 << 0)           /* EL0 and EL1 are in Non-Secure state */
+    orr     x2, x2, #(1 << 4)       /* RES1 */
+    orr     x2, x2, #(1 << 5)       /* RES1 */
+    orr     x2, x2, #(1 << 7)       /* SMC instructions are undefined at EL1 and above */
+    orr     x2, x2, #(1 << 8)       /* HVC instructions are enabled at EL1 and above */
+    orr     x2, x2, #(1 << 10)      /* The next lower level is AArch64 */
     msr     scr_el3, x2
 
+    /* Change execution level to EL2 */
     mov     x2, #0x3c9
     msr     spsr_el3, x2            /* 0b1111001001 */
     adr     x2, cpu_not_in_el3
@@ -51,8 +53,6 @@ cpu_not_in_el3:                     /* Running at EL2 or EL1 */
     beq     cpu_in_el1              /* Halt this core if running in El1 */
 
 cpu_in_el2:
-    msr     sp_el1, x1
-
     /* Enable CNTP for EL1 */
     mrs     x0, cnthctl_el2         /* Counter-timer Hypervisor Control register */
     orr     x0, x0, #3
@@ -71,6 +71,7 @@ cpu_in_el2:
     eret
 
 cpu_in_el1:
+    msr     spsel, #1
     mov     sp, x1                  /* Set sp in el1 */
 
     /* Avoid trap from SIMD or float point instruction */
@@ -89,7 +90,7 @@ cpu_in_el1:
 clean_bss_loop:
     cbz     w2, jump_to_entry
     str     xzr, [x1], #8
-    sub     w2, w2, #1
+    sub     w2, w2, #8
     cbnz    w2, clean_bss_loop
 
 jump_to_entry:

+ 111 - 111
src/Kconfig

@@ -115,37 +115,40 @@ config RT_USING_TIMER_SOFT
         thread.
 
 if RT_USING_TIMER_SOFT
-config RT_TIMER_THREAD_PRIO
-    int "The priority level value of timer thread"
-    default 4
-
-config RT_TIMER_THREAD_STACK_SIZE
-    int "The stack size of timer thread"
-    default 512
+    config RT_TIMER_THREAD_PRIO
+        int "The priority level value of timer thread"
+        default 4
 
+    config RT_TIMER_THREAD_STACK_SIZE
+        int "The stack size of timer thread"
+        default 512
 endif
 
 menu "kservice optimization"
 
-config RT_KSERVICE_USING_STDLIB
-    bool "Enable kservice to use standard C library"
-    default n
+    config RT_KSERVICE_USING_STDLIB
+        bool "Enable kservice to use standard C library"
+        default n
 
-config RT_KSERVICE_USING_TINY_SIZE
-    bool "Enable kservice to use tiny size"
-    default n
+    config RT_KSERVICE_USING_TINY_SIZE
+        bool "Enable kservice to use tiny size"
+        default n
 
-config RT_USING_ASM_MEMCPY
-    bool
-    default n
+    config RT_USING_ASM_MEMCPY
+        bool
+        default n
 
-config RT_USING_ASM_MEMSET
-    bool
-    default n
+    config RT_USING_ASM_MEMSET
+        bool
+        default n
 
-config RT_USING_TINY_FFS
-    bool "Enable kservice to use tiny ffs"
-    default n
+    config RT_USING_TINY_FFS
+        bool "Enable kservice to use tiny finding first bit set method"
+        default n
+
+    config RT_PRINTF_LONGLONG
+        bool "Enable rt_printf-family functions to support long long format"
+        default n
 
 endmenu
 
@@ -155,121 +158,122 @@ menuconfig RT_DEBUG
 
 if RT_DEBUG
 
-config RT_DEBUG_COLOR
-    bool "Enable color debugging log"
-    default n
+    config RT_DEBUG_COLOR
+        bool "Enable color debugging log"
+        default n
 
-config RT_DEBUG_INIT_CONFIG
-    bool "Enable debugging of components initialization"
-    default n
+    config RT_DEBUG_INIT_CONFIG
+        bool "Enable debugging of components initialization"
+        default n
 
-config RT_DEBUG_INIT
-    int
-    default 1 if RT_DEBUG_INIT_CONFIG
+    config RT_DEBUG_INIT
+        int
+        default 1 if RT_DEBUG_INIT_CONFIG
 
-config RT_DEBUG_THREAD_CONFIG
-    bool "Enable debugging of Thread State Changes"
-    default n
+    config RT_DEBUG_THREAD_CONFIG
+        bool "Enable debugging of Thread State Changes"
+        default n
 
-config RT_DEBUG_THREAD
-    int
-    default 1 if RT_DEBUG_THREAD_CONFIG
+    config RT_DEBUG_THREAD
+        int
+        default 1 if RT_DEBUG_THREAD_CONFIG
 
-config RT_DEBUG_SCHEDULER_CONFIG
-    bool "Enable debugging of Scheduler"
-    default n
+    config RT_DEBUG_SCHEDULER_CONFIG
+        bool "Enable debugging of Scheduler"
+        default n
 
-config RT_DEBUG_SCHEDULER
-    int
-    default 1 if RT_DEBUG_SCHEDULER_CONFIG
+    config RT_DEBUG_SCHEDULER
+        int
+        default 1 if RT_DEBUG_SCHEDULER_CONFIG
 
-config RT_DEBUG_IPC_CONFIG
-    bool "Enable debugging of IPC"
-    default n
+    config RT_DEBUG_IPC_CONFIG
+        bool "Enable debugging of IPC"
+        default n
 
-config RT_DEBUG_IPC
-    int
-    default 1 if RT_DEBUG_IPC_CONFIG
+    config RT_DEBUG_IPC
+        int
+        default 1 if RT_DEBUG_IPC_CONFIG
 
-config RT_DEBUG_TIMER_CONFIG
-    bool "Enable debugging of Timer"
-    default n
+    config RT_DEBUG_TIMER_CONFIG
+        bool "Enable debugging of Timer"
+        default n
 
-config RT_DEBUG_TIMER
-    int
-    default 1 if RT_DEBUG_TIMER_CONFIG
+    config RT_DEBUG_TIMER
+        int
+        default 1 if RT_DEBUG_TIMER_CONFIG
 
-config RT_DEBUG_IRQ_CONFIG
-    bool "Enable debugging of IRQ(Interrupt Request)"
-    default n
+    config RT_DEBUG_IRQ_CONFIG
+        bool "Enable debugging of IRQ(Interrupt Request)"
+        default n
 
-config RT_DEBUG_IRQ
-    int
-    default 1 if RT_DEBUG_IRQ_CONFIG
+    config RT_DEBUG_IRQ
+        int
+        default 1 if RT_DEBUG_IRQ_CONFIG
 
-config RT_DEBUG_MEM_CONFIG
-    bool "Enable debugging of Small Memory Algorithm"
-    default n
+    config RT_DEBUG_MEM_CONFIG
+        bool "Enable debugging of Small Memory Algorithm"
+        default n
 
-config RT_DEBUG_MEM
-    int
-    default 1 if RT_DEBUG_MEM_CONFIG
+    config RT_DEBUG_MEM
+        int
+        default 1 if RT_DEBUG_MEM_CONFIG
 
-config RT_DEBUG_SLAB_CONFIG
-    bool "Enable debugging of SLAB Memory Algorithm"
-    default n
+    config RT_DEBUG_SLAB_CONFIG
+        bool "Enable debugging of SLAB Memory Algorithm"
+        default n
 
-config RT_DEBUG_SLAB
-    int
-    default 1 if RT_DEBUG_SLAB_CONFIG
+    config RT_DEBUG_SLAB
+        int
+        default 1 if RT_DEBUG_SLAB_CONFIG
 
-config RT_DEBUG_MEMHEAP_CONFIG
-    bool "Enable debugging of Memory Heap Algorithm"
-    default n
+    config RT_DEBUG_MEMHEAP_CONFIG
+        bool "Enable debugging of Memory Heap Algorithm"
+        default n
 
-config RT_DEBUG_MEMHEAP
-    int
-    default 1 if RT_DEBUG_MEMHEAP_CONFIG
+    config RT_DEBUG_MEMHEAP
+        int
+        default 1 if RT_DEBUG_MEMHEAP_CONFIG
 
-config RT_DEBUG_MODULE_CONFIG
-    bool "Enable debugging of Application Module"
-    default n
+    config RT_DEBUG_MODULE_CONFIG
+        bool "Enable debugging of Application Module"
+        default n
 
-config RT_DEBUG_MODULE
-    int
-    default 1 if RT_DEBUG_MODULE_CONFIG
+    config RT_DEBUG_MODULE
+        int
+        default 1 if RT_DEBUG_MODULE_CONFIG
 
 endif
 
 menu "Inter-Thread communication"
 
-config RT_USING_SEMAPHORE
-    bool "Enable semaphore"
-    default y
+    config RT_USING_SEMAPHORE
+        bool "Enable semaphore"
+        default y
 
-config RT_USING_MUTEX
-    bool "Enable mutex"
-    default y
+    config RT_USING_MUTEX
+        bool "Enable mutex"
+        default y
 
-config RT_USING_EVENT
-    bool "Enable event flag"
-    default y
+    config RT_USING_EVENT
+        bool "Enable event flag"
+        default y
 
-config RT_USING_MAILBOX
-    bool "Enable mailbox"
-    default y
+    config RT_USING_MAILBOX
+        bool "Enable mailbox"
+        default y
 
-config RT_USING_MESSAGEQUEUE
-    bool "Enable message queue"
-    default y
+    config RT_USING_MESSAGEQUEUE
+        bool "Enable message queue"
+        default y
+
+    config RT_USING_SIGNALS
+        bool "Enable signals"
+        select RT_USING_MEMPOOL
+        default n
+        help
+            A signal is an asynchronous notification sent to a specific thread
+            in order to notify it of an event that occurred.
 
-config RT_USING_SIGNALS
-    bool "Enable signals"
-    select RT_USING_MEMPOOL
-    default n
-    help
-        A signal is an asynchronous notification sent to a specific thread
-        in order to notify it of an event that occurred.
 endmenu
 
 menu "Memory Management"
@@ -375,10 +379,6 @@ menu "Kernel Device Object"
         config RT_CONSOLE_DEVICE_NAME
             string "the device name for console"
             default "uart"
-
-        config RT_PRINTF_LONGLONG
-            bool "rt_kprintf support long long"
-            default n
     endif
 
 endmenu

+ 13 - 31
src/kservice.c

@@ -593,7 +593,6 @@ RTM_EXPORT(rt_show_version);
 /* private function */
 #define _ISDIGIT(c)  ((unsigned)((c) - '0') < 10)
 
-#ifdef RT_PRINTF_LONGLONG
 /**
  * This function will duplicate a string.
  *
@@ -603,44 +602,38 @@ RTM_EXPORT(rt_show_version);
  *
  * @return the duplicated string pointer.
  */
+#ifdef RT_PRINTF_LONGLONG
 rt_inline int divide(long long *n, int base)
+#else
+rt_inline int divide(long *n, int base)
+#endif /* RT_PRINTF_LONGLONG */
 {
     int res;
 
     /* optimized for processor which does not support divide instructions. */
     if (base == 10)
     {
+#ifdef RT_PRINTF_LONGLONG
         res = (int)(((unsigned long long)*n) % 10U);
         *n = (long long)(((unsigned long long)*n) / 10U);
-    }
-    else
-    {
-        res = (int)(((unsigned long long)*n) % 16U);
-        *n = (long long)(((unsigned long long)*n) / 16U);
-    }
-
-    return res;
-}
 #else
-rt_inline int divide(long *n, int base)
-{
-    int res;
-
-    /* optimized for processor which does not support divide instructions. */
-    if (base == 10)
-    {
         res = (int)(((unsigned long)*n) % 10U);
         *n = (long)(((unsigned long)*n) / 10U);
+#endif
     }
     else
     {
+#ifdef RT_PRINTF_LONGLONG
+        res = (int)(((unsigned long long)*n) % 16U);
+        *n = (long long)(((unsigned long long)*n) / 16U);
+#else
         res = (int)(((unsigned long)*n) % 16U);
         *n = (long)(((unsigned long)*n) / 16U);
+#endif
     }
 
     return res;
 }
-#endif /* RT_PRINTF_LONGLONG */
 
 rt_inline int skip_atoi(const char **s)
 {
@@ -659,7 +652,6 @@ rt_inline int skip_atoi(const char **s)
 #define SPECIAL     (1 << 5)    /* 0x */
 #define LARGE       (1 << 6)    /* use 'ABCDEF' instead of 'abcdef' */
 
-#ifdef RT_PRINTF_PRECISION
 static char *print_number(char *buf,
                           char *end,
 #ifdef RT_PRINTF_LONGLONG
@@ -669,20 +661,10 @@ static char *print_number(char *buf,
 #endif /* RT_PRINTF_LONGLONG */
                           int   base,
                           int   s,
+#ifdef RT_PRINTF_PRECISION
                           int   precision,
-                          int   type)
-#else
-static char *print_number(char *buf,
-                          char *end,
-#ifdef RT_PRINTF_LONGLONG
-                          long long  num,
-#else
-                          long  num,
-#endif /* RT_PRINTF_LONGLONG */
-                          int   base,
-                          int   s,
-                          int   type)
 #endif /* RT_PRINTF_PRECISION */
+                          int   type)
 {
     char c, sign;
 #ifdef RT_PRINTF_LONGLONG

+ 1 - 0
src/thread.c

@@ -31,6 +31,7 @@
 
 #include <rthw.h>
 #include <rtthread.h>
+#include <stddef.h>
 
 #ifdef RT_USING_HOOK
 static void (*rt_thread_suspend_hook)(rt_thread_t thread);

+ 2 - 2
src/timer.c

@@ -560,12 +560,12 @@ rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
         if(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
         {
             /*timer is start and run*/
-            *(rt_tick_t *)arg = RT_TIMER_FLAG_ACTIVATED;
+            *(rt_uint32_t *)arg = RT_TIMER_FLAG_ACTIVATED;
         }
         else
         {
             /*timer is stop*/
-            *(rt_tick_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
+            *(rt_uint32_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
         }
         break;
 

+ 36 - 11
tools/building.py

@@ -616,6 +616,17 @@ def MergeGroup(src_group, group):
         else:
             src_group['LOCAL_ASFLAGS'] = group['LOCAL_ASFLAGS']
 
+def _PretreatListParameters(target_list):
+    while '' in target_list: # remove null strings
+        target_list.remove('')
+    while ' ' in target_list: # remove ' '
+        target_list.remove(' ')
+
+    if(len(target_list) == 0):
+        return False # ignore this list, don't add this list to the parameter
+
+    return True # permit to add this list to the parameter
+
 def DefineGroup(name, src, depend, **parameters):
     global Env
     if not GetDepend(depend):
@@ -640,19 +651,29 @@ def DefineGroup(name, src, depend, **parameters):
         group['src'] = src
 
     if 'CCFLAGS' in group:
-        Env.AppendUnique(CCFLAGS = group['CCFLAGS'])
+        target = group['CCFLAGS']
+        if len(target) > 0:
+            Env.AppendUnique(CCFLAGS = target)
     if 'CPPPATH' in group:
-        paths = []
-        for item in group['CPPPATH']:
-            paths.append(os.path.abspath(item))
-        group['CPPPATH'] = paths
-        Env.AppendUnique(CPPPATH = group['CPPPATH'])
+        target = group['CPPPATH']
+        if _PretreatListParameters(target) == True:
+            paths = []
+            for item in target:
+                paths.append(os.path.abspath(item))
+            target = paths
+            Env.AppendUnique(CPPPATH = target)
     if 'CPPDEFINES' in group:
-        Env.AppendUnique(CPPDEFINES = group['CPPDEFINES'])
+        target = group['CPPDEFINES']
+        if _PretreatListParameters(target) == True:
+            Env.AppendUnique(CPPDEFINES = target)
     if 'LINKFLAGS' in group:
-        Env.AppendUnique(LINKFLAGS = group['LINKFLAGS'])
+        target = group['LINKFLAGS']
+        if len(target) > 0:
+            Env.AppendUnique(LINKFLAGS = target)
     if 'ASFLAGS' in group:
-        Env.AppendUnique(ASFLAGS = group['ASFLAGS'])
+        target = group['ASFLAGS']
+        if len(target) > 0:
+            Env.AppendUnique(ASFLAGS = target)
     if 'LOCAL_CPPPATH' in group:
         paths = []
         for item in group['LOCAL_CPPPATH']:
@@ -675,9 +696,13 @@ def DefineGroup(name, src, depend, **parameters):
                 os.unlink(fn)
 
     if 'LIBS' in group:
-        Env.AppendUnique(LIBS = group['LIBS'])
+        target = group['LIBS']
+        if _PretreatListParameters(target) == True:
+            Env.AppendUnique(LIBS = target)
     if 'LIBPATH' in group:
-        Env.AppendUnique(LIBPATH = group['LIBPATH'])
+        target = group['LIBPATH']
+        if _PretreatListParameters(target) == True:
+            Env.AppendUnique(LIBPATH = target)
 
     # check whether to build group library
     if 'LIBRARY' in group: