瀏覽代碼

[bsp][hpmicro] upgrade hpm_sdk to v1.6.0

- upgraded hpm_sdk to v1.6.0

Signed-off-by: Fan YANG <fan.yang@hpmicro.com>
Fan YANG 9 月之前
父節點
當前提交
e19b63e5fb
共有 100 個文件被更改,包括 11560 次插入530 次删除
  1. 1 1
      bsp/hpmicro/hpm5300evk/SConstruct
  2. 11 0
      bsp/hpmicro/hpm5300evk/board/rtt_board.c
  3. 1 0
      bsp/hpmicro/hpm5300evk/rtconfig.py
  4. 1 1
      bsp/hpmicro/hpm5301evklite/SConstruct
  5. 1 0
      bsp/hpmicro/hpm5301evklite/rtconfig.py
  6. 125 31
      bsp/hpmicro/hpm6200evk/.config
  7. 1 1
      bsp/hpmicro/hpm6200evk/SConstruct
  8. 2 3
      bsp/hpmicro/hpm6200evk/board/board.c
  9. 11 0
      bsp/hpmicro/hpm6200evk/board/rtt_board.c
  10. 77 11
      bsp/hpmicro/hpm6200evk/rtconfig.h
  11. 1 0
      bsp/hpmicro/hpm6200evk/rtconfig.py
  12. 1 1
      bsp/hpmicro/hpm6300evk/SConstruct
  13. 13 18
      bsp/hpmicro/hpm6300evk/board/board.c
  14. 11 0
      bsp/hpmicro/hpm6300evk/board/rtt_board.c
  15. 1 0
      bsp/hpmicro/hpm6300evk/rtconfig.py
  16. 1 1
      bsp/hpmicro/hpm6750evk/SConstruct
  17. 11 14
      bsp/hpmicro/hpm6750evk/board/board.c
  18. 1 0
      bsp/hpmicro/hpm6750evk/rtconfig.py
  19. 39 10
      bsp/hpmicro/hpm6750evk2/.config
  20. 1 1
      bsp/hpmicro/hpm6750evk2/SConstruct
  21. 11 14
      bsp/hpmicro/hpm6750evk2/board/board.c
  22. 6 4
      bsp/hpmicro/hpm6750evk2/rtconfig.h
  23. 2 1
      bsp/hpmicro/hpm6750evk2/rtconfig.py
  24. 1 1
      bsp/hpmicro/hpm6750evkmini/SConstruct
  25. 12 15
      bsp/hpmicro/hpm6750evkmini/board/board.c
  26. 1 0
      bsp/hpmicro/hpm6750evkmini/rtconfig.py
  27. 1 1
      bsp/hpmicro/hpm6800evk/SConstruct
  28. 11 0
      bsp/hpmicro/hpm6800evk/board/rtt_board.c
  29. 1 0
      bsp/hpmicro/hpm6800evk/rtconfig.py
  30. 1 1
      bsp/hpmicro/libraries/drivers/SConscript
  31. 19 2
      bsp/hpmicro/libraries/drivers/drv_adc.c
  32. 2 2
      bsp/hpmicro/libraries/drivers/drv_can.c
  33. 6 7
      bsp/hpmicro/libraries/drivers/drv_enet.c
  34. 38 35
      bsp/hpmicro/libraries/drivers/drv_gpio.c
  35. 3 98
      bsp/hpmicro/libraries/drivers/drv_i2c.c
  36. 126 26
      bsp/hpmicro/libraries/drivers/drv_pwm.c
  37. 13 0
      bsp/hpmicro/libraries/drivers/drv_sdio.c
  38. 92 2
      bsp/hpmicro/libraries/drivers/drv_spi.c
  39. 24 2
      bsp/hpmicro/libraries/drivers/drv_uart_v2.c
  40. 254 1
      bsp/hpmicro/libraries/hpm_sdk/CHANGELOG.md
  41. 18 5
      bsp/hpmicro/libraries/hpm_sdk/SConscript
  42. 5 5
      bsp/hpmicro/libraries/hpm_sdk/components/SConscript
  43. 405 0
      bsp/hpmicro/libraries/hpm_sdk/components/codec/wm8978/hpm_wm8978.c
  44. 215 0
      bsp/hpmicro/libraries/hpm_sdk/components/codec/wm8978/hpm_wm8978.h
  45. 549 0
      bsp/hpmicro/libraries/hpm_sdk/components/codec/wm8978/hpm_wm8978_regs.h
  46. 10 1
      bsp/hpmicro/libraries/hpm_sdk/components/debug_console/hpm_debug_console.c
  47. 2 2
      bsp/hpmicro/libraries/hpm_sdk/components/debug_console/hpm_debug_console.h
  48. 110 10
      bsp/hpmicro/libraries/hpm_sdk/components/dma_mgr/hpm_dma_mgr.c
  49. 82 16
      bsp/hpmicro/libraries/hpm_sdk/components/dma_mgr/hpm_dma_mgr.h
  50. 6 0
      bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/hpm_enet_phy_common.h
  51. 122 0
      bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/jl1111/hpm_jl1111.c
  52. 55 0
      bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/jl1111/hpm_jl1111.h
  53. 734 0
      bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/jl1111/hpm_jl1111_regs.h
  54. 139 0
      bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/cc10128007.c
  55. 354 0
      bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/mc10128007_31b.c
  56. 73 0
      bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/tm070rdh13.c
  57. 107 0
      bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/tm103xdgp01.c
  58. 271 0
      bsp/hpmicro/libraries/hpm_sdk/components/ppi/hpm_ppi.c
  59. 58 0
      bsp/hpmicro/libraries/hpm_sdk/components/ppi/hpm_ppi.h
  60. 824 0
      bsp/hpmicro/libraries/hpm_sdk/components/spi/hpm_spi.c
  61. 181 0
      bsp/hpmicro/libraries/hpm_sdk/components/spi/hpm_spi.h
  62. 5 0
      bsp/hpmicro/libraries/hpm_sdk/components/touch/ft5406/hpm_touch_ft5406.c
  63. 144 0
      bsp/hpmicro/libraries/hpm_sdk/components/touch/gt9xx/hpm_gt9xx.c
  64. 136 0
      bsp/hpmicro/libraries/hpm_sdk/components/touch/gt9xx/hpm_gt9xx.h
  65. 93 0
      bsp/hpmicro/libraries/hpm_sdk/components/touch/gt9xx/hpm_touch_gt9xx.c
  66. 5 5
      bsp/hpmicro/libraries/hpm_sdk/components/touch/hpm_touch.h
  67. 4 4
      bsp/hpmicro/libraries/hpm_sdk/components/usb/device/hpm_usb_device.c
  68. 30 4
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_adc16_drv.h
  69. 3 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_cam_drv.h
  70. 26 18
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_can_drv.h
  71. 435 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_clc_drv.h
  72. 60 52
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_common.h
  73. 1 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_dao_drv.h
  74. 1 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_dma_drv.h
  75. 75 2
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_dmav2_drv.h
  76. 13 3
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_enet_drv.h
  77. 347 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_esc_drv.h
  78. 4 6
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_ewdg_drv.h
  79. 4 4
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_femc_drv.h
  80. 62 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_ffa_drv.h
  81. 169 2
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_gptmr_drv.h
  82. 5 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_i2c_drv.h
  83. 2 2
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_lcdc_drv.h
  84. 283 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_lobs_drv.h
  85. 2 2
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_mbx_drv.h
  86. 61 27
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_mcan_drv.h
  87. 726 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_mtg_drv.h
  88. 24 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pixelmux_drv.h
  89. 44 4
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_plb_drv.h
  90. 13 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pllctlv2_drv.h
  91. 366 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_ppi_drv.h
  92. 20 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pwm_drv.h
  93. 1958 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pwmv2_drv.h
  94. 186 12
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_qeiv2_drv.h
  95. 676 0
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_qeov2_drv.h
  96. 90 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_rdc_drv.h
  97. 1 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_romapi_xpi_def.h
  98. 1 1
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_romapi_xpi_nor_def.h
  99. 6 3
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_rtc_drv.h
  100. 224 28
      bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_sdp_drv.h

+ 1 - 1
bsp/hpmicro/hpm5300evk/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 11 - 0
bsp/hpmicro/hpm5300evk/board/rtt_board.c

@@ -116,3 +116,14 @@ void rt_hw_cpu_reset(void)
 }
 
 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reset, reset the board);
+
+#ifdef RT_USING_CACHE
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_FLUSH) {
+        l1c_dc_flush((uint32_t)addr, size);
+    } else {
+        l1c_dc_invalidate((uint32_t)addr, size);
+    }
+}
+#endif

+ 1 - 0
bsp/hpmicro/hpm5300evk/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM5300'
 CHIP_NAME='HPM5361'
 
 CROSS_TOOL='gcc'

+ 1 - 1
bsp/hpmicro/hpm5301evklite/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 1 - 0
bsp/hpmicro/hpm5301evklite/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM5300'
 CHIP_NAME='HPM5301'
 
 CROSS_TOOL='gcc'

+ 125 - 31
bsp/hpmicro/hpm6200evk/.config

@@ -1,7 +1,3 @@
-#
-# Automatically generated file; DO NOT EDIT.
-# RT-Thread Configuration
-#
 
 #
 # RT-Thread Kernel
@@ -18,7 +14,6 @@ CONFIG_RT_THREAD_PRIORITY_32=y
 # CONFIG_RT_THREAD_PRIORITY_256 is not set
 CONFIG_RT_THREAD_PRIORITY_MAX=32
 CONFIG_RT_TICK_PER_SECOND=1000
-CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
 CONFIG_RT_HOOK_USING_FUNC_PTR=y
 # CONFIG_RT_USING_HOOKLIST is not set
@@ -28,15 +23,23 @@ CONFIG_IDLE_THREAD_STACK_SIZE=512
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
 CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
+# CONFIG_RT_USING_TIMER_ALL_SOFT is not set
+# CONFIG_RT_USING_CPU_USAGE_TRACER is not set
 
 #
 # kservice optimization
 #
-CONFIG_RT_KSERVICE_USING_STDLIB=y
-# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set
-# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
 # CONFIG_RT_USING_TINY_FFS is not set
-# CONFIG_RT_KPRINTF_USING_LONGLONG is not set
+# end of kservice optimization
+
+#
+# klibc optimization
+#
+# CONFIG_RT_KLIBC_USING_STDLIB is not set
+# CONFIG_RT_KLIBC_USING_TINY_SIZE is not set
+# CONFIG_RT_KLIBC_USING_PRINTF_LONGLONG is not set
+# end of klibc optimization
+
 # CONFIG_RT_USING_DEBUG is not set
 
 #
@@ -49,6 +52,7 @@ CONFIG_RT_USING_MAILBOX=y
 CONFIG_RT_USING_MESSAGEQUEUE=y
 # CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set
 # CONFIG_RT_USING_SIGNALS is not set
+# end of Inter-Thread communication
 
 #
 # Memory Management
@@ -65,6 +69,8 @@ CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
 # CONFIG_RT_USING_MEMTRACE is not set
 # CONFIG_RT_USING_HEAP_ISR is not set
 CONFIG_RT_USING_HEAP=y
+# end of Memory Management
+
 CONFIG_RT_USING_DEVICE=y
 # CONFIG_RT_USING_DEVICE_OPS is not set
 # CONFIG_RT_USING_INTERRUPT_INFO is not set
@@ -73,14 +79,10 @@ CONFIG_RT_USING_DEVICE=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=128
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
-CONFIG_RT_VER_NUM=0x50100
+CONFIG_RT_VER_NUM=0x50200
 # CONFIG_RT_USING_STDC_ATOMIC is not set
 CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32
-# CONFIG_RT_USING_CACHE is not set
-# CONFIG_RT_USING_HW_ATOMIC is not set
-# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
-# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
-# CONFIG_RT_USING_CPU_FFS is not set
+# end of RT-Thread Kernel
 
 #
 # RT-Thread Components
@@ -126,12 +128,15 @@ CONFIG_RT_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_RAMFS is not set
 # CONFIG_RT_USING_DFS_TMPFS is not set
 # CONFIG_RT_USING_DFS_MQUEUE is not set
+# end of DFS: device virtual file system
+
 # CONFIG_RT_USING_FAL is not set
 
 #
 # Device Drivers
 #
 # CONFIG_RT_USING_DM is not set
+# CONFIG_RT_USING_DEV_BUS is not set
 CONFIG_RT_USING_DEVICE_IPC=y
 CONFIG_RT_UNAMED_PIPE_NUMBER=64
 # CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
@@ -150,6 +155,8 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
 # CONFIG_RT_USING_ZERO is not set
 # CONFIG_RT_USING_RANDOM is not set
 # CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_PULSE_ENCODER is not set
+# CONFIG_RT_USING_INPUT_CAPTURE is not set
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_PM is not set
@@ -162,21 +169,13 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
 # CONFIG_RT_USING_TOUCH is not set
 # CONFIG_RT_USING_LCD is not set
 # CONFIG_RT_USING_HWCRYPTO is not set
-# CONFIG_RT_USING_PULSE_ENCODER is not set
-# CONFIG_RT_USING_INPUT_CAPTURE is not set
-# CONFIG_RT_USING_DEV_BUS is not set
 # CONFIG_RT_USING_WIFI is not set
 # CONFIG_RT_USING_VIRTIO is not set
 CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_KTIME is not set
 # CONFIG_RT_USING_HWTIMER is not set
-
-#
-# Using USB
-#
-# CONFIG_RT_USING_USB is not set
-# CONFIG_RT_USING_USB_HOST is not set
-# CONFIG_RT_USING_USB_DEVICE is not set
+# CONFIG_RT_USING_CHERRYUSB is not set
+# end of Device Drivers
 
 #
 # C/C++ and POSIX layer
@@ -194,6 +193,8 @@ CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y
 CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8
 CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0
 CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
+# end of Timezone and Daylight Saving Time
+# end of ISO-ANSI C layer
 
 #
 # POSIX (Portable Operating System Interface) layer
@@ -215,7 +216,11 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 #
 # Socket is in the 'Network' category
 #
+# end of Interprocess Communication (IPC)
+# end of POSIX (Portable Operating System Interface) layer
+
 # CONFIG_RT_USING_CPLUSPLUS is not set
+# end of C/C++ and POSIX layer
 
 #
 # Network
@@ -224,12 +229,14 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_RT_USING_NETDEV is not set
 # CONFIG_RT_USING_LWIP is not set
 # CONFIG_RT_USING_AT is not set
+# end of Network
 
 #
 # Memory protection
 #
 # CONFIG_RT_USING_MEM_PROTECTION is not set
 # CONFIG_RT_USING_HW_STACK_GUARD is not set
+# end of Memory protection
 
 #
 # Utilities
@@ -241,12 +248,25 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_RT_USING_RESOURCE_ID is not set
 # CONFIG_RT_USING_ADT is not set
 # CONFIG_RT_USING_RT_LINK is not set
+# end of Utilities
+
 # CONFIG_RT_USING_VBUS is not set
 
+#
+# Using USB legacy version
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+# end of Using USB legacy version
+
+# CONFIG_RT_USING_FDT is not set
+# end of RT-Thread Components
+
 #
 # RT-Thread Utestcases
 #
 # CONFIG_RT_USING_UTESTCASES is not set
+# end of RT-Thread Utestcases
 
 #
 # RT-Thread online packages
@@ -255,7 +275,6 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 #
 # IoT - internet of things
 #
-# CONFIG_PKG_USING_LWIP is not set
 # CONFIG_PKG_USING_LORAWAN_DRIVER is not set
 # CONFIG_PKG_USING_PAHOMQTT is not set
 # CONFIG_PKG_USING_UMQTT is not set
@@ -268,6 +287,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_WEBTERMINAL is not set
 # CONFIG_PKG_USING_FREEMODBUS is not set
 # CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set
 
 #
 # Wi-Fi
@@ -277,27 +297,35 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # Marvell WiFi
 #
 # CONFIG_PKG_USING_WLANMARVELL is not set
+# end of Marvell WiFi
 
 #
 # Wiced WiFi
 #
 # CONFIG_PKG_USING_WLAN_WICED is not set
+# end of Wiced WiFi
+
 # CONFIG_PKG_USING_RW007 is not set
 
 #
 # CYW43012 WiFi
 #
 # CONFIG_PKG_USING_WLAN_CYW43012 is not set
+# end of CYW43012 WiFi
 
 #
 # BL808 WiFi
 #
 # CONFIG_PKG_USING_WLAN_BL808 is not set
+# end of BL808 WiFi
 
 #
 # CYW43439 WiFi
 #
 # CONFIG_PKG_USING_WLAN_CYW43439 is not set
+# end of CYW43439 WiFi
+# end of Wi-Fi
+
 # CONFIG_PKG_USING_COAP is not set
 # CONFIG_PKG_USING_NOPOLL is not set
 # CONFIG_PKG_USING_NETUTILS is not set
@@ -320,6 +348,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
 # CONFIG_PKG_USING_JOYLINK is not set
 # CONFIG_PKG_USING_IOTSHARP_SDK is not set
+# end of IoT Cloud
+
 # CONFIG_PKG_USING_NIMBLE is not set
 # CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
 # CONFIG_PKG_USING_OTA_DOWNLOADER is not set
@@ -362,6 +392,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ZEPHYR_POLLING is not set
 # CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set
 # CONFIG_PKG_USING_LHC_MODBUS is not set
+# CONFIG_PKG_USING_QMODBUS is not set
+# end of IoT - internet of things
 
 #
 # security packages
@@ -372,6 +404,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_TINYCRYPT is not set
 # CONFIG_PKG_USING_TFM is not set
 # CONFIG_PKG_USING_YD_CRYPTO is not set
+# end of security packages
 
 #
 # language packages
@@ -387,18 +420,22 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_JSMN is not set
 # CONFIG_PKG_USING_AGILE_JSMN is not set
 # CONFIG_PKG_USING_PARSON is not set
+# end of JSON: JavaScript Object Notation, a lightweight data-interchange format
 
 #
 # XML: Extensible Markup Language
 #
 # CONFIG_PKG_USING_SIMPLE_XML is not set
 # CONFIG_PKG_USING_EZXML is not set
+# end of XML: Extensible Markup Language
+
 # CONFIG_PKG_USING_LUATOS_SOC is not set
 # CONFIG_PKG_USING_LUA is not set
 # CONFIG_PKG_USING_JERRYSCRIPT is not set
 # CONFIG_PKG_USING_MICROPYTHON is not set
 # CONFIG_PKG_USING_PIKASCRIPT is not set
 # CONFIG_PKG_USING_RTT_RUST is not set
+# end of language packages
 
 #
 # multimedia packages
@@ -410,12 +447,15 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_LVGL is not set
 # CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
 # CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
+# end of LVGL: powerful and easy-to-use embedded GUI library
 
 #
 # u8g2: a monochrome graphic library
 #
 # CONFIG_PKG_USING_U8G2_OFFICIAL is not set
 # CONFIG_PKG_USING_U8G2 is not set
+# end of u8g2: a monochrome graphic library
+
 # CONFIG_PKG_USING_OPENMV is not set
 # CONFIG_PKG_USING_MUPDF is not set
 # CONFIG_PKG_USING_STEMWIN is not set
@@ -435,6 +475,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_QRCODE is not set
 # CONFIG_PKG_USING_GUIENGINE is not set
 # CONFIG_PKG_USING_3GPP_AMRNB is not set
+# end of multimedia packages
 
 #
 # tools packages
@@ -483,6 +524,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
 # CONFIG_PKG_USING_VOFA_PLUS is not set
 # CONFIG_PKG_USING_ZDEBUG is not set
+# end of tools packages
 
 #
 # system packages
@@ -494,6 +536,9 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
 # CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
+# end of enhanced kernel services
+
+# CONFIG_PKG_USING_AUNITY is not set
 
 #
 # acceleration: Assembly language or algorithmic acceleration packages
@@ -501,6 +546,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # 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
+# end of acceleration: Assembly language or algorithmic acceleration packages
 
 #
 # CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
@@ -511,6 +557,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_CMSIS_NN is not set
 # CONFIG_PKG_USING_CMSIS_RTOS1 is not set
 # CONFIG_PKG_USING_CMSIS_RTOS2 is not set
+# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
 
 #
 # Micrium: Micrium software products porting for RT-Thread
@@ -521,6 +568,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_UC_CLK is not set
 # CONFIG_PKG_USING_UC_COMMON is not set
 # CONFIG_PKG_USING_UC_MODBUS is not set
+# end of Micrium: Micrium software products porting for RT-Thread
+
 # CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
 # CONFIG_PKG_USING_LITEOS_SDK is not set
 # CONFIG_PKG_USING_TZ_DATABASE is not set
@@ -568,6 +617,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_RTP is not set
 # CONFIG_PKG_USING_REB is not set
 # CONFIG_PKG_USING_R_RHEALSTONE is not set
+# end of system packages
 
 #
 # peripheral libraries and drivers
@@ -580,9 +630,27 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 #
 # STM32 HAL & SDK Drivers
 #
-# CONFIG_PKG_USING_STM32L4XX_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set
 # CONFIG_PKG_USING_STM32WB55_SDK is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
+# end of STM32 HAL & SDK Drivers
+
+#
+# Infineon HAL Packages
+#
+# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set
+# CONFIG_PKG_USING_INFINEON_CMSIS is not set
+# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set
+# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set
+# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set
+# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set
+# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set
+# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set
+# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set
+# CONFIG_PKG_USING_INFINEON_USBDEV is not set
+# end of Infineon HAL Packages
+
 # CONFIG_PKG_USING_BLUETRUM_SDK is not set
 # CONFIG_PKG_USING_EMBARC_BSP is not set
 # CONFIG_PKG_USING_ESP_IDF is not set
@@ -592,9 +660,12 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 #
 # CONFIG_PKG_USING_K210_SDK is not set
 # CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# end of Kendryte SDK
+
 # CONFIG_PKG_USING_NRF5X_SDK is not set
 # CONFIG_PKG_USING_NRFX is not set
 # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
+# end of HAL & SDK Drivers
 
 #
 # sensors drivers
@@ -664,6 +735,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ICM20608 is not set
 # CONFIG_PKG_USING_PAJ7620 is not set
 # CONFIG_PKG_USING_STHS34PF80 is not set
+# end of sensors drivers
 
 #
 # touch drivers
@@ -678,6 +750,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_XPT2046_TOUCH is not set
 # CONFIG_PKG_USING_CST816X is not set
 # CONFIG_PKG_USING_CST812T is not set
+# end of touch drivers
+
 # CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_BUTTON is not set
 # CONFIG_PKG_USING_PCF8574 is not set
@@ -750,6 +824,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_BT_MX01 is not set
 # CONFIG_PKG_USING_RGPOWER is not set
 # CONFIG_PKG_USING_SPI_TOOLS is not set
+# end of peripheral libraries and drivers
 
 #
 # AI packages
@@ -764,15 +839,18 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_QUEST is not set
 # CONFIG_PKG_USING_NAXOS is not set
 # CONFIG_PKG_USING_R_TINYMAIX is not set
+# end of AI packages
 
 #
 # Signal Processing and Control Algorithm Packages
 #
+# CONFIG_PKG_USING_APID is not set
 # CONFIG_PKG_USING_FIRE_PID_CURVE is not set
 # CONFIG_PKG_USING_QPID is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_DIGITALCTRL is not set
 # CONFIG_PKG_USING_KISSFFT is not set
+# end of Signal Processing and Control Algorithm Packages
 
 #
 # miscellaneous packages
@@ -781,6 +859,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 #
 # project laboratory
 #
+# end of project laboratory
 
 #
 # samples: kernel and components samples
@@ -789,6 +868,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
 # CONFIG_PKG_USING_NETWORK_SAMPLES is not set
 # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# end of samples: kernel and components samples
 
 #
 # entertainment: terminal games and other interesting software packages
@@ -804,6 +884,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_DONUT is not set
 # CONFIG_PKG_USING_COWSAY is not set
 # CONFIG_PKG_USING_MORSE is not set
+# end of entertainment: terminal games and other interesting software packages
+
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -837,6 +919,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_SOEM is not set
 # CONFIG_PKG_USING_QPARAM is not set
 # CONFIG_PKG_USING_CorevMCU_CLI is not set
+# end of miscellaneous packages
 
 #
 # Arduino libraries
@@ -852,6 +935,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set
 # CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
 # CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
+# end of Projects and Demos
 
 #
 # Sensors
@@ -991,6 +1075,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
 # CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
 # CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_JARZEBSKI_MPU6050 is not set
+# end of Sensors
 
 #
 # Display
@@ -1002,6 +1088,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set
 # CONFIG_PKG_USING_SEEED_TM1637 is not set
+# end of Display
 
 #
 # Timing
@@ -1010,6 +1097,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
 # CONFIG_PKG_USING_ARDUINO_TICKER is not set
 # CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set
+# end of Timing
 
 #
 # Data Processing
@@ -1017,6 +1105,8 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
 # CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
 # CONFIG_PKG_USING_ARDUINO_TENSORFLOW_LITE_MICRO is not set
+# CONFIG_PKG_USING_ARDUINO_RUNNINGMEDIAN is not set
+# end of Data Processing
 
 #
 # Data Storage
@@ -1027,6 +1117,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 #
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
+# end of Communication
 
 #
 # Device Control
@@ -1038,12 +1129,14 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set
 # CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
+# end of Device Control
 
 #
 # Other
 #
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set
+# end of Other
 
 #
 # Signal IO
@@ -1056,10 +1149,13 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
+# end of Signal IO
 
 #
 # Uncategorized
 #
+# end of Arduino libraries
+# end of RT-Thread online packages
 
 #
 # Hardware Drivers Config
@@ -1074,14 +1170,10 @@ CONFIG_BSP_USING_UART=y
 CONFIG_BSP_USING_UART0=y
 # CONFIG_BSP_UART0_RX_USING_DMA is not set
 # CONFIG_BSP_UART0_TX_USING_DMA is not set
-CONFIG_BSP_UART0_RX_DMA_CHANNEL=0
-CONFIG_BSP_UART0_TX_DMA_CHANNEL=1
 # CONFIG_BSP_USING_UART2 is not set
 # CONFIG_BSP_USING_UART6 is not set
 # CONFIG_BSP_USING_SPI is not set
 # CONFIG_BSP_USING_RTC is not set
-# CONFIG_BSP_USING_ETH is not set
-# CONFIG_BSP_USING_SDXC is not set
 # CONFIG_BSP_USING_GPTMR is not set
 # CONFIG_BSP_USING_I2C is not set
 # CONFIG_BSP_USING_XPI_FLASH is not set
@@ -1090,3 +1182,5 @@ CONFIG_BSP_UART0_TX_DMA_CHANNEL=1
 # CONFIG_BSP_USING_WDG is not set
 # CONFIG_BSP_USING_MCAN is not set
 # CONFIG_BSP_USING_ADC is not set
+# end of On-chip Peripheral Drivers
+# end of Hardware Drivers Config

+ 1 - 1
bsp/hpmicro/hpm6200evk/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 2 - 3
bsp/hpmicro/hpm6200evk/board/board.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 HPMicro
+ * Copyright (c) 2023-2024 HPMicro
  * SPDX-License-Identifier: BSD-3-Clause
  *
  *
@@ -8,7 +8,6 @@
 #include "board.h"
 #include "hpm_uart_drv.h"
 #include "hpm_gptmr_drv.h"
-#include "hpm_lcdc_drv.h"
 #include "hpm_i2c_drv.h"
 #include "hpm_gpio_drv.h"
 #include "pinmux.h"
@@ -520,7 +519,7 @@ void board_init_clock(void)
     clock_add_to_group(clock_mot2, 0);
     clock_add_to_group(clock_mot3, 0);
     clock_add_to_group(clock_acmp, 0);
-    clock_add_to_group(clock_msyn, 0);
+    clock_add_to_group(clock_synt, 0);
     clock_add_to_group(clock_lmm0, 0);
     clock_add_to_group(clock_lmm1, 0);
 

+ 11 - 0
bsp/hpmicro/hpm6200evk/board/rtt_board.c

@@ -116,3 +116,14 @@ void rt_hw_cpu_reset(void)
 }
 
 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reset, reset the board);
+
+#ifdef RT_USING_CACHE
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_FLUSH) {
+        l1c_dc_flush((uint32_t)addr, size);
+    } else {
+        l1c_dc_invalidate((uint32_t)addr, size);
+    }
+}
+#endif

+ 77 - 11
bsp/hpmicro/hpm6200evk/rtconfig.h

@@ -1,9 +1,6 @@
 #ifndef RT_CONFIG_H__
 #define RT_CONFIG_H__
 
-/* Automatically generated file; DO NOT EDIT. */
-/* RT-Thread Configuration */
-
 /* RT-Thread Kernel */
 
 #define RT_NAME_MAX 8
@@ -12,7 +9,6 @@
 #define RT_THREAD_PRIORITY_32
 #define RT_THREAD_PRIORITY_MAX 32
 #define RT_TICK_PER_SECOND 1000
-#define RT_USING_OVERFLOW_CHECK
 #define RT_USING_HOOK
 #define RT_HOOK_USING_FUNC_PTR
 #define RT_USING_IDLE_HOOK
@@ -24,7 +20,11 @@
 
 /* kservice optimization */
 
-#define RT_KSERVICE_USING_STDLIB
+/* end of kservice optimization */
+
+/* klibc optimization */
+
+/* end of klibc optimization */
 
 /* Inter-Thread communication */
 
@@ -33,6 +33,7 @@
 #define RT_USING_EVENT
 #define RT_USING_MAILBOX
 #define RT_USING_MESSAGEQUEUE
+/* end of Inter-Thread communication */
 
 /* Memory Management */
 
@@ -40,12 +41,14 @@
 #define RT_USING_SMALL_MEM
 #define RT_USING_SMALL_MEM_AS_HEAP
 #define RT_USING_HEAP
+/* end of Memory Management */
 #define RT_USING_DEVICE
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 128
 #define RT_CONSOLE_DEVICE_NAME "uart0"
-#define RT_VER_NUM 0x50100
+#define RT_VER_NUM 0x50200
 #define RT_BACKTRACE_LEVEL_MAX_NR 32
+/* end of RT-Thread Kernel */
 
 /* RT-Thread Components */
 
@@ -78,6 +81,7 @@
 #define DFS_FILESYSTEMS_MAX 4
 #define DFS_FILESYSTEM_TYPES_MAX 4
 #define RT_USING_DFS_DEVFS
+/* end of DFS: device virtual file system */
 
 /* Device Drivers */
 
@@ -88,9 +92,7 @@
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_RB_BUFSZ 64
 #define RT_USING_PIN
-
-/* Using USB */
-
+/* end of Device Drivers */
 
 /* C/C++ and POSIX layer */
 
@@ -102,6 +104,8 @@
 #define RT_LIBC_TZ_DEFAULT_HOUR 8
 #define RT_LIBC_TZ_DEFAULT_MIN 0
 #define RT_LIBC_TZ_DEFAULT_SEC 0
+/* end of Timezone and Daylight Saving Time */
+/* end of ISO-ANSI C layer */
 
 /* POSIX (Portable Operating System Interface) layer */
 
@@ -111,18 +115,30 @@
 
 /* Socket is in the 'Network' category */
 
+/* end of Interprocess Communication (IPC) */
+/* end of POSIX (Portable Operating System Interface) layer */
+/* end of C/C++ and POSIX layer */
 
 /* Network */
 
+/* end of Network */
 
 /* Memory protection */
 
+/* end of Memory protection */
 
 /* Utilities */
 
+/* end of Utilities */
+
+/* Using USB legacy version */
+
+/* end of Using USB legacy version */
+/* end of RT-Thread Components */
 
 /* RT-Thread Utestcases */
 
+/* end of RT-Thread Utestcases */
 
 /* RT-Thread online packages */
 
@@ -133,57 +149,78 @@
 
 /* Marvell WiFi */
 
+/* end of Marvell WiFi */
 
 /* Wiced WiFi */
 
+/* end of Wiced WiFi */
 
 /* CYW43012 WiFi */
 
+/* end of CYW43012 WiFi */
 
 /* BL808 WiFi */
 
+/* end of BL808 WiFi */
 
 /* CYW43439 WiFi */
 
+/* end of CYW43439 WiFi */
+/* end of Wi-Fi */
 
 /* IoT Cloud */
 
+/* end of IoT Cloud */
+/* end of IoT - internet of things */
 
 /* security packages */
 
+/* end of security packages */
 
 /* language packages */
 
 /* JSON: JavaScript Object Notation, a lightweight data-interchange format */
 
+/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */
 
 /* XML: Extensible Markup Language */
 
+/* end of XML: Extensible Markup Language */
+/* end of language packages */
 
 /* multimedia packages */
 
 /* LVGL: powerful and easy-to-use embedded GUI library */
 
+/* end of LVGL: powerful and easy-to-use embedded GUI library */
 
 /* u8g2: a monochrome graphic library */
 
+/* end of u8g2: a monochrome graphic library */
+/* end of multimedia packages */
 
 /* tools packages */
 
+/* end of tools packages */
 
 /* system packages */
 
 /* enhanced kernel services */
 
+/* end of enhanced kernel services */
 
 /* acceleration: Assembly language or algorithmic acceleration packages */
 
+/* end of acceleration: Assembly language or algorithmic acceleration packages */
 
 /* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
 
+/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
 
 /* Micrium: Micrium software products porting for RT-Thread */
 
+/* end of Micrium: Micrium software products porting for RT-Thread */
+/* end of system packages */
 
 /* peripheral libraries and drivers */
 
@@ -191,66 +228,95 @@
 
 /* STM32 HAL & SDK Drivers */
 
+/* end of STM32 HAL & SDK Drivers */
+
+/* Infineon HAL Packages */
+
+/* end of Infineon HAL Packages */
 
 /* Kendryte SDK */
 
+/* end of Kendryte SDK */
+/* end of HAL & SDK Drivers */
 
 /* sensors drivers */
 
+/* end of sensors drivers */
 
 /* touch drivers */
 
+/* end of touch drivers */
+/* end of peripheral libraries and drivers */
 
 /* AI packages */
 
+/* end of AI packages */
 
 /* Signal Processing and Control Algorithm Packages */
 
+/* end of Signal Processing and Control Algorithm Packages */
 
 /* miscellaneous packages */
 
 /* project laboratory */
 
+/* end of project laboratory */
+
 /* samples: kernel and components samples */
 
+/* end of samples: kernel and components samples */
 
 /* entertainment: terminal games and other interesting software packages */
 
+/* end of entertainment: terminal games and other interesting software packages */
+/* end of miscellaneous packages */
 
 /* Arduino libraries */
 
 
 /* Projects and Demos */
 
+/* end of Projects and Demos */
 
 /* Sensors */
 
+/* end of Sensors */
 
 /* Display */
 
+/* end of Display */
 
 /* Timing */
 
+/* end of Timing */
 
 /* Data Processing */
 
+/* end of Data Processing */
 
 /* Data Storage */
 
 /* Communication */
 
+/* end of Communication */
 
 /* Device Control */
 
+/* end of Device Control */
 
 /* Other */
 
+/* end of Other */
 
 /* Signal IO */
 
+/* end of Signal IO */
 
 /* Uncategorized */
 
+/* end of Arduino libraries */
+/* end of RT-Thread online packages */
+
 /* Hardware Drivers Config */
 
 #define SOC_HPM6000
@@ -260,7 +326,7 @@
 #define BSP_USING_GPIO
 #define BSP_USING_UART
 #define BSP_USING_UART0
-#define BSP_UART0_RX_DMA_CHANNEL 0
-#define BSP_UART0_TX_DMA_CHANNEL 1
+/* end of On-chip Peripheral Drivers */
+/* end of Hardware Drivers Config */
 
 #endif

+ 1 - 0
bsp/hpmicro/hpm6200evk/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM6200'
 CHIP_NAME='HPM6280'
 
 CROSS_TOOL='gcc'

+ 1 - 1
bsp/hpmicro/hpm6300evk/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 13 - 18
bsp/hpmicro/hpm6300evk/board/board.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
@@ -7,7 +7,6 @@
 #include "board.h"
 #include "hpm_uart_drv.h"
 #include "hpm_gptmr_drv.h"
-#include "hpm_lcdc_drv.h"
 #include "hpm_i2c_drv.h"
 #include "hpm_gpio_drv.h"
 #include "hpm_femc_drv.h"
@@ -458,7 +457,7 @@ void board_init_clock(void)
     clock_add_to_group(clock_mot1, 0);
     clock_add_to_group(clock_acmp, 0);
     clock_add_to_group(clock_dao, 0);
-    clock_add_to_group(clock_msyn, 0);
+    clock_add_to_group(clock_synt, 0);
     clock_add_to_group(clock_lmm0, 0);
     clock_add_to_group(clock_pdm, 0);
 
@@ -647,9 +646,10 @@ void _init_ext_ram(void)
     femc_sdram_config_t sdram_config = {0};
 
     femc_default_config(HPM_FEMC, &config);
-    config.dqs = FEMC_DQS_INTERNAL;
     femc_init(HPM_FEMC, &config);
 
+    femc_get_typical_sdram_config(HPM_FEMC, &sdram_config);
+
     sdram_config.bank_num = FEMC_SDRAM_BANK_NUM_4;
     sdram_config.prescaler = 0x3;
     sdram_config.burst_len_in_byte = 8;
@@ -657,18 +657,14 @@ void _init_ext_ram(void)
     sdram_config.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS;
     sdram_config.cas_latency = FEMC_SDRAM_CAS_LATENCY_3;
 
-    sdram_config.precharge_to_act_in_ns = 18;   /* Trp */
-    sdram_config.act_to_rw_in_ns = 18;          /* Trcd */
-    sdram_config.refresh_recover_in_ns = 70;     /* Trfc/Trc */
-    sdram_config.write_recover_in_ns = 12;      /* Twr/Tdpl */
-    sdram_config.cke_off_in_ns = 42;             /* Trcd */
-    sdram_config.act_to_precharge_in_ns = 42;   /* Tras */
-
-    sdram_config.self_refresh_recover_in_ns = 66;   /* Txsr */
-    sdram_config.refresh_to_refresh_in_ns = 66;     /* Trfc/Trc */
+    sdram_config.refresh_to_refresh_in_ns = 60;     /* Trc */
+    sdram_config.refresh_recover_in_ns = 60;        /* Trc */
+    sdram_config.act_to_precharge_in_ns = 42;       /* Tras */
+    sdram_config.act_to_rw_in_ns = 18;              /* Trcd */
+    sdram_config.precharge_to_act_in_ns = 18;       /* Trp */
     sdram_config.act_to_act_in_ns = 12;             /* Trrd */
-    sdram_config.idle_timeout_in_ns = 6;
-    sdram_config.cs_mux_pin = FEMC_IO_MUX_NOT_USED;
+    sdram_config.write_recover_in_ns = 12;          /* Twr/Tdpl */
+    sdram_config.self_refresh_recover_in_ns = 72;   /* Txsr */
 
     sdram_config.cs = BOARD_SDRAM_CS;
     sdram_config.base_address = BOARD_SDRAM_ADDRESS;
@@ -676,9 +672,8 @@ void _init_ext_ram(void)
     sdram_config.port_size = BOARD_SDRAM_PORT_SIZE;
     sdram_config.refresh_count = BOARD_SDRAM_REFRESH_COUNT;
     sdram_config.refresh_in_ms = BOARD_SDRAM_REFRESH_IN_MS;
-    sdram_config.data_width_in_byte = BOARD_SDRAM_DATA_WIDTH_IN_BYTE;
-    sdram_config.delay_cell_disable = false;
-    sdram_config.delay_cell_value = 29;
+    sdram_config.delay_cell_disable = true;
+    sdram_config.delay_cell_value = 0;
 
     femc_config_sdram(HPM_FEMC, femc_clk_in_hz, &sdram_config);
 }

+ 11 - 0
bsp/hpmicro/hpm6300evk/board/rtt_board.c

@@ -116,3 +116,14 @@ void rt_hw_cpu_reset(void)
 }
 
 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reset, reset the board);
+
+#ifdef RT_USING_CACHE
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_FLUSH) {
+        l1c_dc_flush((uint32_t)addr, size);
+    } else {
+        l1c_dc_invalidate((uint32_t)addr, size);
+    }
+}
+#endif

+ 1 - 0
bsp/hpmicro/hpm6300evk/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM6300'
 CHIP_NAME='HPM6360'
 
 CROSS_TOOL='gcc'

+ 1 - 1
bsp/hpmicro/hpm6750evk/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 11 - 14
bsp/hpmicro/hpm6750evk/board/board.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
@@ -717,7 +717,7 @@ void board_init_clock(void)
     clock_add_to_group(clock_mot3, 0);
     clock_add_to_group(clock_acmp, 0);
     clock_add_to_group(clock_dao, 0);
-    clock_add_to_group(clock_msyn, 0);
+    clock_add_to_group(clock_synt, 0);
     clock_add_to_group(clock_lmm0, 0);
     clock_add_to_group(clock_lmm1, 0);
     clock_add_to_group(clock_pdm, 0);
@@ -1058,6 +1058,8 @@ void _init_ext_ram(void)
     femc_default_config(HPM_FEMC, &config);
     femc_init(HPM_FEMC, &config);
 
+    femc_get_typical_sdram_config(HPM_FEMC, &sdram_config);
+
     sdram_config.bank_num = FEMC_SDRAM_BANK_NUM_4;
     sdram_config.prescaler = 0x3;
     sdram_config.burst_len_in_byte = 8;
@@ -1065,18 +1067,14 @@ void _init_ext_ram(void)
     sdram_config.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS;
     sdram_config.cas_latency = FEMC_SDRAM_CAS_LATENCY_3;
 
-    sdram_config.precharge_to_act_in_ns = 18;   /* Trp */
-    sdram_config.act_to_rw_in_ns = 18;          /* Trcd */
-    sdram_config.refresh_recover_in_ns = 70;     /* Trfc/Trc */
-    sdram_config.write_recover_in_ns = 12;      /* Twr/Tdpl */
-    sdram_config.cke_off_in_ns = 42;             /* Trcd */
-    sdram_config.act_to_precharge_in_ns = 42;   /* Tras */
-
-    sdram_config.self_refresh_recover_in_ns = 66;   /* Txsr */
-    sdram_config.refresh_to_refresh_in_ns = 66;     /* Trfc/Trc */
+    sdram_config.refresh_to_refresh_in_ns = 60;     /* Trc */
+    sdram_config.refresh_recover_in_ns = 60;        /* Trc */
+    sdram_config.act_to_precharge_in_ns = 42;       /* Tras */
+    sdram_config.act_to_rw_in_ns = 18;              /* Trcd */
+    sdram_config.precharge_to_act_in_ns = 18;       /* Trp */
     sdram_config.act_to_act_in_ns = 12;             /* Trrd */
-    sdram_config.idle_timeout_in_ns = 6;
-    sdram_config.cs_mux_pin = FEMC_IO_MUX_NOT_USED;
+    sdram_config.write_recover_in_ns = 12;          /* Twr/Tdpl */
+    sdram_config.self_refresh_recover_in_ns = 72;   /* Txsr */
 
     sdram_config.cs = BOARD_SDRAM_CS;
     sdram_config.base_address = BOARD_SDRAM_ADDRESS;
@@ -1084,7 +1082,6 @@ void _init_ext_ram(void)
     sdram_config.port_size = BOARD_SDRAM_PORT_SIZE;
     sdram_config.refresh_count = BOARD_SDRAM_REFRESH_COUNT;
     sdram_config.refresh_in_ms = BOARD_SDRAM_REFRESH_IN_MS;
-    sdram_config.data_width_in_byte = BOARD_SDRAM_DATA_WIDTH_IN_BYTE;
     sdram_config.delay_cell_disable = true;
     sdram_config.delay_cell_value = 0;
 

+ 1 - 0
bsp/hpmicro/hpm6750evk/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM6700'
 CHIP_NAME='HPM6750'
 
 CROSS_TOOL='gcc'

+ 39 - 10
bsp/hpmicro/hpm6750evk2/.config

@@ -14,7 +14,6 @@ CONFIG_RT_THREAD_PRIORITY_32=y
 # CONFIG_RT_THREAD_PRIORITY_256 is not set
 CONFIG_RT_THREAD_PRIORITY_MAX=32
 CONFIG_RT_TICK_PER_SECOND=1000
-CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
 CONFIG_RT_HOOK_USING_FUNC_PTR=y
 # CONFIG_RT_USING_HOOKLIST is not set
@@ -24,6 +23,8 @@ CONFIG_IDLE_THREAD_STACK_SIZE=2048
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
 CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+# CONFIG_RT_USING_TIMER_ALL_SOFT is not set
+# CONFIG_RT_USING_CPU_USAGE_TRACER is not set
 
 #
 # kservice optimization
@@ -136,6 +137,7 @@ CONFIG_RT_USING_DFS_DEVFS=y
 # Device Drivers
 #
 # CONFIG_RT_USING_DM is not set
+# CONFIG_RT_USING_DEV_BUS is not set
 CONFIG_RT_USING_DEVICE_IPC=y
 CONFIG_RT_UNAMED_PIPE_NUMBER=64
 CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
@@ -156,6 +158,8 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
 # CONFIG_RT_USING_ZERO is not set
 # CONFIG_RT_USING_RANDOM is not set
 # CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_PULSE_ENCODER is not set
+# CONFIG_RT_USING_INPUT_CAPTURE is not set
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_PM is not set
@@ -170,9 +174,6 @@ CONFIG_RT_USING_RTC=y
 # CONFIG_RT_USING_TOUCH is not set
 # CONFIG_RT_USING_LCD is not set
 # CONFIG_RT_USING_HWCRYPTO is not set
-# CONFIG_RT_USING_PULSE_ENCODER is not set
-# CONFIG_RT_USING_INPUT_CAPTURE is not set
-# CONFIG_RT_USING_DEV_BUS is not set
 # CONFIG_RT_USING_WIFI is not set
 # CONFIG_RT_USING_VIRTIO is not set
 CONFIG_RT_USING_PIN=y
@@ -191,16 +192,17 @@ CONFIG_RT_CHERRYUSB_HOST_EHCI_HPM=y
 # CONFIG_RT_CHERRYUSB_HOST_DWC2_ST is not set
 # CONFIG_RT_CHERRYUSB_HOST_DWC2_ESP is not set
 # CONFIG_RT_CHERRYUSB_HOST_DWC2_CUSTOM is not set
-# CONFIG_RT_CHERRYUSB_HOST_MUSB_STANDARD is not set
+# CONFIG_RT_CHERRYUSB_HOST_MUSB_ES is not set
 # CONFIG_RT_CHERRYUSB_HOST_MUSB_SUNXI is not set
+# CONFIG_RT_CHERRYUSB_HOST_MUSB_BK is not set
 # CONFIG_RT_CHERRYUSB_HOST_MUSB_CUSTOM is not set
 # CONFIG_RT_CHERRYUSB_HOST_PUSB2 is not set
 # CONFIG_RT_CHERRYUSB_HOST_XHCI is not set
 CONFIG_RT_CHERRYUSB_HOST_CDC_ACM=y
 CONFIG_RT_CHERRYUSB_HOST_HID=y
 # CONFIG_RT_CHERRYUSB_HOST_MSC is not set
-# CONFIG_RT_CHERRYUSB_HOST_CDC_RNDIS is not set
 # CONFIG_RT_CHERRYUSB_HOST_CDC_ECM is not set
+# CONFIG_RT_CHERRYUSB_HOST_CDC_RNDIS is not set
 # CONFIG_RT_CHERRYUSB_HOST_CDC_NCM is not set
 # CONFIG_RT_CHERRYUSB_HOST_VIDEO is not set
 # CONFIG_RT_CHERRYUSB_HOST_AUDIO is not set
@@ -211,9 +213,7 @@ CONFIG_RT_CHERRYUSB_HOST_HID=y
 # CONFIG_RT_CHERRYUSB_HOST_CH34X is not set
 # CONFIG_RT_CHERRYUSB_HOST_CP210X is not set
 # CONFIG_RT_CHERRYUSB_HOST_PL2303 is not set
-CONFIG_RT_CHERRYUSB_HOST_TEMPLATE=y
-CONFIG_TEST_USBH_CDC_ACM=1
-CONFIG_TEST_USBH_HID=1
+# CONFIG_CHERRYUSB_HOST_TEMPLATE is not set
 # end of Device Drivers
 
 #
@@ -291,6 +291,7 @@ CONFIG_NETDEV_USING_IFCONFIG=y
 CONFIG_NETDEV_USING_PING=y
 CONFIG_NETDEV_USING_NETSTAT=y
 CONFIG_NETDEV_USING_AUTO_DEFAULT=y
+# CONFIG_NETDEV_USING_LINK_STATUS_CALLBACK is not set
 # CONFIG_NETDEV_USING_IPV6 is not set
 CONFIG_NETDEV_IPV4=1
 CONFIG_NETDEV_IPV6=0
@@ -385,6 +386,8 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_RT_USING_USB_HOST is not set
 # CONFIG_RT_USING_USB_DEVICE is not set
 # end of Using USB legacy version
+
+# CONFIG_RT_USING_FDT is not set
 # end of RT-Thread Components
 
 #
@@ -412,6 +415,7 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_WEBTERMINAL is not set
 # CONFIG_PKG_USING_FREEMODBUS is not set
 # CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set
 
 #
 # Wi-Fi
@@ -674,6 +678,8 @@ CONFIG_PKG_NETUTILS_VER_NUM=0x99999
 # CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
 # end of enhanced kernel services
 
+# CONFIG_PKG_USING_AUNITY is not set
+
 #
 # acceleration: Assembly language or algorithmic acceleration packages
 #
@@ -770,6 +776,21 @@ CONFIG_PKG_NETUTILS_VER_NUM=0x99999
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # end of STM32 HAL & SDK Drivers
 
+#
+# Infineon HAL Packages
+#
+# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set
+# CONFIG_PKG_USING_INFINEON_CMSIS is not set
+# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set
+# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set
+# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set
+# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set
+# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set
+# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set
+# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set
+# CONFIG_PKG_USING_INFINEON_USBDEV is not set
+# end of Infineon HAL Packages
+
 # CONFIG_PKG_USING_BLUETRUM_SDK is not set
 # CONFIG_PKG_USING_EMBARC_BSP is not set
 # CONFIG_PKG_USING_ESP_IDF is not set
@@ -963,6 +984,7 @@ CONFIG_PKG_NETUTILS_VER_NUM=0x99999
 #
 # Signal Processing and Control Algorithm Packages
 #
+# CONFIG_PKG_USING_APID is not set
 # CONFIG_PKG_USING_FIRE_PID_CURVE is not set
 # CONFIG_PKG_USING_QPID is not set
 # CONFIG_PKG_USING_UKAL is not set
@@ -1306,9 +1328,16 @@ CONFIG_BSP_USING_RTC=y
 # CONFIG_BSP_USING_DAO is not set
 # CONFIG_BSP_USING_PDM is not set
 # CONFIG_BSP_USING_I2S is not set
-# CONFIG_BSP_USING_USB is not set
+CONFIG_BSP_USING_USB=y
+CONFIG_BSP_USING_USB_DEVICE=y
+# CONFIG_BSP_USING_USB_HOST is not set
 # CONFIG_BSP_USING_WDG is not set
 # CONFIG_BSP_USING_CAN is not set
 # CONFIG_BSP_USING_ADC is not set
+# CONFIG_BSP_USING_CAMERA is not set
+# CONFIG_BSP_USING_JPEG is not set
+# CONFIG_BSP_USING_CAM is not set
+# CONFIG_BSP_USING_PANEL is not set
+# CONFIG_BSP_USING_RTT_LCD_DRIVER is not set
 # end of On-chip Peripheral Drivers
 # end of Hardware Drivers Config

+ 1 - 1
bsp/hpmicro/hpm6750evk2/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 11 - 14
bsp/hpmicro/hpm6750evk2/board/board.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
@@ -688,7 +688,7 @@ void board_init_clock(void)
     clock_add_to_group(clock_mot3, 0);
     clock_add_to_group(clock_acmp, 0);
     clock_add_to_group(clock_dao, 0);
-    clock_add_to_group(clock_msyn, 0);
+    clock_add_to_group(clock_synt, 0);
     clock_add_to_group(clock_lmm0, 0);
     clock_add_to_group(clock_lmm1, 0);
     clock_add_to_group(clock_pdm, 0);
@@ -1008,6 +1008,8 @@ void _init_ext_ram(void)
     femc_default_config(HPM_FEMC, &config);
     femc_init(HPM_FEMC, &config);
 
+    femc_get_typical_sdram_config(HPM_FEMC, &sdram_config);
+
     sdram_config.bank_num = FEMC_SDRAM_BANK_NUM_4;
     sdram_config.prescaler = 0x3;
     sdram_config.burst_len_in_byte = 8;
@@ -1015,18 +1017,14 @@ void _init_ext_ram(void)
     sdram_config.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS;
     sdram_config.cas_latency = FEMC_SDRAM_CAS_LATENCY_3;
 
-    sdram_config.precharge_to_act_in_ns = 18;   /* Trp */
-    sdram_config.act_to_rw_in_ns = 18;          /* Trcd */
-    sdram_config.refresh_recover_in_ns = 70;     /* Trfc/Trc */
-    sdram_config.write_recover_in_ns = 12;      /* Twr/Tdpl */
-    sdram_config.cke_off_in_ns = 42;             /* Trcd */
-    sdram_config.act_to_precharge_in_ns = 42;   /* Tras */
-
-    sdram_config.self_refresh_recover_in_ns = 66;   /* Txsr */
-    sdram_config.refresh_to_refresh_in_ns = 66;     /* Trfc/Trc */
+    sdram_config.refresh_to_refresh_in_ns = 60;     /* Trc */
+    sdram_config.refresh_recover_in_ns = 60;        /* Trc */
+    sdram_config.act_to_precharge_in_ns = 42;       /* Tras */
+    sdram_config.act_to_rw_in_ns = 18;              /* Trcd */
+    sdram_config.precharge_to_act_in_ns = 18;       /* Trp */
     sdram_config.act_to_act_in_ns = 12;             /* Trrd */
-    sdram_config.idle_timeout_in_ns = 6;
-    sdram_config.cs_mux_pin = FEMC_IO_MUX_NOT_USED;
+    sdram_config.write_recover_in_ns = 12;          /* Twr/Tdpl */
+    sdram_config.self_refresh_recover_in_ns = 72;   /* Txsr */
 
     sdram_config.cs = BOARD_SDRAM_CS;
     sdram_config.base_address = BOARD_SDRAM_ADDRESS;
@@ -1034,7 +1032,6 @@ void _init_ext_ram(void)
     sdram_config.port_size = BOARD_SDRAM_PORT_SIZE;
     sdram_config.refresh_count = BOARD_SDRAM_REFRESH_COUNT;
     sdram_config.refresh_in_ms = BOARD_SDRAM_REFRESH_IN_MS;
-    sdram_config.data_width_in_byte = BOARD_SDRAM_DATA_WIDTH_IN_BYTE;
     sdram_config.delay_cell_disable = true;
     sdram_config.delay_cell_value = 0;
 

+ 6 - 4
bsp/hpmicro/hpm6750evk2/rtconfig.h

@@ -9,7 +9,6 @@
 #define RT_THREAD_PRIORITY_32
 #define RT_THREAD_PRIORITY_MAX 32
 #define RT_TICK_PER_SECOND 1000
-#define RT_USING_OVERFLOW_CHECK
 #define RT_USING_HOOK
 #define RT_HOOK_USING_FUNC_PTR
 #define RT_USING_IDLE_HOOK
@@ -102,9 +101,6 @@
 #define RT_CHERRYUSB_HOST_EHCI_HPM
 #define RT_CHERRYUSB_HOST_CDC_ACM
 #define RT_CHERRYUSB_HOST_HID
-#define RT_CHERRYUSB_HOST_TEMPLATE
-#define TEST_USBH_CDC_ACM 1
-#define TEST_USBH_HID 1
 /* end of Device Drivers */
 
 /* C/C++ and POSIX layer */
@@ -312,6 +308,10 @@
 
 /* end of STM32 HAL & SDK Drivers */
 
+/* Infineon HAL Packages */
+
+/* end of Infineon HAL Packages */
+
 /* Kendryte SDK */
 
 /* end of Kendryte SDK */
@@ -405,6 +405,8 @@
 #define BSP_USING_UART
 #define BSP_USING_UART0
 #define BSP_USING_RTC
+#define BSP_USING_USB
+#define BSP_USING_USB_DEVICE
 /* end of On-chip Peripheral Drivers */
 /* end of Hardware Drivers Config */
 

+ 2 - 1
bsp/hpmicro/hpm6750evk2/rtconfig.py

@@ -1,4 +1,4 @@
-# Copyright 2021-2023 HPMicro
+# Copyright 2021-2024 HPMicro
 # SPDX-License-Identifier: BSD-3-Clause
 
 import os
@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM6700'
 CHIP_NAME='HPM6750'
 
 CROSS_TOOL='gcc'

+ 1 - 1
bsp/hpmicro/hpm6750evkmini/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 12 - 15
bsp/hpmicro/hpm6750evkmini/board/board.c

@@ -729,7 +729,7 @@ void board_init_clock(void)
     clock_add_to_group(clock_mot3, 0);
     clock_add_to_group(clock_acmp, 0);
     clock_add_to_group(clock_dao, 0);
-    clock_add_to_group(clock_msyn, 0);
+    clock_add_to_group(clock_synt, 0);
     clock_add_to_group(clock_lmm0, 0);
     clock_add_to_group(clock_lmm1, 0);
     clock_add_to_group(clock_pdm, 0);
@@ -1069,6 +1069,8 @@ void _init_ext_ram(void)
     femc_default_config(HPM_FEMC, &config);
     femc_init(HPM_FEMC, &config);
 
+    femc_get_typical_sdram_config(HPM_FEMC, &sdram_config);
+
     sdram_config.bank_num = FEMC_SDRAM_BANK_NUM_4;
     sdram_config.prescaler = 0x3;
     sdram_config.burst_len_in_byte = 8;
@@ -1076,18 +1078,14 @@ void _init_ext_ram(void)
     sdram_config.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS;
     sdram_config.cas_latency = FEMC_SDRAM_CAS_LATENCY_3;
 
-    sdram_config.precharge_to_act_in_ns = 18;   /* Trp */
-    sdram_config.act_to_rw_in_ns = 18;          /* Trcd */
-    sdram_config.refresh_recover_in_ns = 70;     /* Trfc/Trc */
-    sdram_config.write_recover_in_ns = 12;      /* Twr/Tdpl */
-    sdram_config.cke_off_in_ns = 42;             /* Trcd */
-    sdram_config.act_to_precharge_in_ns = 42;   /* Tras */
-
-    sdram_config.self_refresh_recover_in_ns = 66;   /* Txsr */
-    sdram_config.refresh_to_refresh_in_ns = 66;     /* Trfc/Trc */
+    sdram_config.refresh_to_refresh_in_ns = 60;     /* Trc */
+    sdram_config.refresh_recover_in_ns = 60;        /* Trc */
+    sdram_config.act_to_precharge_in_ns = 42;       /* Tras */
+    sdram_config.act_to_rw_in_ns = 18;              /* Trcd */
+    sdram_config.precharge_to_act_in_ns = 18;       /* Trp */
     sdram_config.act_to_act_in_ns = 12;             /* Trrd */
-    sdram_config.idle_timeout_in_ns = 6;
-    sdram_config.cs_mux_pin = FEMC_IO_MUX_NOT_USED;
+    sdram_config.write_recover_in_ns = 12;          /* Twr/Tdpl */
+    sdram_config.self_refresh_recover_in_ns = 72;   /* Txsr */
 
     sdram_config.cs = BOARD_SDRAM_CS;
     sdram_config.base_address = BOARD_SDRAM_ADDRESS;
@@ -1095,7 +1093,6 @@ void _init_ext_ram(void)
     sdram_config.port_size = BOARD_SDRAM_PORT_SIZE;
     sdram_config.refresh_count = BOARD_SDRAM_REFRESH_COUNT;
     sdram_config.refresh_in_ms = BOARD_SDRAM_REFRESH_IN_MS;
-    sdram_config.data_width_in_byte = BOARD_SDRAM_DATA_WIDTH_IN_BYTE;
     sdram_config.delay_cell_disable = true;
     sdram_config.delay_cell_value = 0;
 
@@ -1134,9 +1131,9 @@ uint32_t board_sd_configure_clock(SDXC_Type *ptr, uint32_t freq, bool need_inver
         else if (freq <= 100000000UL) {
             clock_set_source_divider(sdxc_clk, clk_src_pll1_clk1, 4);
         }
-            /* Configure the clock to 133MHz for SDR104/HS200/HS400  */
+            /* Configure the clock to 166MHz for SDR104/HS200/HS400  */
         else if (freq <= 208000000UL) {
-            clock_set_source_divider(sdxc_clk, clk_src_pll1_clk1, 3);
+            clock_set_source_divider(sdxc_clk, clk_src_pll2_clk0, 2);
         }
             /* For other unsupported clock ranges, configure the clock to 24MHz */
         else {

+ 1 - 0
bsp/hpmicro/hpm6750evkmini/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM6700'
 CHIP_NAME='HPM6750'
 
 CROSS_TOOL='gcc'

+ 1 - 1
bsp/hpmicro/hpm6800evk/SConstruct

@@ -59,7 +59,7 @@ hpm_library = 'hpm_sdk'
 rtconfig.BSP_LIBRARY_TYPE = hpm_library
 
 # include soc
-objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.CHIP_NAME, 'SConscript')))
+objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript')))
 
 # include libraries
 objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript')))

+ 11 - 0
bsp/hpmicro/hpm6800evk/board/rtt_board.c

@@ -119,3 +119,14 @@ void rt_hw_cpu_reset(void)
 }
 
 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reset, reset the board);
+
+#ifdef RT_USING_CACHE
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_FLUSH) {
+        l1c_dc_flush((uint32_t)addr, size);
+    } else {
+        l1c_dc_invalidate((uint32_t)addr, size);
+    }
+}
+#endif

+ 1 - 0
bsp/hpmicro/hpm6800evk/rtconfig.py

@@ -7,6 +7,7 @@ import sys
 # toolchains options
 ARCH='risc-v'
 CPU='hpmicro'
+SOC_FAMILY='HPM6800'
 CHIP_NAME='HPM6880'
 
 CROSS_TOOL='gcc'

+ 1 - 1
bsp/hpmicro/libraries/drivers/SConscript

@@ -29,7 +29,7 @@ if GetDepend('BSP_USING_ETH'):
 if GetDepend('BSP_USING_SDXC'):
     src += ['drv_sdio.c']
 
-if GetDepend('BSP_USING_PWM'):
+if GetDepend('BSP_USING_PWM') or GetDepend('BSP_USING_PWMV2'):
     src += ['drv_pwm.c']
 
 if GetDepend('BSP_USING_GPTMR'):

+ 19 - 2
bsp/hpmicro/libraries/drivers/drv_adc.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,6 +36,7 @@ typedef struct
 
 
 static uint32_t hpm_adc_init_clock(struct rt_adc_device *device);
+static void hpm_adc_init_pins(struct rt_adc_device *device);
 
 static rt_err_t hpm_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled);
 static rt_err_t hpm_get_adc_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value);
@@ -121,6 +122,22 @@ static uint32_t hpm_adc_init_clock(struct rt_adc_device *device)
     return clock_freq;
 }
 
+static void hpm_adc_init_pins(struct rt_adc_device *device)
+{
+    hpm_rtt_adc *hpm_adc;
+    RT_ASSERT(device != RT_NULL);
+    hpm_adc = (hpm_rtt_adc *)device->parent.user_data;
+
+#if defined(ADC12_SOC_MAX_CH_NUM)
+    if (hpm_adc->is_adc12)
+    {
+        board_init_adc12_pins();
+    } else
+#endif
+    {
+        board_init_adc16_pins();
+    }
+}
 static rt_err_t init_adc_config(hpm_rtt_adc *adc)
 {
     hpm_stat_t ret;
@@ -208,6 +225,7 @@ static rt_err_t hpm_adc_enabled(struct rt_adc_device *device, rt_int8_t channel,
         {
             if (!hpm_adc->adc_enabled)
             {
+                hpm_adc_init_pins(device);
                 (void)hpm_adc_init_clock(device);
                 ret = init_adc_config(hpm_adc);
                 if (ret != RT_EOK) {
@@ -251,7 +269,6 @@ static rt_err_t hpm_get_adc_value(struct rt_adc_device *device, rt_int8_t channe
 #ifdef BSP_USING_ADC16
         hpm_stat_t status = adc16_get_oneshot_result((ADC16_Type *)hpm_adc->adc_base, adc_chn, &val);
         *value = val;
-       // rt_kprintf("%s, status=%d\n", __func__, status);
 #endif
     }
 

+ 2 - 2
bsp/hpmicro/libraries/drivers/drv_can.c

@@ -347,7 +347,7 @@ static rt_err_t hpm_can_control(struct rt_can_device *can, int cmd, void *arg)
         else if (arg_val == RT_DEVICE_CAN_INT_ERR)
         {
             uint8_t irq_txrx_mask = CAN_EVENT_ERROR;
-            uint8_t irq_error_mask = CAN_ERROR_ARBITRAITION_LOST_INT_ENABLE | CAN_ERROR_PASSIVE_INT_ENABLE | CAN_ERROR_BUS_ERROR_INT_ENABLE;
+            uint8_t irq_error_mask = CAN_ERROR_ARBITRATION_LOST_INT_ENABLE | CAN_ERROR_PASSIVE_INT_ENABLE | CAN_ERROR_BUS_ERROR_INT_ENABLE;
             drv_can->can_config.irq_txrx_enable_mask &= (uint8_t)~irq_txrx_mask;
             drv_can->can_config.irq_error_enable_mask &= (uint8_t)~irq_error_mask;
             can_disable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);
@@ -377,7 +377,7 @@ static rt_err_t hpm_can_control(struct rt_can_device *can, int cmd, void *arg)
         else if (arg_val == RT_DEVICE_CAN_INT_ERR)
         {
             uint8_t irq_txrx_mask = CAN_EVENT_ERROR;
-            uint8_t irq_error_mask = CAN_ERROR_ARBITRAITION_LOST_INT_ENABLE | CAN_ERROR_PASSIVE_INT_ENABLE | CAN_ERROR_BUS_ERROR_INT_ENABLE;
+            uint8_t irq_error_mask = CAN_ERROR_ARBITRATION_LOST_INT_ENABLE | CAN_ERROR_PASSIVE_INT_ENABLE | CAN_ERROR_BUS_ERROR_INT_ENABLE;
             drv_can->can_config.irq_txrx_enable_mask |= irq_txrx_mask;
             drv_can->can_config.irq_error_enable_mask |= irq_error_mask;
             can_enable_tx_rx_irq(drv_can->can_base, irq_txrx_mask);

+ 6 - 7
bsp/hpmicro/libraries/drivers/drv_enet.c

@@ -208,9 +208,14 @@ static rt_err_t hpm_enet_init(enet_device *init)
         enet_rgmii_set_clock_delay(init->instance, init->tx_delay, init->rx_delay);
    }
 #endif
+    /* Get the default interrupt config */
+    enet_get_default_interrupt_config(init->instance, &init->int_config);
 
     /* Initialize eth controller */
-   enet_controller_init(init->instance, init->media_interface, &init->desc, &init->mac_config, &init->int_config);
+    enet_controller_init(init->instance, init->media_interface, &init->desc, &init->mac_config, &init->int_config);
+
+    /* Disable LPI interrupt */
+    enet_disable_lpi_interrupt(init->instance);
 
 #if __USE_ENET_PTP
    /* initialize PTP Clock */
@@ -581,12 +586,6 @@ int rt_hw_eth_init(void)
         s_geths[i]->enet_dev->ptp_config    = *s_geths[i]->ptp_config;
         s_geths[i]->enet_dev->ptp_timestamp = *s_geths[i]->ptp_timestamp;
 #endif
-        /* Set the interrupt enable mask */
-        s_geths[i]->enet_dev->int_config.int_enable = enet_normal_int_sum_en   /* Enable normal interrupt summary */
-                                                    | enet_receive_int_en;  /* Enable receive interrupt */
-        /* Set the interrupt disable mask */
-
-        s_geths[i]->enet_dev->int_config.int_mask = enet_rgsmii_int_mask;
 
         /* Set the irq number */
         s_geths[i]->enet_dev->irq_number = s_geths[i]->irq_num;

+ 38 - 35
bsp/hpmicro/libraries/drivers/drv_gpio.c

@@ -12,6 +12,7 @@
  * 2024-01-08   HPMicro     Implemented pin_get
  * 2024-04-17   HPMicro     Refined pin irq implementation
  * 2024-05-31   HPMicro     Adapt later PIN driver framework
+ * 2024-07-03   HPMicro     Determined the existence of GPIO via GPIO_DO_GPIOx macro
  */
 
 #include <rtthread.h>
@@ -34,72 +35,72 @@ typedef struct
     struct rt_pin_irq_hdr *pin_irq_tbl;
 } gpio_irq_map_t;
 
-#ifdef IRQn_GPIO0_A
+#ifdef GPIO_DO_GPIOA
 static struct rt_pin_irq_hdr hpm_gpio0_a_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_B
+#ifdef GPIO_DO_GPIOB
 static struct rt_pin_irq_hdr hpm_gpio0_b_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_C
+#ifdef GPIO_DO_GPIOC
 static struct rt_pin_irq_hdr hpm_gpio0_c_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_D
+#ifdef GPIO_DO_GPIOD
 static struct rt_pin_irq_hdr hpm_gpio0_d_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_E
+#ifdef GPIO_DO_GPIOE
 static struct rt_pin_irq_hdr hpm_gpio0_e_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_F
+#ifdef GPIO_DO_GPIOF
 static struct rt_pin_irq_hdr hpm_gpio0_f_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_V
+#ifdef GPIO_DO_GPIOV
 static struct rt_pin_irq_hdr hpm_gpio0_v_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_W
+#ifdef GPIO_DO_GPIOW
 static struct rt_pin_irq_hdr hpm_gpio0_w_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_X
+#ifdef GPIO_DO_GPIOX
 static struct rt_pin_irq_hdr hpm_gpio0_x_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_Y
+#ifdef GPIO_DO_GPIOY
 static struct rt_pin_irq_hdr hpm_gpio0_y_pin_hdr[32];
 #endif
-#ifdef IRQn_GPIO0_Z
+#ifdef GPIO_DO_GPIOZ
 static struct rt_pin_irq_hdr hpm_gpio0_z_pin_hdr[32];
 #endif
 
 static const gpio_irq_map_t hpm_gpio_irq_map[] = {
-#ifdef IRQn_GPIO0_A
+#ifdef GPIO_DO_GPIOA
         { GPIO_IE_GPIOA, IRQn_GPIO0_A, hpm_gpio0_a_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_B
+#ifdef GPIO_DO_GPIOB
         { GPIO_IE_GPIOB, IRQn_GPIO0_B, hpm_gpio0_b_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_C
+#ifdef GPIO_DO_GPIOC
         { GPIO_IE_GPIOC, IRQn_GPIO0_C, hpm_gpio0_c_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_D
+#ifdef GPIO_DO_GPIOD
         { GPIO_IE_GPIOD, IRQn_GPIO0_D, hpm_gpio0_d_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_E
+#ifdef GPIO_DO_GPIOE
         { GPIO_IE_GPIOE, IRQn_GPIO0_E, hpm_gpio0_e_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_F
+#ifdef GPIO_DO_GPIOF
         { GPIO_IE_GPIOF, IRQn_GPIO0_F, hpm_gpio0_f_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_V
+#ifdef GPIO_DO_GPIOV
         { GPIO_IE_GPIOV, IRQn_GPIO0_V, hpm_gpio0_v_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_W
+#ifdef GPIO_DO_GPIOW
         { GPIO_IE_GPIOW, IRQn_GPIO0_W, hpm_gpio0_w_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_X
+#ifdef GPIO_DO_GPIOX
         { GPIO_IE_GPIOX, IRQn_GPIO0_X, hpm_gpio0_x_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_Y
+#ifdef GPIO_DO_GPIOY
         { GPIO_IE_GPIOY, IRQn_GPIO0_Y, hpm_gpio0_y_pin_hdr },
 #endif
-#ifdef IRQn_GPIO0_Z
+#ifdef GPIO_DO_GPIOZ
         { GPIO_IE_GPIOZ, IRQn_GPIO0_Z, hpm_gpio0_z_pin_hdr },
 #endif
 };
@@ -162,7 +163,7 @@ static void hpm_gpio_isr(uint32_t gpio_idx, GPIO_Type *base)
     }
 }
 
-#ifdef IRQn_GPIO0_A
+#ifdef GPIO_DO_GPIOA
 void gpioa_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOA, HPM_GPIO0);
@@ -170,7 +171,7 @@ void gpioa_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_A, gpioa_isr)
 #endif
 
-#ifdef IRQn_GPIO0_B
+#ifdef GPIO_DO_GPIOB
 void gpiob_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOB, HPM_GPIO0);
@@ -178,7 +179,7 @@ void gpiob_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_B, gpiob_isr)
 #endif
 
-#ifdef IRQn_GPIO0_C
+#ifdef GPIO_DO_GPIOC
 void gpioc_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOC, HPM_GPIO0);
@@ -186,7 +187,7 @@ void gpioc_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_C, gpioc_isr)
 #endif
 
-#ifdef IRQn_GPIO0_D
+#ifdef GPIO_DO_GPIOD
 void gpiod_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOD, HPM_GPIO0);
@@ -194,7 +195,7 @@ void gpiod_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_D, gpiod_isr)
 #endif
 
-#ifdef IRQn_GPIO0_E
+#ifdef GPIO_DO_GPIOE
 void gpioe_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOE, HPM_GPIO0);
@@ -202,7 +203,7 @@ void gpioe_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_E, gpioe_isr)
 #endif
 
-#ifdef IRQn_GPIO0_F
+#ifdef GPIO_DO_GPIOF
 void gpiof_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOF, HPM_GPIO0);
@@ -210,23 +211,23 @@ void gpiof_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_F, gpiof_isr)
 #endif
 
-#ifdef IRQn_GPIO0_V
-void gpiox_isr(void)
+#ifdef GPIO_DO_GPIOV
+void gpiov_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOV, HPM_GPIO0);
 }
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_V, gpiox_isr)
 #endif
 
-#ifdef IRQn_GPIO0_W
-void gpiox_isr(void)
+#ifdef GPIO_DO_GPIOW
+void gpiow_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOW, HPM_GPIO0);
 }
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_W, gpiox_isr)
 #endif
 
-#ifdef IRQn_GPIO0_X
+#ifdef GPIO_DO_GPIOX
 void gpiox_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOX, HPM_GPIO0);
@@ -234,7 +235,7 @@ void gpiox_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_X, gpiox_isr)
 #endif
 
-#ifdef IRQn_GPIO0_Y
+#ifdef GPIO_DO_GPIOY
 void gpioy_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOY, HPM_GPIO0);
@@ -242,7 +243,7 @@ void gpioy_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_Y, gpioy_isr)
 #endif
 
-#ifdef IRQn_GPIO0_Z
+#ifdef GPIO_DO_GPIOZ
 void gpioz_isr(void)
 {
     hpm_gpio_isr(GPIO_IF_GPIOZ, HPM_GPIO0);
@@ -289,11 +290,13 @@ static void hpm_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
     case GPIO_DI_GPIOY :
         HPM_PIOC->PAD[pin].FUNC_CTL = 3;
         break;
+#ifdef GPIO_DI_GPIOZ
     case GPIO_DI_GPIOZ :
 #ifdef HPM_BIOC
         HPM_BIOC->PAD[pin].FUNC_CTL = 3;
 #endif
         break;
+#endif
     default :
         break;
     }

+ 3 - 98
bsp/hpmicro/libraries/drivers/drv_i2c.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -157,101 +157,6 @@ void i2c3_isr(void)
 SDK_DECLARE_EXT_ISR_M(IRQn_I2C3, i2c3_isr);
 #endif
 
-static hpm_stat_t i2c_transfer(I2C_Type *ptr, const uint16_t device_address,
-                                    uint8_t *buf, const uint32_t size,  uint16_t flags)
-{
-    uint32_t ctrl = 0;
-    uint32_t retry = 0;
-    uint32_t left = 0;
-    if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
-        return status_invalid_argument;
-    }
-    /* W1C, clear CMPL bit to avoid blocking the transmission */
-    ptr->STATUS = I2C_STATUS_CMPL_MASK;
-    ptr->CMD = I2C_CMD_CLEAR_FIFO;
-    ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
-
-    if (flags & RT_I2C_RD) {
-        ctrl |= I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ);
-    } else {
-        ctrl |= I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE);/* is write flag */
-    }
-    /* no start signal send*/
-    if (flags & RT_I2C_NO_START) {
-        ctrl |= I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(true) \
-               | I2C_CTRL_PHASE_ADDR_SET(true);
-    } else if (flags & RT_I2C_NO_STOP) { /* no end signal send*/
-        ctrl |= I2C_CTRL_PHASE_START_SET(true) | I2C_CTRL_PHASE_STOP_SET(false) \
-               | I2C_CTRL_PHASE_ADDR_SET(true);
-    } else {
-        ctrl |= I2C_CTRL_PHASE_START_SET(true) | I2C_CTRL_PHASE_STOP_SET(true) \
-               | I2C_CTRL_PHASE_ADDR_SET(true);
-    }
-    ptr->CTRL = ctrl | I2C_CTRL_PHASE_DATA_SET(true) \
-                | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U) \
-                | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
-    /* disable auto ack */
-    ptr->INTEN |= I2C_EVENT_BYTE_RECEIVED;
-    ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
-    retry = 0;
-    left = size;
-    if (flags & RT_I2C_RD) {
-        while (left) {
-            if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
-                *(buf++) = ptr->DATA;
-                left--;
-                if (left == 0) {
-                    ptr->CMD = I2C_CMD_NACK;
-                } else {
-                    /* ACK is sent when reading */
-                    if (!(flags & RT_I2C_NO_READ_ACK)) {
-                        ptr->CMD = I2C_CMD_ACK;
-                    }
-                }
-                retry = 0;
-            } else {
-                if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
-                    break;
-                }
-                retry++;
-            }
-        }
-        if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
-            return status_timeout;
-        }
-    } else {
-        while (left) {
-            if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
-                ptr->DATA = *(buf++);
-                left--;
-                retry = 0;
-            } else {
-                if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
-                    break;
-                }
-                retry++;
-            }
-        }
-        if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
-            return status_timeout;
-        }
-    }
-    retry = 0;
-    while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
-        if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
-            break;
-        }
-        retry++;
-    };
-    if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
-        return status_timeout;
-    }
-
-    if (i2c_get_data_count(ptr) && (size)) {
-        return status_i2c_transmit_not_completed;
-    }
-}
-
 static hpm_stat_t i2c_tx_trigger_dma(DMA_Type *dma_ptr, uint8_t ch_num, I2C_Type *i2c_ptr, uint32_t src, uint32_t size)
 {
     dma_handshake_config_t config;
@@ -398,7 +303,7 @@ static rt_ssize_t hpm_i2c_master_transfer(struct rt_i2c_bus_device *bus, struct
                     }
                     else
                     {
-                        i2c_transfer(i2c_info->base, msg->addr, dummy_buf, transfer_len, msg->flags);
+                        i2c_master_transfer(i2c_info->base, msg->addr, dummy_buf, transfer_len, msg->flags);
                     }
                     dummy_buf += transfer_len;
                     remaining_size -= transfer_len;
@@ -451,7 +356,7 @@ static rt_ssize_t hpm_i2c_master_transfer(struct rt_i2c_bus_device *bus, struct
                     }
                     else
                     {
-                        i2c_transfer(i2c_info->base, msg->addr, dummy_buf, transfer_len, msg->flags);
+                        i2c_master_transfer(i2c_info->base, msg->addr, dummy_buf, transfer_len, msg->flags);
                     }
                     dummy_buf += transfer_len;
                     remaining_size -= transfer_len;

+ 126 - 26
bsp/hpmicro/libraries/drivers/drv_pwm.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,16 +8,24 @@
  * 2022-05-09   HPMicro     First version
  * 2023-04-12   HPMicro     Adapt hpm_sdk v1.0.0
  * 2023-05-13   HPMicro     Fix compiling error on HPM6360/HPM6200
+ * 2023-06-10	HPMicro     Add PWMv2 support
  */
 
 #include <rtthread.h>
 
-#ifdef BSP_USING_PWM
+#if defined(BSP_USING_PWM) || defined(BSP_USING_PWMV2)
+#if defined(BSP_USING_PWMV2)
+#define HPMSOC_HAS_HPMSDK_PWMV2
+#endif
 #include <rthw.h>
 #include <rtdevice.h>
 #include "board.h"
 #include "drv_gpio.h"
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+#include "hpm_pwmv2_drv.h"
+#else
 #include "hpm_pwm_drv.h"
+#endif
 #include "hpm_clock_drv.h"
 
 #ifdef HPM_PWM3
@@ -30,8 +38,11 @@
 #define PWM_INSTANCE_NUM 1
 #endif
 
-
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+static PWMV2_Type * pwm_base_tbl[PWM_INSTANCE_NUM] = {
+#else
 static PWM_Type * pwm_base_tbl[PWM_INSTANCE_NUM] = {
+#endif
     HPM_PWM0,
 #ifdef HPM_PWM1
     HPM_PWM1,
@@ -44,37 +55,103 @@ static PWM_Type * pwm_base_tbl[PWM_INSTANCE_NUM] = {
 #endif
     };
 
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+
+#ifdef PWMV2_CNT_3
+#define PWMV2_CNT_NUM 4
+#elif PWMV2_CNT_2
+#define PWMV2_CNT_NUM 3
+#elif PWMV2_CNT_1
+#define PWMV2_CNT_NUM 2
+#else
+#define PWMV2_CNT_NUM 1
+#endif
+
+static pwm_counter_t pwmv2_counter_tbl[PWMV2_CNT_NUM * 2] = {
+    pwm_counter_0,
+    pwm_counter_0,
+#ifdef PWMV2_CNT_1
+    pwm_counter_1,
+    pwm_counter_1,
+#endif
+#ifdef PWMV2_CNT_2
+    pwm_counter_2,
+    pwm_counter_2,
+#endif
+#ifdef PWMV2_CNT_3
+    pwm_counter_3,
+    pwm_counter_3,
+#endif
+};
+#endif
+
 rt_err_t hpm_generate_central_aligned_waveform(uint8_t pwm_index, uint8_t channel, uint32_t period, uint32_t pulse)
 {
-    uint32_t duty;
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+    PWMV2_Type * pwm_base;
+    pwm_counter_t pwm_counter;
+#else
+    PWM_Type * pwm_base;
     pwm_cmp_config_t cmp_config[2] = {0};
     pwm_config_t pwm_config = {0};
+#endif
+    uint32_t duty;
     uint32_t reload = 0;
     uint32_t freq;
-    PWM_Type * pwm_name_index;
-    pwm_name_index = pwm_base_tbl[pwm_index];
+    pwm_base = pwm_base_tbl[pwm_index];
 
-    init_pwm_pins(pwm_name_index);
-    freq = board_init_pwm_clock(pwm_name_index);
+    init_pwm_pins(pwm_base);
+    freq = board_init_pwm_clock(pwm_base);
     if(period != 0) {
         reload = (uint64_t)freq * period / 1000000000;
     } else {
         reload = 0;
     }
+    duty = (uint64_t)freq * pulse / 1000000000;
+
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
 
-    pwm_stop_counter(pwm_name_index);
-    pwm_get_default_pwm_config(pwm_name_index, &pwm_config);
+    pwm_counter = pwmv2_counter_tbl[channel];
+
+    pwmv2_disable_counter(pwm_base, pwm_counter);
+    pwmv2_reset_counter(pwm_base, pwm_counter);
+    pwmv2_shadow_register_unlock(pwm_base);
+
+    pwmv2_set_shadow_val(pwm_base, channel / 2, reload, 0, false);  /**< cnt use 0-3 shadow */
+    pwmv2_set_shadow_val(pwm_base, channel * 2 + 4, reload + 1, 0, false);
+    pwmv2_set_shadow_val(pwm_base, channel * 2 + 5, reload, 0, false);
+
+    pwmv2_counter_select_data_offset_from_shadow_value(pwm_base, pwm_counter, channel / 2);
+    pwmv2_counter_burst_disable(pwm_base, pwm_counter);
+    pwmv2_set_reload_update_time(pwm_base, pwm_counter, pwm_reload_update_on_reload);
+
+    pwmv2_select_cmp_source(pwm_base, channel * 2, cmp_value_from_shadow_val, channel * 2 + 4);
+    pwmv2_select_cmp_source(pwm_base, channel * 2 + 1, cmp_value_from_shadow_val, channel * 2 + 5);
+
+    pwmv2_shadow_register_lock(pwm_base);
+    pwmv2_disable_four_cmp(pwm_base, channel);
+    pwmv2_channel_enable_output(pwm_base, channel);
+    pwmv2_enable_counter(pwm_base, pwm_counter);
+    pwmv2_start_pwm_output(pwm_base, pwm_counter);
+
+    pwmv2_shadow_register_unlock(pwm_base);
+    pwmv2_set_shadow_val(pwm_base, channel * 2, (reload - duty) >> 1, 0, false);
+    pwmv2_set_shadow_val(pwm_base, channel * 2, (reload + duty) >> 1, 0, false);
+    pwmv2_shadow_register_lock(pwm_base);
+#else
+
+    pwm_stop_counter(pwm_base);
+    pwm_get_default_pwm_config(pwm_base, &pwm_config);
 
     /*
      * reload and start counter
      */
-    pwm_set_reload(pwm_name_index, 0, reload);
-    pwm_set_start_count(pwm_name_index, 0, 0);
+    pwm_set_reload(pwm_base, 0, reload);
+    pwm_set_start_count(pwm_base, 0, 0);
 
     /*
      * config cmp1 and cmp2
      */
-    duty = (uint64_t)freq * pulse / 1000000000;
 
     cmp_config[0].mode = pwm_cmp_mode_output_compare;
     cmp_config[0].cmp = (reload - duty) >> 1;
@@ -91,45 +168,68 @@ rt_err_t hpm_generate_central_aligned_waveform(uint8_t pwm_index, uint8_t channe
     /*
      * config pwm
      */
-    if (status_success != pwm_setup_waveform(pwm_name_index, channel, &pwm_config, channel * 2, cmp_config, 2)) {
+    if (status_success != pwm_setup_waveform(pwm_base, channel, &pwm_config, channel * 2, cmp_config, 2)) {
         return -RT_ERROR;
     }
-    pwm_start_counter(pwm_name_index);
-    pwm_issue_shadow_register_lock_event(pwm_name_index);
+    pwm_start_counter(pwm_base);
+    pwm_issue_shadow_register_lock_event(pwm_base);
 
+#endif
     return RT_EOK;
 
 }
 
 rt_err_t hpm_set_central_aligned_waveform(uint8_t pwm_index, uint8_t channel, uint32_t period, uint32_t pulse)
 {
-    uint32_t duty;
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+    PWMV2_Type * pwm_base;
+#else
+    PWM_Type * pwm_base;
     pwm_config_t pwm_config = {0};
+#endif
+
+    uint32_t duty;
     uint32_t reload = 0;
     uint32_t freq;
-    PWM_Type * pwm_name_index;
-    pwm_name_index = pwm_base_tbl[pwm_index];
 
-    freq = board_init_pwm_clock(pwm_name_index);
+    pwm_base = pwm_base_tbl[pwm_index];
+    freq = board_init_pwm_clock(pwm_base);
     if(period != 0) {
         reload = (uint64_t)freq * period / 1000000000;
     } else {
         reload = 0;
     }
-
-    pwm_get_default_pwm_config(pwm_name_index, &pwm_config);
-    pwm_set_reload(pwm_name_index, 0, reload);
     duty = (uint64_t)freq * pulse / 1000000000;
-    pwm_update_raw_cmp_central_aligned(pwm_name_index, channel * 2, channel * 2 + 1, (reload - duty) >> 1, (reload + duty) >> 1);
-    pwm_issue_shadow_register_lock_event(pwm_name_index);
+
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+    pwmv2_shadow_register_unlock(pwm_base);
+    pwmv2_set_shadow_val(pwm_base, channel / 2, reload, 0, false);  /**< cnt use 0-3 shadow */
+    pwmv2_set_shadow_val(pwm_base, channel * 2 + 4, (reload - duty) >> 1, 0, false);
+    pwmv2_set_shadow_val(pwm_base, channel * 2 + 5, (reload + duty) >> 1, 0, false);
+    pwmv2_shadow_register_lock(pwm_base);
+#else
+    pwm_get_default_pwm_config(pwm_base, &pwm_config);
+    pwm_set_reload(pwm_base, 0, reload);
+    pwm_update_raw_cmp_central_aligned(pwm_base, channel * 2, channel * 2 + 1, (reload - duty) >> 1, (reload + duty) >> 1);
+    pwm_issue_shadow_register_lock_event(pwm_base);
+#endif
 
     return RT_EOK;
 }
 
 rt_err_t hpm_disable_pwm(uint8_t pwm_index, uint8_t channel)
 {
-
+#if defined(HPMSOC_HAS_HPMSDK_PWMV2)
+    PWMV2_Type * pwm_base;
+
+    pwm_base = pwm_base_tbl[pwm_index];
+    pwmv2_shadow_register_unlock(pwm_base);
+    pwmv2_set_shadow_val(pwm_base, channel * 2 + 4, 0, 0, false);
+    pwmv2_set_shadow_val(pwm_base, channel * 2 + 5, 0, 0, false);
+    pwmv2_shadow_register_lock(pwm_base);
+#else
     pwm_disable_output(pwm_base_tbl[pwm_index], channel);
+#endif
     return RT_EOK;
 
 }

+ 13 - 0
bsp/hpmicro/libraries/drivers/drv_sdio.c

@@ -13,6 +13,7 @@
  * 2024-05-23   HPMicro     Fixed unaligned transfer issue in the SDIO case
  * 2024-05-25   HPMicro     Added HS200 & HS400 support, optimize the cache-management policy for read
  * 2024-05-26   HPMicro     Added UHS-I support, added DDR50 and High Speed DDR mode support
+ * 2024-06-19   HPMicro     Added timeout check for SDXC transfer
  */
 #include <rtthread.h>
 
@@ -336,11 +337,17 @@ static hpm_stat_t hpm_sdmmc_transfer(SDXC_Type *base, sdxc_adma_config_t *dma_co
     }
     /* Wait until idle */
     volatile uint32_t interrupt_status = sdxc_get_interrupt_status(base);
+    volatile rt_base_t start_tick = rt_tick_get();
     while (!IS_HPM_BITMASK_SET(interrupt_status, SDXC_INT_STAT_CMD_COMPLETE_MASK))
     {
         interrupt_status = sdxc_get_interrupt_status(base);
         status = sdxc_parse_interrupt_status(base);
         HPM_BREAK_IF(status != status_success);
+        rt_base_t current_tick = rt_tick_get();
+        if ((current_tick - start_tick) > RT_TICK_PER_SECOND)
+        {
+            return -RT_ETIMEOUT;
+        }
     }
     sdxc_clear_interrupt_status(base, SDXC_INT_STAT_CMD_COMPLETE_MASK);
     if (status == status_success)
@@ -350,11 +357,17 @@ static hpm_stat_t hpm_sdmmc_transfer(SDXC_Type *base, sdxc_adma_config_t *dma_co
     if ((status == status_success) && (data != RT_NULL))
     {
         interrupt_status = sdxc_get_interrupt_status(base);
+        start_tick = rt_tick_get();
         while (!IS_HPM_BITMASK_SET(interrupt_status, SDXC_INT_STAT_XFER_COMPLETE_MASK | SDXC_STS_ERROR))
         {
             interrupt_status = sdxc_get_interrupt_status(base);
             status = sdxc_parse_interrupt_status(base);
             HPM_BREAK_IF(status != status_success);
+            rt_base_t current_tick = rt_tick_get();
+            if ((current_tick - start_tick) > RT_TICK_PER_SECOND)
+            {
+                return -RT_ETIMEOUT;
+            }
         }
     }
 

+ 92 - 2
bsp/hpmicro/libraries/drivers/drv_spi.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -9,6 +9,7 @@
  * 2023-02-15   HPMicro     Add DMA support
  * 2023-07-14   HPMicro     Manage the DMA buffer alignment in driver
  * 2023-12-14   HPMicro     change state blocking wait to interrupt semaphore wait for DMA
+ * 2024-06-10   HPMicro     Add the SPI pin settings
  */
 #include <rtthread.h>
 
@@ -42,6 +43,7 @@ struct hpm_spi
     rt_sem_t spi_xfer_done_sem;
     rt_sem_t txdma_xfer_done_sem;
     rt_sem_t rxdma_xfer_done_sem;
+    void (*spi_pins_init)(SPI_Type *spi_base);
 };
 
 static rt_err_t hpm_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg);
@@ -59,6 +61,11 @@ static struct hpm_spi hpm_spis[] =
         .tx_dmamux = HPM_DMA_SRC_SPI0_TX,
         .rx_dmamux = HPM_DMA_SRC_SPI0_RX,
         .spi_irq   = IRQn_SPI0,
+#if !defined BSP_SPI0_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
     },
 #endif
 #if defined(BSP_USING_SPI1)
@@ -71,6 +78,11 @@ static struct hpm_spi hpm_spis[] =
         .tx_dmamux = HPM_DMA_SRC_SPI1_TX,
         .rx_dmamux = HPM_DMA_SRC_SPI1_RX,
         .spi_irq   = IRQn_SPI1,
+#if !defined BSP_SPI1_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
     },
 #endif
 #if defined(BSP_USING_SPI2)
@@ -83,6 +95,11 @@ static struct hpm_spi hpm_spis[] =
         .tx_dmamux = HPM_DMA_SRC_SPI2_TX,
         .rx_dmamux = HPM_DMA_SRC_SPI2_RX,
         .spi_irq   = IRQn_SPI2,
+#if !defined BSP_SPI2_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
     },
 #endif
 #if defined(BSP_USING_SPI3)
@@ -95,6 +112,79 @@ static struct hpm_spi hpm_spis[] =
         .tx_dmamux = HPM_DMA_SRC_SPI3_TX,
         .rx_dmamux = HPM_DMA_SRC_SPI3_RX,
         .spi_irq   = IRQn_SPI3,
+#if !defined BSP_SPI3_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
+    },
+#endif
+#if defined(BSP_USING_SPI4)
+    {
+        .bus_name = "spi4",
+        .spi_base = HPM_SPI4,
+#if defined(BSP_SPI4_USING_DMA)
+        .enable_dma = RT_TRUE,
+#endif
+        .tx_dmamux = HPM_DMA_SRC_SPI4_TX,
+        .rx_dmamux = HPM_DMA_SRC_SPI4_RX,
+        .spi_irq   = IRQn_SPI4,
+#if !defined BSP_SPI4_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
+    },
+#endif
+#if defined(BSP_USING_SPI5)
+    {
+        .bus_name = "spi5",
+        .spi_base = HPM_SPI5,
+#if defined(BSP_SPI5_USING_DMA)
+        .enable_dma = RT_TRUE,
+#endif
+        .tx_dmamux = HPM_DMA_SRC_SPI5_TX,
+        .rx_dmamux = HPM_DMA_SRC_SPI5_RX,
+        .spi_irq   = IRQn_SPI5,
+#if !defined BSP_SPI5_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
+    },
+#endif
+#if defined(BSP_USING_SPI6)
+    {
+        .bus_name = "spi6",
+        .spi_base = HPM_SPI6,
+#if defined(BSP_SPI6_USING_DMA)
+        .enable_dma = RT_TRUE,
+#endif
+        .tx_dmamux = HPM_DMA_SRC_SPI6_TX,
+        .rx_dmamux = HPM_DMA_SRC_SPI6_RX,
+        .spi_irq   = IRQn_SPI6,
+#if !defined BSP_SPI6_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
+    },
+#endif
+#if defined(BSP_USING_SPI7)
+    {
+        .bus_name = "spi7",
+        .spi_base = HPM_SPI7,
+#if defined(BSP_SPI7_USING_DMA)
+        .enable_dma = RT_TRUE,
+#endif
+        .tx_dmamux = HPM_DMA_SRC_SPI7_TX,
+        .rx_dmamux = HPM_DMA_SRC_SPI7_RX,
+        .spi_irq   = IRQn_SPI7,
+#if !defined BSP_SPI7_USING_HARD_CS
+        .spi_pins_init = init_spi_pins_with_gpio_as_cs,
+#else
+        .spi_pins_init = init_spi_pins,
+#endif
     },
 #endif
 };
@@ -197,7 +287,7 @@ static rt_err_t hpm_spi_configure(struct rt_spi_device *device, struct rt_spi_co
     spi_master_get_default_timing_config(&timing_config);
     spi_master_get_default_format_config(&format_config);
 
-    init_spi_pins_with_gpio_as_cs(spi->spi_base);
+    spi->spi_pins_init(spi->spi_base);
 
     timing_config.master_config.clk_src_freq_in_hz = board_init_spi_clock(spi->spi_base);
 

+ 24 - 2
bsp/hpmicro/libraries/drivers/drv_uart_v2.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -9,6 +9,7 @@
  * 2022-07-28   HPMicro     Fix compiling warning if RT_SERIAL_USING_DMA was not defined
  * 2022-08-08   HPMicro     Integrate DMA Manager and support dynamic DMA resource assignment'
  * 2023-03-07   HPMicro     Fix the issue that the data_width was not initialized before setup dma handshake
+ * 2024-06-10   HPMicro     Fix memory leakage issue
  *
  */
 #include <rtthread.h>
@@ -34,6 +35,7 @@ typedef struct dma_channel {
     void (*tranfer_done)(struct rt_serial_device *serial);
     void (*tranfer_abort)(struct rt_serial_device *serial);
     void (*tranfer_error)(struct rt_serial_device *serial);
+    void *ringbuf_ptr;
 } hpm_dma_channel_handle_t;
 
 //static struct dma_channel dma_channels[DMA_SOC_CHANNEL_NUM];
@@ -596,6 +598,10 @@ static void uart_rx_done(struct rt_serial_device *serial)
             uint32_t aligned_size = aligned_end - aligned_start;
             l1c_dc_invalidate(aligned_start, aligned_size);
     }
+    /* if open uart again after closing uart, an idle interrupt may be triggered, but uart initialization is not performed at this time, and the program exits if the rxfifo is empty. */
+    if (rx_fifo == RT_NULL) {
+        return;
+    }
     rt_ringbuffer_put(&(rx_fifo->rb), uart->rx_idle_tmp_buffer, uart_recv_data_count);
     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE);
 #else
@@ -903,9 +909,17 @@ static rt_err_t hpm_uart_control(struct rt_serial_device *serial, int cmd, void
             else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX) {
                 dma_mgr_disable_chn_irq(&uart->tx_chn_ctx.resource, DMA_INTERRUPT_MASK_ALL);
                 dma_abort_channel(uart->tx_chn_ctx.resource.base, uart->tx_chn_ctx.resource.channel);
+                if (uart->tx_chn_ctx.ringbuf_ptr != RT_NULL) {
+                    rt_free(uart->tx_chn_ctx.ringbuf_ptr);
+                    uart->tx_chn_ctx.ringbuf_ptr = RT_NULL;
+                }
             } else if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) {
                 dma_mgr_disable_chn_irq(&uart->rx_chn_ctx.resource, DMA_INTERRUPT_MASK_ALL);
                 dma_abort_channel(uart->rx_chn_ctx.resource.base, uart->rx_chn_ctx.resource.channel);
+                if (uart->rx_chn_ctx.ringbuf_ptr != RT_NULL) {
+                    rt_free(uart->rx_chn_ctx.ringbuf_ptr);
+                    uart->rx_chn_ctx.ringbuf_ptr = RT_NULL;
+                }
             }
 #endif
             break;
@@ -932,6 +946,10 @@ static rt_err_t hpm_uart_control(struct rt_serial_device *serial, int cmd, void
                     RT_ASSERT(rx_fifo != RT_NULL);
                     tmp_buffer = rt_malloc(serial->config.rx_bufsz + HPM_L1C_CACHELINE_SIZE);
                     RT_ASSERT(tmp_buffer != RT_NULL);
+                    if (uart->rx_chn_ctx.ringbuf_ptr != RT_NULL) {
+                        rt_free(uart->rx_chn_ctx.ringbuf_ptr);
+                    }
+                    uart->rx_chn_ctx.ringbuf_ptr = (void *)tmp_buffer;
                     tmp_buffer += (HPM_L1C_CACHELINE_SIZE - ((rt_ubase_t) tmp_buffer % HPM_L1C_CACHELINE_SIZE));
                     rt_ringbuffer_init(&rx_fifo->rb, tmp_buffer, serial->config.rx_bufsz);
                     rt_ringbuffer_reset(&rx_fifo->rb);
@@ -947,7 +965,11 @@ static rt_err_t hpm_uart_control(struct rt_serial_device *serial, int cmd, void
                     RT_ASSERT(tx_fifo != RT_NULL);
                     tmp_buffer = rt_malloc(serial->config.tx_bufsz + HPM_L1C_CACHELINE_SIZE);
                     RT_ASSERT(tmp_buffer != RT_NULL);
-                    tmp_buffer+= (HPM_L1C_CACHELINE_SIZE - ((rt_ubase_t) tmp_buffer % HPM_L1C_CACHELINE_SIZE));
+                    if (uart->tx_chn_ctx.ringbuf_ptr != RT_NULL) {
+                        rt_free(uart->tx_chn_ctx.ringbuf_ptr);
+                    }
+                    uart->tx_chn_ctx.ringbuf_ptr = (void *)tmp_buffer;
+                    tmp_buffer += (HPM_L1C_CACHELINE_SIZE - ((rt_ubase_t) tmp_buffer % HPM_L1C_CACHELINE_SIZE));
                     rt_ringbuffer_init(&tx_fifo->rb, tmp_buffer, serial->config.tx_bufsz);
                     rt_ringbuffer_reset(&tx_fifo->rb);
                     tx_fifo->activated = RT_FALSE;

+ 254 - 1
bsp/hpmicro/libraries/hpm_sdk/CHANGELOG.md

@@ -1,6 +1,259 @@
 # Change Log
 
-## [1.5.0] - 2024-02-29:
+## [1.6.0] - 2024-06-28:
+
+Main changes since 1.5.0
+Tested Segger Embedded Studio Version: 8.10d
+Tested IAR Embedded Workbench for RISC-V Version: 3.30.1
+
+### Known Issue:
+  - some IAR projects does not work properly when optimization level is increased
+
+### Changed:
+  - soc: reorganize the directory structure
+  - soc: hpm6750: declare get_frequency_for_source API for clock drver header file
+  - soc: update soc cmakelists to add b ext info
+  - soc: hpm6750: add feature for ioc pad ctrl setting issue
+  - soc: toolchains: gcc: correct LMA for NOLOAD sections
+  - soc: move eh_frame into separate section
+  - boards: hpm6750xxxx apply workaround for E00029.
+  - boards: change hpm5301evklite adc16 channel
+  - boards: board.h: adc16: add marco BOARD_APP_ADC16_HW_TRIG_SRC_CLK_NAME
+  - boards: adjust function position of adc pin initialization
+  - boards: hpm6300evk and hpm6e00evk: sdram use px07 as femc dqs pin
+  - boards: hpm6e00evk: rename init_sdram_pins to init_femc_pins
+  - boards: hpm6e00evk: change board i2c instance to I2C0
+  - drivers: can/mcan add parameter check for low-level bit timing.
+  - drivers: enet: add bitfield ENET0_RMII_TXCLK_SEL for hpm6300
+  - drivers: i2c: add DATACNT high byte process
+  - drivers: pwm: update HRPWM process
+  - drivers: spi: optimize reading speed for spi_read_data API
+  - drivers: spi: add set/get data phase format APIs for spi master
+  - drivers: spi: delete the spi startand operation APIs
+  - drivers: adc16: remove an unused member conv_duration from adc16_config_t
+  - drivers: enet: update for enet_interrupt_enable_t
+  - drivers: mcan reduce unnecessary register access in mcan_read_rxfifo.
+  - drivers: mtg: add calculate function param clock
+  - drivers: mtg: add several calculate functions
+  - drivers: mcan lookeup the mcan msg ram base via mcan_soc_msg_buf variable if the MSG_BUF is in AHB RAM.
+  - drivers: adc16: disable improvement logic of adc16 for continuous sampling maximum voltage
+  - drivers: mcan improve transmitter delay compensation setting logic.
+  - drivers: femc: rename data_width_in_byte to cmd_data_width
+  - drivers: femc: update ns2cycle() to align up
+  - drivers: common: add packed attribute
+  - drivers: femc: delete duplicate config
+  - drivers: mtg: change the default parameters to the low order filter
+  - drivers: adc16: add API adc16_set_seq_hw_trigger_enable()
+  - drivers: spi : convert enumeration return in that gets parameters APIs
+  - drivers: pwm: add fault recovery code.
+  - driver: pwm: change pwm trig time
+  - components: enet_phy: dp83867/rtl8211: move the macro definition RGMII to board-level CMakeLists.txt
+  - components: eeprom_emulation: Add ATTR_RAMFUNC for all function
+  - components: eeprom_emulation: add power-off protection mechanism.
+  - components: dma_mgr: add burst in fixed transfer size and swap feature
+  - components: spi: add full_duplex and half_duplex operating APIs
+  - components: spi: support 1 to 32 bits width transfer for nonblocking APIs
+  - components: usb: device: support iso transfer mult feature
+  - middleware: hpm_sdmmc add emmc sleep & wakeup function.
+  - middleware: tinyusb: ehci: support chain transfer
+  - middleware: threadx: add low power support
+  - middleware: cherryusb: update for advance descriptor
+  - middleware: hpm_sdmmc:  optimized to support multiple cards
+  - middleware: cherryusb/tinyusb/usbx: enable suspend isr
+  - middleware: FreeRTOS: update to 202210.01 lts
+  - middleware: cherryusb: update to v1.3.0
+  - middleware: freertos: modify missed timer count num
+  - middleware: freertos: update IAR port file
+  - middleware: freertos: delete fence operations
+  - middleware: freertos: make the calculation more simple.
+  - middleware: hpm_sdmmc add cache control macro.
+  - middleware: hpm_sdmmc: improve the logic for detecting CMD23 support.
+  - middleware: freertos: add tickless stop mode support
+  - middleware: freertos: add user custom process function call
+  - middleware: hpm_mcl_v2: add hpm smc control.
+  - middleware: freertos: place xPortxxx to isr_vector section
+  - middleware: hpm_math: add dsp support for zcc
+  - middleware: microros: add zcc support
+  - middleware: rtos: asm adjustment for zcc toolchain
+  - middleware: hpm_mcl_v2: add pwm dead area compensation.
+  - middleware: hpm_mcl_v2: add dq axis decoupling function
+  - middleware: cherryusb: add macro USBH_USE_CUSTOM_ISR/USBD_USE_CUSTOM_ISR
+  - middleware: lvgl: upgrade to v9
+  - middleware: lvgl: rewrite the scissor.
+  - middleware: lvgl: upgrade allocate algorithm for draw_buf.
+  - samples: rdc: remove unused dac driver in sample
+  - samples: lwip/netxduo/modbus: add conditional compile for reference clock setting in RMII mode
+  - samples: audio_codec: common: change FIL_SEARCH_NUM from 10 to 20
+  - samples: dhyrstone: surpress build warnings
+  - samples: dhrystone Optimize performance.
+  - samples: coremark Optimize performance.
+  - samples: drivers: spi: interrupt: transmission optimization. The transmission will start after the configuration is completed.
+  - samples: adapt spi components to drive and move to the samples dir for spi sdcard samples
+  - samples: cherryusb: device: change descriptor string to HPMicro
+  - samples: cherryusb: device: use advanced descriptor to support high/full speed
+  - samples: rename jpeg to image
+  - samples: drivers: sdxc: sd_fatfs: add card hotplug support
+  - samples: cherryusb: host: usbnet:  replace block to noblock for read terminal char
+  - samples: cherryusb: host: usbnet: decrease lwip MEM_SIZE
+  - samples: cherryusb: move host hid info print code to thread
+  - samples: audio_codec: refactoring code
+  - samples: spi: dma: SPI master transmission optimization
+  - samples: mtg: make the open_loop_trajectory sample more readable
+  - samples: drivers: adc16: add some misc optimization
+  - samples: drivers: adc16: add pwmv2 support
+  - samples: motor_ctrl: bldc_foc_hw: remove hardware control
+  - samples: drivers: mcan add tips for the usage of tdc.
+  - samples: vglite: update rtos config file to fit gptmr tickless mode
+  - samples: lwip/modus/netxduo: add a function call to get the enet default interrupt config
+  - samples: sdm: using pwm to provide clock for sdm sensor.
+  - samples: spi_components: half_duplex: updated to support 1 to 32bits width transfer
+  - samples: spi_components: full_duplex: updated to support 1 to 32bits width transfer
+  - samples: add freertos tickless stop mode sample
+  - samples: benchmark: update compile options for zcc
+  - samples: drivers: adc16: optimize the process logic of sequence and preemption
+  - samples: drivers: sei: device: tamagawa: update eeprom cmd
+  - samples: adc12: optimization for trigger mux and trigger frequency settings
+  - samples: sei: device: tamagawa: support EEPROM protocol
+  - samples: mcl: add pwm dead area compensation.
+  - samples: motor_ctrl: add dq axis decoupling function
+  - samples: cherryusb: move dual_port samples to dual_port folder
+  - samples: cherryusb: adapter to cherryusb v1.3.0
+  - samples: drivers: adc12/adc16/dac: support abort feature in interactive terminal
+  - samples: lwip: lwip_iperf: support abort feature to reselect the test mode
+  - samples: lwip: common: multiple: add definitions of remote ip addresses for iperf
+  - samples: motor_ctrl: bldc_lvlg_foc: add lvgl v8.3.5 for this demo
+  - samples: tinyusb: uac2: support full speed
+  - samples: power_mode_switch: update readme
+  - samples: cherryusb: uac2: change default samplerate order
+  - samples: bldc_foc: update bldc_foc_angle_align() for hardware loop
+  - cmake: toolchain: add ar option to remove timestamp
+  - cmake: toolchain: suppress output while querying spec
+  - cmake: lld: update link option for zcc
+  - cmake/scripts/soc: support b ext convertion to tools
+  - cmake: sdk_app_src_glob: modify to recursive
+
+### Fixed:
+  - soc: update USE_NONVECTOR_MODE defined used
+  - soc: initialize .fast_ram.* section
+  - soc: iar linker: fix safe stack init
+  - soc: add missing ptmr clock
+  - soc: hpm6880: fix get_frequency_for_i2s error
+  - soc: hpm6880: Modify the value of SPI_SOC_FIFO_DEPTH from 4 to 8. for hpm_soc_feature.h
+  - soc: toolchain: iar fix iar ram_stress issue in ram_debug build.
+  - boards: hpm5301evklite: fixed can't output work for gptmr samples such as pwm_generate
+  - drivers: enet: fix the clearing of DMA PBL setting
+  - drivers: dma: fix dma_clear_transfer_status() API
+  - drivers: sdxc Fix timeout calculation issue and DMA enabling logic.
+  - drivers: adc16: fix the logic of adc16_set_pmt_queue_enable() when the parameter enable is false
+  - drivers: mbox: fix error that BEIE can't be operated by interface
+  - drivers: spi: fixed assignment value error for  spi_set_clock_phase and spi_set_clock_polarity APIs
+  - drivers: lcdc: fix ST and DMA_ST clear api.
+  - drivers: mipi_dsi: fix MIPI_DSI_FMT_RGB565 config.
+  - drivers: spi: fixed assignment error issue for enable/disable address phase APIs
+  - drivers: i2c: fix return value type of i2c_get_data_count()
+  - components: usb device/enet_phy: fix unwanted files in localize folder
+  - components: panle: fix panel timing.
+  - components: eeprom_emulation: demo flash crashed.
+  - middleware: cherryusb: ehci: delete timeout clear before give sem
+  - middleware: uC/OS-III: modify fpu context save&restore
+  - middleware: cherryusb: fix freertos enter/exit critical
+  - middleware: audio_codec: fix hpm_wav_decode() single channel pbuf data
+  - middleware: mclv2: fix andes toolchain compiler error.
+  - middleware: cherryusb: fix ehci_qh_pool init miss busid for v1.3.0
+  - middleware: lwip: apps: lwiperf: fix the bug of failing to restart iperf in TCP/UDP server mode
+  - middleware: tinyusb: fix _usbd_dev.speed error to support full speed
+  - middleware: hpm_mcl_v2: fix uncontrolled after large changes in motor speed.
+  - samples: dhyrstone: fix build issue for release type using nds toolchain
+  - samples: lwip: lwip_tcpclient: fix TCP commnuication error after DHCP enabled
+  - samples: lwip: lwip_tcpclient_freertos_socket: fix connection error before IP assigned from DHCP
+  - samples: correct cmsis_os2/mem_pool project name
+  - samples: multicore: common Fix SDP memcpy blocking issue in ram_build.
+  - samples: lwip: lwip_tcpecho_xxx_rtthread_nano: fix failing to get IP by DHCP serivice
+  - samples: spi_sdcard: fixed the place section name error issue
+  - samples: cherryusb: audio: fix wm8960 codec volume max value
+  - samples: img: jpeg_decode: fix decode when only one qtab exist.
+  - samples: tflm: mlperf: remove unnecessary codes.
+  - samples: fix cherryusb mic no sound error
+  - samples: spi_components: polling: fixed doesn't work for polling samples
+  - samples: tamagawa: fix delay times is zero.
+  - samples: bldc_foc: fix hardware_foc position loop error
+  - cmake: link ndsgcc itf for application
+  - cmake: localize_sdk: use utf-8 as default encoding
+  - cmake: ide: keep preprocessing definition
+
+### Added:
+  - soc: add zcc toolchain support
+  - soc: clock_driver Add clock_set_wdg_source API.
+  - soc: gcc linker: add fast_ram.init section size overflow check
+  - soc: add FreeRTOS vector mode support
+  - soc/board: add HPM6E80 support
+  - drivers: common: add macros for .fast_ram.*
+  - drivers: enet: add an API enet_get_default_interrupt_config
+  - drivers: enet: add MII mode support
+  - drivers: common add api for converting tick to us or ms.
+  - drivers: pllctlv2 add new API to configure PLL.
+  - drivers: uart: add uart_modem_write_rts_pin API
+  - drivers: uart: add get/clear addr match flags APIs such as addr_match, addr_match_idle, data_lost
+  - drivers: add lobs drivers
+  - drivers: usb: add some APIs for low power future usage drivers: spi: add spi_slave_set_user_status API
+  - drivers: usb: add suspend/resume APIs
+  - drivers: usb: add enter/exit lower power suspend APIs
+  - drivers: spi: add read SPI RX/TX FIFO size APIs
+  - drivers: usb: add usb_set_port_test_mode() API
+  - drivers: sdp add new apis.
+  - drivers: mcan add new api for canceling pending transmission.
+  - drivers: mtg: add get&clear event irq interface
+  - drivers: qeiv2: add oneshot mode
+  - drivers: add clc driver
+  - drivers: add vsc driver
+  - drivers: spi: add get/set shift direction APIs
+  - drivers: uart: add an new API uart_try_receive_byte()
+  - drivers: pixelmux: add api that set mipi dsi date type.
+  - drivers: gptmr: add monitor function APIs
+  - drivers: gptmr: add opmode APIs
+  - drivers: gptmr: add qeimode APIs
+  - components: add i2s_over_spi
+  - components: codec: add wm8978
+  - components: enet_phy: add jl1111 driver
+  - components: add ppi components
+  - components: touch: add gt9271 driver.
+  - components: debug_console: add a new API console_try_receive_byte()
+  - middleware: add lodepng
+  - middleware: add minimp3
+  - samples: cherryusb: device: add WinUSB 1.0 and WinUSB 2.0 samples
+  - samples: lwip: add LPI interrupt mask setting
+  - samples: add i2s_emulation sample
+  - samples: lvgl_audio_player: support mp3 decoder
+  - samples: uart: add uart_rx_line_status sample
+  - samples: add half_duplex samples for spi_components
+  - samples: add full_duplex samples for spi_components
+  - samples: drivers: sdxc: emmc add new sameple for eMMC sleep & awake.
+  - samples: drivers: add lobs sample
+  - samples: drivers: spi: sd/sd_fatfs: support DMA transfer
+  - samples: threadx: add low power mode sample
+  - samples: image: add png encoder sample
+  - samples: image: add png decoder sample
+  - samples: audio_codec: add decoder_mp3 sample
+  - samples: ppi: add parallel adc sample
+  - samples: ppi: add async_sram sample
+  - samples: qeov2: add wave_out sample
+  - samples: qeov2: add abz_out sample
+  - samples: pwm: add async fault demo
+  - samples: motor_ctrl: add hardware foc
+  - samples: drivers: pwmv2: add pwmv2 pair waveform
+  - samples: dmav2: add dmav2_fixed_burst_swap sample
+  - samples: qeiv2: add oneshot mode sample
+  - samples: add smix_dao sample.
+  - samples: add ecat_io sample.
+  - samples: cherryusb: add one host and one device dual port sample
+  - samples: add pwm/hrpwm fault mode
+  - samples: lwip: add lwip_iperf_multi_ports
+  - samples: drivers: tsw: add a tsn_switch sample
+  - cmake: add symbol HPM_BUILD_TYPE to specify build type
+  - docs: add generated cmake_intro.rst
+  - docs: getting started: add zcc support related information
+
+## [1.5.0] - 2024-03-29:
 
 Main changes since 1.4.0
 

+ 18 - 5
bsp/hpmicro/libraries/hpm_sdk/SConscript

@@ -5,7 +5,7 @@ from building import *
 cwd = GetCurrentDir()
 
 # Update include path
-path = [ cwd + '/arch', cwd + "/drivers/inc", cwd + '/soc/ip']
+path = [ cwd + '/arch', cwd + "/drivers/inc", cwd + '/soc/' + rtconfig.SOC_FAMILY + '/' + '/ip']
 
 # The set of source files associated with this SConscript file.
 src = []
@@ -13,11 +13,14 @@ src = []
 CPPDEFINES=[]
 
 src += ['drivers/src/hpm_pmp_drv.c']
-src += ['drivers/src/hpm_pllctl_drv.c']
-src += ['drivers/src/hpm_pllctlv2_drv.c']
 src += ['drivers/src/hpm_pcfg_drv.c']
 
-if rtconfig.CHIP_NAME == "HPM6750" or rtconfig.CHIP_NAME == "HPM6360" or rtconfig.CHIP_NAME == "HPM6280":
+if rtconfig.SOC_FAMILY == "HPM6700":
+    src += ['drivers/src/hpm_pllctl_drv.c']
+else:
+    src += ['drivers/src/hpm_pllctlv2_drv.c']
+
+if rtconfig.SOC_FAMILY == "HPM6700" or rtconfig.SOC_FAMILY == "HPM6300" or rtconfig.SOC_FAMILY == "HPM6200":
     src += ['drivers/src/hpm_dma_drv.c']
 else:
     src += ['drivers/src/hpm_dmav2_drv.c']
@@ -77,7 +80,10 @@ if GetDepend(['BSP_USING_FEMC']):
 if GetDepend(['BSP_USING_PWM']):
     src += ['drivers/src/hpm_pwm_drv.c']
 
-if GetDepend(['BSP_USING_USB']) or GetDepend(['RT_USING_CHERRYUSB']):
+if GetDepend(['BSP_USING_PWMV2']):
+    src += ['drivers/src/hpm_pwmv2_drv.c']
+
+if GetDepend(['BSP_USING_USB']):
     src += ['drivers/src/hpm_usb_drv.c']
 
 if GetDepend(['BSP_USING_I2S']):
@@ -110,6 +116,13 @@ if GetDepend(['BSP_USING_MIPI_CSI']):
 if GetDepend(['BSP_USING_MIPI_DSI']):
     src += ['drivers/src/hpm_mipi_dsi_drv.c']
     src += ['drivers/src/hpm_mipi_dsi_phy_drv.c']
+
+if GetDepend(['BSP_USING_LVB']):
+    src += ['drivers/src/hpm_lvb_drv.c']
+
+if GetDepend(['BSP_USING_LCB']):
+    src += ['drivers/src/hpm_lcb_drv.c']
+
 group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES=CPPDEFINES)
 
 Return ('group')

+ 5 - 5
bsp/hpmicro/libraries/hpm_sdk/components/SConscript

@@ -16,11 +16,11 @@ src = []
 src += [ os.path.join(cwd, 'debug_console', 'hpm_debug_console.c') ]
 src += [ os.path.join(cwd, 'dma_mgr', 'hpm_dma_mgr.c') ]
 
-if GetDepend(['BSP_USING_TOUCH_GT911']):
-	src += [os.path.join(cwd, 'touch', 'gt911', 'hpm_touch_gt911.c') ]
-	src += [os.path.join(cwd, 'touch', 'gt911', 'hpm_gt911.c') ]
-	path += [ os.path.join(cwd, 'touch', 'gt911') ]
-	CPPDEFINES += ['CONFIG_TOUCH_GT911=1']
+if GetDepend(['BSP_USING_TOUCH_GT9xx']):
+	src += [os.path.join(cwd, 'touch', 'gt9xx', 'hpm_touch_gt9xx.c') ]
+	src += [os.path.join(cwd, 'touch', 'gt9xx', 'hpm_gt9xx.c') ]
+	path += [ os.path.join(cwd, 'touch', 'gt9xx') ]
+	CPPDEFINES += ['CONFIG_TOUCH_GT9XX=1']
 if GetDepend(['BSP_USING_TOUCH_FT5406']):
 	src += [ os.path.join(cwd, 'touch', 'ft5406', 'hpm_touch_ft5406.c') ]
 	src += [ os.path.join(cwd, 'touch', 'ft5406', 'hpm_ft5406.c') ]

+ 405 - 0
bsp/hpmicro/libraries/hpm_sdk/components/codec/wm8978/hpm_wm8978.c

@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include "hpm_wm8978.h"
+
+#define WM8978_I2C_SLAVE_ADDRESS1  (0x1A)
+#define WM8978_I2C_SLAVE_ADDRESS2  (0x1A)
+
+/* store reg value */
+static volatile uint16_t wm8978_reg_val[] = {
+    0x000, 0x000, 0x000, 0x000, 0x050, 0x000, 0x140, 0x000,
+    0x000, 0x000, 0x000, 0x0FF, 0x0FF, 0x000, 0x100, 0x0FF,
+    0x0FF, 0x000, 0x12C, 0x02C, 0x02C, 0x02C, 0x02C, 0x000,
+    0x032, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+    0x038, 0x00B, 0x032, 0x000, 0x008, 0x00C, 0x093, 0x0E9,
+    0x000, 0x000, 0x000, 0x000, 0x003, 0x010, 0x010, 0x100,
+    0x100, 0x002, 0x001, 0x001, 0x039, 0x039, 0x039, 0x039,
+};
+;
+
+hpm_stat_t wm8979_init(wm8978_context_t *control)
+{
+    hpm_stat_t stat;
+    uint8_t i;
+    for (i = 0; i < 0x7F; i++) {
+        if (i2c_master_write(control->ptr, i, NULL, 0) == status_success) {
+            if ((i == WM8978_I2C_SLAVE_ADDRESS1) || (i == WM8978_I2C_SLAVE_ADDRESS2)) {
+                control->device_address = i;
+                break;
+            }
+        }
+    }
+    if (i == 0x7F) {
+        return status_fail;
+    }
+    stat = wm8978_reset(control);
+    return stat;
+}
+
+hpm_stat_t wm8978_reset(wm8978_context_t *control)
+{
+    hpm_stat_t stat = status_success;
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RESET, 0));
+    return stat;
+}
+
+hpm_stat_t wm8978_set_out_volume(wm8978_context_t *control, wm8978_out_channel_t channel, uint8_t volume)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t l_out_reg;
+    uint8_t r_out_reg;
+    if (volume > WM8978_OUT_VOLUME_MASK) {
+        volume = WM8978_OUT_VOLUME_MASK;
+    }
+    if (channel == wm8978_out1_channel) {
+        l_out_reg = WM8978_LOUT1_VOLUME_CTRL;
+        r_out_reg = WM8978_ROUT1_VOLUME_CTRL;
+    } else if (channel == wm8978_out2_channel) {
+        l_out_reg = WM8978_LOUT2_VOLUME_CTRL;
+        r_out_reg = WM8978_ROUT2_VOLUME_CTRL;
+    } else {
+        return status_invalid_argument;
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, l_out_reg, WM8978_OUT_VOLUME_SET(volume) | WM8978_OUT_SPKVU_SET(0)));
+    /* LOUT1/2 and ROUT1/2 volumes do not update untila 1 is written to SPKkVU */
+    HPM_CHECK_RET(wm8978_write_reg(control, r_out_reg, WM8978_OUT_VOLUME_SET(volume) | WM8978_OUT_SPKVU_SET(1)));
+    return stat;
+}
+
+hpm_stat_t wm8978_get_out_volume(wm8978_context_t *control, wm8978_out_channel_t channel, uint8_t *volume)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t out_reg;
+    uint16_t val;
+    if (channel == wm8978_out1_channel) {
+        out_reg = WM8978_LOUT1_VOLUME_CTRL;
+    } else if (channel == wm8978_out2_channel) {
+        out_reg = WM8978_LOUT2_VOLUME_CTRL;
+    } else {
+        return status_invalid_argument;
+    }
+    HPM_CHECK_RET(wm8978_read_reg(control, out_reg, &val));
+    *volume = WM8978_OUT_VOLUME_GET(val);
+    return stat;
+}
+
+hpm_stat_t wm8978_set_out_mute(wm8978_context_t *control, wm8978_out_channel_t channel, bool mute)
+{
+    hpm_stat_t stat = status_success;
+    uint16_t val;
+    uint8_t l_out_reg;
+    uint8_t r_out_reg;
+    if (channel == wm8978_out1_channel) {
+        l_out_reg = WM8978_LOUT1_VOLUME_CTRL;
+        r_out_reg = WM8978_ROUT1_VOLUME_CTRL;
+    } else if (channel == wm8978_out2_channel) {
+        l_out_reg = WM8978_LOUT2_VOLUME_CTRL;
+        r_out_reg = WM8978_ROUT2_VOLUME_CTRL;
+    } else {
+        return status_invalid_argument;
+    }
+    if (mute == true) {
+        HPM_CHECK_RET(wm8978_read_reg(control, l_out_reg, &val));
+        val |= WM8978_OUT_MUTE_MASK;
+        HPM_CHECK_RET(wm8978_write_reg(control, l_out_reg, val));
+        HPM_CHECK_RET(wm8978_read_reg(control, r_out_reg, &val));
+        val |= WM8978_OUT_MUTE_MASK;
+        HPM_CHECK_RET(wm8978_write_reg(control, r_out_reg, val));
+    } else {
+        HPM_CHECK_RET(wm8978_read_reg(control, l_out_reg, &val));
+        val &= ~WM8978_OUT_MUTE_MASK;
+        HPM_CHECK_RET(wm8978_write_reg(control, l_out_reg, val));
+        HPM_CHECK_RET(wm8978_read_reg(control, r_out_reg, &val));
+        val &= ~WM8978_OUT_MUTE_MASK;
+        HPM_CHECK_RET(wm8978_write_reg(control, r_out_reg, val));
+    }
+    return stat;
+}
+
+hpm_stat_t wm8978_set_mic_gain(wm8978_context_t *control, uint8_t gain)
+{
+    hpm_stat_t stat = status_success;
+    if (gain > WM8978_INPPGA_VOL_MASK) {
+        gain = WM8978_INPPGA_VOL_MASK;
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LINP_PGA_GAIM_CTRL, WM8978_INPPGA_VOL_SET(gain)));
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LINP_PGA_GAIM_CTRL, WM8978_INPPGA_VOL_SET(gain) | WM8978_INPGA_UPDATE_SET(1)));
+    return stat;
+}
+
+hpm_stat_t wm8978_set_line_gain(wm8978_context_t *control, uint8_t gain)
+{
+    uint16_t val;
+    hpm_stat_t stat = status_success;
+    if (gain > WM8978_AUXL2BOOSTVOL_MASK) {
+        gain = WM8978_AUXL2BOOSTVOL_MASK;
+    }
+    HPM_CHECK_RET(wm8978_read_reg(control, WM8978_LADC_BOOST_CTRL, &val));
+    val &= (~WM8978_2_2_BOOSTVOL_MASK);
+    val |= WM8978_2_2_BOOSTVOL_SET(gain);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LADC_BOOST_CTRL, val));
+
+    HPM_CHECK_RET(wm8978_read_reg(control, WM8978_RADC_BOOST_CTRL, &val));
+    val &= ~WM8978_2_2_BOOSTVOL_MASK;
+    val |= WM8978_2_2_BOOSTVOL_SET(gain);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RADC_BOOST_CTRL, val));
+    return stat;
+}
+
+hpm_stat_t wm8978_power_down(wm8978_context_t *control)
+{
+    return wm8978_reset(control);
+}
+
+hpm_stat_t wm8978_cfg_audio_interface(wm8978_context_t *control, wm8978_audio_interface_t standard, wm8978_word_length_t word_len)
+{
+    hpm_stat_t stat = status_success;
+    uint16_t usReg = 0;
+    usReg  |= WM8978_FMT_SET(standard) | WM8978_WL_SET(word_len);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_AUDIO_INTERFACE, usReg));
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_CLOCK_GEN_CTRL, 0x000));
+    return stat;
+}
+
+hpm_stat_t wm8978_cfg_audio_channel(wm8978_context_t *control, input_channel_flags_t in_flags, output_channel_flag_t out_flags)
+{
+    uint16_t reg_val = 0;
+    hpm_stat_t stat = status_success;
+    if ((in_flags == input_off) && (out_flags == output_off)) {
+        wm8978_power_down(control);
+        return stat;
+    }
+
+    reg_val = WM8978_BIASEN_R1_MASK | WM8978_VMIDSEL_R1_SET(3);
+    if (out_flags & out_3_4_on) {
+        reg_val |= (WM8978_OUT4MIXEN_R1_MASK | WM8978_OUT3MIXEN_R1_MASK);
+    }
+    if ((in_flags & mic_left_on) || (in_flags & mic_right_on)) {
+        reg_val |= WM8978_MICBEN_R1_MASK;
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_POWER_MANAGET_1, reg_val));
+
+    reg_val = 0;
+    if (out_flags & earphone_left_on) {
+        reg_val |= WM8978_LOUT1EN_R2_MASK;
+    }
+    if (out_flags & earphone_right_on) {
+        reg_val |= WM8978_ROUT1EN_R2_MASK;
+    }
+    if (in_flags & mic_left_on) {
+        reg_val |= (WM8978_BOOSTENL_R2_MASK | WM8978_INPPGAENL_R2_MASK);
+    }
+    if (in_flags & mic_right_on) {
+        reg_val |= (WM8978_BOOSTENR_R2_MASK | WM8978_INPPGAENR_R2_MASK);
+    }
+    if (in_flags & line_on) {
+        reg_val |= (WM8978_BOOSTENL_R2_MASK | WM8978_BOOSTENR_R2_MASK);
+    }
+    if (in_flags & adc_on) {
+        reg_val |= (WM8978_ADCENR_R2_MASK | WM8978_ADCENL_R2_MASK);
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_POWER_MANAGET_2, reg_val));
+
+    reg_val = 0;
+    if (out_flags & out_3_4_on) {
+        reg_val |= (WM8978_OUT4EN_R3_MASK | WM8978_OUT3EN_R3_MASK);
+    }
+    if (out_flags & spk_on) {
+        reg_val |= (WM8978_LOUT2EN_R3_MASK | WM8978_ROUT2EN_R3_MASK);
+    }
+    if (out_flags != output_off) {
+        reg_val |= (WM8978_RMIXEN_R3_MASK | WM8978_LMIXEN_R3_MASK);
+    }
+    if (in_flags & dac_on) {
+        reg_val |= (WM8978_DACENR_R3_MASK | WM8978_DACENL_R3_MASK);
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_POWER_MANAGET_3, reg_val));
+
+    reg_val = 0 << 8;
+    if (in_flags & line_on) {
+        reg_val |= (WM8978_R2_2INPPGA_R44_MASK | WM8978_L2_2INPPGA_R44_MASK);
+    }
+    if (in_flags & mic_right_on) {
+        reg_val |= (WM8978_RIN2INPPGA_R44_MASK | WM8978_RIP2INPPGA_R44_MASK);
+    }
+    if (in_flags & mic_left_on) {
+        reg_val |= (WM8978_LIN2INPPGA_R44_MASK | WM8978_LIP2INPPGA_R44_MASK);
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_INPUT_CTRL, reg_val));
+    reg_val = 0;
+    if (in_flags & adc_on) {
+        reg_val |= (WM8978_ADCOSR128_R14_MASK) | (0 << 8) | (4 << 0);
+    } else {
+        reg_val = 0;
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_ADC_CONTROL, reg_val));
+
+    if (in_flags & adc_on) {
+        reg_val = (0 << 7);
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER1, reg_val));
+        reg_val = 0;
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER2, reg_val));
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER3, reg_val));
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER4, reg_val));
+    }
+    reg_val = 0;
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_ALC_CONTROL1, reg_val));
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_ALC_CONTROL2, reg_val));
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_ALC_CONTROL3, reg_val));
+
+    /* Disable automatic gain control */
+    reg_val = (3 << 1) | (7 << 0);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOISE_GATE, reg_val));
+
+    reg_val = 0;
+    if ((in_flags & mic_left_on) || (in_flags & mic_right_on)) {
+        reg_val |= (1 << 8); /* MIC gain = +20dB */
+    }
+    if (in_flags & aux_on) {
+        reg_val |= (3 << 0); /* Aux = 3*/
+    }
+    if (in_flags & line_on) {
+        reg_val |= (3 << 4);	/* Line gain = 3 */
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LADC_BOOST_CTRL, reg_val));
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RADC_BOOST_CTRL, reg_val));
+
+    reg_val = 0xFF;
+    /* Select 0dB to cache the left channel first */
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LEFT_ADC_VOL, reg_val));
+    reg_val = 0x1FF;
+    /* Update left and right channels simultaneously */
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RIGHT_ADC_VOL, reg_val));
+
+    reg_val = 0;
+    if (out_flags & spk_on) {
+        /* ROUT2 is inverted and used to drive the speaker */
+        reg_val |= (1 << 4);
+    }
+    if (in_flags & aux_on) {
+        reg_val |= ((7 << 1) | (1 << 0));
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_BEEP_CONTROL, reg_val));
+
+    reg_val = 0;
+    if (in_flags & dac_on) {
+        reg_val |= ((1 << 6) | (1 << 5));
+    }
+    if (out_flags & spk_on) {
+        /* SPK 1.5x gain, thermal protection enabled */
+        reg_val |=  ((1 << 2) | (1 << 1));
+    }
+    if (out_flags & out_3_4_on) {
+        /* BOOT3  BOOT4  1.5x gain */
+        reg_val |=  ((1 << 4) | (1 << 3));
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_OUTPUT_CTRL, reg_val));
+
+    reg_val = 0;
+    if (in_flags & aux_on) {
+        reg_val |= ((7 << 6) | (1 << 5));
+    }
+    if ((in_flags & line_on) || (in_flags & mic_left_on) || (in_flags & mic_right_on)) {
+        reg_val |= ((7 << 2) | (1 << 1));
+    }
+    if (in_flags & dac_on) {
+        reg_val |= (1 << 0);
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LEFT_MIXER_CTRL, reg_val));
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RIGHT_MIXER_CTRL, reg_val));
+
+    reg_val = 0;
+    if (out_flags & out_3_4_on) {
+        reg_val |= (1 << 3);
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_OUT3_MIXER_CTRL, reg_val));
+
+    reg_val = 0;
+    if (out_flags & out_3_4_on) {
+        reg_val |= ((1 << 4) |  (1 << 1));
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_OUT4_MIXER_CTRL, reg_val));
+
+    if (in_flags & dac_on) {
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LEFT_DAC_VOL, 0xFF));
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RIGHT_DAC_VOL, 0x1FF));
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_DAC_CTRL, 0));
+    } else {
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_LEFT_DAC_VOL, 0));
+        HPM_CHECK_RET(wm8978_write_reg(control, WM8978_RIGHT_DAC_VOL, 0x100));
+    }
+    return stat;
+}
+
+hpm_stat_t wm8978_notch_filter(wm8978_context_t *control, uint16_t nfa0, uint16_t nfa1)
+{
+    hpm_stat_t stat = status_success;
+    uint16_t reg_val;
+    reg_val = (1 << 7) | (nfa0 & 0x3F);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER1, reg_val));
+
+    reg_val = ((nfa0 >> 7) & 0x3F);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER2, reg_val));
+
+    reg_val = (nfa1 & 0x3F);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER3, reg_val));
+
+    reg_val = (1 << 8) | ((nfa1 >> 7) & 0x3F);
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_NOTCH_FILTER4, reg_val));
+    return stat;
+}
+
+hpm_stat_t wm8978_ctrl_gpio1(wm8978_context_t *control, bool value)
+{
+    hpm_stat_t stat = status_success;
+    uint16_t reg_val;
+    if (value == false) {
+        reg_val = 6; /* B2:0 = 110 */
+    } else {
+        reg_val = 7; /* B2:0 = 111 */
+    }
+    HPM_CHECK_RET(wm8978_write_reg(control, WM8978_GPIO_CTRL, reg_val));
+    return stat;
+}
+
+hpm_stat_t wm8978_write_reg(wm8978_context_t *control, uint8_t reg, uint16_t val)
+{
+    uint8_t buff[2];
+    /* The first 7 bits (B15 to B9) are address bits that select which control register */
+    /* is accessed. The remaining 9 bits (B8 to B0) are data bits */
+    buff[0] = (reg << 1) | (uint8_t)((val >> 8U) & 0x0001U);
+    buff[1] = (uint8_t)(val & 0xFFU);
+
+    /* record reg val */
+    wm8978_reg_val[reg] = val;
+    return i2c_master_write(control->ptr, control->device_address, buff, 2U);
+}
+
+hpm_stat_t wm8978_read_reg(wm8978_context_t *control, uint8_t reg, uint16_t *val)
+{
+    (void)control;
+    *val = wm8978_reg_val[reg];
+    return status_success;
+}
+
+hpm_stat_t wm8978_modify_reg(wm8978_context_t *control, uint8_t reg, uint16_t mask, uint16_t val)
+{
+    hpm_stat_t stat = status_success;
+    uint16_t reg_val;
+    /* Read the register value out */
+    HPM_CHECK_RET(wm8978_read_reg(control, reg, &reg_val));
+    /* Modify the value */
+    reg_val &= (uint16_t)~mask;
+    reg_val |= val;
+    /* Write the data to register */
+    HPM_CHECK_RET(wm8978_write_reg(control, reg, reg_val));
+    if (stat != status_success) {
+        return status_fail;
+    }
+    return stat;
+}
+

+ 215 - 0
bsp/hpmicro/libraries/hpm_sdk/components/codec/wm8978/hpm_wm8978.h

@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _HPM_W8978_H_
+#define _HPM_W8978_H_
+
+#include "hpm_i2c_drv.h"
+#include "hpm_wm8978_regs.h"
+
+typedef enum wm8978_audio_interface {
+    wm8978_right_justified = 0,  /* Right Justified */
+    wm8978_left_justified,       /* Left Justified */
+    wm8978_philips_i2s,          /* I2S format */
+    wm8978_pcm_mode,             /* DSP/PCM mode */
+} wm8978_audio_interface_t;
+
+typedef enum wm8978_word_length {
+    wm8978_16bits_length        = 0,  /* 16bits */
+    wm8978_20bits_length,           /* 20bits */
+    wm8978_24bits_length,           /* 24bits */
+    wm8978_32bits_length,           /* 32bits */
+} wm8978_word_length_t;
+
+typedef enum wm8978_out_channel {
+    wm8978_out1_channel         = 0,  /* R/LOUT1 channel. */
+    wm8978_out2_channel         = 1, /*  R/LOUT2 channel. */
+} wm8978_out_channel_t;
+
+typedef enum input_channel_flag {
+    input_off                  = 0x00,    /* no input */
+    mic_left_on                = 0x01,    /* LIN,LIP pin,MIC left input */
+    mic_right_on               = 0x02,    /* RIN,RIP pin,MIC right input */
+    line_on                    = 0x04,    /* L2,R2 pin input */
+    aux_on                     = 0x08,    /* AUXL,AUXR pins input */
+    dac_on                     = 0x10,    /* dac for i2s */
+    adc_on                     = 0x20     /* input fed into the WM8978 internal ADC */
+} input_channel_flags_t;
+
+/* WM8978 音频输出通道控制选项, 可以选择多路 */
+typedef enum output_channel_flag {
+    output_off                 = 0x00,    /* no output */
+    earphone_left_on           = 0x01,    /* LOUT1 earphone */
+    earphone_right_on          = 0x02,    /* ROUT1 earphone */
+    spk_on                     = 0x04,    /* LOUT2 and ROUT2 Inverting output mono*/
+    out_3_4_on                 = 0x08,    /* OUT3 and OUT4 output mono audio*/
+} output_channel_flag_t;
+
+typedef struct {
+    I2C_Type *ptr;                      /* I2C bus */
+    uint8_t device_address;             /* code device address */
+} wm8978_context_t;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * @brief WM8979 initialize function.
+ *
+ * @param [in] control WM8979 control structure.
+ * @retval hpm_stat_t status_success if init without any error
+ */
+hpm_stat_t wm8979_init(wm8978_context_t *control);
+
+/**
+ * @brief WM8979 set out volume function.
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] channel out channel
+ * @param [in] volume volume value
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_set_out_volume(wm8978_context_t *control, wm8978_out_channel_t channel, uint8_t volume);
+
+/**
+ * @brief WM8979 read out volume function.
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] channel out channel
+ * @param [out] volume volume points value
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_get_out_volume(wm8978_context_t *control, wm8978_out_channel_t channel, uint8_t *volume);
+
+/**
+ * @brief WM8979 set out mute.
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] channel out channel
+ * @param [in] mute if mute is set to true
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_set_out_mute(wm8978_context_t *control, wm8978_out_channel_t channel, bool mute);
+
+/**
+ * @brief WM8979 set gain of mic.
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] gain gain value, range: 0 ~ 63
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_set_mic_gain(wm8978_context_t *control, uint8_t gain);
+
+/**
+ * @brief WM8979 set the gain of the Line input channel
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] gain volume value, range: 0 ~ 7
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_set_line_gain(wm8978_context_t *control, uint8_t gain);
+
+/**
+ * @brief WM8979 enter power down mode
+ *
+ * @param [in] control WM8979 control structure.
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_power_down(wm8978_context_t *control);
+
+/**
+ * @brief Control the GPIO1 pin of WM8978 to output high or low
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] value output high or low. if true, it's high
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_ctrl_gpio1(wm8978_context_t *control, bool value);
+
+/**
+ * @brief Configuring the audio interface of WM8978
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] standard wm8978_audio_interface_t structure
+ * @param [in] word_len wm8978_word_length_t structure
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_cfg_audio_interface(wm8978_context_t *control,
+                                        wm8978_audio_interface_t standard,
+                                        wm8978_word_length_t word_len);
+
+/**
+ * @brief Configure wm8978 audio channel
+ *
+ * @param [in] control WM8979 control structure.
+ * @param [in] in_flags input_channel_flags_t structure
+ * @param [in] out_flags output_channel_flag_t structure
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_cfg_audio_channel(wm8978_context_t *control,
+                                    input_channel_flags_t in_flags,
+                                    output_channel_flag_t out_flags);
+
+/**
+ * @brief setting the Notch Filter for WM8978
+ *
+ * @note used to suppress positive feedback of microphone sound waves to avoid howling
+ * @param [in] control WM8979 control structure.
+ * @param [in] nfa0 Notch Filter0 value
+ * @param [in] nfa1 Notch Filter1 value
+ * @retval hpm_stat_t status_success if set without any error
+ */
+hpm_stat_t wm8978_notch_filter(wm8978_context_t *control, uint16_t nfa0, uint16_t nfa1);
+
+/**
+ * @brief Write register to WM8978 using I2C.
+ *
+ * @param [in] control WM8978 control structure.
+ * @retval hpm_stat_t status_success if reset without any error
+ */
+hpm_stat_t wm8978_reset(wm8978_context_t *control);
+
+/**
+ * @brief Write register to WM8978 using I2C.
+ *
+ * @param [in] control WM8978 control structure.
+ * @param [in] reg The register address in WM8978.
+ * @param [in] val Value needs to write into the register.
+ * @retval hpm_stat_t status_success if write reg without any error
+ */
+hpm_stat_t wm8978_write_reg(wm8978_context_t *control, uint8_t reg, uint16_t val);
+
+/**
+ * @brief Read register from WM8978 using I2C.
+ * @param [in] reg The register address in WM8978.
+ * @param [in] reg The register address in WM8978.
+ * @param [out] val Value point read to.
+ * @retval hpm_stat_t status_success if read reg without any error
+ */
+hpm_stat_t wm8978_read_reg(wm8978_context_t *control, uint8_t reg, uint16_t *val);
+
+/**
+ * @brief Modify some bits in the register using I2C.
+ * @param [in] control WM8978 control structure.
+ * @param [in] reg The register address in WM8978.
+ * @param [in] mask The mask code for the bits want to write. The bit you want to write should be 0.
+ * @param [in] val Value needs to write into the register.
+ * @retval hpm_stat_t status_success if modify reg without any error
+ */
+hpm_stat_t wm8978_modify_reg(wm8978_context_t *control, uint8_t reg, uint16_t mask, uint16_t val);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ *
+ */
+
+#endif /* HPM_WM8978_H */

+ 549 - 0
bsp/hpmicro/libraries/hpm_sdk/components/codec/wm8978/hpm_wm8978_regs.h

@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _HPM_WM8978_REG_H_
+#define _HPM_WM8978_REG_H_
+
+/* Define the register address of WM8978 */
+#define WM8978_RESET                   0x00U    /* software reset */
+#define WM8978_POWER_MANAGET_1         0x01U    /* power managet 1 */
+#define WM8978_POWER_MANAGET_2         0x02U    /* power managet 2 */
+#define WM8978_POWER_MANAGET_3         0x03U    /* power managet 3 */
+#define WM8978_AUDIO_INTERFACE         0x04U   /* audio interface */
+#define WM8978_CLOCK_GEN_CTRL          0x06U   /* clock gen ctrl */
+#define WM8978_GPIO_CTRL               0x08U   /* GPIO ctrl */
+#define WM8978_DAC_CTRL                0x0AU   /* DAC ctrl */
+#define WM8978_LEFT_DAC_VOL            0x0BU   /* Left DAC digital vol */
+#define WM8978_RIGHT_DAC_VOL           0x0CU   /* Right DAC digital vol  */
+#define WM8978_ADC_CONTROL             0x0EU   /* ADC control */
+#define WM8978_LEFT_ADC_VOL            0x0FU   /* Left ADC digital vol */
+#define WM8978_RIGHT_ADC_VOL           0x10U   /* Right ADC digital vol  */
+#define WM8978_NOTCH_FILTER1           0x1BU   /* notch filter1 */
+#define WM8978_NOTCH_FILTER2           0x1CU   /* notch filter2 */
+#define WM8978_NOTCH_FILTER3           0x1DU   /* notch filter3 */
+#define WM8978_NOTCH_FILTER4           0x1EU   /* notch filter4 */
+#define WM8978_ALC_CONTROL1            0x20U   /* ALC control1 */
+#define WM8978_ALC_CONTROL2            0x21U   /* ALC control2 */
+#define WM8978_ALC_CONTROL3            0x22U   /* ALC control3 */
+#define WM8978_NOISE_GATE              0x23U   /* noise Gate */
+#define WM8978_BEEP_CONTROL            0x2BU   /* beep control */
+#define WM8978_INPUT_CTRL              0x2CU   /* input ctrl */
+#define WM8978_LOUT1_VOLUME_CTRL       0x34U   /* LOUT1 (HP)volume ctrl */
+#define WM8978_ROUT1_VOLUME_CTRL       0x35U   /* ROUT1 (HP)volume ctrl */
+#define WM8978_LOUT2_VOLUME_CTRL       0x36U   /* LOUT2 (SPK)volume ctrl */
+#define WM8978_ROUT2_VOLUME_CTRL       0x37U   /* ROUT2 (SPK)volume ctrl */
+#define WM8978_LINP_PGA_GAIM_CTRL      0x2DU   /* Left INP PGA gain ctrl */
+#define WM8978_RINP_PGA_GAIM_CTRL      0x2EU   /* Right INP PGA gain ctrl */
+#define WM8978_LADC_BOOST_CTRL         0x2FU   /* Left INP PGA gain ctrl */
+#define WM8978_RADC_BOOST_CTRL         0x30U   /* Right INP PGA gain ctrl */
+#define WM8978_OUTPUT_CTRL             0x31U   /* Output ctrl */
+#define WM8978_LEFT_MIXER_CTRL         0x32U   /* left mixer ctrl */
+#define WM8978_RIGHT_MIXER_CTRL        0x33U   /* right mixer ctrl */
+#define WM8978_OUT3_MIXER_CTRL         0x38U   /* out3 mixer ctrl */
+#define WM8978_OUT4_MIXER_CTRL         0x39U   /* out4 mixer ctrl */
+
+/*
+ * BUFDCOPEN (RW)
+ * Dedicated buffer for DC level shifting output stages when in 1.5x gain boost configuration
+ */
+#define WM8978_BUFDCOPEN_R1_MASK   (0x100U)
+#define WM8978_BUFDCOPEN_R1_SHIFT  (8U)
+#define WM8978_BUFDCOPEN_R1_SET(x) (((uint16_t)(x) << WM8978_BUFDCOPEN_R1_SHIFT) & WM8978_BUFDCOPEN_R1_MASK)
+#define WM8978_BUFDCOPEN_R1_GET(x) (((uint16_t)(x) & WM8978_BUFDCOPEN_R1_MASK) >> WM8978_BUFDCOPEN_R1_SHIFT)
+
+/*
+ * OUT4MIXEN (RW)
+ * OUT4 mixer enable
+ */
+#define WM8978_OUT4MIXEN_R1_MASK   (0x80U)
+#define WM8978_OUT4MIXEN_R1_SHIFT  (7U)
+#define WM8978_OUT4MIXEN_R1_SET(x) (((uint16_t)(x) << WM8978_OUT4MIXEN_R1_SHIFT) & WM8978_OUT4MIXEN_R1_MASK)
+#define WM8978_OUT4MIXEN_R1_GET(x) (((uint16_t)(x) & WM8978_OUT4MIXEN_R1_MASK) >> WM8978_OUT4MIXEN_R1_SHIFT)
+
+/*
+ * OUT3MIXEN (RW)
+ * OUT3 mixer enable
+ */
+#define WM8978_OUT3MIXEN_R1_MASK   (0x40U)
+#define WM8978_OUT3MIXEN_R1_SHIFT  (6U)
+#define WM8978_OUT3MIXEN_R1_SET(x) (((uint16_t)(x) << WM8978_OUT3MIXEN_R1_SHIFT) & WM8978_OUT3MIXEN_R1_MASK)
+#define WM8978_OUT3MIXEN_R1_GET(x) (((uint16_t)(x) & WM8978_OUT3MIXEN_R1_MASK) >> WM8978_OUT3MIXEN_R1_SHIFT)
+
+/*
+ * PLLEN (RW)
+ * PLL enable
+ */
+#define WM8978_PLLEN_R1_MASK   (0x20U)
+#define WM8978_PLLEN_R1_SHIFT  (5U)
+#define WM8978_PLLEN_R1_SET(x) (((uint16_t)(x) << WM8978_PLLEN_R1_SHIFT) & WM8978_PLLEN_R1_MASK)
+#define WM8978_PLLEN_R1_GET(x) (((uint16_t)(x) & WM8978_PLLEN_R1_MASK) >> WM8978_PLLEN_R1_SHIFT)
+
+/*
+ * MICBEN (RW)
+ * Microphone Bias Enable
+ */
+#define WM8978_MICBEN_R1_MASK   (0x10U)
+#define WM8978_MICBEN_R1_SHIFT  (4U)
+#define WM8978_MICBEN_R1_SET(x) (((uint16_t)(x) << WM8978_MICBEN_R1_SHIFT) & WM8978_MICBEN_R1_MASK)
+#define WM8978_MICBEN_R1_GET(x) (((uint16_t)(x) & WM8978_MICBEN_R1_MASK) >> WM8978_MICBEN_R1_SHIFT)
+
+/*
+ * BIASEN (RW)
+ * Analogue amplifier bias control
+ */
+#define WM8978_BIASEN_R1_MASK   (0x08U)
+#define WM8978_BIASEN_R1_SHIFT  (3U)
+#define WM8978_BIASEN_R1_SET(x) (((uint16_t)(x) << WM8978_BIASEN_R1_SHIFT) & WM8978_BIASEN_R1_MASK)
+#define WM8978_BIASEN_R1_GET(x) (((uint16_t)(x) & WM8978_BIASEN_R1_MASK) >> WM8978_BIASEN_R1_SHIFT)
+
+
+/*
+ * BUFIOEN (RW)
+ * Unused input/output tie off buffer enable
+ */
+#define WM8978_BUFIOEN_R1_MASK   (0x04U)
+#define WM8978_BUFIOEN_R1_SHIFT  (2U)
+#define WM8978_BUFIOEN_R1_SET(x) (((uint16_t)(x) << WM8978_BUFIOEN_R1_SHIFT) & WM8978_BUFIOEN_R1_MASK)
+#define WM8978_BUFIOEN_R1_GET(x) (((uint16_t)(x) & WM8978_BUFIOEN_R1_MASK) >> WM8978_BUFIOEN_R1_SHIFT)
+
+/*
+ * VMIDSEL (RW)
+ * Reference string impedance to VMID pin
+ */
+#define WM8978_VMIDSEL_R1_MASK   (0x03U)
+#define WM8978_VMIDSEL_R1_SHIFT  (0U)
+#define WM8978_VMIDSEL_R1_SET(x) (((uint16_t)(x) << WM8978_VMIDSEL_R1_SHIFT) & WM8978_VMIDSEL_R1_MASK)
+#define WM8978_VMIDSEL_R1_GET(x) (((uint16_t)(x) & WM8978_VMIDSEL_R1_MASK) >> WM8978_VMIDSEL_R1_SHIFT)
+
+/*
+ * ROUT1EN (RW)
+ * ROUT1 output enable
+ */
+#define WM8978_ROUT1EN_R2_MASK   (0x100U)
+#define WM8978_ROUT1EN_R2_SHIFT  (8U)
+#define WM8978_ROUT1EN_R2_SET(x) (((uint16_t)(x) << WM8978_ROUT1EN_R2_SHIFT) & WM8978_ROUT1EN_R2_MASK)
+#define WM8978_ROUT1EN_R2_GET(x) (((uint16_t)(x) & WM8978_ROUT1EN_R2_MASK) >> WM8978_ROUT1EN_R2_SHIFT)
+
+/*
+ * LOUT1EN (RW)
+ * LOUT1 output enable
+ */
+#define WM8978_LOUT1EN_R2_MASK   (0x80U)
+#define WM8978_LOUT1EN_R2_SHIFT  (7U)
+#define WM8978_LOUT1EN_R2_SET(x) (((uint16_t)(x) << WM8978_LOUT1EN_R2_SHIFT) & WM8978_LOUT1EN_R2_MASK)
+#define WM8978_LOUT1EN_R2_GET(x) (((uint16_t)(x) & WM8978_LOUT1EN_R2_MASK) >> WM8978_LOUT1EN_R2_SHIFT)
+
+/*
+ * SLEEP (RW)
+ * residual current reduced in device standby mode if 1
+ */
+#define WM8978_SLEEP_R2_MASK   (0x40U)
+#define WM8978_SLEEP_R2_SHIFT  (6U)
+#define WM8978_SLEEP_R2_SET(x) (((uint16_t)(x) << WM8978_SLEEP_R2_SHIFT) & WM8978_SLEEP_R2_MASK)
+#define WM8978_SLEEP_R2_GET(x) (((uint16_t)(x) & WM8978_SLEEP_R2_MASK) >> WM8978_SLEEP_R2_SHIFT)
+
+/*
+ * BOOSTENR (RW)
+ * Right channel Input BOOST enable
+ */
+#define WM8978_BOOSTENR_R2_MASK   (0x20U)
+#define WM8978_BOOSTENR_R2_SHIFT  (5U)
+#define WM8978_BOOSTENR_R2_SET(x) (((uint16_t)(x) << WM8978_BOOSTENR_R2_SHIFT) & WM8978_BOOSTENR_R2_MASK)
+#define WM8978_BOOSTENR_R2_GET(x) (((uint16_t)(x) & WM8978_BOOSTENR_R2_MASK) >> WM8978_BOOSTENR_R2_SHIFT)
+
+/*
+ * BOOSTENL (RW)
+ * Left channel Input BOOST enable
+ */
+#define WM8978_BOOSTENL_R2_MASK   (0x10U)
+#define WM8978_BOOSTENL_R2_SHIFT  (4U)
+#define WM8978_BOOSTENL_R2_SET(x) (((uint16_t)(x) << WM8978_BOOSTENL_R2_SHIFT) & WM8978_BOOSTENL_R2_MASK)
+#define WM8978_BOOSTENL_R2_GET(x) (((uint16_t)(x) & WM8978_BOOSTENL_R2_MASK) >> WM8978_BOOSTENL_R2_SHIFT)
+
+/*
+ * INPPGAENR (RW)
+ * Right channel input PGA enable
+ */
+#define WM8978_INPPGAENR_R2_MASK   (0x08U)
+#define WM8978_INPPGAENR_R2_SHIFT  (3U)
+#define WM8978_INPPGAENR_R2_SET(x) (((uint16_t)(x) << WM8978_INPPGAENR_R2_SHIFT) & WM8978_INPPGAENR_R2_MASK)
+#define WM8978_INPPGAENR_R2_GET(x) (((uint16_t)(x) & WM8978_INPPGAENR_R2_MASK) >> WM8978_INPPGAENR_R2_SHIFT)
+
+
+/*
+ * INPPGAENL (RW)
+ * Left channel input PGA enable
+ */
+#define WM8978_INPPGAENL_R2_MASK   (0x04U)
+#define WM8978_INPPGAENL_R2_SHIFT  (2U)
+#define WM8978_INPPGAENL_R2_SET(x) (((uint16_t)(x) << WM8978_INPPGAENL_R2_SHIFT) & WM8978_INPPGAENL_R2_MASK)
+#define WM8978_INPPGAENL_R2_GET(x) (((uint16_t)(x) & WM8978_INPPGAENL_R2_MASK) >> WM8978_INPPGAENL_R2_SHIFT)
+
+/*
+ * ADCENR (RW)
+ * Enable ADC right channel
+ */
+#define WM8978_ADCENR_R2_MASK   (0x02U)
+#define WM8978_ADCENR_R2_SHIFT  (1U)
+#define WM8978_ADCENR_R2_SET(x) (((uint16_t)(x) << WM8978_ADCENR_R2_SHIFT) & WM8978_ADCENR_R2_MASK)
+#define WM8978_ADCENR_R2_GET(x) (((uint16_t)(x) & WM8978_ADCENR_R2_MASK) >> WM8978_ADCENR_R2_SHIFT)
+
+/*
+ * ADCENL (RW)
+ * Enable ADC left channel
+ */
+#define WM8978_ADCENL_R2_MASK   (0x01U)
+#define WM8978_ADCENL_R2_SHIFT  (0U)
+#define WM8978_ADCENL_R2_SET(x) (((uint16_t)(x) << WM8978_ADCENL_R2_SHIFT) & WM8978_ADCENL_R2_MASK)
+#define WM8978_ADCENL_R2_GET(x) (((uint16_t)(x) & WM8978_ADCENL_R2_MASK) >> WM8978_ADCENL_R2_SHIFT)
+
+/*
+ * MBVSEL (RW)
+ * Microphone Bias Voltage Control
+ */
+#define WM8978_OUT4EN_R3_MASK   (0x100U)
+#define WM8978_OUT4EN_R3_SHIFT  (8U)
+#define WM8978_OUT4EN_R3_SET(x) (((uint16_t)(x) << WM8978_OUT4EN_R3_SHIFT) & WM8978_OUT4EN_R3_MASK)
+#define WM8978_OUT4EN_R3_GET(x) (((uint16_t)(x) & WM8978_OUT4EN_R3_MASK) >> WM8978_OUT4EN_R3_SHIFT)
+
+/*
+ * OUT3EN (RW)
+ * OUT3 enable
+ */
+#define WM8978_OUT3EN_R3_MASK   (0x80U)
+#define WM8978_OUT3EN_R3_SHIFT  (7U)
+#define WM8978_OUT3EN_R3_SET(x) (((uint16_t)(x) << WM8978_OUT3EN_R3_SHIFT) & WM8978_OUT3EN_R3_MASK)
+#define WM8978_OUT3EN_R3_GET(x) (((uint16_t)(x) & WM8978_OUT3EN_R3_MASK) >> WM8978_OUT3EN_R3_SHIFT)
+
+/*
+ * LOUT2EN (RW)
+ * LOUT2 enable
+ */
+#define WM8978_LOUT2EN_R3_MASK   (0x40U)
+#define WM8978_LOUT2EN_R3_SHIFT  (6U)
+#define WM8978_LOUT2EN_R3_SET(x) (((uint16_t)(x) << WM8978_LOUT2EN_R3_SHIFT) & WM8978_LOUT2EN_R3_MASK)
+#define WM8978_LOUT2EN_R3_GET(x) (((uint16_t)(x) & WM8978_LOUT2EN_R3_MASK) >> WM8978_LOUT2EN_R3_SHIFT)
+
+/*
+ * ROUT2EN (RW)
+ * ROUT2 enable
+ */
+#define WM8978_ROUT2EN_R3_MASK   (0x20U)
+#define WM8978_ROUT2EN_R3_SHIFT  (5U)
+#define WM8978_ROUT2EN_R3_SET(x) (((uint16_t)(x) << WM8978_ROUT2EN_R3_SHIFT) & WM8978_ROUT2EN_R3_MASK)
+#define WM8978_ROUT2EN_R3_GET(x) (((uint16_t)(x) & WM8978_ROUT2EN_R3_MASK) >> WM8978_ROUT2EN_R3_SHIFT)
+
+/*
+ * RMIXEN (RW)
+ * Right output channel mixer enable
+ */
+#define WM8978_RMIXEN_R3_MASK   (0x08U)
+#define WM8978_RMIXEN_R3_SHIFT  (3U)
+#define WM8978_RMIXEN_R3_SET(x) (((uint16_t)(x) << WM8978_RMIXEN_R3_SHIFT) & WM8978_RMIXEN_R3_MASK)
+#define WM8978_RMIXEN_R3_GET(x) (((uint16_t)(x) & WM8978_RMIXEN_R3_MASK) >> WM8978_RMIXEN_R3_SHIFT)
+
+/*
+ * LMIXEN (RW)
+ * Left output channel mixer enable
+ */
+#define WM8978_LMIXEN_R3_MASK   (0x04U)
+#define WM8978_LMIXEN_R3_SHIFT  (2U)
+#define WM8978_LMIXEN_R3_SET(x) (((uint16_t)(x) << WM8978_LMIXEN_R3_SHIFT) & WM8978_LMIXEN_R3_MASK)
+#define WM8978_LMIXEN_R3_GET(x) (((uint16_t)(x) & WM8978_LMIXEN_R3_MASK) >> WM8978_LMIXEN_R3_SHIFT)
+
+/*
+ * DACENR (RW)
+ * Right channel DAC enable
+ */
+#define WM8978_DACENR_R3_MASK   (0x02U)
+#define WM8978_DACENR_R3_SHIFT  (1U)
+#define WM8978_DACENR_R3_SET(x) (((uint16_t)(x) << WM8978_DACENR_R3_SHIFT) & WM8978_DACENR_R3_MASK)
+#define WM8978_DACENR_R3_GET(x) (((uint16_t)(x) & WM8978_DACENR_R3_MASK) >> WM8978_DACENR_R3_SHIFT)
+
+/*
+ * DACENL (RW)
+ * Left channel DAC enable
+ */
+#define WM8978_DACENL_R3_MASK   (0x01U)
+#define WM8978_DACENL_R3_SHIFT  (0U)
+#define WM8978_DACENL_R3_SET(x) (((uint16_t)(x) << WM8978_DACENL_R3_SHIFT) & WM8978_DACENL_R3_MASK)
+#define WM8978_DACENL_R3_GET(x) (((uint16_t)(x) & WM8978_DACENL_R3_MASK) >> WM8978_DACENL_R3_SHIFT)
+
+/*
+ * HPFEN (RW)
+ * High Pass Filter Enable
+ */
+#define WM8978_HPFEN_R14_MASK   (0x100U)
+#define WM8978_HPFEN_R14_SHIFT  (8U)
+#define WM8978_HPFEN_R14_SET(x) (((uint16_t)(x) << WM8978_HPFEN_R14_SHIFT) & WM8978_HPFEN_R14_MASK)
+#define WM8978_HPFEN_R14_GET(x) (((uint16_t)(x) & WM8978_HPFEN_R14_MASK) >> WM8978_HPFEN_R14_SHIFT)
+
+/*
+ * ADCOSR128 (RW)
+ * ADC oversample rate select
+ */
+#define WM8978_ADCOSR128_R14_MASK   (0x08U)
+#define WM8978_ADCOSR128_R14_SHIFT  (3U)
+#define WM8978_ADCOSR128_R14_SET(x) (((uint16_t)(x) << WM8978_ADCOSR128_R14_SHIFT) & WM8978_ADCOSR128_R14_MASK)
+#define WM8978_ADCOSR128_R14_GET(x) (((uint16_t)(x) & WM8978_ADCOSR128_R14_MASK) >> WM8978_ADCOSR128_R14_SHIFT)
+
+/*
+ * ADCRPOL (RW)
+ * ADC right channel polarity adjust
+ */
+#define WM8978_ADCRPOL_R14_MASK   (0x02U)
+#define WM8978_ADCRPOL_R14_SHIFT  (1U)
+#define WM8978_ADCRPOL_R14_SET(x) (((uint16_t)(x) << WM8978_ADCRPOL_R14_SHIFT) & WM8978_ADCRPOL_R14_MASK)
+#define WM8978_ADCRPOL_R14_GET(x) (((uint16_t)(x) & WM8978_ADCRPOL_R14_MASK) >> WM8978_ADCRPOL_R14_SHIFT)
+
+/*
+ * ADCLPOL (RW)
+ * ADC left channel polarity adjust
+ */
+#define WM8978_ADCLPOL_R14_MASK   (0x01U)
+#define WM8978_ADCLPOL_R14_SHIFT  (0U)
+#define WM8978_ADCLPOL_R14_SET(x) (((uint16_t)(x) << WM8978_ADCLPOL_R14_SHIFT) & WM8978_ADCLPOL_R14_MASK)
+#define WM8978_ADCLPOL_R14_GET(x) (((uint16_t)(x) & WM8978_ADCLPOL_R14_MASK) >> WM8978_ADCLPOL_R14_SHIFT)
+
+/*
+ * MBVSEL (RW)
+ * Microphone Bias Voltage Control
+ */
+#define WM8978_MBVSEL_R44_MASK   (0x100U)
+#define WM8978_MBVSEL_R44_SHIFT  (8U)
+#define WM8978_MBVSEL_R44_SET(x) (((uint16_t)(x) << WM8978_MBVSEL_R44_SHIFT) & WM8978_MBVSEL_R44_MASK)
+#define WM8978_MBVSEL_R44_GET(x) (((uint16_t)(x) & WM8978_MBVSEL_R44_MASK) >> WM8978_MBVSEL_R44_SHIFT)
+
+/*
+ * R2_2INPPGA (RW)
+ * Connect R2 pin to right channel input PGA positive terminal
+ */
+#define WM8978_R2_2INPPGA_R44_MASK   (0x40U)
+#define WM8978_R2_2INPPGA_R44_SHIFT  (6U)
+#define WM8978_R2_2INPPGA_R44_SET(x) (((uint16_t)(x) << WM8978_R2_2INPPGA_R44_SHIFT) & WM8978_R2_2INPPGA_R44_MASK)
+#define WM8978_R2_2INPPGA_R44_GET(x) (((uint16_t)(x) & WM8978_R2_2INPPGA_R44_MASK) >> WM8978_R2_2INPPGA_R44_SHIFT)
+
+/*
+ * RIN2INPPGA (RW)
+ * Connect RIN pin to right channel input PGA negative terminaL
+ */
+#define WM8978_RIN2INPPGA_R44_MASK   (0x20U)
+#define WM8978_RIN2INPPGA_R44_SHIFT  (5U)
+#define WM8978_RIN2INPPGA_R44_SET(x) (((uint16_t)(x) << WM8978_RIN2INPPGA_R44_SHIFT) & WM8978_RIN2INPPGA_R44_MASK)
+#define WM8978_RIN2INPPGA_R44_GET(x) (((uint16_t)(x) & WM8978_RIN2INPPGA_R44_MASK) >> WM8978_RIN2INPPGA_R44_SHIFT)
+
+/*
+ * RIP2INPPGA (RW)
+ * Connect RIP pin to right channel input PGA amplifier positive terminal
+ */
+#define WM8978_RIP2INPPGA_R44_MASK   (0x10U)
+#define WM8978_RIP2INPPGA_R44_SHIFT  (4U)
+#define WM8978_RIP2INPPGA_R44_SET(x) (((uint16_t)(x) << WM8978_RIP2INPPGA_R44_SHIFT) & WM8978_RIP2INPPGA_R44_MASK)
+#define WM8978_RIP2INPPGA_R44_GET(x) (((uint16_t)(x) & WM8978_RIP2INPPGA_R44_MASK) >> WM8978_RIP2INPPGA_R44_SHIFT)
+
+/*
+ * L2_2INPPGA (RW)
+ * Connect L2 pin to left channel input PGA positive terminal
+ */
+#define WM8978_L2_2INPPGA_R44_MASK   (0x04U)
+#define WM8978_L2_2INPPGA_R44_SHIFT  (2U)
+#define WM8978_L2_2INPPGA_R44_SET(x) (((uint16_t)(x) << WM8978_L2_2INPPGA_R44_SHIFT) & WM8978_L2_2INPPGA_R44_MASK)
+#define WM8978_L2_2INPPGA_R44_GET(x) (((uint16_t)(x) & WM8978_L2_2INPPGA_R44_MASK) >> WM8978_L2_2INPPGA_R44_SHIFT)
+
+/*
+ * LIN2INPPGA (RW)
+ * Connect LIN pin to left channel input PGA negative terminal
+ */
+#define WM8978_LIN2INPPGA_R44_MASK   (0x02U)
+#define WM8978_LIN2INPPGA_R44_SHIFT  (1U)
+#define WM8978_LIN2INPPGA_R44_SET(x) (((uint16_t)(x) << WM8978_LIN2INPPGA_R44_SHIFT) & WM8978_LIN2INPPGA_R44_MASK)
+#define WM8978_LIN2INPPGA_R44_GET(x) (((uint16_t)(x) & WM8978_LIN2INPPGA_R44_MASK) >> WM8978_LIN2INPPGA_R44_SHIFT)
+
+/*
+ * DACENL (RW)
+ * Connect LIP pin to left channel input PGA amplifier positive terminal
+ */
+#define WM8978_LIP2INPPGA_R44_MASK   (0x01U)
+#define WM8978_LIP2INPPGA_R44_SHIFT  (0U)
+#define WM8978_LIP2INPPGA_R44_SET(x) (((uint16_t)(x) << WM8978_LIP2INPPGA_R44_SHIFT) & WM8978_LIP2INPPGA_R44_MASK)
+#define WM8978_LIP2INPPGA_R44_GET(x) (((uint16_t)(x) & WM8978_LIP2INPPGA_R44_MASK) >> WM8978_LIP2INPPGA_R44_SHIFT)
+
+/*
+ * BCP (RW)
+ * BCLK polarity
+ * for 0x04 reg
+ */
+#define WM8978_BCP_MASK   (0x100U)
+#define WM8978_BCP_SHIFT  (8U)
+#define WM8978_BCP_SET(x) (((uint16_t)(x) << WM8978_BCP_SHIFT) & WM8978_BCP_MASK)
+#define WM8978_BCP_GET(x) (((uint16_t)(x) & WM8978_BCP_MASK) >> WM8978_BCP_SHIFT)
+
+/*
+ * LRP (RW)
+ * LRC clock polarity
+ * for 0x04 reg
+ */
+#define WM8978_LRP_MASK   (0x80U)
+#define WM8978_LRP_SHIFT  (7U)
+#define WM8978_LRP_SET(x) (((uint16_t)(x) << WM8978_LRP_SHIFT) & WM8978_LRP_MASK)
+#define WM8978_LRP_GET(x) (((uint16_t)(x) & WM8978_LRP_MASK) >> WM8978_LRP_SHIFT)
+
+/*
+ * WL (RW)
+ * word length
+ * for 0x04 reg
+ */
+#define WM8978_WL_MASK   (0x60U)
+#define WM8978_WL_SHIFT  (5U)
+#define WM8978_WL_SET(x) (((uint16_t)(x) << WM8978_WL_SHIFT) & WM8978_WL_MASK)
+#define WM8978_WL_GET(x) (((uint16_t)(x) & WM8978_WL_MASK) >> WM8978_WL_SHIFT)
+
+/*
+ * FMT (RW)
+ * addio interface data format select
+ * for 0x04 reg
+ */
+#define WM8978_FMT_MASK   (0x18U)
+#define WM8978_FMT_SHIFT  (3U)
+#define WM8978_FMT_SET(x) (((uint16_t)(x) << WM8978_FMT_SHIFT) & WM8978_FMT_MASK)
+#define WM8978_FMT_GET(x) (((uint16_t)(x) & WM8978_FMT_MASK) >> WM8978_FMT_SHIFT)
+
+/*
+ * DACLRSWAP (RW)
+ * Controls whether DAC data appears in 'right'orleft’ phases of LRC clock
+ * for 0x04 reg
+ */
+#define WM8978_DACLRSWAP_MASK   (0x04U)
+#define WM8978_DACLRSWAP_SHIFT  (2U)
+#define WM8978_DACLRSWAP_SET(x) (((uint16_t)(x) << WM8978_DACLRSWAP_SHIFT) & WM8978_DACLRSWAP_MASK)
+#define WM8978_DACLRSWAP_GET(x) (((uint16_t)(x) & WM8978_DACLRSWAP_MASK) >> WM8978_DACLRSWAP_SHIFT)
+
+/*
+ * ADCLRSWAP (RW)
+ * Controls whether ADC data appears in 'right' orleft’ phases of LRC clock
+ * for 0x04 reg
+ */
+#define WM8978_ADCLRSWAP_MASK   (0x02U)
+#define WM8978_ADCLRSWAP_SHIFT  (1U)
+#define WM8978_ADCLRSWAP_SET(x) (((uint16_t)(x) << WM8978_ADCLRSWAP_SHIFT) & WM8978_ADCLRSWAP_MASK)
+#define WM8978_ADCLRSWAP_GET(x) (((uint16_t)(x) & WM8978_ADCLRSWAP_MASK) >> WM8978_ADCLRSWAP_SHIFT)
+
+/*
+ * MONO (RW)
+ * Selects between stereo and mono deviceoperation
+ * for 0x04 reg
+ */
+#define WM8978_MONO_MASK   (0x01U)
+#define WM8978_MONO_SHIFT  (0U)
+#define WM8978_MONO_SET(x) (((uint16_t)(x) << WM8978_MONO_SHIFT) & WM8978_MONO_MASK)
+#define WM8978_MONO_GET(x) (((uint16_t)(x) & WM8978_MONO_MASK) >> WM8978_MONO_SHIFT)
+
+/*
+ * ROUTVOL (RW)
+ *
+ * OUT Volume
+ * 000000 = -57dB
+ * 111001 = 0dB
+ * 111111 = 6dB
+ * for 0x34/0x35/0x36/0x37 regs
+ */
+#define WM8978_OUT_VOLUME_MASK (0x7FU)
+#define WM8978_OUT_VOLUME_SHIFT (0U)
+#define WM8978_OUT_VOLUME_SET(x) (((uint16_t)(x) << WM8978_OUT_VOLUME_SHIFT) & WM8978_OUT_VOLUME_MASK)
+#define WM8978_OUT_VOLUME_GET(x) (((uint16_t)(x) & WM8978_OUT_VOLUME_MASK) >> WM8978_OUT_VOLUME_SHIFT)
+
+/*
+ * OUT_SPKVU (RW)
+ * LOUT1/2 and ROUT1/2 volumes do not update untila 1 is written to SPKkVU
+ * for 0x34/0x35/0x36/0x37 regs
+ */
+#define WM8978_OUT_SPKVU_MASK (0x100U)
+#define WM8978_OUT_SPKVU_SHIFT (8U)
+#define WM8978_OUT_SPKVU_SET(x) (((uint16_t)(x) << WM8978_OUT_SPKVU_SHIFT) & WM8978_OUT_SPKVU_MASK)
+#define WM8978_OUT_SPKVU_GET(x) (((uint16_t)(x) & WM8978_OUT_SPKVU_MASK) >> WM8978_OUT_SPKVU_SHIFT)
+
+/*
+ * OUT_MUTE (RW)
+ * LOUT1/2 and ROUT1/2 headphone output mute
+ * for 0x34/0x35/0x36/0x37 regs
+ */
+#define WM8978_OUT_MUTE_MASK (0x40U)
+#define WM8978_OUT_MUTE_SHIFT (6U)
+#define WM8978_OUT_MUTE_SET(x) (((uint16_t)(x) << WM8978_OUT_MUTE_SHIFT) & WM8978_OUT_MUTE_MASK)
+#define WM8978_OUT_MUTE_GET(x) (((uint16_t)(x) & WM8978_OUT_MUTE_MASK) >> WM8978_OUT_MUTE_SHIFT)
+
+/*
+ * INPGA_UPDATE (RW)
+ * inpga update
+ * for 0x45/0x46 regs
+ */
+#define WM8978_INPGA_UPDATE_MASK (0x100U)
+#define WM8978_INPGA_UPDATE_SHIFT (8U)
+#define WM8978_INPGA_UPDATE_SET(x) (((uint16_t)(x) << WM8978_INPGA_UPDATE_SHIFT) & WM8978_INPGA_UPDATE_MASK)
+#define WM8978_INPGA_UPDATE_GET(x) (((uint16_t)(x) & WM8978_INPGA_UPDATE_MASK) >> WM8978_INPGA_UPDATE_SHIFT)
+
+/*
+ * NPPGAZCR/L (RW)
+ * Left/Right channel input PGA zero cross enable
+ * for 0x45/0x46 regs
+ */
+#define WM8978_NP_PGA_ZC_MASK (0x80U)
+#define WM8978_NP_PGA_ZC_SHIFT (7U)
+#define WM8978_NP_PGA_ZC_SET(x) (((uint16_t)(x) << WM8978_NP_PGA_ZC_SHIFT) & WM8978_NP_PGA_ZC_MASK)
+#define WM8978_NP_PGA_ZC_GET(x) (((uint16_t)(x) & WM8978_NP_PGA_ZC_MASK) >> WM8978_NP_PGA_ZC_SHIFT)
+
+/*
+ * NPPGA_MUTEL (RW)
+ * Mute control for left/right channel input PGA
+ * for 0x45/0x46 regs
+ */
+#define WM8978_INPPGA_MUTEL_MASK (0x40U)
+#define WM8978_INPPGA_MUTEL_SHIFT (6U)
+#define WM8978_INPPGA_MUTEL_SET(x) (((uint16_t)(x) << WM8978_INPPGA_MUTEL_SHIFT) & WM8978_INPPGA_MUTEL_MASK)
+#define WM8978_INPPGA_MUTEL_GET(x) (((uint16_t)(x) & WM8978_INPPGA_MUTEL_MASK) >> WM8978_INPPGA_MUTEL_SHIFT)
+
+/*
+ * INPPGA_VOL (RW)
+ * Left/Right channel input PGA volume
+ * for 0x2d/0x2e regs
+ */
+#define WM8978_INPPGA_VOL_MASK (0x3FU)
+#define WM8978_INPPGA_VOL_SHIFT (0U)
+#define WM8978_INPPGA_VOL_SET(x) (((uint16_t)(x) << WM8978_INPPGA_VOL_SHIFT) & WM8978_INPPGA_VOL_MASK)
+#define WM8978_INPPGA_VOL_GET(x) (((uint16_t)(x) & WM8978_INPPGA_VOL_MASK) >> WM8978_INPPGA_VOL_SHIFT)
+
+/*
+ * PGABOOST (RW)
+ * Boost enable for left/right channel input PGA
+ * for 0x2f/0x30 regs
+ */
+#define WM8978_PGABOOST_MASK (0x100U)
+#define WM8978_PGABOOST_SHIFT (8U)
+#define WM8978_PGABOOST_SET(x) (((uint16_t)(x) << WM8978_PGABOOST_SHIFT) & WM8978_PGABOOST_MASK)
+#define WM8978_PGABOOST_GET(x) (((uint16_t)(x) & WM8978_PGABOOST_MASK) >> WM8978_PGABOOST_SHIFT)
+
+/*
+ * LR2_2BOOSTVOL (RW)
+ * Controls the L2 pin to the left/right channel input
+ * for 0x2f/0x30 regs
+ */
+#define WM8978_2_2_BOOSTVOL_MASK (0x70U)
+#define WM8978_2_2_BOOSTVOL_SHIFT (4U)
+#define WM8978_2_2_BOOSTVOL_SET(x) (((uint16_t)(x) << WM8978_2_2_BOOSTVOL_SHIFT) & WM8978_2_2_BOOSTVOL_MASK)
+#define WM8978_2_2_BOOSTVOL_GET(x) (((uint16_t)(x) & WM8978_2_2_BOOSTVOL_MASK) >> WM8978_2_2_BOOSTVOL_SHIFT)
+
+/*
+ * AUXL2BOOSTVOL (RW)
+ * Controls the auxiliary amplifer to the left/right channelinput boost stage
+ * for 0x2f/0x30 regs
+ */
+#define WM8978_AUXL2BOOSTVOL_MASK (0x07U)
+#define WM8978_AUXL2BOOSTVOL_SHIFT (0U)
+#define WM8978_AUXL2BOOSTVOL_SET(x) (((uint16_t)(x) << WM8978_AUXL2BOOSTVOL_SHIFT) & WM8978_AUXL2BOOSTVOL_MASK)
+#define WM8978_AUXL2BOOSTVOL_GET(x) (((uint16_t)(x) & WM8978_AUXL2BOOSTVOL_MASK) >> WM8978_AUXL2BOOSTVOL_SHIFT)
+#endif
+

+ 10 - 1
bsp/hpmicro/libraries/hpm_sdk/components/debug_console/hpm_debug_console.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -39,6 +39,15 @@ uint8_t console_receive_byte(void)
     return c;
 }
 
+uint8_t console_try_receive_byte(void)
+{
+    uint8_t c = 0;
+
+    uart_try_receive_byte(g_console_uart, &c);
+
+    return c;
+}
+
 void console_send_byte(uint8_t c)
 {
     while (status_success != uart_send_byte(g_console_uart, c)) {

+ 2 - 2
bsp/hpmicro/libraries/hpm_sdk/components/debug_console/hpm_debug_console.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -26,7 +26,7 @@ extern "C" {
 hpm_stat_t console_init(console_config_t *cfg);
 
 uint8_t console_receive_byte(void);
-
+uint8_t console_try_receive_byte(void);
 void console_send_byte(uint8_t c);
 
 #if defined(__cplusplus)

+ 110 - 10
bsp/hpmicro/libraries/hpm_sdk/components/dma_mgr/hpm_dma_mgr.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -354,6 +354,10 @@ void dma_mgr_get_default_chn_config(dma_mgr_chn_conf_t *config)
     config->en_infiniteloop = false;
     config->handshake_opt = DMA_MGR_HANDSHAKE_OPT_ONE_BURST;
     config->burst_opt = DMA_MGR_SRC_BURST_OPT_STANDAND_SIZE;
+    config->en_src_burst_in_fixed_trans = false;
+    config->en_dst_burst_in_fixed_trans = false;
+    config->swap_mode = DMA_MGR_SWAP_MODE_TABLE;
+    config->swap_table = 0;
 }
 
 hpm_stat_t dma_mgr_setup_channel(const dma_resource_t *resource, dma_mgr_chn_conf_t *config)
@@ -382,14 +386,22 @@ hpm_stat_t dma_mgr_setup_channel(const dma_resource_t *resource, dma_mgr_chn_con
         dma_config.size_in_byte = config->size_in_byte;
         dma_config.linked_ptr = config->linked_ptr;
         dma_config.interrupt_mask = config->interrupt_mask;
-#ifdef DMA_MGR_HAS_INFINITE_LOOP
+#if defined(DMA_MGR_HAS_INFINITE_LOOP) && DMA_MGR_HAS_INFINITE_LOOP
         dma_config.en_infiniteloop = config->en_infiniteloop;
 #endif
-#ifdef DMA_MGR_HAS_HANDSHAKE_OPT
+#if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
         dma_config.handshake_opt = config->handshake_opt;
 #endif
-#ifdef DMA_MGR_HAS_BURST_OPT
+#if defined(DMA_MGR_HAS_BURST_OPT) && DMA_MGR_HAS_BURST_OPT
         dma_config.burst_opt = config->burst_opt;
+#endif
+#if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
+        dma_config.en_src_burst_in_fixed_trans = config->en_src_burst_in_fixed_trans;
+        dma_config.en_dst_burst_in_fixed_trans = config->en_dst_burst_in_fixed_trans;
+#endif
+#if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
+        dma_config.swap_mode = config->swap_mode;
+        dma_config.swap_table = config->swap_table;
 #endif
         status = dma_setup_channel(resource->base, resource->channel, &dma_config, false);
     }
@@ -419,14 +431,22 @@ hpm_stat_t dma_mgr_config_linked_descriptor(const dma_resource_t *resource, dma_
         dma_config.size_in_byte = config->size_in_byte;
         dma_config.linked_ptr = config->linked_ptr;
         dma_config.interrupt_mask = config->interrupt_mask;
-#ifdef DMA_MGR_HAS_INFINITE_LOOP
+#if defined(DMA_MGR_HAS_INFINITE_LOOP) && DMA_MGR_HAS_INFINITE_LOOP
         dma_config.en_infiniteloop = config->en_infiniteloop;
 #endif
-#ifdef DMA_MGR_HAS_HANDSHAKE_OPT
+#if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
         dma_config.handshake_opt = config->handshake_opt;
 #endif
-#ifdef DMA_MGR_HAS_BURST_OPT
+#if defined(DMA_MGR_HAS_BURST_OPT) && DMA_MGR_HAS_BURST_OPT
         dma_config.burst_opt = config->burst_opt;
+#endif
+#if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
+        dma_config.en_src_burst_in_fixed_trans = config->en_src_burst_in_fixed_trans;
+        dma_config.en_dst_burst_in_fixed_trans = config->en_dst_burst_in_fixed_trans;
+#endif
+#if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
+        dma_config.swap_mode = config->swap_mode;
+        dma_config.swap_table = config->swap_table;
 #endif
         status = dma_config_linked_descriptor(resource->base, (dma_linked_descriptor_t *)descriptor, resource->channel, &dma_config);
     }
@@ -696,7 +716,7 @@ hpm_stat_t dma_mgr_set_chn_infinite_loop_mode(const dma_resource_t *resource, bo
     if (chn_ctx == NULL) {
         status = status_invalid_argument;
     } else {
-#ifdef DMA_MGR_HAS_INFINITE_LOOP
+#if defined(DMA_MGR_HAS_INFINITE_LOOP) && DMA_MGR_HAS_INFINITE_LOOP
         dma_set_infinite_loop_mode(resource->base, resource->channel, infinite_loop);
         status = status_success;
 #else
@@ -716,7 +736,7 @@ hpm_stat_t dma_mgr_set_chn_src_busrt_option(const dma_resource_t *resource, uint
     if (chn_ctx == NULL) {
         status = status_invalid_argument;
     } else {
-#ifdef DMA_MGR_HAS_BURST_OPT
+#if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
         dma_set_src_busrt_option(resource->base, resource->channel, burst_opt);
         status = status_success;
 #else
@@ -736,7 +756,7 @@ hpm_stat_t dma_mgr_set_chn_handshake_option(const dma_resource_t *resource, uint
     if (chn_ctx == NULL) {
         status = status_invalid_argument;
     } else {
-#ifdef DMA_MGR_HAS_HANDSHAKE_OPT
+#if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
         dma_set_handshake_option(resource->base, resource->channel, handshake_opt);
         status = status_success;
 #else
@@ -776,3 +796,83 @@ hpm_stat_t dma_mgr_check_chn_transfer_status(const dma_resource_t *resource, uin
     }
     return stat;
 }
+
+hpm_stat_t dma_mgr_set_source_burst_in_fixed_transize_enable(const dma_resource_t *resource, bool enable)
+{
+    hpm_stat_t status;
+
+    dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
+
+    if (chn_ctx == NULL) {
+        status = status_invalid_argument;
+    } else {
+#if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
+        dma_set_source_burst_in_fixed_transize_enable(resource->base, resource->channel, enable);
+        status = status_success;
+#else
+        (void)enable;
+        status = status_fail;
+#endif
+    }
+    return status;
+}
+
+hpm_stat_t dma_mgr_set_destination_burst_in_fix_transize_enable(const dma_resource_t *resource, bool enable)
+{
+    hpm_stat_t status;
+
+    dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
+
+    if (chn_ctx == NULL) {
+        status = status_invalid_argument;
+    } else {
+#if defined(DMA_MGR_HAS_BURST_IN_FIXED_TRANS) && DMA_MGR_HAS_BURST_IN_FIXED_TRANS
+        dma_set_destination_burst_in_fixed_transize_enable(resource->base, resource->channel, enable);
+        status = status_success;
+#else
+        (void)enable;
+        status = status_fail;
+#endif
+    }
+    return status;
+}
+
+hpm_stat_t dma_mgr_set_swap_mode(const dma_resource_t *resource, uint8_t swap_mode)
+{
+    hpm_stat_t status;
+
+    dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
+
+    if (chn_ctx == NULL) {
+        status = status_invalid_argument;
+    } else {
+#if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
+        dma_set_swap_mode(resource->base, resource->channel, swap_mode);
+        status = status_success;
+#else
+        (void)swap_mode;
+        status = status_fail;
+#endif
+    }
+    return status;
+}
+
+hpm_stat_t dma_mgr_set_swap_table(const dma_resource_t *resource, uint32_t swap_table)
+{
+    hpm_stat_t status;
+
+    dma_chn_context_t *chn_ctx = dma_mgr_search_chn_context(resource);
+
+    if (chn_ctx == NULL) {
+        status = status_invalid_argument;
+    } else {
+#if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
+        dma_set_swap_table(resource->base, resource->channel, swap_table);
+        status = status_success;
+#else
+        (void)swap_table;
+        status = status_fail;
+#endif
+    }
+    return status;
+}

+ 82 - 16
bsp/hpmicro/libraries/hpm_sdk/components/dma_mgr/hpm_dma_mgr.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -19,10 +19,20 @@
 #include "hpm_soc_feature.h"
 
 #ifdef HPMSOC_HAS_HPMSDK_DMAV2
-#define DMA_MGR_HAS_INFINITE_LOOP (1U)
-#define DMA_MGR_HAS_HALF_TC_INT (1U)
-#define DMA_MGR_HAS_HANDSHAKE_OPT (1U)
-#define DMA_MGR_HAS_BURST_OPT (1U)
+#define DMA_MGR_HAS_INFINITE_LOOP        (1U)
+#define DMA_MGR_HAS_HALF_TC_INT          (1U)
+#define DMA_MGR_HAS_HANDSHAKE_OPT        (1U)
+#define DMA_MGR_HAS_BURST_OPT            (1U)
+#if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
+#define DMA_MGR_HAS_BURST_IN_FIXED_TRANS HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS
+#else
+#define DMA_MGR_HAS_BURST_IN_FIXED_TRANS 0
+#endif
+#if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
+#define DMA_MGR_HAS_BYTE_ORDER_SWAP HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP
+#else
+#define DMA_MGR_HAS_BYTE_ORDER_SWAP 0
+#endif
 #endif
 
 #define DMA_MGR_CHANNEL_PRIORITY_LOW  DMA_CHANNEL_PRIORITY_LOW
@@ -52,7 +62,7 @@
 #define DMA_MGR_ADDRESS_CONTROL_DECREMENT DMA_ADDRESS_CONTROL_DECREMENT
 #define DMA_MGR_ADDRESS_CONTROL_FIXED     DMA_ADDRESS_CONTROL_FIXED
 
-#ifdef DMA_MGR_HAS_BURST_OPT
+#if defined(DMA_MGR_HAS_BURST_OPT) && DMA_MGR_HAS_BURST_OPT
 #define DMA_MGR_SRC_BURST_OPT_STANDAND_SIZE DMA_SRC_BURST_OPT_STANDAND_SIZE
 #define DMA_MGR_SRC_BURST_OPT_CUSTOM_SIZE   DMA_SRC_BURST_OPT_CUSTOM_SIZE
 #else
@@ -60,7 +70,7 @@
 #define DMA_MGR_SRC_BURST_OPT_CUSTOM_SIZE   0
 #endif
 
-#ifdef DMA_MGR_HAS_HANDSHAKE_OPT
+#if defined(DMA_MGR_HAS_HANDSHAKE_OPT) && DMA_MGR_HAS_HANDSHAKE_OPT
 #define DMA_MGR_HANDSHAKE_OPT_ONE_BURST    DMA_HANDSHAKE_OPT_ONE_BURST
 #define DMA_MGR_HANDSHAKE_OPT_ALL_TRANSIZE DMA_HANDSHAKE_OPT_ALL_TRANSIZE
 #else
@@ -72,21 +82,33 @@
 #define DMA_MGR_CHANNEL_STATUS_ERROR   DMA_CHANNEL_STATUS_ERROR
 #define DMA_MGR_CHANNEL_STATUS_ABORT   DMA_CHANNEL_STATUS_ABORT
 #define DMA_MGR_CHANNEL_STATUS_TC      DMA_CHANNEL_STATUS_TC
-#ifdef DMA_MGR_HAS_HALF_TC_INT
+#if defined(DMA_MGR_HAS_HALF_TC_INT) && DMA_MGR_HAS_HALF_TC_INT
 #define DMA_MGR_CHANNEL_STATUS_HALF_TC DMA_CHANNEL_STATUS_HALF_TC
 #else
 #define DMA_MGR_CHANNEL_STATUS_HALF_TC 0
 #endif
-#define DMA_MGR_INTERRUPT_MASK_NONE           DMA_INTERRUPT_MASK_NONE
-#define DMA_MGR_INTERRUPT_MASK_ERROR          DMA_INTERRUPT_MASK_ERROR
-#define DMA_MGR_INTERRUPT_MASK_ABORT          DMA_INTERRUPT_MASK_ABORT
-#define DMA_MGR_INTERRUPT_MASK_TC             DMA_INTERRUPT_MASK_TERMINAL_COUNT
-#ifdef DMA_MGR_HAS_HALF_TC_INT
-#define DMA_MGR_INTERRUPT_MASK_HALF_TC        DMA_INTERRUPT_MASK_HALF_TC
+#define DMA_MGR_INTERRUPT_MASK_NONE  DMA_INTERRUPT_MASK_NONE
+#define DMA_MGR_INTERRUPT_MASK_ERROR DMA_INTERRUPT_MASK_ERROR
+#define DMA_MGR_INTERRUPT_MASK_ABORT DMA_INTERRUPT_MASK_ABORT
+#define DMA_MGR_INTERRUPT_MASK_TC    DMA_INTERRUPT_MASK_TERMINAL_COUNT
+#if defined(DMA_MGR_HAS_HALF_TC_INT) && DMA_MGR_HAS_HALF_TC_INT
+#define DMA_MGR_INTERRUPT_MASK_HALF_TC DMA_INTERRUPT_MASK_HALF_TC
 #else
-#define DMA_MGR_INTERRUPT_MASK_HALF_TC        0
+#define DMA_MGR_INTERRUPT_MASK_HALF_TC 0
+#endif
+#define DMA_MGR_INTERRUPT_MASK_ALL DMA_INTERRUPT_MASK_ALL
+
+#if defined(DMA_MGR_HAS_BYTE_ORDER_SWAP) && DMA_MGR_HAS_BYTE_ORDER_SWAP
+#define DMA_MGR_SWAP_MODE_TABLE     DMA_SWAP_MODE_TABLE
+#define DMA_MGR_SWAP_MODE_BYTE      DMA_SWAP_MODE_BYTE
+#define DMA_MGR_SWAP_MODE_HALF_WORD DMA_SWAP_MODE_HALF_WORD
+#define DMA_MGR_SWAP_MODE_WORD      DMA_SWAP_MODE_WORD
+#else
+#define DMA_MGR_SWAP_MODE_TABLE     0
+#define DMA_MGR_SWAP_MODE_BYTE      0
+#define DMA_MGR_SWAP_MODE_HALF_WORD 0
+#define DMA_MGR_SWAP_MODE_WORD      0
 #endif
-#define DMA_MGR_INTERRUPT_MASK_ALL            DMA_INTERRUPT_MASK_ALL
 
 #ifdef __cplusplus
 
@@ -137,6 +159,10 @@ typedef struct hpm_dma_mgr_chn_conf {
     bool en_infiniteloop;             /**< Infinite loop transfer enable. Attention: only DMAV2 support */
     uint8_t handshake_opt;            /**< Handshake transfer option. Attention: only DMAV2 support */
     uint8_t burst_opt;                /**< Burst size option. Attention: only DMAV2 support  */
+    bool en_src_burst_in_fixed_trans; /**< Source address burst in fix transfer size enable, discard src_addr_ctrl setting. Attention: only DMAV2 support */
+    bool en_dst_burst_in_fixed_trans; /**< Destination address burst in fix transfer size enable, discard dst_addr_ctrl setting. Attention: only DMAV2 support */
+    uint8_t swap_mode;                /**< Swap Mode. Attention: only DMAV2 support */
+    uint32_t swap_table;              /**< Swap Table. Attention: only DMAV2 support */
 } dma_mgr_chn_conf_t;
 
 typedef struct hpm_dma_mgr_linked_descriptor {
@@ -550,6 +576,46 @@ hpm_stat_t dma_mgr_abort_chn_transfer(const dma_resource_t *resource);
  */
 hpm_stat_t dma_mgr_check_chn_transfer_status(const dma_resource_t *resource, uint32_t *status);
 
+/**
+ * @brief   Set DMA channel source burst in fixed transfer size enable or disable
+ *
+ * @param [in] resource DMA resource
+ * @param[in] enable false - disable; true - enable
+ *
+ */
+hpm_stat_t dma_mgr_set_source_burst_in_fixed_transize_enable(const dma_resource_t *resource, bool enable);
+
+/**
+ * @brief   Set DMA channel destination burst in fixed transfer size enable or disable
+ *
+ * @param [in] resource DMA resource
+ * @param[in] enable false - disable; true - enable
+ *
+ */
+hpm_stat_t dma_mgr_set_destination_burst_in_fix_transize_enable(const dma_resource_t *resource, bool enable);
+
+/**
+ * @brief   Set DMA channel swap mode
+ *
+ * @param [in] resource DMA resource
+ * @param[in] swap_mode swap mode
+ *  @arg @ref DMA_MGR_SWAP_MODE_TABLE
+ *  @arg @ref DMA_MGR_SWAP_MODE_BYTE
+ *  @arg @ref DMA_MGR_SWAP_MODE_HALF_WORD
+ *  @arg @ref DMA_MGR_SWAP_MODE_WORD
+ *
+ */
+hpm_stat_t dma_mgr_set_swap_mode(const dma_resource_t *resource, uint8_t swap_mode);
+
+/**
+ * @brief   Set DMA channel swap table
+ *
+ * @param [in] resource DMA resource
+ * @param[in] swap_table swap table
+ *
+ */
+hpm_stat_t dma_mgr_set_swap_table(const dma_resource_t *resource, uint32_t swap_table);
+
 #ifdef __cplusplus
 }
 #endif

+ 6 - 0
bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/hpm_enet_phy_common.h

@@ -32,4 +32,10 @@
     #include "hpm_lan8720_regs.h"
 #endif
 
+#if defined(__USE_JL1111) && __USE_JL1111
+    #include "hpm_jl1111.h"
+    #include "hpm_jl1111_regs.h"
+#endif
+
+
 #endif /* HPM_ENET_PHY_H */

+ 122 - 0
bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/jl1111/hpm_jl1111.c

@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*---------------------------------------------------------------------
+ * Includes
+ *---------------------------------------------------------------------
+ */
+#include "hpm_enet_drv.h"
+#include "hpm_jl1111_regs.h"
+#include "hpm_jl1111.h"
+
+/*---------------------------------------------------------------------
+ * Internal API
+ *---------------------------------------------------------------------
+ */
+static bool jl1111_check_id(ENET_Type *ptr)
+{
+    uint16_t id1, id2;
+
+    id1 = enet_read_phy(ptr, JL1111_ADDR, JL1111_PHYID1);
+    id2 = enet_read_phy(ptr, JL1111_ADDR, JL1111_PHYID2);
+
+    if (JL1111_PHYID1_OUI_MSB_GET(id1) == JL1111_ID1 && JL1111_PHYID2_OUI_LSB_GET(id2) == JL1111_ID2) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/*---------------------------------------------------------------------
+ * API
+ *---------------------------------------------------------------------
+ */
+void jl1111_reset(ENET_Type *ptr)
+{
+    uint16_t data;
+
+    /* PHY reset */
+    enet_write_phy(ptr, JL1111_ADDR, JL1111_BMCR, JL1111_BMCR_RESET_SET(1));
+
+    /* wait until the reset is completed */
+    do {
+        data = enet_read_phy(ptr, JL1111_ADDR, JL1111_BMCR);
+    } while (JL1111_BMCR_RESET_GET(data));
+}
+
+void jl1111_basic_mode_default_config(ENET_Type *ptr, jl1111_config_t *config)
+{
+    (void)ptr;
+
+    config->loopback         = false;                        /* Disable PCS loopback mode */
+    #if defined(__DISABLE_AUTO_NEGO) && (__DISABLE_AUTO_NEGO)
+    config->auto_negotiation = false;                        /* Disable Auto-Negotiation */
+    config->speed            = enet_phy_port_speed_100mbps;
+    config->duplex           = enet_phy_duplex_full;
+    #else
+    config->auto_negotiation = true;                         /* Enable Auto-Negotiation */
+    #endif
+}
+
+bool jl1111_basic_mode_init(ENET_Type *ptr, jl1111_config_t *config)
+{
+    uint16_t data = 0;
+
+    data |= JL1111_BMCR_RESET_SET(0)                        /* Normal operation */
+         |  JL1111_BMCR_LOOPBACK_SET(config->loopback)      /* configure PCS loopback mode */
+         |  JL1111_BMCR_ANE_SET(config->auto_negotiation)   /* configure Auto-Negotiation */
+         |  JL1111_BMCR_PWD_SET(0)                          /* Normal operation */
+         |  JL1111_BMCR_ISOLATE_SET(0)                      /* Normal operation */
+         |  JL1111_BMCR_RESTART_AN_SET(0)                   /* Normal operation (ignored when Auto-Negotiation is disabled) */
+         |  JL1111_BMCR_COLLISION_TEST_SET(0);              /* Normal operation */
+
+    if (config->auto_negotiation == 0) {
+        data |= JL1111_BMCR_SPEED0_SET(config->speed);      /* Set port speed */
+        data |= JL1111_BMCR_DUPLEX_SET(config->duplex);     /* Set duplex mode */
+    }
+
+    /* check the id of jl1111 */
+    if (jl1111_check_id(ptr) == false) {
+        return false;
+    }
+
+    enet_write_phy(ptr, JL1111_ADDR, JL1111_BMCR, data);
+
+    return true;
+}
+
+void jl1111_get_phy_status(ENET_Type *ptr, enet_phy_status_t *status)
+{
+    uint16_t data, anar, anlpar;
+
+    data = enet_read_phy(ptr, JL1111_ADDR, JL1111_BMSR);
+    status->enet_phy_link = JL1111_BMSR_LINK_STATUS_GET(data);
+
+    anar = enet_read_phy(ptr, JL1111_ADDR, JL1111_ANAR);
+    anlpar = enet_read_phy(ptr, JL1111_ADDR, JL1111_ANLPAR);
+    data = anar & anlpar;
+
+    if (JL1111_ANAR_100BASE_TX_GET(data)) {
+        if (JL1111_ANAR_100BASE_TX_FD_GET(data)) {
+            status->enet_phy_speed = enet_phy_port_speed_100mbps;
+            status->enet_phy_duplex = enet_phy_duplex_full;
+        } else {
+            status->enet_phy_speed = enet_phy_port_speed_100mbps;
+            status->enet_phy_duplex = enet_phy_duplex_half;
+        }
+    } else if (JL1111_ANAR_10BASE_T_GET(data)) {
+        if (JL1111_ANAR_10BASE_T_FD_GET(data)) {
+            status->enet_phy_speed = enet_phy_port_speed_10mbps;
+            status->enet_phy_duplex = enet_phy_duplex_full;
+        } else {
+            status->enet_phy_speed = enet_phy_port_speed_10mbps;
+            status->enet_phy_duplex = enet_phy_duplex_half;
+        }
+    } else {
+
+    }
+}

+ 55 - 0
bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/jl1111/hpm_jl1111.h

@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_JL1111_H
+#define HPM_JL1111_H
+
+/*---------------------------------------------------------------------
+ * Includes
+ *---------------------------------------------------------------------
+ */
+#include "hpm_enet_phy.h"
+#include "hpm_common.h"
+#include "hpm_enet_regs.h"
+/*---------------------------------------------------------------------
+ *  Macro Const Definitions
+ *---------------------------------------------------------------------
+ */
+#ifndef JL1111_ADDR
+#define JL1111_ADDR (0U)
+#endif
+
+#define JL1111_ID1  (0x937CU)
+#define JL1111_ID2  (0x10U)
+
+/*---------------------------------------------------------------------
+ *  Typedef Struct Declarations
+ *---------------------------------------------------------------------
+ */
+typedef struct {
+    bool loopback;
+    uint8_t speed;
+    bool auto_negotiation;
+    uint8_t duplex;
+} jl1111_config_t;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+/*---------------------------------------------------------------------
+ * Exported Functions
+ *---------------------------------------------------------------------
+ */
+void jl1111_reset(ENET_Type *ptr);
+void jl1111_basic_mode_default_config(ENET_Type *ptr, jl1111_config_t *config);
+bool jl1111_basic_mode_init(ENET_Type *ptr, jl1111_config_t *config);
+void jl1111_get_phy_status(ENET_Type *ptr, enet_phy_status_t *status);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+#endif /* HPM_JL1111_H */

+ 734 - 0
bsp/hpmicro/libraries/hpm_sdk/components/enet_phy/jl1111/hpm_jl1111_regs.h

@@ -0,0 +1,734 @@
+/*
+ * Copyright (c) 2021-2024 hpmicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+
+#ifndef HPM_JL1111_REGS_H
+#define HPM_JL1111_REGS_H
+
+typedef enum {
+    JL1111_BMCR                         = 0,   /* 0x0: Basic Mode Control Register */
+    JL1111_BMSR                         = 1,   /* 0x1: Basic Mode Status Register */
+    JL1111_PHYID1                       = 2,   /* 0x2: PHY Identifier Register 1 */
+    JL1111_PHYID2                       = 3,   /* 0x3: PHY Identifier Register 2 */
+    JL1111_ANAR                         = 4,   /* 0x4: Auto-Negotiation Advertisement Register */
+    JL1111_ANLPAR                       = 5,   /* 0x5: Auto-Negotiation Link Partner Ability Register */
+    JL1111_MMDAC                        = 19,  /* 0x13: MMD Access Control Register */
+    JL1111_MMDAAD                       = 20,  /* 0x14: MMD Access Address Data Register */
+    JL1111_RMSR_P7                      = 22,  /* 0x16: RMII Mode Setting Register */
+    JL1111_INTSQI                       = 48,  /* 0x30: Interrupt Indicators and Signal Quality Indicator Register */
+    JL1111_PAGESEL                      = 49,  /* 0x31: Page Select Register */
+} JL1111_REG_Type;
+
+
+/* Bitfield definition for register: BMCR */
+/*
+ * RESET (RW/SC)
+ *
+ * 1: PHY reset
+ * 0: normal operation
+ * After software reset, need to delay 10ms de-assert time for chip steady.
+ */
+#define JL1111_BMCR_RESET_MASK (0x8000U)
+#define JL1111_BMCR_RESET_SHIFT (15U)
+#define JL1111_BMCR_RESET_SET(x) (((uint16_t)(x) << JL1111_BMCR_RESET_SHIFT) & JL1111_BMCR_RESET_MASK)
+#define JL1111_BMCR_RESET_GET(x) (((uint16_t)(x) & JL1111_BMCR_RESET_MASK) >> JL1111_BMCR_RESET_SHIFT)
+
+/*
+ * LOOPBACK (RW)
+ *
+ * This bit enables loopback of transmit data nibbles TXD3:0 to the
+ * receive data path.
+ * 1: Enable loopback  0: Normal operation
+ */
+#define JL1111_BMCR_LOOPBACK_MASK (0x4000U)
+#define JL1111_BMCR_LOOPBACK_SHIFT (14U)
+#define JL1111_BMCR_LOOPBACK_SET(x) (((uint16_t)(x) << JL1111_BMCR_LOOPBACK_SHIFT) & JL1111_BMCR_LOOPBACK_MASK)
+#define JL1111_BMCR_LOOPBACK_GET(x) (((uint16_t)(x) & JL1111_BMCR_LOOPBACK_MASK) >> JL1111_BMCR_LOOPBACK_SHIFT)
+
+/*
+ * SPEED0 (RW)
+ *
+ * This bit sets the network speed.
+ * 1: 100Mbps  0: 10Mbps
+ */
+#define JL1111_BMCR_SPEED0_MASK (0x2000U)
+#define JL1111_BMCR_SPEED0_SHIFT (13U)
+#define JL1111_BMCR_SPEED0_SET(x) (((uint16_t)(x) << JL1111_BMCR_SPEED0_SHIFT) & JL1111_BMCR_SPEED0_MASK)
+#define JL1111_BMCR_SPEED0_GET(x) (((uint16_t)(x) & JL1111_BMCR_SPEED0_MASK) >> JL1111_BMCR_SPEED0_SHIFT)
+
+/*
+ * ANE (RW)
+ *
+ * This bit enables/disables the NWay auto-negotiation function.
+ * 1: Enable auto-negotiation; bits 0:13 and 0:8 will be ignored
+ * 0: Disable auto-negotiation; bits 0:13 and 0:8 will determine the
+ * link speed and the data transfer mode
+ */
+#define JL1111_BMCR_ANE_MASK (0x1000U)
+#define JL1111_BMCR_ANE_SHIFT (12U)
+#define JL1111_BMCR_ANE_SET(x) (((uint16_t)(x) << JL1111_BMCR_ANE_SHIFT) & JL1111_BMCR_ANE_MASK)
+#define JL1111_BMCR_ANE_GET(x) (((uint16_t)(x) & JL1111_BMCR_ANE_MASK) >> JL1111_BMCR_ANE_SHIFT)
+
+/*
+ * PWD (RW)
+ *
+ * This bit turns down the power of the PHY chip
+ * The MDC, MDIO is still alive for accessing the MAC.
+ * 1: Power down  0: Normal operation
+ */
+#define JL1111_BMCR_PWD_MASK (0x800U)
+#define JL1111_BMCR_PWD_SHIFT (11U)
+#define JL1111_BMCR_PWD_SET(x) (((uint16_t)(x) << JL1111_BMCR_PWD_SHIFT) & JL1111_BMCR_PWD_MASK)
+#define JL1111_BMCR_PWD_GET(x) (((uint16_t)(x) & JL1111_BMCR_PWD_MASK) >> JL1111_BMCR_PWD_SHIFT)
+
+/*
+ * ISOLATE (RW)
+ *
+ * 1: Electrically isolate the PHY from MII/RMII
+ * PHY is still able to respond to MDC/MDIO.
+ * 0: Normal operation
+ */
+#define JL1111_BMCR_ISOLATE_MASK (0x400U)
+#define JL1111_BMCR_ISOLATE_SHIFT (10U)
+#define JL1111_BMCR_ISOLATE_SET(x) (((uint16_t)(x) << JL1111_BMCR_ISOLATE_SHIFT) & JL1111_BMCR_ISOLATE_MASK)
+#define JL1111_BMCR_ISOLATE_GET(x) (((uint16_t)(x) & JL1111_BMCR_ISOLATE_MASK) >> JL1111_BMCR_ISOLATE_SHIFT)
+
+/*
+ * RESTART_AN (RW/SC)
+ *
+ * This bit allows the NWay auto-negotiation function to be reset.
+ * 1: Re-start auto-negotiation  0: Normal operation
+ */
+#define JL1111_BMCR_RESTART_AN_MASK (0x200U)
+#define JL1111_BMCR_RESTART_AN_SHIFT (9U)
+#define JL1111_BMCR_RESTART_AN_SET(x) (((uint16_t)(x) << JL1111_BMCR_RESTART_AN_SHIFT) & JL1111_BMCR_RESTART_AN_MASK)
+#define JL1111_BMCR_RESTART_AN_GET(x) (((uint16_t)(x) & JL1111_BMCR_RESTART_AN_MASK) >> JL1111_BMCR_RESTART_AN_SHIFT)
+
+/*
+ * DUPLEX (RW)
+ *
+ * This bit sets the duplex mode if auto-negotiation is disabled (bit
+ * 0:12=0).
+ * 1: Full duplex  0: Half duplex
+ */
+#define JL1111_BMCR_DUPLEX_MASK (0x100U)
+#define JL1111_BMCR_DUPLEX_SHIFT (8U)
+#define JL1111_BMCR_DUPLEX_SET(x) (((uint16_t)(x) << JL1111_BMCR_DUPLEX_SHIFT) & JL1111_BMCR_DUPLEX_MASK)
+#define JL1111_BMCR_DUPLEX_GET(x) (((uint16_t)(x) & JL1111_BMCR_DUPLEX_MASK) >> JL1111_BMCR_DUPLEX_SHIFT)
+
+/*
+ * COLLISION_TEST (RW)
+ *
+ * Collision Test.
+ * 1: Collision test enabled
+ * 0: Normal operation
+ * When set, this bit will cause the COL signal to be asserted in
+ * response to the TXEN assertion within 512-bit times. The COL
+ * signal will be de-asserted within 4-bit times in response to the
+ * TXEN de-assertion.
+ */
+#define JL1111_BMCR_COLLISION_TEST_MASK (0x80U)
+#define JL1111_BMCR_COLLISION_TEST_SHIFT (7U)
+#define JL1111_BMCR_COLLISION_TEST_SET(x) (((uint16_t)(x) << JL1111_BMCR_COLLISION_TEST_SHIFT) & JL1111_BMCR_COLLISION_TEST_MASK)
+#define JL1111_BMCR_COLLISION_TEST_GET(x) (((uint16_t)(x) & JL1111_BMCR_COLLISION_TEST_MASK) >> JL1111_BMCR_COLLISION_TEST_SHIFT)
+
+/*
+ * SPEED1 (RW)
+ *
+ * Speed Select Bit 1.
+ * Refer to bit 13.
+ */
+#define JL1111_BMCR_SPEED1_MASK (0x40U)
+#define JL1111_BMCR_SPEED1_SHIFT (6U)
+#define JL1111_BMCR_SPEED1_SET(x) (((uint16_t)(x) << JL1111_BMCR_SPEED1_SHIFT) & JL1111_BMCR_SPEED1_MASK)
+#define JL1111_BMCR_SPEED1_GET(x) (((uint16_t)(x) & JL1111_BMCR_SPEED1_MASK) >> JL1111_BMCR_SPEED1_SHIFT)
+
+/* Bitfield definition for register: BMSR */
+/*
+ * BASE100_T4_1 (RO)
+ *
+ * 1: Enable 100Base-T4 support
+ * 0: Suppress 100Base-T4 support
+ */
+#define JL1111_BMSR_BASE100_T4_1_MASK (0x8000U)
+#define JL1111_BMSR_BASE100_T4_1_SHIFT (15U)
+#define JL1111_BMSR_BASE100_T4_1_GET(x) (((uint16_t)(x) & JL1111_BMSR_BASE100_T4_1_MASK) >> JL1111_BMSR_BASE100_T4_1_SHIFT)
+
+/*
+ * BASE100_TX_FD_1 (RO)
+ *
+ * 1: Enable 100Base-TX full duplex support
+ * 0: Suppress 100Base-TX full duplex support
+ */
+#define JL1111_BMSR_BASE100_TX_FD_1_MASK (0x4000U)
+#define JL1111_BMSR_BASE100_TX_FD_1_SHIFT (14U)
+#define JL1111_BMSR_BASE100_TX_FD_1_GET(x) (((uint16_t)(x) & JL1111_BMSR_BASE100_TX_FD_1_MASK) >> JL1111_BMSR_BASE100_TX_FD_1_SHIFT)
+
+/*
+ * BASE100_TX_HD_1 (RO)
+ *
+ * 1: Enable 100Base-TX half duplex support
+ * 0: Suppress 100Base-TX half duplex support
+ */
+#define JL1111_BMSR_BASE100_TX_HD_1_MASK (0x2000U)
+#define JL1111_BMSR_BASE100_TX_HD_1_SHIFT (13U)
+#define JL1111_BMSR_BASE100_TX_HD_1_GET(x) (((uint16_t)(x) & JL1111_BMSR_BASE100_TX_HD_1_MASK) >> JL1111_BMSR_BASE100_TX_HD_1_SHIFT)
+
+/*
+ * BASE10_TX_FD (RO)
+ *
+ * 1: Enable 10Base-T full duplex support
+ * 0: Suppress 10Base-T full duplex support
+ */
+#define JL1111_BMSR_BASE10_TX_FD_MASK (0x1000U)
+#define JL1111_BMSR_BASE10_TX_FD_SHIFT (12U)
+#define JL1111_BMSR_BASE10_TX_FD_GET(x) (((uint16_t)(x) & JL1111_BMSR_BASE10_TX_FD_MASK) >> JL1111_BMSR_BASE10_TX_FD_SHIFT)
+
+/*
+ * BASE10_TX_HD (RO)
+ *
+ * 1: Enable 10Base-T half duplex support
+ * 0: Suppress 10Base-T half duplex support
+ */
+#define JL1111_BMSR_BASE10_TX_HD_MASK (0x800U)
+#define JL1111_BMSR_BASE10_TX_HD_SHIFT (11U)
+#define JL1111_BMSR_BASE10_TX_HD_GET(x) (((uint16_t)(x) & JL1111_BMSR_BASE10_TX_HD_MASK) >> JL1111_BMSR_BASE10_TX_HD_SHIFT)
+
+/*
+ * MDIO_MFPS (RO)
+ *
+ */
+#define JL1111_BMSR_MDIO_MFPS_MASK (0x40U)
+#define JL1111_BMSR_MDIO_MFPS_SHIFT (6U)
+#define JL1111_BMSR_MDIO_MFPS_GET(x) (((uint16_t)(x) & JL1111_BMSR_MDIO_MFPS_MASK) >> JL1111_BMSR_MDIO_MFPS_SHIFT)
+
+/*
+ * AUTO_NEGOTIATION_COMPLETE (RO)
+ *
+ * 1: Auto-negotiation process completed
+ * 0: Auto-negotiation process not completed
+ */
+#define JL1111_BMSR_AUTO_NEGOTIATION_COMPLETE_MASK (0x20U)
+#define JL1111_BMSR_AUTO_NEGOTIATION_COMPLETE_SHIFT (5U)
+#define JL1111_BMSR_AUTO_NEGOTIATION_COMPLETE_GET(x) (((uint16_t)(x) & JL1111_BMSR_AUTO_NEGOTIATION_COMPLETE_MASK) >> JL1111_BMSR_AUTO_NEGOTIATION_COMPLETE_SHIFT)
+
+/*
+ * REMOTE_FAULT (RC)
+ *
+ * 1: Remote fault condition detected (cleared on read)
+ * 0: No remote fault condition detected
+ */
+#define JL1111_BMSR_REMOTE_FAULT_MASK (0x10U)
+#define JL1111_BMSR_REMOTE_FAULT_SHIFT (4U)
+#define JL1111_BMSR_REMOTE_FAULT_GET(x) (((uint16_t)(x) & JL1111_BMSR_REMOTE_FAULT_MASK) >> JL1111_BMSR_REMOTE_FAULT_SHIFT)
+
+/*
+ * AUTO_NEGOTIATION_ABILITY (RO)
+ *
+ * 1: PHY is able to perform auto-negotiation
+ * 0: PHY is not able to perform auto-negotiation
+ */
+#define JL1111_BMSR_AUTO_NEGOTIATION_ABILITY_MASK (0x8U)
+#define JL1111_BMSR_AUTO_NEGOTIATION_ABILITY_SHIFT (3U)
+#define JL1111_BMSR_AUTO_NEGOTIATION_ABILITY_GET(x) (((uint16_t)(x) & JL1111_BMSR_AUTO_NEGOTIATION_ABILITY_MASK) >> JL1111_BMSR_AUTO_NEGOTIATION_ABILITY_SHIFT)
+
+/*
+ * LINK_STATUS (RO)
+ *
+ * 1: Valid link established
+ * 0: No valid link established
+ */
+#define JL1111_BMSR_LINK_STATUS_MASK (0x4U)
+#define JL1111_BMSR_LINK_STATUS_SHIFT (2U)
+#define JL1111_BMSR_LINK_STATUS_GET(x) (((uint16_t)(x) & JL1111_BMSR_LINK_STATUS_MASK) >> JL1111_BMSR_LINK_STATUS_SHIFT)
+
+/*
+ * JABBER_DETECT (RO)
+ *
+ * 1: Jabber condition detected
+ * 0: No jabber condition detected
+ */
+#define JL1111_BMSR_JABBER_DETECT_MASK (0x2U)
+#define JL1111_BMSR_JABBER_DETECT_SHIFT (1U)
+#define JL1111_BMSR_JABBER_DETECT_GET(x) (((uint16_t)(x) & JL1111_BMSR_JABBER_DETECT_MASK) >> JL1111_BMSR_JABBER_DETECT_SHIFT)
+
+/*
+ * EXTENDED_CAPABILITY (RO)
+ *
+ * 1: Extended register capable (permanently=1)
+ * 0: Not extended register capable
+ */
+#define JL1111_BMSR_EXTENDED_CAPABILITY_MASK (0x1U)
+#define JL1111_BMSR_EXTENDED_CAPABILITY_SHIFT (0U)
+#define JL1111_BMSR_EXTENDED_CAPABILITY_GET(x) (((uint16_t)(x) & JL1111_BMSR_EXTENDED_CAPABILITY_MASK) >> JL1111_BMSR_EXTENDED_CAPABILITY_SHIFT)
+
+/* Bitfield definition for register: PHYID1 */
+/*
+ * OUI_MSB (RO)
+ *
+ * JLSemi OUI is 0x24DF10
+ * 0010 0100 1101 1111 0001 0000
+ * BIT1.......................................................BIT24
+ * Register 2.[15:0] show bit3 to 18 of OUI
+ * 1001 0011 0111 1100
+ * BIT3................................BIT18
+ */
+#define JL1111_PHYID1_OUI_MSB_MASK (0xFFFFU)
+#define JL1111_PHYID1_OUI_MSB_SHIFT (0U)
+#define JL1111_PHYID1_OUI_MSB_GET(x) (((uint16_t)(x) & JL1111_PHYID1_OUI_MSB_MASK) >> JL1111_PHYID1_OUI_MSB_SHIFT)
+
+/* Bitfield definition for register: PHYID2 */
+/*
+ * OUI_LSB (RO)
+ *
+ * Organizationally Unique Identifier bits 19:24
+ * 01 0000
+ * bit19....bit24
+ */
+#define JL1111_PHYID2_OUI_LSB_MASK (0xFC00U)
+#define JL1111_PHYID2_OUI_LSB_SHIFT (10U)
+#define JL1111_PHYID2_OUI_LSB_GET(x) (((uint16_t)(x) & JL1111_PHYID2_OUI_LSB_MASK) >> JL1111_PHYID2_OUI_LSB_SHIFT)
+
+/*
+ * MODEL_NUMBER (RO)
+ *
+ * Model Number
+ */
+#define JL1111_PHYID2_MODEL_NUMBER_MASK (0x3F0U)
+#define JL1111_PHYID2_MODEL_NUMBER_SHIFT (4U)
+#define JL1111_PHYID2_MODEL_NUMBER_GET(x) (((uint16_t)(x) & JL1111_PHYID2_MODEL_NUMBER_MASK) >> JL1111_PHYID2_MODEL_NUMBER_SHIFT)
+
+/*
+ * REVISION_NUMBER (RO)
+ *
+ * Contact JLSemi FAEs for information on the device revision number
+ */
+#define JL1111_PHYID2_REVISION_NUMBER_MASK (0xFU)
+#define JL1111_PHYID2_REVISION_NUMBER_SHIFT (0U)
+#define JL1111_PHYID2_REVISION_NUMBER_GET(x) (((uint16_t)(x) & JL1111_PHYID2_REVISION_NUMBER_MASK) >> JL1111_PHYID2_REVISION_NUMBER_SHIFT)
+
+/* Bitfield definition for register: ANAR */
+/*
+ * NEXT_PAGE (RW)
+ *
+ * Next Page Bit.
+ * 0: Transmitting the primary capability data page
+ * 1: Transmitting the protocol specific data page
+ */
+#define JL1111_ANAR_NEXT_PAGE_MASK (0x8000U)
+#define JL1111_ANAR_NEXT_PAGE_SHIFT (15U)
+#define JL1111_ANAR_NEXT_PAGE_SET(x) (((uint16_t)(x) << JL1111_ANAR_NEXT_PAGE_SHIFT) & JL1111_ANAR_NEXT_PAGE_MASK)
+#define JL1111_ANAR_NEXT_PAGE_GET(x) (((uint16_t)(x) & JL1111_ANAR_NEXT_PAGE_MASK) >> JL1111_ANAR_NEXT_PAGE_SHIFT)
+
+/*
+ * ACKNOWLEDGE (RO)
+ *
+ * 1: Acknowledge reception of link partner capability data world
+ * 0: Do not acknowledge reception
+ */
+#define JL1111_ANAR_ACKNOWLEDGE_MASK (0x4000U)
+#define JL1111_ANAR_ACKNOWLEDGE_SHIFT (14U)
+#define JL1111_ANAR_ACKNOWLEDGE_GET(x) (((uint16_t)(x) & JL1111_ANAR_ACKNOWLEDGE_MASK) >> JL1111_ANAR_ACKNOWLEDGE_SHIFT)
+
+/*
+ * REMOTE_FAULT (RO)
+ *
+ * 1: Advertise remote fault detection capability
+ * 0: Do not advertise remote fault detection capability
+ */
+#define JL1111_ANAR_REMOTE_FAULT_MASK (0x2000U)
+#define JL1111_ANAR_REMOTE_FAULT_SHIFT (13U)
+#define JL1111_ANAR_REMOTE_FAULT_GET(x) (((uint16_t)(x) & JL1111_ANAR_REMOTE_FAULT_MASK) >> JL1111_ANAR_REMOTE_FAULT_SHIFT)
+
+/*
+ * ASYMMETRIC_PAUSE (RW)
+ *
+ * Asymmetric Pause Support For Full-Duplex Links
+ * 1: Advertise asymmetric pause ability
+ * 0: Do not advertise asymmetric pause ability
+ */
+#define JL1111_ANAR_ASYMMETRIC_PAUSE_MASK (0x800U)
+#define JL1111_ANAR_ASYMMETRIC_PAUSE_SHIFT (11U)
+#define JL1111_ANAR_ASYMMETRIC_PAUSE_SET(x) (((uint16_t)(x) << JL1111_ANAR_ASYMMETRIC_PAUSE_SHIFT) & JL1111_ANAR_ASYMMETRIC_PAUSE_MASK)
+#define JL1111_ANAR_ASYMMETRIC_PAUSE_GET(x) (((uint16_t)(x) & JL1111_ANAR_ASYMMETRIC_PAUSE_MASK) >> JL1111_ANAR_ASYMMETRIC_PAUSE_SHIFT)
+
+/*
+ * PAUSE (RW)
+ *
+ * Pause Support For Full-Duplex Links
+ * 1: Advertise pause ability
+ * 0: Do not advertise pause ability
+ */
+#define JL1111_ANAR_PAUSE_MASK (0x400U)
+#define JL1111_ANAR_PAUSE_SHIFT (10U)
+#define JL1111_ANAR_PAUSE_SET(x) (((uint16_t)(x) << JL1111_ANAR_PAUSE_SHIFT) & JL1111_ANAR_PAUSE_MASK)
+#define JL1111_ANAR_PAUSE_GET(x) (((uint16_t)(x) & JL1111_ANAR_PAUSE_MASK) >> JL1111_ANAR_PAUSE_SHIFT)
+
+/*
+ * 100BASE_T4 (RO)
+ *
+ * 1: 100Base-T4 is supported by local node
+ * 0: 100Base-T4 not supported by local node
+ */
+#define JL1111_ANAR_100BASE_T4_MASK (0x200U)
+#define JL1111_ANAR_100BASE_T4_SHIFT (9U)
+#define JL1111_ANAR_100BASE_T4_GET(x) (((uint16_t)(x) & JL1111_ANAR_100BASE_T4_MASK) >> JL1111_ANAR_100BASE_T4_SHIFT)
+
+/*
+ * 100BASE_TX_FD (RW)
+ *
+ * 1: 100Base-TX full duplex is supported by local node
+ * 0: 100Base-TX full duplex not supported by local node
+ */
+#define JL1111_ANAR_100BASE_TX_FD_MASK (0x100U)
+#define JL1111_ANAR_100BASE_TX_FD_SHIFT (8U)
+#define JL1111_ANAR_100BASE_TX_FD_SET(x) (((uint16_t)(x) << JL1111_ANAR_100BASE_TX_FD_SHIFT) & JL1111_ANAR_100BASE_TX_FD_MASK)
+#define JL1111_ANAR_100BASE_TX_FD_GET(x) (((uint16_t)(x) & JL1111_ANAR_100BASE_TX_FD_MASK) >> JL1111_ANAR_100BASE_TX_FD_SHIFT)
+
+/*
+ * 100BASE_TX (RW)
+ *
+ * 1: 100Base-TX is supported by local node
+ * 0: 100Base-TX not supported by local node
+ */
+#define JL1111_ANAR_100BASE_TX_MASK (0x80U)
+#define JL1111_ANAR_100BASE_TX_SHIFT (7U)
+#define JL1111_ANAR_100BASE_TX_SET(x) (((uint16_t)(x) << JL1111_ANAR_100BASE_TX_SHIFT) & JL1111_ANAR_100BASE_TX_MASK)
+#define JL1111_ANAR_100BASE_TX_GET(x) (((uint16_t)(x) & JL1111_ANAR_100BASE_TX_MASK) >> JL1111_ANAR_100BASE_TX_SHIFT)
+
+/*
+ * 10BASE_T_FD (RW)
+ *
+ * 1: 10Base-T full duplex supported by local node
+ * 0: 10Base-T full duplex not supported by local node
+ */
+#define JL1111_ANAR_10BASE_T_FD_MASK (0x40U)
+#define JL1111_ANAR_10BASE_T_FD_SHIFT (6U)
+#define JL1111_ANAR_10BASE_T_FD_SET(x) (((uint16_t)(x) << JL1111_ANAR_10BASE_T_FD_SHIFT) & JL1111_ANAR_10BASE_T_FD_MASK)
+#define JL1111_ANAR_10BASE_T_FD_GET(x) (((uint16_t)(x) & JL1111_ANAR_10BASE_T_FD_MASK) >> JL1111_ANAR_10BASE_T_FD_SHIFT)
+
+/*
+ * 10BASE_T (RW)
+ *
+ * 1: 10Base-T is supported by local node
+ * 0: 10Base-T not supported by local node
+ */
+#define JL1111_ANAR_10BASE_T_MASK (0x20U)
+#define JL1111_ANAR_10BASE_T_SHIFT (5U)
+#define JL1111_ANAR_10BASE_T_SET(x) (((uint16_t)(x) << JL1111_ANAR_10BASE_T_SHIFT) & JL1111_ANAR_10BASE_T_MASK)
+#define JL1111_ANAR_10BASE_T_GET(x) (((uint16_t)(x) & JL1111_ANAR_10BASE_T_MASK) >> JL1111_ANAR_10BASE_T_SHIFT)
+
+/*
+ * SELECTOR_FIELD (RO)
+ *
+ * Binary Encoded Selector Supported by This Node. Currently only CSMA/CD 00001 is specified. No other protocols are supported.
+ */
+#define JL1111_ANAR_SELECTOR_FIELD_MASK (0x1FU)
+#define JL1111_ANAR_SELECTOR_FIELD_SHIFT (0U)
+#define JL1111_ANAR_SELECTOR_FIELD_GET(x) (((uint16_t)(x) & JL1111_ANAR_SELECTOR_FIELD_MASK) >> JL1111_ANAR_SELECTOR_FIELD_SHIFT)
+
+/* Bitfield definition for register: ANLPAR */
+/*
+ * NEXT_PAGE (RO)
+ *
+ * Next Page Bit.
+ * 0: Transmitting the primary capability data page
+ * 1: Transmitting the protocol specific data page
+ */
+#define JL1111_ANLPAR_NEXT_PAGE_MASK (0x8000U)
+#define JL1111_ANLPAR_NEXT_PAGE_SHIFT (15U)
+#define JL1111_ANLPAR_NEXT_PAGE_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_NEXT_PAGE_MASK) >> JL1111_ANLPAR_NEXT_PAGE_SHIFT)
+
+/*
+ * ACKNOWLEDGE (RO)
+ *
+ * 1: Link partner acknowledges reception of local node's capability data word
+ * 0: No acknowledgement
+ */
+#define JL1111_ANLPAR_ACKNOWLEDGE_MASK (0x4000U)
+#define JL1111_ANLPAR_ACKNOWLEDGE_SHIFT (14U)
+#define JL1111_ANLPAR_ACKNOWLEDGE_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_ACKNOWLEDGE_MASK) >> JL1111_ANLPAR_ACKNOWLEDGE_SHIFT)
+
+/*
+ * REMOTE_FAULT (RO)
+ *
+ * 1: Link partner is indicating a remote fault
+ * 0: Link partner is not indicating a remote fault
+ */
+#define JL1111_ANLPAR_REMOTE_FAULT_MASK (0x2000U)
+#define JL1111_ANLPAR_REMOTE_FAULT_SHIFT (13U)
+#define JL1111_ANLPAR_REMOTE_FAULT_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_REMOTE_FAULT_MASK) >> JL1111_ANLPAR_REMOTE_FAULT_SHIFT)
+
+/*
+ * ASYMMETRIC_PAUSE (RO)
+ *
+ * Asymmetric Pause Support For Full-Duplex Links
+ * 1: Advertise asymmetric pause ability
+ * 0: Do not advertise asymmetric puase ability
+ */
+#define JL1111_ANLPAR_ASYMMETRIC_PAUSE_MASK (0x800U)
+#define JL1111_ANLPAR_ASYMMETRIC_PAUSE_SHIFT (11U)
+#define JL1111_ANLPAR_ASYMMETRIC_PAUSE_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_ASYMMETRIC_PAUSE_MASK) >> JL1111_ANLPAR_ASYMMETRIC_PAUSE_SHIFT)
+
+/*
+ * PAUSE (RO)
+ *
+ * Pause Support For Full-Duplex Links
+ * 1: Advertise pause ability
+ * 0: Do not advertise pause ability
+ */
+#define JL1111_ANLPAR_PAUSE_MASK (0x400U)
+#define JL1111_ANLPAR_PAUSE_SHIFT (10U)
+#define JL1111_ANLPAR_PAUSE_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_PAUSE_MASK) >> JL1111_ANLPAR_PAUSE_SHIFT)
+
+/*
+ * 100BASE_T4 (RO)
+ *
+ * 1: 100Base-T4 is supported by link partner
+ * 0: 100Base-T4 not supported by link partner
+ */
+#define JL1111_ANLPAR_100BASE_T4_MASK (0x200U)
+#define JL1111_ANLPAR_100BASE_T4_SHIFT (9U)
+#define JL1111_ANLPAR_100BASE_T4_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_100BASE_T4_MASK) >> JL1111_ANLPAR_100BASE_T4_SHIFT)
+
+/*
+ * 100BASE_TX_FD (RO)
+ *
+ * 1: 100Base-TX full duplex is supported by link partner
+ * 0: 100Base-TX full duplex not supported by link partner
+ */
+#define JL1111_ANLPAR_100BASE_TX_FD_MASK (0x100U)
+#define JL1111_ANLPAR_100BASE_TX_FD_SHIFT (8U)
+#define JL1111_ANLPAR_100BASE_TX_FD_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_100BASE_TX_FD_MASK) >> JL1111_ANLPAR_100BASE_TX_FD_SHIFT)
+
+/*
+ * 100BASE_TX (RO)
+ *
+ * 1: 100Base-TX is supported by link partner
+ * 0: 100Base-TX not supported by link partner
+ */
+#define JL1111_ANLPAR_100BASE_TX_MASK (0x80U)
+#define JL1111_ANLPAR_100BASE_TX_SHIFT (7U)
+#define JL1111_ANLPAR_100BASE_TX_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_100BASE_TX_MASK) >> JL1111_ANLPAR_100BASE_TX_SHIFT)
+
+/*
+ * 10BASE_T_FD (RO)
+ *
+ * 1: 10Base-T full duplex is supported by link partner
+ * 0: 10Base-T full duplex not supported by link partner
+ */
+#define JL1111_ANLPAR_10BASE_T_FD_MASK (0x40U)
+#define JL1111_ANLPAR_10BASE_T_FD_SHIFT (6U)
+#define JL1111_ANLPAR_10BASE_T_FD_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_10BASE_T_FD_MASK) >> JL1111_ANLPAR_10BASE_T_FD_SHIFT)
+
+/*
+ * 10BASE_T (RO)
+ *
+ * 1: 10Base-T is supported by link partner
+ * 0: 10Base-T not supported by link partner
+ */
+#define JL1111_ANLPAR_10BASE_T_MASK (0x20U)
+#define JL1111_ANLPAR_10BASE_T_SHIFT (5U)
+#define JL1111_ANLPAR_10BASE_T_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_10BASE_T_MASK) >> JL1111_ANLPAR_10BASE_T_SHIFT)
+
+/*
+ * SELECTOR_FIELD (RO)
+ *
+ * Link Partner's Binary Encoded Node Selector.
+ * Currently only CSMA/CD 00001 is specified.
+ */
+#define JL1111_ANLPAR_SELECTOR_FIELD_MASK (0x1FU)
+#define JL1111_ANLPAR_SELECTOR_FIELD_SHIFT (0U)
+#define JL1111_ANLPAR_SELECTOR_FIELD_GET(x) (((uint16_t)(x) & JL1111_ANLPAR_SELECTOR_FIELD_MASK) >> JL1111_ANLPAR_SELECTOR_FIELD_SHIFT)
+
+/* Bitfield definition for register: MMDAC */
+/*
+ * MMD_FUNCTION (RW)
+ *
+ * 00: address
+ * 01: data, no post increment
+ * 10: data, post increment on reads and writes
+ * 11: data, post increment on writes only
+ */
+#define JL1111_MMDAC_MMD_FUNCTION_MASK (0xC000U)
+#define JL1111_MMDAC_MMD_FUNCTION_SHIFT (14U)
+#define JL1111_MMDAC_MMD_FUNCTION_SET(x) (((uint16_t)(x) << JL1111_MMDAC_MMD_FUNCTION_SHIFT) & JL1111_MMDAC_MMD_FUNCTION_MASK)
+#define JL1111_MMDAC_MMD_FUNCTION_GET(x) (((uint16_t)(x) & JL1111_MMDAC_MMD_FUNCTION_MASK) >> JL1111_MMDAC_MMD_FUNCTION_SHIFT)
+
+/*
+ * RESERVERD (RW)
+ *
+ * Write as 0, ignore on read
+ */
+#define JL1111_MMDAC_RESERVERD_MASK (0x3FE0U)
+#define JL1111_MMDAC_RESERVERD_SHIFT (5U)
+#define JL1111_MMDAC_RESERVERD_SET(x) (((uint16_t)(x) << JL1111_MMDAC_RESERVERD_SHIFT) & JL1111_MMDAC_RESERVERD_MASK)
+#define JL1111_MMDAC_RESERVERD_GET(x) (((uint16_t)(x) & JL1111_MMDAC_RESERVERD_MASK) >> JL1111_MMDAC_RESERVERD_SHIFT)
+
+/*
+ * MMD_DEVAD (RW)
+ *
+ * Device address
+ */
+#define JL1111_MMDAC_MMD_DEVAD_MASK (0x1FU)
+#define JL1111_MMDAC_MMD_DEVAD_SHIFT (0U)
+#define JL1111_MMDAC_MMD_DEVAD_SET(x) (((uint16_t)(x) << JL1111_MMDAC_MMD_DEVAD_SHIFT) & JL1111_MMDAC_MMD_DEVAD_MASK)
+#define JL1111_MMDAC_MMD_DEVAD_GET(x) (((uint16_t)(x) & JL1111_MMDAC_MMD_DEVAD_MASK) >> JL1111_MMDAC_MMD_DEVAD_SHIFT)
+
+/* Bitfield definition for register: MMDAAD */
+/*
+ * MMD_ADDRESS_DATA (RW)
+ *
+ * If MMDAC[15:14]=00, MMD DEVAD's address register. Otherwise, MMD DEVAD's data register as indicated by the contents of its address register
+ */
+#define JL1111_MMDAAD_MMD_ADDRESS_DATA_MASK (0xFFFFU)
+#define JL1111_MMDAAD_MMD_ADDRESS_DATA_SHIFT (0U)
+#define JL1111_MMDAAD_MMD_ADDRESS_DATA_SET(x) (((uint16_t)(x) << JL1111_MMDAAD_MMD_ADDRESS_DATA_SHIFT) & JL1111_MMDAAD_MMD_ADDRESS_DATA_MASK)
+#define JL1111_MMDAAD_MMD_ADDRESS_DATA_GET(x) (((uint16_t)(x) & JL1111_MMDAAD_MMD_ADDRESS_DATA_MASK) >> JL1111_MMDAAD_MMD_ADDRESS_DATA_SHIFT)
+
+/* Bitfield definition for register: RMSR_P7 */
+/*
+ * RMII_TX_LPI_ENABLE (RW)
+ *
+ * Enable transmition LPI signal of RMII
+ * TX_EN=0 and TXD=1 will represent MII LPI
+ */
+#define JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_MASK (0x8000U)
+#define JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_SHIFT (15U)
+#define JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_SHIFT) & JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_MASK)
+#define JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_MASK) >> JL1111_RMSR_P7_RMII_TX_LPI_ENABLE_SHIFT)
+
+/*
+ * RMII_RX_LPI_ENABLE (RW)
+ *
+ * Enable reception LPI signal of RMII
+ * CRS_DV=0 and RXD=1 will represent MII LPI
+ */
+#define JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_MASK (0x4000U)
+#define JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_SHIFT (14U)
+#define JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_SHIFT) & JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_MASK)
+#define JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_MASK) >> JL1111_RMSR_P7_RMII_RX_LPI_ENABLE_SHIFT)
+
+/*
+ * RMII_RX_ER_IN_RXD (RW)
+ *
+ * For Non-Bad-SSD rx_er, RXD will be 1
+ */
+#define JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_MASK (0x2000U)
+#define JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_SHIFT (13U)
+#define JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_SHIFT) & JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_MASK)
+#define JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_MASK) >> JL1111_RMSR_P7_RMII_RX_ER_IN_RXD_SHIFT)
+
+/*
+ * RMII_CLOCK_DIRECTION (RW)
+ *
+ * Clock Direction of TX_CLK in RMII Mode.
+ * 0: 50MHz Output
+ * 1: 50MHz Input
+ */
+#define JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_MASK (0x1000U)
+#define JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_SHIFT (12U)
+#define JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_SHIFT) & JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_MASK)
+#define JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_MASK) >> JL1111_RMSR_P7_RMII_CLOCK_DIRECTION_SHIFT)
+
+/*
+ * RMII_TX_SKEW (RW)
+ *
+ * Adjust RMII TX Interface Timing
+ */
+#define JL1111_RMSR_P7_RMII_TX_SKEW_MASK (0xF00U)
+#define JL1111_RMSR_P7_RMII_TX_SKEW_SHIFT (8U)
+#define JL1111_RMSR_P7_RMII_TX_SKEW_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_TX_SKEW_SHIFT) & JL1111_RMSR_P7_RMII_TX_SKEW_MASK)
+#define JL1111_RMSR_P7_RMII_TX_SKEW_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_TX_SKEW_MASK) >> JL1111_RMSR_P7_RMII_TX_SKEW_SHIFT)
+
+/*
+ * RMII_RX_SKEW (RW)
+ *
+ * Adjust RMII RX Interface Timing
+ */
+#define JL1111_RMSR_P7_RMII_RX_SKEW_MASK (0xF0U)
+#define JL1111_RMSR_P7_RMII_RX_SKEW_SHIFT (4U)
+#define JL1111_RMSR_P7_RMII_RX_SKEW_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_RX_SKEW_SHIFT) & JL1111_RMSR_P7_RMII_RX_SKEW_MASK)
+#define JL1111_RMSR_P7_RMII_RX_SKEW_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_RX_SKEW_MASK) >> JL1111_RMSR_P7_RMII_RX_SKEW_SHIFT)
+
+/*
+ * MII_RMII_MODE_SELECTION (RW)
+ *
+ * 0: RMII Mode
+ * 1: RMII Mode
+ */
+#define JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_MASK (0x8U)
+#define JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_SHIFT (3U)
+#define JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_SHIFT) & JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_MASK)
+#define JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_MASK) >> JL1111_RMSR_P7_MII_RMII_MODE_SELECTION_SHIFT)
+
+/*
+ * RMII_CRS_DV_FUNCTIONAL (RW)
+ *
+ * 0: CRS_DV pin is CRS_DV signal
+ * 1: CRS_DV pin is RXDV signal
+ */
+#define JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_MASK (0x4U)
+#define JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_SHIFT (2U)
+#define JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_SHIFT) & JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_MASK)
+#define JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_MASK) >> JL1111_RMSR_P7_RMII_CRS_DV_FUNCTIONAL_SHIFT)
+
+/*
+ * RMII_RXD_BAD_SSD_ENABLE (RW)
+ *
+ * 0: RMII data only
+ * 1: RMII data with SSD Error
+ */
+#define JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_MASK (0x2U)
+#define JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_SHIFT (1U)
+#define JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_SET(x) (((uint16_t)(x) << JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_SHIFT) & JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_MASK)
+#define JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_GET(x) (((uint16_t)(x) & JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_MASK) >> JL1111_RMSR_P7_RMII_RXD_BAD_SSD_ENABLE_SHIFT)
+
+/* Bitfield definition for register: INTSQI */
+/*
+ * AUTONEG_ERROR (RC)
+ *
+ * Auto-Negotiation Error Interrupt
+ */
+#define JL1111_INTSQI_AUTONEG_ERROR_MASK (0x8000U)
+#define JL1111_INTSQI_AUTONEG_ERROR_SHIFT (15U)
+#define JL1111_INTSQI_AUTONEG_ERROR_GET(x) (((uint16_t)(x) & JL1111_INTSQI_AUTONEG_ERROR_MASK) >> JL1111_INTSQI_AUTONEG_ERROR_SHIFT)
+
+/*
+ * LINK_STATUS_CHANGE (RC)
+ *
+ * Link_Status_Change_Interrupt
+ * 1: Enable
+ * 0: Disable
+ */
+#define JL1111_INTSQI_LINK_STATUS_CHANGE_MASK (0x800U)
+#define JL1111_INTSQI_LINK_STATUS_CHANGE_SHIFT (11U)
+#define JL1111_INTSQI_LINK_STATUS_CHANGE_GET(x) (((uint16_t)(x) & JL1111_INTSQI_LINK_STATUS_CHANGE_MASK) >> JL1111_INTSQI_LINK_STATUS_CHANGE_SHIFT)
+
+/*
+ * SIGNAL_QUALITY_INDICATOR (RO)
+ *
+ * Signal Quality Indicator, lower is better. The value is only valid in 100Base-TX mode and its link status is ON
+ */
+#define JL1111_INTSQI_SIGNAL_QUALITY_INDICATOR_MASK (0x1FU)
+#define JL1111_INTSQI_SIGNAL_QUALITY_INDICATOR_SHIFT (0U)
+#define JL1111_INTSQI_SIGNAL_QUALITY_INDICATOR_GET(x) (((uint16_t)(x) & JL1111_INTSQI_SIGNAL_QUALITY_INDICATOR_MASK) >> JL1111_INTSQI_SIGNAL_QUALITY_INDICATOR_SHIFT)
+
+/* Bitfield definition for register: PAGESEL */
+/*
+ * PAGE_SELECTION (RW)
+ *
+ */
+#define JL1111_PAGESEL_PAGE_SELECTION_MASK (0xFFU)
+#define JL1111_PAGESEL_PAGE_SELECTION_SHIFT (0U)
+#define JL1111_PAGESEL_PAGE_SELECTION_SET(x) (((uint16_t)(x) << JL1111_PAGESEL_PAGE_SELECTION_SHIFT) & JL1111_PAGESEL_PAGE_SELECTION_MASK)
+#define JL1111_PAGESEL_PAGE_SELECTION_GET(x) (((uint16_t)(x) & JL1111_PAGESEL_PAGE_SELECTION_MASK) >> JL1111_PAGESEL_PAGE_SELECTION_SHIFT)
+
+
+
+
+#endif /* HPM_JL1111_REGS_H */

+ 139 - 0
bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/cc10128007.c

@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include "hpm_panel.h"
+#include "hpm_pixelmux_drv.h"
+#include "hpm_lvb_drv.h"
+
+static void lvds_panel_lvb_init(hpm_panel_t *panel)
+{
+    LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
+    lvb_config_t lvb_config;
+    lvb_get_default_config(&lvb_config);
+
+    lvb_config.split_mode_en = false;
+    lvb_config.txclk_shift = lvb_txclk_shift_1100011;
+    lvb_init(lvb_base, &lvb_config);
+
+    lvb_ch_config_t lvb_ch_cfg;
+    lvb_ch_cfg.map = lvb_ch_mapping_vesa;
+
+    if (panel->hw_if.video.lvds.channel_di_index == 0)
+        lvb_ch_cfg.data_src = lvb_ch_data_source_di0;
+    else
+        lvb_ch_cfg.data_src = lvb_ch_data_source_di1;
+
+    if (panel->hw_if.video.lvds.channel_index == 0) {
+        lvb_ch_config(lvb_base, lvb_ch_num_0, &lvb_ch_cfg);
+        lvb_ch_enable(lvb_base, lvb_ch_num_0);
+    } else {
+        lvb_ch_config(lvb_base, lvb_ch_num_1, &lvb_ch_cfg);
+        lvb_ch_enable(lvb_base, lvb_ch_num_1);
+    }
+}
+
+static void lvds_panel_phy_init(hpm_panel_t *panel)
+{
+    LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
+    lvds_phy_clk_param_t param;
+    uint32_t pixel_clk = panel->hw_if.lcdc_pixel_clk_khz * 1000;
+    pixelmux_lvds_phy_calc_pll_cfg(pixel_clk, false, &param);
+
+    lvb_lvds_phy_lane_config_t lvds_lane_cfg;
+    lvb_lvds_phy_lane_get_default_config(&lvds_lane_cfg);
+    lvds_lane_cfg.fvco_div4 = param.reg.data_rate_div4;
+
+    if (panel->hw_if.video.lvds.channel_index == 0) {
+        pixelmux_config_lvds_tx_phy0_clk(&param.reg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx0, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx1, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx2, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx3, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_txck, &lvds_lane_cfg);
+        lvb_lvds_phy0_poweron(lvb_base);
+
+        while (lvb_lvds_phy0_pll_is_lock(lvb_base) == false) {
+        }
+    } else {
+        pixelmux_config_lvds_tx_phy1_clk(&param.reg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx0, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx1, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx2, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx3, &lvds_lane_cfg);
+        lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_txck, &lvds_lane_cfg);
+        lvb_lvds_phy1_poweron(lvb_base);
+
+        while (lvb_lvds_phy1_pll_is_lock(lvb_base) == false) {
+        }
+    }
+}
+
+static void reset(hpm_panel_t *panel)
+{
+    if (!panel->hw_if.set_reset_pin_level)
+        return;
+
+    panel->hw_if.set_reset_pin_level(0);
+    hpm_panel_delay_us(2000);
+
+    panel->hw_if.set_reset_pin_level(1);
+    hpm_panel_delay_us(2000);
+}
+
+static void init(hpm_panel_t *panel)
+{
+    if (panel->hw_if.set_video_router)
+        panel->hw_if.set_video_router();
+
+    lvds_panel_lvb_init(panel);
+    lvds_panel_phy_init(panel);
+}
+
+static void power_on(hpm_panel_t *panel)
+{
+    if (panel->state.power_state != HPM_PANEL_STATE_POWER_ON &&
+        panel->hw_if.set_backlight) {
+        if (panel->state.backlight_percent == 0)
+            panel->state.backlight_percent = 100;
+
+        panel->hw_if.set_backlight(panel->state.backlight_percent);
+        panel->state.power_state = HPM_PANEL_STATE_POWER_ON;
+    }
+}
+
+static void power_off(hpm_panel_t *panel)
+{
+    if (panel->state.power_state != HPM_PANEL_STATE_POWER_OFF &&
+        panel->hw_if.set_backlight) {
+
+        panel->hw_if.set_backlight(0);
+        panel->state.power_state = HPM_PANEL_STATE_POWER_OFF;
+    }
+}
+
+hpm_panel_t panel_cc10128007 = {
+    .name = "cc10128007",
+    .if_type = HPM_PANEL_IF_TYPE_LVDS_SINGLE,
+    .timing = {
+        .pixel_clock_khz = 74250,
+        .hactive = 800,
+        .hfront_porch = 60,
+        .hback_porch = 60,
+        .hsync_len = 40,
+
+        .vactive = 1280,
+        .vfront_porch = 18,
+        .vback_porch = 18,
+        .vsync_len = 6,
+    },
+    .funcs = {
+        .reset = reset,
+        .init = init,
+        .power_on = power_on,
+        .power_off = power_off,
+    },
+};
+

+ 354 - 0
bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/mc10128007_31b.c

@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include "hpm_panel.h"
+#include "hpm_pixelmux_drv.h"
+#include "hpm_mipi_dsi_drv.h"
+#include "hpm_mipi_dsi_phy_drv.h"
+#include <stdio.h>
+
+typedef struct mipi_cmd_list {
+    uint16_t len;
+    uint8_t cmd[4];
+} mipi_cmd_list_t;
+
+static const mipi_cmd_list_t mipi_panel_cmd[] = {
+    {4, {0xFF, 0x98, 0x81, 0x03}},
+    {2, {0x01, 0x00}},
+    {2, {0x02, 0x00}},
+    {2, {0x03, 0x55}},
+    {2, {0x04, 0x55}},
+    {2, {0x05, 0x03}},
+    {2, {0x06, 0x06}},
+    {2, {0x07, 0x00}},
+    {2, {0x08, 0x07}},
+    {2, {0x09, 0x00}},
+    {2, {0x0A, 0x00}},
+    {2, {0x0B, 0x00}},
+    {2, {0x0C, 0x00}},
+    {2, {0x0D, 0x00}},
+    {2, {0x0E, 0x00}},
+    {2, {0x0F, 0x00}},
+    {2, {0x10, 0x00}},
+    {2, {0x11, 0x00}},
+    {2, {0x12, 0x00}},
+    {2, {0x13, 0x00}},
+    {2, {0x14, 0x00}},
+    {2, {0x15, 0x00}},
+    {2, {0x16, 0x00}},
+    {2, {0x17, 0x00}},
+    {2, {0x18, 0x00}},
+    {2, {0x19, 0x00}},
+    {2, {0x1A, 0x00}},
+    {2, {0x1B, 0x00}},
+    {2, {0x1C, 0x00}},
+    {2, {0x1D, 0x00}},
+    {2, {0x1E, 0xC0}},
+    {2, {0x1F, 0x80}},
+    {2, {0x20, 0x04}},
+    {2, {0x21, 0x03}},
+    {2, {0x22, 0x00}},
+    {2, {0x23, 0x00}},
+    {2, {0x24, 0x00}},
+    {2, {0x25, 0x00}},
+    {2, {0x26, 0x00}},
+    {2, {0x27, 0x00}},
+    {2, {0x28, 0x33}},
+    {2, {0x29, 0x33}},
+    {2, {0x2A, 0x00}},
+    {2, {0x2B, 0x00}},
+    {2, {0x2C, 0x00}},
+    {2, {0x2D, 0x00}},
+    {2, {0x2E, 0x00}},
+    {2, {0x2F, 0x00}},
+    {2, {0x30, 0x00}},
+    {2, {0x31, 0x00}},
+    {2, {0x32, 0x00}},
+    {2, {0x33, 0x00}},
+    {2, {0x34, 0x04}},
+    {2, {0x35, 0x00}},
+    {2, {0x36, 0x00}},
+    {2, {0x37, 0x00}},
+    {2, {0x38, 0x3C}},
+    {2, {0x39, 0x00}},
+    {2, {0x3A, 0x00}},
+    {2, {0x3B, 0x00}},
+    {2, {0x3C, 0x00}},
+    {2, {0x3D, 0x00}},
+    {2, {0x3E, 0x00}},
+    {2, {0x3F, 0x00}},
+    {2, {0x40, 0x00}},
+    {2, {0x41, 0x00}},
+    {2, {0x42, 0x00}},
+    {2, {0x43, 0x00}},
+    {2, {0x44, 0x00}},
+    {2, {0x50, 0x00}},
+    {2, {0x51, 0x11}},
+    {2, {0x52, 0x44}},
+    {2, {0x53, 0x55}},
+    {2, {0x54, 0x88}},
+    {2, {0x55, 0xAB}},
+    {2, {0x56, 0x00}},
+    {2, {0x57, 0x11}},
+    {2, {0x58, 0x22}},
+    {2, {0x59, 0x33}},
+    {2, {0x5A, 0x44}},
+    {2, {0x5B, 0x55}},
+    {2, {0x5C, 0x66}},
+    {2, {0x5D, 0x77}},
+    {2, {0x5E, 0x00}},
+    {2, {0x5F, 0x02}},
+    {2, {0x60, 0x02}},
+    {2, {0x61, 0x0A}},
+    {2, {0x62, 0x09}},
+    {2, {0x63, 0x08}},
+    {2, {0x64, 0x13}},
+    {2, {0x65, 0x12}},
+    {2, {0x66, 0x11}},
+    {2, {0x67, 0x10}},
+    {2, {0x68, 0x0F}},
+    {2, {0x69, 0x0E}},
+    {2, {0x6A, 0x0D}},
+    {2, {0x6B, 0x0C}},
+    {2, {0x6C, 0x06}},
+    {2, {0x6D, 0x07}},
+    {2, {0x6E, 0x02}},
+    {2, {0x6F, 0x02}},
+    {2, {0x70, 0x02}},
+    {2, {0x71, 0x02}},
+    {2, {0x72, 0x02}},
+    {2, {0x73, 0x02}},
+    {2, {0x74, 0x02}},
+    {2, {0x75, 0x02}},
+    {2, {0x76, 0x02}},
+    {2, {0x77, 0x0A}},
+    {2, {0x78, 0x06}},
+    {2, {0x79, 0x07}},
+    {2, {0x7A, 0x10}},
+    {2, {0x7B, 0x11}},
+    {2, {0x7C, 0x12}},
+    {2, {0x7D, 0x13}},
+    {2, {0x7E, 0x0C}},
+    {2, {0x7F, 0x0D}},
+    {2, {0x80, 0x0E}},
+    {2, {0x81, 0x0F}},
+    {2, {0x82, 0x09}},
+    {2, {0x83, 0x08}},
+    {2, {0x84, 0x02}},
+    {2, {0x85, 0x02}},
+    {2, {0x86, 0x02}},
+    {2, {0x87, 0x02}},
+    {2, {0x88, 0x02}},
+    {2, {0x89, 0x02}},
+    {2, {0x8A, 0x02}},
+    {4, {0xFF, 0x98, 0x81, 0x04}},
+    {2, {0x6E, 0x2A}},
+    {2, {0x6F, 0x37}},
+    {2, {0x3A, 0x24}},
+    {2, {0x8D, 0x19}},
+    {2, {0x87, 0xBA}},
+    {2, {0xB2, 0xD1}},
+    {2, {0x88, 0x0B}},
+    {2, {0x38, 0x01}},
+    {2, {0x39, 0x00}},
+    {2, {0xB5, 0x02}},
+    {2, {0x31, 0x25}},
+    {2, {0x3B, 0x98}},
+    {4, {0xFF, 0x98, 0x81, 0x01}},
+    {2, {0x22, 0x0A}},
+    {2, {0x31, 0x0C}},
+    {2, {0x53, 0x40}},
+    {2, {0x55, 0x45}},
+    {2, {0x50, 0xB7}},
+    {2, {0x51, 0xB2}},
+    {2, {0x60, 0x07}},
+    {2, {0xA0, 0x22}},
+    {2, {0xA1, 0x3F}},
+    {2, {0xA2, 0x4E}},
+    {2, {0xA3, 0x17}},
+    {2, {0xA4, 0x1A}},
+    {2, {0xA5, 0x2D}},
+    {2, {0xA6, 0x21}},
+    {2, {0xA7, 0x22}},
+    {2, {0xA8, 0xC4}},
+    {2, {0xA9, 0x1B}},
+    {2, {0xAA, 0x25}},
+    {2, {0xAB, 0xA7}},
+    {2, {0xAC, 0x1A}},
+    {2, {0xAD, 0x19}},
+    {2, {0xAE, 0x4B}},
+    {2, {0xAF, 0x1F}},
+    {2, {0xB0, 0x2A}},
+    {2, {0xB1, 0x59}},
+    {2, {0xB2, 0x64}},
+    {2, {0xB3, 0x3F}},
+    {2, {0xC0, 0x22}},
+    {2, {0xC1, 0x48}},
+    {2, {0xC2, 0x59}},
+    {2, {0xC3, 0x15}},
+    {2, {0xC4, 0x15}},
+    {2, {0xC5, 0x28}},
+    {2, {0xC6, 0x1C}},
+    {2, {0xC7, 0x1E}},
+    {2, {0xC8, 0xC4}},
+    {2, {0xC9, 0x1C}},
+    {2, {0xCA, 0x2B}},
+    {2, {0xCB, 0xA3}},
+    {2, {0xCC, 0x1F}},
+    {2, {0xCD, 0x1E}},
+    {2, {0xCE, 0x52}},
+    {2, {0xCF, 0x24}},
+    {2, {0xD0, 0x2A}},
+    {2, {0xD1, 0x58}},
+    {2, {0xD2, 0x68}},
+    {2, {0xD3, 0x3F}},
+    {4, {0xFF, 0x98, 0x81, 0x00}},
+    {1, {0x11}},
+    {1, {0x29}},
+};
+
+static void mipi_panel_init_cmd_send(hpm_panel_t *panel)
+{
+    int ret;
+    uint8_t page_cmd[4] = {0xFF, 0x98, 0x81, 0x01};
+    uint8_t panel_id[2] = {0x98, 0x81};
+    uint8_t rdata;
+    MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
+
+    mipi_dsi_dcs_write_buffer(mipi_host, 0, page_cmd, 4);
+
+    for (int i = 0; i < 2; i++) {
+        mipi_dsi_set_maximum_return_packet_size(mipi_host, 0, 1);
+        ret = mipi_dsi_dcs_read(mipi_host, 0, i, &rdata, 1);
+        if (ret <= 0 || rdata != panel_id[i]) {
+            printf("read id[%d]: 0x%02X -- failed\n", i, rdata);
+            while (1) {
+            }
+        } else {
+            printf("read id[%d]: 0x%02X -- ok\n", i, rdata);
+        }
+        hpm_panel_delay_ms(10);
+    }
+
+    int mipi_cmd_num = sizeof(mipi_panel_cmd) / sizeof(mipi_panel_cmd[0]);
+    for (int i = 0; i < mipi_cmd_num; i++) {
+        ret = mipi_dsi_dcs_write_buffer(mipi_host, 0, mipi_panel_cmd[i].cmd, mipi_panel_cmd[i].len);
+        if (ret <= 0)
+            printf("mipi_cmd[%d].cmd: 0x%02X -- failed\n", i, mipi_panel_cmd[i].cmd[0]);
+    }
+
+    hpm_panel_delay_ms(10);
+}
+
+static void mipi_panel_host_init(hpm_panel_t *panel)
+{
+    MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
+    const hpm_panel_timing_t *timing = &panel->timing;
+    mipi_dsi_config_t mipi_cfg;
+    mipi_dsi_get_defconfig_on_video(&mipi_cfg);
+
+    mipi_cfg.channel = 0;
+    mipi_cfg.lanes = 4;
+    mipi_cfg.video_para.pixel_clock_khz = panel->hw_if.lcdc_pixel_clk_khz;
+    mipi_cfg.video_para.hactive = timing->hactive;
+    mipi_cfg.video_para.hsync_len = timing->hsync_len;
+    mipi_cfg.video_para.hback_porch = timing->hback_porch;
+    mipi_cfg.video_para.hfront_porch = timing->hfront_porch;
+    mipi_cfg.video_para.vsync_len = timing->vsync_len;
+    mipi_cfg.video_para.vactive = timing->vactive;
+    mipi_cfg.video_para.vback_porch = timing->vback_porch;
+    mipi_cfg.video_para.vfront_porch = timing->vfront_porch;
+
+    mipi_dsi_init(mipi_host, &mipi_cfg);
+}
+
+static void mipi_panel_phy_init(hpm_panel_t *panel)
+{
+    MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
+    MIPI_DSI_PHY_Type *mipi_phy = panel->hw_if.video.mipi.mipi_phy_base;
+
+    mipi_dsi_phy_config_t mipi_phy_cfg = {
+        .lanes = 4,
+        .lane_mbps = 500
+    };
+    mipi_dsi_phy_powerdown(mipi_host);
+    mipi_dsi_phy_init(mipi_phy, &mipi_phy_cfg);
+    mipi_dsi_phy_poweron(mipi_host);
+}
+
+static void reset(hpm_panel_t *panel)
+{
+    if (!panel->hw_if.set_reset_pin_level)
+        return;
+
+    panel->hw_if.set_reset_pin_level(0);
+    hpm_panel_delay_ms(20);
+
+    panel->hw_if.set_reset_pin_level(1);
+    hpm_panel_delay_ms(15);
+}
+
+static void init(hpm_panel_t *panel)
+{
+    if (panel->hw_if.set_video_router)
+        panel->hw_if.set_video_router();
+
+    mipi_panel_host_init(panel);
+    mipi_panel_phy_init(panel);
+    mipi_panel_init_cmd_send(panel);
+}
+
+static void power_on(hpm_panel_t *panel)
+{
+    MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
+
+    if (panel->state.power_state != HPM_PANEL_STATE_POWER_ON) {
+        mipi_dsi_video_mode_hs_transfer_enable(mipi_host);
+
+        if (panel->hw_if.set_backlight) {
+            if (panel->state.backlight_percent == 0)
+                panel->state.backlight_percent = 100;
+            panel->hw_if.set_backlight(panel->state.backlight_percent);
+        }
+        panel->state.power_state = HPM_PANEL_STATE_POWER_ON;
+    }
+}
+
+static void power_off(hpm_panel_t *panel)
+{
+    MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
+
+    if (panel->state.power_state != HPM_PANEL_STATE_POWER_OFF) {
+        if (panel->hw_if.set_backlight)
+            panel->hw_if.set_backlight(0);
+        mipi_dsi_video_mode_hs_transfer_disable(mipi_host);
+        panel->state.power_state = HPM_PANEL_STATE_POWER_OFF;
+    }
+}
+
+hpm_panel_t panel_mc10128007_31b = {
+    .name = "mc10128007_31b",
+    .if_type = HPM_PANEL_IF_TYPE_MIPI,
+    .timing = {
+        .pixel_clock_khz = 60000,
+        .hactive = 800,
+        .hfront_porch = 52,
+        .hback_porch = 48,
+        .hsync_len = 8,
+
+        .vactive = 1280,
+        .vfront_porch = 15,
+        .vback_porch = 16,
+        .vsync_len = 6,
+    },
+    .funcs = {
+        .reset = reset,
+        .init = init,
+        .power_on = power_on,
+        .power_off = power_off,
+    },
+};
+

+ 73 - 0
bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/tm070rdh13.c

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include "hpm_panel.h"
+
+static void reset(hpm_panel_t *panel)
+{
+    if (!panel->hw_if.set_reset_pin_level)
+        return;
+
+    panel->hw_if.set_reset_pin_level(0);
+    hpm_panel_delay_ms(20);
+
+    panel->hw_if.set_reset_pin_level(1);
+    hpm_panel_delay_ms(20);
+}
+
+static void init(hpm_panel_t *panel)
+{
+    if (panel->hw_if.set_video_router)
+        panel->hw_if.set_video_router();
+}
+
+static void power_on(hpm_panel_t *panel)
+{
+    if (panel->state.power_state != HPM_PANEL_STATE_POWER_ON &&
+        panel->hw_if.set_backlight) {
+        if (panel->state.backlight_percent == 0)
+            panel->state.backlight_percent = 100;
+
+        panel->hw_if.set_backlight(panel->state.backlight_percent);
+        panel->state.power_state = HPM_PANEL_STATE_POWER_ON;
+    }
+}
+
+static void power_off(hpm_panel_t *panel)
+{
+    if (panel->state.power_state != HPM_PANEL_STATE_POWER_OFF &&
+        panel->hw_if.set_backlight) {
+
+        panel->hw_if.set_backlight(0);
+        panel->state.power_state = HPM_PANEL_STATE_POWER_OFF;
+    }
+}
+
+hpm_panel_t panel_tm070rdh13 = {
+    .name = "tm070rdh13",
+    .if_type = HPM_PANEL_IF_TYPE_RGB,
+    .timing = {
+        .pixel_clock_khz = 60000,
+        .hactive = 800,
+        .hfront_porch = 50,
+        .hback_porch = 36,
+        .hsync_len = 10,
+        .hsync_pol = 1,
+
+        .vactive = 480,
+        .vfront_porch = 10,
+        .vback_porch = 20,
+        .vsync_len = 3,
+        .vsync_pol = 1,
+    },
+    .funcs = {
+        .reset = reset,
+        .init = init,
+        .power_on = power_on,
+        .power_off = power_off,
+    },
+};
+

+ 107 - 0
bsp/hpmicro/libraries/hpm_sdk/components/panel/panels/tm103xdgp01.c

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include "hpm_panel.h"
+#include "hpm_pixelmux_drv.h"
+#include "hpm_lvb_drv.h"
+
+static void lvds_panel_lvb_init(hpm_panel_t *panel)
+{
+    LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
+    lvb_config_t lvb_config;
+    lvb_get_default_config(&lvb_config);
+
+    lvb_config.split_mode_en = true;
+    lvb_config.txclk_shift = lvb_txclk_shift_1100011;
+    lvb_init(lvb_base, &lvb_config);
+
+    lvb_ch_config_t lvb_ch_cfg;
+    lvb_ch_cfg.map = lvb_ch_mapping_vesa;
+
+    if (panel->hw_if.video.lvds.channel_di_index == 0)
+        lvb_ch_cfg.data_src = lvb_ch_data_source_di0;
+    else
+        lvb_ch_cfg.data_src = lvb_ch_data_source_di1;
+
+    lvb_ch_config(lvb_base, lvb_ch_num_0, &lvb_ch_cfg);
+    lvb_ch_config(lvb_base, lvb_ch_num_1, &lvb_ch_cfg);
+
+    lvb_ch_enable(lvb_base, lvb_ch_num_0);
+    lvb_ch_enable(lvb_base, lvb_ch_num_1);
+}
+
+static void lvds_panel_phy_init(hpm_panel_t *panel)
+{
+    LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
+    lvds_phy_clk_param_t param;
+    uint32_t pixel_clk = panel->hw_if.lcdc_pixel_clk_khz * 1000;
+    pixelmux_lvds_phy_calc_pll_cfg(pixel_clk, true, &param);
+    pixelmux_config_lvds_tx_phy0_clk(&param.reg);
+    pixelmux_config_lvds_tx_phy1_clk(&param.reg);
+
+    lvb_lvds_phy_lane_config_t lvds_lane_cfg;
+    lvb_lvds_phy_lane_get_default_config(&lvds_lane_cfg);
+    lvds_lane_cfg.fvco_div4 = param.reg.data_rate_div4;
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx0, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx1, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx2, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx3, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_txck, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx0, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx1, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx2, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx3, &lvds_lane_cfg);
+    lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_txck, &lvds_lane_cfg);
+
+    lvb_lvds_phy0_poweron(lvb_base);
+    lvb_lvds_phy1_poweron(lvb_base);
+
+    while (lvb_lvds_phy_split_pll_is_lock(lvb_base) == false) {
+    }
+}
+
+static void reset(hpm_panel_t *panel)
+{
+    if (!panel->hw_if.set_reset_pin_level)
+        return;
+
+    panel->hw_if.set_reset_pin_level(0);
+    hpm_panel_delay_us(2000);
+
+    panel->hw_if.set_reset_pin_level(1);
+    hpm_panel_delay_us(2000);
+}
+
+static void init(hpm_panel_t *panel)
+{
+    if (panel->hw_if.set_video_router)
+        panel->hw_if.set_video_router();
+
+    lvds_panel_lvb_init(panel);
+    lvds_panel_phy_init(panel);
+}
+
+hpm_panel_t panel_tm103xdgp01 = {
+    .name = "tm103xdgp01",
+    .if_type = HPM_PANEL_IF_TYPE_LVDS_SPLIT,
+    .timing = {
+        .pixel_clock_khz = 45000,
+        .hactive = 1920,
+        .hfront_porch = 32,
+        .hback_porch = 32,
+        .hsync_len = 64,
+
+        .vactive = 720,
+        .vfront_porch = 2,
+        .vback_porch = 2,
+        .vsync_len = 4,
+    },
+    .funcs = {
+        .reset = reset,
+        .init = init,
+    },
+};
+

+ 271 - 0
bsp/hpmicro/libraries/hpm_sdk/components/ppi/hpm_ppi.c

@@ -0,0 +1,271 @@
+
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*---------------------------------------------------------------------
+ * Include
+ *---------------------------------------------------------------------
+ */
+#include "hpm_ppi.h"
+#include "hpm_clock_drv.h"
+
+static uint32_t ppi_ns2cycle(uint32_t ns)
+{
+    uint32_t ppi_freq = clock_get_frequency(clock_ppi0);
+    uint32_t max_cycle = PPI_CMD_CMD_CFG_CYCLE_NUM_MASK >> PPI_CMD_CMD_CFG_CYCLE_NUM_SHIFT;
+    uint32_t ns_per_cycle;
+    uint32_t cycle;
+
+    ns_per_cycle = 1000000000 / ppi_freq;
+    cycle = ns / ns_per_cycle;
+    if (cycle > max_cycle) {
+        cycle = max_cycle;
+    }
+
+    return cycle;
+}
+
+/* API */
+void ppi_config_async_sram(PPI_Type *ppi, uint8_t cs_index, uint8_t cmd_start_index, ppi_async_sram_config_t *config)
+{
+    ppi_cs_pin_config_t cs_config;
+    ppi_cmd_config_t cmd_config;
+
+    assert(!config->ad_mux_mode && (config->port_size != ppi_port_size_32bits));
+    assert(((config->base_address & 0xFFFFF) == 0) && (config->size_in_byte > 0));    /* Addr should be aligned by 1MB */
+
+    /*
+     * Pin polarity Config
+     */
+    if (config->cs_valid_polarity) {
+        ppi_config_cs_pin_polarity(ppi, cs_index, ppi_cs_idle_pol_low);
+    } else {
+        ppi_config_cs_pin_polarity(ppi, cs_index, ppi_cs_idle_pol_high);
+    }
+
+    if (config->ad_mux_mode) {
+        ppi_set_ctrl_pin_dir(ppi, config->adv_ctrl_pin, ppi_ctrl_pin_dir_output);
+        ppi_config_ctrl_pin_polarity(ppi, config->adv_ctrl_pin, ppi_ctrl_pol_low);
+    }
+    ppi_set_ctrl_pin_dir(ppi, config->rel_ctrl_pin, ppi_ctrl_pin_dir_output);
+    ppi_config_ctrl_pin_polarity(ppi, config->rel_ctrl_pin, ppi_ctrl_pol_low);
+    ppi_set_ctrl_pin_dir(ppi, config->wel_ctrl_pin, ppi_ctrl_pin_dir_output);
+    ppi_config_ctrl_pin_polarity(ppi, config->wel_ctrl_pin, ppi_ctrl_pol_low);
+
+    /*
+     * Read Cmd
+     */
+    /* common */
+    cmd_config.cs_pin_value = config->cs_valid_polarity;
+    cmd_config.clk_output = false;
+    if (config->ad_mux_mode) {
+        cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
+        cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
+        cmd_config.byte_sel[2] = ppi_byte_sel_16_23_bits;
+        cmd_config.byte_sel[3] = ppi_byte_sel_24_31_bits;
+    } else {
+        if (config->port_size == ppi_port_size_8bits) {
+            cmd_config.ad_func_sel[0] = ppi_ad_func_data;
+            cmd_config.ad_pin_dir[0] = ppi_ad_pin_dir_input;
+            cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
+            for (uint8_t i = 1; i < 4; i++) {
+                cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+                cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+            }
+            cmd_config.byte_sel[1] = ppi_byte_sel_0_7_bits;
+            cmd_config.byte_sel[2] = ppi_byte_sel_8_15_bits;
+            cmd_config.byte_sel[3] = ppi_byte_sel_16_23_bits;
+        } else if (config->port_size == ppi_port_size_16bits) {
+            for (uint8_t i = 0; i < 2; i++) {
+                cmd_config.ad_func_sel[i] = ppi_ad_func_data;
+                cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_input;
+            }
+            cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
+            cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
+            for (uint8_t i = 2; i < 4; i++) {
+                cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+                cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+            }
+            cmd_config.byte_sel[2] = ppi_byte_sel_0_7_bits;
+            cmd_config.byte_sel[3] = ppi_byte_sel_8_15_bits;
+        } else {
+            ;    /* Not Support */
+        }
+    }
+    cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
+
+    /* AS Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->as_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
+    ppi_config_cmd(ppi, cmd_start_index, &cmd_config);
+
+    /* AH Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->ah_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
+    ppi_config_cmd(ppi, cmd_start_index + 1, &cmd_config);
+
+    /* REL Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->rel_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_data;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_input;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = false;
+    ppi_config_cmd(ppi, cmd_start_index + 2, &cmd_config);
+
+    /* REH Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->reh_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_data;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_input;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
+    ppi_config_cmd(ppi, cmd_start_index + 3, &cmd_config);
+
+    /*
+     * Write Cmd
+     */
+    /* common */
+    cmd_config.cs_pin_value = config->cs_valid_polarity;
+    cmd_config.clk_output = false;
+    if (config->ad_mux_mode) {
+        cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
+        cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
+        cmd_config.byte_sel[2] = ppi_byte_sel_16_23_bits;
+        cmd_config.byte_sel[3] = ppi_byte_sel_24_31_bits;
+    } else {
+        if (config->port_size == ppi_port_size_8bits) {
+            cmd_config.ad_func_sel[0] = ppi_ad_func_data;
+            cmd_config.ad_pin_dir[0] = ppi_ad_pin_dir_output;
+            cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
+            for (uint8_t i = 1; i < 4; i++) {
+                cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+                cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+            }
+            cmd_config.byte_sel[1] = ppi_byte_sel_0_7_bits;
+            cmd_config.byte_sel[2] = ppi_byte_sel_8_15_bits;
+            cmd_config.byte_sel[3] = ppi_byte_sel_16_23_bits;
+        } else if (config->port_size == ppi_port_size_16bits) {
+            for (uint8_t i = 0; i < 2; i++) {
+                cmd_config.ad_func_sel[i] = ppi_ad_func_data;
+                cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+            }
+            cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
+            cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
+            for (uint8_t i = 2; i < 4; i++) {
+                cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+                cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+            }
+            cmd_config.byte_sel[2] = ppi_byte_sel_0_7_bits;
+            cmd_config.byte_sel[3] = ppi_byte_sel_8_15_bits;
+        } else {
+            ;    /* Not Support */
+        }
+    }
+    cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
+
+    /* AS Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->as_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
+    ppi_config_cmd(ppi, cmd_start_index + 4, &cmd_config);
+
+    /* AH Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->ah_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
+    ppi_config_cmd(ppi, cmd_start_index + 5, &cmd_config);
+
+    /* WEL Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->wel_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_data;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = false;
+    ppi_config_cmd(ppi, cmd_start_index + 6, &cmd_config);
+
+    /* WEH Stage */
+    cmd_config.cmd_cycle = ppi_ns2cycle(config->weh_in_ns);
+    if (config->ad_mux_mode) {
+        for (uint8_t i = 0; i < 4; i++) {
+            cmd_config.ad_func_sel[i] = ppi_ad_func_data;
+            cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
+        }
+        cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
+    }
+    cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
+    ppi_config_cmd(ppi, cmd_start_index + 7, &cmd_config);
+
+    /*
+     * CS Config
+     */
+    cs_config.addr_start_high_12bits = (config->base_address & 0xFFF00000u) >> 20u;
+    cs_config.addr_end_high_12bits = ((config->base_address + (config->size_in_byte - 1u)) & 0xFFF00000u) >> 20u;
+    cs_config.port_size = config->port_size;
+    cs_config.addr_mask = 0xFFFFu;
+    cs_config.sync_clk_en = false;
+    cs_config.sync_clk_sel = 0;
+    cs_config.interval_cycle = 2;
+    cs_config.rcmd_start0 = cmd_start_index;
+    cs_config.rcmd_end0 = cmd_start_index + 3;
+    cs_config.rcmd_start1 = cmd_start_index;
+    cs_config.rcmd_end1 = cmd_start_index + 3;
+    cs_config.wcmd_start0 = cmd_start_index + 4;
+    cs_config.wcmd_end0 = cmd_start_index + 7;
+    cs_config.wcmd_start1 = cmd_start_index + 4;
+    cs_config.wcmd_end1 = cmd_start_index + 7;
+#if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS
+    if (config->dm_valid_polarity) {
+        cs_config.dm_polarity = ppi_dm_valid_pol_high;
+    } else {
+        cs_config.dm_polarity = ppi_dm_valid_pol_low;
+    }
+#else
+    if (config->dm_valid_polarity) {
+        ppi_config_dm_pin_polarity(ppi, cs_index, ppi_dm_valid_pol_high);
+    } else {
+        ppi_config_dm_pin_polarity(ppi, cs_index, ppi_dm_valid_pol_low);
+    }
+#endif
+    ppi_config_cs_pin(ppi, cs_index, &cs_config);
+}

+ 58 - 0
bsp/hpmicro/libraries/hpm_sdk/components/ppi/hpm_ppi.h

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _HPM_PPI_H
+#define _HPM_PPI_H
+
+/*---------------------------------------------------------------------
+ * Includes
+ *---------------------------------------------------------------------
+ */
+#include "hpm_ppi_drv.h"
+
+/**
+ * @brief ppi async sram config structure
+ *
+ */
+typedef struct {
+    uint32_t base_address;              /**< external SRAM base address, should be 1MB aligned */
+    uint32_t size_in_byte;              /**< external SRAM size in byte */
+    ppi_port_size_t port_size;          /**< port size */
+    bool ad_mux_mode;                   /**< addr and data mux mode */
+    bool cs_valid_polarity;             /**< cs valid polarity */
+    bool dm_valid_polarity;             /**< dm valid polarity */
+    bool addr_valid_polarity;           /**< addr valid polarity */
+    uint8_t adv_ctrl_pin;               /**< adv ctrl pin number, 0 - 7 */
+    uint8_t rel_ctrl_pin;               /**< rel ctrl pin number, 0 - 7 */
+    uint8_t wel_ctrl_pin;               /**< wel ctrl pin number, 0 - 7 */
+    uint8_t as_in_ns;                   /**< address setup time */
+    uint8_t ah_in_ns;                   /**< address hold time */
+    uint8_t rel_in_ns;                  /**< RE low time */
+    uint8_t reh_in_ns;                  /**< RE high time */
+    uint8_t wel_in_ns;                  /**< WE low time */
+    uint8_t weh_in_ns;                  /**< WE high time */
+} ppi_async_sram_config_t;
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief config async sram
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] cs_index cs index, value: 0 - 3
+ * @param[in] cmd_index cmd start index
+ * @param[in] config async sram config structure pointer, @ref ppi_async_sram_config_t
+ */
+void ppi_config_async_sram(PPI_Type *ppi, uint8_t cs_index, uint8_t cmd_start_index, ppi_async_sram_config_t *config);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+#endif /* _HPM_PPI_H */

+ 824 - 0
bsp/hpmicro/libraries/hpm_sdk/components/spi/hpm_spi.c

@@ -6,6 +6,170 @@
  */
 
 #include "hpm_spi.h"
+#include "hpm_clock_drv.h"
+#include <stdlib.h>
+
+#if USE_DMA_MGR
+#include "hpm_dma_mgr.h"
+#endif
+typedef struct {
+    SPI_Type *spi_ptr;
+    clock_name_t spi_clock_name;
+#if USE_DMA_MGR
+    uint8_t tx_dmamux_src;
+    uint8_t rx_dmamux_src;
+    dma_resource_t txdma_resource;
+    dma_resource_t rxdma_resource;
+    spi_dma_complete_cb tx_dma_complete;
+    spi_dma_complete_cb rx_dma_complete;
+#endif
+} hpm_spi_cfg_t;
+
+static hpm_spi_cfg_t spi_dma_cfg_table[] = {
+#if defined(HPM_SPI0)
+    {
+        .spi_ptr = HPM_SPI0,
+        .spi_clock_name = clock_spi0,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI0_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI0_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI1)
+    {
+        .spi_ptr = HPM_SPI1,
+        .spi_clock_name = clock_spi1,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI1_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI1_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI2)
+    {
+        .spi_ptr = HPM_SPI2,
+        .spi_clock_name = clock_spi2,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI2_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI2_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI3)
+    {
+        .spi_ptr = HPM_SPI3,
+        .spi_clock_name = clock_spi3,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI3_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI3_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI4)
+    {
+        .spi_ptr = HPM_SPI4,
+        .spi_clock_name = clock_spi4,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI4_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI4_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI5)
+    {
+        .spi_ptr = HPM_SPI5,
+        .spi_clock_name = clock_spi5,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI5_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI5_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI6)
+    {
+        .spi_ptr = HPM_SPI6,
+        .spi_clock_name = clock_spi6,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI6_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI6_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI7)
+    {
+        .spi_ptr = HPM_SPI7,
+        .spi_clock_name = clock_spi7,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI7_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI7_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI8)
+    {
+        .spi_ptr = HPM_SPI8,
+        .spi_clock_name = clock_spi8,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI8_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI8_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI9)
+    {
+        .spi_ptr = HPM_SPI9,
+        .spi_clock_name = clock_spi9,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI9_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI9_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+
+#if defined(HPM_SPI10)
+    {
+        .spi_ptr = HPM_SPI10,
+        .spi_clock_name = clock_spi10,
+#if USE_DMA_MGR
+        .tx_dmamux_src = HPM_DMA_SRC_SPI10_TX,
+        .rx_dmamux_src = HPM_DMA_SRC_SPI10_RX,
+        .rx_dma_complete = NULL,
+        .tx_dma_complete = NULL,
+#endif
+    },
+#endif
+};
+
 
 static hpm_stat_t hpm_spi_tx_trigger_dma(DMA_Type *dma_ptr, uint8_t ch_num, SPI_Type *spi_ptr, uint32_t src, uint8_t data_width, uint32_t size)
 {
@@ -428,3 +592,663 @@ hpm_stat_t hpm_spi_release_gpio_cs(spi_context_t *context)
     return status_success;
 }
 
+static hpm_stat_t wait_spi_slave_active(SPI_Type *ptr, bool active_status, uint32_t timeout)
+{
+    uint32_t ticks_per_us = (hpm_core_clock + 1000000 - 1U) / 1000000;
+    uint64_t expected_ticks = hpm_csr_get_core_cycle() + (uint64_t)ticks_per_us * 1000UL * timeout;
+    do {
+        if (hpm_csr_get_core_cycle() > expected_ticks) {
+            return status_timeout;
+        }
+    } while (spi_is_active(ptr) == !active_status);
+    return status_success;
+}
+
+static hpm_spi_cfg_t *hpm_spi_get_cfg_obj(SPI_Type *ptr)
+{
+    hpm_spi_cfg_t *obj;
+    uint8_t i = 0;
+    for (i = 0; i < (sizeof(spi_dma_cfg_table) / sizeof(hpm_spi_cfg_t)); i++) {
+        obj = &spi_dma_cfg_table[i];
+        if (obj->spi_ptr == ptr) {
+            return obj;
+        }
+    }
+    return NULL;
+}
+
+static void hpm_spi_transfer_init(SPI_Type *ptr, spi_trans_mode_t mode, uint32_t size)
+{
+    uint32_t slv_mode = SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT);
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4;
+    }
+    if (slv_mode == spi_master_mode) {
+        spi_set_transfer_mode(ptr, mode);
+    } else {
+        /* for slave mode, only support trans_write_read_together mode in only_data_mode */
+        spi_set_transfer_mode(ptr, spi_trans_write_read_together);
+    }
+    if ((mode == spi_trans_write_read_together) || (slv_mode == spi_slave_mode)) {
+        spi_set_write_data_count(ptr, size / data_len_in_bytes);
+        spi_set_read_data_count(ptr, size / data_len_in_bytes);
+    } else if (mode == spi_trans_write_only) {
+        spi_set_write_data_count(ptr, size / data_len_in_bytes);
+    } else {
+        spi_set_read_data_count(ptr, size / data_len_in_bytes);
+    }
+    /* start new transmission, reset spi for slave*/
+    if (slv_mode == spi_slave_mode) {
+        spi_reset(ptr);
+    }
+    spi_transmit_fifo_reset(ptr);
+    spi_receive_fifo_reset(ptr);
+    while (ptr->CTRL & (SPI_CTRL_TXFIFORST_MASK | SPI_CTRL_RXFIFORST_MASK)) {
+    }
+}
+
+static hpm_stat_t write_read_data_together(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *wbuff, uint32_t wsize,
+                                                uint8_t *rbuff, uint32_t rsize, uint32_t timeout)
+{
+    uint8_t txfifo_size = spi_get_tx_fifo_size(ptr);
+    uint32_t rx_index = 0, tx_index = 0;
+    uint8_t rxfifo_valid_size, txfifo_valid_size, j;
+    uint32_t ticks_per_us = (hpm_core_clock + 1000000 - 1U) / 1000000;
+    uint64_t expected_ticks = hpm_csr_get_core_cycle() + (uint64_t)ticks_per_us * 1000UL * timeout;
+    while ((rx_index < rsize) || (tx_index < wsize)) {
+        if (tx_index < wsize) {
+            txfifo_valid_size = spi_get_tx_fifo_valid_data_size(ptr);
+            if ((txfifo_size - txfifo_valid_size) > 0) {
+                for (j = 0; j < (txfifo_size - txfifo_valid_size); j++) {
+                    if (tx_index >= wsize) {
+                        break;
+                    }
+                    switch (data_len_in_bytes) {
+                    case 1:
+                        ptr->DATA = *(uint8_t *)wbuff;
+                        break;
+                    case 2:
+                        ptr->DATA = *(uint16_t *)wbuff;
+                        break;
+                    default:
+                        ptr->DATA = *(uint32_t *)wbuff;
+                        break;
+                    }
+                    wbuff += data_len_in_bytes;
+                    tx_index++;
+                }
+            }
+        }
+        if (rx_index < rsize) {
+            rxfifo_valid_size = spi_get_rx_fifo_valid_data_size(ptr);
+            if (rxfifo_valid_size > 0) {
+                for (j = 0; j < rxfifo_valid_size; j++) {
+                    if (rx_index >= rsize) {
+                        break;
+                    }
+                    switch (data_len_in_bytes) {
+                    case 1:
+                        *(uint8_t *)rbuff = (uint8_t)ptr->DATA;
+                        break;
+                    case 2:
+                        *(uint16_t *)rbuff = (uint16_t)ptr->DATA;
+                        break;
+                    default:
+                        *(uint32_t *)rbuff = ptr->DATA;
+                        break;
+                    }
+                    rbuff += data_len_in_bytes;
+                    rx_index++;
+                }
+            }
+        }
+        if (hpm_csr_get_core_cycle() > expected_ticks) {
+            return status_timeout;
+        }
+    }
+    return status_success;
+}
+
+static hpm_stat_t read_data_single(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *rbuff, uint32_t rsize, uint32_t timeout)
+{
+    uint32_t rx_index = 0;
+    uint8_t rxfifo_valid_size, j;
+    uint32_t ticks_per_us = (hpm_core_clock + 1000000 - 1U) / 1000000;
+    uint64_t expected_ticks = hpm_csr_get_core_cycle() + (uint64_t)ticks_per_us * 1000UL * timeout;
+    while (rx_index < rsize) {
+        rxfifo_valid_size = spi_get_rx_fifo_valid_data_size(ptr);
+        if (rxfifo_valid_size > 0) {
+            for (j = 0; j < rxfifo_valid_size; j++) {
+                if (rx_index >= rsize) {
+                    break;
+                }
+                switch (data_len_in_bytes) {
+                case 1:
+                    *(uint8_t *)rbuff = (uint8_t)ptr->DATA;
+                    break;
+                case 2:
+                    *(uint16_t *)rbuff = (uint16_t)ptr->DATA;
+                    break;
+                default:
+                    *(uint32_t *)rbuff = ptr->DATA;
+                    break;
+                }
+                rbuff += data_len_in_bytes;
+                rx_index++;
+            }
+        }
+        if (hpm_csr_get_core_cycle() > expected_ticks) {
+            return status_timeout;
+        }
+    }
+    return status_success;
+}
+
+static hpm_stat_t write_data_single(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *wbuff, uint32_t wsize, uint32_t timeout)
+{
+    uint8_t txfifo_size = spi_get_tx_fifo_size(ptr);
+    uint32_t tx_index = 0;
+    uint8_t txfifo_valid_size, j;
+    uint32_t ticks_per_us = (hpm_core_clock + 1000000 - 1U) / 1000000;
+    uint64_t expected_ticks = hpm_csr_get_core_cycle() + (uint64_t)ticks_per_us * 1000UL * timeout;
+    while (tx_index < wsize) {
+        txfifo_valid_size = spi_get_tx_fifo_valid_data_size(ptr);
+        if ((txfifo_size - txfifo_valid_size) > 0) {
+            for (j = 0; j < (txfifo_size - txfifo_valid_size); j++) {
+                if (tx_index >= wsize) {
+                    break;
+                }
+                switch (data_len_in_bytes) {
+                case 1:
+                    ptr->DATA = *(uint8_t *)wbuff;
+                    break;
+                case 2:
+                    ptr->DATA = *(uint16_t *)wbuff;
+                    break;
+                default:
+                    ptr->DATA = *(uint32_t *)wbuff;
+                    break;
+                }
+                wbuff += data_len_in_bytes;
+                tx_index++;
+            }
+        }
+        if (hpm_csr_get_core_cycle() > expected_ticks) {
+            return status_timeout;
+        }
+    }
+    return status_success;
+}
+
+void hpm_spi_get_default_init_config(spi_initialize_config_t *config)
+{
+    config->mode = spi_master_mode;
+    config->io_mode = spi_single_io_mode;
+    config->clk_polarity = spi_sclk_low_idle;
+    config->clk_phase = spi_sclk_sampling_odd_clk_edges;
+    config->data_len = 8;
+    config->data_merge = false;
+    config->direction = msb_first;
+}
+
+hpm_stat_t hpm_spi_initialize(SPI_Type *ptr, spi_initialize_config_t *config)
+{
+    if (config->data_len == 0) {
+        return status_invalid_argument;
+    }
+    /* frist init TRANSFMT reg*/
+    ptr->TRANSFMT = SPI_TRANSFMT_DATALEN_SET(config->data_len - 1) |
+                    SPI_TRANSFMT_DATAMERGE_SET(config->data_merge) |
+                    SPI_TRANSFMT_LSB_SET(config->direction) |
+                    SPI_TRANSFMT_SLVMODE_SET(config->mode) |
+                    SPI_TRANSFMT_CPOL_SET(config->clk_polarity) |
+                    SPI_TRANSFMT_CPHA_SET(config->clk_phase);
+    /* second init TRANSCTRL reg
+     * default phase: disable command/address/token phase,
+     * default Transfer mode: write and read at the same time
+     */
+    ptr->TRANSCTRL = SPI_TRANSCTRL_SLVDATAONLY_SET(1) | /* it's only data anyway for slave*/
+                     SPI_TRANSCTRL_DUALQUAD_SET(config->io_mode);
+
+    /* third: init TIMING reg */
+    ptr->TIMING = SPI_TIMING_CS2SCLK_SET(spi_cs2sclk_half_sclk_1) |
+                  SPI_TIMING_CSHT_SET(spi_csht_half_sclk_1) |
+                  SPI_TIMING_SCLK_DIV_SET(0x10);
+    return status_success;
+}
+
+hpm_stat_t hpm_spi_set_sclk_frequency(SPI_Type *ptr, uint32_t freq)
+{
+    int freq_list[clock_source_general_source_end] = {0};
+    int _freq = freq;
+    uint8_t i = 0;
+    int min_diff_freq;
+    int current_diff_freq;
+    int best_freq;
+    hpm_stat_t stat;
+    uint32_t div;
+    clock_source_t clock_source;
+    clk_src_t clk_src;
+    static spi_timing_config_t timing_config = {0};
+    uint32_t pll_clk = 0;
+    hpm_spi_cfg_t *obj = hpm_spi_get_cfg_obj(ptr);
+    if (obj == NULL) {
+        return status_invalid_argument;
+    }
+    spi_master_get_default_timing_config(&timing_config);
+    timing_config.master_config.clk_src_freq_in_hz = clock_get_frequency(obj->spi_clock_name);
+    timing_config.master_config.sclk_freq_in_hz = freq;
+    timing_config.master_config.cs2sclk = spi_cs2sclk_half_sclk_1;
+    timing_config.master_config.csht = spi_csht_half_sclk_1;
+    stat = spi_master_timing_init(ptr, &timing_config);
+    if (stat != status_success) {
+        spi_master_set_sclk_div(ptr, 0xFF);
+        for (clock_source = (clock_source_t)0; clock_source < clock_source_general_source_end; clock_source++) {
+            pll_clk = get_frequency_for_source(clock_source);
+            div = pll_clk / freq;
+            /* The division factor ranges from 1 to 256 as any integer */
+            if ((div > 0) && (div <= 0x100)) {
+                freq_list[clock_source] = pll_clk / div;
+            }
+        }
+        /* Find the best sclk frequency */
+        min_diff_freq = abs(freq_list[0] - _freq);
+        best_freq = freq_list[0];
+        for (i = 1; i < clock_source_general_source_end; i++) {
+            current_diff_freq = abs(freq_list[i] - _freq);
+            if (current_diff_freq < min_diff_freq) {
+                min_diff_freq = current_diff_freq;
+                best_freq = freq_list[i];
+            }
+        }
+        /* Find the best spi clock frequency */
+        for (i = 0; i < clock_source_general_source_end; i++) {
+            if (best_freq == freq_list[i]) {
+                pll_clk = get_frequency_for_source((clock_source_t)i);
+                clk_src = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, i);
+                div = pll_clk / best_freq;
+                clock_set_source_divider(obj->spi_clock_name, clk_src, div);
+                break;
+            }
+        }
+        stat = status_success;
+    }
+    return stat;
+}
+
+hpm_stat_t hpm_spi_transmit_receive_blocking(SPI_Type *ptr, uint8_t *wbuff, uint8_t *rbuff, uint32_t size, uint32_t timeout)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    uint8_t txfifo_size = spi_get_tx_fifo_size(ptr);
+    uint8_t remain_size = 0, j = 0;
+    uint32_t temp, count;
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    }
+    if ((wbuff == NULL) || (rbuff == NULL) || (size == 0) ||
+        ((SPI_SOC_TRANSFER_COUNT_MAX == 512) && (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes))) ||
+        (spi_master_get_data_phase_format(ptr) != spi_single_io_mode)) {
+        return status_invalid_argument;
+    }
+    count = (size / data_len_in_bytes);
+    hpm_spi_transfer_init(ptr, spi_trans_write_read_together, size);
+    /* for master mode, This CMD register must be written with a dummy value
+     *  to start a SPI transfer even when the command phase is not enabled
+     */
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        ptr->CMD = 0xFF;
+        stat = write_read_data_together(ptr, data_len_in_bytes, wbuff, count, rbuff, count, timeout);
+        if (stat == status_success) {
+            /* waiting....in master mode, becomes 0 after the transfer is finished */
+            stat = wait_spi_slave_active(ptr, false, timeout);
+        }
+    } else {
+        /* Before receiving the host to start transmission, fill the TX FIFO */
+        remain_size = txfifo_size - spi_get_tx_fifo_valid_data_size(ptr);
+        for (j = 0; j < remain_size; j++) {
+            temp = 0;
+            for (uint8_t i = 0; i < data_len_in_bytes; i++) {
+                temp += *(wbuff++) << i * 8;
+            }
+            ptr->DATA = temp;
+        }
+        count -= remain_size;
+        /* waiting....in slave mode, becomes 1 after the SPI CS signal is asserted */
+        stat = wait_spi_slave_active(ptr, true, timeout);
+        /* no need to read RXFIFO because no effect SPI bus for slave mode */
+        if (((size - remain_size) > 0) && (stat == status_success)) {
+            stat = write_read_data_together(ptr, data_len_in_bytes, wbuff, count, rbuff, count + remain_size, timeout);
+        }
+    }
+    return stat;
+}
+
+hpm_stat_t hpm_spi_receive_blocking(SPI_Type *ptr, uint8_t *buff, uint32_t size, uint32_t timeout)
+{
+    hpm_stat_t stat = status_success;
+    uint32_t count;
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    }
+    if ((buff == NULL) || (size == 0) ||
+        ((SPI_SOC_TRANSFER_COUNT_MAX == 512) && (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes)))) {
+        return status_invalid_argument;
+    }
+    count = (size / data_len_in_bytes);
+    hpm_spi_transfer_init(ptr, spi_trans_read_only, size);
+    /* for master mode, This CMD register must be written with a dummy value
+     * to start a SPI transfer even when the command phase is not enabled
+     */
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        ptr->CMD = 0xFF;
+    } else {
+        /* waiting....in slave mode, becomes 1 after the SPI CS signal is asserted */
+        stat = wait_spi_slave_active(ptr, true, timeout);
+    }
+    /* no need to write TXFIFO because no effect SPI bus for slave mode */
+    if (stat == status_success) {
+        stat = read_data_single(ptr, data_len_in_bytes, buff, count, timeout);
+    }
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        /* waiting....in master mode, becomes 0 after the transfer is finished */
+        if (stat == status_success) {
+            stat = wait_spi_slave_active(ptr, false, timeout);
+        }
+    }
+    return stat;
+}
+
+hpm_stat_t hpm_spi_transmit_blocking(SPI_Type *ptr, uint8_t *buff, uint32_t size, uint32_t timeout)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t txfifo_size = spi_get_tx_fifo_size(ptr);
+    uint8_t remain_size = 0, j = 0;
+    uint32_t temp, count;
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    }
+    if ((buff == NULL) || (size == 0) ||
+        ((SPI_SOC_TRANSFER_COUNT_MAX == 512) && (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes)))) {
+        return status_invalid_argument;
+    }
+    count = (size / data_len_in_bytes);
+    hpm_spi_transfer_init(ptr, spi_trans_write_only, size);
+    /* for master mode, This CMD register must be written with a dummy value
+     * to start a SPI transfer even when the command phase is not enabled
+     */
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        ptr->CMD = 0xFF;
+        stat = write_data_single(ptr, data_len_in_bytes, buff, count, timeout);
+        if (stat == status_success) {
+            /* waiting....in master mode, becomes 0 after the transfer is finished */
+            stat = wait_spi_slave_active(ptr, false, timeout);
+        }
+    } else {
+        /* Before receiving the host to start transmission, fill the TX FIFO */
+        remain_size = txfifo_size - spi_get_tx_fifo_valid_data_size(ptr);
+        for (j = 0; j < remain_size; j++) {
+            temp = 0;
+            for (uint8_t i = 0; i < data_len_in_bytes; i++) {
+                temp += *(buff++) << i * 8;
+            }
+            ptr->DATA = temp;
+        }
+        count -= remain_size;
+        /* waiting....in slave mode, becomes 1 after the SPI CS signal is asserted */
+        stat = wait_spi_slave_active(ptr, true, timeout);
+        /* no need to read RXFIFO because no effect SPI bus for slave mode */
+        if ((count > 0) && (stat == status_success)) {
+            stat = write_data_single(ptr, data_len_in_bytes, buff, count, timeout);
+        }
+    }
+    return stat;
+}
+
+hpm_stat_t hpm_spi_transmit_receive_setup_dma(SPI_Type *ptr, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    }
+    if ((size == 0) ||
+        ((SPI_SOC_TRANSFER_COUNT_MAX == 512) && (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes)))) {
+        return status_invalid_argument;
+    }
+    hpm_spi_transfer_init(ptr, spi_trans_write_read_together, size);
+    spi_enable_tx_dma(ptr);
+    spi_enable_rx_dma(ptr);
+    /* for master mode, This CMD register must be written with a dummy value
+     * to start a SPI transfer even when the command phase is not enabled
+     */
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        ptr->CMD = 0xFF;
+    }
+    return stat;
+}
+
+hpm_stat_t hpm_spi_receive_setup_dma(SPI_Type *ptr, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    }
+    if ((size == 0) ||
+        ((SPI_SOC_TRANSFER_COUNT_MAX == 512) && (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes)))) {
+        return status_invalid_argument;
+    }
+    hpm_spi_transfer_init(ptr, spi_trans_read_only, size);
+    spi_disable_tx_dma(ptr);
+    spi_enable_rx_dma(ptr);
+    /* for master mode, This CMD register must be written with a dummy value
+        to start a SPI transfer even when the command phase is not enabled
+    */
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        ptr->CMD = 0xFF;
+    }
+    return stat;
+}
+
+hpm_stat_t hpm_spi_transmit_setup_dma(SPI_Type *ptr, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    }
+    if ((size == 0) ||
+        ((SPI_SOC_TRANSFER_COUNT_MAX == 512) && (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes)))) {
+        return status_invalid_argument;
+    }
+    hpm_spi_transfer_init(ptr, spi_trans_write_only, size);
+    spi_enable_tx_dma(ptr);
+    spi_disable_rx_dma(ptr);
+    /* for master mode, This CMD register must be written with a dummy value
+     * to start a SPI transfer even when the command phase is not enabled
+     */
+    if (SPI_TRANSFMT_SLVMODE_GET(ptr->TRANSFMT) == spi_master_mode) {
+        ptr->CMD = 0xFF;
+    }
+    return stat;
+}
+
+#if USE_DMA_MGR
+void dma_channel_tc_callback(DMA_Type *ptr, uint32_t channel, void *user_data)
+{
+    hpm_spi_cfg_t *obj = (hpm_spi_cfg_t *)user_data;
+    if ((obj->rxdma_resource.channel == channel) &&
+        (obj->rxdma_resource.base == ptr) &&
+        (obj->rx_dma_complete != NULL)) {
+            obj->rx_dma_complete(channel);
+    }
+    if ((obj->txdma_resource.channel == channel) &&
+        (obj->txdma_resource.base == ptr) &&
+        (obj->tx_dma_complete != NULL)) {
+            obj->tx_dma_complete(channel);
+    }
+}
+
+hpm_stat_t hpm_spi_dma_install_callback(SPI_Type *ptr, spi_dma_complete_cb tx_complete, spi_dma_complete_cb rx_complete)
+{
+    dma_mgr_chn_conf_t chg_config;
+    dma_resource_t *resource = NULL;
+    hpm_spi_cfg_t *obj = hpm_spi_get_cfg_obj(ptr);
+    if (obj == NULL) {
+        return status_invalid_argument;
+    }
+    dma_mgr_get_default_chn_config(&chg_config);
+    chg_config.src_width = DMA_MGR_TRANSFER_WIDTH_BYTE;
+    chg_config.dst_width = DMA_MGR_TRANSFER_WIDTH_BYTE;
+    /* spi rx dma config */
+    resource = &obj->rxdma_resource;
+    if (dma_mgr_request_resource(resource) == status_success) {
+        chg_config.src_mode = DMA_MGR_HANDSHAKE_MODE_HANDSHAKE;
+        chg_config.src_addr_ctrl = DMA_MGR_ADDRESS_CONTROL_FIXED;
+        chg_config.src_addr = (uint32_t)&ptr->DATA;
+        chg_config.dst_mode = DMA_MGR_HANDSHAKE_MODE_NORMAL;
+        chg_config.dst_addr_ctrl = DMA_MGR_ADDRESS_CONTROL_INCREMENT;
+        chg_config.en_dmamux = true;
+        chg_config.dmamux_src = obj->rx_dmamux_src;
+        dma_mgr_setup_channel(resource, &chg_config);
+        dma_mgr_install_chn_tc_callback(resource, dma_channel_tc_callback, (void *)obj);
+        dma_mgr_enable_chn_irq(resource, DMA_MGR_INTERRUPT_MASK_TC);
+        dma_mgr_enable_dma_irq_with_priority(resource, 1);
+        obj->rx_dma_complete = rx_complete;
+    }
+     /* spi tx dma config */
+    resource = &obj->txdma_resource;
+    if (dma_mgr_request_resource(resource) == status_success) {
+        chg_config.src_mode = DMA_MGR_HANDSHAKE_MODE_NORMAL;
+        chg_config.src_addr_ctrl = DMA_MGR_ADDRESS_CONTROL_INCREMENT;
+        chg_config.dst_mode = DMA_MGR_HANDSHAKE_MODE_HANDSHAKE;
+        chg_config.dst_addr_ctrl = DMA_MGR_ADDRESS_CONTROL_FIXED;
+        chg_config.dst_addr = (uint32_t)&ptr->DATA;
+        chg_config.en_dmamux = true;
+        chg_config.dmamux_src = obj->tx_dmamux_src;
+        dma_mgr_setup_channel(resource, &chg_config);
+        dma_mgr_install_chn_tc_callback(resource, dma_channel_tc_callback, (void *)obj);
+        dma_mgr_enable_chn_irq(resource, DMA_MGR_INTERRUPT_MASK_TC);
+        dma_mgr_enable_dma_irq_with_priority(resource, 1);
+        obj->tx_dma_complete = tx_complete;
+    }
+    return status_success;
+}
+
+hpm_stat_t hpm_spi_transmit_receive_nonblocking(SPI_Type *ptr, uint8_t *wbuff, uint8_t *rbuff, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t transfer_width;
+    dma_resource_t *resource;
+    uint32_t buf_addr;
+    hpm_spi_cfg_t *obj = hpm_spi_get_cfg_obj(ptr);
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        /* word */
+        transfer_width = DMA_MGR_TRANSFER_WIDTH_WORD;
+        data_len_in_bytes = 4; /* must be 4 aglin */
+    } else {
+        /* byte or half_word*/
+        transfer_width = data_len_in_bytes - 1;
+    }
+    if ((obj == NULL) ||
+        (spi_master_get_data_phase_format(ptr) != spi_single_io_mode) ||
+        (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes))) {
+        return status_invalid_argument;
+    }
+    spi_disable_rx_dma(ptr);
+    spi_disable_tx_dma(ptr);
+    spi_transmit_fifo_reset(ptr);
+    spi_receive_fifo_reset(ptr);
+    resource = &obj->rxdma_resource;
+    buf_addr = core_local_mem_to_sys_address(HPM_CORE0, (uint32_t)rbuff);
+    dma_mgr_set_chn_dst_width(resource, transfer_width);
+    dma_mgr_set_chn_src_width(resource, transfer_width);
+    dma_mgr_set_chn_dst_addr(resource, buf_addr);
+    dma_mgr_set_chn_transize(resource, size / data_len_in_bytes);
+    dma_mgr_enable_channel(resource);
+    resource = &obj->txdma_resource;
+    buf_addr = core_local_mem_to_sys_address(HPM_CORE0, (uint32_t)wbuff);
+    dma_mgr_set_chn_dst_width(resource, transfer_width);
+    dma_mgr_set_chn_src_width(resource, transfer_width);
+    dma_mgr_set_chn_src_addr(resource, buf_addr);
+    dma_mgr_set_chn_transize(resource, size / data_len_in_bytes);
+    dma_mgr_enable_channel(resource);
+    stat = hpm_spi_transmit_receive_setup_dma(ptr, size);
+    return stat;
+}
+
+hpm_stat_t hpm_spi_receive_nonblocking(SPI_Type *ptr, uint8_t *buff, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t transfer_width;
+    dma_resource_t *resource;
+    uint32_t buf_addr;
+    hpm_spi_cfg_t *obj = hpm_spi_get_cfg_obj(ptr);
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+        /* word */
+        transfer_width = DMA_MGR_TRANSFER_WIDTH_WORD;
+    } else {
+        /* byte or half_word*/
+        transfer_width = data_len_in_bytes - 1;
+    }
+    if ((obj == NULL) ||
+        ((size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes)))) {
+        return status_invalid_argument;
+    }
+    spi_disable_rx_dma(ptr);
+    spi_disable_tx_dma(ptr);
+    spi_transmit_fifo_reset(ptr);
+    spi_receive_fifo_reset(ptr);
+    resource = &obj->rxdma_resource;
+    buf_addr = core_local_mem_to_sys_address(HPM_CORE0, (uint32_t)buff);
+    dma_mgr_set_chn_dst_width(resource, transfer_width);
+    dma_mgr_set_chn_src_width(resource, transfer_width);
+    dma_mgr_set_chn_dst_addr(resource, buf_addr);
+    dma_mgr_set_chn_transize(resource, size / data_len_in_bytes);
+    dma_mgr_enable_channel(resource);
+    stat = hpm_spi_receive_setup_dma(ptr, size);
+    return stat;
+}
+
+hpm_stat_t hpm_spi_transmit_nonblocking(SPI_Type *ptr, uint8_t *buff, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t transfer_width;
+    dma_resource_t *resource;
+    uint32_t buf_addr;
+    hpm_spi_cfg_t *obj = hpm_spi_get_cfg_obj(ptr);
+    uint8_t data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
+    if (data_len_in_bytes > 2) {
+        data_len_in_bytes = 4; /* must be 4 aglin */
+        /* word */
+        transfer_width = DMA_MGR_TRANSFER_WIDTH_WORD;
+    } else {
+        /* byte or half_word*/
+        transfer_width = data_len_in_bytes - 1;
+    }
+    if ((obj == NULL) ||
+        (size > (SPI_SOC_TRANSFER_COUNT_MAX * data_len_in_bytes))) {
+        return status_invalid_argument;
+    }
+    resource = &obj->txdma_resource;
+    buf_addr = core_local_mem_to_sys_address(HPM_CORE0, (uint32_t)buff);
+    spi_disable_rx_dma(ptr);
+    spi_disable_tx_dma(ptr);
+    spi_transmit_fifo_reset(ptr);
+    spi_receive_fifo_reset(ptr);
+    dma_mgr_set_chn_src_addr(resource, buf_addr);
+    dma_mgr_set_chn_dst_width(resource, transfer_width);
+    dma_mgr_set_chn_src_width(resource, transfer_width);
+    dma_mgr_set_chn_transize(resource, size / data_len_in_bytes);
+    dma_mgr_enable_channel(resource);
+    stat = hpm_spi_transmit_setup_dma(ptr, size);
+    return stat;
+}
+#endif

+ 181 - 0
bsp/hpmicro/libraries/hpm_sdk/components/spi/hpm_spi.h

@@ -23,6 +23,10 @@
 #define SPI_CS_ACTIVE 0
 #endif
 
+#ifndef USE_DMA_MGR
+#define USE_DMA_MGR      (0U)
+#endif
+
 /* Every transaction can be delineated by 3 dma descriptions: SPI control, SPI cmd, SPI data */
 #define SPI_DMA_DESC_COUNT_PER_TRANS    (3U)
 
@@ -58,6 +62,23 @@ typedef struct {
     dma_linked_descriptor_t *dma_linked_descriptor;
 } spi_context_t;
 
+/**
+ * @brief spi configuration init structure
+ */
+typedef struct {
+    spi_mode_selection_t mode;               /*!< the spi operating mode */
+    spi_data_phase_format_t io_mode;         /*!< the spi data line mode */
+    spi_sclk_idle_state_t clk_polarity;      /*!< CPOL */
+    spi_sclk_sampling_clk_edges_t clk_phase; /*!< CPHA */
+    spi_shift_direction_t direction;                /*!< MSB or LSB data shift direction */
+    uint8_t data_len;                        /*!< the unit is bit (1~32bit) */
+    bool data_merge;                         /*!< data Merge mode*/
+} spi_initialize_config_t;
+
+#if USE_DMA_MGR
+typedef void (*spi_dma_complete_cb)(uint32_t channel);
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -85,6 +106,166 @@ hpm_stat_t hpm_spi_setup_dma_transfer(spi_context_t *context, spi_control_config
  */
 hpm_stat_t hpm_spi_release_gpio_cs(spi_context_t *context);
 
+
+/**
+ * @brief spi get default init config
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *
+ * @param [out] config spi_init_config_t
+ */
+void hpm_spi_get_default_init_config(spi_initialize_config_t *config);
+
+/**
+ * @brief initialize for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] config spi_init_config_t struct
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_initialize(SPI_Type *ptr, spi_initialize_config_t *config);
+
+/**
+ * @brief set spi sclk frequency for spi master
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] freq spi sclk frequency
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_set_sclk_frequency(SPI_Type *ptr, uint32_t freq);
+
+/**
+ * @brief transmit and receive block for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] wbuff spi sent data buff address
+ * @param [out] rbuff spi receive data buff address
+ * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @param [in] timeout  wait time. unit is millisecond
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_transmit_receive_blocking(SPI_Type *ptr, uint8_t *wbuff, uint8_t *rbuff, uint32_t size, uint32_t timeout);
+
+/**
+ * @brief receive block for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *
+ * @param [in] ptr SPI base address
+ * @param [out] buff spi receive data buff address
+ * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @param [in] timeout  wait time. unit is millisecond
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_receive_blocking(SPI_Type *ptr, uint8_t *buff, uint32_t size, uint32_t timeout);
+
+/**
+ * @brief transmit block for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] buff spi sent data buff address
+ * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @param [in] timeout  wait time. unit is millisecond
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_transmit_blocking(SPI_Type *ptr, uint8_t *buff, uint32_t size, uint32_t timeout);
+
+/**
+ * @brief transmit and receive setup dma for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *       main configuration spi dma related, call this API after configuring DMA best
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] size spi sent and receive  data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_transmit_receive_setup_dma(SPI_Type *ptr, uint32_t size);
+
+/**
+ * @brief receive setup dma for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *       main configuration spi dma related, call this API after configuring DMA best
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] size spi receive data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_receive_setup_dma(SPI_Type *ptr, uint32_t size);
+
+/**
+ * @brief transmit setup dma for spi
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *       main configuration spi dma related, call this API after configuring DMA best
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] size spi transmit data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_transmit_setup_dma(SPI_Type *ptr, uint32_t size);
+
+#if USE_DMA_MGR
+/**
+ * @brief Install callback for SPI DMA channel transmit and receive complete
+ *
+ * @note it's no command/address/token phase, only data phase.
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] tx_complete callback for SPI TX DMA
+ * @param [in] rx_complete callback for SPI RX DMA
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_dma_install_callback(SPI_Type *ptr,
+                                        spi_dma_complete_cb tx_complete,
+                                        spi_dma_complete_cb rx_complete);
+
+/**
+ * @brief transmit and receive noblock for spi
+ *
+ * @note it's no command/address/token phase, only data phase. use dma
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] wbuff spi sent data buff address
+ * @param [out] rbuff spi receive data buff address
+ * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_transmit_receive_nonblocking(SPI_Type *ptr, uint8_t *wbuff, uint8_t *rbuff, uint32_t size);
+
+/**
+ * @brief receive noblock for spi
+ *
+ * @note it's no command/address/token phase, only data phase. use dma
+ *
+ * @param [in] ptr SPI base address
+ * @param [out] buff spi receive data buff address
+ * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_receive_nonblocking(SPI_Type *ptr, uint8_t *buff, uint32_t size);
+
+/**
+ * @brief transmit noblock for spi
+ *
+ * @note it's no command/address/token phase, only data phase. use dma
+ *
+ * @param [in] ptr SPI base address
+ * @param [in] buff spi sent data buff address
+ * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
+ * @retval hpm_stat_t status_success if spi in busy status
+ */
+hpm_stat_t hpm_spi_transmit_nonblocking(SPI_Type *ptr, uint8_t *buff, uint32_t size);
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 5 - 0
bsp/hpmicro/libraries/hpm_sdk/components/touch/ft5406/hpm_touch_ft5406.c

@@ -49,3 +49,8 @@ hpm_stat_t touch_init(I2C_Type *i2c_ptr)
 #endif
     return stat;
 }
+
+hpm_stat_t touch_config(bool exchange_xy, bool reverse_x, bool reverse_y)
+{
+    return status_fail;
+}

+ 144 - 0
bsp/hpmicro/libraries/hpm_sdk/components/touch/gt9xx/hpm_gt9xx.c

@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "hpm_gt9xx.h"
+static uint8_t g_i2c_addr;
+
+hpm_stat_t gt9xx_read_data(gt9xx_context_t *context, uint16_t addr, uint8_t *buf, uint32_t size)
+{
+    uint8_t r[2];
+    r[0] = addr >> 8;
+    r[1] = addr & 0xFF;
+    return i2c_master_address_read(context->ptr, g_i2c_addr, r, sizeof(r), buf, size);
+}
+
+hpm_stat_t gt9xx_write_data(gt9xx_context_t *context, uint16_t addr, uint8_t *buf, uint32_t size)
+{
+    uint8_t r[2];
+    r[0] = addr >> 8;
+    r[1] = addr & 0xFF;
+
+    return i2c_master_address_write(context->ptr, g_i2c_addr, r, sizeof(r), buf, size);
+}
+
+hpm_stat_t gt9xx_read_register(gt9xx_context_t *context, uint16_t reg, uint8_t *buf)
+{
+    return gt9xx_read_data(context, reg, buf, 1);
+}
+
+hpm_stat_t gt9xx_write_register(gt9xx_context_t *context, uint16_t reg, uint8_t val)
+{
+    return gt9xx_write_data(context, reg, &val, 1);
+}
+
+hpm_stat_t gt9xx_soft_reset(gt9xx_context_t *context)
+{
+    return gt9xx_write_register(context, GT9XX_CMD, 0);
+}
+
+static uint8_t gt9xx_calcualte_config_data_checksum(uint8_t *config)
+{
+    uint8_t checksum = 0;
+    for (uint32_t i = 0; i < GT9XX_CONFIG_DATA_SIZE - 2; i++) {
+        checksum += config[i];
+    }
+    return (~checksum + 1);
+}
+
+hpm_stat_t gt9xx_read_config(gt9xx_context_t *context, uint8_t *buf, uint8_t size)
+{
+    return gt9xx_read_data(context, GT9XX_CONFIG, buf, size);
+}
+
+hpm_stat_t gt9xx_init(gt9xx_context_t *context, uint16_t width, uint16_t height)
+{
+    hpm_stat_t stat = status_success;
+    uint8_t config[GT9XX_CONFIG_DATA_SIZE] = {0};
+
+#ifdef GT9XX_I2C_ADDR
+    g_i2c_addr = GT9XX_I2C_ADDR;
+    stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
+    if (stat != status_success) {
+        return stat;
+    }
+#elif !GT9XX_NO_AUTO_PROBE
+    g_i2c_addr = GT9XX_I2C_ADDR0;
+    stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
+    if (stat != status_success) {
+        printf("0x%x failed to init GT9XX", g_i2c_addr);
+        g_i2c_addr = GT9XX_I2C_ADDR1;
+        printf(", try 0x%x\n", g_i2c_addr);
+        stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
+    }
+    if (stat != status_success) {
+        return stat;
+    }
+#else
+    g_i2c_addr = GT9XX_I2C_ADDR0;
+    stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
+    if (stat != status_success) {
+        return stat;
+    }
+#endif
+
+    if (config[GT9XX_CONFIG_DATA_SIZE - 2] != gt9xx_calcualte_config_data_checksum(config)) {
+        return status_fail;
+    }
+
+    /* < 90: fixed config; >=90 custom config */
+    if (config[GT9XX_CONFIG_DATA_CONFIG_VERSION] < 90) {
+        printf("ERR: GTXXX custom config can't be supported\n");
+        return status_fail;
+    } else {
+        context->abs_x_max = config[GT9XX_CONFIG_DATA_RESOLUTION_XH];
+        context->abs_x_max <<= 8;
+        context->abs_x_max |= config[GT9XX_CONFIG_DATA_RESOLUTION_XL];
+
+        context->abs_y_max = config[GT9XX_CONFIG_DATA_RESOLUTION_YH];
+        context->abs_y_max <<= 8;
+        context->abs_y_max |= config[GT9XX_CONFIG_DATA_RESOLUTION_YL];
+    }
+    /* stat = gt9xx_read_data(context, GT9XX_ID_B0, (uint8_t*)&val, sizeof(val)); */
+    /* if (stat != status_success) { */
+        /* return stat; */
+    /* } */
+
+    /* if (val != GT9XX_PRODUCT_ID) { */
+        /* return status_fail; */
+    /* } */
+
+    config[GT9XX_CONFIG_DATA_RESOLUTION_XL] = width & 0xFF;
+    config[GT9XX_CONFIG_DATA_RESOLUTION_XH] = width >> 8;
+    config[GT9XX_CONFIG_DATA_RESOLUTION_YL] = height & 0xFF;
+    config[GT9XX_CONFIG_DATA_RESOLUTION_YH] = height >> 8;
+    config[GT9XX_CONFIG_DATA_TOUCH_NUMBER] = 5;
+    config[GT9XX_CONFIG_DATA_MODULE_SWITCH1] = (config[GT9XX_CONFIG_DATA_MODULE_SWITCH1] & ~0x3);
+
+    config[GT9XX_CONFIG_DATA_SIZE - 2] = gt9xx_calcualte_config_data_checksum(config);
+    config[GT9XX_CONFIG_DATA_SIZE - 1] = 1;
+    /*
+     * for (uint8_t i = 0; i < 5; i++) {
+     *     gt9xx_write_data(context, GT9XX_CONFIG, config, GT9XX_CONFIG_DATA_SIZE);
+     * }
+     */
+    gt9xx_write_register(context, GT9XX_CMD, GT9XX_CMD_SOFT_RESET);
+    return status_success;
+}
+
+hpm_stat_t gt9xx_read_touch_data(gt9xx_context_t *context,
+                                  gt9xx_touch_data_t *touch_data)
+{
+    hpm_stat_t stat = status_success;
+
+    stat = gt9xx_read_data(context, GT9XX_STATUS,
+            (uint8_t *)touch_data, sizeof(gt9xx_touch_data_t));
+    if (stat != status_success) {
+        return stat;
+    }
+
+    return stat;
+}

+ 136 - 0
bsp/hpmicro/libraries/hpm_sdk/components/touch/gt9xx/hpm_gt9xx.h

@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_GT9XX_H
+#define HPM_GT9XX_H
+#include "board.h"
+#include "hpm_common.h"
+#include "hpm_i2c_drv.h"
+
+#ifdef BOARD_GT9XX_ADDR
+/* if i2c addres is specified by board, use it */
+#define GT9XX_I2C_ADDR BOARD_GT9XX_ADDR
+/* no auto probe in this case */
+#define GT9XX_NO_AUTO_PROBE 1
+#else
+#undef GT9XX_I2C_ADDR
+
+/* enable auto probe */
+#ifndef GT9XX_NO_AUTO_PROBE
+#define GT9XX_NO_AUTO_PROBE 0
+#endif
+
+/* i2c device address candidates */
+#define GT9XX_I2C_ADDR0 (0x14U)
+#define GT9XX_I2C_ADDR1 (0x5DU)
+#endif
+
+#define GT9XX_PRODUCT_ID (0x313139U)
+/*
+ * GT9XX registers at operation mode
+ */
+
+#define GT9XX_CMD                    (0x8040U)
+#define   GT9XX_CMD_READ_COORD_STAT  (0U)
+#define   GT9XX_CMD_READ_RAW_DATA    (1U)
+#define   GT9XX_CMD_SOFT_RESET       (2U)
+#define   GT9XX_CMD_READ_SCREEN_OFF  (5U)
+
+#define GT9XX_CONFIG                    (0x8047U)
+
+#define GT9XX_ID_B0                     (0x8140U)
+#define GT9XX_ID_B1                     (0x8141U)
+#define GT9XX_ID_B2                     (0x8142U)
+#define GT9XX_ID_B4                     (0x8143U)
+#define GT9XX_FW_VERSION_L              (0x8144U)
+#define GT9XX_FW_VERSION_H              (0x8145U)
+#define GT9XX_TOUCH_XL                  (0x8146U)
+#define GT9XX_TOUCH_XH                  (0x8147U)
+#define GT9XX_TOUCH_YL                  (0x8148U)
+#define GT9XX_TOUCH_YH                  (0x8149U)
+#define GT9XX_VENDOR_ID                 (0x814AU)
+#define GT9XX_STATUS                    (0x814EU)
+#define GT9XX_GET_STATUS_NUM_OF_POINTS(x)  ((x) & 0xFU)
+#define GT9XX_GET_STATUS_LARGE_DETECT(x)   (((x) & 0x40U) >> 6)
+#define GT9XX_GET_STATUS_BUFFER_STAT(x)    (((x) & 0x80U) >> 7)
+#define GT9XX_FIRST_POINT               (0x814FU)
+
+#define GT9XX_MAX_TOUCH_POINTS             (5U)
+#define GT9XX_CONFIG_DATA_SIZE             (186U)
+#define GT9XX_CONFIG_DATA_CONFIG_VERSION   (0U)
+#define GT9XX_CONFIG_DATA_RESOLUTION_XL    (1U)
+#define GT9XX_CONFIG_DATA_RESOLUTION_XH    (2U)
+#define GT9XX_CONFIG_DATA_RESOLUTION_YL    (3U)
+#define GT9XX_CONFIG_DATA_RESOLUTION_YH    (4U)
+#define GT9XX_CONFIG_DATA_TOUCH_NUMBER     (5U)
+#define GT9XX_CONFIG_DATA_MODULE_SWITCH1   (6U)
+
+typedef struct {
+    uint8_t track_id;
+    uint8_t x_l;
+    uint8_t x_h;
+    uint8_t y_l;
+    uint8_t y_h;
+    uint8_t size_l;
+    uint8_t size_h;
+    uint8_t reserved;
+} gt9xx_touch_point_t;
+
+typedef struct {
+    uint8_t status;
+    gt9xx_touch_point_t points[GT9XX_MAX_TOUCH_POINTS];
+} gt9xx_touch_data_t;
+
+typedef struct {
+    I2C_Type *ptr;
+    uint16_t abs_x_max;
+    uint16_t abs_y_max;
+    bool exchange_xy;
+    bool reverse_x;
+    bool reverse_y;
+} gt9xx_context_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * gt9xx initialization routine
+ */
+hpm_stat_t gt9xx_init(gt9xx_context_t *context, uint16_t width, uint16_t height);
+
+/*
+ * gt9xx read touch data
+ */
+hpm_stat_t gt9xx_read_touch_data(gt9xx_context_t *context,
+                                  gt9xx_touch_data_t *touch_data);
+
+/*
+ * gt9xx read data
+ */
+hpm_stat_t gt9xx_read_data(gt9xx_context_t *context, uint16_t addr,
+                            uint8_t *buf, uint32_t size);
+
+/*
+ * gt9xx write value to given register
+ */
+hpm_stat_t gt9xx_write_register(gt9xx_context_t *context,
+                                 uint16_t reg, uint8_t val);
+
+/*
+ * gt9xx read value of given register
+ */
+hpm_stat_t gt9xx_read_register(gt9xx_context_t *context, uint16_t reg, uint8_t *buf);
+
+/*
+ * gt9xx read config data
+ */
+hpm_stat_t gt9xx_read_config(gt9xx_context_t *context, uint8_t *buf, uint8_t size);
+#ifdef __cplusplus
+}
+#endif
+#endif /* HPM_GT9XX_H */

+ 93 - 0
bsp/hpmicro/libraries/hpm_sdk/components/touch/gt9xx/hpm_touch_gt9xx.c

@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "board.h"
+#include "hpm_touch.h"
+#include "hpm_gpio_drv.h"
+#include "hpm_gt9xx.h"
+#include "hpm_touch.h"
+
+gt9xx_context_t gt9xx = {0};
+
+hpm_stat_t touch_get_data(touch_point_t *points, uint8_t *num_of_points)
+{
+    hpm_stat_t stat = status_success;
+    gt9xx_touch_data_t touch_data = {0};
+    uint8_t num, i;
+    uint16_t tmp;
+
+    stat = gt9xx_read_touch_data(&gt9xx, &touch_data);
+    if (stat != status_success) {
+        printf("gt9xx read data failed\n");
+        return stat;
+    }
+    /* the buffer status is ready*/
+    if (GT9XX_GET_STATUS_BUFFER_STAT(touch_data.status) == 1) {
+        num = GT9XX_GET_STATUS_NUM_OF_POINTS(touch_data.status);
+        *num_of_points = num;
+        if (num > 0 && num <= GT9XX_MAX_TOUCH_POINTS) {
+            for (i = 0; i < num; i++) {
+                points[i].x = (touch_data.points[i].x_h & 0xF) << 8 | touch_data.points[i].x_l;
+                points[i].y = (touch_data.points[i].y_h & 0xF) << 8 | touch_data.points[i].y_l;
+
+                if (gt9xx.reverse_x)
+                    points[i].x = gt9xx.abs_x_max - points[i].x;
+
+                if (gt9xx.reverse_y)
+                    points[i].y = gt9xx.abs_y_max - points[i].y;
+
+                if (gt9xx.exchange_xy) {
+                    tmp = points[i].x;
+                    points[i].x = points[i].y;
+                    points[i].y = tmp;
+                }
+            }
+        } else {
+            stat = status_touch_points_over_number;
+        }
+        gt9xx_write_register(&gt9xx, GT9XX_STATUS, 0);
+    } else {
+        stat = status_touch_buffer_no_ready;
+    }
+
+    return stat;
+}
+
+void pull_int_pin(bool high)
+{
+    gpio_set_pin_output(BOARD_CAP_INTR_GPIO, BOARD_CAP_INTR_GPIO_INDEX, BOARD_CAP_INTR_GPIO_PIN);
+    gpio_write_pin(BOARD_CAP_INTR_GPIO, BOARD_CAP_INTR_GPIO_INDEX, BOARD_CAP_INTR_GPIO_PIN, high);
+}
+
+void float_int_pin(void)
+{
+    gpio_set_pin_input(BOARD_CAP_INTR_GPIO, BOARD_CAP_INTR_GPIO_INDEX, BOARD_CAP_INTR_GPIO_PIN);
+}
+
+hpm_stat_t touch_init(I2C_Type *i2c_ptr)
+{
+    hpm_stat_t stat = status_success;
+
+    gt9xx.ptr = i2c_ptr;
+
+    stat = gt9xx_init(&gt9xx, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT);
+    if (stat != status_success) {
+        return stat;
+    }
+    gt9xx_write_register(&gt9xx, GT9XX_CMD, GT9XX_CMD_READ_COORD_STAT);
+
+    return stat;
+}
+
+hpm_stat_t touch_config(bool exchange_xy, bool reverse_x, bool reverse_y)
+{
+    gt9xx.exchange_xy = exchange_xy;
+    gt9xx.reverse_x = reverse_x;
+    gt9xx.reverse_y = reverse_y;
+
+    return status_success;
+}

+ 5 - 5
bsp/hpmicro/libraries/hpm_sdk/components/touch/hpm_touch.h

@@ -13,11 +13,11 @@
 #if defined(CONFIG_TOUCH_FT5406) && (CONFIG_TOUCH_FT5406 == 1)
 #include "hpm_ft5406.h"
 #define HPM_TOUCH_MAX_POINTS (FT5406_MAX_TOUCH_POINTS)
-#elif defined(CONFIG_TOUCH_GT911) && (CONFIG_TOUCH_GT911 == 1)
-#include "hpm_gt911.h"
-#define HPM_TOUCH_MAX_POINTS (GT911_MAX_TOUCH_POINTS)
+#elif defined(CONFIG_TOUCH_GT9XX) && (CONFIG_TOUCH_GT9XX == 1)
+#include "hpm_gt9xx.h"
+#define HPM_TOUCH_MAX_POINTS (GT9XX_MAX_TOUCH_POINTS)
 #else
-#error "unknown touch type, either have CONFIG_FT5406 or CONFIG_GT911 defined"
+#error "unknown touch type, either have CONFIG_FT5406 or CONFIG_GT9XX defined"
 #endif
 
 enum {
@@ -35,7 +35,7 @@ extern "C" {
 #endif
 
 hpm_stat_t touch_init(I2C_Type *i2c_ptr);
-
+hpm_stat_t touch_config(bool exchange_xy, bool reverse_x, bool reverse_y);
 hpm_stat_t touch_get_data(touch_point_t *points, uint8_t *num_of_points);
 
 #ifdef __cplusplus

+ 4 - 4
bsp/hpmicro/libraries/hpm_sdk/components/usb/device/hpm_usb_device.c

@@ -207,8 +207,11 @@ bool usb_device_edpt_open(usb_device_handle_t *handle, usb_endpoint_config_t *co
     memset(p_qhd, 0, sizeof(dcd_qhd_t));
 
     p_qhd->zero_length_termination = 1;
-    p_qhd->max_packet_size         = config->max_packet_size;
+    p_qhd->max_packet_size         = config->max_packet_size & 0x7FFu;
     p_qhd->qtd_overlay.next        = USB_SOC_DCD_QTD_NEXT_INVALID;
+    if (config->xfer == usb_xfer_isochronous) {
+        p_qhd->iso_mult = ((config->max_packet_size >> 11u) & 0x3u) + 1u;
+    }
 
     usb_dcd_edpt_open(handle->regs, config);
 
@@ -274,9 +277,6 @@ bool usb_device_edpt_xfer(usb_device_handle_t *handle, uint8_t ep_addr, uint8_t
 
     p_qhd->qtd_overlay.next = core_local_mem_to_sys_address(0, (uint32_t) first_p_qtd); /* link qtd to qhd */
 
-    if (usb_dcd_edpt_get_type(handle->regs, ep_addr) == usb_xfer_isochronous) {
-        p_qhd->iso_mult = 1;
-    }
     usb_dcd_edpt_xfer(handle->regs, ep_idx);
 
     return true;

+ 30 - 4
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_adc16_drv.h

@@ -118,7 +118,6 @@ typedef struct {
     uint8_t res;
     uint8_t conv_mode;
     uint32_t adc_clk_div;
-    uint16_t conv_duration;
     bool port3_realtime;
     bool wait_dis;
     bool sel_sync_ahb;
@@ -344,8 +343,8 @@ hpm_stat_t adc16_set_pmt_config(ADC16_Type *ptr, adc16_pmt_config_t *config);
  *
  * @param[in] ptr An ADC16 peripheral base address.
  * @param[in] trig_ch An ADC16 peripheral trigger channel.
- * @param[in] enable A enable control
- * @return A result of setting queue enable in preemption
+ * @param[in] enable Set true to enable and false to disable.
+ * @return A result of setting queue enable in preemption.
  * @retval status_success Get the result of an ADC16 conversion in oneshot mode successfully.
  * @retval status_invalid_argument Get the result of an ADC16 conversion in oneshot mode unsuccessfully due to passing invalid arguments.
  */
@@ -353,6 +352,32 @@ hpm_stat_t adc16_set_pmt_queue_enable(ADC16_Type *ptr, uint8_t trig_ch, bool ena
 
 /** @} */
 
+/**
+ * @name Enablement Control
+ * @{
+ */
+/**
+ * @brief Enable the hw trigger control for the sequence mode.
+ *
+ * @param[in] ptr An ADC16 peripheral base address.
+ *
+ */
+static inline void adc16_seq_enable_hw_trigger(ADC16_Type *ptr)
+{
+    ptr->SEQ_CFG0 |= ADC16_SEQ_CFG0_HW_TRIG_EN_MASK;
+}
+/**
+ * @brief Disable the hw trigger control for the sequence mode.
+ *
+ * @param[in] ptr An ADC16 peripheral base address.
+ *
+ */
+static inline void adc16_seq_disable_hw_trigger(ADC16_Type *ptr)
+{
+    ptr->SEQ_CFG0 &= ~ADC16_SEQ_CFG0_HW_TRIG_EN_MASK;
+}
+/** @} */
+
 /**
  * @name DMA Control
  * @{
@@ -556,7 +581,6 @@ hpm_stat_t adc16_trigger_seq_by_sw(ADC16_Type *ptr);
  */
 hpm_stat_t adc16_trigger_pmt_by_sw(ADC16_Type *ptr, uint8_t trig_ch);
 
-
 /**
  * @brief Get the result in oneshot mode.
  *
@@ -602,10 +626,12 @@ void adc16_disable_temp_sensor(ADC16_Type *ptr);
  *
  * @param[in] ptr An ADC16 peripheral base address.
  */
+#if defined(HPM_IP_FEATURE_ADC16_HAS_MOT_EN) && HPM_IP_FEATURE_ADC16_HAS_MOT_EN
 static inline void adc16_enable_motor(ADC16_Type *ptr)
 {
     ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_MOTO_EN_MASK;
 }
+#endif
 
 /** @} */
 

+ 3 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_cam_drv.h

@@ -11,6 +11,7 @@
 #include "hpm_common.h"
 #include "hpm_display_common.h"
 #include "hpm_cam_regs.h"
+#include "hpm_soc_feature.h"
 
 /**
  * @brief CAM driver APIs
@@ -80,7 +81,9 @@ typedef struct {
     uint32_t width;
     uint32_t height;
     bool pixclk_sampling_falling;
+#if defined(HPM_IP_FEATURE_CAM_INV_DEN) && (HPM_IP_FEATURE_CAM_INV_DEN == 1)
     bool de_active_low; /* de_active_low must is same with hsync_active_low when dvp be used */
+#endif
     bool hsync_active_low;
     bool vsync_active_low;
     bool color_ext;

+ 26 - 18
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_can_drv.h

@@ -39,6 +39,7 @@ enum {
     status_can_tx_fifo_full = MAKE_STATUS(status_group_can, 6),         /**< CAN TX fifo full */
     status_can_filter_index_invalid = MAKE_STATUS(status_group_can, 7), /**< CAN filter index is invalid */
     status_can_filter_num_invalid = MAKE_STATUS(status_group_can, 8),   /**< CAN filter number is invalid */
+    status_can_invalid_bit_timing = MAKE_STATUS(status_group_can, 9),   /**< Invalid CAN bit timing parameter */
 };
 
 /**
@@ -56,10 +57,10 @@ enum {
 /**
  * @brief CAN Secondary Transmit buffer Status
  */
-#define CAN_STB_IS_EMPTY (0U)                               /**< CAN Sencondary Transmit buffer is empty */
-#define CAN_STB_LESS_EQUAL_HALF_FULL (1U)                   /**< CAN Sencondary Transmit buffer <= 1/2 * FULL */
-#define CAN_STB_MORE_THAN_HALF_FULL (2U)                    /**< CAN Sencondary Transmit buffer > 1/2 * FULL */
-#define CAN_STB_IS_FULL (3U)                                /**< CAN Sencondary Transmit buffer is full */
+#define CAN_STB_IS_EMPTY (0U)                               /**< CAN Secondary Transmit buffer is empty */
+#define CAN_STB_LESS_EQUAL_HALF_FULL (1U)                   /**< CAN Secondary Transmit buffer <= 1/2 * FULL */
+#define CAN_STB_MORE_THAN_HALF_FULL (2U)                    /**< CAN Secondary Transmit buffer > 1/2 * FULL */
+#define CAN_STB_IS_FULL (3U)                                /**< CAN Secondary Transmit buffer is full */
 
 /**
  * @brief CAN Receive Buffer States
@@ -73,14 +74,14 @@ enum {
  * @brief CAN Error interrupts/flags
  *
  */
-#define CAN_ERROR_WARNING_LIMIT_FLAG            (CAN_ERRINT_EWARN_MASK)     /**< CAN Error Limit reached */
-#define CAN_ERROR_PASSIVE_MODE_ACTIVE_FLAG      (CAN_ERRINT_EPASS_MASK)     /**< CAN Passive mode active */
-#define CAN_ERROR_PASSIVE_INT_ENABLE            (CAN_ERRINT_EPIE_MASK)      /**< CAN Passive Interrupt Enable */
-#define CAN_ERROR_PASSIVE_INT_FLAG              (CAN_ERRINT_EPIF_MASK)      /**< CAN Passive Interrupt Flag */
-#define CAN_ERROR_ARBITRAITION_LOST_INT_ENABLE  (CAN_ERRINT_ALIE_MASK)      /**< CAN Abitration Lost Interrupt Enable */
-#define CAN_ERROR_ARBITRAITION_LOST_INT_FLAG    (CAN_ERRINT_ALIE_MASK)      /**< CAN arbitration Lost Interrupt Flag */
-#define CAN_ERROR_BUS_ERROR_INT_ENABLE          (CAN_ERRINT_BEIE_MASK)      /**< CAN BUS error Interrupt Enable */
-#define CAN_ERROR_BUS_ERROR_INT_FLAG            (CAN_ERRINT_BEIF_MASK)      /**< CAN BUS error Interrupt flag */
+#define CAN_ERROR_WARNING_LIMIT_FLAG           (CAN_ERRINT_EWARN_MASK)     /**< CAN Error Limit reached */
+#define CAN_ERROR_PASSIVE_MODE_ACTIVE_FLAG     (CAN_ERRINT_EPASS_MASK)     /**< CAN Passive mode active */
+#define CAN_ERROR_PASSIVE_INT_ENABLE           (CAN_ERRINT_EPIE_MASK)      /**< CAN Passive Interrupt Enable */
+#define CAN_ERROR_PASSIVE_INT_FLAG             (CAN_ERRINT_EPIF_MASK)      /**< CAN Passive Interrupt Flag */
+#define CAN_ERROR_ARBITRATION_LOST_INT_ENABLE  (CAN_ERRINT_ALIE_MASK)      /**< CAN Arbitration Lost Interrupt Enable */
+#define CAN_ERROR_ARBITRATION_LOST_INT_FLAG    (CAN_ERRINT_ALIE_MASK)      /**< CAN arbitration Lost Interrupt Flag */
+#define CAN_ERROR_BUS_ERROR_INT_ENABLE         (CAN_ERRINT_BEIE_MASK)      /**< CAN BUS error Interrupt Enable */
+#define CAN_ERROR_BUS_ERROR_INT_FLAG           (CAN_ERRINT_BEIF_MASK)      /**< CAN BUS error Interrupt flag */
 
 /**
  * @brief CAN Error Kinds
@@ -110,7 +111,7 @@ typedef enum _can_mode {
  */
 typedef enum _can_bit_timing_option {
     can_bit_timing_can2_0,          /**< CAN 2.0 bit timing option */
-    can_bit_timing_canfd_norminal,  /**< CANFD norminal timing option */
+    can_bit_timing_canfd_nominal,  /**< CANFD nominal timing option */
     can_bit_timing_canfd_data,      /**< CANFD data timing option */
 } can_bit_timing_option_t;
 
@@ -245,7 +246,7 @@ typedef struct {
     bool enable_self_ack;                       /**< CAN self-ack flag */
     bool disable_ptb_retransmission;            /**< disable re-transmission for primary transmit buffer */
     bool disable_stb_retransmission;            /**< disable re-transmission for secondary transmit buffer */
-    bool enable_tdc;                            /**< Enable transmittor delay compensation */
+    bool enable_tdc;                            /**< Enable transmitter delay compensation */
 
     uint8_t filter_list_num;                    /**< element number of CAN filters in filter list */
     can_filter_config_t *filter_list;           /**< CAN filter list pointer */
@@ -279,6 +280,15 @@ static inline void can_reset(CAN_Type *base, bool enable)
     }
 }
 
+/**
+ * @brief Force CAN controller to Bus-off mode
+ * @param [in] base CAN base address
+ */
+static inline void can_force_bus_off(CAN_Type *base)
+{
+    base->CMD_STA_CMD_CTRL = CAN_CMD_STA_CMD_CTRL_BUSOFF_MASK;
+}
+
 /**
  * @brief Set CAN mode
  *
@@ -811,10 +821,8 @@ hpm_stat_t can_get_default_config(can_config_t *config);
  */
 hpm_stat_t can_init(CAN_Type *base, can_config_t *config, uint32_t src_clk_freq);
 
-
 /**
  * @brief De-initialize the CAN controller
- *
  * @param [in] base CAN base address
  */
 void can_deinit(CAN_Type *base);
@@ -920,7 +928,7 @@ hpm_stat_t can_send_high_priority_message_nonblocking(CAN_Type *base, const can_
  * @param [in] base CAN base address
  * @param [out] message CAN message buffer
  *
- * @retval status_success API exection is successful
+ * @retval status_success API execution is successful
  * @retval status_invalid_argument Invalid parameters
  * @retval status_can_bit_error CAN bit error happened during receiving message
  * @retval status_can_form_error  CAN form error happened during receiving message
@@ -940,7 +948,7 @@ hpm_stat_t can_receive_message_blocking(CAN_Type *base, can_receive_buf_t *messa
  * @param [in] base CAN base address
  * @param [out] message CAN message buffer
  *
- * @retval status_success API exection is successful
+ * @retval status_success API execution is successful
  * @retval status_invalid_argument Invalid parameters
  * @retval status_can_bit_error CAN bit error happened during receiving message
  * @retval status_can_form_error  CAN form error happened during receiving message

+ 435 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_clc_drv.h

@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_CLC_DRV_H
+#define HPM_CLC_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_clc_regs.h"
+
+/**
+ * @brief CLC driver APIs
+ * @defgroup clc_interface CLC driver APIs
+ * @ingroup motor_interfaces
+ * @{
+ */
+
+/**
+ * @brief clc channel
+ */
+typedef enum {
+    clc_vd_chn = CLC_VDVQ_CHAN_VD,
+    clc_vq_chn = CLC_VDVQ_CHAN_VQ,
+} clc_chn_t; /**< clc_chn_t */
+
+/**
+ * @brief clc coefficient zone
+ */
+typedef enum {
+    clc_coeff_zone_0 = CLC_COEFF_0,
+    clc_coeff_zone_1 = CLC_COEFF_1,
+    clc_coeff_zone_2 = CLC_COEFF_2,
+} clc_coeff_zone_t; /**< clc_coeff_zone_t */
+
+/**
+ * @brief clc irq mask bit
+ */
+typedef enum {
+    clc_irq_calc_done = BIT0_MASK,
+    clc_irq_eadc_setting_err = BIT1_MASK,
+    clc_irq_2p2z_clamp_setting_err = BIT2_MASK,
+    clc_irq_2p2z_over_hi = BIT3_MASK,
+    clc_irq_2p2z_over_lo = BIT4_MASK,
+    clc_irq_2p2z_over_sf = BIT5_MASK,
+    clc_irq_3p3z_clamp_setting_err = BIT6_MASK,
+    clc_irq_3p3z_over_hi = BIT7_MASK,
+    clc_irq_3p3z_over_lo = BIT8_MASK,
+    clc_irq_forb_setting_err = BIT9_MASK,
+    clc_irq_data_in_forbid = BIT10_MASK
+} clc_irq_mask_t;
+
+/**
+ * @brief clc parameter configuration
+ */
+typedef struct {
+    int32_t eadc_lowth;
+    int32_t eadc_mid_lowth;
+    int32_t eadc_mid_highth;
+    int32_t eadc_highth;
+    int32_t _2p2z_clamp_lowth;
+    int32_t _2p2z_clamp_highth;
+    int32_t _3p3z_clamp_lowth;
+    int32_t _3p3z_clamp_highth;
+    int32_t output_forbid_lowth;
+    int32_t output_forbid_mid;
+    int32_t output_forbid_highth;
+} clc_param_config_t;   /**< clc_param_config_t */
+
+/**
+ * @brief clc coefficient configuration
+ */
+typedef struct {
+    float b0;
+    float b1;
+    float b2;
+    float b3;
+    float a0;
+    float a1;
+    float a2;
+} clc_coeff_config_t;   /**< clc_coeff_config_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief CLC enable or disable
+ *
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] enable true-enable, false-disable
+ */
+static inline void clc_set_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
+{
+    if (enable) {
+        clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_ENABLE_CLC_MASK;
+    } else {
+        clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_ENABLE_CLC_MASK;
+    }
+}
+
+/**
+ * @brief CLC keep working even if bad irq status ocurred
+ *
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] enable true-enable, false-disable
+ */
+static inline void clc_set_mask_mode_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
+{
+    if (enable) {
+        clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_MASK_MODE_MASK;
+    } else {
+        clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_MASK_MODE_MASK;
+    }
+}
+
+/**
+ * @brief CLC set software inject dq work mode
+ *
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] enable true-if the ADC value comes from software injection and the VD/VQ channel is required for joint use.
+ */
+static inline void clc_set_sw_inject_dq_mode_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
+{
+    if (enable) {
+        clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_DQ_MODE_MASK;
+    } else {
+        clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_DQ_MODE_MASK;
+    }
+}
+
+/**
+ * @brief CLC set irq enable or disable
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
+ * @param[in] enable enable or disable
+ *  @arg true enable
+ *  @arg false disable
+ */
+static inline void clc_set_irq_enable(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask, bool enable)
+{
+    if (enable) {
+        clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_ENABLE_IRQ_SET(irq_mask);
+    } else {
+        clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_ENABLE_IRQ_SET(irq_mask);
+    }
+}
+
+/**
+ * @brief CLC get irq status
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+
+ * @retval irq status.
+ */
+static inline uint32_t clc_get_irq_status(CLC_Type *clc, clc_chn_t chn)
+{
+    return CLC_VDVQ_CHAN_STATUS_STATUS_GET(clc->VDVQ_CHAN[chn].STATUS);
+}
+
+/**
+ * @brief CLC clear irq status
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
+ */
+static inline void clc_clear_irq_status(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask)
+{
+    clc->VDVQ_CHAN[chn].STATUS = CLC_VDVQ_CHAN_STATUS_STATUS_SET(irq_mask);
+}
+
+/**
+ * @brief CLC check irq request flag
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
+
+ * @retval true-has irq req, false-no irq req.
+ */
+static inline bool clc_get_irq_flag(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask)
+{
+    return ((clc->VDVQ_CHAN[chn].STATUS & irq_mask) == irq_mask) ? true : false;
+}
+
+/**
+ * @brief CLC set adc channel
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] adc_chn adc channel for ADC0~3 or SDM_ADC0~7, adc from VSC must be set to 0.
+ * @param[in] adc_offset adc offset for ADC0~3 or SDM_ADC0~7, adc from VSC must be set to 0.
+ */
+static inline void clc_set_adc_chn_offset(CLC_Type *clc, clc_chn_t chn, uint32_t adc_chn, uint32_t adc_offset)
+{
+    clc->VDVQ_CHAN[chn].ADC_CHAN = adc_chn;
+    clc->VDVQ_CHAN[chn].ADC_OFFSET = adc_offset;
+}
+
+/**
+ * @brief CLC set pwm period
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] pwm_period 0-clc dac output pwm duty ratio, else-clc dac output pwm period, number of clock cycles.
+ */
+static inline void clc_set_pwm_period(CLC_Type *clc, clc_chn_t chn, uint32_t pwm_period)
+{
+    clc->VDVQ_CHAN[chn].PWM_PERIOD = pwm_period;
+}
+
+/**
+ * @brief CLC set pwm period
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval pwm period
+ */
+static inline uint32_t clc_get_pwm_period(CLC_Type *clc, clc_chn_t chn)
+{
+    return clc->VDVQ_CHAN[chn].PWM_PERIOD;
+}
+
+/**
+ * @brief CLC get output caculated value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC output caculated value
+ */
+static inline uint32_t clc_get_output_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return clc->VDVQ_CHAN[chn].OUTPUT_VALUE;
+}
+
+/**
+ * @brief CLC get timestamp
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC adc timestamp
+ */
+static inline uint32_t clc_get_timestamp(CLC_Type *clc, clc_chn_t chn)
+{
+    return clc->VDVQ_CHAN[chn].TIMESTAMP;
+}
+
+/**
+ * @brief CLC get error adc latest value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC error adc latest value
+ */
+static inline int32_t clc_get_eadc_current_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return (int32_t)clc->VDVQ_CHAN[chn].EADC_CURR;
+}
+
+/**
+ * @brief CLC get error adc previous0 value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC error adc previous0 value
+ */
+static inline int32_t clc_get_eadc_previous0_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return (int32_t)clc->VDVQ_CHAN[chn].EADC_PRE0;
+}
+
+/**
+ * @brief CLC software inject error adc previous0 value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] value CLC error adc previous0 value
+ */
+static inline void clc_sw_inject_eadc_previous0_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
+{
+    clc->VDVQ_CHAN[chn].EADC_PRE0 = (uint32_t)value;
+}
+
+/**
+ * @brief CLC get error adc previous1 value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC error adc previous1 value
+ */
+static inline int32_t clc_get_eadc_previous1_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return (int32_t)clc->VDVQ_CHAN[chn].EADC_PRE1;
+}
+
+/**
+ * @brief CLC software inject error adc previous1 value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] value CLC error adc previous1 value
+ */
+static inline void clc_sw_inject_eadc_previous1_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
+{
+    clc->VDVQ_CHAN[chn].EADC_PRE1 = (uint32_t)value;
+}
+
+/**
+ * @brief CLC get 2p2z last value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC 2p2z last value
+ */
+static inline int32_t clc_get_2p2z_current_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return (int32_t)clc->VDVQ_CHAN[chn].P2Z2_CURR;
+}
+
+/**
+ * @brief CLC software inject 2p2z last value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] value CLC 2p2z last value
+ */
+static inline void clc_sw_inject_2p2z_current_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
+{
+    clc->VDVQ_CHAN[chn].P2Z2_CURR = (uint32_t)value;
+}
+
+/**
+ * @brief CLC get 2p2z previous0 value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC 2p2z previous0 value
+ */
+static inline int32_t clc_get_2p2z_previous0_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return (int32_t)clc->VDVQ_CHAN[chn].P2Z2_PRE0;
+}
+
+/**
+ * @brief CLC software inject 2p2z previous0 value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] value CLC 2p2z previous0 value
+ */
+static inline void clc_sw_inject_2p2z_previous0_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
+{
+    clc->VDVQ_CHAN[chn].P2Z2_PRE0 = (uint32_t)value;
+}
+
+/**
+ * @brief CLC get 3p3z last value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @retval CLC 3p3z last value
+ */
+static inline int32_t clc_get_3p3z_current_value(CLC_Type *clc, clc_chn_t chn)
+{
+    return (int32_t)clc->VDVQ_CHAN[chn].P3Z3_CURR;
+}
+
+/**
+ * @brief CLC software inject 3p3z last value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] value CLC 3p3z last value
+ */
+static inline void clc_sw_inject_3p3z_current_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
+{
+    clc->VDVQ_CHAN[chn].P3Z3_CURR = (uint32_t)value;
+}
+
+/**
+ * @brief CLC set expected adc value
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] expect expected adc value
+ */
+static inline void clc_set_expect_adc_value(CLC_Type *clc, clc_chn_t chn, int32_t expect)
+{
+    clc->VDVQ_CHAN[chn].ADC_EXPECT = (uint32_t)expect;
+}
+
+/**
+ * @brief CLC software inject adc value. If it's not dq mode, this will trig clc calculation.
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] value CLC adc value
+ */
+static inline void clc_sw_inject_adc_value(CLC_Type *clc, clc_chn_t chn, uint32_t value)
+{
+    clc->VDVQ_CHAN[chn].ADC_SW = value;
+}
+
+/**
+ * @brief CLC set software inject dq adc value ready, this will trig clc calculation.
+ * @param[in] clc CLC base address
+ */
+static inline void clc_set_sw_inject_dq_adc_value_ready(CLC_Type *clc)
+{
+    clc->DQ_ADC_SW_READY = CLC_DQ_ADC_SW_READY_DQ_ADC_SW_READY_MASK;
+}
+
+/**
+ * @brief CLC parameter configuration
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] param @ref clc_param_config_t.
+ */
+void clc_config_param(CLC_Type *clc, clc_chn_t chn, clc_param_config_t *param);
+
+/**
+ * @brief CLC coefficient configuration
+ * @param[in] clc CLC base address
+ * @param[in] chn CLC channel, @ref clc_chn_t
+ * @param[in] zone CLC coefficient zone, @ref clc_coeff_zone_t
+ * @param[in] coeff @ref clc_param_config_t.
+ *
+ * @retval status_invalid_argument some parameters are invalid
+ * @retval status_success operation is successful
+ */
+hpm_stat_t clc_config_coeff(CLC_Type *clc, clc_chn_t chn, clc_coeff_zone_t zone, clc_coeff_config_t *coeff);
+
+/**
+ * @brief CLC software inject dq adc value
+ * @param[in] clc CLC base address
+ * @param[in] d_value CLC d adc value
+ * @param[in] q_value CLC q adc value
+ */
+void clc_sw_inject_dq_adc_value(CLC_Type *clc, uint32_t d_value, uint32_t q_value);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_CLC_DRV_H */

+ 60 - 52
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_common.h

@@ -156,6 +156,7 @@ enum {
     status_group_ffa,
     status_group_mcan,
     status_group_ewdg,
+    status_group_esc,
 
     status_group_middleware_start = 500,
     status_group_sdmmc = status_group_middleware_start,
@@ -174,58 +175,39 @@ enum {
 };
 
 #if defined(__GNUC__)
-
-/* alway_inline */
-#define ATTR_ALWAYS_INLINE __attribute__((always_inline))
-
 /* weak */
 #define ATTR_WEAK __attribute__((weak))
 
-/* alignment */
-#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
-
-/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
-#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
-
-#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
-ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
-
-#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss")
-#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
-    ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
-
-#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
-#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
-    ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
-
-/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
-#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
-#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
-    ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
-
-#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
-#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
-    ATTR_RAMFUNC ATTR_ALIGN(alignment)
-
-#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
-
-#define NOP() __asm volatile("nop")
-#define WFI() __asm volatile("wfi")
-
 #define HPM_ATTR_MACHINE_INTERRUPT __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)))
 #define HPM_ATTR_SUPERVISOR_INTERRUPT __attribute__ ((section(".isr_s_vector"), interrupt("supervisor"), aligned(4)))
 
 #elif defined(__ICCRISCV__)
+/* weak */
+#define ATTR_WEAK __weak
+
+#define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt
+#define HPM_ATTR_SUPERVISOR_INTERRUPT __supervisor __interrupt
+
+#ifndef __TIMEVAL_DEFINED
+#define __TIMEVAL_DEFINED 1
+struct timeval {
+  long tv_sec;    /* Seconds since the Epoch */
+  long tv_usec;   /* Microseconds */
+};
+#endif
 
+#else
+#error Unknown toolchain
+#endif
+
+#if defined(__GNUC__) || defined(__ICCRISCV__)
 
 /* alway_inline */
 #define ATTR_ALWAYS_INLINE __attribute__((always_inline))
 
-/* weak */
-#define ATTR_WEAK __weak
-
 /* alignment */
 #define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
+#define ATTR_PACKED __attribute__((packed, aligned(1)))
 
 /* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
 #define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
@@ -233,7 +215,7 @@ ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
 #define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
 ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
 
-#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss")
+#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable")
 #define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
     ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
 
@@ -246,6 +228,19 @@ ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
 #define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
     ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
 
+/* .fast_ram section */
+#define ATTR_PLACE_AT_FAST_RAM ATTR_PLACE_AT(".fast_ram")
+#define ATTR_PLACE_AT_FAST_RAM_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_FAST_RAM ATTR_ALIGN(alignment)
+
+#define ATTR_PLACE_AT_FAST_RAM_BSS ATTR_PLACE_AT(".fast_ram.bss")
+#define ATTR_PLACE_AT_FAST_RAM_BSS_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_FAST_RAM_BSS ATTR_ALIGN(alignment)
+
+#define ATTR_PLACE_AT_FAST_RAM_INIT ATTR_PLACE_AT(".fast_ram.init")
+#define ATTR_PLACE_AT_FAST_RAM_INIT_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_FAST_RAM_INIT ATTR_ALIGN(alignment)
+
 #define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
 #define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
     ATTR_RAMFUNC ATTR_ALIGN(alignment)
@@ -255,19 +250,6 @@ ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
 #define NOP() __asm volatile("nop")
 #define WFI() __asm volatile("wfi")
 
-#define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt
-#define HPM_ATTR_SUPERVISOR_INTERRUPT __supervisor __interrupt
-
-#ifndef __TIMEVAL_DEFINED
-#define __TIMEVAL_DEFINED 1
-struct timeval {
-  long tv_sec;    /* Seconds since the Epoch */
-  long tv_usec;   /* Microseconds */
-};
-#endif
-
-#else
-#error Unknown toolchain
 #endif
 
 #ifdef __cplusplus
@@ -333,6 +315,32 @@ static inline uint32_t get_first_set_bit_from_msb(uint32_t value)
     return i;
 }
 
+/**
+ * @brief Convert the elapsed ticks to microseconds according to the source clock frequency
+ * @param [in] ticks elapsed ticks
+ * @param [in] src_clk_freq The Frequency of the source
+ *
+ * @return elapsed microseconds
+ */
+static inline uint32_t hpm_convert_ticks_to_us(uint32_t ticks, uint32_t src_clk_freq)
+{
+    uint32_t ticks_per_us = (src_clk_freq + 1000000UL - 1UL) / 1000000UL;
+    return (ticks + ticks_per_us - 1UL) / ticks_per_us;
+}
+
+/**
+ * @brief Convert the elapsed ticks to milliseconds according to the source clock frequency
+ * @param [in] ticks elapsed ticks
+ * @param [in] src_clk_freq The Frequency of the source
+ *
+ * @return elapsed milliseconds
+ */
+static inline uint32_t hpm_convert_ticks_to_ms(uint32_t ticks, uint32_t src_clk_freq)
+{
+    uint32_t ticks_per_ms = (src_clk_freq + 1000UL - 1UL) / 1000UL;
+    return (ticks + ticks_per_ms - 1UL) / ticks_per_ms;
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_dao_drv.h

@@ -44,7 +44,7 @@ typedef struct dao_config {
     bool enable_mono_output;
     uint8_t default_output_level;
     uint8_t channel_count;
-#if defined(DAO_SOC_SUPPORT_DATA_FORMAT_CONFIG) && (DAO_SOC_SUPPORT_DATA_FORMAT_CONFIG == 1)
+#if defined(HPM_IP_FEATURE_DAO_DATA_FORMAT_CONFIG) && (HPM_IP_FEATURE_DAO_DATA_FORMAT_CONFIG == 1)
     bool enable_tdm_mode;
     bool frame_start_at_rising_edge;
     uint8_t protocol;

+ 1 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_dma_drv.h

@@ -497,7 +497,7 @@ static inline uint32_t dma_check_transfer_status(DMA_Type *ptr, uint8_t ch_index
  */
 static inline void dma_clear_transfer_status(DMA_Type *ptr, uint8_t ch_index)
 {
-    ptr->INTSTATUS &= ~((1 << (DMA_STATUS_TC_SHIFT + ch_index)) | (1 << (DMA_STATUS_ERROR_SHIFT + ch_index)) | (1 << (DMA_STATUS_ABORT_SHIFT + ch_index)));
+    ptr->INTSTATUS = ((1 << (DMA_STATUS_TC_SHIFT + ch_index)) | (1 << (DMA_STATUS_ERROR_SHIFT + ch_index)) | (1 << (DMA_STATUS_ABORT_SHIFT + ch_index)));
 }
 
 /**

+ 75 - 2
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_dmav2_drv.h

@@ -70,6 +70,11 @@
 #define DMA_HANDSHAKE_OPT_ONE_BURST             (0U)
 #define DMA_HANDSHAKE_OPT_ALL_TRANSIZE          (1U)
 
+#define DMA_SWAP_MODE_TABLE                     (0U)
+#define DMA_SWAP_MODE_BYTE                      (1U)
+#define DMA_SWAP_MODE_HALF_WORD                 (2U)
+#define DMA_SWAP_MODE_WORD                      (3U)
+
 #define DMA_INTERRUPT_MASK_NONE                 (0U)
 #define DMA_INTERRUPT_MASK_ERROR  DMAV2_CHCTRL_CTRL_INTERRMASK_MASK
 #define DMA_INTERRUPT_MASK_ABORT  DMAV2_CHCTRL_CTRL_INTABTMASK_MASK
@@ -106,9 +111,9 @@ typedef struct dma_linked_descriptor {
     uint32_t src_addr;          /**< Source address */
     uint32_t req_ctrl;          /**< Request select */
     uint32_t dst_addr;          /**< Destination address */
-    uint32_t reserved0;         /**< not used on dmav2 */
+    uint32_t swap_table;        /**< Swap table */
     uint32_t linked_ptr;        /**< Linked descriptor address */
-    uint32_t reserved1;         /**< not used on dmav2 */
+    uint32_t reserved0;         /**< not used on dmav2 */
 } dma_linked_descriptor_t;
 
 /* @brief Channel config */
@@ -129,6 +134,14 @@ typedef struct dma_channel_config {
     bool en_infiniteloop;           /**< Infinite loop transfer enable. Attention: only DMAV2 support */
     uint8_t handshake_opt;          /**< Handshake transfer option. Attention: only DMAV2 support */
     uint8_t burst_opt;              /**< Burst size option. Attention: only DMAV2 support */
+#if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
+    bool en_src_burst_in_fixed_trans;          /**< Source burst in fix transfer size enable, discard src_addr_ctrl setting. Attention: only DMAV2 support */
+    bool en_dst_burst_in_fixed_trans;          /**< Destination burst in fix transfer size enable, discard dst_addr_ctrl setting. Attention: only DMAV2 support */
+#endif
+#if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
+    uint8_t swap_mode;              /**< Swap Mode. Attention: only DMAV2 support */
+    uint32_t swap_table;            /**< Swap Table. Attention: only DMAV2 support */
+#endif
 } dma_channel_config_t;
 
 /* @brief Channel config */
@@ -467,6 +480,66 @@ static inline void dma_set_handshake_option(DMAV2_Type *ptr, uint32_t ch_index,
     ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_HANDSHAKEOPT_MASK) | DMAV2_CHCTRL_CTRL_HANDSHAKEOPT_SET(handshake_opt);
 }
 
+#if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
+/**
+ * @brief   Set DMA channel source burst in fixed transfer size enable or disable
+ *
+ * @param[in] ptr DMA base address
+ * @param[in] ch_index Index of the channel
+ * @param[in] enable false - disable; true - enable
+ *
+ */
+static inline void dma_set_source_burst_in_fixed_transize_enable(DMAV2_Type *ptr, uint32_t ch_index, bool enable)
+{
+    ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRC_FIXBURST_MASK) | DMAV2_CHCTRL_CTRL_SRC_FIXBURST_SET(enable);
+}
+
+/**
+ * @brief   Set DMA channel destination burst in fixed transfer size enable or disable
+ *
+ * @param[in] ptr DMA base address
+ * @param[in] ch_index Index of the channel
+ * @param[in] enable false - disable; true - enable
+ *
+ */
+static inline void dma_set_destination_burst_in_fixed_transize_enable(DMAV2_Type *ptr, uint32_t ch_index, bool enable)
+{
+    ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DST_FIXBURST_MASK) | DMAV2_CHCTRL_CTRL_DST_FIXBURST_SET(enable);
+}
+#endif
+
+#if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
+/**
+ * @brief   Set DMA channel swap mode
+ *
+ * @param[in] ptr DMA base address
+ * @param[in] ch_index Index of the channel
+ * @param[in] swap_mode swap mode
+ *  @arg @ref DMA_SWAP_MODE_TABLE
+ *  @arg @ref DMA_SWAP_MODE_BYTE
+ *  @arg @ref DMA_SWAP_MODE_HALF_WORD
+ *  @arg @ref DMA_SWAP_MODE_WORD
+ *
+ */
+static inline void dma_set_swap_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t swap_mode)
+{
+    ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SWAP_CTL_MASK) | DMAV2_CHCTRL_CTRL_SWAP_CTL_SET(swap_mode);
+}
+
+/**
+ * @brief   Set DMA channel swap table
+ *
+ * @param[in] ptr DMA base address
+ * @param[in] ch_index Index of the channel
+ * @param[in] swap_table swap table
+ *
+ */
+static inline void dma_set_swap_table(DMAV2_Type *ptr, uint32_t ch_index, uint32_t swap_table)
+{
+    ptr->CHCTRL[ch_index].SWAPTABLE = swap_table;
+}
+#endif
+
 /**
  * @brief   Abort channel transfer with mask
  *

+ 13 - 3
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_enet_drv.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -59,7 +59,8 @@
 typedef enum {
     enet_normal_int_sum_en   = ENET_DMA_INTR_EN_NIE_MASK,
     enet_aboarmal_int_sum_en = ENET_DMA_INTR_EN_AIE_MASK,
-    enet_receive_int_en      = ENET_DMA_INTR_EN_RIE_MASK
+    enet_receive_int_en      = ENET_DMA_INTR_EN_RIE_MASK,
+    enet_transmit_int_en     = ENET_DMA_INTR_EN_TIE_MASK
 } enet_interrupt_enable_t;
 
 /** @brief interrupt mask type */
@@ -153,6 +154,7 @@ typedef enum {
 
 /** @brief enet interface selections */
 typedef enum {
+    enet_inf_mii  = 0,
     enet_inf_rmii = 4,
     enet_inf_rgmii = 1
 } enet_inf_type_t;
@@ -232,7 +234,7 @@ typedef enum {
     enet_pps_ctrl_bin_4096hz_digital_2048hz,
     enet_pps_ctrl_bin_8192hz_digital_4096hz,
     enet_pps_ctrl_bin_16384hz_digital_8192hz,
-    enet_pps_ctrl_bin_32867hz_digital_16384hz
+    enet_pps_ctrl_bin_32768hz_digital_16384hz
 } enet_pps_ctrl_t;
 
 /** @brief PPS0 commands */
@@ -545,6 +547,14 @@ extern "C" {
  */
 void enet_get_default_tx_control_config(ENET_Type *ptr, enet_tx_control_config_t *config);
 
+/**
+ * @brief Get a default interrupt config
+ *
+ * @param[in] ptr An Ethernet peripheral base address
+ * @param[in] config A pointer to a interrupt config structure
+ */
+void enet_get_default_interrupt_config(ENET_Type *ptr, enet_int_config_t *config);
+
 /**
  * @brief Get interrupt status
  *

+ 347 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_esc_drv.h

@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+
+#ifndef HPM_ESC_DRV_H
+#define HPM_ESC_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_esc_regs.h"
+
+/**
+ *
+ * @brief ESC driver APIs
+ * @defgroup esc_interface ESC driver APIs
+ * @ingroup esc_interfaces
+ * @{
+ */
+
+ /**
+ * @brief ESC error codes
+ */
+enum {
+    status_esc_eeprom_ack_error      = MAKE_STATUS(status_group_esc, 0),           /**< ESC EEPROM ack error */
+    status_esc_eeprom_checksum_error = MAKE_STATUS(status_group_esc, 1),           /**< ESC EEPROM checksum error */
+};
+
+
+typedef enum {
+    latch_source_from_ntm = 0,
+    latch_source_from_trigger_mux = 1,
+} esc_latch_source_t;
+
+typedef enum {
+    esc_eeprom_idle_cmd = 0, /* clear error bits */
+    esc_eeprom_read_cmd = 1,
+    esc_eeprom_write_cmd = 2,
+    esc_eeprom_reload_cmd = 4,
+} esc_eeprom_cmd_t;
+
+typedef enum  {
+    esc_ctrl_signal_func_alt_nmii_link0 = 0,
+    esc_ctrl_signal_func_alt_nmii_link1 = 1,
+    esc_ctrl_signal_func_alt_nmii_link2 = 2,
+    esc_ctrl_signal_func_alt_link_act0  = 3,
+    esc_ctrl_signal_func_alt_link_act1  = 4,
+    esc_ctrl_signal_func_alt_link_act2  = 5,
+    esc_ctrl_signal_func_alt_led_run    = 6,
+    esc_ctrl_signal_func_alt_led_err    = 7,
+    esc_ctrl_signal_func_alt_reset_out  = 8,
+} esc_ctrl_signal_function_t;
+
+
+typedef struct {
+    bool eeprom_emulation;
+    bool eeprom_size_over_16kbit;
+    bool core_clock_en;
+    bool phy_refclk_en;
+} esc_eeprom_clock_config_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief ESC peripheral clock
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] enable Set true to enable or false to disable
+ */
+static inline void esc_core_enable_clock(ESC_Type *ptr, bool enable)
+{
+    if (enable) {
+        ptr->GPR_CFG0 |= ESC_GPR_CFG0_CLK100_EN_MASK;
+    } else {
+        ptr->GPR_CFG0 &= ~ESC_GPR_CFG0_CLK100_EN_MASK;
+    }
+}
+
+/**
+ * @brief ESC PHY clock
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] enable Set true to enable or false to disable
+ */
+static inline void esc_phy_enable_clock(ESC_Type *ptr, bool enable)
+{
+    if (enable) {
+        ptr->PHY_CFG1 |= ESC_PHY_CFG1_REFCK_25M_OE_MASK;   /*!< enable PHY 25M refck */
+    } else {
+        ptr->PHY_CFG1 &= ~ESC_PHY_CFG1_REFCK_25M_OE_MASK;   /*!< disable PHY 25M refck */
+    }
+}
+
+/**
+ * @brief ESC config eeprom attributes(emulation and size) and peripheral clock
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] config esc_eeprom_clock_config_t
+ */
+static inline void esc_config_eeprom_and_clock(ESC_Type *ptr, esc_eeprom_clock_config_t *config)
+{
+    uint32_t gpr_cfg0 = ptr->GPR_CFG0;
+
+    if (config->eeprom_emulation) {
+        gpr_cfg0 |= ESC_GPR_CFG0_EEPROM_EMU_MASK;
+        gpr_cfg0 &= ~(ESC_GPR_CFG0_PROM_SIZE_MASK | ESC_GPR_CFG0_I2C_SCLK_EN_MASK);
+    } else {
+        gpr_cfg0 &= ~ESC_GPR_CFG0_EEPROM_EMU_MASK;
+        gpr_cfg0 |= ESC_GPR_CFG0_I2C_SCLK_EN_MASK;
+        if (config->eeprom_size_over_16kbit) {
+            gpr_cfg0 |= ESC_GPR_CFG0_PROM_SIZE_MASK;
+        } else {
+            gpr_cfg0 &= ~ESC_GPR_CFG0_PROM_SIZE_MASK;
+        }
+    }
+    ptr->GPR_CFG0 = gpr_cfg0;
+    esc_core_enable_clock(ptr, config->core_clock_en);
+    esc_phy_enable_clock(ptr, config->phy_refclk_en);
+}
+
+/**
+ * @brief ESC assign specific function to CTRL signal
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] index CTRL signal index(0-8)
+ * @param[in] func specific function
+ * @param[in] invert invert signal
+ */
+static inline void esc_config_ctrl_signal_function(ESC_Type *ptr, uint8_t index, esc_ctrl_signal_function_t func, bool invert)
+{
+    ptr->IO_CFG[index] = ESC_IO_CFG_FUNC_ALT_SET(func) | ESC_IO_CFG_INVERT_SET(invert);
+}
+
+/**
+ * @brief ESC config nmii_link signal source
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] link0_from_io true for signal from configured IO; false for signal from register(GPR_CFG2) value
+ * @param[in] link1_from_io true for signal from configured IO; false for signal from register(GPR_CFG2) value
+ * @param[in] link2_from_io true for signal from configured IO; false for signal from register(GPR_CFG2) value
+ */
+static inline void esc_config_nmii_link_source(ESC_Type *ptr, bool link0_from_io, bool link1_from_io, bool link2_from_io)
+{
+    if (link0_from_io) {
+        ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK0_FROM_IO_MASK;
+    } else {
+        ptr->GPR_CFG2 &= ~ESC_GPR_CFG2_NMII_LINK0_FROM_IO_MASK;
+        ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK0_GPR_MASK; /* config GRP to indicate LINK0 is invalid by default */
+    }
+
+    if (link1_from_io) {
+        ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK1_FROM_IO_MASK;
+    } else {
+        ptr->GPR_CFG2 &= ~ESC_GPR_CFG2_NMII_LINK1_FROM_IO_MASK;
+        ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK1_GPR_MASK; /* config GRP to indicate LINK1 is invalid by default */
+    }
+
+    if (link2_from_io) {
+        ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK2_FROM_IO_MASK;
+    } else {
+        ptr->GPR_CFG2 &= ~ESC_GPR_CFG2_NMII_LINK2_FROM_IO_MASK;
+        ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK2_GPR_MASK; /* config GRP to indicate LINK2 is invalid by default */
+    }
+}
+
+/* config ESC reset request source: ESC core or GRP_REG value */
+/**
+ * @brief ESC config reset signal source
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] reset_from_ecat_core true for reset signal from ecat core; false for reset signal from register(GPR_CFG1) value
+ */
+static inline void esc_config_reset_source(ESC_Type *ptr, bool reset_from_ecat_core)
+{
+    if (reset_from_ecat_core) {
+        ptr->GPR_CFG1 |= ESC_GPR_CFG1_RSTO_OVRD_ENJ_MASK;
+    } else {
+        ptr->GPR_CFG1 &= ~ESC_GPR_CFG1_RSTO_OVRD_ENJ_MASK;
+    }
+}
+
+/**
+ * @brief ESC generate reset signal to ESC_RESET interrupt and RESET_OUT pin
+ * @note the reset signal source should be configured in esc_config_reset_source before
+ *
+ * @param[in] ptr ESC base address
+ */
+static inline void esc_pdi_reset(ESC_Type *ptr)
+{
+    ptr->ESC_RST_PDI = 0x52; /* R */
+    ptr->ESC_RST_PDI = 0x45; /* E */
+    ptr->ESC_RST_PDI = 0x53; /* S */
+}
+
+/*!
+ * @brief ESC read PHY register via ESC MII Management Interface
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] phy_addr PHY address.
+ * @param[in] reg_addr Register address.
+ * @param[in] data PHY data returned.
+ */
+
+hpm_stat_t esc_mdio_read(ESC_Type *ptr, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
+
+/*!
+ * @brief ESc write PHY register via ESC MII Management Interface
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] phy_addr PHY address.
+ * @param[in] reg_addr Register address.
+ * @param[in] data Write to PHY register.
+ */
+hpm_stat_t esc_mdio_write(ESC_Type *ptr, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
+
+/*!
+ * @brief ESC check eeprom loading data status
+ * @note EtherCAT communication is possible even if the EEPROM is blank
+ *
+ * @param[in] ptr ESC base address.
+ * @retval status_success: loding data successfully and correctlly.
+ * @retval status_esc_eeprom_ack_error: loding  data checksum error(eeprom blank).
+ * @retval status_esc_eeprom_checksum_error: no ack error.
+ * @retval status_timeout: loding data timeout.
+ */
+hpm_stat_t esc_check_eeprom_loading(ESC_Type *ptr);
+
+/*!
+ * @brief ESC get eeprom cmd, this using in eeprom emulation function
+ *
+ * @param[in] ptr ESC base address
+ * @return uint8_t esc_eeprom_cmd_t.
+ */
+static inline uint8_t esc_get_eeprom_cmd(ESC_Type *ptr)
+{
+    return ESC_EEPROM_CTRL_STAT_CMD_GET(ptr->EEPROM_CTRL_STAT);
+}
+
+/*!
+ * @brief ESC ack eeprom cmd in eeprom emualtion function
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] cmd esc_eeprom_cmd_t
+ * @param[in] ack_err eeprom ack error occurrred
+ * @param[in] crc_err eeprom checksum error occurrred
+ */
+static inline void esc_eeprom_emulation_ack(ESC_Type *ptr, esc_eeprom_cmd_t cmd, bool ack_err, bool crc_err)
+{
+    uint16_t temp = ESC_EEPROM_CTRL_STAT_CMD_SET(cmd);
+    if (ack_err) {
+        temp |= ESC_EEPROM_CTRL_STAT_ERR_ACK_CMD_MASK;
+    }
+    if (crc_err) {
+        temp |= ESC_EEPROM_CTRL_STAT_CKSM_ERR_MASK;
+    }
+
+    ptr->EEPROM_CTRL_STAT = temp;
+}
+
+/*!
+ * @brief ESC get eeprom byte address
+ *
+ * @param[in] ptr ESC base address
+ * @return byte address
+ */
+static inline uint32_t esc_get_eeprom_byte_address(ESC_Type *ptr)
+{
+    return (ptr->EEPROM_ADDR) << 1U;
+}
+
+/*!
+ * @brief ESC get eeprom word(2 bytes) address
+ *
+ * @param[in] ptr ESC base address
+ * @return word address
+ */
+static inline uint32_t esc_get_eeprom_word_address(ESC_Type *ptr)
+{
+    return ptr->EEPROM_ADDR;
+}
+
+/*!
+ * @brief ESC read eeprom data from register, this function is using in eeprom emulation function
+ *
+ * @param[in] ptr ESC base address
+ * @return eeprom data
+ */
+static inline uint64_t esc_read_eeprom_data(ESC_Type *ptr)
+{
+    return ptr->EEPROM_DATA;
+}
+
+/*!
+ * @brief ESC write eeprom data to register, this function is using in eeprom emulation function
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] data eeprom data
+ */
+static inline void esc_write_eeprom_data(ESC_Type *ptr, uint64_t data)
+{
+    ptr->EEPROM_DATA = data;
+}
+
+/*!
+ * @brief ESC config latch0 signal source
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] latch0_from_ntm true for signal from ntm system, false for signal from IO
+ */
+static inline void esc_config_latch0_source(ESC_Type *ptr, bool latch0_from_ntm)
+{
+    if (latch0_from_ntm) {
+        ptr->GPR_CFG1 &= ~ESC_GPR_CFG1_LATCH0_FROM_IO_MASK;
+    } else {
+        ptr->GPR_CFG1 |= ESC_GPR_CFG1_LATCH0_FROM_IO_MASK;
+    }
+}
+
+/*!
+ * @brief ESC config latch1 signal source
+ *
+ * @param[in] ptr ESC base address
+ * @param[in] latch0_from_trigmux true for signal from trigmux system, false for signal from IO
+ */
+static inline void esc_config_latch1_source(ESC_Type *ptr, bool latch0_from_trigmux)
+{
+    if (latch0_from_trigmux) {
+        ptr->GPR_CFG1 &= ~ESC_GPR_CFG1_LATCH1_FROM_IO_MASK;
+    } else {
+        ptr->GPR_CFG1 |= ESC_GPR_CFG1_LATCH1_FROM_IO_MASK;
+    }
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_ESC_DRV_H */

+ 4 - 6
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_ewdg_drv.h

@@ -19,6 +19,9 @@
  * @{
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /**
  * @brief EWDG error codes
@@ -159,9 +162,7 @@ typedef enum {
 
 typedef enum {
     ewdg_low_power_mode_halt = 0,               /*!< Watchdog is halted in low power mode */
-    ewdg_low_power_mode_work_clock_div_4 = 1,   /*!< Watchdog is will work with 1/4 normal clock in low power mode */
-    ewdg_low_power_mode_work_clock_div_2 = 2,   /*!< Watchdog is will work with 1/2 normal clock in low power mode */
-    ewdg_low_power_mode_work_clock_normal = 3,  /*!< Watchdog is will work with normal clock in low power mode */
+    ewdg_low_power_mode_work_clock_normal = 1,  /*!< Watchdog is will work with normal clock in low power mode */
 } ewdg_low_power_mode_t;
 
 /***
@@ -505,9 +506,6 @@ void ewdg_disable_reset(EWDG_Type *ptr, uint32_t mask);
  */
 void ewdg_switch_clock_source(EWDG_Type *ptr, ewdg_cnt_clk_sel_t clk_sel);
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 
 #ifdef __cplusplus
 }

+ 4 - 4
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_femc_drv.h

@@ -114,18 +114,18 @@ typedef struct {
     uint8_t prescaler;                  /**< presecaler */
     uint8_t port_size;                  /**< SDRAM port size */
     uint8_t burst_len_in_byte;          /**< 1/2/4/8 bytes */
-    uint8_t cke_off_in_ns;              /**< Tcks */
+    uint8_t cke_off_in_ns;
     uint8_t act_to_precharge_in_ns;     /**< Tras */
     uint8_t precharge_to_act_in_ns;     /**< Trp  */
     uint8_t act_to_rw_in_ns;            /**< Trcd */
     uint8_t act_to_act_in_ns;           /**< Trrd */
     uint8_t refresh_to_refresh_in_ns;   /**< Trc */
-    uint8_t write_recover_in_ns;        /**< Tdpl */
+    uint8_t write_recover_in_ns;        /**< Twr */
     uint8_t self_refresh_recover_in_ns; /**< Txsr */
-    uint8_t refresh_recover_in_ns;      /**< Txsr */
+    uint8_t refresh_recover_in_ns;      /**< Trc */
     uint8_t refresh_in_ms;              /**< Tref */
     uint8_t idle_timeout_in_ns;
-    uint8_t data_width_in_byte;
+    uint8_t cmd_data_width;
     uint8_t auto_refresh_count_in_one_burst;
     bool delay_cell_disable;            /**< Delay cell disable */
     uint8_t delay_cell_value;           /**< Delay cell value */

+ 62 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_ffa_drv.h

@@ -9,6 +9,7 @@
 
 #include "hpm_common.h"
 #include "hpm_ffa_regs.h"
+#include "hpm_soc_ip_feature.h"
 
 /**
  * @brief FFA driver APIs
@@ -36,6 +37,10 @@
 #define FFA_DATA_TYPE_REAL_Q15      (1U)    /* !< FFA Data type: Real Q15 */
 #define FFA_DATA_TYPE_COMPLEX_Q31   (2U)    /* !< FFA Data type: Complex Q31 */
 #define FFA_DATA_TYPE_COMPLEX_Q15   (3U)    /* !< FFA Data type: Complex Q15 */
+#if defined(HPM_IP_FEATURE_FFA_FP32) && HPM_IP_FEATURE_FFA_FP32
+#define FFA_DATA_TYPE_COMPLEX_FP32  (4U)    /* !< FFA Data type: Complex Q15 */
+#define FFA_DATA_TYPE_REAL_FP32     (5U)    /* !< FFA Data type: Complex Q15 */
+#endif
 
 /**
  * @brief FFA Q31 data type definition
@@ -100,6 +105,14 @@ enum {
     status_ffa_read_error = MAKE_STATUS(status_group_ffa, 4),           /*!< FFA read error */
 };
 
+#if defined(HPM_IP_FEATURE_FFA_FP32) && HPM_IP_FEATURE_FFA_FP32
+typedef enum {
+    input_data = 0,
+    output_data = 1,
+    coeff_data = 2
+} ffa_fp32_status_source_t;
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -157,6 +170,55 @@ static inline void ffa_disable_interrupt(FFA_Type *ptr, uint32_t mask)
     ptr->INT_EN &= ~mask;
 }
 
+#if defined(HPM_IP_FEATURE_FFA_FP32) && HPM_IP_FEATURE_FFA_FP32
+
+static inline void ffa_enable_fp32_interrupt(FFA_Type *ptr, uint32_t mask)
+{
+    ptr->FP_CTRL |= mask;
+}
+
+static inline void ffa_disable_fp32_interrupt(FFA_Type *ptr, uint32_t mask)
+{
+    ptr->FP_CTRL &= ~mask;
+}
+
+static inline void ffa_set_fp_status_source(FFA_Type *ptr, ffa_fp32_status_source_t source)
+{
+    ptr->FP_CTRL = FFA_FP_CTRL_EXP_ST_SEL_SET(source);
+}
+
+static inline void ffa_enable_fp_bias(FFA_Type *ptr)
+{
+    ptr->FP_CTRL |= FFA_FP_CTRL_OPT_BIAS_EXP_MASK;
+}
+
+static inline void ffa_disable_fp_bias(FFA_Type *ptr)
+{
+    ptr->FP_CTRL &= ~FFA_FP_CTRL_OPT_BIAS_EXP_MASK;
+}
+
+static inline void ffa_set_coef_max_index(FFA_Type *ptr, uint8_t max)
+{
+    ptr->FP_CTRL = (ptr->FP_CTRL & ~FFA_FP_CTRL_COEF_MAX_MASK) | FFA_FP_CTRL_COEF_MAX_SET(max);
+}
+
+static inline void ffa_set_output_max_index(FFA_Type *ptr, uint8_t max)
+{
+    ptr->FP_CTRL = (ptr->FP_CTRL & ~FFA_FP_CTRL_OUT_MAX_MASK) | FFA_FP_CTRL_OUT_MAX_SET(max);
+}
+
+static inline void ffa_set_input_max_index(FFA_Type *ptr, uint8_t max)
+{
+    ptr->FP_CTRL = (ptr->FP_CTRL & ~FFA_FP_CTRL_IN_MAX_MASK) | FFA_FP_CTRL_IN_MAX_SET(max);
+}
+
+static inline uint32_t ffa_get_fp_status(FFA_Type *ptr)
+{
+    return ptr->FP_ST;
+}
+
+#endif
+
 /**
  * @brief Start an FFT operation
  *

+ 169 - 2
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_gptmr_drv.h

@@ -9,6 +9,7 @@
 #define HPM_GPTMR_DRV_H
 #include "hpm_common.h"
 #include "hpm_gptmr_regs.h"
+#include "hpm_soc_feature.h"
 
 /**
  * @brief GPTMR driver APIs
@@ -84,6 +85,17 @@ typedef enum gptmr_counter_type {
     gptmr_counter_type_normal,
 } gptmr_counter_type_t;
 
+/**
+ * @brief GPTMR counter mode
+ */
+
+#if defined(HPM_IP_FEATURE_GPTMR_CNT_MODE) && (HPM_IP_FEATURE_GPTMR_CNT_MODE  == 1)
+typedef enum gptmr_counter_mode {
+    gptmr_counter_mode_internal = 0,
+    gptmr_counter_mode_external,
+} gptmr_counter_mode_t;
+#endif
+
 /**
  * @brief GPTMR channel config
  */
@@ -100,6 +112,19 @@ typedef struct gptmr_channel_config {
     bool debug_mode;
 } gptmr_channel_config_t;
 
+#if defined(HPM_IP_FEATURE_GPTMR_MONITOR) && (HPM_IP_FEATURE_GPTMR_MONITOR  == 1)
+typedef enum gptmr_channel_monitor_type {
+    monitor_signal_period = 0,
+    monitor_signal_high_level_time,
+} gptmr_channel_monitor_type_t;
+
+typedef struct gptmr_channel_monitor_config {
+    gptmr_channel_monitor_type_t monitor_type;
+    uint32_t max_value;   /**< The unit is the gptmr clock source period */
+    uint32_t min_value;   /**< The unit is the gptmr clock source period */
+} gptmr_channel_monitor_config_t;
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -346,7 +371,7 @@ static inline void gptmr_channel_set_capmode(GPTMR_Type *ptr, uint8_t ch_index,
  */
 static inline gptmr_work_mode_t gptmr_channel_get_capmode(GPTMR_Type *ptr, uint8_t ch_index)
 {
-    return GPTMR_CHANNEL_CR_CAPMODE_GET(ptr->CHANNEL[ch_index].CR);
+    return (gptmr_work_mode_t)GPTMR_CHANNEL_CR_CAPMODE_GET(ptr->CHANNEL[ch_index].CR);
 }
 
 /**
@@ -401,7 +426,7 @@ static inline void gptmr_channel_config_update_reload(GPTMR_Type *ptr, uint8_t c
  */
 static inline gptmr_dma_request_event_t gptmr_channel_get_dma_request_event(GPTMR_Type *ptr, uint8_t ch_index)
 {
-    return GPTMR_CHANNEL_CR_DMASEL_GET(ptr->CHANNEL[ch_index].CR);
+    return (gptmr_dma_request_event_t)GPTMR_CHANNEL_CR_DMASEL_GET(ptr->CHANNEL[ch_index].CR);
 }
 
 /**
@@ -429,6 +454,148 @@ hpm_stat_t gptmr_channel_config(GPTMR_Type *ptr,
  */
 void gptmr_channel_get_default_config(GPTMR_Type *ptr, gptmr_channel_config_t *config);
 
+
+#if defined(HPM_IP_FEATURE_GPTMR_CNT_MODE) && (HPM_IP_FEATURE_GPTMR_CNT_MODE  == 1)
+/**
+ * @brief gptmr set counter mode.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ * @param [in] mode gptmr_counter_mode_t, gptmr_counter_mode_external for gptmr enable external counting mode
+ */
+static inline void gptmr_channel_set_counter_mode(GPTMR_Type *ptr, uint8_t ch_index, gptmr_counter_mode_t mode)
+{
+    ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR & ~GPTMR_CHANNEL_CR_CNT_MODE_MASK) | GPTMR_CHANNEL_CR_CNT_MODE_SET(mode);
+}
+
+/**
+ * @brief gptmr channel get external trigger input counting mode.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ * @retval gptmr_counter_mode_external for external counting mode, gptmr_counter_mode_internal for internal counting mode
+ */
+static inline gptmr_counter_mode_t gptmr_channel_get_counter_mode(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    return ((ptr->CHANNEL[ch_index].CR & GPTMR_CHANNEL_CR_CNT_MODE_MASK) ==
+            GPTMR_CHANNEL_CR_CNT_MODE_MASK) ?
+            gptmr_counter_mode_external : gptmr_counter_mode_internal;
+}
+
+#endif
+
+#if defined(HPM_IP_FEATURE_GPTMR_OP_MODE) && (HPM_IP_FEATURE_GPTMR_OP_MODE  == 1)
+/**
+ * @brief gptmr channel enable opmode, it's one-shot mode, timer will stopped at reload point.
+ *
+ * @note  reload irq will be always set at one-shot mode at end
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ */
+static inline void gptmr_channel_enable_opmode(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_OPMODE_MASK;
+}
+
+/**
+ * @brief gptmr channel disable opmode, it's round mode.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ */
+static inline void gptmr_channel_disable_opmode(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_OPMODE_MASK;
+}
+
+/**
+ * @brief gptmr channel get opmode.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ * @retval bool true for opmode, false for normal mode
+ */
+static inline bool gptmr_channel_is_opmode(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    return ((ptr->CHANNEL[ch_index].CR & GPTMR_CHANNEL_CR_OPMODE_MASK) == GPTMR_CHANNEL_CR_OPMODE_MASK) ? true : false;
+}
+#endif
+
+#if defined(HPM_IP_FEATURE_GPTMR_MONITOR) && (HPM_IP_FEATURE_GPTMR_MONITOR  == 1)
+/**
+ * @brief gptmr channel enable monitor, set to monitor input signal period or high level time.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ */
+static inline void gptmr_channel_enable_monitor(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_MONITOR_EN_MASK;
+}
+
+/**
+ * @brief gptmr channel disable monitor
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ */
+static inline void gptmr_channel_disable_monitor(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_MONITOR_EN_MASK;
+}
+
+/**
+ * @brief gptmr channel set to monitor input signal period or high level time.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ * @param [in] type gptmr_channel_monitor_type_t
+ */
+static inline void gptmr_channel_set_monitor_type(GPTMR_Type *ptr, uint8_t ch_index, gptmr_channel_monitor_type_t type)
+{
+    ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR & ~GPTMR_CHANNEL_CR_MONITOR_SEL_MASK) | GPTMR_CHANNEL_CR_MONITOR_SEL_SET(type);
+}
+
+/**
+ * @brief gptmr channel get to monitor input signal period or high level time.
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ * @retval gptmr_channel_monitor_type_t monitor_signal_high_level_time or monitor_signal_period
+ */
+static inline gptmr_channel_monitor_type_t gptmr_channel_get_monitor_type(GPTMR_Type *ptr, uint8_t ch_index)
+{
+    return (gptmr_channel_monitor_type_t)GPTMR_CHANNEL_CR_MONITOR_SEL_GET(ptr->CHANNEL[ch_index].CR);
+}
+/**
+ * @brief gptmr channel get default monitor config
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [out] config gptmr_channel_monitor_config_t
+ */
+void gptmr_channel_get_default_monitor_config(GPTMR_Type *ptr, gptmr_channel_monitor_config_t *config);
+
+/**
+ * @brief gptmr channel monitor config
+ *
+ * @param [in] ptr GPTMR base address
+ * @param [in] ch_index channel index
+ * @param [in] config gptmr_channel_monitor_config_t
+ * @param [in] enable
+ *  @arg true: enable monitor and reset reload count
+ *  @arg false: disable monitor
+ *
+ * @retval hpm_stat_t status_invalid_argument or status_success
+ */
+
+hpm_stat_t gptmr_channel_monitor_config(GPTMR_Type *ptr, uint8_t ch_index,
+                                        gptmr_channel_monitor_config_t *config,
+                                        bool enable);
+
+#endif
+
+
 /**
  * @}
  */

+ 5 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_i2c_drv.h

@@ -163,10 +163,14 @@ static inline void i2c_clear_fifo(I2C_Type *ptr)
  * @param [in] ptr I2C base address
  * @retval data count value in byte
  */
-static inline uint8_t i2c_get_data_count(I2C_Type *ptr)
+static inline uint16_t i2c_get_data_count(I2C_Type *ptr)
 {
     uint32_t i2c_ctrl = ptr->CTRL;
+#ifdef I2C_CTRL_DATACNT_HIGH_MASK
     return (I2C_CTRL_DATACNT_HIGH_GET(i2c_ctrl) << 8U) + I2C_CTRL_DATACNT_GET(i2c_ctrl);
+#else
+    return I2C_CTRL_DATACNT_GET(i2c_ctrl);
+#endif
 }
 
 /**

+ 2 - 2
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_lcdc_drv.h

@@ -153,7 +153,7 @@ static inline void lcdc_disable_interrupt(LCDC_Type *ptr, uint32_t interrupt_mas
  */
 static inline void lcdc_clear_status(LCDC_Type *ptr, uint32_t mask)
 {
-    ptr->ST |= mask;
+    ptr->ST = mask;
 }
 
 /**
@@ -203,7 +203,7 @@ static inline bool lcdc_check_dma_status(LCDC_Type *ptr, uint32_t mask)
  */
 static inline void lcdc_clear_dma_status(LCDC_Type *ptr, uint32_t mask)
 {
-    ptr->DMA_ST |= mask;
+    ptr->DMA_ST = mask;
 }
 
 /**

+ 283 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_lobs_drv.h

@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_LOBS_DRV_H
+#define HPM_LOBS_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_soc_ip_feature.h"
+#include "hpm_lobs_regs.h"
+
+/**
+ * @brief LOBS driver APIs
+ * @defgroup lobs_interface LOBS driver APIs
+ * @ingroup lobs_interfaces
+ * @{
+ */
+
+#define LOBS_UNLOCK_KEY 0xc5acce55u
+
+#define LOBS_PIN_DO(x) (x * 3)
+#define LOBS_PIN_OE(x) (x * 3 + 1)
+#define LOBS_PIN_DI(x) (x * 3 + 2)
+
+/**
+ * @brief group mode selection
+ *
+ */
+typedef enum {
+    lobs_one_group_128_bits = 0,
+    lobs_two_group_8_bits
+} lobs_group_mode_t;    /**< lobs_group_mode_t */
+
+/**
+ * @brief sample rate selection
+ *
+ */
+typedef enum {
+    lobs_sample_1_per_5 = 4,
+    lobs_sample_1_per_6 = 5,
+    lobs_sample_1_per_7 = 6,
+} lobs_sample_rate_t;    /**< lobs_sample_rate_t */
+
+/**
+ * @brief burst selection
+ *
+ */
+typedef enum {
+    lobs_burst_4 = 3,
+    lobs_burst_8 = 5,
+    lobs_burst_16 = 7,
+} lobs_burst_t;    /**< lobs_burst_t */
+
+/**
+ * @brief two group selection
+ *
+ */
+typedef enum {
+    lobs_two_group_1 = 0,
+    lobs_two_group_2,
+} lobs_two_group_sel_t;    /**< lobs_two_group_sel_t */
+
+/**
+ * @brief state selection
+ *
+ */
+typedef enum {
+    lobs_state_0 = 0,
+    lobs_state_1,
+    lobs_state_2,
+    lobs_state_3,
+    lobs_state_4,
+} lobs_state_sel_t;    /**< lobs_state_sel_t */
+
+/**
+ * @brief compare mode
+ *
+ */
+typedef enum {
+    lobs_sig_cmp_mode = 0,
+    lobs_cnt_cmp_mode,
+} lobs_cmp_mode_t;    /**< lobs_cmp_mode_t */
+
+/**
+ * @brief compare condition
+ *
+ */
+typedef enum {
+    lobs_cnt_matched = 0,
+    lobs_sig_equal_golden,
+    lobs_sig_greater_golden,
+    lobs_sig_greater_equal_golden,
+    lobs_sig_not_equal_golden,
+    lobs_sig_less_golden,
+    lobs_sig_less_equal_golden,
+} lobs_state_chg_condition_t;    /**< lobs_state_chg_condition_t */
+
+/**
+ * @brief next state
+ *
+ */
+typedef enum {
+    lobs_next_state_finish = 0x00,
+    lobs_next_state_0 = 0x01,
+    lobs_next_state_1 = 0x02,
+    lobs_next_state_2 = 0x04,
+    lobs_next_state_3 = 0x08,
+    lobs_next_state_4 = 0x10,
+} lobs_next_state_t;    /**< lobs_next_state_t */
+
+/**
+ * @brief ctrl config structure
+ *
+ */
+typedef struct {
+    lobs_group_mode_t group_mode;
+    lobs_sample_rate_t sample_rate;
+    uint32_t start_addr;
+    uint32_t end_addr;
+} lobs_ctrl_config_t;    /**< lobs_ctrl_config_t */
+
+/**
+ * @brief two group mode config structure
+ *
+ */
+typedef struct {
+    bool group_enable;
+    uint8_t sig_group_num;
+    uint8_t sample_sig_bit[4];
+    bool sample_sig_en[4];
+} lobs_two_group_mode_config_t;    /**< lobs_two_group_mode_config_t */
+
+/**
+ * @brief two group mode config structure
+ *
+ */
+typedef struct {
+    uint8_t sig_group_num;
+    lobs_cmp_mode_t cmp_mode;
+    lobs_state_chg_condition_t state_chg_condition;
+    lobs_next_state_t next_state;
+    uint32_t cmp_counter;
+    uint8_t cmp_sig_bit[4];
+    bool cmp_sig_en[4];
+    bool cmp_golden_value[4];
+} lobs_state_config_t;    /**< lobs_state_config_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief set lobs unlock
+ *
+ * @param[in] lobs LOBS base address
+ */
+static inline void lobs_unlock(LOBS_Type *lobs)
+{
+    lobs->LAR = LOBS_UNLOCK_KEY;
+}
+
+/**
+ * @brief set lobs lock
+ *
+ * @param[in] lobs LOBS base address
+ */
+static inline void lobs_lock(LOBS_Type *lobs)
+{
+    lobs->LAR = 0;
+}
+
+/**
+ * @brief set lobs enable or disable
+ *
+ * @param[in] lobs LOBS base address
+ * @param[in] enable true - enable; false - disable.
+ */
+static inline void lobs_set_enable(LOBS_Type *lobs, bool enable)
+{
+    lobs->CTRL = (lobs->CTRL & ~LOBS_CTRL_RUN_MASK) | LOBS_CTRL_RUN_SET(enable);
+}
+
+/**
+ * @brief set lobs pre-trig enable or disable
+ *
+ * @param[in] lobs LOBS base address
+ * @param[in] enable true - enable; false - disable.
+ */
+static inline void lobs_set_pre_trig_enable(LOBS_Type *lobs, bool enable)
+{
+    lobs->PTACTION = (lobs->PTACTION & ~LOBS_PTACTION_TRACE_MASK) | LOBS_PTACTION_TRACE_SET(enable);
+}
+
+/**
+ * @brief set lobs state enable or disable
+ *
+ * @param[in] lobs LOBS base address
+ * @param[in] state one of state, @ref lobs_state_sel_t
+ * @param[in] enable true - enable; false - disable.
+ */
+static inline void lobs_set_state_enable(LOBS_Type *lobs, lobs_state_sel_t state, bool enable)
+{
+    lobs->STATE[state].ACTION = (lobs->STATE[state].ACTION & ~LOBS_STATE_ACTION_TRACE_MASK) | LOBS_STATE_ACTION_TRACE_SET(enable);
+}
+
+/**
+ * @brief get lobs final address
+ *
+ * @param[in] lobs LOBS base address
+ *
+ * @return uint32_t trace final address
+ */
+static inline uint32_t lobs_get_final_address(LOBS_Type *lobs)
+{
+    return lobs->FINALADDR;
+}
+
+/**
+ * @brief check lobs trace finish
+ *
+ * @param[in] lobs LOBS base address
+ *
+ * @return bool true - trace finish; false - trace not finish
+ */
+static inline bool lobs_is_trace_finish(LOBS_Type *lobs)
+{
+    return (LOBS_CTSR_FINALSTATE_GET(lobs->CTSR) != 0) ? true : false;
+}
+
+/**
+ * @brief clear lobs fifo overflow flag
+ *
+ * @param[in] lobs LOBS base address
+ *
+ */
+static inline void lobs_clear_fifo_overflow_flag(LOBS_Type *lobs)
+{
+    lobs->STREAMCTRL |= LOBS_STREAMCTRL_FULL_CLEAR_MASK;
+}
+
+/**
+ * @brief lobs deinit
+ *
+ * @param[in] lobs LOBS base address
+ */
+void lobs_deinit(LOBS_Type *lobs);
+
+/**
+ * @brief lobs control config
+ *
+ * @param[in] lobs LOBS base address
+ * @param[in] config control config structure pointer
+ */
+void lobs_ctrl_config(LOBS_Type *lobs, lobs_ctrl_config_t *config);
+
+/**
+ * @brief lobs two group mode config
+ *
+ * @param[in] lobs LOBS base address
+ * @param[in] group one of the two group, @ref lobs_two_group_sel_t
+ * @param[in] config two group mode config structure pointer
+ */
+void lobs_two_group_mode_config(LOBS_Type *lobs, lobs_two_group_sel_t group, lobs_two_group_mode_config_t *config);
+
+/**
+ * @brief lobs state config
+ *
+ * @param[in] lobs LOBS base address
+ * @param[in] state one of state, @ref lobs_state_sel_t
+ * @param[in] config state config structure pointer
+ */
+void lobs_state_config(LOBS_Type *lobs, lobs_state_sel_t state, lobs_state_config_t *config);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_LOBS_DRV_H */

+ 2 - 2
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_mbx_drv.h

@@ -57,7 +57,7 @@ static inline void mbx_set_bus_access_response(MBX_Type *ptr, mbx_bus_access_res
  * @param[in] ptr MBX base address
  * @param[in] mask Mask of interrupts to be enabled
  */
-static inline void mbx_enable_intr(MBX_Type *ptr, uint8_t mask)
+static inline void mbx_enable_intr(MBX_Type *ptr, uint32_t mask)
 {
     ptr->CR |= mask;
 }
@@ -68,7 +68,7 @@ static inline void mbx_enable_intr(MBX_Type *ptr, uint8_t mask)
  * @param[in] ptr MBX base address
  * @param[in] mask Mask of interrupts to be disabled
  */
-static inline void mbx_disable_intr(MBX_Type *ptr, uint8_t mask)
+static inline void mbx_disable_intr(MBX_Type *ptr, uint32_t mask)
 {
     ptr->CR &= ~mask;
 }

+ 61 - 27
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_mcan_drv.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 HPMicro
+ * Copyright (c) 2023-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -26,19 +26,20 @@ extern "C" {
 
 enum {
     status_mcan_filter_index_out_of_range = MAKE_STATUS(status_group_mcan, 0),
-    status_mcan_rxfifo_empty,
-    status_mcan_rxfifo_full,
-    status_mcan_txbuf_full,
-    status_mcan_txfifo_full,
-    status_mcan_rxfifo0_busy,
-    status_mcan_rxfifo1_busy,
-    status_mcan_txbuf_index_out_of_range,
-    status_mcan_rxbuf_index_out_of_range,
-    status_mcan_rxbuf_empty,
-    status_mcan_tx_evt_fifo_empty,
-    status_mcan_timestamp_not_exist,
-    status_mcan_ram_out_of_range,
-    status_mcan_timeout,
+    status_mcan_rxfifo_empty = MAKE_STATUS(status_group_mcan, 1),
+    status_mcan_rxfifo_full = MAKE_STATUS(status_group_mcan, 2),
+    status_mcan_txbuf_full = MAKE_STATUS(status_group_mcan, 3),
+    status_mcan_txfifo_full = MAKE_STATUS(status_group_mcan, 4),
+    status_mcan_rxfifo0_busy = MAKE_STATUS(status_group_mcan, 5),
+    status_mcan_rxfifo1_busy = MAKE_STATUS(status_group_mcan, 6),
+    status_mcan_txbuf_index_out_of_range = MAKE_STATUS(status_group_mcan, 7),
+    status_mcan_rxbuf_index_out_of_range = MAKE_STATUS(status_group_mcan, 8),
+    status_mcan_rxbuf_empty = MAKE_STATUS(status_group_mcan, 9),
+    status_mcan_tx_evt_fifo_empty = MAKE_STATUS(status_group_mcan, 10),
+    status_mcan_timestamp_not_exist = MAKE_STATUS(status_group_mcan, 11),
+    status_mcan_ram_out_of_range = MAKE_STATUS(status_group_mcan, 12),
+    status_mcan_timeout = MAKE_STATUS(status_group_mcan, 13),
+    status_mcan_invalid_bit_timing = MAKE_STATUS(status_group_mcan, 14),
 };
 
 /**
@@ -646,6 +647,15 @@ typedef struct mcan_timeout_config_struct {
     uint16_t timeout_period;            /*!< Timeout period */
 } mcan_timeout_config_t;
 
+/**
+ * @brief MCAN Transmitter Delay Compensation Configuration
+ */
+typedef struct mcan_tdc_config_t {
+    uint8_t ssp_offset;                 /*!< SSP offset */
+    uint8_t filter_window_length;       /*!< Filter Window Length */
+} mcan_tdc_config_t;
+
+
 /**
  * @brief MCAN Configuration Structure
  */
@@ -678,7 +688,7 @@ typedef struct mcan_config_struct {
     bool enable_tdc;                                /*!< Enable transmitter delay compensation */
     bool enable_restricted_operation_mode;          /*!< Enable Restricted Operation Mode: Receive only */
     bool disable_auto_retransmission;               /*!< Disable auto retransmission */
-    uint8_t padding[2];
+    mcan_tdc_config_t tdc_config;                   /*!< Transmitter Delay Compensation Configuration */
     mcan_internal_timestamp_config_t timestamp_cfg; /*!< Internal Timestamp Configuration */
     mcan_tsu_config_t tsu_config;                   /*!< TSU configuration */
     mcan_ram_config_t ram_config;                   /*!< MCAN RAM configuration */
@@ -734,15 +744,6 @@ typedef struct mcan_protocol_status {
     bool in_error_passive_state;                /*!< Node is in error passive state */
 } mcan_protocol_status_t;
 
-/**
- * @brief MCAN Transmitter Delay Compensation Configuration
- */
-typedef struct mcan_tdc_config_t {
-    uint8_t ssp_offset;                 /*!< SSP offset */
-    uint8_t filter_window_length;       /*!< Filter Window Length */
-} mcan_tdc_config_t;
-
-
 /**
  * @brief MCAN Message Storage Indicator Types
  */
@@ -987,7 +988,7 @@ static inline void mcan_enable_write_to_prot_config_registers(MCAN_Type *ptr)
 }
 
 /**
- * @brief Disalbe Write Access to Protected Configuration Registers
+ * @brief Disable Write Access to Protected Configuration Registers
  * @param [in] ptr MCAN base
  */
 static inline void mcan_disable_write_to_prot_config_registers(MCAN_Type *ptr)
@@ -1339,6 +1340,27 @@ static inline void mcan_send_add_request(MCAN_Type *ptr, uint32_t index)
     ptr->TXBAR = (1UL << index);
 }
 
+/**
+ * @brief Request several transmission via specified TXBUF/FIFO Bit masks
+ *        MCAN IP will transmit data in the buffer if corresponding bit in index_bitmask is asserted
+ * @param [in] ptr MCAN Base
+ * @param [in] index_bitmask TXFIFO/BUF bit masks
+ */
+static inline void mcan_send_add_multiple_requests(MCAN_Type *ptr, uint32_t index_bitmask)
+{
+    ptr->TXBAR = index_bitmask;
+}
+
+/**
+ * @brief Cancel the TXBUF Send request
+ * @param [in] ptr MCAN Base
+ * @param [in] index TXBUF index
+ */
+static inline void mcan_cancel_tx_buf_send_request(MCAN_Type *ptr, uint32_t index)
+{
+    ptr->TXBCR = (1UL << index);
+}
+
 /**
  * @brief Check whether the Transmission completed via specified TXBUF/TXFIFO
  * @param [in] ptr MCAN base
@@ -1685,6 +1707,18 @@ hpm_stat_t mcan_read_tx_evt_fifo(MCAN_Type *ptr, mcan_tx_event_fifo_elem_t *tx_e
  */
 hpm_stat_t mcan_transmit_blocking(MCAN_Type *ptr, mcan_tx_frame_t *tx_frame);
 
+/**
+ * @brief Request TXFIFO and fill data into TXFIFO
+ * @note This API can be used to prepare the data for several CAN frames prior to transmission.
+ *       After this operation, software can call `mcan_send_add_request(ptr, *fifo_index)` API to trigger a transmission
+ *       or call `mcan_send_add_requests(ptr, fifo_index_masks)` to trigger several transmissions
+ * @param [in] ptr MCAN base
+ * @param [in] tx_frame CAN Transmit Message buffer
+ * @param [out] fifo_index The index of the element in FIFO assigned to the tx_frame
+ * @return status_success if no errors reported
+ */
+hpm_stat_t mcan_request_and_fill_txfifo(MCAN_Type *ptr, mcan_tx_frame_t *tx_frame, uint32_t *fifo_index);
+
 /**
  * @brief Transmit CAN message via TX FIFO in non-blocking way
  * @param [in] ptr MCAN base
@@ -1723,7 +1757,7 @@ hpm_stat_t mcan_receive_from_buf_blocking(MCAN_Type *ptr, uint32_t index, mcan_r
 hpm_stat_t mcan_receive_from_fifo_blocking(MCAN_Type *ptr, uint32_t fifo_index, mcan_rx_message_t *rx_frame);
 
 /**
- * @brief Get Timstamp from MCAN TX Event
+ * @brief Get Timestamp from MCAN TX Event
  * @param [in] ptr MCAN base
  * @param [in] tx_evt TX Event Element
  * @param [out] timestamp Timestamp value
@@ -1736,7 +1770,7 @@ hpm_stat_t mcan_get_timestamp_from_tx_event(MCAN_Type *ptr,
                                             mcan_timestamp_value_t *timestamp);
 
 /**
- * @brief Get Timstamp from MCAN RX frame
+ * @brief Get Timestamp from MCAN RX frame
  * @param [in] ptr MCAN base
  * @param [in] rx_msg Received message
  * @param [out] timestamp Timestamp value

+ 726 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_mtg_drv.h

@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_MMC_DRV_H
+#define HPM_MMC_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_mtg_regs.h"
+/**
+ * @brief MTG driver APIs
+ * @defgroup mtg_interface MTG driver APIs
+ * @ingroup motor_interfaces
+ * @{
+ */
+
+/**
+ * @brief define the struct of mtg lock values
+ *
+ */
+typedef struct mtg_result {
+    int32_t rev; /* revolution */
+    uint32_t pos; /* postion */
+    int32_t vel; /* velocity */
+    int32_t acc; /* acceleration */
+    uint32_t time_stamp; /* time stamp */
+} mtg_lock_value_t;
+
+/**
+ * @brief define the enum of the postion of the observed object
+ */
+typedef enum mtg_evnet_object_postion {
+    event_source_before_filter = 1 << 0, /* before filter, also treat as input of mtg */
+    event_source_filter_output = 1 << 1, /* after filter, also treat as input of mtg's time compensation module */
+    event_source_tra0_output = 1 << 2, /* output of mtg's trajectory predictor0 */
+    event_source_tra1_output = 1 << 3, /* output of mtg's trajectory predictor1 */
+} mtg_evnet_object_postion_t;
+
+/**
+ * @brief define the enum of the observed object
+ */
+typedef enum mtg_event_object {
+    event_object_rev_pos = 1, /* location, revolution and position */
+    event_object_vel = 2, /* velocity */
+    event_object_acc = 4, /* acceleration */
+    event_object_pos = 8, /* postion, ignore revolution */
+} mtg_event_object_t;
+
+/**
+ * @brief define the enum of the event detection mode
+ */
+typedef enum mtg_event_mode {
+    event_mode_across = 1, /* across mode, change from greater than to less than, or opposite */
+    event_mode_hold = 2, /* hold mode, maintain within a range for a period of time */
+    event_mode_over_protect = 4, /* over protect mode, greater than or less than */
+    event_mode_time_match = 8, /* time match mode, when the synt's cnt value is equal to the preset */
+} mtg_event_mode_t;
+
+/**
+ * @brief define the enum of the event detection direction
+ */
+typedef enum mtg_event_dir {
+    event_dir_negative = 0,
+    event_dir_positive = 1,
+    event_dir_both = 2,
+} mtg_event_dir_t;
+
+/**
+ * @brief define the enum of the event detection direction calculation mode
+ */
+typedef enum mtg_event_dir_mode {
+    event_dir_mode_dy = 0, /* use first derivative of object */
+    event_dir_mode_y1_y0 = 1, /* use difference of current and previous */
+} mtg_event_dir_mode_t;
+
+/**
+ * @brief define the enum of the event detection over protect mode
+ */
+typedef enum mtg_event_over_mode_cmp {
+    event_over_cmp_mode_smaller = 0,
+    event_over_cmp_mode_bigger = 1,
+} mtg_event_over_mode_cmp_t;
+
+/**
+ * @brief define the enum of the event trigger number
+ */
+typedef enum mtg_event_trig_num {
+    event_trig_once = 0, /* event can only be triggered once */
+    event_trig_repeat = 1, /* event can be triggered multiple times */
+} mtg_event_trig_num_t;
+
+/**
+ * @brief define the struct of the event setup parameter
+ */
+typedef struct mtg_event_param {
+    bool enable;
+    bool irq_en; /* enable or disable the event irq */
+    mtg_event_object_t obj;
+    mtg_evnet_object_postion_t obj_postion;
+    mtg_event_mode_t mode;
+    mtg_event_dir_t dir;
+    mtg_event_dir_mode_t dir_mode;
+    mtg_event_over_mode_cmp_t cmp_mode;
+    mtg_event_trig_num_t trig_num;
+
+    /* union struct of event presets registers, different meaning when different event mode */
+    union {
+        struct {
+            uint32_t cross_value_h; /* the high 32bit of cross_value, only need set when object is ${event_object_rev_pos} */
+            uint32_t cross_value_l; /* the low 32bit of cross_value */
+        } cross_param;
+        struct {
+            uint32_t hold_value_h; /* the high 32bit of hold_value, only need set when object is ${event_object_rev_pos} */
+            uint32_t hold_value_l; /* the low 32bit of hold_value */
+            uint32_t error_limit; /* the range is between ${hold value - error_limit} and ${hold value + error_limit} */
+            uint32_t hold_clock_cnt; /* the event will be triggered when match the hold value and error_limit and last for &{hold_clock_cnt} clocks */
+        } hold_param;
+        struct {
+            uint32_t limit_value_h; /* the high 32bit of limit_value */
+            uint32_t limit_value_l; /* the low 32bit of limit_value */
+        } over_protect_param;
+        struct {
+            uint32_t clock_count; /* the event will be triggered when synt clock match the value */
+        } time_param;
+        uint32_t preset[4];
+    } preset;
+} mtg_event_param_t;
+
+/*
+ * @brief define the struct of the trajectory predictor limit
+ */
+typedef struct mtg_tra_limit_param {
+    bool vel_step_limit_en; /* velocity step limit enable, when enable, the velocity variation per clock will be limited by vel_step_max and vel_step_min */
+    uint32_t vel_step_max; /* velocity step limit value max */
+    uint32_t vel_step_min;  /* velocity step limit value min */
+    bool pos_step_limit_en; /* postion step limit enable, when enable, the postion variation per clock will be limited by pos_step_max and pos_step_min */
+    uint32_t pos_step_max; /* postion step limit value max */
+    uint32_t pos_step_min; /* postion step limit value min */
+} mtg_tra_limit_param_t;
+
+/**
+ * @brief define the enum of the software force one way mode
+ */
+typedef enum mtg_software_force_one_way_mode {
+    sw_force_negative = 0,
+    sw_force_positive = 1,
+} mtg_software_force_one_way_mode_t;
+
+/**
+ * @brief define the enum of the hardware force one way mode
+ */
+typedef enum vel_one_way_mode {
+    bigger_or_eq_zero = 0,
+    smaller_or_eq_zero = 1,
+} vel_one_way_mode_t;
+
+/**
+ * @brief define the struct of the hardware force one way mode
+ */
+typedef struct mtg_hardware_force_one_way_mode {
+    uint32_t vel_limit_p;
+    uint32_t vel_limit_n;
+} mtg_hardware_force_one_way_mode_t;
+
+/**
+ * @brief define the enum of the filter initialization mode
+ */
+typedef enum mtg_filter_rev_init_mode {
+    rev_init_mode_from_first_input_value = 0, /* the first input value will be used by the mtg filter to initialize the filter */
+    rev_init_mode_from_register = 1, /* the value in the register will be used by the mtg filter to initialize the filter */
+} mtg_filter_rev_init_mode_t;
+
+/**
+ * @brief define the enum of the filter judge mode
+ * It affects the judgment conditions for changes in the number of revolution
+ */
+typedef enum mtg_filter_rev_judge_mode {
+    mtg_rev_judge_mode_new_sub_old = 0,
+    mtg_rev_judge_mode_encoder_lines = 1,
+} mtg_filter_rev_judge_mode_t;
+
+/**
+ * @brief define the enum of the filter ff mode
+ */
+typedef enum mtg_filter_ff_mode {
+    mtg_filter_ff_mode_from_register = 0,
+    mtg_filter_ff_mode_from_input = 1,
+} mtg_filter_ff_mode_t;
+
+typedef struct mtg_filter_param {
+    bool enable; /* filter enable */
+    bool ff_en; /* filter feedforward enable */
+    bool init_en; /* filter first value initialization enable */
+    bool err_bypass_en; /* filter error bypass enable. when difference between filter input and output beyond the limit, filter output will be bypassed  */
+    bool err_init; /* filter error reset enable. when difference between filter input and output beyond the limit, the filter will reset */
+    bool timeout_en; /* filter timeout enable */
+    bool err_bypass_i_f_en;
+    bool err_bypass_f_i_en;
+    bool multi_err_irq_en;
+    bool acceleration_en; /* filter acceleration enable. when enable, the filter will output acceleration value */
+    mtg_filter_rev_init_mode_t rev_ini_mode;
+    mtg_filter_rev_judge_mode_t rev_judge_mode;
+    mtg_filter_ff_mode_t ff_mode;
+    int32_t rev_init_value; /* the initial value of revolution. only used when init_en == true */
+    int32_t vel_init_value; /* the initial value of velocity. only used when init_en == true */
+    int32_t acc_init_value; /* the initial value of acceleration. only used when init_en == true */
+    uint32_t pos_init_value; /* the initial value of postion. only used when init_en == true */
+    uint32_t filter_mot_sel;
+    uint32_t filter_stage_sel;
+    uint32_t filter_time_constant_tp;
+    uint32_t filter_time_constant_tz;
+    uint32_t filter_time_constant_tz_1;
+    uint32_t filter_zero_tz_sel;
+    uint32_t filter_gain;
+    uint32_t filter_stage_shift[2];
+    uint32_t filter_param_shift;
+    uint32_t filter_time_shift;
+    uint32_t filter_ff_shift;
+    uint32_t filter_error_limit_l;
+    uint32_t filter_error_limit_h;
+} mtg_filter_param_t;
+
+/**
+ * @brief define the enum of the trajectory predictor time input source
+ */
+typedef enum mtg_time_input_source {
+    mtg_time_input_from_filter = 1, /* the value in the filter will be used */
+    mtg_time_input_from_input = 2, /* the value in the input will be used */
+} mtg_time_input_source_t;
+
+/**
+ * @brief define the struct of the trajectory predictor time initialization
+ */
+typedef struct mtg_time_init_param {
+    bool enable;
+    uint32_t adjust_value; /* time compensation clocks */
+    uint8_t index;
+    mtg_time_input_source_t source;
+} mtg_time_init_param_t;
+
+/**
+ * @brief define the struct of the trajectory predictor timeout
+ */
+typedef struct mtg_timeout_param {
+    bool enable;
+    uint32_t timeout_clock_count;
+} mtg_timeout_param_t;
+
+/**
+ * @brief define the enum of the trajectory predictor link event
+ * link the trigger source and the cmd object, it describes the
+ * trigger source
+ */
+typedef enum mtg_link_cfg {
+    link_event0 = 0,
+    link_event1 = 1,
+    link_event2 = 2,
+    link_event3 = 3,
+    link_hw_trigger = 4,
+    link_sw_trigger = 5,
+    link_event_timeout = 6,
+} mtg_link_cfg_t;
+
+/**
+ * @brief define the enum of the trajectory predictor command object
+ */
+typedef enum {
+    cmd_object_rev = 1 << 0,
+    cmd_object_pos = 1 << 1,
+    cmd_object_vel = 1 << 2,
+    cmd_object_acc = 1 << 3,
+    cmd_object_jer = 1 << 4,
+} mtg_tra_cmd_object_t;
+
+/**
+ * @brief define the enum of the trajectory predictor command mode
+ */
+typedef enum {
+    cmd_mode_new_value = 0, /* when cmd exec, the preset value will replace the old value */
+    cmd_mode_old_delta = 1, /* when cmd exec, the preset value will be added to the old value */
+} mtg_link_cmd_mode_t;
+
+/**
+ * @brief define the struct of the trajectory shift struct
+ */
+typedef struct mtg_tra_shift {
+    uint8_t jerk_shift;
+    uint8_t acc_shift;
+    uint8_t vel_shift;
+} mtg_tra_shift_t;
+
+/**
+ * @brief define the struct of the trajectory predictor command
+ */
+typedef struct mtg_tra_cmd_cfg {
+    uint8_t index;
+    uint32_t object; /* cmd object, see ${mtg_tra_cmd_object_t} */
+    mtg_link_cmd_mode_t mode;
+    uint32_t rev_preset;
+    uint32_t pos_preset;
+    uint32_t vel_preset;
+    uint32_t acc_preset;
+    uint32_t jer_preset;
+} mtg_tra_cmd_cfg_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief MTG get trajectory predictor control register value
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @retval control register value
+ */
+static inline uint32_t mtg_get_tra_control_status(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    return base->TRA[tra_index].CONTROL;
+}
+
+/**
+ * @brief MTG get trajectory predictor commond control register value
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @param [in] cmd_index - trajectory predicotr command index
+ * @retval control register value
+ */
+static inline uint32_t mtg_get_tra_cmd_control_status(MTG_Type *base, uint8_t tra_index, uint8_t cmd_index)
+{
+    assert((tra_index < 2) && (cmd_index < 4));
+    return base->TRA[tra_index].CMD[cmd_index].CONTROL;
+}
+
+/**
+ * @brief MTG trigger trajectory predictor lock current values
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ */
+static inline void mtg_trig_tra_lock(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    base->TRA[tra_index].CONTROL |= MTG_TRA_CONTROL_SW_LOCK_SET(1);
+}
+
+/**
+ * @brief MTG clear trajectory predictor lock status
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ */
+static inline void mtg_clear_tra_lock(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    base->TRA[tra_index].CONTROL &= ~MTG_TRA_CONTROL_SW_LOCK_MASK;
+}
+
+/**
+ * @brief MTG get trajectory predictor revolution lock value
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @retval trajectory predictor revolution value
+ */
+static inline int32_t mtg_get_tra_rev_lock_value(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    return base->TRA[tra_index].LOCK_REV;
+}
+
+/**
+ * @brief MTG get trajectory predictor postion lock value
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @retval trajectory predictor postion value
+ */
+static inline uint32_t mtg_get_tra_pos_lock_value(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    return base->TRA[tra_index].LOCK_POS;
+}
+
+/**
+ * @brief MTG get trajectory predictor velocity lock value
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @retval trajectory predictor velocity value
+ */
+static inline int32_t mtg_get_tra_vel_lock_value(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    return base->TRA[tra_index].LOCK_VEL;
+}
+
+/**
+ * @brief MTG get trajectory predictor acceleration lock value
+ * @param [in] base - MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @retval trajectory predictor acceleration value
+ */
+static inline int32_t mtg_get_tra_acc_lock_value(MTG_Type *base, uint8_t tra_index)
+{
+    assert(tra_index < 2);
+    return base->TRA[tra_index].LOCK_ACC;
+}
+
+/**
+ * @brief MTG setup filter error bypass limit
+ * @param [in] base MTG base address
+ * @param [in] limit - bypass limit
+ */
+static inline void mtg_filter_set_err_bypass_limit(MTG_Type *base, uint32_t limit)
+{
+    base->FILTER_ERROR_LIMIT_H = limit;
+}
+
+/**
+ * @brief MTG setup hardware switch from bypass status to filter status's limit
+ *        When the difference between input and filter's pos result is smaller than the limit,
+ *        the filter will use the filter's result inside of the input.
+ * @param [in] base MTG base address
+ * @param [in] param - filter params
+ */
+static inline void mtg_filter_set_bypass_switch_filter_limit(MTG_Type *base, uint32_t limit)
+{
+    base->FILTER_ERROR_LIMIT_L = limit;
+}
+
+/**
+ * @brief MTG enable filter error bypass
+ *        When difference between input and filter's pos result is bigger than the limit,
+ *        the filter output will be bypass and input will be output to the filter's port.
+ * @param [in] base MTG base address
+ * @param [in] limit - bypass limit
+ */
+static inline void mtg_filter_enable_bypass(MTG_Type *base)
+{
+    base->FILTER_CONTROL |= MTG_FILTER_CONTROL_ERR_BYPASS_F_I_EN_SET(1);
+    base->FILTER_CONTROL |= MTG_FILTER_CONTROL_ERR_BYPASS_EN_SET(1);
+}
+
+/**
+ * @brief MTG disable filter error bypass
+ *        When difference between input and filter's pos result is bigger than the limit,
+ *        the filter output will be bypass and input will be output to the filter's port.
+ * @param [in] base MTG base address
+ * @param [in] limit - bypass limit
+ */
+static inline void mtg_filter_disable_bypass(MTG_Type *base)
+{
+    base->FILTER_CONTROL &= ~MTG_FILTER_CONTROL_ERR_BYPASS_F_I_EN_MASK;
+    base->FILTER_CONTROL &= ~MTG_FILTER_CONTROL_ERR_BYPASS_EN_MASK;
+}
+
+/**
+ * @brief MTG reset filter enable error reset
+ * @param [in] base MTG base address
+ */
+static inline void mtg_filter_enable_reset_init(MTG_Type *base)
+{
+    base->FILTER_CONTROL |= MTG_FILTER_CONTROL_ERR_INI_SET(1);
+}
+
+/**
+ * @brief MTG reset filter disable error reset
+ * @param [in] base MTG base address
+ */
+static inline void mtg_filter_disable_reset_init(MTG_Type *base)
+{
+    base->FILTER_CONTROL &= ~MTG_FILTER_CONTROL_ERR_INI_MASK;
+}
+
+/**
+ * @brief MTG enable hardware switch from bypass status to filter status's limit
+ *        When the difference between input and filter's pos result is smaller than the limit,
+ *        the filter will use the filter's result inside of the input.
+ *        The switch result can be defined by reading the switch status register.
+ * @param [in] base MTG base address
+ * @param [in] param - filter params
+ */
+static inline void mtg_filter_switch_filter_result(MTG_Type *base)
+{
+    base->FILTER_CONTROL |= MTG_FILTER_CONTROL_ERR_BYPASS_I_F_EN_SET(1);
+}
+
+/**
+ * @brief MTG disable hardware switch from bypass status to filter status's limit
+ *        When the difference between input and filter's pos result is smaller than the limit,
+ *        the filter will use the filter's result inside of the input.
+ *        The switch result can be defined by reading the switch status register.
+ * @param [in] base MTG base address
+ * @param [in] param - filter params
+ */
+static inline void mtg_filter_stop_auto_switch_filter_result(MTG_Type *base)
+{
+    base->FILTER_CONTROL &= ~MTG_FILTER_CONTROL_ERR_BYPASS_I_F_EN_MASK;
+}
+
+/**
+ * @brief MTG setup hardware switch from bypass status to filter status's limit
+ *        When the difference between input and filter's pos result is smaller than the limit,
+ *        the filter will use the filter's result inside of the input.
+ * @param [in] base - MTG base address
+ * @retval bypass status
+ */
+static inline bool mtg_get_err_bypass_status(MTG_Type *base)
+{
+    return MTG_FILTER_CONTROL_ERR_BYPASS_STATUS_GET(base->FILTER_CONTROL) == 0 ? true : false;
+}
+
+/**
+ * @brief MTG set time0 adjust value
+ * @param [in] base - MTG base address
+ * @param [in] value - adjust value
+ */
+static inline void mtg_set_time0_adjust_value(MTG_Type *base, uint32_t value)
+{
+    base->FILTER_TIME0_SW_ADJUST = value;
+}
+
+/**
+ * @brief MTG set time1 adjust value
+ * @param [in] base - MTG base address
+ * @param [in] value - adjust value
+ */
+static inline void mtg_set_time1_adjust_value(MTG_Type *base, uint32_t value)
+{
+    base->FILTER_TIME1_SW_ADJUST = value;
+}
+
+/**
+ * @brief MTG set time shift value
+ * @param [in] base - MTG base address
+ * @param [in] index - tra index
+ * @param [in] jer_shift - jerk shift
+ * @param [in] acc_shift - acceleration shift
+ * @param [in] vel_shift - velocity shift
+ */
+static inline void mtg_tra_set_shift(MTG_Type *base, uint8_t index, uint8_t jer_shift, uint8_t acc_shift, uint8_t vel_shift)
+{
+    assert(index < 2);
+    base->TRA[index].SHIFT = MTG_TRA_SHIFT_JER_SHIFT_SET(jer_shift) |
+                             MTG_TRA_SHIFT_ACC_SHIFT_SET(acc_shift) |
+                             MTG_TRA_SHIFT_VEL_SHIFT_SET(vel_shift);
+}
+
+/**
+ * @brief MTG global reset
+ * @param [in] base - MTG base address
+ */
+static inline void mtg_set_global_reset(MTG_Type *base)
+{
+    base->SW_GLB_RESET = 1;
+}
+
+/**
+ * @brief MTG stop global reset
+ */
+static inline void mtg_stop_global_reset(MTG_Type *base)
+{
+    base->SW_GLB_RESET = 0;
+}
+
+/**
+ * @brief MTG predictor get lock result
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory predictor index
+ * @param [out] para mtg_lock_value_t
+ */
+void mtg_get_tra_lock_result(MTG_Type *base, uint8_t tra_index, mtg_lock_value_t *para);
+
+/**
+ * @brief MTG setup event params
+ * @param [in] base MTG base address
+ * @param [in] event_index - event index
+ * @param [in] param - event params
+ * @param [out] setup status
+ */
+hpm_stat_t mtg_setup_event(MTG_Type *base, uint8_t event_index, mtg_event_param_t *param);
+
+/**
+ * @brief MTG setup trajectory limit params
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory index
+ * @param [in] param - trajectory limit params
+ * @param [out] setup status
+ */
+hpm_stat_t mtg_setup_tra_limit(MTG_Type *base, uint8_t tra_index, mtg_tra_limit_param_t *param);
+
+/**
+ * @brief MTG setup trajectory software one_way mode
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory index
+ * @param [in] param - 0:force + , 1:force -
+ * @param [out] setup status
+ */
+void mtg_setup_tra_software_pos_one_way_mode(MTG_Type *base, uint8_t tra_index, mtg_software_force_one_way_mode_t param);
+
+/**
+ * @brief MTG setup trajectory hardware one_way mode
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory index
+ * @param [in] param - 0:force + , 1:force -
+ * @param [out] setup status
+ */
+void mtg_setup_tra_hardware_pos_one_way_mode(MTG_Type *base, uint8_t tra_index, mtg_hardware_force_one_way_mode_t *param);
+
+/**
+ * @brief MTG disable trajectory postion one_way mode
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory index
+ */
+void mtg_disable_tra_pos_one_way_mode(MTG_Type *base, uint8_t tra_index);
+
+/**
+ * @brief MTG setup trajectory velocity one_way mode
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory index
+ * @param [in] mode - 0:bigger_or_eq_zero , 1:smaller_or_eq_zero
+ */
+void mtg_setup_tra_vel_one_way(MTG_Type *base, uint8_t tra_index, vel_one_way_mode_t mode, bool enable);
+
+/**
+ * @brief MTG setup filter
+ * @param [in] base MTG base address
+ * @param [in] param - filter params
+ */
+void mtg_filter_get_default_filter_stage_param(mtg_filter_param_t *param);
+
+/**
+ * @brief MTG setup time compensation module
+ * @param [in] base MTG base address
+ * @param [in] param - time compensation params
+ */
+void mtg_setup_time(MTG_Type *base, mtg_time_init_param_t *param);
+
+/**
+ * @brief MTG setup filter
+ * @param [in] base MTG base address
+ * @param [in] param - filter params
+ */
+void mtg_setup_filter(MTG_Type *base, mtg_filter_param_t *param);
+
+/**
+ * @brief MTG setup timeout
+ * @param [in] base MTG base address
+ * @param [in] param - timeout params
+ */
+void mtg_setup_timeout(MTG_Type *base, mtg_timeout_param_t *param);
+
+/**
+ * @brief MTG link trigger source and trajectory command
+ * @param [in] base MTG base address
+ * @param [in] tra_index - trajectory index
+ * @param [in] link_cfg - link config
+ * @param [in] cmd_cfg - command config
+ */
+void mtg_setup_link_cfg(MTG_Type *base, uint8_t tra_index, mtg_link_cfg_t link_cfg, mtg_tra_cmd_cfg_t *cmd_cfg);
+
+/**
+ * @brief MTG software trigger trajectory command
+ * @param [in] base MTG base address
+ */
+void mtg_soft_event_trigger(MTG_Type *base);
+
+/**
+ * @brief Get default trajectory shift
+ * @param [out] cfg pointer to the tra shift var
+ */
+void mtg_get_default_tra_shift(mtg_tra_shift_t *cfg);
+
+/**
+ * @brief Get the event irq status
+ * @param [in] ptr the mtg base
+ * @param [in] idx the event index
+ */
+static inline bool mtg_get_irq_status(MTG_Type *ptr, uint8_t idx)
+{
+    return ((MTG_EVENT_CONTROL_EVENT_IRQ_GET(ptr->EVENT[idx].CONTROL) != 0) ? true : false);
+}
+
+/**
+ * @brief Clear the event irq status
+ * @param [in] ptr the mtg base
+ * @param [in] idx the event index
+ */
+static inline void mtg_clear_irq_status(MTG_Type *ptr, uint8_t idx)
+{
+    ptr->EVENT[idx].CONTROL |= MTG_EVENT_CONTROL_EVENT_IRQ_MASK;
+}
+
+/**
+ * @brief calculate the vel preset
+ * @param [in] base MTG base address
+ * @param [in] clock MTG clock name
+ * @param [in] tra_index - trajectory index
+ * @param [in] speed - speed in r/s
+ */
+int32_t mtg_calc_vel_preset(MTG_Type *base, clock_name_t clock, uint8_t tra_index, float speed);
+
+/**
+ * @brief calculate the acc preset
+ * @param [in] base MTG base address
+ * @param [in] clock MTG clock name
+ * @param [in] tra_index - trajectory index
+ * @param [in] acc - acc in r/s2
+ */
+int32_t mtg_calc_acc_preset(MTG_Type *base, clock_name_t clock, uint8_t tra_index, float acc);
+
+/**
+ * @brief MTG link trigger source and trajectory command
+ * @param [in] base MTG base address
+ * @param [in] clock MTG clock name
+ * @param [in] tra_index - trajectory index
+ * @param [in] jer - jer in r/s3
+ */
+int32_t mtg_calc_jer_preset(MTG_Type *base, clock_name_t clock, uint8_t tra_index, float jer);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_MTG_DRV_H */

+ 24 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pixelmux_drv.h

@@ -75,6 +75,16 @@ typedef enum {
     pixelmux_mipi_dsi0_sel_lcdc1
 } pixelmux_mipi_dsi0_select_t;
 
+/**
+ * @brief mipi dsi pixel data type
+ */
+typedef enum {
+    pixelmux_mipi_dsi_data_type_rgb565 = 0,
+    pixelmux_mipi_dsi_data_type_rgb666 = 3,
+    pixelmux_mipi_dsi_data_type_rgb666_packed = 4,
+    pixelmux_mipi_dsi_data_type_rgb888 = 5,
+} pixelmux_mipi_dsi_data_type_t;
+
 /**
  * @brief cam1 pixel data source
  */
@@ -226,6 +236,20 @@ void pixelmux_mipi_dsi0_data_source_enable(pixelmux_mipi_dsi0_select_t src);
  */
 void pixelmux_mipi_dsi0_data_source_disable(void);
 
+/**
+ * @brief set data type for mipi dsi1
+ *
+ * @param[in] type mipi dsi data type
+ */
+void pixelmux_mipi_dsi1_set_data_type(pixelmux_mipi_dsi_data_type_t type);
+
+/**
+ * @brief set data type for mipi dsi0
+ *
+ * @param[in] type mipi dsi data type
+ */
+void pixelmux_mipi_dsi0_set_data_type(pixelmux_mipi_dsi_data_type_t type);
+
 /**
  * @brief select pixel data source and enable for camera1
  *

+ 44 - 4
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_plb_drv.h

@@ -29,10 +29,30 @@
  *
  */
 typedef enum plb_chn {
-    plb_chn0 = 0,
-    plb_chn1 = 1,
-    plb_chn2 = 2,
-    plb_chn3 = 3,
+#ifdef PLB_TYPE_B_0
+    plb_chn0 = PLB_TYPE_B_0,
+#endif
+#ifdef PLB_TYPE_B_1
+    plb_chn1 = PLB_TYPE_B_1,
+#endif
+#ifdef PLB_TYPE_B_2
+    plb_chn2 = PLB_TYPE_B_2,
+#endif
+#ifdef PLB_TYPE_B_3
+    plb_chn3 = PLB_TYPE_B_3,
+#endif
+#ifdef PLB_TYPE_B_4
+    plb_chn4 = PLB_TYPE_B_4,
+#endif
+#ifdef PLB_TYPE_B_5
+    plb_chn5 = PLB_TYPE_B_5,
+#endif
+#ifdef PLB_TYPE_B_6
+    plb_chn6 = PLB_TYPE_B_6,
+#endif
+#ifdef PLB_TYPE_B_7
+    plb_chn7 = PLB_TYPE_B_7,
+#endif
 } plb_chn_t;
 
 /**
@@ -40,10 +60,30 @@ typedef enum plb_chn {
  *
  */
 typedef enum plb_type_a_lut_num {
+#ifdef PLB_TYPE_A_0
     plb_type_a_table0 = PLB_TYPE_A_0,
+#endif
+#ifdef PLB_TYPE_A_1
     plb_type_a_table1 = PLB_TYPE_A_1,
+#endif
+#ifdef PLB_TYPE_A_2
     plb_type_a_table2 = PLB_TYPE_A_2,
+#endif
+#ifdef PLB_TYPE_A_3
     plb_type_a_table3 = PLB_TYPE_A_3,
+#endif
+#ifdef PLB_TYPE_A_4
+    plb_type_a_table4 = PLB_TYPE_A_4,
+#endif
+#ifdef PLB_TYPE_A_5
+    plb_type_a_table5 = PLB_TYPE_A_5,
+#endif
+#ifdef PLB_TYPE_A_6
+    plb_type_a_table6 = PLB_TYPE_A_6,
+#endif
+#ifdef PLB_TYPE_A_7
+    plb_type_a_table7 = PLB_TYPE_A_7,
+#endif
 } plb_type_a_lut_num_t;
 
 /**

+ 13 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pllctlv2_drv.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 HPMicro
+ * Copyright (c) 2022-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -137,6 +137,18 @@ static inline void pllctlv2_set_pll_step_time(PLLCTLV2_Type *ptr, uint8_t pll, u
  */
 void pllctlv2_set_postdiv(PLLCTLV2_Type *ptr, uint8_t pll,  uint8_t div_index, uint8_t div_value);
 
+/**
+ * @brief Set the PLL via the low-level MFI, MFD and MFN
+ *        PLL frequency = REF CLOCK * (mfi + 1.0 * mfn / mfd)
+ * @param [in] ptr  PLLCTLV2 base
+ * @param [in] pll  PLL index
+ * @param [in] mfi  MFI value
+ * @param [in] mfn  MFN value
+ * @retval status_invalid_argument some parameters are invalid
+ * @retval status_success operation is successful
+ */
+hpm_stat_t pllctlv2_set_pll_with_mfi_mfn(PLLCTLV2_Type *ptr, uint8_t pll,  uint32_t mfi, uint32_t mfn);
+
 /**
  * @brief Initialize PLL to specified frequency
  *        Note: the specified PLL clock needs to be enabled before being configured

+ 366 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_ppi_drv.h

@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2024 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_PPI_DRV_H
+#define HPM_PPI_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_soc_ip_feature.h"
+#include "hpm_ppi_regs.h"
+
+/**
+ * @brief PPI driver APIs
+ * @defgroup ppi_interface PPI driver APIs
+ * @ingroup ppi_interfaces
+ * @{
+ */
+
+/**
+ * @brief cs pin idle polarity
+ *
+ */
+typedef enum {
+    ppi_cs_idle_pol_low = 0,
+    ppi_cs_idle_pol_high
+} ppi_cs_idle_polarity_t;    /**< ppi_cs_idle_polarity_t */
+
+/**
+ * @brief dm pin valid polarity
+ *
+ */
+typedef enum {
+    ppi_dm_valid_pol_high = 0,
+    ppi_dm_valid_pol_low
+} ppi_dm_valid_polarity_t;    /**< ppi_dm_valid_polarity_t */
+
+/**
+ * @brief ctrl pin polarity
+ *
+ */
+typedef enum {
+    ppi_ctrl_pol_low = 0,
+    ppi_ctrl_pol_high
+} ppi_ctrl_polarity_t;    /**< ppi_ctrl_polarity_t */
+
+/**
+ * @brief ctrl pin direction
+ *
+ */
+typedef enum {
+    ppi_ctrl_pin_dir_input = 0,
+    ppi_ctrl_pin_dir_output,
+} ppi_ctrl_pin_dir_t;    /**< ppi_ctrl_pin_dir_t */
+
+/**
+ * @brief clock pin output mode
+ *
+ */
+typedef enum {
+    ppi_clk_output_by_cmd_clk_output = 0,
+    ppi_clk_always_output
+} ppi_clk_output_mode_t;    /**< ppi_clk_output_mode_t */
+
+/**
+ * @brief irq mask
+ *
+ */
+typedef enum {
+    ppi_irq_tm_out_mask = PPI_IRQ_EN_IRQ_TMOUT_EN_MASK,
+} ppi_irq_mask_t;    /**< ppi_irq_mask_t */
+
+/**
+ * @brief port size
+ *
+ */
+typedef enum {
+    ppi_port_size_8bits = 0,
+    ppi_port_size_16bits,
+    ppi_port_size_32bits,
+} ppi_port_size_t;    /**< ppi_port_size_t */
+
+/**
+ * @brief cmd byte select
+ *
+ */
+typedef enum {
+    ppi_byte_sel_0_7_bits = 0,
+    ppi_byte_sel_8_15_bits,
+    ppi_byte_sel_16_23_bits,
+    ppi_byte_sel_24_31_bits
+} ppi_byte_sel_t;    /**< ppi_byte_sel_t */
+
+/**
+ * @brief cmd address and data function
+ *
+ */
+typedef enum {
+    ppi_ad_func_data = 0,
+    ppi_ad_func_addr
+} ppi_ad_func_t;    /**< ppi_ad_func_t */
+
+/**
+ * @brief cmd address and data pins direction
+ *
+ */
+typedef enum {
+    ppi_ad_pin_dir_output = 0,
+    ppi_ad_pin_dir_input
+} ppi_ad_pin_dir_t;    /**< ppi_ad_pin_dir_t */
+
+/**
+ * @brief clock pin config structure
+ *
+ */
+typedef struct {
+    uint8_t cycle_num;
+    uint8_t high_num;
+    uint8_t low_num;
+    ppi_clk_output_mode_t mode;
+    bool revert;
+} ppi_clk_pin_config_t;    /**< ppi_clk_pin_config_t */
+
+/**
+ * @brief cs pin config structure
+ *
+ */
+typedef struct {
+    ppi_port_size_t port_size;
+    uint16_t addr_start_high_12bits;    /* address space: 0xF8000000 ~ 0xFFFFFFFF */
+    uint16_t addr_end_high_12bits;      /* address space: 0xF8000000 ~ 0xFFFFFFFF */
+    uint16_t addr_mask;
+    bool sync_clk_en;
+    uint8_t sync_clk_sel;
+    uint8_t interval_cycle;
+    uint8_t rcmd_start0;
+    uint8_t rcmd_end0;
+    uint8_t rcmd_start1;
+    uint8_t rcmd_end1;
+    uint8_t wcmd_start0;
+    uint8_t wcmd_end0;
+    uint8_t wcmd_start1;
+    uint8_t wcmd_end1;
+#if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS
+    ppi_dm_valid_polarity_t dm_polarity;
+#endif
+} ppi_cs_pin_config_t;    /**< ppi_cs_pin_config_t */
+
+/**
+ * @brief cmd config structure
+ *
+ */
+typedef struct {
+    bool cs_pin_value;
+    bool clk_output;
+    uint8_t cmd_cycle;
+    ppi_ad_func_t ad_func_sel[4];
+    ppi_ad_pin_dir_t ad_pin_dir[4];
+    ppi_byte_sel_t byte_sel[4];
+    bool ctrl_pin_value[8];
+} ppi_cmd_config_t;    /**< ppi_cmd_config_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief set ppi software reset
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] reset true - software reset; false - normal work.
+ */
+static inline void ppi_set_reset(PPI_Type *ppi, bool reset)
+{
+    if (reset) {
+        ppi->GLB_CFG |= PPI_GLB_CFG_SOFT_RESET_MASK;
+    } else {
+        ppi->GLB_CFG &= ~PPI_GLB_CFG_SOFT_RESET_MASK;
+    }
+}
+
+/**
+ * @brief config cs pin work valid polarity
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] index cs pin index, value: 0 - 3
+ * @param[in] pol @ref ppi_cs_idle_polarity_t
+ */
+static inline void ppi_config_cs_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_cs_idle_polarity_t pol)
+{
+    assert(index < 4);
+    ppi->PAD_CFG = (ppi->PAD_CFG & ~(((1u << PPI_PAD_CFG_CS_IDLE_ST_SHIFT) << index))) | (((pol << PPI_PAD_CFG_CS_IDLE_ST_SHIFT) << index));
+}
+
+/**
+ * @brief config dm pin work polarity
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] index If has HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS feature, this is cs pin index, value: 0 - 3. Else, not use.
+ * @param[in] pol @ref ppi_dm_valid_polarity_t
+ */
+static inline void ppi_config_dm_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_dm_valid_polarity_t pol)
+{
+#if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS
+    assert(index < 4);
+    ppi->CS[index].CFG2 = (ppi->CS[index].CFG2 & ~PPI_CS_CFG2_DM_POLARITY_MASK) | PPI_CS_CFG2_DM_POLARITY_SET(pol);
+#else
+    (void)index;
+    if (pol == ppi_dm_valid_pol_high) {
+        ppi->PAD_CFG &= ~PPI_PAD_CFG_DM_PAD_POL_MASK;
+    } else {
+        ppi->PAD_CFG |= PPI_PAD_CFG_DM_PAD_POL_MASK;
+    }
+#endif
+}
+
+/**
+ * @brief config ctrl pin work polarity, output and input ctrl pin polarity has different meaning
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] index Ctrl pin index, value: 0 - 7
+ * @param[in] pol @ref ppi_ctrl_polarity_t
+ *   [1] Output: ppi_ctrl_pol_low is output the value in cmd; ppi_ctrl_pol_high is output reversed value in cmd.
+ *   [2] Input: ppi_ctrl_pol_low is input low valid; ppi_ctrl_pol_high is input high valid.
+ */
+static inline void ppi_config_ctrl_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_ctrl_polarity_t pol)
+{
+    assert(index < 8);
+    ppi->PAD_CFG = (ppi->PAD_CFG & ~(((1u << PPI_PAD_CFG_CTRL_PAD_POL_SHIFT) << index))) | (((pol << PPI_PAD_CFG_CTRL_PAD_POL_SHIFT) << index));
+}
+
+/**
+ * @brief set ctrl pin direction
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] index Ctrl pin index, value: 0 - 7
+ * @param[in] dir Ctrl pin direction, @ref ppi_ctrl_pin_dir_t
+ */
+static inline void ppi_set_ctrl_pin_dir(PPI_Type *ppi, uint8_t index, ppi_ctrl_pin_dir_t dir)
+{
+    assert(index < 8);
+    ppi->PAD_CFG = (ppi->PAD_CFG & ~(((1u << PPI_PAD_CFG_CTRL_PAD_OE_SHIFT) << index))) | (((dir << PPI_PAD_CFG_CTRL_PAD_OE_SHIFT) << index));
+}
+
+/**
+ * @brief config timeout
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] timeout_cnt timeout counter
+ * @param[in] enable true - enable; false - disable
+ */
+static inline void ppi_config_timeout(PPI_Type *ppi, uint16_t timeout_cnt, bool enable)
+{
+    ppi->TM_CFG = PPI_TM_CFG_TM_CFG_SET(timeout_cnt) | PPI_TM_CFG_TM_EN_SET(enable);
+}
+
+/**
+ * @brief set irq enable
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] mask irq mask, @ref ppi_irq_mask_t
+ */
+static inline void ppi_set_irq_enable(PPI_Type *ppi, uint32_t mask)
+{
+    ppi->IRQ_EN |= mask;
+}
+
+/**
+ * @brief set irq disable
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] mask irq mask, @ref ppi_irq_mask_t
+ */
+static inline void ppi_set_irq_disable(PPI_Type *ppi, uint32_t mask)
+{
+    ppi->IRQ_EN &= ~mask;
+}
+
+/**
+ * @brief get irq enable status
+ *
+ * @param[in] ppi PPI base address
+ * @retval irq enable status, @ref ppi_irq_mask_t
+ */
+static inline uint32_t ppi_get_irq_enable_status(PPI_Type *ppi)
+{
+    return ppi->IRQ_EN;
+}
+
+/**
+ * @brief get irq status
+ *
+ * @param[in] ppi PPI base address
+ * @retval irq status, @ref ppi_irq_mask_t
+ */
+static inline uint32_t ppi_get_irq_status(PPI_Type *ppi)
+{
+    return ppi->IRQ_STS;
+}
+
+/**
+ * @brief clear irq flag
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] mask irq mask, @ref ppi_irq_mask_t
+ */
+static inline void ppi_clear_irq_flag(PPI_Type *ppi, uint32_t mask)
+{
+    ppi->IRQ_STS = mask;
+}
+
+/**
+ * @brief set clk pin enable
+ *
+ * @param[in] ppi PPI base address
+ */
+static inline void ppi_set_clk_pin_enable(PPI_Type *ppi)
+{
+    ppi->CLKPIN_CFG |= PPI_CLKPIN_CFG_EN_MASK;
+}
+
+/**
+ * @brief set clk pin disable
+ *
+ * @param[in] ppi PPI base address
+ */
+static inline void ppi_set_clk_pin_disable(PPI_Type *ppi)
+{
+    ppi->CLKPIN_CFG &= ~PPI_CLKPIN_CFG_EN_MASK;
+}
+
+/**
+ * @brief config clock pin output
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] config clock pin config structure pointer, @ref ppi_clk_pin_config_t
+ */
+void ppi_config_clk_pin(PPI_Type *ppi, ppi_clk_pin_config_t *config);
+
+/**
+ * @brief config cs pin
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] index cs pin index, value: 0 - 3
+ * @param[in] config cs pin config structure pointer, @ref ppi_cs_pin_config_t
+ */
+void ppi_config_cs_pin(PPI_Type *ppi, uint8_t index, ppi_cs_pin_config_t *config);
+
+/**
+ * @brief config cmd
+ *
+ * @param[in] ppi PPI base address
+ * @param[in] index cmd index, value: 0 - 63
+ * @param[in] config cmd config structure pointer, @ref ppi_cmd_config_t
+ */
+void ppi_config_cmd(PPI_Type *ppi, uint8_t index, ppi_cmd_config_t *config);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_PPI_DRV_H */

+ 20 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pwm_drv.h

@@ -14,7 +14,7 @@
 /**
  * @brief PWM driver APIs
  * @defgroup pwm_interface PWM driver APIs
- * @ingroup io_interfaces
+ * @ingroup motor_interfaces
  * @{
  *
  */
@@ -94,6 +94,7 @@ typedef enum pwm_fault_source {
     pwm_fault_source_internal_3 = PWM_GCR_FAULTI3EN_MASK, /**< FAULTI3 */
     pwm_fault_source_external_0 = PWM_GCR_FAULTE0EN_MASK, /**< EXFAULTI0 */
     pwm_fault_source_external_1 = PWM_GCR_FAULTE1EN_MASK, /**< EXFAULTI1 */
+    pwm_fault_source_debug = PWM_GCR_DEBUGFAULT_MASK,   /**< Debug fault */
 } pwm_fault_source_t;
 
 /**
@@ -217,7 +218,9 @@ static inline void pwm_deinit(PWM_Type *pwm_x)
     pwm_x->FRCMD = 0;
     pwm_x->GCR = 0;
     pwm_x->SHCR = 0;
+#if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
     pwm_x->HRPWM_CFG = 0;
+#endif
     for (uint8_t i = 0; i < PWM_SOC_OUTPUT_TO_PWM_MAX_COUNT; i++) {
         pwm_x->PWMCFG[i] = 0;
     }
@@ -1000,6 +1003,22 @@ hpm_stat_t pwm_update_raw_cmp_edge_aligned(PWM_Type *pwm_x, uint8_t cmp_index,
 hpm_stat_t pwm_update_raw_cmp_central_aligned(PWM_Type *pwm_x, uint8_t cmp1_index,
                                        uint8_t cmp2_index, uint32_t target_cmp1, uint32_t target_cmp2);
 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
+
+/**
+ * @brief recovery hrpwm output
+ *
+ * @param pwm_x @ref PWM_Type PWM base address
+ */
+static inline void pwm_recovery_hrpwm_output(PWM_Type *pwm_x)
+{
+    pwm_x->HRPWM_CFG |= PWM_HRPWM_CFG_CAL_SW_EN_MASK;
+    pwm_x->ANA_CFG0 |= PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
+    pwm_x->ANA_CFG0 &= ~PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
+    pwm_x->ANA_CFG0 |= PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
+    pwm_x->ANA_CFG0 &= ~PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
+    pwm_x->HRPWM_CFG &= ~PWM_HRPWM_CFG_CAL_SW_EN_MASK;
+}
+
 /**
  * @brief Enable high-precision pwm
  *

+ 1958 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_pwmv2_drv.h

@@ -0,0 +1,1958 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_PWMV2_DRV_H
+#define HPM_PWMV2_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_pwmv2_regs.h"
+#include "hpm_soc_feature.h"
+
+
+/**
+ * @brief PWM driver APIs
+ * @defgroup pwmv2_interface PWMV2 driver APIs
+ * @ingroup motor_interfaces
+ * @{
+ *
+ */
+#define PWM_UNLOCK_KEY (0xB0382607UL)
+#define PWM_CMP_UNABLE_OUTPUT_INDEX (16)
+
+/* IRQ enable bit mask */
+#define PWM_IRQ_FAULT PWM_IRQEN_FAULTIRQE_MASK
+#define PWM_IRQ_EX_RELOAD PWM_IRQEN_XRLDIRQE_MASK
+#define PWM_IRQ_HALF_RELOAD PWM_IRQEN_HALFRLDIRQE_MASK
+#define PWM_IRQ_RELOAD PWM_IRQEN_RLDIRQE_MASK
+#define PWM_IRQ_CMP(x) PWM_IRQEN_CMPIRQEX_SET((1 << x))
+
+/* PWM force output mask */
+#define PWM_FORCE_OUTPUT(pwm_index, force_output) \
+    (force_output << (pwm_index << 1))
+
+#define PWM_DUTY_CYCLE_FP_MAX ((1U << 24) - 1)
+
+#ifndef PWMV2_SOC_CAL_COUNT_MAX
+    #define PWMV2_SOC_CAL_COUNT_MAX 8
+#endif
+
+#define PWMV2_SHADOW_INDEX(x)  PWMV2_SHADOW_VAL_##x
+#define PWMV2_CMP_INDEX(x) PWMV2_CMP_VAL_WORK_##x
+#define PWMV2_CALCULATE_INDEX(x) PWMV2_CAL_##x
+#define PWMV2_CAL_SHADOW_OFFSET_ZERO    (31)
+
+typedef enum {
+    pwm_counter_0 = 0,
+    pwm_counter_1 = 1,
+    pwm_counter_2 = 2,
+    pwm_counter_3 = 3,
+} pwm_counter_t;
+
+typedef enum {
+    pwm_channel_0 = 0,
+    pwm_channel_1 = 1,
+    pwm_channel_2 = 2,
+    pwm_channel_3 = 3,
+    pwm_channel_4 = 4,
+    pwm_channel_5 = 5,
+    pwm_channel_6 = 6,
+    pwm_channel_7 = 7,
+} pwm_channel_t;
+
+
+typedef enum {
+    pwm_reload_update_on_shlk = 0,
+    pwm_reload_update_on_compare_point = 1,
+    pwm_reload_update_on_reload = 2,
+    pwm_reload_update_on_trigger = 3,
+} pwm_reload_update_time_t;
+
+
+/**
+ * @brief pwm output type
+ *
+ */
+typedef enum {
+    pwm_force_output_0 = 0, /**< output 0 */
+    pwm_force_output_1 = 1, /**< output 1 */
+    pwm_force_output_high_z = 2, /**< output */
+    pwm_force_output_no_force = 3,
+} pwm_force_mode_t;
+
+typedef enum {
+    pwm_fault_output_0 = 0, /**< output 0 */
+    pwm_fault_output_1 = 1, /**< output 1 */
+    pwm_fault_output_high_z = 2, /**< output */
+} pwm_fault_mode_t;
+
+typedef enum {
+    pad_fault_active_low = 1,
+    pad_fault_active_high = 0,
+} pwm_fault_pad_polarity_t;
+
+typedef enum {
+    pwm_shadow_register_output_polarity_on_shlk = 0,
+    pwm_shadow_register_output_polarity_on_reload = 1,
+} pwm_shadow_register_output_polarity_t;
+
+typedef enum {
+    pwm_force_update_shadow_immediately = 0,  /**< after software set shlk bit of shlk register */
+    pwm_force_update_shadow_at_cmp_point = 1,
+    pwm_force_update_shadow_at_reload = 2,     /**< immediately after the register being modified */
+    pwm_force_update_shadow_none = 3,         /**< after SHSYNCI assert */
+} pwm_force_shadow_trigger_t;
+
+typedef enum {
+    pwm_force_immediately = 0,  /**< after software set shlk bit of shlk register */
+    pwm_force_at_reload = 1,
+    pwm_force_at_trigmux = 2,
+    pwm_force_none = 3,         /**< after SHSYNCI assert */
+} pwm_force_trigger_t;
+
+
+typedef enum {
+    pwm_logic_four_cmp_or = 0,
+    pwm_logic_four_cmp_and = 1,
+    pwm_logic_four_cmp_xor = 2,
+    pwm_logic_four_cmp_cd = 3,
+} pwm_logic_four_cmp_cfg_t;
+
+/**
+ * @brief  select when to recover PWM output after fault
+ *
+ */
+typedef enum {
+    pwm_fault_recovery_immediately = 0, /**< immediately*/
+    pwm_fault_recovery_on_reload = 1,   /**<  after pwm timer counter reload time*/
+    pwm_fault_recovery_on_hw_event = 2, /**< after hardware event assert*/
+    pwm_fault_recovery_on_fault_clear = 3,  /**<  after software write faultclr bit in GCR register*/
+} pwm_fault_recovery_trigger_t;
+
+typedef enum {
+    pwm_dac_channel_0 = 0,
+    pwm_dac_channel_1 = 1,
+    pwm_dac_channel_2 = 2,
+    pwm_dac_channel_3 = 3,
+} pwm_dac_channel_t;
+
+typedef enum {
+    pwm_capture_from_trigmux = 0,
+    pwm_capture_from_gpio = 1
+} pwm_capture_input_select_t;
+
+typedef enum {
+    pwm_dma_0 = 0,
+    pwm_dma_1 = 1,
+    pwm_dma_2 = 2,
+    pwm_dma_3 = 3,
+} pwm_dma_chn_t;
+
+typedef enum {
+    pwm_shadow_register_update_on_shlk = 0,     /**< after software set shlk bit of shlk register*/
+    pwm_shadow_register_update_on_modify = 1,   /**<  immediately after the register being modified*/
+    pwm_shadow_register_update_on_reload = 2,
+    pwm_shadow_register_update_on_trigmux = 3,
+    pwm_shadow_register_update_on_rld_cmp_select0 = 4,
+    pwm_shadow_register_update_on_rld_cmp_select1 = 5,
+    pwm_shadow_register_update_on_none = 6
+} pwm_cmp_shadow_register_update_trigger_t;
+
+typedef enum {
+    cmp_value_from_shadow_val = 0,
+    cmp_value_from_calculate = 0x20,
+    cmp_value_from_capture_posedge = 0x30,
+    cmp_value_from_counters = 0x38,
+    cmp_value_fffff000 = 0x3e,
+    cmp_value_ffffff00 = 0x3f
+} pwm_cmp_source_t;
+
+/**
+ * @brief pwm compare config
+ *
+ */
+typedef struct pwmv2_cmp_config {
+    uint32_t cmp;         /**< compare value */
+    bool enable_half_cmp;   /**< enable half compare value */
+    bool enable_hrcmp;     /**< enable high precision pwm */
+    pwm_cmp_source_t cmp_source;    /**< @ref pwm_cmp_source_t */
+    pwm_counter_t cmp_use_counter;  /**< select one from 4 counters, only for CMP_N>=16 */
+    uint8_t cmp_source_index;   /**< soure index */
+    uint8_t mode;         /**< compare work mode: pwm_cmp_mode_output_compare or pwm_cmp_mode_input_capture */
+    pwm_cmp_shadow_register_update_trigger_t update_trigger;  /**< compare configuration update trigger, need update trigger use pwm_shadow_register_update_on_trigmux */
+    uint8_t update_trigger_index;   /**< select one trigger from 8, should set to pulse in trig_mux */
+    uint8_t hrcmp;         /**< high precision pwm */
+} pwmv2_cmp_config_t;
+
+/**
+ * @brief pwm fault source config
+ *
+ */
+typedef struct pwmv2_async_fault_source_config {
+    uint8_t async_signal_from_pad_index;     /**< select from 16bit async fault from pad*/
+    pwm_fault_pad_polarity_t fault_async_pad_level;      /**< fault polarity for input fault from pad, 1-active low;  0-active high */
+} pwmv2_async_fault_source_config_t;
+
+/**
+ * @brief pwm config data
+ *
+ */
+typedef struct pwmv2_config {
+    bool enable_output;                 /**< enable pwm output */
+    bool enable_async_fault;            /**< enable the input async faults from pad directly */
+    bool enable_sync_fault;             /**< enable the input faults from trig_mux */
+    bool invert_output;                 /**< invert pwm output level */
+    bool enable_four_cmp;                /**< Enable the four cmp functions */
+    pwmv2_async_fault_source_config_t async_fault_source;
+    pwm_shadow_register_output_polarity_t update_polarity_time;
+    pwm_logic_four_cmp_cfg_t logic;     /**< valid only for pwm0/2/4/6 when trig_sel4 is set */
+    uint8_t update_trigger;             /**< pwm config update trigger */
+    uint8_t fault_mode;                 /**< fault mode */
+    pwm_fault_recovery_trigger_t fault_recovery_trigger;     /**< fault recoverty trigger */
+    uint8_t fault_recovery_trigmux_index;   /**< select one trigger from 8, should set to pulse in trig_mux */
+    uint8_t force_shadow_trigmux_index;          /**< select one trigger from 8, should set to pulse in trig_mux */
+    pwm_force_shadow_trigger_t force_shadow_trigger;         /**< will load shadow register(force)mode) to force_mode_work at this time */
+    uint8_t force_trigmux_index;               /**< select one trigger from 8 as force signal */
+    pwm_force_trigger_t force_trigger;          /**< @ref pwm_force_trigger_t */
+    uint32_t dead_zone_in_half_cycle;   /**< dead zone in half cycle*/
+} pwmv2_config_t;
+
+/**
+ * @brief pair pwm config
+ *
+ */
+typedef struct pwmv2_pair_config {
+    pwmv2_config_t pwm[2];    /**< pwm config data */
+} pwmv2_pair_config_t;
+
+typedef struct pwmv2_cmp_calculate_cfg {
+    uint8_t counter_index;        /**< select one of 4 counter reload time */
+    uint8_t in_index;       /**< 0~3 to select one of the dac input value; 4~7 to select one of the current counter value */
+    uint8_t in_offset_index;    /**< from one of the shadow_val */
+    int8_t t_param;    /**< period parameter */
+    int8_t d_param;    /**< dac/counter value parameter */
+    int8_t up_limit_param;
+    uint8_t up_limit_offset_index;  /**< from one of the shadow_val */
+    int8_t low_limit_param;
+    uint8_t low_limit_offset_index; /**< from one of the shadow_val */
+    bool enable_up_limit;
+    bool enbale_low_limit;
+} pwmv2_cmp_calculate_cfg_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief pwm deinitialize function
+ *
+ * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
+ *
+ */
+void pwmv2_deinit(PWMV2_Type *pwm_x);
+
+/**
+ * @brief issue all shawdow register
+ *
+ * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_issue_shadow_register_lock_event(PWMV2_Type *pwm_x)
+{
+    pwm_x->WORK_CTRL1 |= PWMV2_WORK_CTRL1_SHADOW_LOCK_MASK;
+}
+
+/**
+ * @brief lock all shawdow register
+ *
+ * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_shadow_register_lock(PWMV2_Type *pwm_x)
+{
+    pwm_x->WORK_CTRL1 |= PWMV2_WORK_CTRL1_SHADOW_LOCK_MASK;
+}
+
+/**
+ * @brief select one trigger from 8, set to use input signal(selected by cnt_reload_trig) to reload timer
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param trig_index one trigger from 8
+ */
+static inline void pwmv2_set_counter_reload_trigmux_index(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t trig_index)
+{
+    pwm_x->CNT[counter].CFG2 = (pwm_x->CNT[counter].CFG2 & ~PWMV2_CNT_CFG2_CNT_RELOAD_TRIG_MASK) | PWMV2_CNT_CFG2_CNT_RELOAD_TRIG_SET(trig_index);
+}
+
+/**
+ * @brief Multiple counters are enabled at the same time
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask bit0 - cnt0, bit1 - cnt1, bitn - cntn, n==3
+ */
+static inline void pwmv2_enable_multi_counter_sync(PWMV2_Type *pwm_x, uint8_t mask)
+{
+    pwm_x->CNT_GLBCFG &= ~(PWMV2_CNT_GLBCFG_TIMER_ENABLE_SET(mask));
+    fencerw();
+    pwm_x->CNT_GLBCFG |= PWMV2_CNT_GLBCFG_TIMER_ENABLE_SET(mask);
+}
+
+/**
+ * @brief Multiple pwm out at the same time
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask bit0 - cnt0, bit1 - cnt1, bitn - cntn, n==3
+ */
+static inline void pwmv2_start_pwm_output_sync(PWMV2_Type *pwm_x, uint8_t mask)
+{
+    pwm_x->CNT_GLBCFG |= PWMV2_CNT_GLBCFG_CNT_SW_START_SET(mask);
+}
+
+/**
+ * @brief unlock all shadow register
+ *
+ * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_shadow_register_unlock(PWMV2_Type *pwm_x)
+{
+    pwm_x->WORK_CTRL0 = PWM_UNLOCK_KEY;
+}
+
+/**
+ * @brief The shadow registers can be updated only when related unlock_bit is set.
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask bit2 to bit 29 for value_shadow, bit30 for force_mode, bit31 for polarity.
+ */
+static inline void pwmv2_shadow_unlock_bit_mask(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->UNLOCK = mask;
+}
+
+/**
+ * @brief Set the value of the shadow register
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param index shadow index
+ * @param value normal value (24bit)
+ * @param high_resolution_tick High precision pwm values (0 -255)
+ * @param enable_half_cycle half-cycle pwm
+ */
+static inline void pwmv2_set_shadow_val(PWMV2_Type *pwm_x, uint8_t index, uint32_t value, uint8_t high_resolution_tick, bool enable_half_cycle)
+{
+    pwm_x->SHADOW_VAL[index] = PWMV2_SHADOW_VAL_VALUE_SET(((value << 8) | (enable_half_cycle << 7) | (high_resolution_tick)));
+}
+
+/**
+ * @brief force pwm output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param mode @ref pwm_force_mode_t
+ * @param invert 0 - low level, 1 - high level
+ */
+static inline void pwmv2_force_output(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_force_mode_t mode, bool invert)
+{
+    pwm_x->FORCE_MODE = (pwm_x->FORCE_MODE & ~(PWMV2_FORCE_MODE_POLARITY_SET((1 << (chn << 1))) | PWMV2_FORCE_MODE_FORCE_MODE_SET((3 << (chn << 1))))) |
+                        PWMV2_FORCE_MODE_POLARITY_SET((invert << (chn << 1))) |
+                        PWMV2_FORCE_MODE_FORCE_MODE_SET((mode << (chn << 1)));
+}
+
+/**
+ * @brief enable four pwm outputs
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_four_cmp(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 |= PWMV2_PWM_CFG0_TRIG_SEL4_MASK;
+}
+
+/**
+ * @brief disable four pwm outputs
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_four_cmp(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 &= ~PWMV2_PWM_CFG0_TRIG_SEL4_MASK;
+}
+
+/**
+ * @brief Direct selection of the fail signal from the pin
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param pad_index motor pad
+ */
+static inline void pwmv2_fault_signal_select_from_pad(PWMV2_Type *pwm_x, pwm_channel_t chn, uint8_t pad_index)
+{
+    pwm_x->PWM[chn].CFG0 = (pwm_x->PWM[chn].CFG0 & ~PWMV2_PWM_CFG0_FAULT_SEL_ASYNC_MASK) | PWMV2_PWM_CFG0_FAULT_SEL_ASYNC_SET(pad_index);
+}
+
+/**
+ * @brief Configure the polarity of the fail signal
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param polarity @ref pwm_fault_pad_polarity_t
+ */
+static inline void pwmv2_fault_signal_polarity(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_fault_pad_polarity_t polarity)
+{
+    pwm_x->PWM[chn].CFG0 = (pwm_x->PWM[chn].CFG0 & ~PWMV2_PWM_CFG0_FAULT_POL_ASYNC_MASK) | PWMV2_PWM_CFG0_FAULT_POL_ASYNC_SET(polarity);
+}
+
+/**
+ * @brief Enable the fault signal from the pin
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_fault_from_pad(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 |= PWMV2_PWM_CFG0_FAULT_EN_ASYNC_MASK;
+}
+
+/**
+ * @brief Disable the fault signal from the pin
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_fault_from_pad(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 &= ~PWMV2_PWM_CFG0_FAULT_EN_ASYNC_MASK;
+}
+
+/**
+ * @brief Enable the fault signal from the trigmux
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_fault_from_trigmux(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 |= PWMV2_PWM_CFG0_FAULT_EN_SYNC_MASK;
+}
+
+/**
+ * @brief Disable the fault signal from the trigmux
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_fault_from_trigmux(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 &= ~PWMV2_PWM_CFG0_FAULT_EN_SYNC_MASK;
+}
+
+/**
+ * @brief Enable pwm output invert
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_output_invert(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 |= PWMV2_PWM_CFG0_OUT_POLARITY_MASK;
+}
+
+/**
+ * @brief Disable pwm output invert
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_output_invert(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 &= ~PWMV2_PWM_CFG0_OUT_POLARITY_MASK;
+}
+
+/**
+ * @brief Enable invert operations via shadow registers
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param update_select @ref pwm_shadow_register_output_polarity_t
+ */
+static inline void pwmv2_enable_invert_by_shadow(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_shadow_register_output_polarity_t update_select)
+{
+    pwm_x->PWM[chn].CFG0 |= PWMV2_PWM_CFG0_POLARITY_OPT0_MASK;
+    pwm_x->PWM[chn].CFG0 = (pwm_x->PWM[chn].CFG0 & ~PWMV2_PWM_CFG0_POL_UPDATE_SEL_MASK) | PWMV2_PWM_CFG0_POL_UPDATE_SEL_SET(update_select);
+}
+
+/**
+ * @brief Disable invert operations via shadow registers
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param update_select @ref pwm_shadow_register_output_polarity_t
+ */
+static inline void pwmv2_disable_invert_by_shadow(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG0 &= ~PWMV2_PWM_CFG0_POLARITY_OPT0_MASK;
+}
+
+/**
+ * @brief Enable pwm output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_channel_enable_output(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 |= PWMV2_PWM_CFG1_HIGHZ_EN_N_MASK;
+}
+
+/**
+ * @brief Disable pwm output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_channel_disable_output(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 &= ~PWMV2_PWM_CFG1_HIGHZ_EN_N_MASK;
+}
+
+/**
+ * @brief Forces the output configuration to be updated from the time shadow hosting takes effect
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param update_time @ref pwm_force_shadow_trigger_t
+ */
+static inline void pwmv2_force_update_time_by_shadow(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_force_shadow_trigger_t update_time)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FORCE_UPDATE_TIME_MASK) | PWMV2_PWM_CFG1_FORCE_UPDATE_TIME_SET(update_time);
+}
+
+/**
+ * @brief set the fault mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param mode @ref pwm_fault_mode_t
+ */
+static inline void pwmv2_set_fault_mode(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_fault_mode_t mode)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FAULT_MODE_MASK) | PWMV2_PWM_CFG1_FAULT_MODE_SET(mode);
+}
+
+/**
+ * @brief Set the fault mode recovery time
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param trig @ref pwm_fault_recovery_trigger_t
+ */
+static inline void pwmv2_set_fault_recovery_time(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_fault_recovery_trigger_t trig)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FAULT_REC_TIME_MASK) | PWMV2_PWM_CFG1_FAULT_REC_TIME_SET(trig);
+}
+
+/**
+ * @brief Trigger forced mode by hardware signal
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_force_by_hardware(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 &= ~PWMV2_PWM_CFG1_SW_FORCE_EN_MASK;
+}
+
+/**
+ * @brief Enable force mode triggered by software
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_force_by_software(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 |= PWMV2_PWM_CFG1_SW_FORCE_EN_MASK;
+}
+
+/**
+ * @brief Disable force mode triggered by software
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_force_by_software(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 &= ~PWMV2_PWM_CFG1_SW_FORCE_EN_MASK;
+}
+
+/**
+ * @brief Enable pwm complementary mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_pair_mode(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 |= PWMV2_PWM_CFG1_PAIR_MODE_MASK;
+}
+
+/**
+ * @brief Disable pwm complementary mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_pair_mode(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->PWM[chn].CFG1 &= ~PWMV2_PWM_CFG1_PAIR_MODE_MASK;
+}
+
+/**
+ * @brief Configure the logic between the 4 cmp, valid only if the 4 cmp output is enabled
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param logic @ref pwm_logic_four_cmp_cfg_t
+ */
+static inline void pwmv2_set_four_cmp_logic(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_logic_four_cmp_cfg_t logic)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_PWM_LOGIC_MASK) | PWMV2_PWM_CFG1_PWM_LOGIC_SET(logic);
+}
+
+/**
+ * @brief Setting the effective time of forced output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param time @ref pwm_force_trigger_t
+ */
+static inline void pwmv2_set_force_update_time(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_force_trigger_t time)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FORCE_TIME_MASK) | PWMV2_PWM_CFG1_FORCE_TIME_SET(time);
+}
+
+/**
+ * @brief Selecting trigmux's signal as a forced mode trigger source
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param trigmux_index trigmux index
+ */
+static inline void pwmv2_trig_force_mode_select_trigmux_index(PWMV2_Type *pwm_x, pwm_channel_t chn, uint8_t trigmux_index)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FORCE_TRIG_SEL_MASK) | PWMV2_PWM_CFG1_FORCE_TRIG_SEL_SET(trigmux_index);
+}
+
+/**
+ * @brief Selection of trigger signals for software or hardware trigmux
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param trigmux_index select one trigger from 8
+ */
+static inline void pwmv2_trig_force_hardware_or_software_select_trigmux_index(PWMV2_Type *pwm_x, pwm_channel_t chn, uint8_t trigmux_index)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FORCE_ACT_SEL_MASK) | PWMV2_PWM_CFG1_FORCE_ACT_SEL_SET(trigmux_index);
+}
+
+/**
+ * @brief Select the trigger source that forces the output to take effect
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param trigmux_index select one trigger from 8
+ */
+static inline void pwmv2_select_force_trigmux_index(PWMV2_Type *pwm_x, pwm_channel_t chn, uint8_t trigmux_index)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_PWM_FORCE_SEL_MASK) | PWMV2_PWM_CFG1_PWM_FORCE_SEL_SET(trigmux_index);
+}
+
+/**
+ * @brief Selection of trigger signal for fault recovery
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param trigmux_index select one trigger from 8
+ */
+static inline void pwmv2_select_recovery_fault_trigmux_index(PWMV2_Type *pwm_x, pwm_channel_t chn, uint8_t trigmux_index)
+{
+    pwm_x->PWM[chn].CFG1 = (pwm_x->PWM[chn].CFG1 & ~PWMV2_PWM_CFG1_FAULT_REC_SEL_MASK) | PWMV2_PWM_CFG1_FAULT_REC_SEL_SET(trigmux_index);
+}
+
+/**
+ * @brief set pwm dead area
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param dead dead area time
+ */
+static inline void pwmv2_set_dead_area(PWMV2_Type *pwm_x, pwm_channel_t chn, uint32_t dead)
+{
+    pwm_x->PWM[chn].DEAD_AREA = PWMV2_PWM_DEAD_AREA_DEAD_AREA_SET((dead << 8));
+}
+
+/**
+ * @brief Setting the comparator as an input to trigmux
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param trigmux_chn @ref pwm_channel_t
+ * @param cmp_index cmp index
+ */
+static inline void pwmv2_set_trigout_cmp_index(PWMV2_Type *pwm_x, pwm_channel_t trigmux_chn, uint8_t cmp_index)
+{
+    pwm_x->TRIGGER_CFG[trigmux_chn] = (pwm_x->TRIGGER_CFG[trigmux_chn] & ~PWMV2_TRIGGER_CFG_TRIGGER_OUT_SEL_MASK) | PWMV2_TRIGGER_CFG_TRIGGER_OUT_SEL_SET(cmp_index);
+}
+
+/**
+ * @brief Enable software forced output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_software_force(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->GLB_CTRL |= PWMV2_GLB_CTRL_SW_FORCE_SET((1 << chn));
+}
+
+/**
+ * @brief Disable software forced output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_software_force(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->GLB_CTRL &= ~(PWMV2_GLB_CTRL_SW_FORCE_SET((1 << chn)));
+}
+
+#ifdef PWM_SOC_HRPWM_SUPPORT
+
+/**
+ * @brief Add a delay after deadband, 0-255ths of a clock cycle
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param delay_tick 0-255
+ */
+static inline void pwmv2_add_delay_tick_after_dead_area(PWMV2_Type *pwm_x, uint8_t delay_tick)
+{
+    pwm_x->GLB_CTRL = (pwm_x->GLB_CTRL & ~PWMV2_GLB_CTRL_OUTPUT_DELAY_MASK) | PWMV2_GLB_CTRL_OUTPUT_DELAY_SET(delay_tick);
+}
+
+/**
+ * @brief Enable high precision pwm
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_enable_hrpwm(PWMV2_Type *pwm_x)
+{
+    pwm_x->GLB_CTRL |= PWMV2_GLB_CTRL_HR_PWM_EN_MASK;
+}
+
+/**
+ * @brief Disable high precision pwm
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_disable_hrpwm(PWMV2_Type *pwm_x)
+{
+    pwm_x->GLB_CTRL &= ~PWMV2_GLB_CTRL_HR_PWM_EN_MASK;
+}
+
+#endif
+
+/**
+ * @brief Enable the software dac mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dac_index @ref pwm_dac_channel_t
+ */
+static inline void pwmv2_enable_software_dac_mode(PWMV2_Type *pwm_x, pwm_dac_channel_t dac_index)
+{
+    pwm_x->GLB_CTRL2 |= PWMV2_GLB_CTRL2_DAC_SW_MODE_SET((1 << dac_index));
+}
+
+/**
+ * @brief Disable the software dac mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dac_index @ref pwm_dac_channel_t
+ */
+static inline void pwmv2_disable_software_dac_mode(PWMV2_Type *pwm_x, pwm_dac_channel_t dac_index)
+{
+    pwm_x->GLB_CTRL2 &= ~PWMV2_GLB_CTRL2_DAC_SW_MODE_SET((1 << dac_index));
+}
+
+/**
+ * @brief Enable debug mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_enable_debug_mode(PWMV2_Type *pwm_x)
+{
+    pwm_x->GLB_CTRL2 |= PWMV2_GLB_CTRL2_DEBUG_IN_EN_MASK;
+}
+
+
+/**
+ * @brief Disable debug mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_disable_debug_mode(PWMV2_Type *pwm_x)
+{
+    pwm_x->GLB_CTRL2 &= ~PWMV2_GLB_CTRL2_DEBUG_IN_EN_MASK;
+}
+
+/**
+ * @brief Clear fault event
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ */
+static inline void pwmv2_clear_fault_event(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    pwm_x->GLB_CTRL2 = (pwm_x->GLB_CTRL2 & ~(PWMV2_GLB_CTRL2_FAULT_CLEAR_MASK)) | PWMV2_GLB_CTRL2_FAULT_CLEAR_SET((1 << chn));
+}
+
+/**
+ * @brief Using the Shadow Register Function
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_enable_shadow_lock_feature(PWMV2_Type *pwm_x)
+{
+    pwm_x->GLB_CTRL2 |= PWMV2_GLB_CTRL2_SHADOW_LOCK_EN_MASK;
+}
+
+/**
+ * @brief Do not use the shadow register function
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_disable_shadow_lock_feature(PWMV2_Type *pwm_x)
+{
+    pwm_x->GLB_CTRL2 &= ~PWMV2_GLB_CTRL2_SHADOW_LOCK_EN_MASK;
+}
+
+/**
+ * @brief Get counter work status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter_index @ref pwm_counter_t
+ * @return uint32_t status mask
+ */
+static inline uint32_t pwmv2_get_counter_working_status(PWMV2_Type *pwm_x, pwm_counter_t counter_index)
+{
+    return PWMV2_CNT_RELOAD_WORK_VALUE_GET(pwm_x->CNT_RELOAD_WORK[counter_index]);
+}
+
+/**
+ * @brief Get cmp work status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ * @return uint32_t status mask
+ */
+static inline uint32_t pwmv2_get_cmp_working_status(PWMV2_Type *pwm_x, uint8_t cmp_index)
+{
+    return PWMV2_CMP_VAL_WORK_VALUE_GET(pwm_x->CMP_VAL_WORK[cmp_index]);
+}
+
+/**
+ * @brief Get force mode work status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t status mask
+ */
+static inline uint32_t pwmv2_get_force_working_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_FORCE_WORK_FORCE_MODE_GET(pwm_x->FORCE_WORK);
+}
+
+/**
+ * @brief Get the status of the output polarity
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t polarity
+ */
+static inline uint32_t pwmv2_get_force_work_out_polarity_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_FORCE_WORK_OUT_POLARITY_GET(pwm_x->FORCE_WORK);
+}
+
+/**
+ * @brief Getting the value of a counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter_index @ref pwm_counter_t
+ * @return uint32_t counter value
+ */
+static inline uint32_t pwmv2_get_counter_value(PWMV2_Type *pwm_x, pwm_counter_t counter_index)
+{
+    return PWMV2_CNT_VAL_VALUE_GET(pwm_x->CNT_VAL[counter_index]);
+}
+
+/**
+ * @brief set dac value
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dac_index @ref pwm_dac_channel_t
+ * @param value dac value
+ */
+static inline void pwmv2_set_dac_value(PWMV2_Type *pwm_x, pwm_dac_channel_t dac_index, uint32_t value)
+{
+    pwm_x->DAC_VALUE_SV[dac_index] = PWMV2_DAC_VALUE_SV_VALUE_SET(value);
+}
+
+/**
+ * @brief get capture posedge value
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @return uint32_t posedge value
+ */
+static inline uint32_t pwmv2_get_capture_posedge_value(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    return PWMV2_CAPTURE_POS_CAPTURE_POS_GET(pwm_x->CAPTURE_POS[chn]);
+}
+
+/**
+ * @brief Select the input source for the captured signal
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param select @ref pwm_capture_input_select_t
+ */
+static inline void pwmv2_capture_selection_input_source(PWMV2_Type *pwm_x, pwm_channel_t chn, pwm_capture_input_select_t select)
+{
+    pwm_x->CAPTURE_POS[chn] = (pwm_x->CAPTURE_POS[chn] & ~PWMV2_CAPTURE_POS_CAPTURE_SELGPIO_MASK) |
+                                                        PWMV2_CAPTURE_POS_CAPTURE_SELGPIO_SET(select);
+}
+
+/**
+ * @brief Set the counter to be used for the capture channel
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param counter_index counter index
+ */
+static inline void pwmv2_set_capture_counter_index(PWMV2_Type *pwm_x, pwm_channel_t chn, uint8_t counter_index)
+{
+    pwm_x->CAPTURE_POS[chn] = (pwm_x->CAPTURE_POS[chn] & ~PWMV2_CAPTURE_POS_CNT_INDEX_MASK) |
+                                                        PWMV2_CAPTURE_POS_CNT_INDEX_SET(counter_index);
+}
+
+/**
+ * @brief get capture negedge value
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @return uint32_t posedge value
+ */
+static inline uint32_t pwmv2_get_capture_negedge_value(PWMV2_Type *pwm_x, pwm_channel_t chn)
+{
+    return PWMV2_CAPTURE_NEG_CAPTURE_NEG_GET(pwm_x->CAPTURE_NEG[chn]);
+}
+
+/**
+ * @brief Get all interrupt status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status mask
+ */
+static inline uint32_t pwmv2_get_irq_status_all(PWMV2_Type *pwm_x)
+{
+    return pwm_x->IRQ_STS;
+}
+
+/**
+ * @brief clear calculate overflow irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_clear_calculate_overflow_irq_status(PWMV2_Type *pwm_x)
+{
+    pwm_x->IRQ_STS &= PWMV2_IRQ_STS_IRQ_CAL_OVERFLOW_MASK;
+}
+
+/**
+ * @brief enable calculate overflow irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_enable_calculate_overflow_irq(PWMV2_Type *pwm_x)
+{
+    pwm_x->IRQ_EN |= PWMV2_IRQ_EN_IRQ_EN_OVERFLOW_MASK;
+}
+
+/**
+ * @brief Disable calculate overflow irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ */
+static inline void pwmv2_disable_calculate_overflow_irq(PWMV2_Type *pwm_x)
+{
+    pwm_x->IRQ_EN &= ~PWMV2_IRQ_EN_IRQ_EN_OVERFLOW_MASK;
+}
+
+/**
+ * @brief Get cmp irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status
+ */
+static inline uint32_t pwmv2_get_cmp_irq_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_IRQ_STS_CMP_IRQ_STS_CMP_GET(pwm_x->IRQ_STS_CMP);
+}
+
+/**
+ * @brief Clear cmp irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask uint32_t irq status
+ */
+static inline void pwmv2_clear_cmp_irq_status(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->IRQ_STS_CMP = PWMV2_IRQ_STS_CMP_IRQ_STS_CMP_SET(mask);
+}
+
+/**
+ * @brief Get reload irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t reload irq status
+ */
+static inline uint32_t pwmv2_get_reload_irq_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_IRQ_STS_RELOAD_IRQ_STS_RELOAD_GET(pwm_x->IRQ_STS_RELOAD);
+}
+
+/**
+ * @brief Clear reload irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask irq status mask
+ */
+static inline void pwmv2_clear_reload_irq_status(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->IRQ_STS_RELOAD = PWMV2_IRQ_STS_RELOAD_IRQ_STS_RELOAD_SET(mask);
+}
+
+/**
+ * @brief Get capture posedge irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status
+ */
+static inline uint32_t pwmv2_get_capture_posedge_irq_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_IRQ_STS_CAP_POS_IRQ_STS_CAP_POS_GET(pwm_x->IRQ_STS_CAP_POS);
+}
+
+/**
+ * @brief Clear capture posedge irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask capture posedge irq mask
+ */
+static inline void pwmv2_clear_capture_posedge_irq_status(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->IRQ_STS_CAP_POS = PWMV2_IRQ_STS_CAP_POS_IRQ_STS_CAP_POS_SET(mask);
+}
+
+/**
+ * @brief Get capture negedge irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status
+ */
+static inline uint32_t pwmv2_get_capture_negedge_irq_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_IRQ_STS_CAP_NEG_IRQ_STS_CAP_NEG_GET(pwm_x->IRQ_STS_CAP_NEG);
+}
+
+/**
+ * @brief Clear capture negedge irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask capture posedge irq mask
+ */
+static inline void pwmv2_clear_capture_negedge_irq_status(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->IRQ_STS_CAP_NEG = PWMV2_IRQ_STS_CAP_NEG_IRQ_STS_CAP_NEG_SET(mask);
+}
+
+/**
+ * @brief Get fault irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status
+ */
+static inline uint32_t pwmv2_get_fault_irq_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_IRQ_STS_FAULT_IRQ_STS_FAULT_GET(pwm_x->IRQ_STS_FAULT);
+}
+
+/**
+ * @brief Clear fault irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status
+ */
+static inline void pwmv2_clear_fault_irq_status(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->IRQ_STS_FAULT = PWMV2_IRQ_STS_FAULT_IRQ_STS_FAULT_SET(mask);
+}
+
+/**
+ * @brief Get burstend irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @return uint32_t irq status
+ */
+static inline uint32_t pwmv2_get_burstend_irq_status(PWMV2_Type *pwm_x)
+{
+    return PWMV2_IRQ_STS_BURSTEND_IRQ_STS_BURSTEND_GET(pwm_x->IRQ_STS_BURSTEND);
+}
+
+/**
+ * @brief Clear burstend irq status
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param mask mask status
+ */
+static inline void pwmv2_clear_burstend__irq_status(PWMV2_Type *pwm_x, uint32_t mask)
+{
+    pwm_x->IRQ_STS_BURSTEND = PWMV2_IRQ_STS_BURSTEND_IRQ_STS_BURSTEND_SET(mask);
+}
+
+/**
+ * @brief enable cmp irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ */
+static inline void pwmv2_enable_cmp_irq(PWMV2_Type *pwm_x, uint8_t cmp_index)
+{
+    pwm_x->IRQ_EN_CMP |= PWMV2_IRQ_EN_CMP_IRQ_EN_CMP_SET(1 << cmp_index);
+}
+
+/**
+ * @brief disable cmp irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ */
+static inline void pwmv2_disable_cmp_irq(PWMV2_Type *pwm_x, uint8_t cmp_index)
+{
+    pwm_x->IRQ_EN_CMP &= ~PWMV2_IRQ_EN_CMP_IRQ_EN_CMP_SET(1 << cmp_index);
+}
+
+/**
+ * @brief enable reload irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter_index @ref pwm_counter_t
+ */
+static inline void pwmv2_enable_reload_irq(PWMV2_Type *pwm_x, pwm_counter_t counter_index)
+{
+    pwm_x->IRQ_EN_RELOAD |= PWMV2_IRQ_EN_RELOAD_IRQ_EN_RELOAD_SET(1 << counter_index);
+}
+
+/**
+ * @brief disable reload irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter_index @ref pwm_counter_t
+ */
+static inline void pwmv2_disable_reload_irq(PWMV2_Type *pwm_x, pwm_counter_t counter_index)
+{
+    pwm_x->IRQ_EN_RELOAD &= ~PWMV2_IRQ_EN_RELOAD_IRQ_EN_RELOAD_SET(1 << counter_index);
+}
+
+/**
+ * @brief enable capture posedge irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param channel_index @ref pwm_counter_t
+ */
+static inline void pwmv2_enable_capture_posedge_irq(PWMV2_Type *pwm_x, pwm_channel_t channel_index)
+{
+    pwm_x->IRQ_EN_CAP_POS |= PWMV2_IRQ_EN_CAP_POS_IRQ_EN_CAP_POS_SET(1 << channel_index);
+}
+
+/**
+ * @brief disable capture posedge irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param channel_index @ref pwm_counter_t
+ */
+static inline void pwmv2_disable_capture_posedge_irq(PWMV2_Type *pwm_x, pwm_channel_t channel_index)
+{
+    pwm_x->IRQ_EN_CAP_POS &= ~PWMV2_IRQ_EN_CAP_POS_IRQ_EN_CAP_POS_SET(1 << channel_index);
+}
+
+/**
+ * @brief enable capture nedege irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param channel_index @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_capture_nededge_irq(PWMV2_Type *pwm_x, pwm_channel_t channel_index)
+{
+    pwm_x->IRQ_EN_CAP_NEG |= PWMV2_IRQ_EN_CAP_NEG_IRQ_EN_CAP_NEG_SET(1 << channel_index);
+}
+
+/**
+ * @brief disable capture nedege irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param channel_index @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_capture_nededge_irq(PWMV2_Type *pwm_x, pwm_channel_t channel_index)
+{
+    pwm_x->IRQ_EN_CAP_NEG &= ~PWMV2_IRQ_EN_CAP_NEG_IRQ_EN_CAP_NEG_SET(1 << channel_index);
+}
+
+/**
+ * @brief enable fault irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param channel_index @ref pwm_channel_t
+ */
+static inline void pwmv2_enable_fault_irq(PWMV2_Type *pwm_x, pwm_channel_t channel_index)
+{
+    pwm_x->IRQ_EN_FAULT |= PWMV2_IRQ_EN_FAULT_IRQ_EN_FAULT_SET(1 << channel_index);
+}
+
+/**
+ * @brief disable fault irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param channel_index @ref pwm_channel_t
+ */
+static inline void pwmv2_disable_fault_irq(PWMV2_Type *pwm_x, pwm_channel_t channel_index)
+{
+    pwm_x->IRQ_EN_FAULT &= ~PWMV2_IRQ_EN_FAULT_IRQ_EN_FAULT_SET(1 << channel_index);
+}
+
+/**
+ * @brief enable burstend irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter_index @ref pwm_counter_t
+ */
+static inline void pwmv2_enable_burstend_irq(PWMV2_Type *pwm_x, pwm_counter_t counter_index)
+{
+    pwm_x->IRQ_EN_BURSTEND |= PWMV2_IRQ_EN_FAULT_IRQ_EN_FAULT_SET(1 << counter_index);
+}
+
+/**
+ * @brief disable burstend irq
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter_index @ref pwm_counter_t
+ */
+static inline void pwmv2_disable_burstend_irq(PWMV2_Type *pwm_x, pwm_counter_t counter_index)
+{
+    pwm_x->IRQ_EN_BURSTEND &= ~PWMV2_IRQ_EN_FAULT_IRQ_EN_FAULT_SET(1 << counter_index);
+}
+
+/**
+ * @brief enable dma at compare point
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dma_channel @ref pwm_dma_chn_t
+ * @param cmp_index cmp index
+ */
+static inline void pwmv2_enable_dma_at_compare_point(PWMV2_Type *pwm_x, pwm_dma_chn_t dma_channel, uint8_t cmp_index)
+{
+    pwm_x->DMA_EN = (pwm_x->DMA_EN & ~((PWMV2_DMA_EN_DMA0_SEL_MASK | PWMV2_DMA_EN_DMA0_EN_MASK) << (PWMV2_DMA_EN_DMA1_SEL_SHIFT * dma_channel))) |
+    ((PWMV2_DMA_EN_DMA0_SEL_SET(cmp_index) | PWMV2_DMA_EN_DMA0_EN_MASK) << (PWMV2_DMA_EN_DMA1_SEL_SHIFT * dma_channel));
+}
+
+/**
+ * @brief disable dma at compare point
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dma_channel @ref pwm_dma_chn_t
+ */
+static inline void pwmv2_disable_dma_at_compare_point(PWMV2_Type *pwm_x, pwm_dma_chn_t dma_channel)
+{
+    pwm_x->DMA_EN &= ~((PWMV2_DMA_EN_DMA0_SEL_MASK | PWMV2_DMA_EN_DMA0_EN_MASK) << (PWMV2_DMA_EN_DMA1_SEL_SHIFT * dma_channel));
+}
+
+/**
+ * @brief enable dma at reload point
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dma_channel @ref pwm_dma_chn_t
+ * @param reload_index @ref pwm_counter_t
+ */
+static inline void pwmv2_enable_dma_at_reload_point(PWMV2_Type *pwm_x, pwm_dma_chn_t dma_channel, pwm_counter_t reload_index)
+{
+    pwm_x->DMA_EN = (pwm_x->DMA_EN & ~((PWMV2_DMA_EN_DMA0_SEL_MASK | PWMV2_DMA_EN_DMA0_EN_MASK) << (PWMV2_DMA_EN_DMA1_SEL_SHIFT * dma_channel))) |
+    ((PWMV2_DMA_EN_DMA0_SEL_SET(reload_index + 24) | PWMV2_DMA_EN_DMA0_EN_MASK) << (PWMV2_DMA_EN_DMA1_SEL_SHIFT * dma_channel));
+}
+
+/**
+ * @brief disable dma at reload point
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param dma_channel @ref pwm_dma_chn_t
+ */
+static inline void pwmv2_disable_dma_at_reload_point(PWMV2_Type *pwm_x, pwm_dma_chn_t dma_channel)
+{
+    pwm_x->DMA_EN &= ~((PWMV2_DMA_EN_DMA0_SEL_MASK | PWMV2_DMA_EN_DMA0_EN_MASK) << (PWMV2_DMA_EN_DMA1_SEL_SHIFT * dma_channel));
+}
+
+/**
+ * @brief select compare point 0 index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param cmp_index cmp index
+ */
+static inline void pwmv2_reload_select_compare_point0_index(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t cmp_index)
+{
+    pwm_x->CNT[counter].CFG0 = (pwm_x->CNT[counter].CFG0 & ~(PWMV2_CNT_CFG0_RLD_CMP_SEL0_MASK)) | PWMV2_CNT_CFG0_RLD_CMP_SEL0_SET(cmp_index);
+}
+
+/**
+ * @brief select compare point 1 index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param cmp_index cmp index
+ */
+static inline void pwmv2_reload_select_compare_point1_index(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t cmp_index)
+{
+    pwm_x->CNT[counter].CFG0 = (pwm_x->CNT[counter].CFG0 & ~(PWMV2_CNT_CFG0_RLD_CMP_SEL1_MASK)) | PWMV2_CNT_CFG0_RLD_CMP_SEL1_SET(cmp_index);
+}
+
+/**
+ * @brief Select the input trigger source for the reload point
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param trig_index trig index
+ */
+static inline void pwmv2_reload_select_input_trigger(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t trig_index)
+{
+    pwm_x->CNT[counter].CFG0 = (pwm_x->CNT[counter].CFG0 & ~(PWMV2_CNT_CFG0_RLD_TRIG_SEL_MASK)) | PWMV2_CNT_CFG0_RLD_TRIG_SEL_SET(trig_index);
+}
+
+/**
+ * @brief Set reload update time
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param update @ref pwm_reload_update_time_t
+ */
+static inline void pwmv2_set_reload_update_time(PWMV2_Type *pwm_x, pwm_counter_t counter, pwm_reload_update_time_t update)
+{
+    pwm_x->CNT[counter].CFG0 = (pwm_x->CNT[counter].CFG0 & ~(PWMV2_CNT_CFG0_RLD_UPDATE_TIME_MASK)) | PWMV2_CNT_CFG0_RLD_UPDATE_TIME_SET(update);
+}
+
+/**
+ * @brief Set dac data parameter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param dac_parameter dac parameter
+ */
+static inline void pwmv2_counter_set_dac_data_parameter(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t dac_parameter)
+{
+    pwm_x->CNT[counter].CFG0 = (pwm_x->CNT[counter].CFG0 & ~PWMV2_CNT_CFG0_CNT_D_PARAM_MASK) | PWMV2_CNT_CFG0_CNT_D_PARAM_SET(dac_parameter);
+}
+
+/**
+ * @brief Select dac index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param dac_index @ref pwm_dac_channel_t
+ */
+static inline void pwmv2_conuter_select_dac_index(PWMV2_Type *pwm_x, pwm_counter_t counter, pwm_dac_channel_t dac_index)
+{
+    pwm_x->CNT[counter].CFG1 = (pwm_x->CNT[counter].CFG1 & ~PWMV2_CNT_CFG1_CNT_DAC_INDEX_MASK) | PWMV2_CNT_CFG1_CNT_DAC_INDEX_SET(dac_index);
+}
+
+/**
+ * @brief Enable the upper limit of the calculation unit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_up_limit_enable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG1 |= PWMV2_CNT_CFG1_CNT_LU_EN_MASK;
+}
+
+/**
+ * @brief Disable the upper limit of the calculation unit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_up_limit_disable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG1 &= ~PWMV2_CNT_CFG1_CNT_LU_EN_MASK;
+}
+
+/**
+ * @brief Select the upper limit from the shadow register
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param index shadow index
+ */
+static inline void pwmv2_counter_select_up_limit_from_shadow_value(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t index)
+{
+    pwm_x->CNT[counter].CFG1 = (pwm_x->CNT[counter].CFG1 & ~PWMV2_CNT_CFG1_CNT_LIM_UP_MASK) | PWMV2_CNT_CFG1_CNT_LIM_UP_SET(index);
+}
+
+/**
+ * @brief Enable the lower limit of the calculation unit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_low_limit_enable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG1 |= PWMV2_CNT_CFG1_CNT_LL_EN_MASK;
+}
+
+
+/**
+ * @brief Disable the lower limit of the calculation unit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_low_limit_disable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG1 &= ~PWMV2_CNT_CFG1_CNT_LL_EN_MASK;
+}
+
+/**
+ * @brief Select the lower limit from the shadow register
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param index shadow index
+ */
+static inline void pwmv2_counter_select_low_limit_from_shadow_value(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t index)
+{
+    pwm_x->CNT[counter].CFG1 = (pwm_x->CNT[counter].CFG1 & ~PWMV2_CNT_CFG1_CNT_LIM_LO_MASK) | PWMV2_CNT_CFG1_CNT_LIM_LO_SET(index);
+}
+
+/**
+ * @brief Select data offset from shadow register
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param index shadow index
+ */
+static inline void pwmv2_counter_select_data_offset_from_shadow_value(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t index)
+{
+    pwm_x->CNT[counter].CFG1 = (pwm_x->CNT[counter].CFG1 & ~PWMV2_CNT_CFG1_CNT_IN_OFF_MASK) | PWMV2_CNT_CFG1_CNT_IN_OFF_SET(index);
+}
+
+/**
+ * @brief enable counter reload by trigmux
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_enable_reload_by_trig(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG2 |= PWMV2_CNT_CFG2_CNT_RELOAD_EN_MASK;
+}
+
+/**
+ * @brief disable counter reload by trigmux
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_disable_reload_by_trig(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG2 &= ~PWMV2_CNT_CFG2_CNT_RELOAD_EN_MASK;
+}
+
+/**
+ * @brief Select counter update by trigmux1
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param trig_index trigmux index
+ */
+static inline void pwmv2_counter_update_trig1(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t trig_index)
+{
+    pwm_x->CNT[counter].CFG2 = (pwm_x->CNT[counter].CFG2 & ~PWMV2_CNT_CFG2_CNT_UPDATE_TRIG1_MASK) | PWMV2_CNT_CFG2_CNT_UPDATE_TRIG1_SET(trig_index);
+}
+
+/**
+ * @brief Enable counter update by trigmux1
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_enable_update_trig1(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG2 |= PWMV2_CNT_CFG2_CNT_UPDATE_EN1_MASK;
+}
+
+/**
+ * @brief Disable counter update by trigmux1
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_disable_update_trig1(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG2 &= ~PWMV2_CNT_CFG2_CNT_UPDATE_EN1_MASK;
+}
+
+/**
+ * @brief Enable change counter value to one of the calculation cell output when cnt_update_triger1 issued
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param cal_index cal index
+ */
+static inline void pwmv2_counter_set_trig1_calculate_cell_index(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t cal_index)
+{
+    pwm_x->CNT[counter].CFG2 = (pwm_x->CNT[counter].CFG2 & ~PWMV2_CNT_CFG2_CNT_TRIG1_MASK) | PWMV2_CNT_CFG2_CNT_TRIG1_SET(cal_index);
+}
+
+/**
+ * @brief Select counter update by trigmux0
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param trig_index trigmux index
+ */
+static inline void pwmv2_counter_update_trig0(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t trig_index)
+{
+    pwm_x->CNT[counter].CFG2 = (pwm_x->CNT[counter].CFG2 & ~PWMV2_CNT_CFG2_CNT_UPDATE_TRIG0_MASK) | PWMV2_CNT_CFG2_CNT_UPDATE_TRIG0_SET(trig_index);
+}
+
+/**
+ * @brief Enable counter update by trigmux0
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_enable_update_trig0(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG2 |= PWMV2_CNT_CFG2_CNT_UPDATE_EN0_MASK;
+}
+
+/**
+ * @brief Disable counter update by trigmux0
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_disable_update_trig0(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG2 &= ~PWMV2_CNT_CFG2_CNT_UPDATE_EN0_MASK;
+}
+
+/**
+ * @brief Enable change counter value to one of the calculation cell output when cnt_update_triger0 issued
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param cal_index cal index
+ */
+static inline void pwmv2_counter_set_trig0_calculate_cell_index(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t cal_index)
+{
+    pwm_x->CNT[counter].CFG2 = (pwm_x->CNT[counter].CFG2 & ~PWMV2_CNT_CFG2_CNT_TRIG0_MASK) | PWMV2_CNT_CFG2_CNT_TRIG0_SET(cal_index);
+}
+
+/**
+ * @brief Set trigmux index to start counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param trig_index trig index
+ */
+static inline void pwmv2_counter_start_select_trigger_index(PWMV2_Type *pwm_x, pwm_counter_t counter, uint8_t trig_index)
+{
+    pwm_x->CNT[counter].CFG3 = (pwm_x->CNT[counter].CFG3 & ~PWMV2_CNT_CFG3_CNT_START_SEL_MASK) | PWMV2_CNT_CFG3_CNT_START_SEL_SET(trig_index);
+}
+
+/**
+ * @brief Enable trigmux to trigger counter initiation
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_start_trigger_enable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG3 |= PWMV2_CNT_CFG3_CNT_HW_START_EN_MASK;
+}
+
+/**
+ * @brief Disable trigmux to trigger counter initiation
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_start_trigger_disable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG3 &= ~PWMV2_CNT_CFG3_CNT_HW_START_EN_MASK;
+}
+
+/**
+ * @brief Set counter burst value
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ * @param burst burst value
+ */
+static inline void pwmv2_set_counter_burst(PWMV2_Type *pwm_x, pwm_counter_t counter, uint16_t burst)
+{
+    pwm_x->CNT[counter].CFG3 |= PWMV2_CNT_CFG3_CNT_BURST_SET(burst);
+}
+
+/**
+ * @brief Disable counter burst function
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_counter_burst_disable(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT[counter].CFG3 |= PWMV2_CNT_CFG3_CNT_BURST_MASK;
+}
+
+/**
+ * @brief start pwm output
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_start_pwm_output(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT_GLBCFG |= PWMV2_CNT_GLBCFG_CNT_SW_START_SET((1 << counter));
+}
+
+/**
+ * @brief Reset pwm counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_reset_counter(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT_GLBCFG |= PWMV2_CNT_GLBCFG_TIMER_RESET_SET((1 << counter));
+}
+
+/**
+ * @brief Enable pwm counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_enable_counter(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT_GLBCFG |= PWMV2_CNT_GLBCFG_TIMER_ENABLE_SET((1 << counter));
+}
+
+/**
+ * @brief Disable pwm counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param counter @ref pwm_counter_t
+ */
+static inline void pwmv2_disable_counter(PWMV2_Type *pwm_x, pwm_counter_t counter)
+{
+    pwm_x->CNT_GLBCFG &= ~PWMV2_CNT_GLBCFG_TIMER_ENABLE_SET((1 << counter));
+}
+
+/**
+ * @brief Set calculate up limit parameter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param value parameter
+ */
+static inline void pwmv2_calculate_set_up_limit_parameter(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t value)
+{
+    pwm_x->CAL[cal_index].CFG0 = (pwm_x->CAL[cal_index].CFG0 & ~PWMV2_CAL_CFG0_CAL_LU_PARAM_MASK) | PWMV2_CAL_CFG0_CAL_LU_PARAM_SET(value);
+}
+
+/**
+ * @brief Set calculate low limit parameter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param value parameter
+ */
+static inline void pwmv2_calculate_set_low_limit_parameter(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t value)
+{
+    pwm_x->CAL[cal_index].CFG0 = (pwm_x->CAL[cal_index].CFG0 & ~PWMV2_CAL_CFG0_CAL_LL_PARAM_MASK) | PWMV2_CAL_CFG0_CAL_LL_PARAM_SET(value);
+}
+
+/**
+ * @brief Set calculate period parameter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param value parameter
+ */
+static inline void pwmv2_calculate_set_period_parameter(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t value)
+{
+    pwm_x->CAL[cal_index].CFG0 = (pwm_x->CAL[cal_index].CFG0 & ~PWMV2_CAL_CFG0_CAL_T_PARAM_MASK) | PWMV2_CAL_CFG0_CAL_T_PARAM_SET(value);
+}
+
+/**
+ * @brief Set calculate dac value parameter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param value parameter
+ */
+static inline void pwmv2_calculate_set_dac_value_parameter(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t value)
+{
+    pwm_x->CAL[cal_index].CFG0 = (pwm_x->CAL[cal_index].CFG0 & ~PWMV2_CAL_CFG0_CAL_D_PARAM_MASK) | PWMV2_CAL_CFG0_CAL_D_PARAM_SET(value);
+}
+
+/**
+ * @brief Select calculate index to counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param counter_calculate counter index
+ */
+static inline void pwmv2_calculate_select_counter_calculate_index(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t counter_calculate)
+{
+    pwm_x->CAL[cal_index].CFG1 = (pwm_x->CAL[cal_index].CFG1 & ~PWMV2_CAL_CFG1_CAL_T_INDEX_MASK) | PWMV2_CAL_CFG1_CAL_T_INDEX_SET(counter_calculate);
+}
+
+/**
+ * @brief Select calculate input value
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param index shadow index
+ */
+static inline void pwmv2_calculate_select_in_value(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t index)
+{
+    pwm_x->CAL[cal_index].CFG1 = (pwm_x->CAL[cal_index].CFG1 & ~PWMV2_CAL_CFG1_CAL_IN_INDEX_MASK) | PWMV2_CAL_CFG1_CAL_IN_INDEX_SET(index);
+}
+
+/**
+ * @brief enable calculate up limit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ */
+static inline void pwmv2_calculate_enable_up_limit(PWMV2_Type *pwm_x, uint8_t cal_index)
+{
+    pwm_x->CAL[cal_index].CFG1 |= PWMV2_CAL_CFG1_CAL_LU_EN_MASK;
+}
+
+/**
+ * @brief disable calculate up limit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ */
+static inline void pwmv2_calculate_disable_up_limit(PWMV2_Type *pwm_x, uint8_t cal_index)
+{
+    pwm_x->CAL[cal_index].CFG1 &= ~PWMV2_CAL_CFG1_CAL_LU_EN_MASK;
+}
+
+/**
+ * @brief Select up limit offset from shadow index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param shadow_index shadow index
+ */
+static inline void pwmv2_calculate_select_up_limit_offset(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t shadow_index)
+{
+    pwm_x->CAL[cal_index].CFG1 = (pwm_x->CAL[cal_index].CFG1 & ~PWMV2_CAL_CFG1_CAL_LIM_UP_MASK) | PWMV2_CAL_CFG1_CAL_LIM_UP_SET(shadow_index);
+}
+
+/**
+ * @brief Select low limit offset from shadow index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param shadow_index shadow index
+ */
+static inline void pwmv2_calculate_select_low_limit_offset(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t shadow_index)
+{
+    pwm_x->CAL[cal_index].CFG1 = (pwm_x->CAL[cal_index].CFG1 & ~PWMV2_CAL_CFG1_CAL_LIM_LO_MASK) | PWMV2_CAL_CFG1_CAL_LIM_LO_SET(shadow_index);
+}
+
+/**
+ * @brief Select offset from shadow index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param shadow_index shadow index
+ */
+static inline void pwmv2_calculate_select_in_offset(PWMV2_Type *pwm_x, uint8_t cal_index, uint8_t shadow_index)
+{
+    pwm_x->CAL[cal_index].CFG1 = (pwm_x->CAL[cal_index].CFG1 & ~PWMV2_CAL_CFG1_CAL_IN_OFF_MASK) | PWMV2_CAL_CFG1_CAL_IN_OFF_SET(shadow_index);
+}
+
+/**
+ * @brief enable low limit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ */
+static inline void pwmv2_calculate_enable_low_limit(PWMV2_Type *pwm_x, uint8_t cal_index)
+{
+    pwm_x->CAL[cal_index].CFG1 |= PWMV2_CAL_CFG1_CAL_LL_EN_MASK;
+}
+
+/**
+ * @brief disable low limit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ */
+static inline void pwmv2_calculate_disable_low_limit(PWMV2_Type *pwm_x, uint8_t cal_index)
+{
+    pwm_x->CAL[cal_index].CFG1 &= ~PWMV2_CAL_CFG1_CAL_LL_EN_MASK;
+}
+
+/**
+ * @brief Select cmp trigmux index
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ * @param trig_index trigmux index
+ */
+static inline void pwmv2_select_cmp_trigmux(PWMV2_Type *pwm_x, uint8_t cmp_index, uint8_t trig_index)
+{
+    pwm_x->CMP[cmp_index].CFG = (pwm_x->CMP[cmp_index].CFG & ~PWMV2_CMP_CFG_CMP_TRIG_SEL_MASK) | PWMV2_CMP_CFG_CMP_TRIG_SEL_SET(trig_index);
+}
+
+/**
+ * @brief Select cmp update trigmux time
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ * @param trig_time @ref pwm_cmp_shadow_register_update_trigger_t
+ */
+static inline void pwmv2_cmp_update_trig_time(PWMV2_Type *pwm_x, uint8_t cmp_index, pwm_cmp_shadow_register_update_trigger_t trig_time)
+{
+    pwm_x->CMP[cmp_index].CFG = (pwm_x->CMP[cmp_index].CFG & ~PWMV2_CMP_CFG_CMP_UPDATE_TIME_MASK) | PWMV2_CMP_CFG_CMP_UPDATE_TIME_SET(trig_time);
+}
+
+/**
+ * @brief Select cmp source
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ * @param cmp_sel @ref pwm_cmp_source_t
+ * @param index source index
+ */
+static inline void pwmv2_select_cmp_source(PWMV2_Type *pwm_x, uint8_t cmp_index, pwm_cmp_source_t cmp_sel, uint8_t index)
+{
+    pwm_x->CMP[cmp_index].CFG = (pwm_x->CMP[cmp_index].CFG & ~PWMV2_CMP_CFG_CMP_IN_SEL_MASK) | PWMV2_CMP_CFG_CMP_IN_SEL_SET((cmp_sel + index));
+}
+
+/**
+ * @brief Select cmp use counter
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cmp_index cmp index
+ * @param counter_index @ref pwm_counter_t
+ */
+static inline void pwmv2_cmp_select_counter(PWMV2_Type *pwm_x, uint8_t cmp_index, pwm_counter_t counter_index)
+{
+    if (cmp_index >= 16) {
+        pwm_x->CMP[cmp_index].CFG = (pwm_x->CMP[cmp_index].CFG & ~PWMV2_CMP_CFG_CMP_CNT_MASK) | PWMV2_CMP_CFG_CMP_CNT_SET((counter_index));
+    }
+}
+
+/**
+ * @brief config pwm cmp
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param index cmp index
+ * @param config @ref pwmv2_cmp_config_t
+ */
+void pwmv2_config_cmp(PWMV2_Type *pwm_x, uint8_t index, pwmv2_cmp_config_t *config);
+
+/**
+ * @brief config async fault source
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param index cmp index
+ * @param config @ref pwmv2_async_fault_source_config_t
+ */
+void pwmv2_config_async_fault_source(PWMV2_Type *pwm_x, pwm_channel_t index, pwmv2_async_fault_source_config_t *config);
+
+/**
+ * @brief config pwm
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param index @ref pwm_channel_t
+ * @param config @ref pwmv2_config_t
+ * @param enable_pair_mode bool
+ */
+void pwmv2_config_pwm(PWMV2_Type *pwm_x, pwm_channel_t index, pwmv2_config_t *config, bool enable_pair_mode);
+
+/**
+ * @brief Set pwm waveform
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param pwm_config @ref pwmv2_config_t
+ * @param cmp_start_index cmp start index
+ * @param cmp @ref pwmv2_cmp_config_t
+ * @param cmp_num cmp number
+ * @return hpm_stat_t @ref hpm_stat_t
+ */
+hpm_stat_t pwmv2_setup_waveform(PWMV2_Type *pwm_x,
+                        pwm_channel_t chn, pwmv2_config_t *pwm_config,
+                        uint8_t cmp_start_index, pwmv2_cmp_config_t *cmp, uint8_t cmp_num);
+
+/**
+ * @brief set the pwm waveform complementary mode
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param chn @ref pwm_channel_t
+ * @param pwm_pair_config @ref pwmv2_pair_config_t
+ * @param cmp_start_index cmp start index
+ * @param cmp @ref pwmv2_cmp_config_t
+ * @param cmp_num cmp number
+ * @return hpm_stat_t @ref hpm_stat_t
+ */
+hpm_stat_t pwmv2_setup_waveform_in_pair(PWMV2_Type *pwm_x, pwm_channel_t chn,
+                        pwmv2_pair_config_t *pwm_pair_config, uint8_t cmp_start_index,
+                        pwmv2_cmp_config_t *cmp, uint8_t cmp_num);
+
+/**
+ * @brief Configure the cmp calculate unit
+ *
+ * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
+ * @param cal_index calculate index
+ * @param cal @ref pwmv2_cmp_calculate_cfg_t
+ */
+void pwmv2_setup_cmp_calculate(PWMV2_Type *pwm_x, uint8_t cal_index, pwmv2_cmp_calculate_cfg_t *cal);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_PWMV2_DRV_H */

+ 186 - 12
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_qeiv2_drv.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 HPMicro
+ * Copyright (c) 2023-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -9,6 +9,7 @@
 #define HPM_QEIV2_DRV_H
 
 #include "hpm_common.h"
+#include "hpm_soc_ip_feature.h"
 #include "hpm_qeiv2_regs.h"
 /**
  * @brief QEIV2 driver APIs
@@ -1039,6 +1040,190 @@ static inline void qeiv2_set_cycle1_num(QEIV2_Type *qeiv2_x, uint32_t cycle_num)
     qeiv2_x->CYCLE1_NUM = QEIV2_CYCLE1_NUM_CYCLE1_NUM_SET(cycle_num);
 }
 
+#if defined(HPM_IP_FEATURE_QEIV2_ONESHOT_MODE) && HPM_IP_FEATURE_QEIV2_ONESHOT_MODE
+/**
+ * @brief disable cycle0 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_cycle0_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_CYCLE0_ONESHOT_MASK;
+}
+
+/**
+ * @brief enable cycle0 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_cycle0_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_CYCLE0_ONESHOT_MASK;
+}
+
+/**
+ * @brief disable cycle1 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_cycle1_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_CYCLE1_ONESHOT_MASK;
+}
+
+/**
+ * @brief enable cycle1 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_cycle1_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_CYCLE1_ONESHOT_MASK;
+}
+
+/**
+ * @brief disable pulse0 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_pulse0_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_PULSE0_ONESHOT_MASK;
+}
+
+/**
+ * @brief enable pulse0 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_pulse0_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_PULSE0_ONESHOT_MASK;
+}
+
+/**
+ * @brief disable pulse1 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_pulse1_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_PULSE1_ONESHOT_MASK;
+}
+
+/**
+ * @brief enable pulse1 oneshot mode
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_pulse1_oneshot_mode(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_PULSE1_ONESHOT_MASK;
+}
+#endif
+
+#if defined(HPM_IP_FEATURE_QEIV2_SW_RESTART_TRG) && HPM_IP_FEATURE_QEIV2_SW_RESTART_TRG
+/**
+ * @brief disable trigger cycle0
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_trig_cycle0(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_TRIG_CYCLE0_EN_MASK;
+}
+
+/**
+ * @brief enable trigger cycle0
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_trig_cycle0(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_TRIG_CYCLE0_EN_MASK;
+}
+
+/**
+ * @brief disable trigger cycle1
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_trig_cycle1(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_TRIG_CYCLE1_EN_MASK;
+}
+
+/**
+ * @brief enable trigger cycle1
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_trig_cycle1(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_TRIG_CYCLE1_EN_MASK;
+}
+
+/**
+ * @brief disable trigger pulse0
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_trig_pulse0(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_TRIG_PULSE0_EN_MASK;
+}
+
+/**
+ * @brief enable trigger pulse0
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_trig_pulse0(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_TRIG_PULSE0_EN_MASK;
+}
+
+/**
+ * @brief disable trigger pulse1
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_disable_trig_pulse1(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG &= ~QEIV2_QEI_CFG_TRIG_PULSE1_EN_MASK;
+}
+
+/**
+ * @brief enable trigger pulse1
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_enable_trig_pulse1(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_TRIG_PULSE1_EN_MASK;
+}
+
+/**
+ * @brief software restart cycle0
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_sw_restart_cycle0(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_SW_PULSE0_RESTART_MASK;
+}
+
+/**
+ * @brief software restart cycle1
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_sw_restart_cycle1(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_SW_PULSE1_RESTART_MASK;
+}
+
+/**
+ * @brief software restart pulse0
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_sw_restart_pulse0(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_SW_CYCLE0_RESTART_MASK;
+}
+
+/**
+ * @brief software restart pulse1
+ * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
+ */
+static inline void qeiv2_sw_restart_pulse1(QEIV2_Type *qeiv2_x)
+{
+    qeiv2_x->QEI_CFG |= QEIV2_QEI_CFG_SW_CYCLE1_RESTART_MASK;
+}
+#endif
+
 /**
  * @brief get pulse1 snap0 value
  *
@@ -1320,17 +1505,6 @@ static inline uint32_t qeiv2_get_angle(QEIV2_Type *qeiv2_x)
     return qeiv2_x->ANGLE;
 }
 
-/**
- * @brief set angle adjust value
- *
- * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n)
- * @param[in] angle_adj angle adjust value
- */
-static inline void qeiv2_set_angle_adjust_value(QEIV2_Type *qeiv2_x, int32_t angle_adj)
-{
-    qeiv2_x->ANGLE_ADJ = QEIV2_ANGLE_ADJ_ANGLE_ADJ_SET(angle_adj);
-}
-
 /**
  * @brief config position timeout for mmc module
  *

+ 676 - 0
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_qeov2_drv.h

@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_QEOV2_DRV_H
+#define HPM_QEOV2_DRV_H
+
+#include "hpm_common.h"
+#include "hpm_qeov2_regs.h"
+/**
+ * @brief QEOV2 driver APIs
+ * @defgroup qeov2_interface QEOV2 driver APIs
+ * @ingroup qeov2_interfaces
+ * @{
+ */
+
+typedef enum {
+    qeo_wave_cosine = 0,
+    qeo_wave_saddle = 1,
+    qeo_wave_abs_cosine = 2,
+    qeo_wave_saw = 3,
+} qeo_wave_type_t;
+
+typedef enum {
+    qeo_saddle_standard = 0,
+    qeo_saddle_triple
+} qeo_saddle_type_t;
+
+typedef enum {
+    qeo_wave_above_max_limit_max_val = 0,
+    qeo_wave_above_max_limit_zero = 1,
+    qeo_wave_above_max_limit_max_level0_val = 2,
+
+    qeo_wave_high_area_limit_max_val = 0,
+    qeo_wave_high_area_limit_max_level0_val = 1,
+
+    qeo_wave_low_area_limit_zero = 0,
+    qeo_wave_low_area_limit_min_level1_val = 1,
+
+    qeo_wave_below_min_limit_zero = 0,
+    qeo_wave_below_min_limit_max_val = 1,
+    qeo_wave_below_min_limit_min_level1_val = 2,
+} qeo_wave_limit_t;
+
+typedef struct {
+    qeo_wave_limit_t above_max_limit;
+    qeo_wave_limit_t high_area0_limit;
+    qeo_wave_limit_t high_area1_limit;
+    qeo_wave_limit_t low_area0_limit;
+    qeo_wave_limit_t low_area1_limit;
+    qeo_wave_limit_t below_min_limit;
+} qeo_wave_limit_config_t;
+
+typedef struct {
+    qeo_wave_limit_config_t wave0;
+    qeo_wave_limit_config_t wave1;
+    qeo_wave_limit_config_t wave2;
+    bool dq_valid_trig_enable; /*!< DQ valid trigger calculate */
+    bool pos_valid_trig_enable; /*!< Position valid trigger calculate */
+    bool vd_vq_inject_enable;
+    bool vd_vq_from_sw; /*!< true: DQ from register; false: DQ from CLC module */
+    qeo_wave_type_t wave_type;
+    qeo_saddle_type_t saddle_type;
+} qeo_wave_mode_t;
+
+typedef enum {
+    qeo_abz_output_abz = 0, /*!< A and B are orthogonal signals, Z is zero pulse */
+    qeo_abz_output_pulse_revise = 1, /*!< A is speed pulse, B is directional pulse, Z not used */
+    qeo_abz_output_up_down = 2, /*!< A is forward pulse, B is reverse pusle, Z not used */
+    qeo_abz_output_three_phase = 3, /*!< A/B/Z are 3-phase orthogonal pulse */
+} qeo_abz_type_t;
+
+typedef enum {
+    qeo_z_as_zero_signal_mode0 = 0,
+    qeo_z_as_zero_signal_mode1 = 1,
+    qeo_z_as_no_output_signal = 2,
+    qeo_z_as_third_phase_signal = 3,
+} qeo_z_pulse_type_t;
+
+typedef struct {
+    bool z_inv_pol;
+    bool b_inv_pol;
+    bool a_inv_pol;
+    bool enable_wdog;
+    bool sync_step_position;
+    bool reverse_align_clk_falling_edge;
+    qeo_abz_type_t output_type; /*!< @ref qeo_abz_type_t */
+} qeo_abz_mode_t;
+
+/*!< zero pusle legth mode */
+typedef struct {
+    uint8_t type;
+    uint32_t start_line;
+    uint32_t end_line;
+    uint8_t  start_step;
+    uint8_t  end_step;
+    uint32_t width;
+} qeo_z_output_mode_t;
+
+typedef enum {
+    qeo_pwm_output_force_0 = 2,
+    qeo_pwm_output_force_1 = 3,
+    qeo_pwm_output_not_force = 0,
+} qeo_pwm_force_output_t;
+
+typedef enum {
+    qeo_pwm_safety_output_0 = 0,
+    qeo_pwm_safety_output_1 = 1,
+    qeo_pwm_safety_output_highz = 2,
+} qeo_pwm_safety_output_t;
+
+typedef struct {
+    qeo_pwm_force_output_t pwm0_output; /*!< @ref qeo_pwm_force_output_t */
+    qeo_pwm_force_output_t pwm1_output;
+    qeo_pwm_force_output_t pwm2_output;
+    qeo_pwm_force_output_t pwm3_output;
+    qeo_pwm_force_output_t pwm4_output;
+    qeo_pwm_force_output_t pwm5_output;
+    qeo_pwm_force_output_t pwm6_output;
+    qeo_pwm_force_output_t pwm7_output;
+} qeo_pwm_phase_output_table_t;
+
+typedef struct {
+    qeo_pwm_safety_output_t pwm0_output; /*!< @ref qeo_pwm_safety_output_t */
+    qeo_pwm_safety_output_t pwm1_output;
+    qeo_pwm_safety_output_t pwm2_output;
+    qeo_pwm_safety_output_t pwm3_output;
+    qeo_pwm_safety_output_t pwm4_output;
+    qeo_pwm_safety_output_t pwm5_output;
+    qeo_pwm_safety_output_t pwm6_output;
+    qeo_pwm_safety_output_t pwm7_output;
+} qeo_pwm_safety_output_table_t;
+
+typedef struct {
+    uint8_t phase_num;
+    bool shield_hardware_trig_safety;
+    bool revise_pairs_output;
+} qeo_pwm_mode_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* WAVE API */
+/**
+ * @brief QEO set resolution lines for wave mode
+ * @param [in] base QEO base address
+ * @param [in] lines resolution lines
+ */
+static inline void qeo_wave_set_resolution_lines(QEOV2_Type *base, uint32_t lines)
+{
+    base->WAVE.RESOLUTION = QEOV2_WAVE_RESOLUTION_LINES_SET(lines);
+}
+
+/**
+ * @brief QEO set output type for wave mode
+ * @param [in] base QEO base address
+ * @param [in] type qeo_wave_type_t
+ */
+static inline void qeo_wave_set_output_type(QEOV2_Type *base, qeo_wave_type_t type)
+{
+    base->WAVE.MODE = (base->WAVE.MODE & ~QEOV2_WAVE_MODE_WAVES_OUTPUT_TYPE_MASK) | QEOV2_WAVE_MODE_WAVES_OUTPUT_TYPE_SET(type);
+}
+
+/**
+ * @brief QEO set saddle type for wave mode
+ * @param [in] base QEO base address
+ * @param [in] standard true for standard saddle, false for triangular wave stacking
+ */
+static inline void qeo_wave_set_saddle_type(QEOV2_Type *base, bool standard)
+{
+    if (standard) {
+        base->WAVE.MODE &= ~QEOV2_WAVE_MODE_SADDLE_TYPE_MASK;
+    } else {
+        base->WAVE.MODE |= QEOV2_WAVE_MODE_SADDLE_TYPE_MASK;
+    }
+}
+
+/**
+ * @brief QEO set phase shift for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @param [in] angle left shift angle
+ */
+static inline void qeo_wave_set_phase_shift(QEOV2_Type *base, uint8_t index, double angle)
+{
+    assert((angle >= 0) && (angle <= 360));
+    uint32_t val = (uint32_t)(angle * 0x100000000UL / 360);
+    base->WAVE.PHASE_SHIFT[index] = QEOV2_WAVE_PHASE_SHIFT_VAL_SET(val);
+}
+
+/**
+ * @brief QEO enable vd vq inject and select vq vq source for wave mode
+ * @param [in] base QEO base address
+ * @param [in] from_sw false for vd vq data from clc module, true for vd vq from software inject register
+ */
+static inline void qeo_wave_enable_vd_vq_inject(QEOV2_Type *base, bool from_sw)
+{
+    if (from_sw) {
+        base->WAVE.MODE |= QEOV2_WAVE_MODE_VD_VQ_SEL_MASK;
+    } else {
+        base->WAVE.MODE &= ~QEOV2_WAVE_MODE_VD_VQ_SEL_MASK;
+    }
+    base->WAVE.MODE |= QEOV2_WAVE_MODE_EN_WAVE_VD_VQ_INJECT_MASK;
+}
+
+/**
+ * @brief QEO disable vd vq inject for wave mode
+ * @param [in] base QEO base address
+ */
+static inline void qeo_wave_disable_vd_vq_inject(QEOV2_Type *base)
+{
+    base->WAVE.MODE &= ~QEOV2_WAVE_MODE_EN_WAVE_VD_VQ_INJECT_MASK;
+}
+
+/**
+ * @brief QEO config vd vq value when vd vq from register
+ * @param [in] base QEO base address
+ * @param [in] vd_val vd value
+ * @param [in] vq_val vq value
+ */
+static inline void qeo_wave_config_vd_vq_value(QEOV2_Type *base, int32_t vd_val, int32_t vq_val)
+{
+    base->WAVE.VD_INJECT = QEOV2_WAVE_VD_INJECT_VD_VAL_SET(vd_val);
+    base->WAVE.VQ_INJECT = QEOV2_WAVE_VQ_INJECT_VQ_VAL_SET(vq_val);
+}
+
+/**
+ * @brief QEO load vd vq inject value when vd vq from register
+ * @param [in] base QEO base address
+ */
+static inline void qeo_wave_load_vd_vq(QEOV2_Type *base)
+{
+    base->WAVE.VD_VQ_LOAD = QEOV2_WAVE_VD_VQ_LOAD_LOAD_MASK;
+}
+
+/**
+ * @brief QEO enable amplitude for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @param [in] amp amplitude value
+ */
+static inline void qeo_wave_enable_amplitude(QEOV2_Type *base, uint8_t index, double amp)
+{
+    assert(amp > 0);
+    uint32_t val = (uint32_t)(amp * (1U << 12U));
+    base->WAVE.AMPLITUDE[index] = QEOV2_WAVE_AMPLITUDE_EN_SCAL_MASK | QEOV2_WAVE_AMPLITUDE_AMP_VAL_SET(val);
+}
+
+/**
+ * @brief QEO disable amplitude for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ */
+static inline void qeo_wave_disable_amplitude(QEOV2_Type *base, uint8_t index)
+{
+    base->WAVE.AMPLITUDE[index] &= ~QEOV2_WAVE_AMPLITUDE_EN_SCAL_MASK;
+}
+
+/**
+ * @brief QEO set mid point shift for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @param [in] shift mid point shift value
+ */
+static inline void qeo_wave_set_mid_point_shift(QEOV2_Type *base, uint8_t index, double shift)
+{
+    int32_t val = (int32_t)(shift * (1U << 27U));
+    base->WAVE.MID_POINT[index] = QEOV2_WAVE_MID_POINT_VAL_SET(val);
+}
+
+/**
+ * @brief QEO set max limmit for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @param [in] limit0 limit0 value
+ * @param [in] limit1 limit1 value
+ */
+static inline void qeo_wave_set_max_limit(QEOV2_Type *base, uint8_t index, uint32_t limit0, uint32_t limit1)
+{
+    base->WAVE.LIMIT0[index].MAX_LEVEL0 = QEOV2_WAVE_LIMIT0_MAX_LEVEL0_LIMIT_LEVEL0_SET(limit0);
+    base->WAVE.LIMIT1[index].MAX_LEVEL1 = QEOV2_WAVE_LIMIT1_MAX_LEVEL1_LIMIT_LEVEL1_SET(limit1);
+}
+
+/**
+ * @brief QEO set min limmit for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @param [in] limit0 limit0 value
+ * @param [in] limit1 limit1 value
+ */
+static inline void qeo_wave_set_min_limit(QEOV2_Type *base, uint8_t index, uint32_t limit0, uint32_t limit1)
+{
+    base->WAVE.LIMIT0[index].MIN_LEVEL0 = QEOV2_WAVE_LIMIT0_MIN_LEVEL0_LIMIT_LEVEL0_SET(limit0);
+    base->WAVE.LIMIT1[index].MIN_LEVEL1 = QEOV2_WAVE_LIMIT1_MIN_LEVEL1_LIMIT_LEVEL1_SET(limit1);
+}
+
+/**
+ * @brief QEO set deadzone shift for wave mode
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @param [in] shift deadzone shift value
+ */
+static inline void qeo_wave_set_deadzone_shift(QEOV2_Type *base, uint8_t index, int32_t shift)
+{
+    base->WAVE.DEADZONE_SHIFT[index] = QEOV2_WAVE_DEADZONE_SHIFT_VAL_SET(shift);
+}
+
+/**
+ * @brief QEO wave set pwm cycle
+ *
+ * @note when cycle is 0, output value is 0 - 0xFFFFFFFF, others, output value is 0 - cycle
+ *
+ * @param [in] base QEO base address
+ * @param [in] cycle pwm period cycle
+ */
+static inline void qeo_wave_set_pwm_cycle(QEOV2_Type *base, uint32_t cycle)
+{
+    base->WAVE.PWM_CYCLE = QEOV2_WAVE_PWM_CYCLE_VAL_SET(cycle);
+}
+
+/**
+ * @brief QEO get wave output value
+ * @param [in] base QEO base address
+ * @param [in] index wave index(0/1/2)
+ * @retval wave output value
+ */
+static inline uint32_t qeo_get_wave_output_val(QEOV2_Type *base, uint8_t index)
+{
+    if (index == 0) {
+        return QEOV2_DEBUG0_VALUE_DAC0_GET(base->DEBUG0);
+    } else if (index == 1) {
+        return QEOV2_DEBUG4_VALUE_DAC1_GET(base->DEBUG4);
+    } else if (index  == 2) {
+        return QEOV2_DEBUG5_VALUE_DAC2_GET(base->DEBUG5);
+    }
+    return 0;
+}
+
+/**
+ * @brief QEO wave get defalut mode config
+ * @param [in] base QEO base address
+ * @param [in] config qeo_wave_mode_t
+ */
+void qeo_wave_get_default_mode_config(QEOV2_Type *base, qeo_wave_mode_t *config);
+
+/**
+ * @brief QEO wave config mode
+ * @param [in] base QEO base address
+ * @param [in] config qeo_wave_mode_t
+ */
+void qeo_wave_config_mode(QEOV2_Type *base, qeo_wave_mode_t *config);
+
+/* ABZ API */
+/**
+ * @brief QEO set resolution lines for ABZ mode
+ * @param [in] base QEO base address
+ * @param [in] lines resolution lines
+ */
+static inline void qeo_abz_set_resolution_lines(QEOV2_Type *base, uint32_t lines)
+{
+    base->ABZ.RESOLUTION = QEOV2_ABZ_RESOLUTION_LINES_SET(lines);
+}
+
+/**
+ * @brief QEO set phase shift for three phase output mode
+ * @param [in] base QEO base address
+ * @param [in] index ABZ index(0/1/2)
+ * @param [in] angle left shift angle
+ */
+static inline void qeo_abz_set_phase_shift(QEOV2_Type *base, uint8_t index, double angle)
+{
+    assert((angle >= 0) && (angle <= 360));
+    uint32_t val = (uint32_t)(angle * 0x100000000U / 360);
+    base->ABZ.PHASE_SHIFT[index] = QEOV2_ABZ_PHASE_SHIFT_VAL_SET(val);
+}
+
+/**
+ * @brief QEO set offset for output signal in ABZ mode
+ * @param [in] base QEO base address
+ * @param [in] physical_angle physical angle
+ */
+static inline void qeo_abz_set_offset(QEOV2_Type *base, double physical_angle)
+{
+    assert((physical_angle >= 0) && (physical_angle <= 360));
+    uint32_t val = (uint32_t)(physical_angle * 0x100000000U / 360);
+    base->ABZ.OVERALL_OFFSET = QEOV2_ABZ_OVERALL_OFFSET_VAL_SET(val);
+}
+
+/**
+ * @brief QEO set max frequency for ABZ mode
+ * @param [in] base QEO base address
+ * @param [in] src_freq QEO(MOTO system) frequency
+ * @param [in] freq abz signal frequency (A pulse frequency)
+ * @retval status_success or status_invalid_argument
+ */
+hpm_stat_t qeo_abz_set_max_frequency(QEOV2_Type *base, uint32_t src_freq, uint32_t freq);
+
+/**
+ * @brief QEO set wdog frequency for ABZ mode
+ * @param [in] base QEO base address
+ * @param [in] src_freq QEO(MOTO system) frequency
+ * @param [in] freq wdog frequency
+ * @retval status_success or status_invalid_argument
+ */
+hpm_stat_t qeo_abz_set_wdog_frequency(QEOV2_Type *base, uint32_t src_freq, uint32_t freq);
+
+/**
+ * @brief QEO disable wdog for ABZ mode
+ * @param [in] base QEO base address
+ */
+static inline void qeo_abz_disable_wdog(QEOV2_Type *base)
+{
+    base->ABZ.MODE &= ~QEOV2_ABZ_MODE_EN_WDOG_MASK;
+}
+
+/**
+ * @brief QEO config reverse edge for ABZ mode
+ * @param [in] base QEO base address
+ * @param [in] speed_pulse_negedge true for reverse edge point speed pulse's negedge
+ * false for reverse edge point between speed pulse's posedge and negedge, min period dedicated by the num line_width
+ *
+ * @note take effect when ABZ work on qeo_abz_output_pulse_revise mode
+ */
+static inline void qeo_abz_config_reverse_edge(QEOV2_Type *base, bool speed_pulse_negedge)
+{
+    if (speed_pulse_negedge) {
+        base->ABZ.MODE |= QEOV2_ABZ_MODE_REVERSE_EDGE_TYPE_MASK;
+    } else {
+        base->ABZ.MODE &= ~QEOV2_ABZ_MODE_REVERSE_EDGE_TYPE_MASK;
+    }
+}
+
+/**
+ * @brief QEO ABZ get default mode config
+ * @param [in] base QEO base address
+ * @param [in] config qeo_abz_mode_t
+ */
+void qeo_abz_get_default_mode_config(QEOV2_Type *base, qeo_abz_mode_t *config);
+
+/**
+ * @brief QEO ABZ config mode
+ * @param [in] base QEO base address
+ * @param [in] config qeo_abz_mode_t
+ */
+void qeo_abz_config_mode(QEOV2_Type *base, qeo_abz_mode_t *config);
+
+/**
+ * @brief QEO ABZ mode enable output
+ * @param [in] base QEO base address
+ */
+static inline void qeo_abz_enable_output(QEOV2_Type *base)
+{
+    base->ABZ.MODE |= QEOV2_ABZ_MODE_ABZ_OUTPUT_ENABLE_MASK;
+}
+
+/**
+ * @brief QEO ABZ mode disable output
+ * @param [in] base QEO base address
+ */
+static inline void qeo_abz_disable_output(QEOV2_Type *base)
+{
+    base->ABZ.MODE &= ~QEOV2_ABZ_MODE_ABZ_OUTPUT_ENABLE_MASK;
+}
+
+/**
+ * @brief QEO ABZ mode enable and configure position sync mode
+ * @param [in] base QEO base address
+ * @param [in] sync_identical_pos true: sync identical posistion; false: sync step of position
+ */
+static inline void qeo_abz_enable_position_sync(QEOV2_Type *base, bool sync_identical_pos)
+{
+    if (sync_identical_pos) {
+        base->ABZ.MODE |= QEOV2_ABZ_MODE_POSITION_SYNC_MODE_MASK;
+    } else {
+        base->ABZ.MODE &= ~QEOV2_ABZ_MODE_POSITION_SYNC_MODE_MASK;
+    }
+
+    base->ABZ.POSTION_SYNC = QEOV2_ABZ_POSTION_SYNC_POSTION_MASK;
+}
+
+/**
+ * @brief QEO ABZ mode get default zero pulse output mode
+ * @param [in] base QEO base address
+ * @param [out] mode qeo_z_output_mode_t
+ */
+void qeo_abz_get_default_z_output_mode(QEOV2_Type *base, qeo_z_output_mode_t *mode);
+
+/**
+ * @brief QEO ABZ mode configure zero pulse output mode
+ * @param [in] base QEO base address
+ * @param [in] mode qeo_z_output_mode_t
+ */
+void qeo_abz_config_z_output_mode(QEOV2_Type *base, qeo_z_output_mode_t *mode);
+
+/* PWM API */
+/**
+ * @brief QEO set resolution lines for PWM mode
+ * @param [in] base QEO base address
+ * @param [in] lines resolution lines
+ */
+static inline void qeo_pwm_set_resolution_lines(QEOV2_Type *base, uint32_t lines)
+{
+    base->PWM.RESOLUTION = QEOV2_PWM_RESOLUTION_LINES_SET(lines);
+}
+
+/**
+ * @brief QEO set phase shift for PWM mode
+ * @param [in] base QEO base address
+ * @param [in] index PWM index(0/1/2/3)
+ * @param [in] angle left shift angle
+ */
+static inline void qeo_pwm_set_phase_shift(QEOV2_Type *base, uint8_t index, double angle)
+{
+    assert((angle >= 0) && (angle <= 360));
+    uint32_t val = (uint32_t)(angle * 0x1000010000U / 360);
+    base->PWM.PHASE_SHIFT[index] = QEOV2_PWM_PHASE_SHIFT_VAL_SET(val);
+}
+
+/**
+ * @brief QEO PWM mode enable output
+ * @param [in] base QEO base address
+ */
+static inline void qeo_pwm_enable_output(QEOV2_Type *base)
+{
+    base->PWM.MODE |= QEOV2_PWM_MODE_ENABLE_PWM_MASK;
+}
+
+/**
+ * @brief QEO PWM mode disable output
+ * @param [in] base QEO base address
+ */
+static inline void qeo_pwm_disable_output(QEOV2_Type *base)
+{
+    base->PWM.MODE &= ~QEOV2_PWM_MODE_ENABLE_PWM_MASK;
+}
+
+/**
+ * @brief QEO PWM check if it is triggered by hardware to enter safety mode
+ *
+ * @note This bit is only valid if the hardware trigger source has not been cleared
+ *
+ * @param [in] base QEO base address
+ * @retval true or false
+ */
+static inline bool qeo_pwm_check_hardware_trig_safety(QEOV2_Type *base)
+{
+    return ((base->STATUS & QEOV2_STATUS_PWM_SAFETY_MASK) != 0) ? true : false;
+}
+
+/**
+ * @brief QEO PWM select phase table
+ * @param [in] base QEO base address
+ * @param [in] positive true for using positive phase table, false for using negative phase table
+ */
+static inline void qeo_pwm_select_phase_table(QEOV2_Type *base, bool positive)
+{
+    if (positive) {
+        base->PWM.MODE &= ~QEOV2_PWM_MODE_REVISE_UP_DN_MASK;
+    } else {
+        base->PWM.MODE |= QEOV2_PWM_MODE_REVISE_UP_DN_MASK;
+    }
+}
+
+/**
+ * @brief QEO PWM enter safety mode by software
+ *
+ * @note call qeo_pwm_software_exit_safety to exit safety mode
+ *
+ * @param [in] base QEO base address
+ */
+static inline void qeo_pwm_software_enter_safety(QEOV2_Type *base)
+{
+    base->PWM.MODE |= QEOV2_PWM_MODE_PWM_ENTER_SAFETY_MODE_MASK;
+}
+
+/**
+ * @brief QEO PWM exit safety mode by software
+ * @param [in] base QEO base address
+ */
+static inline void qeo_pwm_software_exit_safety(QEOV2_Type *base)
+{
+    base->PWM.MODE &= ~QEOV2_PWM_MODE_PWM_ENTER_SAFETY_MODE_MASK;
+}
+
+/**
+ * @brief QEO PWM get default mode config
+ * @param [in] base QEO base address
+ * @param [in] config qeo_pwm_mode_t
+ */
+void qeo_pwm_get_default_mode_config(QEOV2_Type *base, qeo_pwm_mode_t *config);
+
+/**
+ * @brief QEO PWM config mode
+ * @param [in] base QEO base address
+ * @param [in] config qeo_pwm_mode_t
+ */
+void qeo_pwm_config_mode(QEOV2_Type *base, qeo_pwm_mode_t *config);
+
+/**
+ * @brief QEO PWM get default safety table
+ * @param [in] base QEO base address
+ * @param [in] table qeo_pwm_safety_output_table_t
+ */
+void qeo_pwm_get_default_safety_table_config(QEOV2_Type *base, qeo_pwm_safety_output_table_t *table);
+
+/**
+ * @brief QEO PWM get default phase table
+ * @param [in] base QEO base address
+ * @param [in] table qeo_pwm_phase_output_table_t
+ */
+void qeo_pwm_get_default_phase_table_config(QEOV2_Type *base, qeo_pwm_phase_output_table_t *table);
+
+/**
+ * @brief QEO PWM config safety table
+ * @param [in] base QEO base address
+ * @param [in] table qeo_pwm_safety_output_table_t
+ */
+void qeo_pwm_config_safety_table(QEOV2_Type *base, qeo_pwm_safety_output_table_t *table);
+
+/**
+ * @brief QEO PWM onfig phase table
+ * @param [in] base QEO base address
+ * @param [in] index phase table index
+ * @param [in] table qeo_pwm_phase_output_table_t
+ */
+void qeo_pwm_config_phase_table(QEOV2_Type *base, uint8_t index, qeo_pwm_phase_output_table_t *table);
+
+/**
+ * @brief QEO enable software position inject
+ * @param [in] base QEO base address
+ */
+static inline void qeo_enable_software_position_inject(QEOV2_Type *base)
+{
+    base->POSTION_SEL |= QEOV2_POSTION_SEL_POSTION_SEL_MASK;
+}
+
+/**
+ * @brief QEO software inject position
+ * @param [in] base QEO base address
+ * @param [in] position position value
+ */
+static inline void qeo_software_position_inject(QEOV2_Type *base, uint32_t position)
+{
+    base->POSTION_SOFTWARE = QEOV2_POSTION_SOFTWARE_POSTION_SOFTWAVE_SET(position);
+}
+
+/**
+ * @brief QEO disable software position inject, QEO will using position from hardware
+ * @param [in] base QEO base address
+ */
+static inline void qeo_disable_software_position_inject(QEOV2_Type *base)
+{
+    base->POSTION_SEL &= ~QEOV2_POSTION_SEL_POSTION_SEL_MASK;
+}
+
+/**
+ * @brief QEO check calculate finish status
+ * @param [in] base QEO base address
+ * @retval true or false
+ */
+static inline bool qeo_check_calculate_finish(QEOV2_Type *base)
+{
+    return (QEOV2_DEBUG1_QEO_FINISH_GET(base->DEBUG1) != 0) ? true : false;
+}
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* HPM_QEOV2_DRV_H */

+ 90 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_rdc_drv.h

@@ -134,6 +134,11 @@ typedef enum rdc_input_acc_chn {
     rdc_acc_chn_q = 1
 } rdc_input_acc_chn_t;
 
+typedef enum rdc_input_max_min_value_source {
+    rdc_value_at_adc = 0,
+    rdc_value_at_iir = 1
+} rdc_input_max_min_value_source_t;
+
 /**
  * @brief Rdc status flags
  *
@@ -188,7 +193,11 @@ typedef struct rdc_output_cfg {
  */
 typedef struct rdc_input_cfg {
     rdc_rectify_signal_t rectify_signal_sel;    /**< Select reference point of rectify signal */
-    uint8_t acc_cycle_len;  /**< Accumulate time, support on the fly change */
+#if defined(HPM_IP_FEATURE_RDC_IIR) && (HPM_IP_FEATURE_RDC_IIR)
+    bool acc_fast;          /**< every adc value can be as one accumulate value,  */
+    rdc_input_max_min_value_source_t max_min_value_position;    /**< max min value position */
+#endif
+    uint8_t acc_cycle_len;  /**< Accumulate time, support on the fly change, Only acc_fast is zero, this bit is available */
     rdc_acc_stamp_time_t acc_stamp; /**< Time stamp selection for accumulation */
     uint32_t acc_input_chn_i;   /**< Input channel selection for i_channel */
     uint32_t acc_input_port_i;  /**< Input port selection for i_channel */
@@ -205,6 +214,10 @@ typedef struct rdc_acc_cfg {
         uint16_t continue_edge_num: 3;  /**< Filtering val: 1 - 8 */
         uint16_t edge_distance: 6;  /**< Minimum distance between two edges 0-63 */
     };
+#if defined(HPM_IP_FEATURE_RDC_IIR) && (HPM_IP_FEATURE_RDC_IIR)
+    bool enable_i_thrs_data_for_acc;  /**< enable thrs data for accumulate */
+    bool enable_q_thrs_data_for_acc;  /**< enable thrs data for accumulate */
+#endif
     uint8_t right_shift_without_sign;   /**< Right shift without sign bit */
     bool error_data_remove; /**< Toxic accumulation data be removed */
     uint32_t exc_carrier_period;    /**< The num in clock cycle for period of excitation 0-NULL others-cycles */
@@ -214,6 +227,19 @@ typedef struct rdc_acc_cfg {
     uint32_t amp_min;   /**< The minimum of acc amplitude */
 } rdc_acc_cfg_t;
 
+#if defined(HPM_IP_FEATURE_RDC_IIR) && (HPM_IP_FEATURE_RDC_IIR)
+/**
+ * @brief IIR Filter Configuration
+ *
+ */
+typedef struct rdc_iir_cfg {
+    float b;    /**< IIR parameter for b branch */
+    float a1;   /**< IIR parameter a1 for a1 branch*/
+    float a2;   /**< IIR parameter a1 for a2 branch*/
+    bool enable_lowpass;    /**< IIR in lowpass mode */
+} rdc_iir_cfg_t;
+#endif
+
 /** @} */
 
 /**
@@ -269,6 +295,69 @@ static inline void rdc_acc_disable(RDC_Type *ptr)
     ptr->RDC_CTL &= ~RDC_RDC_CTL_ACC_EN_MASK;
 }
 
+#if defined(HPM_IP_FEATURE_RDC_IIR) && (HPM_IP_FEATURE_RDC_IIR)
+/**
+ * @brief Enable IIR for adc input
+ *
+ * @param ptr @ref RDC_Type base
+ */
+static inline void rdc_irr_enable(RDC_Type *ptr)
+{
+    ptr->RDC_CTL |= RDC_RDC_CTL_IIR_EN_MASK;
+}
+
+/**
+ * @brief Disable IIR for adc input
+ *
+ * @param ptr @ref RDC_Type base
+ */
+static inline void rdc_irr_disable(RDC_Type *ptr)
+{
+    ptr->RDC_CTL &= ~RDC_RDC_CTL_IIR_EN_MASK;
+}
+
+/**
+ * @brief enable i thrs data for accumulate
+ *
+ * @param ptr @ref RDC_Type base
+ */
+static inline void rdc_enable_i_channel_thrs_data_for_acc(RDC_Type *ptr)
+{
+    ptr->THRS_I |= RDC_THRS_I_THRS4ACC_MASK;
+}
+
+/**
+ * @brief disable i thrs data for accumulate
+ *
+ * @param ptr @ref RDC_Type base
+ */
+static inline void rdc_disable_i_channel_thrs_data_for_acc(RDC_Type *ptr)
+{
+    ptr->THRS_I &= ~RDC_THRS_I_THRS4ACC_MASK;
+}
+
+/**
+ * @brief enable q thrs data for accumulate
+ *
+ * @param ptr @ref RDC_Type base
+ */
+static inline void rdc_enable_q_channel_thrs_data_for_acc(RDC_Type *ptr)
+{
+    ptr->THRS_Q |= RDC_THRS_Q_THRS4ACC_MASK;
+}
+
+/**
+ * @brief disable q thrs data for accumulate
+ *
+ * @param ptr @ref RDC_Type base
+ */
+static inline void rdc_disable_q_channel_thrs_data_for_acc(RDC_Type *ptr)
+{
+    ptr->THRS_Q &= ~RDC_THRS_Q_THRS4ACC_MASK;
+}
+
+#endif
+
 /**
  * @brief Get the accumulate value
  *

+ 1 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_romapi_xpi_def.h

@@ -59,7 +59,7 @@ typedef enum {
 } xpi_xfer_channel_t;
 
 /**
- * @brief XPI Channel defitions
+ * @brief XPI Channel definitions
  */
 typedef enum {
     xpi_channel_a1,        /**< Port:  Channel A1 */

+ 1 - 1
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_romapi_xpi_nor_def.h

@@ -205,7 +205,7 @@ enum {
 };
 
 /**
- * @brief Device Mode confiuration structure
+ * @brief Device Mode configuration structure
  */
 typedef struct {
     uint8_t cfg_cmd_type;       /**< Configuration command type */

+ 6 - 3
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_rtc_drv.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -17,7 +17,10 @@
 
 #include "hpm_common.h"
 #include "hpm_rtc_regs.h"
+#ifndef __ICCRISCV__
 #include <sys/time.h>
+#endif
+#include <time.h>
 
 /**
  * @brief RTC alarm configuration
@@ -25,7 +28,7 @@
 typedef struct {
     uint16_t index;         /**< RTC alarm index */
     uint16_t type;          /**< Alarm type */
-    time_t period;          /**< ALarm period */
+    time_t period;          /**< Alarm period */
 } rtc_alarm_config_t;
 
 /**
@@ -59,7 +62,7 @@ hpm_stat_t rtc_config_time(RTC_Type *base, time_t time);
  * @brief Configure RTC Alarm
  * @param [in] base RTC base address
  * @param [in] config RTC alarm configuration pointer
- * @retval API execution status status_success or status_invalid_arugment;
+ * @retval API execution status status_success or status_invalid_argument;
  */
 hpm_stat_t rtc_config_alarm(RTC_Type *base, rtc_alarm_config_t *config);
 

+ 224 - 28
bsp/hpmicro/libraries/hpm_sdk/drivers/inc/hpm_sdp_drv.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -63,12 +63,39 @@ typedef sdp_crypto_op_t sdp_sm4_op_t;
  *
  */
 typedef enum {
-    sdp_crypto_alg_aes, /**< AES */
+    sdp_crypto_alg_aes = 0, /**< AES */
 #if defined(SDP_HAS_SM4_SUPPORT) && (SDP_HAS_SM4_SUPPORT == 1)
-    sdp_crypto_alg_sm4, /**< SM4 */
+    sdp_crypto_alg_sm4 = 1, /**< SM4 */
 #endif
 } sdp_crypto_alg_t;
 
+/**
+ * @brief  SDP Crypto modes
+ */
+typedef enum {
+    sdp_crypto_mode_ecb = 0,    /*!< ECB mode */
+    sdp_crypto_mode_cbc = 1,    /*!< CBC mode */
+} sdp_crypto_mode_t;
+
+/**
+ * @brief SDP Data Swap modes
+ */
+typedef enum {
+    sdp_swap_mode_none = 0,             /*!< No data swap */
+    sdp_swap_mode_bytes_in_word = 1,    /*!< Swap bytes within one word */
+    sdp_swap_mode_word_swap = 2,        /*!< Swap words in one crypto block (16-bytes) */
+    sdp_swap_mode_switch_endian = 3,    /*!< Swap the data-endian in one crypto block (16-bytes) */
+} sdp_data_swap_mode_t;
+
+/**
+ * @brief SDP HASH calculation mode
+ */
+typedef enum {
+    sdp_calc_hash_for_input = 0,        /*!< Calculate HASH before doing crypto operation */
+    sdp_calc_hash_for_output = 1,       /*!< Calculate HASH after doing crypto operation */
+} sdp_calc_hash_mode_t;
+
+
 /**
  * @brief SDP HASH algorithm definitions
  */
@@ -102,7 +129,7 @@ typedef enum {
 #define SDP_PKT_CTRL_CIPHIV_MASK (1U << 6)
 
 /**
- * @brief SDP packet data structure
+ * @brief SDP Command Packet structure
  */
 typedef struct _sdp_packet_struct {
     struct _sdp_packet_struct *next_cmd;
@@ -110,7 +137,7 @@ typedef struct _sdp_packet_struct {
         struct {
             uint32_t RESERVED0: 1;
             uint32_t PKTINT: 1;     /**< Packet interrupt flag */
-            uint32_t DCRSEMA: 1;    /**< Descrement Semaphore flag */
+            uint32_t DCRSEMA: 1;    /**< Decrement Semaphore flag */
             uint32_t CHAIN: 1;      /**< Chain Packet flag */
             uint32_t HASHINIT: 1;   /**< Hash initialize flag */
             uint32_t HASHFINISH: 1; /**< Hash finish flag */
@@ -176,11 +203,47 @@ enum {
     status_sdp_error_dst = MAKE_STATUS(status_group_sdp, 8),         /**< Error destination address */
     status_sdp_error_hash = MAKE_STATUS(status_group_sdp, 9),        /**< Error Hash digest */
     status_sdp_error_chain = MAKE_STATUS(status_group_sdp, 10),      /**< Error packet chain */
-    status_sdp_error_invalid_mac = MAKE_STATUS(status_group_sdp, 11),/**< Inavlid Message Athenticaion Code (MAC) */
+    status_sdp_error_invalid_mac = MAKE_STATUS(status_group_sdp, 11),/**< Invalid Message Authentication Code (MAC) */
     status_sdp_invalid_alg = MAKE_STATUS(status_group_sdp, 12),      /**< Invalid algorithm */
 
 };
 
+/**
+ * @brief SDP Operations
+ */
+typedef enum {
+    sdp_op_invalid = 0,
+    sdp_op_cipher_only = SDP_SDPCR_CIPHEN_MASK,
+    sdp_op_hash_only = SDP_SDPCR_HASHEN_MASK,
+    sdp_op_memcpy_only = SDP_SDPCR_MCPEN_MASK,
+    sdp_op_memfill_only = SDP_SDPCR_CONFEN_MASK,
+    sdp_op_cipher_hash = SDP_SDPCR_CIPHEN_MASK | SDP_SDPCR_HASHEN_MASK,
+    sdp_op_copy_hash = SDP_SDPCR_MCPEN_MASK | SDP_SDPCR_HASHEN_MASK,
+} sdp_operation_t;
+
+/**
+ * @brief SDP Action Structure
+ */
+typedef struct {
+    sdp_operation_t op;                     /*!< SDP operation */
+    sdp_data_swap_mode_t input_swap_mode;   /*!< SDP input data swap mode */
+    sdp_data_swap_mode_t output_swap_mode;  /*!< SDP output data swap mode */
+    struct {
+        sdp_hash_alg_t hash_alg;            /*!< SDP HASH algorithm */
+        bool hash_check;                    /*!< Enable HASH verify mode */
+    };
+    struct {
+        sdp_crypto_alg_t crypto_alg;        /*!< SDP Crypto Algorithm */
+        sdp_crypto_mode_t crypto_mode;      /*!< SDP Crypto mode */
+        uint16_t key_bits;                  /*!< SDP crypto key bits */
+        uint8_t key_index;                  /*!< SDP key index */
+        sdp_crypto_op_t crypto_op;          /*!< SDP Crypto operation mode */
+        sdp_data_swap_mode_t key_swap_mode; /*!< SDP Key swap mode */
+        sdp_calc_hash_mode_t hash_mode;     /*!< SDP Hash calculation mode */
+    };
+} sdp_action_t;
+
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -190,17 +253,129 @@ extern "C"
 /***********************************************************************************************************************
  * Prototypes
  **********************************************************************************************************************/
+/**
+ * @brief Enable SDP interrupt
+ * @param [in] base SDP base address
+ */
+static inline void sdp_enable_interrupt(SDP_Type *base)
+{
+    base->SDPCR |= SDP_SDPCR_INTEN_MASK;
+}
+
+/**
+ * @brief Disable SDP interrupt
+ * @param [in] base SDP base address
+ */
+static inline void sdp_disable_interrupt(SDP_Type *base)
+{
+    base->SDPCR &= ~SDP_SDPCR_INTEN_MASK;
+}
+
+/**
+ * @brief Set the Crypto Key Index in SDP
+ * @param [in] base SDP base address
+ * @param [in] key_index SDP key index
+ */
+static inline void sdp_set_key_index(SDP_Type *base, uint32_t key_index)
+{
+    base->KEYADDR = SDP_KEYADDR_INDEX_SET(key_index);
+}
+
+/**
+ * @brief Write SDP key to specified SDP Key RAM
+ * @param [in] base SDP base address
+ * @param [in] key_index Key Index
+ * @param [in] key_bits Key bits, valid value: 128, 256
+ * @param [in] crypto_key Crypto Key buffer
+ */
+static inline void sdp_write_key(SDP_Type *base, uint32_t key_index, uint32_t key_bits, const uint32_t *crypto_key)
+{
+    if (key_bits == 256) {
+        uint32_t actual_key_index = key_index * 2;
+        for (uint32_t i = 0; i < 2; i++) {
+            sdp_set_key_index(base, actual_key_index++);
+            for (uint32_t j = 0; j < 4; j++) {
+                base->KEYDAT = *crypto_key++;
+            }
+        }
+    } else {
+        sdp_set_key_index(base, key_index);
+        for (uint32_t j = 0; j < 4; j++) {
+            base->KEYDAT = *crypto_key++;
+        }
+    }
+}
+
+/**
+ * @brief Write the HASH digest result to SDP
+ * @param [in] base SDP base address
+ * @param [in] digest HASH digest
+ * @param [in] num_words Digest size in words
+ */
+static inline void sdp_write_hash_digest(SDP_Type *base, const uint32_t *digest, uint32_t num_words)
+{
+    for (uint32_t i = 0; i < num_words; i++) {
+        base->HASWRD[i] = *digest++;
+    }
+}
+
+/**
+ * @brief Read the HASH digest result from SDP
+ * @param [in] base SDP base address
+ * @param [out] digest HASH digest
+ * @param [in] num_words Digest size in words
+ */
+static inline void sdp_get_hash_digest(SDP_Type *base, uint32_t *digest, uint32_t num_words)
+{
+    for (uint32_t i = 0; i < num_words; i++) {
+        *digest++ = base->HASWRD[i];
+    }
+}
+
+/**
+ * @brief Write the cipher IV to SDP
+ * @param [in] base SDP base address
+ * @param [in] iv Initial vector
+ */
+static inline void sdp_write_cipher_iv(SDP_Type *base, const uint32_t *iv)
+{
+    for (uint32_t i = 0; i < 4; i++) {
+        base->CIPHIV[i] = *iv++;
+    }
+}
+
+/**
+ * @brief Clear SDP status
+ * @param [in] base SDP base address
+ * @param [in] mask Status Mask
+ */
+static inline void sdp_clear_status(SDP_Type *base, uint32_t mask)
+{
+    base->STA = mask;
+}
+
+/**
+ * @brief Get SDP status
+ * @param [in] base SDP base address
+ *
+ * @return SDP status
+ */
+static inline uint32_t sdp_get_status(SDP_Type *base)
+{
+    return base->STA;
+}
+
 /**
  * @brief Initialize the SDP controller
  * @param [in] base SDP base address
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_init(SDP_Type *base);
 
 /**
  * @brief De-initialize the SDP controller
  * @param [in] base SDP base address
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_deinit(SDP_Type *base);
 
@@ -211,7 +386,7 @@ hpm_stat_t sdp_deinit(SDP_Type *base);
  * @param [in] key AES key
  * @param [in] key_bits AES key-bit option
  * @param [in] key_idx AES key index
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_aes_set_key(SDP_Type *base,
                            sdp_aes_ctx_t *aes_ctx,
@@ -220,6 +395,7 @@ hpm_stat_t sdp_aes_set_key(SDP_Type *base,
                            uint32_t key_idx);
 
 #if defined(SDP_HAS_SM4_SUPPORT) && (SDP_HAS_SM4_SUPPORT == 1)
+
 /**
  * @brief Set the SM4 key for the SDP SM4 operation
  * @param [in] base SDP base address
@@ -227,13 +403,14 @@ hpm_stat_t sdp_aes_set_key(SDP_Type *base,
  * @param [in] key SM4 key
  * @param [in] key_bits SM4 key-bit option
  * @param [in] key_idx AES key index
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_sm4_set_key(SDP_Type *base,
                            sdp_sm4_ctx_t *sm4_ctx,
                            const uint8_t *key,
                            sdp_sm4_key_bits_t key_bits,
                            uint32_t key_idx);
+
 #endif
 
 /**
@@ -244,7 +421,7 @@ hpm_stat_t sdp_sm4_set_key(SDP_Type *base,
  * @param [in] len AES data length in bytes
  * @param [in] in Input buffer
  * @param [out] out Output buffer
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_aes_crypt_ecb(SDP_Type *base,
                              sdp_aes_ctx_t *aes_ctx,
@@ -262,7 +439,7 @@ hpm_stat_t sdp_aes_crypt_ecb(SDP_Type *base,
  * @param [in] len SM4 data length in bytes
  * @param [in] in Input buffer
  * @param [out] out Output buffer
- * @retval API execution status.
+ * @return API execution status.
  */
 #define sdp_sm4_crypt_ecb sdp_aes_crypt_ecb
 #endif
@@ -276,7 +453,7 @@ hpm_stat_t sdp_aes_crypt_ecb(SDP_Type *base,
  * @param [in] iv Initial vector/nonce
  * @param [in] input Input buffer
  * @param [out] output Output buffer
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_aes_crypt_cbc(SDP_Type *base,
                              sdp_aes_ctx_t *aes_ctx,
@@ -296,7 +473,7 @@ hpm_stat_t sdp_aes_crypt_cbc(SDP_Type *base,
  * @param [in] iv Initial vector/nonce
  * @param [in] input Input buffer
  * @param [out] output Output buffer
- * @retval API execution status.
+ * @return API execution status.
  */
 #define sdp_sm4_crypt_cbc sdp_aes_crypt_cbc
 #endif
@@ -306,11 +483,11 @@ hpm_stat_t sdp_aes_crypt_cbc(SDP_Type *base,
  *        See NIST Special Publication800-38A for more details
  * @param [in] base SDP base address
  * @param [in] aes_ctx AES operation context
- * @param [in] nonce_counter AES-CTR nounce/counter
+ * @param [in] nonce_counter AES-CTR nonce/counter
  * @param [in] input Input buffer
  * @param [out] output Output buffer
  * @param [in] length Length of data for AES-CTR operation
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_aes_crypt_ctr(SDP_Type *base,
                              sdp_aes_ctx_t *aes_ctx,
@@ -324,11 +501,11 @@ hpm_stat_t sdp_aes_crypt_ctr(SDP_Type *base,
  * @brief Perform the SM4-CTR operation
  * @param [in] base SDP base address
  * @param [in] sm4_ctx SM4 operation context
- * @param [in] nonce_counter SM4-CTR nounce/counter
+ * @param [in] nonce_counter SM4-CTR nonce/counter
  * @param [in] input Input buffer
  * @param [out] output Output buffer
  * @param [in] length Length of data for SM4-CTR operation
- * @retval API execution status.
+ * @return API execution status.
  */
 #define sdp_sm4_crypt_ctr sdp_aes_crypt_ctr
 #endif
@@ -347,7 +524,7 @@ hpm_stat_t sdp_aes_crypt_ctr(SDP_Type *base,
  * @param [out] output Output buffer
  * @param [out] tag MAC buffer
  * @param [in] tag_len Tag/MAC size in bytes
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_aes_ccm_generate_encrypt(SDP_Type *base,
                                         sdp_aes_ctx_t *aes_ctx,
@@ -376,7 +553,7 @@ hpm_stat_t sdp_aes_ccm_generate_encrypt(SDP_Type *base,
  * @param [out] output Output buffer
  * @param [out] tag MAC buffer
  * @param [in] tag_len Tag/MAC size in bytes
- * @retval API execution status.
+ * @return API execution status.
  */
 #define sdp_sm4_ccm_generate_encrypt sdp_aes_ccm_generate_encrypt
 #endif
@@ -395,7 +572,7 @@ hpm_stat_t sdp_aes_ccm_generate_encrypt(SDP_Type *base,
  * @param [out] output Output buffer
  * @param [in] tag MAC buffer
  * @param [in] tag_len Tag/MAC size in bytes
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_aes_ccm_decrypt_verify(SDP_Type *base,
                                       sdp_aes_ctx_t *aes_ctx,
@@ -423,10 +600,11 @@ hpm_stat_t sdp_aes_ccm_decrypt_verify(SDP_Type *base,
  * @param [out] output Output buffer
  * @param [in] tag MAC buffer
  * @param [in] tag_len Tag/MAC size in bytes
- * @retval API execution status.
+ * @return API execution status.
  */
 #define sdp_sm4_ccm_decrypt_verify sdp_aes_ccm_decrypt_verify
 #endif
+
 /**
  * @brief Perform the DMA accelerated memcpy
  * @param [in] base SDP base address
@@ -434,7 +612,7 @@ hpm_stat_t sdp_aes_ccm_decrypt_verify(SDP_Type *base,
  * @param [out] dst Destination address for memcpy operation
  * @param [in] src Source address for memcpy operation
  * @param [in] length Length of the data to be copied
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_memcpy(SDP_Type *base, sdp_dma_ctx_t *sdp_ctx, void *dst, const void *src, uint32_t length);
 
@@ -445,7 +623,7 @@ hpm_stat_t sdp_memcpy(SDP_Type *base, sdp_dma_ctx_t *sdp_ctx, void *dst, const v
  * @param [out] dst SDP destination address for memset operation
  * @param [in] pattern pattern for memset operation
  * @param [in] length length of the memory for memset operation
- * @retval API execution status.
+ * @return API execution status.
  */
 hpm_stat_t sdp_memset(SDP_Type *base, sdp_dma_ctx_t *sdp_ctx, void *dst, uint8_t pattern, uint32_t length);
 
@@ -454,7 +632,7 @@ hpm_stat_t sdp_memset(SDP_Type *base, sdp_dma_ctx_t *sdp_ctx, void *dst, uint8_t
  * @param [in] base SDP base address
  * @param [in] hash_ctx HASH operation context
  * @param [in] alg Hash algorithm
- * @retval API execution status. status_success or status_invalid_argument
+ * @return API execution status. status_success or status_invalid_argument
  */
 hpm_stat_t sdp_hash_init(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, sdp_hash_alg_t alg);
 
@@ -464,7 +642,8 @@ hpm_stat_t sdp_hash_init(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, sdp_hash_alg_
  * @param [in] hash_ctx HASH operation context
  * @param [in] data Data for HASH computing
  * @param [in] length Data size for HASH computing
- * @retval API execution status.
+ *
+ * @return API execution status.
  */
 hpm_stat_t sdp_hash_update(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, const uint8_t *data, uint32_t length);
 
@@ -473,16 +652,33 @@ hpm_stat_t sdp_hash_update(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, const uint8
  * @param [in] base SDP base address
  * @param [in] hash_ctx HASH operation context
  * @param [out] digest  Digest buffer
- * @retval API execution status.
+ *
+ * @return API execution status.
  */
 hpm_stat_t sdp_hash_finish(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, uint8_t *digest);
 
 /**
  * @brief Wait until the SDP operation gets done
- * @retval API execution status.
+ * @param [in] base SDP base address
+ *
+ * @return API execution status.
  */
 hpm_stat_t sdp_wait_done(SDP_Type *base);
 
+
+/**
+ * @brief Trigger SDP operation via the specified SDP packet description
+ * @note 1. The Command Packet List should be in non-cacheable memory
+ *       2. This is a non-blocking API, users should confirm whether action completed or not by checking STA register
+ *          in SDP
+ * @param [in] base SDP base address
+ * @param [in] action SDP action
+ * @param [in] cmd_pkt SDP Command packet description
+ *
+ * @return API execution status.
+ */
+hpm_stat_t sdp_trigger_action(SDP_Type *base, const sdp_action_t *action, const sdp_pkt_struct_t *cmd_pkt);
+
 #ifdef __cplusplus
 }
 #endif

Some files were not shown because too many files changed in this diff