Ver código fonte

add ch579m bsp (#5600)

* add ch579m bsp

Author:    Tuber <tuber@xyza.cn>
Date:      Wed Feb 16 07:20:23 2022 +0000

* fix uart reg value error and format code

* change file encode to utf-8
Tuber 3 anos atrás
pai
commit
5a61304a09
60 arquivos alterados com 13234 adições e 0 exclusões
  1. 715 0
      bsp/wch/arm/ch579m/.config
  2. 20 0
      bsp/wch/arm/ch579m/Kconfig
  3. 15 0
      bsp/wch/arm/ch579m/SConscript
  4. 41 0
      bsp/wch/arm/ch579m/SConstruct
  5. 17 0
      bsp/wch/arm/ch579m/applications/SConscript
  6. 18 0
      bsp/wch/arm/ch579m/applications/main.c
  7. 45 0
      bsp/wch/arm/ch579m/board/Kconfig
  8. 11 0
      bsp/wch/arm/ch579m/board/SConscript
  9. 67 0
      bsp/wch/arm/ch579m/board/board.c
  10. 37 0
      bsp/wch/arm/ch579m/board/board.h
  11. 261 0
      bsp/wch/arm/ch579m/board/drv_eth.c
  12. 19 0
      bsp/wch/arm/ch579m/board/drv_eth.h
  13. 421 0
      bsp/wch/arm/ch579m/board/drv_uart.c
  14. 16 0
      bsp/wch/arm/ch579m/board/drv_uart.h
  15. 299 0
      bsp/wch/arm/ch579m/board/drv_usbh.c
  16. 28 0
      bsp/wch/arm/ch579m/board/drv_usbh.h
  17. 711 0
      bsp/wch/arm/ch579m/libraries/CMSIS/Include/core_cm0.h
  18. 637 0
      bsp/wch/arm/ch579m/libraries/CMSIS/Include/core_cmFunc.h
  19. 880 0
      bsp/wch/arm/ch579m/libraries/CMSIS/Include/core_cmInstr.h
  20. 16 0
      bsp/wch/arm/ch579m/libraries/SConscript
  21. 237 0
      bsp/wch/arm/ch579m/libraries/Startup/startup_ARMCM0.s
  22. 223 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_adc.c
  23. 595 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_clk.c
  24. 283 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_flash.c
  25. 252 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_gpio.c
  26. 242 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_int.c
  27. 27 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_lcd.c
  28. 110 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_pwm.c
  29. 223 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_pwr.c
  30. 324 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_spi0.c
  31. 156 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_spi1.c
  32. 193 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_sys.c
  33. 96 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer0.c
  34. 118 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer1.c
  35. 118 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer2.c
  36. 96 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer3.c
  37. 130 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart0.c
  38. 130 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart1.c
  39. 130 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart2.c
  40. 130 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart3.c
  41. 1934 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH579SFR.h
  42. 112 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_adc.h
  43. 164 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_clk.h
  44. 71 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_common.h
  45. 35 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_flash.h
  46. 102 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_gpio.h
  47. 91 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_lcd.h
  48. 80 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_pwm.h
  49. 69 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_pwr.h
  50. 108 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_spi.h
  51. 76 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_sys.h
  52. 197 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_timer.h
  53. 131 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_uart.h
  54. 59 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_usbdev.h
  55. 130 0
      bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_usbhost.h
  56. 19 0
      bsp/wch/arm/ch579m/libraries/sct/CH57x.sct
  57. 977 0
      bsp/wch/arm/ch579m/project.uvprojx
  58. 238 0
      bsp/wch/arm/ch579m/rtconfig.h
  59. 150 0
      bsp/wch/arm/ch579m/rtconfig.py
  60. 404 0
      bsp/wch/arm/ch579m/template.uvprojx

+ 715 - 0
bsp/wch/arm/ch579m/.config

@@ -0,0 +1,715 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+# CONFIG_RT_USING_SMP is not set
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+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 is not set
+# CONFIG_RT_USING_HOOK is not set
+# CONFIG_RT_USING_IDLE_HOOK is not set
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+# CONFIG_RT_USING_TIMER_SOFT is not set
+
+#
+# kservice optimization
+#
+# CONFIG_RT_KSERVICE_USING_STDLIB is not set
+# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
+# CONFIG_RT_USING_TINY_FFS is not set
+# CONFIG_RT_PRINTF_LONGLONG is not set
+# CONFIG_RT_DEBUG is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+# CONFIG_RT_USING_EVENT is not set
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+# CONFIG_RT_USING_MEMPOOL is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMHEAP is not set
+CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
+# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+# CONFIG_RT_USING_SLAB_AS_HEAP is not set
+# CONFIG_RT_USING_USERHEAP is not set
+# CONFIG_RT_USING_NOHEAP is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+# CONFIG_RT_USING_HEAP_ISR is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+# CONFIG_RT_USING_DEVICE_OPS is not set
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
+CONFIG_RT_VER_NUM=0x40100
+# CONFIG_RT_USING_CPU_FFS is not set
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=1024
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+# CONFIG_RT_USING_LEGACY is not set
+
+#
+# C++ features
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=2048
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_ARG_MAX=10
+
+#
+# Device virtual file system
+#
+# CONFIG_RT_USING_DFS is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
+# CONFIG_RT_SERIAL_USING_DMA is not set
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+# CONFIG_RT_USING_I2C is not set
+# CONFIG_RT_USING_PHY is not set
+# CONFIG_RT_USING_PIN is not set
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_DAC is not set
+# CONFIG_RT_USING_PWM 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
+# CONFIG_RT_USING_RTC is not set
+# CONFIG_RT_USING_SDIO is not set
+# CONFIG_RT_USING_SPI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+# CONFIG_RT_USING_TOUCH 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_WIFI is not set
+
+#
+# Using USB
+#
+CONFIG_RT_USING_USB=y
+CONFIG_RT_USING_USB_HOST=y
+# CONFIG_RT_USBH_MSTORAGE is not set
+# CONFIG_RT_USBH_HID is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+CONFIG_RT_USBD_THREAD_STACK_SZ=512
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
+
+#
+# POSIX (Portable Operating System Interface) layer
+#
+# CONFIG_RT_USING_POSIX_FS is not set
+# CONFIG_RT_USING_POSIX_DELAY is not set
+# CONFIG_RT_USING_POSIX_CLOCK is not set
+# CONFIG_RT_USING_POSIX_TIMER is not set
+# CONFIG_RT_USING_PTHREADS is not set
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# Interprocess Communication (IPC)
+#
+# CONFIG_RT_USING_POSIX_PIPE is not set
+# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
+# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
+
+#
+# Socket is in the 'Network' category
+#
+
+#
+# Network
+#
+
+#
+# Socket abstraction layer
+#
+# CONFIG_RT_USING_SAL is not set
+
+#
+# Network interface device
+#
+CONFIG_RT_USING_NETDEV=y
+CONFIG_NETDEV_USING_IFCONFIG=y
+CONFIG_NETDEV_USING_PING=y
+# CONFIG_NETDEV_USING_NETSTAT is not set
+# CONFIG_NETDEV_USING_AUTO_DEFAULT is not set
+# CONFIG_NETDEV_USING_IPV6 is not set
+CONFIG_NETDEV_IPV4=1
+CONFIG_NETDEV_IPV6=0
+# CONFIG_NETDEV_IPV6_SCOPES is not set
+
+#
+# light weight TCP/IP stack
+#
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP141 is not set
+# CONFIG_RT_USING_LWIP203 is not set
+CONFIG_RT_USING_LWIP212=y
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+CONFIG_RT_LWIP_MEM_ALIGNMENT=4
+# CONFIG_RT_LWIP_IGMP is not set
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+# CONFIG_RT_LWIP_DHCP is not set
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="19.111.115.250"
+CONFIG_RT_LWIP_GWADDR="19.111.115.254"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+CONFIG_RT_LWIP_RAW=y
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=4
+CONFIG_RT_LWIP_PBUF_NUM=4
+CONFIG_RT_LWIP_RAW_PCB_NUM=4
+CONFIG_RT_LWIP_UDP_PCB_NUM=4
+CONFIG_RT_LWIP_TCP_PCB_NUM=4
+CONFIG_RT_LWIP_TCP_SEG_NUM=8
+CONFIG_RT_LWIP_TCP_SND_BUF=3072
+CONFIG_RT_LWIP_TCP_WND=3072
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=4
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=1024
+# CONFIG_LWIP_NO_RX_THREAD is not set
+CONFIG_LWIP_NO_TX_THREAD=y
+CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=512
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=4
+# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=0
+CONFIG_LWIP_NETIF_LINK_CALLBACK=0
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+CONFIG_LWIP_SO_LINGER=0
+# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
+CONFIG_LWIP_NETIF_LOOPBACK=0
+# CONFIG_RT_LWIP_STATS is not set
+# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
+CONFIG_RT_LWIP_USING_PING=y
+# CONFIG_RT_LWIP_DEBUG is not set
+
+#
+# AT commands
+#
+# CONFIG_RT_USING_AT is not set
+# CONFIG_LWIP_USING_DHCPD is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+# CONFIG_RT_USING_UTEST is not set
+# CONFIG_RT_USING_VAR_EXPORT is not set
+# CONFIG_RT_USING_RT_LINK is not set
+
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_MYMQTT is not set
+# CONFIG_PKG_USING_KAWAII_MQTT is not set
+# CONFIG_PKG_USING_BC28_MQTT is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_FREEMODBUS is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_RW007 is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_CMUX is not set
+# CONFIG_PKG_USING_PPP_DEVICE is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+# CONFIG_PKG_USING_ZB_COORDINATOR is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
+# CONFIG_PKG_USING_JIOT-C-SDK is not set
+# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
+# CONFIG_PKG_USING_JOYLINK is not set
+# CONFIG_PKG_USING_EZ_IOT_OS is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+# CONFIG_PKG_USING_TCPSERVER is not set
+# CONFIG_PKG_USING_PROTOBUF_C is not set
+# CONFIG_PKG_USING_DLT645 is not set
+# CONFIG_PKG_USING_QXWZ is not set
+# CONFIG_PKG_USING_SMTP_CLIENT is not set
+# CONFIG_PKG_USING_ABUP_FOTA is not set
+# CONFIG_PKG_USING_LIBCURL2RTT is not set
+# CONFIG_PKG_USING_CAPNP is not set
+# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
+# CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
+# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
+# CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_LORA_PKT_FWD is not set
+# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
+# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
+# CONFIG_PKG_USING_HM is not set
+# CONFIG_PKG_USING_SMALL_MODBUS is not set
+# CONFIG_PKG_USING_NET_SERVER is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_LIBSODIUM is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+# CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
+
+#
+# language packages
+#
+# 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
+
+#
+# multimedia packages
+#
+
+#
+# LVGL: powerful and easy-to-use embedded GUI library
+#
+# CONFIG_PKG_USING_LVGL is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
+
+#
+# u8g2: a monochrome graphic library
+#
+# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+# CONFIG_PKG_USING_WAVPLAYER is not set
+# CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
+# CONFIG_PKG_USING_MP3PLAYER is not set
+# CONFIG_PKG_USING_TINYJPEG is not set
+# CONFIG_PKG_USING_UGUI is not set
+
+#
+# PainterEngine: A cross-platform graphics application framework written in C language
+#
+# CONFIG_PKG_USING_PAINTERENGINE is not set
+# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_QRCODE is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_SEGGER_RTT is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
+# CONFIG_PKG_USING_LOGMGR is not set
+# CONFIG_PKG_USING_ADBD is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
+# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
+# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
+# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
+# CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
+# CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
+# CONFIG_PKG_USING_CPU_USAGE is not set
+# CONFIG_PKG_USING_GBK2UTF8 is not set
+# CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
+# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
+# CONFIG_PKG_USING_LWLOG is not set
+# CONFIG_PKG_USING_ANV_TRACE is not set
+# CONFIG_PKG_USING_ANV_MEMLEAK is not set
+# CONFIG_PKG_USING_ANV_TESTSUIT is not set
+# CONFIG_PKG_USING_ANV_BENCH is not set
+# CONFIG_PKG_USING_DEVMEM is not set
+# CONFIG_PKG_USING_REGEX is not set
+# CONFIG_PKG_USING_MEM_SANDBOX is not set
+# CONFIG_PKG_USING_SOLAR_TERMS is not set
+# CONFIG_PKG_USING_GAN_ZHI is not set
+# CONFIG_PKG_USING_FDT is not set
+
+#
+# system packages
+#
+
+#
+# enhanced kernel services
+#
+# 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
+
+#
+# POSIX extension functions
+#
+# CONFIG_PKG_USING_POSIX_GETLINE is not set
+# CONFIG_PKG_USING_POSIX_WCWIDTH is not set
+# CONFIG_PKG_USING_POSIX_ITOA is not set
+# CONFIG_PKG_USING_POSIX_STRINGS is not set
+
+#
+# acceleration: Assembly language or algorithmic acceleration packages
+#
+# 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
+
+#
+# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
+#
+# CONFIG_PKG_USING_CMSIS_5 is not set
+# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
+# CONFIG_RT_USING_ARDUINO is not set
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_FLASHDB is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+# CONFIG_PKG_USING_ROBOTS is not set
+# CONFIG_PKG_USING_EV is not set
+# CONFIG_PKG_USING_SYSWATCH is not set
+# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
+# CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+# CONFIG_PKG_USING_PPOOL is not set
+# CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
+# CONFIG_PKG_USING_MCUBOOT is not set
+# CONFIG_PKG_USING_TINYUSB is not set
+# CONFIG_PKG_USING_CHERRYUSB is not set
+
+#
+# peripheral libraries and drivers
+#
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AS7341 is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_LITTLED is not set
+# CONFIG_PKG_USING_LKDGUI is not set
+# CONFIG_PKG_USING_NRF5X_SDK is not set
+# CONFIG_PKG_USING_NRFX is not set
+# CONFIG_PKG_USING_WM_LIBRARIES is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_AGILE_BUTTON is not set
+# CONFIG_PKG_USING_AGILE_LED is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_MAX17048 is not set
+# CONFIG_PKG_USING_RPLIDAR is not set
+# CONFIG_PKG_USING_AS608 is not set
+# CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
+# CONFIG_PKG_USING_EMBARC_BSP is not set
+# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
+# CONFIG_PKG_USING_MULTI_RTIMER is not set
+# CONFIG_PKG_USING_MAX7219 is not set
+# CONFIG_PKG_USING_BEEP is not set
+# CONFIG_PKG_USING_EASYBLINK is not set
+# CONFIG_PKG_USING_PMS_SERIES is not set
+# CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
+# CONFIG_PKG_USING_RS485 is not set
+# CONFIG_PKG_USING_RS232 is not set
+# CONFIG_PKG_USING_NES is not set
+# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
+# CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+# CONFIG_PKG_USING_KOBUKI is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_MICRO_ROS is not set
+# CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
+# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
+# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
+# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
+# CONFIG_PKG_USING_BL_MCU_SDK is not set
+# CONFIG_PKG_USING_SOFT_SERIAL is not set
+# CONFIG_PKG_USING_MB85RS16 is not set
+# CONFIG_PKG_USING_CW2015 is not set
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
+
+#
+# miscellaneous packages
+#
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_COWSAY is not set
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_LZMA is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_MINIZIP is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+# CONFIG_PKG_USING_UPACKER is not set
+# CONFIG_PKG_USING_UPARAM is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_KI is not set
+# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_UKAL is not set
+# CONFIG_PKG_USING_CRCLIB is not set
+# CONFIG_PKG_USING_LWGPS is not set
+# CONFIG_PKG_USING_STATE_MACHINE is not set
+# CONFIG_PKG_USING_DESIGN_PATTERN is not set
+# CONFIG_PKG_USING_CONTROLLER is not set
+# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
+
+#
+# Hardware Drivers Config
+#
+CONFIG_SOC_CH579M=y
+
+#
+# On-chip Peripheral Drivers
+#
+CONFIG_BSP_USING_UART=y
+# CONFIG_BSP_USING_UART0 is not set
+CONFIG_BSP_USING_UART1=y
+# CONFIG_BSP_USING_UART2 is not set
+# CONFIG_BSP_USING_UART3 is not set
+CONFIG_BSP_USING_USBH=y
+CONFIG_BSP_USING_ETH=y

+ 20 - 0
bsp/wch/arm/ch579m/Kconfig

@@ -0,0 +1,20 @@
+mainmenu "RT-Thread Configuration"
+
+config BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../../../.."
+
+config PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+source "board/Kconfig"

+ 15 - 0
bsp/wch/arm/ch579m/SConscript

@@ -0,0 +1,15 @@
+# for module compiling
+import os
+Import('RTT_ROOT')
+from building import *
+
+cwd = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 41 - 0
bsp/wch/arm/ch579m/SConstruct

@@ -0,0 +1,41 @@
+import os
+import sys
+import rtconfig
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..')
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+try:
+    from building import *
+except:
+    print('Cannot found RT-Thread root directory, please check RTT_ROOT')
+    print(RTT_ROOT)
+    exit(-1)
+
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+DefaultEnvironment(tools=[])
+env = Environment(tools = ['mingw'],
+    AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+    CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+    AR = rtconfig.AR, ARFLAGS = '-rc',
+    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+if rtconfig.PLATFORM == 'iar':
+    env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
+    env.Replace(ARFLAGS = [''])
+    env.Replace(LINKCOM = env["LINKCOM"] + ' --map project.map')
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 17 - 0
bsp/wch/arm/ch579m/applications/SConscript

@@ -0,0 +1,17 @@
+# RT-Thread building script for component
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+
+# add the general drivers.
+src = Split("""
+main.c
+""")
+
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 18 - 0
bsp/wch/arm/ch579m/applications/main.c

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-06     SummerGift   change to new framework
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <board.h>
+
+int main(void)
+{
+    return RT_EOK;
+}

+ 45 - 0
bsp/wch/arm/ch579m/board/Kconfig

@@ -0,0 +1,45 @@
+menu "Hardware Drivers Config"
+
+config SOC_CH579M
+    bool
+    select RT_USING_USER_MAIN
+    select RT_USING_COMPONENTS_INIT
+    default y
+
+menu "On-chip Peripheral Drivers"
+
+    menuconfig BSP_USING_UART
+        bool "Enable UART"
+        default y
+        select RT_USING_SERIAL
+        if BSP_USING_UART
+			config BSP_USING_UART0
+                bool "Enable UART0"
+                default n
+
+            config BSP_USING_UART1
+                bool "Enable UART1"
+                default y
+
+            config BSP_USING_UART2
+                bool "Enable UART2"
+                default n
+                
+            config BSP_USING_UART3
+                bool "Enable UART3"
+                default n
+        endif
+        
+    config BSP_USING_USBH
+        bool "Enable USBH"
+        default n
+        select RT_USING_USB_HOST
+        
+    config BSP_USING_ETH
+        bool "Enable ETH"
+        default n
+        select RT_USING_LWIP
+
+endmenu
+
+endmenu

+ 11 - 0
bsp/wch/arm/ch579m/board/SConscript

@@ -0,0 +1,11 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd  = GetCurrentDir()
+src  = Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 67 - 0
bsp/wch/arm/ch579m/board/board.c

@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rthw.h>
+#include "board.h"
+
+#ifdef RT_USING_SERIAL
+#include "drv_uart.h"
+#endif
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+static void reboot(uint8_t argc, char **argv)
+{
+    rt_hw_cpu_reset();
+}
+MSH_CMD_EXPORT(reboot, Reboot System)
+#endif /* RT_USING_FINSH */
+
+void SysTick_Handler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    rt_tick_increase();
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+void rt_hw_board_init()
+{
+    // 打开PLL
+    PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL);
+    // 设置外部40M做主频
+    SetSysClock(CLK_SOURCE_PLL_40MHz);
+    SysTick_Config(GetSysClock() / RT_TICK_PER_SECOND);
+    //开启中断
+    NVIC_SetPriority(SysTick_IRQn, 0);
+    NVIC_EnableIRQ(SysTick_IRQn);
+
+#if defined(RT_USING_HEAP)
+    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
+#endif
+
+#ifdef RT_USING_SERIAL
+    rt_hw_uart_init();
+#endif
+
+#ifdef RT_USING_CONSOLE
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif
+
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+#endif
+
+}

+ 37 - 0
bsp/wch/arm/ch579m/board/board.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include "CH57x_common.h"
+
+#define CH579M_FLASH_START_ADRESS     ((uint32_t)0x00000000)
+#define FLASH_PAGE_SIZE             (64)
+#define CH579M_FLASH_SIZE             (512 * 1024)
+#define CH579M_FLASH_END_ADDRESS      ((uint32_t)(CH579M_FLASH_START_ADRESS + CH579M_FLASH_SIZE))
+
+#define CH579M_SRAM_SIZE      32
+#define CH579M_SRAM_END       (0x20000000 + CH579M_SRAM_SIZE * 1024)
+
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+extern int Image$$RW_IRAM1$$ZI$$Limit;
+#define HEAP_BEGIN      ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
+#elif __ICCARM__
+#pragma section="CSTACK"
+#define HEAP_BEGIN      (__segment_end("CSTACK"))
+#else
+extern int __bss_end;
+#define HEAP_BEGIN      ((void *)&__bss_end)
+#endif
+
+#define HEAP_END        CH579M_SRAM_END
+
+#endif /* __BOARD_H__ */

+ 261 - 0
bsp/wch/arm/ch579m/board/drv_eth.c

@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "board.h"
+#include <netif/ethernetif.h>
+#include "drv_eth.h"
+
+#ifdef BSP_USING_ETH
+
+static struct eth_device eth_device;
+
+//DMA接收内存区,必须4字节对齐
+__align(4) UINT8 eth_dma_tx_buf[ETH_BUF_SIZE];
+__align(4) UINT8 eth_dma_rx_buf[ETH_BUF_SIZE];
+
+UINT16 eth_rx_len = 0; //接收状态和长度
+UINT8 eth_rx_buf[ETH_BUF_SIZE]; //中间缓冲区
+
+UINT8 eth_mac_addr[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
+
+static rt_err_t eth_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t eth_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t eth_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_size_t eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_err_t eth_control(rt_device_t dev, int cmd, void *args)
+{
+    switch (cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get mac address */
+        if (args) rt_memcpy(args, eth_mac_addr, 6);
+        else return -RT_ERROR;
+        break;
+    default :
+        break;
+    }
+
+    return RT_EOK;
+}
+
+rt_err_t eth_tx(rt_device_t dev, struct pbuf *p)
+{
+    //判断eth是否处于发送状态
+    if ((R8_ETH_ECON1 & RB_ETH_ECON1_TXRTS) != 0x00)
+    {
+        return ERR_INPROGRESS;
+    }
+
+    //确定缓冲区是否足够
+    if (p->tot_len > sizeof(eth_dma_tx_buf))
+    {
+        return ERR_MEM;
+    }
+
+    //拷贝数据到dma缓冲区
+    rt_memcpy(eth_dma_tx_buf, p->payload, p->tot_len);
+
+    //设置数据长度
+    R16_ETH_ETXLN = p->tot_len;
+
+    //开始发送
+    R8_ETH_ECON1 |= RB_ETH_ECON1_TXRTS;
+
+    return ERR_OK;
+}
+
+struct pbuf *eth_rx(rt_device_t dev)
+{
+    struct pbuf *p = NULL;
+
+    //检查是否有数据
+    if (eth_rx_len == 0)
+    {
+        return NULL;
+    }
+
+    p = pbuf_alloc(PBUF_RAW, eth_rx_len, PBUF_POOL);
+    if (p == NULL)
+    {
+        rt_kprintf("eth_rx: pbuf_alloc failed\n");
+        eth_rx_len = 0;
+        return NULL;
+    }
+
+    //拷贝数据到pbuf
+    rt_memcpy((uint8_t *)((uint8_t *)p->payload), (uint8_t *)((uint8_t *)eth_rx_buf), eth_rx_len);
+    //恢复状态
+    eth_rx_len = 0;
+
+    return p;
+}
+
+int read_eth_link_status()
+{
+    R8_ETH_MIREGADR = 0x01;//状态寄存器
+    R8_ETH_MISTAT |= 0x00; //读MII寄存器
+
+    //获取link状态
+    if ((R16_ETH_MIRD & 0x04) != 0)
+    {
+        return 1; //已插入
+    }
+
+    return 0;
+}
+
+void ETH_IRQHandler(void) /* 以太网中断 */
+{
+    rt_interrupt_enter();
+
+    //接收到数据包
+    if ((R8_ETH_EIR & RB_ETH_EIR_RXIF) != 0)
+    {
+        //判断缓存区是否有数据
+        if (eth_rx_len == 0)
+        {
+            rt_memcpy(eth_rx_buf, eth_dma_rx_buf, R16_ETH_ERXLN);
+            eth_rx_len = R16_ETH_ERXLN;
+            //通知拿数据
+            eth_device_ready(&eth_device);
+        }
+
+        R8_ETH_EIR |= RB_ETH_EIR_RXIF; //清除中断
+    }
+
+    //接收错误
+    if ((R8_ETH_EIR & RB_ETH_EIE_RXERIE) != 0)
+    {
+        R8_ETH_EIR |= RB_ETH_EIE_RXERIE; //清除中断
+    }
+
+    //发送完成
+    if ((R8_ETH_EIR & RB_ETH_EIR_TXIF) != 0)
+    {
+        R8_ETH_EIR |= RB_ETH_EIR_TXIF; //清除中断
+    }
+
+    //发送错误
+    if ((R8_ETH_EIR & RB_ETH_EIE_TXERIE) != 0)
+    {
+        R8_ETH_EIR |= RB_ETH_EIE_TXERIE; //清除中断
+    }
+
+    //Link 变化标志
+    if ((R8_ETH_EIR & RB_ETH_EIR_LINKIF) != 0)
+    {
+        //获取连接状态
+        if (read_eth_link_status())
+        {
+            eth_device_linkchange(&eth_device, RT_TRUE);
+            rt_kprintf("eth1: link is up\n");
+        }
+        else
+        {
+            eth_device_linkchange(&eth_device, RT_FALSE);
+            rt_kprintf("eth1: link is down\n");
+        }
+
+        R8_ETH_EIR |= RB_ETH_EIR_LINKIF; //清除中断
+    }
+
+    rt_interrupt_leave();
+}
+
+int rt_hw_eth_init(void)
+{
+    //使能ETH引脚
+    R16_PIN_ANALOG_IE |= RB_PIN_ETH_IE;
+
+    //进入安全访问模式
+    R8_SAFE_ACCESS_SIG = 0x57;
+    R8_SAFE_ACCESS_SIG = 0xA8;
+    //打开以太网时钟
+    R8_SLP_CLK_OFF1 &= (~RB_SLP_CLK_ETH);
+    //打开以太网电源
+    R8_SLP_POWER_CTRL &= (~RB_SLP_ETH_PWR_DN);
+    //退出安全访问模式
+    R8_SAFE_ACCESS_SIG = 0x00;
+
+    //开启以太网中断
+    R8_ETH_EIE |= RB_ETH_EIE_INTIE;
+    //启用以太网接收中断
+    R8_ETH_EIE |= RB_ETH_EIE_RXIE;
+    //R8_ETH_EIE |= RB_ETH_EIE_RXERIE;
+    //启用以太网发送中断
+    R8_ETH_EIE |= RB_ETH_EIR_TXIF;
+    R8_ETH_EIE |= RB_ETH_EIR_TXERIF;
+    //启用Link变化中断
+    R8_ETH_EIE |= RB_ETH_EIE_LINKIE;
+    //启用内置的50欧姆阻抗匹配电阻
+    R8_ETH_EIE |= RB_ETH_EIE_R_EN50;
+
+    //配置接收过滤模式
+    R8_ETH_ERXFCON = RB_ETH_ERXFCON_ANDOR | RB_ETH_ERXFCON_CRCEN;
+
+    //设置发送dma
+    R16_ETH_ETXST = (uint32_t)eth_dma_tx_buf;
+    //设置接收dma
+    R16_ETH_ERXST = (uint32_t)eth_dma_rx_buf;
+    //设置最大接收长度
+    R16_ETH_MAMXFL = sizeof(eth_dma_rx_buf);
+
+    //使能MAC层接收
+    R8_ETH_MACON1 |= RB_ETH_MACON1_MARXEN;
+    //开启硬件CRC
+    R8_ETH_MACON2 |= RB_ETH_MACON2_TXCRCEN;
+    //所有短包填充0至60字节,再4字节 CRC
+    R8_ETH_MACON2 |= 0x20;
+    //使能接收
+    R8_ETH_ECON1 |= RB_ETH_ECON1_RXEN;
+
+    //开启中断
+    NVIC_EnableIRQ(ETH_IRQn);
+
+    //设置回调函数
+    eth_device.parent.init       = eth_init;
+    eth_device.parent.open       = eth_open;
+    eth_device.parent.close      = eth_close;
+    eth_device.parent.read       = eth_read;
+    eth_device.parent.write      = eth_write;
+    eth_device.parent.control    = eth_control;
+    eth_device.parent.user_data  = RT_NULL;
+    eth_device.eth_rx            = eth_rx;
+    eth_device.eth_tx            = eth_tx;
+
+    return eth_device_init(&(eth_device), "e0");
+}
+INIT_DEVICE_EXPORT(rt_hw_eth_init);
+#endif /* BSP_USING_ETH */

+ 19 - 0
bsp/wch/arm/ch579m/board/drv_eth.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#ifndef __DRV_ETH_H__
+#define __DRV_ETH_H__
+#include <rtthread.h>
+
+#define ETH_BUF_SIZE 1536
+
+int rt_hw_eth_init(void);
+
+#endif

+ 421 - 0
bsp/wch/arm/ch579m/board/drv_uart.c

@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "board.h"
+#include "drv_uart.h"
+
+#ifdef BSP_USING_UART
+
+struct uart_device
+{
+    struct rt_serial_device serial;
+    char *name;
+};
+
+#ifdef BSP_USING_UART0
+static struct uart_device uart_device0 =
+{
+    .name = "uart0",
+};
+#endif
+#ifdef BSP_USING_UART1
+static struct uart_device uart_device1 =
+{
+    .name = "uart1",
+};
+#endif
+#ifdef BSP_USING_UART2
+static struct uart_device uart_device2 =
+{
+    .name = "uart2",
+};
+#endif
+#ifdef BSP_USING_UART3
+static struct uart_device uart_device3 =
+{
+    .name = "uart3",
+};
+#endif
+
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+    UINT32 x;
+    UINT8V R8_UARTx_FCR = 0, R8_UARTx_LCR = 0, R8_UARTx_IER = 0, R8_UARTx_DIV = 0;
+    UINT16V R16_UARTx_DL = 0;
+    struct uart_device *uart_device = serial->parent.user_data;
+
+    //设置波特率
+    x = 10 * GetSysClock() / 8 / cfg->baud_rate;
+    x = (x + 5) / 10;
+    R16_UARTx_DL = (UINT16)x;
+    //设置数据长度
+    switch (cfg->data_bits)
+    {
+    case DATA_BITS_5:
+        //R8_UARTx_LCR |= 0x00;
+        break;
+    case DATA_BITS_6:
+        R8_UARTx_LCR |= 0x01;
+        break;
+    case DATA_BITS_7:
+        R8_UARTx_LCR |= 0x02;
+        break;
+    case DATA_BITS_8:
+    default:
+        R8_UARTx_LCR |= 0x03;
+        break;
+    }
+    //设置停止位
+    switch (cfg->stop_bits)
+    {
+    case STOP_BITS_2:
+        R8_UARTx_LCR |= 0x04;
+        break;
+    case STOP_BITS_1:
+    default:
+        //R8_UARTx_LCR |= 0x00;
+        break;
+    }
+    //设置校验位
+    switch (cfg->parity)
+    {
+    case PARITY_ODD:
+        R8_UART1_LCR |= R8_LCR_PAR_EN;
+        //R8_UART1_LCR |= 0x00;
+        break;
+    case PARITY_EVEN:
+        R8_UART1_LCR |= R8_LCR_PAR_EN;
+        R8_UART1_LCR |= 0x10;
+        break;
+    case PARITY_NONE:
+    default:
+        //R8_UART1_LCR &= (~R8_UART1_LCR);
+        break;
+    }
+
+#ifdef BSP_USING_UART0
+    if (uart_device == &uart_device0)
+    {
+        GPIOB_SetBits(GPIO_Pin_7);
+        GPIOB_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_PU);          // RXD-配置上拉输入
+        GPIOB_ModeCfg(GPIO_Pin_7, GPIO_ModeOut_PP_5mA);     // TXD-配置推挽输出,注意先让IO口输出高电平
+        R16_UART0_DL = R16_UARTx_DL;
+        R8_UART0_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;     // FIFO打开,触发点4字节
+        R8_UART0_LCR = R8_UARTx_LCR;
+        R8_UART0_IER = RB_IER_TXD_EN;
+        R8_UART0_DIV = 1;
+    }
+#endif
+#ifdef BSP_USING_UART1
+    if (uart_device == &uart_device1)
+    {
+        GPIOA_SetBits(GPIO_Pin_9);
+        GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);          // RXD-配置上拉输入
+        GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);     // TXD-配置推挽输出,注意先让IO口输出高电平
+        R16_UART1_DL = R16_UARTx_DL;
+        R8_UART1_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;     // FIFO打开,触发点4字节
+        R8_UART1_LCR = R8_UARTx_LCR;
+        R8_UART1_IER = RB_IER_TXD_EN;
+        R8_UART1_DIV = 1;
+    }
+#endif
+#ifdef BSP_USING_UART2
+    if (uart_device == &uart_device2)
+    {
+        GPIOA_SetBits(GPIO_Pin_7);
+        GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeIN_PU);          // RXD-配置上拉输入
+        GPIOA_ModeCfg(GPIO_Pin_7, GPIO_ModeOut_PP_5mA);     // TXD-配置推挽输出,注意先让IO口输出高电平
+        R16_UART2_DL = R16_UARTx_DL;
+        R8_UART2_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;     // FIFO打开,触发点4字节
+        R8_UART2_LCR = R8_UARTx_LCR;
+        R8_UART2_IER = RB_IER_TXD_EN;
+        R8_UART2_DIV = 1;
+    }
+#endif
+#ifdef BSP_USING_UART3
+    if (uart_device == &uart_device3)
+    {
+        GPIOA_SetBits(GPIO_Pin_5);
+        GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_PU);          // RXD-配置上拉输入
+        GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeOut_PP_5mA);     // TXD-配置推挽输出,注意先让IO口输出高电平
+        R16_UART3_DL = R16_UARTx_DL;
+        R8_UART3_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;     // FIFO打开,触发点4字节
+        R8_UART3_LCR = R8_UARTx_LCR;
+        R8_UART3_IER = RB_IER_TXD_EN;
+        R8_UART3_DIV = 1;
+    }
+#endif
+
+    return RT_EOK;
+}
+
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+    struct uart_device *uart_device = serial->parent.user_data;
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+#ifdef BSP_USING_UART0
+        if (uart_device == &uart_device0)
+        {
+            UART0_INTCfg(DISABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART0_IRQn);
+        }
+#endif
+#ifdef BSP_USING_UART1
+        if (uart_device == &uart_device1)
+        {
+            UART1_INTCfg(DISABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART1_IRQn);
+        }
+#endif
+#ifdef BSP_USING_UART2
+        if (uart_device == &uart_device2)
+        {
+            UART2_INTCfg(DISABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART2_IRQn);
+        }
+#endif
+#ifdef BSP_USING_UART3
+        if (uart_device == &uart_device3)
+        {
+            UART3_INTCfg(DISABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART3_IRQn);
+        }
+#endif
+        break;
+    case RT_DEVICE_CTRL_SET_INT:
+#ifdef BSP_USING_UART0
+        if (uart_device == &uart_device0)
+        {
+            UART0_ByteTrigCfg(UART_1BYTE_TRIG);
+            UART0_INTCfg(ENABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART0_IRQn);
+        }
+#endif
+#ifdef BSP_USING_UART1
+        if (uart_device == &uart_device1)
+        {
+            UART1_ByteTrigCfg(UART_1BYTE_TRIG);
+            UART1_INTCfg(ENABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART1_IRQn);
+        }
+#endif
+#ifdef BSP_USING_UART2
+        if (uart_device == &uart_device2)
+        {
+            UART2_ByteTrigCfg(UART_1BYTE_TRIG);
+            UART2_INTCfg(ENABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART2_IRQn);
+        }
+#endif
+#ifdef BSP_USING_UART3
+        if (uart_device == &uart_device3)
+        {
+            UART3_ByteTrigCfg(UART_1BYTE_TRIG);
+            UART3_INTCfg(ENABLE, RB_IER_RECV_RDY);
+            NVIC_EnableIRQ(UART3_IRQn);
+        }
+#endif
+        break;
+    default:
+        break;
+    }
+
+    return RT_EOK;
+}
+
+static int uart_putc(struct rt_serial_device *serial, char ch)
+{
+    struct uart_device *uart_device = serial->parent.user_data;
+
+#ifdef BSP_USING_UART0
+    if (uart_device == &uart_device0)
+    {
+        while (R8_UART0_TFC >= UART_FIFO_SIZE);
+        R8_UART0_THR = ch;
+    }
+#endif
+#ifdef BSP_USING_UART1
+    if (uart_device == &uart_device1)
+    {
+        while (R8_UART1_TFC >= UART_FIFO_SIZE);
+        R8_UART1_THR = ch;
+    }
+#endif
+#ifdef BSP_USING_UART2
+    if (uart_device == &uart_device2)
+    {
+        while (R8_UART2_TFC >= UART_FIFO_SIZE);
+        R8_UART2_THR = ch;
+    }
+#endif
+#ifdef BSP_USING_UART3
+    if (uart_device == &uart_device3)
+    {
+        while (R8_UART3_TFC >= UART_FIFO_SIZE);
+        R8_UART3_THR = ch;
+    }
+#endif
+
+    return 1;
+}
+
+static int uart_getc(struct rt_serial_device *serial)
+{
+    struct uart_device *uart_device = serial->parent.user_data;
+
+#ifdef BSP_USING_UART0
+    if (uart_device == &uart_device0)
+    {
+        if (R8_UART0_RFC > 0)
+        {
+            return R8_UART0_RBR;
+        }
+    }
+#endif
+#ifdef BSP_USING_UART1
+    if (uart_device == &uart_device1)
+    {
+        if (R8_UART1_RFC > 0)
+        {
+            return R8_UART1_RBR;
+        }
+    }
+#endif
+#ifdef BSP_USING_UART2
+    if (uart_device == &uart_device2)
+    {
+        if (R8_UART2_RFC > 0)
+        {
+            return R8_UART2_RBR;
+        }
+    }
+#endif
+#ifdef BSP_USING_UART3
+    if (uart_device == &uart_device3)
+    {
+        if (R8_UART3_RFC > 0)
+        {
+            return R8_UART3_RBR;
+        }
+    }
+#endif
+
+    return -1;
+}
+
+static const struct rt_uart_ops uart_ops =
+{
+    .configure = uart_configure,
+    .control = uart_control,
+    .putc = uart_putc,
+    .getc = uart_getc,
+    .dma_transmit = RT_NULL,
+};
+
+void uart_isr(struct rt_serial_device *serial, UINT8 flag)
+{
+    switch (flag)
+    {
+    case UART_II_RECV_RDY:          // 数据达到设置触发点
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+        break;
+    case UART_II_RECV_TOUT:         // 接收超时,暂时一帧数据接收完成
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_TIMEOUT);
+        break;
+    case UART_II_THR_EMPTY:         // 发送缓存区空,可继续发送
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
+        break;
+    default:
+        break;
+    }
+}
+
+#ifdef BSP_USING_UART0
+void UART0_IRQHandler(void)
+{
+    rt_interrupt_enter();
+
+    uart_isr(&uart_device0.serial, UART0_GetITFlag());
+
+    rt_interrupt_leave();
+}
+#endif
+#ifdef BSP_USING_UART1
+void UART1_IRQHandler(void)
+{
+    rt_interrupt_enter();
+
+    uart_isr(&uart_device1.serial, UART1_GetITFlag());
+
+    rt_interrupt_leave();
+}
+#endif
+#ifdef BSP_USING_UART2
+void UART2_IRQHandler(void)
+{
+    rt_interrupt_enter();
+
+    uart_isr(&uart_device2.serial, UART2_GetITFlag());
+
+    rt_interrupt_leave();
+}
+#endif
+#ifdef BSP_USING_UART3
+void UART3_IRQHandler(void)
+{
+    rt_interrupt_enter();
+
+    uart_isr(&uart_device3.serial, UART3_GetITFlag());
+
+    rt_interrupt_leave();
+}
+#endif
+
+int rt_hw_uart_init(void)
+{
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+#ifdef BSP_USING_UART0
+    uart_device0.serial.config = config;
+    uart_device0.serial.ops = &uart_ops;
+    rt_hw_serial_register(&uart_device0.serial, uart_device0.name,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
+                          &uart_device0);
+#endif
+#ifdef BSP_USING_UART1
+    uart_device1.serial.config = config;
+    uart_device1.serial.ops = &uart_ops;
+    rt_hw_serial_register(&uart_device1.serial, uart_device1.name,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
+                          &uart_device1);
+#endif
+#ifdef BSP_USING_UART2
+    uart_device2.serial.config = config;
+    uart_device2.serial.ops = &uart_ops;
+    rt_hw_serial_register(&uart_device2.serial, uart_device2.name,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
+                          &uart_device2);
+#endif
+#ifdef BSP_USING_UART3
+    uart_device3.serial.config = config;
+    uart_device3.serial.ops = &uart_ops;
+    rt_hw_serial_register(&uart_device3.serial, uart_device3.name,
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
+                          &uart_device3);
+#endif
+
+    return RT_EOK;
+}
+#endif /* BSP_USING_UART */

+ 16 - 0
bsp/wch/arm/ch579m/board/drv_uart.h

@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#ifndef DRV_UART_H__
+#define DRV_UART_H__
+
+int rt_hw_uart_init(void);
+
+#endif

+ 299 - 0
bsp/wch/arm/ch579m/board/drv_usbh.c

@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "board.h"
+#include "drv_usbh.h"
+
+#ifdef BSP_USING_USBH
+
+static struct rt_completion urb_completion;
+
+//USB接收缓存区
+__align(4) UINT8 usb_rx_buf[MAX_PACKET_SIZE];   // IN, must even address
+__align(4) UINT8 usb_tx_buf[MAX_PACKET_SIZE];   // OUT, must even address
+
+static struct uhcd uhcd;
+
+static rt_err_t drv_reset_port(rt_uint8_t port)
+{
+    //关闭中断
+    R8_USB_INT_EN = 0x00;
+
+    R8_USB_DEV_AD = (R8_USB_DEV_AD & RB_UDA_GP_BIT) | (0x00 & MASK_USB_ADDR);   //设置地址
+    R8_UHOST_CTRL &= ~RB_UH_PORT_EN;    // 关掉端口
+
+    //判断设备速度
+    if (R8_USB_MIS_ST & RB_UMS_DM_LEVEL)
+    {
+        //低速
+        R8_USB_CTRL |= RB_UC_LOW_SPEED; // 默认为低速
+        R8_UHOST_CTRL = (R8_UHOST_CTRL | RB_UH_LOW_SPEED) | RB_UH_BUS_RESET;    // 默认为低速,开始复位
+    }
+    else
+    {
+        //全速
+        R8_USB_CTRL &= ~ RB_UC_LOW_SPEED;   // 默认为全速
+        R8_UHOST_CTRL = (R8_UHOST_CTRL & ~RB_UH_LOW_SPEED) | RB_UH_BUS_RESET;   // 默认为全速,开始复位
+    }
+
+    rt_thread_mdelay(15); // 复位时间10mS到20mS
+    R8_UHOST_CTRL = R8_UHOST_CTRL & ~ RB_UH_BUS_RESET;  // 结束复位
+    rt_thread_mdelay(1);
+    R8_UHOST_CTRL |= RB_UH_PORT_EN; //打开端口
+    R8_USB_INT_FG = RB_UIF_DETECT;  // 清中断标志
+    //打开中断
+    R8_USB_INT_EN = RB_UIF_TRANSFER | RB_UIE_DETECT;
+
+    return RT_EOK;
+}
+
+static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
+{
+    rt_err_t res;
+    UINT16 i;
+    UINT16 retry_count = 3;
+    rt_uint8_t usb_pid, res_pid;
+    UINT8 *tog = (UINT8 *)pipe->user_data;
+
+    //设置目标usb地址
+    R8_USB_DEV_AD = (R8_USB_DEV_AD & RB_UDA_GP_BIT) | (pipe->inst->address & MASK_USB_ADDR);
+
+    //判断是in还是out操作
+    if (pipe->ep.bEndpointAddress & USB_DIR_IN)
+    {
+        usb_pid = USB_PID_IN; //in
+        R8_UH_TX_LEN = 0x00;
+    }
+    else
+    {
+        usb_pid = (token == USBH_PID_SETUP) ? USB_PID_SETUP : USB_PID_OUT; //setup/out
+        rt_memcpy(usb_tx_buf, buffer, nbytes);
+        R8_UH_TX_LEN = nbytes;
+    }
+
+    //设置数据TOG
+    switch (usb_pid)
+    {
+    case USB_PID_IN:
+        if (nbytes == 0) *tog = USB_PID_DATA1; //状态反馈
+        R8_UH_RX_CTRL = (*tog == USB_PID_DATA1) ? RB_UH_R_TOG : 0x00;
+        break;
+
+    case USB_PID_OUT:
+        if (nbytes == 0) *tog = USB_PID_DATA1; //状态反馈
+        R8_UH_TX_CTRL = (*tog == USB_PID_DATA1) ? RB_UH_T_TOG : 0x00;
+        break;
+
+    case USB_PID_SETUP:
+        *(UINT8 *)pipe->inst->pipe_ep0_out->user_data = USB_PID_DATA0;
+        *(UINT8 *)pipe->inst->pipe_ep0_in->user_data = USB_PID_DATA1;
+        R8_UH_TX_CTRL = (*tog == USB_PID_DATA1) ? RB_UH_T_TOG : 0x00;
+        break;
+    }
+
+    //usb枚举的时候加大重试次数,提高usb设备枚举成功率
+    if ((pipe->ep.bmAttributes & USB_EP_ATTR_TYPE_MASK) == USB_EP_ATTR_CONTROL)
+    {
+        retry_count = 1000;
+    }
+
+    for (i = 0; i < retry_count; i++)
+    {
+        //传输
+        R8_UH_EP_PID = (usb_pid << 4) | (pipe->ep.bEndpointAddress & 0x0F);
+        res = rt_completion_wait(&urb_completion, timeouts);
+        if (res != RT_EOK)
+        {
+            return res;
+        }
+
+        //判断是否需要反转数据
+        if (R8_USB_INT_ST & RB_UIS_TOG_OK)
+        {
+            *tog = (*tog == USB_PID_DATA0) ? USB_PID_DATA1 : USB_PID_DATA0;//翻转
+        }
+
+        res_pid = R8_USB_INT_ST & MASK_UIS_H_RES;
+
+        switch (res_pid)
+        {
+        case USB_PID_ACK://发送成功
+            pipe->status = UPIPE_STATUS_OK;
+            if (pipe->callback != RT_NULL) pipe->callback(pipe);
+            return nbytes;
+        case USB_PID_DATA0: //收到数据
+        case USB_PID_DATA1: //收到数据
+            pipe->status = UPIPE_STATUS_OK;
+            if (pipe->callback != RT_NULL) pipe->callback(pipe);
+            //拷贝数据到buffer
+            if (usb_pid == USB_PID_IN)
+            {
+                rt_memcpy(buffer, usb_rx_buf, R8_USB_RX_LEN);
+                return R8_USB_RX_LEN;
+            }
+            return nbytes;
+        case USB_PID_NAK: //数据未就绪
+            if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
+            {
+                rt_thread_delay((pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) > 0 ? (pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) : 1);
+            }
+            rt_thread_mdelay(1);
+            continue;//重试
+        case USB_PID_STALL: //传输停止
+            pipe->status = UPIPE_STATUS_STALL;
+            if (pipe->callback != RT_NULL) pipe->callback(pipe);
+            return 0;
+        default:
+            break;
+        }
+    }
+
+    pipe->status = UPIPE_STATUS_ERROR;
+
+    if (pipe->callback != RT_NULL) pipe->callback(pipe);
+    return -RT_ERROR;
+}
+
+static rt_err_t drv_open_pipe(upipe_t pipe)
+{
+    pipe->pipe_index = pipe->inst->address & MASK_USB_ADDR;
+    pipe->user_data = rt_malloc(sizeof(UINT8));
+
+    //默认发送DATA0
+    if (pipe->ep.bEndpointAddress & USB_DIR_IN)
+    {
+        *(UINT8 *)pipe->user_data = USB_PID_DATA0;
+    }
+    else
+    {
+        *(UINT8 *)pipe->user_data = USB_PID_DATA0;
+    }
+
+
+    return RT_EOK;
+}
+
+static rt_err_t drv_close_pipe(upipe_t pipe)
+{
+    rt_free(pipe->user_data);
+
+    return RT_EOK;
+}
+
+static struct uhcd_ops uhcd_ops =
+{
+    drv_reset_port,
+    drv_pipe_xfer,
+    drv_open_pipe,
+    drv_close_pipe,
+};
+
+static rt_err_t hcd_init(rt_device_t dev)
+{
+    R16_PIN_ANALOG_IE |= RB_PIN_USB_IE;
+
+    R8_USB_CTRL = RB_UC_HOST_MODE;
+    R8_UHOST_CTRL = 0;
+    R8_USB_DEV_AD = 0x00;
+
+    R8_UH_EP_MOD = RB_UH_EP_TX_EN | RB_UH_EP_RX_EN;
+    R16_UH_RX_DMA = (UINT16)(UINT32)usb_rx_buf;
+    R16_UH_TX_DMA = (UINT16)(UINT32)usb_tx_buf;
+
+    R8_USB_CTRL =  RB_UC_HOST_MODE | RB_UC_INT_BUSY | RB_UC_DMA_EN;
+    R8_UH_SETUP = RB_UH_SOF_EN;
+    R8_USB_INT_FG = 0xFF;
+
+    R8_USB_INT_EN = RB_UIF_TRANSFER | RB_UIE_DETECT;
+
+    //开启中断
+    NVIC_EnableIRQ(USB_IRQn);
+
+    rt_completion_init(&urb_completion);
+
+    return RT_EOK;
+}
+
+void USB_IRQHandler()
+{
+    rt_interrupt_enter();
+
+    //USB连接断开中断
+    if (R8_USB_INT_FG & RB_UIF_DETECT)
+    {
+        R8_USB_INT_FG = RB_UIF_DETECT;//清除中断
+
+        //检查USB设备连接状态
+        if ((R8_USB_MIS_ST & RB_UMS_DEV_ATTACH) != 0)
+        {
+            rt_usbh_root_hub_connect_handler(&uhcd, 1, RT_FALSE);
+            rt_kprintf("usb: up\n");
+        }
+        else
+        {
+            rt_usbh_root_hub_disconnect_handler(&uhcd, 1);
+            rt_kprintf("usb: down\n");
+        }
+    }
+
+    if (R8_USB_INT_FG & RB_UIF_TRANSFER)
+    {
+        R8_UH_EP_PID = 0x00; //停止发送
+
+        R8_USB_INT_FG = RB_UIF_TRANSFER;//清除中断
+
+        rt_completion_done(&urb_completion);
+    }
+
+    if (R8_USB_INT_FG & RB_UIF_SUSPEND)
+    {
+        R8_USB_INT_FG = RB_UIF_SUSPEND;//清除中断
+    }
+
+    if (R8_USB_INT_FG & RB_UIF_HST_SOF)
+    {
+        R8_USB_INT_FG = RB_UIF_HST_SOF;//清除中断
+    }
+
+    if (R8_USB_INT_FG & RB_UIF_FIFO_OV)
+    {
+        R8_USB_INT_FG = RB_UIF_FIFO_OV;//清除中断
+    }
+
+    rt_interrupt_leave();
+}
+
+int rt_hw_usbh_init(void)
+{
+    rt_err_t res = -RT_ERROR;
+
+    rt_memset((void *)&uhcd, 0, sizeof(struct uhcd));
+    uhcd.parent.type = RT_Device_Class_USBHost;
+    uhcd.parent.init = hcd_init;
+    uhcd.ops = &uhcd_ops;
+    uhcd.num_ports = 1;
+
+    res = rt_device_register(&uhcd.parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
+
+    if (res != RT_EOK)
+    {
+        rt_kprintf("register usb host failed res = %d\r\n", res);
+        return -RT_ERROR;
+    }
+
+    rt_usb_host_init("usbh");
+
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_usbh_init);
+#endif /* BSP_USING_USBH */
+

+ 28 - 0
bsp/wch/arm/ch579m/board/drv_usbh.h

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2022-02-16     Tuber             first version
+ */
+
+#ifndef __DRV_USBH_H__
+#define __DRV_USBH_H__
+#include <rtthread.h>
+
+#define USB_PID_SETUP           0x0D
+#define USB_PID_IN              0x09
+#define USB_PID_OUT             0x01
+#define USB_PID_SOF             0x05
+#define USB_PID_ACK             0x02
+#define USB_PID_NAK             0x0A
+#define USB_PID_STALL           0x0E
+#define USB_PID_DATA0           0x03
+#define USB_PID_DATA1           0x0B
+#define USB_PID_PRE             0x0C
+
+int rt_hw_usbh_init(void);
+
+#endif

+ 711 - 0
bsp/wch/arm/ch579m/libraries/CMSIS/Include/core_cm0.h

@@ -0,0 +1,711 @@
+/**************************************************************************//**
+ * @file     core_cm0.h
+ * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version  V4.00
+ * @date     22. August 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M0
+  @{
+ */
+
+/*  CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN  (0x04)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM0_CMSIS_VERSION_SUB   (0x00)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM0_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x00)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler      */
+  #define __INLINE         inline                                    /*use -pc99 on compile line !< inline keyword for COSMIC Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI__VFP_SUPPORT____
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __CSMC__ )      /* Cosmic */
+  #if ( __CSMC__ & 0x400)       // FPU present for parser
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0_REV
+    #define __CM0_REV               0x0000
+    #warning "__CM0_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[1];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[31];
+  __IO uint32_t ICER[1];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register          */
+       uint32_t RSERVED1[31];
+  __IO uint32_t ISPR[1];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register           */
+       uint32_t RESERVED2[31];
+  __IO uint32_t ICPR[1];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register         */
+       uint32_t RESERVED3[31];
+       uint32_t RESERVED4[64];
+  __IO uint32_t IP[8];                   /*!< Offset: 0x300 (R/W)  Interrupt Priority Register              */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+       uint32_t RESERVED0;
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+       uint32_t RESERVED1;
+  __IO uint32_t SHP[2];                  /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED   */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
+                are only accessible over DAP and not via processor. Therefore
+                they are not covered by the Cortex-M0 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address              */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                 */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  (((uint32_t)(IRQn)       )    &  0x03) * 8 )
+#define _SHP_IDX(IRQn)           ( ((((uint32_t)(IRQn) & 0x0F)-8) >>    2)     )
+#define _IP_IDX(IRQn)            (   ((uint32_t)(IRQn)            >>    2)     )
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+  else {
+    NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M0 system interrupts */
+  else {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */

+ 637 - 0
bsp/wch/arm/ch579m/libraries/CMSIS/Include/core_cmFunc.h

@@ -0,0 +1,637 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V4.00
+ * @date     28. August 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  register uint32_t __regIPSR          __ASM("ipsr");
+  return(__regIPSR);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  register uint32_t __regXPSR          __ASM("xpsr");
+  return(__regXPSR);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  return(__regProcessStackPointer);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  __regProcessStackPointer = topOfProcStack;
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  return(__regMainStackPointer);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  __regMainStackPointer = topOfMainStack;
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__STATIC_INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0xff);
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
+
+
+#if       (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief  Enable IRQ Interrupts
+
+  This function enables IRQ interrupts by clearing the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/** \brief  Disable IRQ Interrupts
+
+  This function disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  uint32_t result;
+
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+
+#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
+/* Cosmic specific functions */
+#include <cmsis_csm.h>
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+#endif /* __CORE_CMFUNC_H */

+ 880 - 0
bsp/wch/arm/ch579m/libraries/CMSIS/Include/core_cmInstr.h

@@ -0,0 +1,880 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V4.00
+ * @date     28. August 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+#define __WFI                             __wfi
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+#define __WFE                             __wfe
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+#define __ISB()                           __isb(0xF)
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB()                           __dsb(0xF)
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+#define __DMB()                           __dmb(0xF)
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+  rev16 r0, r0
+  bx lr
+}
+#endif
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+#endif
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+/** \brief  Breakpoint
+
+    This function causes the processor to enter Debug state.
+    Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __breakpoint(value)
+
+
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __RBIT                            __rbit
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function executes a exclusive LDR instruction for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+#define __LDREXB(ptr)                     ((uint8_t ) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function executes a exclusive LDR instruction for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+#define __LDREXH(ptr)                     ((uint16_t) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function executes a exclusive LDR instruction for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+#define __LDREXW(ptr)                     ((uint32_t ) __ldrex(ptr))
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function executes a exclusive STR instruction for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXB(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function executes a exclusive STR instruction for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXH(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function executes a exclusive STR instruction for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXW(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+#define __CLREX                           __clrex
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT                            __ssat
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT                            __usat
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+#define __CLZ                             __clz
+
+
+/** \brief  Rotate Right with Extend (32 bit)
+
+    This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.
+
+    \param [in]    value  Value to rotate
+    \return               Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+  rrx r0, r0
+  bx lr
+}
+#endif
+
+
+/** \brief  LDRT Unprivileged (8 bit)
+
+    This function executes a Unprivileged LDRT instruction for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr)                      ((uint8_t )  __ldrt(ptr))
+
+
+/** \brief  LDRT Unprivileged (16 bit)
+
+    This function executes a Unprivileged LDRT instruction for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr)                      ((uint16_t)  __ldrt(ptr))
+
+
+/** \brief  LDRT Unprivileged (32 bit)
+
+    This function executes a Unprivileged LDRT instruction for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr)                       ((uint32_t ) __ldrt(ptr))
+
+
+/** \brief  STRT Unprivileged (8 bit)
+
+    This function executes a Unprivileged STRT instruction for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+ */
+#define __STRBT(value, ptr)               __strt(value, ptr)
+
+
+/** \brief  STRT Unprivileged (16 bit)
+
+    This function executes a Unprivileged STRT instruction for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+ */
+#define __STRHT(value, ptr)               __strt(value, ptr)
+
+
+/** \brief  STRT Unprivileged (32 bit)
+
+    This function executes a Unprivileged STRT instruction for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+ */
+#define __STRT(value, ptr)                __strt(value, ptr)
+
+#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constrant "l"
+ * Otherwise, use general registers, specified by constrant "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
+{
+  __ASM volatile ("nop");
+}
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
+{
+  __ASM volatile ("wfi");
+}
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
+{
+  __ASM volatile ("wfe");
+}
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
+{
+  __ASM volatile ("sev");
+}
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
+{
+  __ASM volatile ("isb");
+}
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
+{
+  __ASM volatile ("dsb");
+}
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
+{
+  __ASM volatile ("dmb");
+}
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+  return __builtin_bswap32(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+  return (short)__builtin_bswap16(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32 - op2));
+}
+
+
+/** \brief  Breakpoint
+
+    This function causes the processor to enter Debug state.
+    Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function executes a exclusive LDR instruction for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function executes a exclusive LDR instruction for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function executes a exclusive LDR instruction for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function executes a exclusive STR instruction for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function executes a exclusive STR instruction for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function executes a exclusive STR instruction for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
+{
+  __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/** \brief  Rotate Right with Extend (32 bit)
+
+    This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.
+
+    \param [in]    value  Value to rotate
+    \return               Rotated value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/** \brief  LDRT Unprivileged (8 bit)
+
+    This function executes a Unprivileged LDRT instruction for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/** \brief  LDRT Unprivileged (16 bit)
+
+    This function executes a Unprivileged LDRT instruction for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/** \brief  LDRT Unprivileged (32 bit)
+
+    This function executes a Unprivileged LDRT instruction for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/** \brief  STRT Unprivileged (8 bit)
+
+    This function executes a Unprivileged STRT instruction for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+   __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/** \brief  STRT Unprivileged (16 bit)
+
+    This function executes a Unprivileged STRT instruction for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+   __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/** \brief  STRT Unprivileged (32 bit)
+
+    This function executes a Unprivileged STRT instruction for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+   __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
+}
+
+#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+
+#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
+/* Cosmic specific functions */
+#include <cmsis_csm.h>
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */

+ 16 - 0
bsp/wch/arm/ch579m/libraries/SConscript

@@ -0,0 +1,16 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd  = GetCurrentDir()
+# The set of source files associated with this SConscript file.
+src = Split("""
+""")
+CPPPATH = [cwd + '/StdPeriphDriver/inc', cwd + '/CMSIS/Include']
+
+src += ['Startup/startup_ARMCM0.s']
+src += Glob('StdPeriphDriver/*.c')
+
+group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 237 - 0
bsp/wch/arm/ch579m/libraries/Startup/startup_ARMCM0.s

@@ -0,0 +1,237 @@
+;/**************************************************************************//**
+; * @file     startup_ARMCM0.s
+; * @brief    CMSIS Core Device Startup File for
+; *           ARMCM0 Device Series
+; * @version  V1.08
+; * @date     23. November 2012
+; *
+; * @note
+; *
+; ******************************************************************************/
+;/* Copyright (c) 2011 - 2012 ARM LIMITED
+;
+;   All rights reserved.
+;   Redistribution and use in source and binary forms, with or without
+;   modification, are permitted provided that the following conditions are met:
+;   - Redistributions of source code must retain the above copyright
+;     notice, this list of conditions and the following disclaimer.
+;   - Redistributions in binary form must reproduce the above copyright
+;     notice, this list of conditions and the following disclaimer in the
+;     documentation and/or other materials provided with the distribution.
+;   - Neither the name of ARM nor the names of its contributors may be used
+;     to endorse or promote products derived from this software without
+;     specific prior written permission.
+;   *
+;   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+;   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+;   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+;   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+;   POSSIBILITY OF SUCH DAMAGE.
+;   ---------------------------------------------------------------------------*/
+;/*
+;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+;*/
+
+
+; <h> Stack Configuration
+;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Stack_Size      EQU     0x00000400
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem       SPACE   Stack_Size
+__initial_sp    EQU     0x20008000
+
+
+; <h> Heap Configuration
+;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Heap_Size       EQU     0x00000400
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+
+                PRESERVE8
+                THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+
+                AREA    RESET, DATA, READONLY
+                EXPORT  __Vectors
+                EXPORT  __Vectors_End
+                EXPORT  __Vectors_Size
+
+__Vectors       DCD     __initial_sp              ; Top of Stack
+                DCD     Reset_Handler             ; Reset Handler
+                DCD     NMI_Handler               ; NMI Handler
+                DCD     HardFault_Handler         ; Hard Fault Handler
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     SVC_Handler               ; SVCall Handler
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     PendSV_Handler            ; PendSV Handler
+                DCD     SysTick_Handler           ; SysTick Handler
+
+                ; External Interrupts
+                DCD     TMR0_IRQHandler           ;  0:  TMR0
+                DCD     GPIO_IRQHandler           ;  1:  GPIO
+                DCD     SLAVE_IRQHandler          ;  2:  SLAVE
+                DCD     SPI0_IRQHandler           ;  3:  SPI0
+                DCD     BB_IRQHandler             ;  4:  BB
+                DCD     LLE_IRQHandler            ;  5:  LLE
+                DCD     USB_IRQHandler            ;  6:  USB
+                DCD     ETH_IRQHandler            ;  7:  ETH
+                DCD     TMR1_IRQHandler           ;  8:  TMR1
+                DCD     TMR2_IRQHandler           ;  9:  TMR2
+                DCD     UART0_IRQHandler          ; 10:  UART0
+                DCD     UART1_IRQHandler          ; 11:  UART1
+                DCD     RTC_IRQHandler            ; 12:  RTC
+                DCD     ADC_IRQHandler            ; 13:  ADC
+                DCD     SPI1_IRQHandler           ; 14:  SPI1
+                DCD     LED_IRQHandler            ; 15:  LED
+                DCD     TMR3_IRQHandler           ; 16:  TMR3 
+                DCD     UART2_IRQHandler          ; 17:  UART2
+                DCD     UART3_IRQHandler          ; 18:  UART3
+                DCD     WDT_IRQHandler            ; 19:  WDT
+__Vectors_End
+
+__Vectors_Size  EQU     __Vectors_End - __Vectors
+
+                AREA    |.text|, CODE, READONLY
+
+
+; Reset Handler
+
+Reset_Handler   PROC
+                EXPORT  Reset_Handler             [WEAK]
+                IMPORT  SystemInit
+                IMPORT  __main
+				;LDR     R0, =0x1007058	
+				;MOV     SP, R0
+				LDR     R0, =SystemInit
+                BLX     R0
+                LDR     R0, =__main
+                BX      R0
+                ENDP
+
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler     PROC
+                EXPORT  NMI_Handler               [WEAK]
+                B       .
+                ENDP
+HardFault_Handler\
+                PROC
+                EXPORT  HardFault_Handler         [WEAK]
+;                B       .
+                ENDP
+SVC_Handler     PROC
+                EXPORT  SVC_Handler               [WEAK]
+                B       .
+                ENDP
+PendSV_Handler  PROC
+                EXPORT  PendSV_Handler            [WEAK]
+                B       .
+                ENDP
+SysTick_Handler PROC
+                EXPORT  SysTick_Handler           [WEAK]
+                B       .
+                ENDP
+
+Default_Handler PROC
+
+                EXPORT     TMR0_IRQHandler           [WEAK];  0:  TMR0
+                EXPORT     GPIO_IRQHandler           [WEAK];  1:  GPIO
+                EXPORT     SLAVE_IRQHandler          [WEAK];  2:  SLAVE
+                EXPORT     SPI0_IRQHandler           [WEAK];  3:  SPI0
+                EXPORT     BB_IRQHandler             [WEAK];  4:  BB
+                EXPORT     LLE_IRQHandler            [WEAK];  5:  LLE
+                EXPORT     USB_IRQHandler            [WEAK];  6:  USB
+                EXPORT     ETH_IRQHandler            [WEAK];  7:  ETH
+                EXPORT     TMR1_IRQHandler           [WEAK];  8:  TMR1
+                EXPORT     TMR2_IRQHandler           [WEAK];  9:  TMR2
+                EXPORT     UART0_IRQHandler          [WEAK]; 10:  UART0
+                EXPORT     UART1_IRQHandler          [WEAK]; 11:  UART1
+                EXPORT     RTC_IRQHandler            [WEAK]; 12:  RTC
+                EXPORT     ADC_IRQHandler            [WEAK]; 13:  ADC
+                EXPORT     SPI1_IRQHandler           [WEAK]; 14:  SPI1
+                EXPORT     LED_IRQHandler            [WEAK]; 15:  LED
+                EXPORT     TMR3_IRQHandler           [WEAK]; 16:  TMR3 
+                EXPORT     UART2_IRQHandler          [WEAK]; 17:  UART2
+                EXPORT     UART3_IRQHandler          [WEAK]; 18:  UART3
+                EXPORT     WDT_IRQHandler            [WEAK]; 19:  WDT
+
+TMR0_IRQHandler           ;  0:  TMR0
+GPIO_IRQHandler           ;  1:  GPIO
+SLAVE_IRQHandler          ;  2:  SLAVE
+SPI0_IRQHandler           ;  3:  SPI0
+BB_IRQHandler             ;  4:  BB
+LLE_IRQHandler            ;  5:  LLE
+USB_IRQHandler            ;  6:  USB
+ETH_IRQHandler            ;  7:  ETH
+TMR1_IRQHandler           ;  8:  TMR1
+TMR2_IRQHandler           ;  9:  TMR2
+UART0_IRQHandler          ; 10:  UART0
+UART1_IRQHandler          ; 11:  UART1
+RTC_IRQHandler            ; 12:  RTC
+ADC_IRQHandler            ; 13:  ADC
+SPI1_IRQHandler           ; 14:  SPI1
+LED_IRQHandler            ; 15:  LED
+TMR3_IRQHandler           ; 16:  TMR3 
+UART2_IRQHandler          ; 17:  UART2
+UART3_IRQHandler          ; 18:  UART3
+WDT_IRQHandler            ; 19:  WDT
+                B       .
+
+                ENDP
+
+
+                ALIGN
+
+
+; User Initial Stack & Heap
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __initial_sp
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+
+__user_initial_stackheap PROC
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + Stack_Size)
+                LDR     R2, = (Heap_Mem +  Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDP
+
+                ALIGN
+
+                ENDIF
+
+
+                END

+ 223 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_adc.c

@@ -0,0 +1,223 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_adc.c
+* Author             : WCH
+* Version            : V1.1
+* Date               : 2020/04/01
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : ADC_DataCalib_Rough
+* Description    : 采样数据粗调,获取偏差值
+*                  注意,使用粗调校准,必须保证 PA5(AIN1)设置为浮空输入模式,管脚外部不要有电压
+* Input          : None
+* Return         : 偏差值
+*******************************************************************************/
+signed short ADC_DataCalib_Rough( void )        // 采样数据粗调,获取偏差值
+{
+    UINT16  i;
+    UINT32  sum=0;
+    UINT8  ch=0;        // 备份通道
+    UINT8   ctrl=0;     // 备份控制寄存器
+
+    ch = R8_ADC_CHANNEL;
+    ctrl = R8_ADC_CFG;
+
+    ADC_ChannelCfg( 1 );
+    R8_ADC_CFG |= RB_ADC_OFS_TEST;      // 进入测试模式
+    R8_ADC_CONVERT = RB_ADC_START;
+    while( R8_ADC_CONVERT & RB_ADC_START );
+    for(i=0; i<16; i++)
+    {
+        R8_ADC_CONVERT = RB_ADC_START;
+        while( R8_ADC_CONVERT & RB_ADC_START );
+        sum += (~R16_ADC_DATA)&RB_ADC_DATA;
+    }
+    sum = (sum+8)>>4;
+    R8_ADC_CFG &= ~RB_ADC_OFS_TEST;      // 关闭测试模式
+
+
+    R8_ADC_CHANNEL = ch;
+    R8_ADC_CFG = ctrl;
+    return (2048 - sum);
+}
+
+void ADC_DataCalib_Fine( PUINT16 dat, ADC_SignalPGATypeDef ga )        // 采样数据细调
+{
+    UINT32  d = (UINT32)*dat;
+
+    switch( ga )
+    {
+        case ADC_PGA_1_4:         // y=0.973x+55.188
+            *dat = (996*d + 56513 + 512)>>10;
+            break;
+
+        case ADC_PGA_1_2:         // y=0.974x+55.26
+            *dat = (997*d + 56586 + 512)>>10;
+            break;
+
+        case ADC_PGA_0:         // y=0.975x+53.63
+            *dat = (998*d + 54917 + 512)>>10;
+            break;
+
+        case ADC_PGA_2:         // y=0.975x+51.58
+            *dat = (998*d + 52818 + 512)>>10;
+            break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : ADC_ExtSingleChSampInit
+* Description    : 外部信号单通道采样初始化
+* Input          : sp:
+                    refer to ADC_SampClkTypeDef
+                   ga:
+                    refer to ADC_SignalPGATypeDef
+* Return         : None
+*******************************************************************************/
+void ADC_ExtSingleChSampInit( ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga )
+{
+    R8_ADC_CFG = RB_ADC_POWER_ON            \
+                |RB_ADC_BUF_EN              \
+                |( sp<<6 )                  \
+                |( ga<<4 )  ;
+}
+
+/*******************************************************************************
+* Function Name  : ADC_ExtDiffChSampInit
+* Description    : 外部信号差分通道采样初始化
+* Input          : sp:
+                    refer to ADC_SampClkTypeDef
+                   ga:
+                    refer to ADC_SignalPGATypeDef
+* Return         : None
+*******************************************************************************/
+void ADC_ExtDiffChSampInit( ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga )
+{
+    R8_ADC_CFG = RB_ADC_POWER_ON            \
+                |RB_ADC_DIFF_EN             \
+                |( sp<<6 )                  \
+                |( ga<<4 )  ;
+}
+
+/*******************************************************************************
+* Function Name  : ADC_InterTSSampInit
+* Description    : 内置温度传感器采样初始化
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void ADC_InterTSSampInit( void )
+{
+    R8_TEM_SENSOR |= RB_TEM_SEN_PWR_ON;
+    R8_ADC_CHANNEL = CH_INTE_VTEMP;
+    R8_ADC_CFG = RB_ADC_POWER_ON            \
+                |( 2<<4 )   ;
+}
+
+/*******************************************************************************
+* Function Name  : ADC_InterBATSampInit
+* Description    : 内置电池电压采样初始化
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void ADC_InterBATSampInit( void )
+{
+    R8_ADC_CHANNEL = CH_INTE_VBAT;
+    R8_ADC_CFG = RB_ADC_POWER_ON            \
+                |RB_ADC_BUF_EN              \
+                |( 0<<4 )   ;       // 使用-12dB模式,
+}
+
+
+/*******************************************************************************
+* Function Name  : TouchKey_ChSampInit
+* Description    : 触摸按键通道采样初始化
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void TouchKey_ChSampInit( void )
+{
+    R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | ( 2<<4 );
+    R8_TKEY_CTRL = RB_TKEY_PWR_ON;
+}
+
+/*******************************************************************************
+* Function Name  : ADC_ExcutSingleConver
+* Description    : ADC执行单次转换
+* Input          : None
+* Return         : ADC转换后的数据
+*******************************************************************************/
+UINT16 ADC_ExcutSingleConver( void )
+{
+    R8_ADC_CONVERT = RB_ADC_START;
+    while( R8_ADC_CONVERT & RB_ADC_START );
+
+    return ( R16_ADC_DATA&RB_ADC_DATA );
+}
+
+/*******************************************************************************
+* Function Name  : TouchKey_ExcutSingleConver
+* Description    : TouchKey转换后数据
+* Input          : d:  Touchkey充放电时间,高4bit-放电时间,整个8bit-充电时间
+* Return         : 当前TouchKey等效数据
+*******************************************************************************/
+UINT16 TouchKey_ExcutSingleConver( UINT8 d )
+{
+    R8_TKEY_CTRL = RB_TKEY_PWR_ON;
+    R8_TKEY_CNT = d;
+    while( R8_TKEY_CTRL &  RB_TKEY_ACTION );
+
+    return ( R16_ADC_DATA&RB_ADC_DATA );
+}
+
+
+/*******************************************************************************
+* Function Name  : ADC_GetCurrentTS
+* Description    : 获取当前采样的温度值(℃)
+* Input          : ts_v:当前温度传感器采样输出
+* Return         : 转换后的温度值(℃)
+*******************************************************************************/
+int ADC_GetCurrentTS( UINT16 ts_v )
+{
+    UINT16  vol_ts;
+    UINT16  D85_tem, D85_vol;
+    UINT16  D25_tem, D25_vol;
+    UINT16  temperK;
+    UINT32  temp;
+    UINT8   sum, sumck;
+    int     cal;
+
+    temperK = 64;    // mV/16^C
+    vol_ts = (ts_v*1060)>>11;
+    temp = (*((PUINT32)ROM_TMP_25C_ADDR));
+    D25_tem = temp;
+    D25_vol = (temp>>16);
+
+    if( D25_vol != 0 ){ // 默认系数换算
+        // T = T85 + (V-V85)*16/D25
+        cal =  (D25_tem*temperK + vol_ts*16 + (temperK>>1) - D25_vol*16) / temperK ;
+        return ( cal );
+    }
+    else{  // 内置系数换算  D25_tem
+        temp = (*((PUINT32)ROM_TMP_85C_ADDR));
+        sum = (UINT8)(temp>>24);        // 最高字节
+        sumck = (UINT8)(temp>>16);
+        sumck += (UINT8)(temp>>8);
+        sumck += (UINT8)temp;
+        if( sum != sumck )      return 0xff;        // 校验和出错
+
+        temperK = D25_tem;      // D25_tem = temperK
+        D85_tem = (UINT16)((temp>>16)&0x00ff);
+        D85_vol = (UINT16)temp;
+
+        // T = T85 + (V-V85)*16/D25
+        cal =  (D85_tem*temperK + vol_ts*16 + (temperK>>1) - D85_vol*16) / temperK ;
+        return ( cal );
+    }
+}
+
+
+

+ 595 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_clk.c

@@ -0,0 +1,595 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_clk.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+/*******************************************************************************
+* Function Name  : SystemInit
+* Description    : 系统时钟默认初始化
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void SystemInit(void)
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R16_CLK_SYS_CFG = (2<<6)|0x08;          // 32M -> Fsys
+    *((PUINT16V)0x40001048) |= 4;
+    R8_SAFE_ACCESS_SIG = 0;
+
+    mDelayuS(10);
+    /* 开启电压监控 */
+    PowerMonitor( ENABLE );
+}
+
+/*******************************************************************************
+* Function Name  : SetSysClock
+* Description    : 重设系统运行时钟
+* Input          : sc: 系统时钟源选择
+                    refer to SYS_CLKTypeDef
+* Return         : None
+*******************************************************************************/
+void SetSysClock( SYS_CLKTypeDef sc)
+{
+    switch( sc )
+    {
+        case CLK_SOURCE_LSI:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R8_CK32K_CONFIG &= ~RB_CLK_OSC32K_XT;
+            R16_CLK_SYS_CFG = (3<<6)|0x08;
+            break;
+        case CLK_SOURCE_LSE:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R8_CK32K_CONFIG |= RB_CLK_OSC32K_XT;
+            R16_CLK_SYS_CFG = (3<<6)|0x08;
+            break;
+        case CLK_SOURCE_HSE_32MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(2<<6)|0x08;
+            break;
+        case CLK_SOURCE_HSE_16MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(0<<6)|0x02;
+            break;
+        case CLK_SOURCE_HSE_8MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(0<<6)|0x04;
+            break;
+        case CLK_SOURCE_HSI_32MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = (2<<6)|0x08;
+            break;
+        case CLK_SOURCE_HSI_16MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = (0<<6)|0x02;
+            break;
+        case CLK_SOURCE_HSI_8MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = (0<<6)|0x04;
+            break;
+        case CLK_SOURCE_PLL_40MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(1<<6)|12;
+            break;
+        case CLK_SOURCE_PLL_32MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(1<<6)|15;
+            break;
+        case CLK_SOURCE_PLL_24MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(1<<6)|20;
+            break;
+        case CLK_SOURCE_PLL_20MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(1<<6)|24;
+            break;
+        case CLK_SOURCE_PLL_16MHz:
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+            R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(1<<6)|30;
+            break;
+        default :
+            break;
+    }
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : GetSysClock
+* Description    : 获取当前系统时钟
+* Input          : None
+* Return         : Hz
+*******************************************************************************/
+UINT32 GetSysClock( void )
+{
+    UINT16  rev;
+
+    rev = R16_CLK_SYS_CFG & 0xff;
+    if( (rev & RB_CLK_SYS_MOD) == (2<<6) ){             // 32M做主频
+        return (32000000);
+    }
+    else if( (rev & RB_CLK_SYS_MOD) == (1<<6) ){        // PLL进行分频
+        return (480000000/(rev&0x1f));
+    }
+    else if( (rev & RB_CLK_SYS_MOD) == (0<<6) ){        // 32M进行分频
+        return (32000000/(rev&0x1f));
+    }
+    else {                                              // 32K做主频
+        return (32000);
+    }
+}
+
+/*******************************************************************************
+* Function Name  : HClk32M_Select
+* Description    : 32M 高频时钟来源
+* Input          : hc:
+                    Clk32M_HSI   -   选择内部32M
+                    Clk32M_HSE   -   选择外部32M
+* Return         : None
+*******************************************************************************/
+void HClk32M_Select( HClk32MTypeDef hc)
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    if( hc == Clk32M_HSI)
+        R16_CLK_SYS_CFG &= ~RB_CLK_OSC32M_XT;
+    else
+        R16_CLK_SYS_CFG |= RB_CLK_OSC32M_XT;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : LClk32K_Select
+* Description    : 32K 低频时钟来源
+* Input          : hc:
+                    Clk32K_LSI   -   选择内部32K
+                    Clk32K_LSE   -   选择外部32K
+* Return         : None
+*******************************************************************************/
+void LClk32K_Select( LClk32KTypeDef hc)
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    if( hc == Clk32K_LSI)
+        R8_CK32K_CONFIG &= ~RB_CLK_OSC32K_XT;
+    else
+        R8_CK32K_CONFIG |= RB_CLK_OSC32K_XT;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+
+/*******************************************************************************
+* Function Name  : HSECFG_Current
+* Description    : HSE晶体 偏置电流配置
+* Input          : c: 75%,100%,125%,150%
+* Return         : None
+*******************************************************************************/
+void HSECFG_Current( HSECurrentTypeDef c )
+{
+    UINT8  x32M_c;
+
+    x32M_c = R8_XT32M_TUNE;
+    x32M_c = (x32M_c&0xfc)|(c&0x03);
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_XT32M_TUNE = x32M_c;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : HSECFG_Capacitance
+* Description    : HSE晶体 负载电容配置
+* Input          : c: refer to HSECapTypeDef
+* Return         : None
+*******************************************************************************/
+void HSECFG_Capacitance( HSECapTypeDef c )
+{
+    UINT8  x32M_c;
+
+    x32M_c = R8_XT32M_TUNE;
+    x32M_c = (x32M_c&0x8f)|(c<<4);
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_XT32M_TUNE = x32M_c;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : LSECFG_Current
+* Description    : LSE晶体 偏置电流配置
+* Input          : c: 70%,100%,140%,200%
+* Return         : None
+*******************************************************************************/
+void LSECFG_Current( LSECurrentTypeDef c )
+{
+    UINT8  x32K_c;
+
+    x32K_c = R8_XT32K_TUNE;
+    x32K_c = (x32K_c&0xfc)|(c&0x03);
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_XT32K_TUNE = x32K_c;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : LSECFG_Capacitance
+* Description    : LSE晶体 负载电容配置
+* Input          : c: refer to LSECapTypeDef
+* Return         : None
+*******************************************************************************/
+void LSECFG_Capacitance( LSECapTypeDef c )
+{
+    UINT8  x32K_c;
+
+    x32K_c = R8_XT32K_TUNE;
+    x32K_c = (x32K_c&0x0f)|(c<<4);
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_XT32K_TUNE = x32K_c;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+/*******************************************************************************
+* Function Name  : Calibration_LSI
+* Description    : 校准内部32K时钟
+* Input          : None
+* Return         : 误差:千分之(单位)
+*******************************************************************************/
+// 0-26030Hz    1023-44220Hz
+UINT16 Calibration_LSI( void )
+{
+    UINT16  rev, basev;
+    UINT32  calv;
+    UINT16  i;
+    UINT16  loc, loc_t;
+    signed short   CNT_STEP_K;
+    signed short   diff_1, diff_2, diffc;
+    UINT8  k=0;
+
+    /* 根据当前时钟获取标称值和斜率(T-step) */
+    rev = R16_CLK_SYS_CFG & 0xff;
+    // CNT_STEP_K=Fsys*5*(1/26030 - 1/44220)/1023;
+    if( (rev & RB_CLK_SYS_MOD) == (2<<6) ){             // 32M做主频
+        calv = ((5*32000000+(CAB_LSIFQ>>1))/CAB_LSIFQ);
+        CNT_STEP_K = -3;
+    }
+    else if( (rev & RB_CLK_SYS_MOD) == (1<<6) ){        // PLL进行分频
+        calv = (((UINT32)5*480000000/(rev&0x1f)+(CAB_LSIFQ>>1))/CAB_LSIFQ);
+        CNT_STEP_K =( -37-((rev&0x1f)-1))/(rev&0x1f);
+    }
+    else if( (rev & RB_CLK_SYS_MOD) == (0<<6) ){        // 32M进行分频
+        calv = ((5*32000000/(rev&0x1f)+(CAB_LSIFQ>>1))/CAB_LSIFQ);
+        CNT_STEP_K = ( -3-((rev&0x1f)-1))/(rev&0x1f);
+    }
+    else {                                              // 32K做主频
+        calv = (5);
+        CNT_STEP_K = 0;
+    }
+
+    /* 校准 */
+    basev = ( calv &0xfff );                    // 获取校准标称值
+    // loc = 1023*(f-26030)/f/((44220-26030)/44220)  经验曲线
+    loc = R16_INT32K_TUNE;
+    diff_2 = 0;
+    diffc = 0;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_OSC_CAL_CTRL = RB_OSC_CNT_EN;
+    do
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R16_INT32K_TUNE = loc;
+        R8_SAFE_ACCESS_SIG = 0;
+
+        /* 读取当前值 */
+        while(!(R8_OSC_CAL_CTRL&RB_OSC_CNT_HALT));
+        i = R16_OSC_CAL_CNT;            // 用于丢弃
+        while(R8_OSC_CAL_CTRL&RB_OSC_CNT_HALT);
+        while(!(R8_OSC_CAL_CTRL&RB_OSC_CNT_HALT));
+        i = R16_OSC_CAL_CNT;            // 实时校准后采样值
+        k++;
+
+        diff_1 = i-basev;
+
+        if( diff_1 == 0 ){
+            return 0;       // 校准正好
+        }
+        else if((diff_1*diff_2)<0){                 // 处于两点之间
+            if((diffc == 1) || (diffc == -1) || (diffc == 0))
+            {
+                // 都变成正数
+                if( diff_2<0 )  diff_2 = ~(diff_2-1);
+                else            diff_1 = ~(diff_1-1);
+
+                if(diff_1>diff_2){
+                    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+                    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+                    R16_INT32K_TUNE = loc_t;
+                    R8_SAFE_ACCESS_SIG = 0;
+
+                    return (diff_2*1000/basev);             // 返回误差值,千分之
+                }
+                else    return(diff_1*1000/basev);
+            }
+        }
+
+        // 保存上一次值
+        diff_2 = diff_1;
+        loc_t = loc;
+        diffc = diff_1/CNT_STEP_K;
+        loc = loc - diffc;
+        if( loc == loc_t )
+        {
+            if( diff_1 > 0 )    loc = loc+1;    // 当前频率偏小
+            else                loc = loc-1;    // 当前频率偏大
+        }
+    }while( k<20 );
+
+    return(0xff);
+}
+
+
+/*******************************************************************************
+* Function Name  : RTCInitTime
+* Description    : RTC时钟初始化当前时间
+* Input          : y: 配置时间 - 年
+                    MAX_Y = BEGYEAR + 44
+                     mon: 配置时间 - 月
+                    MAX_MON = 12
+                     d: 配置时间 - 日
+                    MAX_D = 31
+
+                     h: 配置时间 - 小时
+                    MAX_H = 23
+                   m: 配置时间 - 分钟
+                    MAX_M = 59
+                   s: 配置时间 - 秒
+                  MAX_S = 59
+* Return         : None
+*******************************************************************************/
+void RTC_InitTime( UINT16 y, UINT16 mon, UINT16 d, UINT16 h, UINT16 m, UINT16 s )
+{
+    UINT32  t;
+    UINT16  year, month, day, sec2, t32k;
+    UINT8V clk_pin;
+
+        year = y;
+        month = mon;
+        day = 0;
+    while ( year > BEGYEAR )
+    {
+      day += YearLength( year-1 );
+      year--;
+    }
+    while ( month > 1 )
+    {
+      day += monthLength( IsLeapYear( y ), month-2 );
+      month--;
+    }
+
+    day += d-1;
+    sec2 = (h%24)*1800+m*30+s/2;
+    t32k = (s&1)?(0x8000):(0);
+    t = sec2;
+    t = t<<16 | t32k;
+
+    do{
+      clk_pin = (R8_CK32K_CONFIG&RB_32K_CLK_PIN);
+    }while( (clk_pin != (R8_CK32K_CONFIG&RB_32K_CLK_PIN)) || (!clk_pin) );
+
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R32_RTC_TRIG = day;
+    R8_RTC_MODE_CTRL |= RB_RTC_LOAD_HI;
+    R32_RTC_TRIG = t;
+    R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : RTC_GetTime
+* Description    : 获取当前时间
+* Input          : y: 获取到的时间 - 年
+                    MAX_Y = BEGYEAR + 44
+                     mon: 获取到的时间 - 月
+                    MAX_MON = 12
+                     d: 获取到的时间 - 日
+                    MAX_D = 31
+                     ph: 获取到的时间 - 小时
+                    MAX_H = 23
+                   pm: 获取到的时间 - 分钟
+                    MAX_M = 59
+                   ps: 获取到的时间 - 秒
+                  MAX_S = 59
+* Return         : None
+*******************************************************************************/
+void RTC_GetTime( PUINT16 py, PUINT16 pmon, PUINT16 pd, PUINT16 ph, PUINT16 pm, PUINT16 ps )
+{
+    UINT32  t;
+    UINT16  day, sec2, t32k;
+
+    day = R32_RTC_CNT_DAY & 0x3FFF;
+    sec2 = R16_RTC_CNT_2S;
+    t32k = R16_RTC_CNT_32K;
+
+    t = sec2*2 + ((t32k<0x8000)?0:1);
+
+        *py = BEGYEAR;
+    while ( day >= YearLength( *py ) )
+    {
+      day -= YearLength( *py );
+      (*py)++;
+    }
+
+    *pmon = 0;
+    while ( day >= monthLength( IsLeapYear( *py ), *pmon ) )
+    {
+      day -= monthLength( IsLeapYear( *py ), *pmon );
+      (*pmon)++;
+    }
+        (*pmon) ++;
+        *pd = day+1;
+    *ph = t/3600;
+    *pm = t%3600/60;
+    *ps = t%60;
+}
+
+/*******************************************************************************
+* Function Name  : RTC_SetCycle32k
+* Description    : 基于LSE/LSI时钟,配置当前RTC 周期数
+* Input          : cyc: 配置周期计数初值 - cycle
+                    MAX_CYC = 0xA8BFFFFF = 2831155199
+* Return         : None
+*******************************************************************************/
+void RTC_SetCycle32k( UINT32 cyc )
+{
+    UINT8V clk_pin;
+
+    do{
+      clk_pin = (R8_CK32K_CONFIG&RB_32K_CLK_PIN);
+    }while( (clk_pin != (R8_CK32K_CONFIG&RB_32K_CLK_PIN)) || (!clk_pin) );
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R32_RTC_TRIG = cyc;
+    R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : RTC_GetCycle32k
+* Description    : 基于LSE/LSI时钟,获取当前RTC 周期数
+* Input          : None
+* Return         : 返回当前周期数,MAX_CYC = 0xA8BFFFFF = 2831155199
+*******************************************************************************/
+UINT32 RTC_GetCycle32k( void )
+{
+    UINT32 i;
+
+    do{
+        i = R32_RTC_CNT_32K;
+    }while( i != R32_RTC_CNT_32K );
+
+    return (i);
+}
+
+/*******************************************************************************
+* Function Name  : RTC_TMRFunCfg
+* Description    : RTC定时模式配置
+* Input          : t:
+                    refer to RTC_TMRCycTypeDef
+* Return         : None
+*******************************************************************************/
+void RTC_TMRFunCfg( RTC_TMRCycTypeDef t )
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_RTC_MODE_CTRL &= ~(RB_RTC_TMR_EN|RB_RTC_TMR_MODE);
+    R8_RTC_MODE_CTRL |= RB_RTC_TMR_EN | (t);
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : RTC_TRIGFunCfg
+* Description    : RTC时间触发模式配置
+* Input          : cyc: 相对当前时间的触发间隔时间,基于LSE/LSI时钟周期数
+* Return         : None
+*******************************************************************************/
+void RTC_TRIGFunCfg( UINT32 cyc )
+{
+    UINT32 t;
+
+    t = RTC_GetCycle32k() + cyc;
+    if( t>0xA8C00000)   t -= 0xA8C00000;
+    if( t&0xFFFF )  t = t+0x10000;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R32_RTC_TRIG = t;
+    R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : RTC_ModeFunDisable
+* Description    : RTC 模式功能关闭
+* Input          : m: 需要关闭的当前模式
+* Return         : None
+*******************************************************************************/
+void RTC_ModeFunDisable( RTC_MODETypeDef m )
+{
+    UINT8  i=0;
+
+    if( m == RTC_TRIG_MODE )    i |= RB_RTC_TRIG_EN;
+    else if( m == RTC_TMR_MODE )     i |= RB_RTC_TMR_EN;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_RTC_MODE_CTRL &= ~(i);
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : RTC_GetITFlag
+* Description    : 获取RTC中断标志
+* Input          : f:
+                    refer to RTC_EVENTTypeDef
+* Return         : 中断标志状态:
+                    0     -     未发生事件
+                   (!0)   -     发生事件
+*******************************************************************************/
+UINT8 RTC_GetITFlag( RTC_EVENTTypeDef f )
+{
+    if( f == RTC_TRIG_EVENT )
+        return ( R8_RTC_FLAG_CTRL & RB_RTC_TRIG_FLAG );
+    else
+        return ( R8_RTC_FLAG_CTRL & RB_RTC_TMR_FLAG );
+}
+
+/*******************************************************************************
+* Function Name  : RTC_ClearITFlag
+* Description    : 清除RTC中断标志
+* Input          : f:
+                    refer to RTC_EVENTTypeDef
+* Return         : None
+*******************************************************************************/
+void RTC_ClearITFlag( RTC_EVENTTypeDef f )
+{
+    switch( f )
+    {
+        case RTC_TRIG_EVENT:
+            R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR;
+            break;
+        case RTC_TMR_EVENT:
+            R8_RTC_FLAG_CTRL = RB_RTC_TMR_CLR;
+            break;
+        default :
+            break;
+    }
+}
+
+

+ 283 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_flash.c

@@ -0,0 +1,283 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_flash.c
+* Author             : WCH
+* Version            : V1.1
+* Date               : 2020/03/20
+* Description        :
+*******************************************************************************/
+
+/******************************************************************************/
+/* 头文件包含 */
+#include "CH57x_common.h"
+
+/* 操作Flash的保护状态标志 */
+#define CODEFLASH_SAFE_FLAG1          0x57
+#define CODEFLASH_SAFE_FLAG2          0xA8
+
+/* 操作Flash的保护状态变量 */
+unsigned char codeflash_access_flag1 = 0x0;
+unsigned char codeflash_access_flag2 = 0x0;
+
+/*******************************************************************************
+* Function Name  : GetUniqueID
+* Description    : 获取芯片唯一ID,小端模式,6B-ID, 2B-CKS
+* Input          : buf: 存储8字节,前6字节(小端)ID,后2字节(小端)校验和
+* Return         : None
+*******************************************************************************/
+void GetUniqueID(PUINT8 buf)
+{
+    PUINT8  pID;
+    UINT8   i;
+
+    pID = (PUINT8)ROM_UUID_ADDR;
+    for(i=0; i<8; i++) *buf++ = *pID++;
+}
+
+/*******************************************************************************
+* Function Name  : GetMACAddress
+* Description    : 获取网络MAC,小端模式,6B-MAC
+* Input          : buf: 存储6字节,6字节(小端)物理 MAC
+* Return         : None
+*******************************************************************************/
+void GetMACAddress(PUINT8 buf)
+{
+    PUINT8  pMAC;
+    UINT8   i;
+
+    pMAC = (PUINT8)ROM_MAC_ADDR;
+    for(i=0; i<6; i++) *buf++ = *pMAC++;
+}
+
+/*******************************************************************************
+* Function Name  : FlashBlockErase
+* Description    : Flash 块擦除,一次擦除512B
+* Input          : addr: 32位地址,需要512对齐
+*                       codeflash:  startAddr - 0x00000000    size - 0x3E800
+*                       dataflash:  startAddr - 0x3E800(DATA_FLASH_ADDR)       size -  0x0800(DATA_FLASH_SIZE)
+* Return         : 0 - 成功,其他  - 错误
+*******************************************************************************/
+UINT8 FlashBlockErase(UINT32 addr)
+{
+    UINT8  status = 0;
+    volatile UINT8  op_step;
+
+    if( addr & (0x200-1) )          return 1;  //地址不对齐
+
+    op_step = 0x11;
+    codeflash_access_flag1 = 0;
+    codeflash_access_flag2 = 0;
+    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
+
+    //开启电压监控中断
+    op_step += 0x11;
+    if((R8_BAT_DET_CTRL & 0x0F) != 0x0D)        PowerMonitor( ENABLE );
+
+    op_step += 0x11;
+    if((R8_BAT_STATUS & 0x03) != 0x00)      return 2;  //电源电压偏低,Flash不允许操作
+
+    op_step += 0x11;
+    if(((R8_BAT_STATUS & 0x03) == 0x00)
+        &&(op_step == 0x44))
+    {
+        codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
+    }
+
+    op_step += 0x11;
+    if(((R8_BAT_STATUS & 0x03) == 0x00)
+        &&(op_step == 0x55)
+        &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
+    {
+        codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
+    }
+
+    op_step += 0x11;
+    if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
+     &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
+     &&(op_step == 0x66))
+    {
+        R32_FLASH_ADDR = addr;
+        if( addr < DATA_FLASH_ADDR  )    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE;   // Codefalsh区
+        else       R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE;         // datafalsh区
+    }
+
+    op_step += 0x11;
+    /* 判断操作Flash的保护状态标志 */
+    if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
+     &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
+     &&(op_step == 0x77))
+    {
+        R8_FLASH_COMMAND = ROM_CMD_ERASE;
+        status = (unsigned char)(R16_FLASH_STATUS & 0xff);
+    }
+
+    op_step = 0x00;
+    codeflash_access_flag1 = 0x00;
+    codeflash_access_flag2 = 0x00;
+    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;       // LOCK
+
+    if( status != RB_ROM_ADDR_OK )  return 3;   //操作失败
+    return 0;
+}
+
+/*******************************************************************************
+* Function Name  : FlashWriteDW
+* Description    : Flash 双字写,地址需4字节对齐
+* Input          : addr: 32位地址,需要4对齐
+*                       codeflash:  startAddr - 0x00000000    size - 0x3E800
+*                       dataflash:  startAddr - 0x3E800(DATA_FLASH_ADDR)       size -  0x0800(DATA_FLASH_SIZE)
+                    dat: 32位写入数据
+* Return         : FAILED  - 错误
+                   SUCCESS - 成功
+*******************************************************************************/
+UINT8 FlashWriteDW(UINT32 addr, UINT32 dat)
+{
+    UINT32  add = addr;
+    UINT32  val = dat;
+    UINT8  status = 0;
+    volatile UINT8  op_step;
+
+    if( addr & (4-1) )              return 1; //地址不对齐
+
+    op_step = 0x11;
+    codeflash_access_flag1 = 0;
+    codeflash_access_flag2 = 0;
+    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
+
+    //开启电压监控中断
+    op_step += 0x11;
+    if((R8_BAT_DET_CTRL & 0x0F) != 0x0D)        PowerMonitor( ENABLE );
+
+    op_step += 0x11;
+    if((R8_BAT_STATUS & 0x03) != 0x00)      return 2;  //电源电压偏低,Flash不允许操作
+
+    op_step += 0x11;
+    if(((R8_BAT_STATUS & 0x01) == 0x00)
+        &&(op_step == 0x44))
+    {
+        codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
+    }
+
+    op_step += 0x11;
+    if(((R8_BAT_STATUS & 0x01) == 0x00)
+        &&(op_step == 0x55)
+        &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
+    {
+        codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
+    }
+
+    op_step += 0x11;
+    if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
+     &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
+     &&(op_step == 0x66))
+    {
+        if( addr < DATA_FLASH_ADDR  )    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE;   // Codefalsh区
+        else       R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE;         // datafalsh区
+    }
+
+    op_step += 0x11;
+    /* 判断OTA操作Flash的保护状态标志 */
+    if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
+     &&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
+     &&(op_step == 0x77))
+    {
+        R32_FLASH_ADDR = add;
+        R32_FLASH_DATA = val;
+        R8_FLASH_COMMAND = ROM_CMD_PROG;
+        status = (unsigned char)(R16_FLASH_STATUS & 0xff);
+    }
+
+    op_step = 0x00;
+    codeflash_access_flag1 = 0x00;
+    codeflash_access_flag2 = 0x00;
+    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
+    if( status != RB_ROM_ADDR_OK )  return 3;  //操作失败
+
+    return 0;
+
+}
+
+/*******************************************************************************
+* Function Name  : FlashWriteBuf
+* Description    : Flash 连续多个双字写入
+* Input          : addr: 32位地址,需要4对齐
+*                       codeflash:  startAddr - 0x00000000    size - 0x3E800
+*                       dataflash:  startAddr - 0x3E800(DATA_FLASH_ADDR)       size -  0x0800(DATA_FLASH_SIZE)
+*                  pdat: 待写入数据缓存区首地址
+*                   len: 待写入数据字节长度
+* Return         : 0 - 成功,其他  - 错误
+*******************************************************************************/
+UINT8 FlashWriteBuf(UINT32 addr, PUINT32 pdat, UINT16 len)
+{
+    UINT32  add = addr;
+    PUINT32 p32 = pdat;
+    UINT8  status = 0;
+    UINT16  i;
+    volatile UINT8  op_step;
+
+    if( addr & (4-1) )              return 1; //地址不对齐
+
+    op_step = 0x11;
+    codeflash_access_flag1 = 0;
+    codeflash_access_flag2 = 0;
+    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
+
+    //开启电压监控中断
+    op_step += 0x11;
+    if((R8_BAT_DET_CTRL & 0x0F) != 0x0D)        PowerMonitor( ENABLE );
+
+    op_step += 0x11;
+    if((R8_BAT_STATUS & 0x03) != 0x00)      return 2;  //电源电压偏低,Flash不允许操作
+
+    op_step += 0x11;
+    if(((R8_BAT_STATUS & 0x01) == 0x00)
+        &&(op_step == 0x44))
+    {
+        codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
+    }
+
+    op_step += 0x11;
+    if(((R8_BAT_STATUS & 0x01) == 0x00)
+        &&(op_step == 0x55)
+        &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
+    {
+        codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
+    }
+
+    op_step += 0x11;
+    if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
+     &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
+     &&(op_step == 0x66))
+    {
+        if( addr < DATA_FLASH_ADDR  )    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE;   // Codefalsh区
+        else       R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE;         // datafalsh区
+    }
+
+    op_step += 0x11;
+    /* 判断OTA操作Flash的保护状态标志 */
+    if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
+     &&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
+     &&(op_step == 0x77))
+    {
+        for(i=0; i<len; i+=4)
+        {
+            R32_FLASH_ADDR = add;
+            R32_FLASH_DATA = *p32++;
+            R8_FLASH_COMMAND = ROM_CMD_PROG;
+            add += 4;
+            //status = R8_FLASH_STATUS;
+            status = (unsigned char)(R16_FLASH_STATUS & 0xff);
+            if( status != RB_ROM_ADDR_OK )  break;
+        }
+    }
+
+    op_step = 0x00;
+    codeflash_access_flag1 = 0x00;
+    codeflash_access_flag2 = 0x00;
+    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
+    if( status != RB_ROM_ADDR_OK )  return 3;  //操作失败
+
+    return 0;
+}
+
+
+

+ 252 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_gpio.c

@@ -0,0 +1,252 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_gpio.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : GPIOA_ModeCfg
+* Description    : GPIOA端口引脚模式配置
+* Input          : pin:  PA0-PA15
+                    GPIO_Pin_0 - GPIO_Pin_15
+                   mode:
+                    GPIO_ModeIN_Floating  -  浮空输入
+                    GPIO_ModeIN_PU        -  上拉输入
+                    GPIO_ModeIN_PD        -  下拉输入
+                    GPIO_ModeOut_PP_5mA   -  推挽输出最大5mA
+                    GPIO_ModeOut_PP_20mA  -  推挽输出最大20mA
+* Return         : None
+*******************************************************************************/
+void GPIOA_ModeCfg( UINT32 pin, GPIOModeTypeDef mode )
+{
+    switch(mode)
+    {
+        case GPIO_ModeIN_Floating:
+            R32_PA_PD_DRV &= ~pin;
+            R32_PA_PU     &= ~pin;
+            R32_PA_DIR    &= ~pin;
+            break;
+
+        case GPIO_ModeIN_PU:
+            R32_PA_PD_DRV &= ~pin;
+            R32_PA_PU     |= pin;
+            R32_PA_DIR    &= ~pin;
+            break;
+
+        case GPIO_ModeIN_PD:
+            R32_PA_PD_DRV |= pin;
+            R32_PA_PU     &= ~pin;
+            R32_PA_DIR    &= ~pin;
+            break;
+
+        case GPIO_ModeOut_PP_5mA:
+            R32_PA_PD_DRV &= ~pin;
+            R32_PA_DIR    |= pin;
+            break;
+
+        case GPIO_ModeOut_PP_20mA:
+            R32_PA_PD_DRV |= pin;
+            R32_PA_DIR    |= pin;
+            break;
+
+        default:
+            break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : GPIOB_ModeCfg
+* Description    : GPIOB端口引脚模式配置
+* Input          : pin:  PB0-PB23
+                    GPIO_Pin_0 - GPIO_Pin_23
+                   mode:
+                    GPIO_ModeIN_Floating  -  浮空输入
+                    GPIO_ModeIN_PU        -  上拉输入
+                    GPIO_ModeIN_PD        -  下拉输入
+                    GPIO_ModeOut_PP_5mA   -  推挽输出最大5mA
+                    GPIO_ModeOut_PP_20mA  -  推挽输出最大20mA
+* Return         : None
+*******************************************************************************/
+void GPIOB_ModeCfg( UINT32 pin, GPIOModeTypeDef mode )
+{
+    switch(mode)
+    {
+        case GPIO_ModeIN_Floating:
+            R32_PB_PD_DRV &= ~pin;
+            R32_PB_PU     &= ~pin;
+            R32_PB_DIR    &= ~pin;
+            break;
+
+        case GPIO_ModeIN_PU:
+            R32_PB_PD_DRV &= ~pin;
+            R32_PB_PU     |= pin;
+            R32_PB_DIR    &= ~pin;
+            break;
+
+        case GPIO_ModeIN_PD:
+            R32_PB_PD_DRV |= pin;
+            R32_PB_PU     &= ~pin;
+            R32_PB_DIR    &= ~pin;
+            break;
+
+        case GPIO_ModeOut_PP_5mA:
+            R32_PB_PD_DRV &= ~pin;
+            R32_PB_DIR    |= pin;
+            break;
+
+        case GPIO_ModeOut_PP_20mA:
+            R32_PB_PD_DRV |= pin;
+            R32_PB_DIR    |= pin;
+            break;
+
+        default:
+            break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : GPIOA_ITModeCfg
+* Description    : GPIOA引脚中断模式配置
+* Input          : pin:  PA0-PA15
+                    GPIO_Pin_0 - GPIO_Pin_15
+                   mode:
+                    GPIO_ITMode_LowLevel   -  低电平触发
+                    GPIO_ITMode_HighLevel  -  高电平触发
+                    GPIO_ITMode_FallEdge   -  下降沿触发
+                    GPIO_ITMode_RiseEdge   -  上升沿触发
+* Return         : None
+*******************************************************************************/
+void GPIOA_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode )
+{
+    switch( mode )
+    {
+        case GPIO_ITMode_LowLevel:      // 低电平触发
+            R16_PA_INT_MODE &= ~pin;
+            R32_PA_CLR |= pin;
+            break;
+
+        case GPIO_ITMode_HighLevel:     // 高电平触发
+            R16_PA_INT_MODE &= ~pin;
+            R32_PA_OUT |= pin;
+            break;
+
+        case GPIO_ITMode_FallEdge:      // 下降沿触发
+            R16_PA_INT_MODE |= pin;
+            R32_PA_CLR |= pin;
+            break;
+
+        case GPIO_ITMode_RiseEdge:      // 上升沿触发
+            R16_PA_INT_MODE |= pin;
+            R32_PA_OUT |= pin;
+            break;
+
+        default :
+            break;
+    }
+    R16_PA_INT_IF = pin;
+    R16_PA_INT_EN |= pin;
+}
+
+/*******************************************************************************
+* Function Name  : GPIOB_ITModeCfg
+* Description    : GPIOB引脚中断模式配置
+* Input          : pin:  PB0-PB15
+                    GPIO_Pin_0 - GPIO_Pin_15
+                   mode:
+                    GPIO_ITMode_LowLevel   -  低电平触发
+                    GPIO_ITMode_HighLevel  -  高电平触发
+                    GPIO_ITMode_FallEdge   -  下降沿触发
+                    GPIO_ITMode_RiseEdge   -  上升沿触发
+* Return         : None
+*******************************************************************************/
+void GPIOB_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode )
+{
+    switch( mode )
+    {
+        case GPIO_ITMode_LowLevel:      // 低电平触发
+            R16_PB_INT_MODE &= ~pin;
+            R32_PB_CLR |= pin;
+            break;
+
+        case GPIO_ITMode_HighLevel:     // 高电平触发
+            R16_PB_INT_MODE &= ~pin;
+            R32_PB_OUT |= pin;
+            break;
+
+        case GPIO_ITMode_FallEdge:      // 下降沿触发
+            R16_PB_INT_MODE |= pin;
+            R32_PB_CLR |= pin;
+            break;
+
+        case GPIO_ITMode_RiseEdge:      // 上升沿触发
+            R16_PB_INT_MODE |= pin;
+            R32_PB_OUT |= pin;
+            break;
+
+        default :
+            break;
+    }
+    R16_PB_INT_IF = pin;
+    R16_PB_INT_EN |= pin;
+}
+
+
+/*******************************************************************************
+* Function Name  : GPIOPinRemap
+* Description    : 外设功能引脚映射
+* Input          : s:
+                    ENABLE  - 引脚映射
+                    DISABLE - 默认引脚
+                   perph:
+                    RB_PIN_SPI0   -  SPI0:  PA12/PA13/PA14/PA15 -> PB12/PB13/PB14/PB15
+                    RB_PIN_UART3  -  UART3: PA4/PA5 ->  PB20/PB21
+                    RB_PIN_UART2  -  UART2: PA6/PA7 ->  PB22/PB23
+                    RB_PIN_UART1  -  UART1: PA8/PA9 ->  PB8/PB9
+                    RB_PIN_UART0  -  UART0: PB4/PB7 ->  PA15/PA14
+                    RB_PIN_TMR3   -  TMR3:  PA2 ->  PB18
+                    RB_PIN_TMR2   -  TMR2:  PA11 ->  PB11
+                    RB_PIN_TMR1   -  TMR1:  PA10 ->  PB10
+                    RB_PIN_TMR0   -  TMR0:  PA3 ->  PB19
+* Return         : None
+*******************************************************************************/
+void GPIOPinRemap( UINT8 s, UINT16 perph )
+{
+    if( s )     R16_PIN_ALTERNATE |= perph;
+    else        R16_PIN_ALTERNATE &= ~perph;
+}
+
+/*******************************************************************************
+* Function Name  : GPIOAGPPCfg
+* Description    : 模拟外设GPIO引脚功能控制
+* Input          : s:
+                    ENABLE  - 打开模拟外设功能,关闭数字功能
+                    DISABLE - 启用数字功能,关闭模拟外设功能
+                   perph:
+                    RB_PIN_ADC0_1_IE      -  ADC0-1通道
+                    RB_PIN_ADC2_3_IE      -  ADC2-3通道
+                    RB_PIN_ADC4_5_IE      -  ADC4-5通道
+                    RB_PIN_ADC6_7_IE      -  ADC6-7通道
+                    RB_PIN_ADC8_9_IE      -  ADC8-9通道
+                    RB_PIN_ADC10_11_IE    -  ADC10-11通道
+                    RB_PIN_ADC12_13_IE    -  ADC12-13通道
+                    RB_PIN_XT32K_IE       -  外部32K引脚
+                    RB_PIN_USB_IE         -  USB功能信号引脚
+                    RB_PIN_ETH_IE         -  以太网功能信号引脚
+                    RB_PIN_SEG0_3_IE      -  LCD控制器SEG0-3驱动引脚
+                    RB_PIN_SEG4_7_IE      -  LCD控制器SEG4-7驱动引脚
+                    RB_PIN_SEG8_11_IE     -  LCD控制器SEG8-11驱动引脚
+                    RB_PIN_SEG12_15_IE    -  LCD控制器SEG12-15驱动引脚
+                    RB_PIN_SEG16_19_IE    -  LCD控制器SEG16-19驱动引脚
+                    RB_PIN_SEG20_23_IE    -  LCD控制器SEG20-23驱动引脚
+* Return         : None
+*******************************************************************************/
+void GPIOAGPPCfg( UINT8 s, UINT16 perph )
+{
+    if( s )     R16_PIN_ANALOG_IE |= perph;
+    else        R16_PIN_ANALOG_IE &= ~perph;
+}

+ 242 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_int.c

@@ -0,0 +1,242 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_int.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2020/03/18
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+/*******************************************************************************
+* Function Name  : NMI_Handler
+* Description    : NMI中断函数
+* Input          : None
+* Return         : None
+*******************************************************************************/
+//__attribute__((section("NMICode")))
+void NMI_Handler( void )
+{
+    UINT32  i=0;
+
+        if( (R8_HFCK_PWR_CTRL & RB_CLK_INT32M_PON) == 0 )
+        {
+            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+                R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+                R8_HFCK_PWR_CTRL |= RB_CLK_INT32M_PON;                          // 打开内部32M
+        }
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R16_CLK_SYS_CFG = 5;                                                                // 降频 HSI/5=6.4M
+    R16_POWER_PLAN &= ~(RB_PWR_DCDC_EN|RB_PWR_DCDC_PRE);        // 旁路 DC/DC
+        R8_HFCK_PWR_CTRL |= RB_CLK_PLL_PON;                                         // 打开PLL
+        R8_SAFE_ACCESS_SIG = 0;
+
+    while(1)
+    {
+        if(R8_BAT_STATUS & RB_BAT_STAT_LOWER)   i = 0;
+        else i++;
+        if( i>2000 )
+                {
+                    /* 执行系统复位 */
+                    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+                    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+                    R8_RST_WDOG_CTRL = RB_SOFTWARE_RESET;
+                    R8_SAFE_ACCESS_SIG = 0;
+                }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : LowPower_Halt_1
+* Description    : 低功耗-Halt_1模式。
+                   此低功耗切到HSI/5时钟运行,唤醒后需要用户自己重新选择系统时钟源
+* Input          : None
+* Return         : None
+*******************************************************************************/
+//__attribute__((section("NMICode")))
+void LowPower_Halt_1( void )
+{
+    UINT8  x32Kpw, x32Mpw;
+
+    x32Kpw = R8_XT32K_TUNE;
+    x32Mpw = R8_XT32M_TUNE;
+    x32Mpw = (x32Mpw&0xfc)|0x03;            // 150%额定电流
+    if(R16_RTC_CNT_32K>0x3fff){     // 超过500ms
+        x32Kpw = (x32Kpw&0xfc)|0x01;        // LSE驱动电流降低到额定电流
+    }
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_SLP_POWER_CTRL &= ~RB_SLP_ROM_PWR_DN;          // flash待机
+    R8_BAT_DET_CTRL = 0;                              // 关闭电压监控
+    R8_XT32K_TUNE = x32Kpw;
+    R8_XT32M_TUNE = x32Mpw;
+    R16_CLK_SYS_CFG = 5;                // 降频 HSI/5=6.4M
+    R8_SAFE_ACCESS_SIG = 0;
+
+    SCB -> SCR |= SCB_SCR_SLEEPDEEP_Msk;                //deep sleep
+    __WFI();
+    R8_SAFE_ACCESS_SIG = 0;
+
+    /* 开启电压监控 */
+    PowerMonitor( ENABLE );
+}
+
+/*******************************************************************************
+* Function Name  : LowPower_Halt_2
+* Description    : 低功耗-Halt_2模式。
+                   此低功耗切到HSI/5时钟运行,唤醒后需要用户自己重新选择系统时钟源
+* Input          : None
+* Return         : None
+*******************************************************************************/
+//__attribute__((section("NMICode")))
+void LowPower_Halt_2( void )
+{
+    UINT8  x32Kpw, x32Mpw;
+
+    x32Kpw = R8_XT32K_TUNE;
+    x32Mpw = R8_XT32M_TUNE;
+    x32Mpw = (x32Mpw&0xfc)|0x03;            // 150%额定电流
+    if(R16_RTC_CNT_32K>0x3fff){     // 超过500ms
+        x32Kpw = (x32Kpw&0xfc)|0x01;        // LSE驱动电流降低到额定电流
+    }
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_SLP_POWER_CTRL |= RB_SLP_ROM_PWR_DN;           // flash停机
+    R8_BAT_DET_CTRL = 0;                              // 关闭电压监控
+    R8_XT32K_TUNE = x32Kpw;
+    R8_XT32M_TUNE = x32Mpw;
+    R16_CLK_SYS_CFG = 5;                // 降频 HSI/5=6.4M
+    R8_SAFE_ACCESS_SIG = 0;
+
+    SCB -> SCR |= SCB_SCR_SLEEPDEEP_Msk;                //deep sleep
+    __WFI();
+    R8_SAFE_ACCESS_SIG = 0;
+
+    /* 开启电压监控 */
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CFG = 1;                     // 2.05V - 2.33V
+        R8_BAT_DET_CTRL = RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+        __nop();    __nop();
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CTRL = RB_BAT_LOW_IE|RB_BAT_LOWER_IE|RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : LowPower_Sleep
+* Description    : 低功耗-Sleep模式。
+                   此低功耗切到HSI/5时钟运行,唤醒后需要用户自己重新选择系统时钟源
+                   注意调用此函数,DCDC功能强制关闭,唤醒后可以手动再次打开
+* Input          : rm:
+                    RB_PWR_RAM2K    -   最后2K SRAM 供电
+                    RB_PWR_RAM14K   -   0x20004000 - 0x20007800 14K SRAM 供电
+                    RB_PWR_EXTEND   -   USB和RF 单元保留区域供电
+                   NULL -   以上单元都断电
+* Return         : None
+*******************************************************************************/
+//__attribute__((section("NMICode")))
+void LowPower_Sleep( UINT8 rm )
+{
+    UINT8  x32Kpw, x32Mpw;
+
+    x32Kpw = R8_XT32K_TUNE;
+    x32Mpw = R8_XT32M_TUNE;
+    x32Mpw = (x32Mpw&0xfc)|0x03;            // 150%额定电流
+    if(R16_RTC_CNT_32K>0x3fff){     // 超过500ms
+        x32Kpw = (x32Kpw&0xfc)|0x01;        // LSE驱动电流降低到额定电流
+    }
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R16_POWER_PLAN = RB_PWR_PLAN_EN         \
+                    |RB_PWR_MUST_0010       \
+                    |RB_PWR_CORE            \
+                    |rm;
+    R8_SAFE_ACCESS_SIG = 0;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_BAT_DET_CTRL = 0;                // 关闭电压监控
+    R8_XT32K_TUNE = x32Kpw;
+    R8_XT32M_TUNE = x32Mpw;
+    R16_CLK_SYS_CFG = 5;                // 降频 HSI/5=6.4M
+    R8_SAFE_ACCESS_SIG = 0;
+
+    SCB -> SCR |= SCB_SCR_SLEEPDEEP_Msk;                //deep sleep
+    __WFI();
+    R8_SAFE_ACCESS_SIG = 0;
+
+    /* 开启电压监控 */
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CFG = 1;                     // 2.05V - 2.33V
+        R8_BAT_DET_CTRL = RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+        __nop();    __nop();
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CTRL = RB_BAT_LOW_IE|RB_BAT_LOWER_IE|RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : LowPower_Shutdown
+* Description    : 低功耗-Shutdown模式。
+                   此低功耗切到HSI/5时钟运行,唤醒后需要用户自己重新选择系统时钟源
+                   注意调用此函数,DCDC功能强制关闭,唤醒后可以手动再次打开
+* Input          : rm:
+                    RB_PWR_RAM2K    -   最后2K SRAM 供电
+                   NULL -   以上单元都断电
+* Return         : None
+*******************************************************************************/
+//__attribute__((section("NMICode")))
+void LowPower_Shutdown( UINT8 rm )
+{
+    UINT8  x32Kpw, x32Mpw;
+
+    x32Kpw = R8_XT32K_TUNE;
+    x32Mpw = R8_XT32M_TUNE;
+    x32Mpw = (x32Mpw&0xfc)|0x03;            // 150%额定电流
+    if(R16_RTC_CNT_32K>0x3fff){     // 超过500ms
+        x32Kpw = (x32Kpw&0xfc)|0x01;        // LSE驱动电流降低到额定电流
+    }
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R16_POWER_PLAN = RB_PWR_PLAN_EN         \
+                    |RB_PWR_MUST_0010       \
+                    |rm;
+    R8_SAFE_ACCESS_SIG = 0;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_BAT_DET_CTRL = 0;                // 关闭电压监控
+    R8_XT32K_TUNE = x32Kpw;
+    R8_XT32M_TUNE = x32Mpw;
+    R16_CLK_SYS_CFG = 5;                // 降频 HSI/5=6.4M
+    R8_SAFE_ACCESS_SIG = 0;
+
+    SCB -> SCR |= SCB_SCR_SLEEPDEEP_Msk;                //deep sleep
+    __WFI();
+    R8_SAFE_ACCESS_SIG = 0;
+
+    /* 开启电压监控 */
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CFG = 1;                     // 2.05V - 2.33V
+        R8_BAT_DET_CTRL = RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+        __nop();    __nop();
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CTRL = RB_BAT_LOW_IE|RB_BAT_LOWER_IE|RB_BAT_DET_EN;
+    R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
+        R8_SAFE_ACCESS_SIG = 0;
+}
+

+ 27 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_lcd.c

@@ -0,0 +1,27 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_lcd.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : LCD_DefInit
+* Description    : LCD段式屏驱动默认初始化配置
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void LCD_DefInit( void )
+{
+    /* 3.3V 1KHZ  COM0~COM3  1/3BISA */
+    R8_LCD_CTRL_MOD = RB_SYS_POWER_ON           \
+                    |RB_LCD_POWER_ON            \
+                    |(1<<2)                     \
+                    |(2<<3)                     \
+                    |(2<<5)                     \
+                    |(0<<7) ;
+}

+ 110 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_pwm.c

@@ -0,0 +1,110 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_pwm.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : PWMX_CycleCfg
+* Description    : PWM4-PWM11基准时钟配置
+* Input          : cyc:
+                    refer to PWMX_CycleTypeDef
+* Return         : None
+*******************************************************************************/
+void PWMX_CycleCfg( PWMX_CycleTypeDef cyc )
+{
+    switch( cyc )
+    {
+        case PWMX_Cycle_256:
+            R8_PWM_CONFIG = R8_PWM_CONFIG & 0xf0;
+            break;
+
+        case PWMX_Cycle_255:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | 0x01;
+            break;
+
+        case PWMX_Cycle_128:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (1<<2);
+            break;
+
+        case PWMX_Cycle_127:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (1<<2) | 0x01;
+            break;
+
+        case PWMX_Cycle_64:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (2<<2);
+            break;
+
+        case PWMX_Cycle_63:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (2<<2) | 0x01;
+            break;
+
+        case PWMX_Cycle_32:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (3<<2);
+            break;
+
+        case PWMX_Cycle_31:
+            R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (3<<2) | 0x01;
+            break;
+
+        default :
+            break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : PWMX_ACTOUT
+* Description    : PWM4-PWM11通道输出波形配置
+* Input          : ch:  select channel of pwm
+                    refer to channel of PWM define
+                   da:  effective pulse width
+                   pr:  select wave polar
+                    refer to PWMX_PolarTypeDef
+                   s :  control pwmx function
+                    ENABLE  - 输出PWM
+                    DISABLE - 关闭PWM
+* Return         : None
+*******************************************************************************/
+void PWMX_ACTOUT( UINT8 ch, UINT8 da, PWMX_PolarTypeDef pr, UINT8 s)
+{
+    UINT8 i;
+
+    if(s == DISABLE)    R8_PWM_OUT_EN &= ~(ch);
+    else
+    {
+        (pr)?(R8_PWM_POLAR|=(ch)):(R8_PWM_POLAR&=~(ch));
+        for(i=0; i<8; i++)
+        {
+            if((ch>>i)&1)       *((PUINT8V)((&R8_PWM4_DATA)+i)) = da;
+        }
+        R8_PWM_OUT_EN |= (ch);
+    }
+}
+
+/*******************************************************************************
+* Function Name  : PWMX_AlterOutCfg
+* Description    : PWM 交替输出模式配置
+* Input          : ch:  select group of PWM alternate output
+                    RB_PWM4_5_STAG_EN   -  PWM4 和 PWM5 通道交替输出
+                    RB_PWM6_7_STAG_EN   -  PWM6 和 PWM7 通道交替输出
+                    RB_PWM8_9_STAG_EN   -  PWM8 和 PWM9 通道交替输出
+                    RB_PWM10_11_STAG_EN -  PWM10 和 PWM11 通道交替输出
+                   s :  control pwmx function
+                    ENABLE  - 打开交替输出功能
+                    DISABLE - 关闭交替输出功能
+* Return         : None
+*******************************************************************************/
+void PWMX_AlterOutCfg( UINT8 ch, UINT8 s)
+{
+    if(s == DISABLE)        R8_PWM_CONFIG &= ~(ch);
+    else                    R8_PWM_CONFIG |= (ch);
+}
+
+
+
+

+ 223 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_pwr.c

@@ -0,0 +1,223 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_pwr.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : PWR_DCDCCfg
+* Description    : 启用内部DC/DC电源,用于节约系统功耗
+* Input          : s:
+                    ENABLE  - 打开DCDC电源
+                    DISABLE - 关闭DCDC电源
+* Return         : None
+*******************************************************************************/
+void PWR_DCDCCfg( UINT8 s )
+{
+    if(s == DISABLE)
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R16_POWER_PLAN &= ~(RB_PWR_DCDC_EN|RB_PWR_DCDC_PRE);        // 旁路 DC/DC
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG0;
+    }
+    else
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R16_POWER_PLAN |= RB_PWR_DCDC_PRE;
+        DelayUs(10);
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R16_POWER_PLAN |= RB_PWR_DCDC_EN;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG0;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : PWR_UnitModCfg
+* Description    : 可控单元模块的电源控制
+* Input          : s:
+                    ENABLE  - 打开
+                    DISABLE - 关闭
+                   unit:
+                    please refer to unit of controllable power supply
+* Return         : None
+*******************************************************************************/
+void PWR_UnitModCfg( UINT8 s, UINT8 unit )
+{
+    if(s == DISABLE)        //关闭
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        if(unit&UNIT_ETH_PHY)       R8_SLP_POWER_CTRL |= RB_SLP_ETH_PWR_DN;
+        R8_HFCK_PWR_CTRL &= ~(unit&0x1c);
+        R8_CK32K_CONFIG &= ~(unit&0x03);
+    }
+    else                    //打开
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        if(unit&UNIT_ETH_PHY)       R8_SLP_POWER_CTRL &= ~RB_SLP_ETH_PWR_DN;
+        R8_HFCK_PWR_CTRL |= (unit&0x1c);
+        R8_CK32K_CONFIG |= (unit&0x03);
+    }
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : PWR_PeriphClkCfg
+* Description    : 外设时钟控制位
+* Input          : s:
+                    ENABLE  - 打开外设时钟
+                    DISABLE - 关闭外设时钟
+                   perph:
+                    please refer to Peripher CLK control bit define
+* Return         : None
+*******************************************************************************/
+void PWR_PeriphClkCfg( UINT8 s, UINT16 perph )
+{
+    if( s == DISABLE )
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R32_SLEEP_CONTROL |= perph;
+    }
+    else
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R32_SLEEP_CONTROL &= ~perph;
+    }
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : PWR_PeriphWakeUpCfg
+* Description    : 睡眠唤醒源配置
+* Input          : s:
+                    ENABLE  - 打开此外设睡眠唤醒功能
+                    DISABLE - 关闭此外设睡眠唤醒功能
+                   perph:
+                    RB_SLP_USB_WAKE     -  USB 为唤醒源
+                    RB_SLP_ETH_WAKE     -  ETH 为唤醒源
+                    RB_SLP_RTC_WAKE     -  RTC 为唤醒源
+                    RB_SLP_GPIO_WAKE    -  GPIO 为唤醒源
+                    RB_SLP_BAT_WAKE     -  BAT 为唤醒源
+                    ALL     -  以上所有
+* Return         : None
+*******************************************************************************/
+void PWR_PeriphWakeUpCfg( UINT8 s, UINT16 perph )
+{
+    if( s == DISABLE )
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_SLP_WAKE_CTRL &= ~perph;
+    }
+    else
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_SLP_WAKE_CTRL |= perph;
+    }
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : PowerMonitor
+* Description    : 电源监控
+* Input          : s:
+                    ENABLE  - 打开此功能
+                    DISABLE - 关闭此功能
+* Return         : None
+*******************************************************************************/
+void PowerMonitor( UINT8 s )
+{
+    if( s == DISABLE )
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CTRL = 0;
+        R8_SAFE_ACCESS_SIG = 0;
+    }
+    else
+    {
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CFG = 1;                     // 2.05V - 2.33V
+        R8_BAT_DET_CTRL = RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+        mDelayuS(1);
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+        R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+        R8_BAT_DET_CTRL = RB_BAT_LOW_IE|RB_BAT_LOWER_IE|RB_BAT_DET_EN;
+        R8_SAFE_ACCESS_SIG = 0;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : LowPower_Idle
+* Description    : 低功耗-Idle模式
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void LowPower_Idle( void )
+{
+    SCB -> SCR &= ~SCB_SCR_SLEEPDEEP_Msk;               // sleep
+    __WFI();
+}
+
+/*******************************************************************************
+* Function Name  : EnterCodeUpgrade
+* Description    : 跳入BOOT程序,准备代码升级
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void EnterCodeUpgrade( void )
+{
+/* RTC wakeup */
+    UINT32 t;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_SLP_WAKE_CTRL |= RB_SLP_RTC_WAKE;
+    R16_POWER_PLAN = RB_PWR_PLAN_EN         \
+                    |RB_PWR_MUST_0010;
+    R8_SAFE_ACCESS_SIG = 0;
+
+    do{
+        t = R32_RTC_CNT_32K;
+    }while( t != R32_RTC_CNT_32K );
+
+    t = t + 10;
+    if( t>0xA8C00000 )  t -= 0xA8C00000;
+    if( t&0xFFFF )  t = t+0x10000;
+
+    R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR|RB_RTC_TMR_CLR;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R32_RTC_TRIG = t;
+    R8_RTC_MODE_CTRL = 0x2f;    // 进入boot下载必要条件
+    R8_SAFE_ACCESS_SIG = 0;
+
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R16_CLK_SYS_CFG = 5;                // 降频 HSI/5=6.4M
+    R8_SAFE_ACCESS_SIG = 0;
+
+/* ready to BOOT */
+    __SEV();
+    __WFE();
+    __WFE();
+    while(1);
+}
+
+
+
+

+ 324 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_spi0.c

@@ -0,0 +1,324 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_SPI0.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterDefInit
+* Description    : 主机模式默认初始化:模式0+3线全双工+8MHz
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void SPI0_MasterDefInit( void )
+{
+    R8_SPI0_CLOCK_DIV = 4;      // 主频时钟4分频
+    R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
+    R8_SPI0_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE ;
+    R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF;        // 访问BUFFER/FIFO自动清除IF_BYTE_END标志
+    R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;    // 不启动DMA方式
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_CLKCfg
+* Description    : SPI0 基准时钟配置,= d*Tsys
+* Input          : c: 时钟分频系数
+* Return         : None
+*******************************************************************************/
+void SPI0_CLKCfg( UINT8 c )
+{
+    if(c==2)
+        R8_SPI0_CTRL_CFG |= RB_SPI_MST_DLY_EN;
+    else
+        R8_SPI0_CTRL_CFG &= ~RB_SPI_MST_DLY_EN;
+    R8_SPI0_CLOCK_DIV = c;
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_DataMode
+* Description    : 设置数据流模式
+* Input          : m: 数据流模式
+                    refer to ModeBitOrderTypeDef
+* Return         : None
+*******************************************************************************/
+void SPI0_DataMode( ModeBitOrderTypeDef m )
+{
+    switch( m )
+    {
+        case Mode0_LowBitINFront:
+            R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
+            R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
+            break;
+        case Mode0_HighBitINFront:
+            R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
+            R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
+            break;
+        case Mode3_LowBitINFront:
+            R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
+            R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
+            break;
+        case Mode3_HighBitINFront:
+            R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
+            R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
+            break;
+        default:
+            break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterSendByte
+* Description    : 发送单字节 (buffer)
+* Input          : d: 发送字节
+* Return         : None
+*******************************************************************************/
+void SPI0_MasterSendByte( UINT8 d )
+{
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R8_SPI0_BUFFER = d;
+    while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterRecvByte
+* Description    : 接收单字节 (buffer)
+* Input          : None
+* Return         : 接收到的字节
+*******************************************************************************/
+UINT8 SPI0_MasterRecvByte( void )
+{
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R8_SPI0_BUFFER = 0xFF;           // 启动传输
+    while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
+    return ( R8_SPI0_BUFFER );
+}
+
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterTrans
+* Description    : 使用FIFO连续发送多字节
+* Input          : pbuf: 待发送的数据内容首地址
+                   len: 请求发送的数据长度,最大4095
+* Return         : None
+*******************************************************************************/
+void SPI0_MasterTrans( UINT8 *pbuf, UINT16 len )
+{
+    UINT16 sendlen;
+
+    sendlen = len;
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;                     // 设置数据方向为输出
+    R16_SPI0_TOTAL_CNT = sendlen;                             // 设置要发送的数据长度
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
+    while( sendlen )
+    {
+        if( R8_SPI0_FIFO_COUNT < SPI_FIFO_SIZE )
+        {
+            R8_SPI0_FIFO = *pbuf;
+            pbuf++;
+            sendlen--;
+        }
+    }
+    while( R8_SPI0_FIFO_COUNT != 0 );                         // 等待FIFO中的数据全部发送完成
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterRecv
+* Description    : 使用FIFO连续接收多字节
+* Input          : pbuf: 待发送的数据内容首地址
+                   len: 请求发送的数据长度,最大4095
+* Return         : None
+*******************************************************************************/
+void SPI0_MasterRecv( UINT8 *pbuf, UINT16 len )
+{
+    UINT16  readlen;
+
+    readlen = len;
+    R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;                     // 设置数据方向为输入
+    R16_SPI0_TOTAL_CNT = len;                                // 设置需要接收的数据长度,FIFO方向为输入长度不为0则会启动传输 */
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
+    while( readlen )
+    {
+        if( R8_SPI0_FIFO_COUNT )
+        {
+            *pbuf = R8_SPI0_FIFO;
+            pbuf++;
+            readlen--;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterDMATrans
+* Description    : DMA方式连续发送数据
+* Input          : pbuf: 待发送数据起始地址
+*                  len : 待发送数据长度
+* Return         : None
+*******************************************************************************/
+void SPI0_MasterDMATrans( PUINT8 pbuf, UINT16 len)
+{
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R16_SPI0_DMA_BEG = (UINT32)pbuf;
+    R16_SPI0_DMA_END = (UINT32)(pbuf + len);
+    R16_SPI0_TOTAL_CNT = len;
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
+    R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
+    while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
+    R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_MasterDMARecv
+* Description    : DMA方式连续接收数据
+* Input          : pbuf: 待接收数据存放起始地址
+*                  len : 待接收数据长度
+* Return         : None
+*******************************************************************************/
+void SPI0_MasterDMARecv( PUINT8 pbuf, UINT16 len)
+{
+    R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
+    R16_SPI0_DMA_BEG = (UINT32)pbuf;
+    R16_SPI0_DMA_END = (UINT32)(pbuf + len);
+    R16_SPI0_TOTAL_CNT = len;
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
+    R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
+    while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
+    R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
+}
+
+
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveInit
+* Description    : 设备模式默认初始化,建议设置MISO的GPIO对应为输入模式
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void SPI0_SlaveInit( void )
+{
+    R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
+    R8_SPI0_CTRL_MOD = RB_SPI_MISO_OE | RB_SPI_MODE_SLAVE;
+    R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF;
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveRecvByte
+* Description    : 从机模式,接收一字节数据
+* Input          : None
+* Return         : 接收到数据
+*******************************************************************************/
+UINT8 SPI0_SlaveRecvByte( void )
+{
+    R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
+    while( R8_SPI0_FIFO_COUNT == 0 );
+    return R8_SPI0_FIFO;
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveSendByte
+* Description    : 从机模式,发送一字节数据
+* Input          : d -待发送数据
+* Return         : None
+*******************************************************************************/
+void SPI0_SlaveSendByte( UINT8 d )
+{
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R8_SPI0_FIFO = d;
+    while( R8_SPI0_FIFO_COUNT != 0 );               // 等待发送完成
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveRecv
+* Description    : 从机模式,接收多字节数据
+* Input          : pbuf: 接收收数据存放起始地址
+*                  len : 请求接收数据长度
+* Return         : None
+*******************************************************************************/
+void SPI0_SlaveRecv( PUINT8 pbuf, UINT16 len )
+{
+    UINT16 revlen;
+
+    revlen = len;
+    R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
+    while( revlen )
+    {
+        if( R8_SPI0_FIFO_COUNT )
+        {
+            *pbuf = R8_SPI0_FIFO;
+            pbuf++;
+            revlen--;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveTrans
+* Description    : 从机模式,发送多字节数据
+* Input          : pbuf: 待发送的数据内容首地址
+                   len: 请求发送的数据长度,最大4095
+* Return         : None
+*******************************************************************************/
+void SPI0_SlaveTrans( UINT8 *pbuf, UINT16 len )
+{
+    UINT16 sendlen;
+
+    sendlen = len;
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;                     // 设置数据方向为输出
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
+    while( sendlen )
+    {
+        if( R8_SPI0_FIFO_COUNT < SPI_FIFO_SIZE )
+        {
+            R8_SPI0_FIFO = *pbuf;
+            pbuf++;
+            sendlen--;
+        }
+    }
+    while( R8_SPI0_FIFO_COUNT != 0 );                         // 等待FIFO中的数据全部发送完成
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveDMARecv
+* Description    : DMA方式连续接收数据
+* Input          : pbuf: 待接收数据存放起始地址
+*                  len : 待接收数据长度
+* Return         : None
+*******************************************************************************/
+void SPI0_SlaveDMARecv( PUINT8 pbuf, UINT16 len)
+{
+    R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
+    R16_SPI0_DMA_BEG = (UINT32)pbuf;
+    R16_SPI0_DMA_END = (UINT32)(pbuf + len);
+    R16_SPI0_TOTAL_CNT = len;
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
+    R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
+    while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
+    R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
+}
+
+/*******************************************************************************
+* Function Name  : SPI0_SlaveDMATrans
+* Description    : DMA方式连续发送数据
+* Input          : pbuf: 待发送数据起始地址
+*                  len : 待发送数据长度
+* Return         : None
+*******************************************************************************/
+void SPI0_SlaveDMATrans( PUINT8 pbuf, UINT16 len)
+{
+    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R16_SPI0_DMA_BEG = (UINT32)pbuf;
+    R16_SPI0_DMA_END = (UINT32)(pbuf + len);
+    R16_SPI0_TOTAL_CNT = len;
+    R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
+    R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
+    while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
+    R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
+}
+
+
+

+ 156 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_spi1.c

@@ -0,0 +1,156 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_SPI1.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2019/4/29
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : SPI1_MasterDefInit
+* Description    : 主机模式默认初始化:模式0+3线全双工+8MHz
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void SPI1_MasterDefInit( void )
+{
+    R8_SPI1_CLOCK_DIV = 4;      // 主频时钟4分频
+    R8_SPI1_CTRL_MOD = RB_SPI_ALL_CLEAR;
+    R8_SPI1_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE ;
+    R8_SPI1_CTRL_CFG |= RB_SPI_AUTO_IF;        // 访问BUFFER/FIFO自动清除IF_BYTE_END标志
+    R8_SPI1_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;    // 不启动DMA方式
+}
+
+/*******************************************************************************
+* Function Name  : SPI1_CLKCfg
+* Description    : SPI1 基准时钟配置,= d*Tsys
+* Input          : c: 时钟分频系数
+* Return         : None
+*******************************************************************************/
+void SPI1_CLKCfg( UINT8 c )
+{
+    if(c==2)
+        R8_SPI1_CTRL_CFG |= RB_SPI_MST_DLY_EN;
+    else
+        R8_SPI1_CTRL_CFG &= ~RB_SPI_MST_DLY_EN;
+    R8_SPI1_CLOCK_DIV = c;
+}
+
+/*******************************************************************************
+* Function Name  : SPI1_DataMode
+* Description    : 设置数据流模式
+* Input          : m: 数据流模式
+                    refer to ModeBitOrderTypeDef
+* Return         : None
+*******************************************************************************/
+void SPI1_DataMode( ModeBitOrderTypeDef m )
+{
+    switch( m )
+    {
+        case Mode0_LowBitINFront:
+            R8_SPI1_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
+            R8_SPI1_CTRL_CFG |= RB_SPI_BIT_ORDER;
+            break;
+        case Mode0_HighBitINFront:
+            R8_SPI1_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
+            R8_SPI1_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
+            break;
+        case Mode3_LowBitINFront:
+            R8_SPI1_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
+            R8_SPI1_CTRL_CFG |= RB_SPI_BIT_ORDER;
+            break;
+        case Mode3_HighBitINFront:
+            R8_SPI1_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
+            R8_SPI1_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
+            break;
+        default:
+            break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : SPI1_MasterSendByte
+* Description    : 发送单字节 (buffer)
+* Input          : d: 发送字节
+* Return         : None
+*******************************************************************************/
+void SPI1_MasterSendByte( UINT8 d )
+{
+    R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R8_SPI1_BUFFER = d;
+    while( !(R8_SPI1_INT_FLAG & RB_SPI_FREE) );
+}
+
+/*******************************************************************************
+* Function Name  : SPI1_MasterRecvByte
+* Description    : 接收单字节 (buffer)
+* Input          : None
+* Return         : 接收到的字节
+*******************************************************************************/
+UINT8 SPI1_MasterRecvByte( void )
+{
+    R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
+    R8_SPI1_BUFFER = 0xFF;           // 启动传输
+    while( !(R8_SPI1_INT_FLAG & RB_SPI_FREE) );
+    return ( R8_SPI1_BUFFER );
+}
+
+
+/*******************************************************************************
+* Function Name  : SPI1_MasterTrans
+* Description    : 使用FIFO连续发送多字节
+* Input          : pbuf: 待发送的数据内容首地址
+                   len: 请求发送的数据长度,最大4095
+* Return         : None
+*******************************************************************************/
+void SPI1_MasterTrans( UINT8 *pbuf, UINT16 len )
+{
+    UINT16 sendlen;
+
+    sendlen = len;
+    R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;                     // 设置数据方向为输出
+    R16_SPI1_TOTAL_CNT = sendlen;                             // 设置要发送的数据长度
+    R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END;
+    while( sendlen )
+    {
+        if( R8_SPI1_FIFO_COUNT < SPI_FIFO_SIZE )
+        {
+            R8_SPI1_FIFO = *pbuf;
+            pbuf++;
+            sendlen--;
+        }
+    }
+    while( R8_SPI1_FIFO_COUNT != 0 );                         // 等待FIFO中的数据全部发送完成
+}
+
+/*******************************************************************************
+* Function Name  : SPI1_MasterRecv
+* Description    : 使用FIFO连续接收多字节
+* Input          : pbuf: 待发送的数据内容首地址
+                   len: 请求发送的数据长度,最大4095
+* Return         : None
+*******************************************************************************/
+void SPI1_MasterRecv( UINT8 *pbuf, UINT16 len )
+{
+    UINT16  readlen;
+
+    readlen = len;
+    R8_SPI1_CTRL_MOD |= RB_SPI_FIFO_DIR;                     // 设置数据方向为输入
+    R16_SPI1_TOTAL_CNT = len;                                // 设置需要接收的数据长度,FIFO方向为输入长度不为0则会启动传输 */
+    R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END;
+    while( readlen )
+    {
+        if( R8_SPI1_FIFO_COUNT )
+        {
+            *pbuf = R8_SPI1_FIFO;
+            pbuf++;
+            readlen--;
+        }
+    }
+}
+
+
+

+ 193 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_sys.c

@@ -0,0 +1,193 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_SYS.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : SYS_GetInfoSta
+* Description    : 获取当前系统信息状态
+* Input          : i:
+                    refer to SYS_InfoStaTypeDef
+* Return         : DISABLE  -  关闭
+                   ENABLE   -  开启
+*******************************************************************************/
+UINT8 SYS_GetInfoSta( SYS_InfoStaTypeDef i )
+{
+    if(i == STA_SAFEACC_ACT)
+        return (R8_SAFE_ACCESS_SIG & RB_SAFE_ACC_ACT);
+    else
+        return (R8_GLOB_CFG_INFO&(1<<i));
+}
+
+/*******************************************************************************
+* Function Name  : SYS_ResetExecute
+* Description    : 执行系统软件复位
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void SYS_ResetExecute( void )
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : SYS_DisableAllIrq
+* Description    : 关闭所有中断,并保留当前中断值
+* Input          : pirqv:当前保留中断值
+* Return         : None
+*******************************************************************************/
+void SYS_DisableAllIrq( PUINT32 pirqv)
+{
+    *pirqv = NVIC->ISER[0];
+    NVIC->ICER[0] = 0xffffffff;
+}
+
+/*******************************************************************************
+* Function Name  : SYS_RecoverIrq
+* Description    : 恢复之前关闭的中断值
+* Input          : irq_status:当前保留中断值
+* Return         : None
+*******************************************************************************/
+void SYS_RecoverIrq( UINT32 irq_status )
+{
+    NVIC->ISER[0] = irq_status;
+}
+
+/*******************************************************************************
+* Function Name  : SYS_GetSysTickCnt
+* Description    : 获取当前系统(SYSTICK)计数值
+* Input          : None
+* Return         : 当前计数值
+*******************************************************************************/
+UINT32 SYS_GetSysTickCnt( void )
+{
+    return(SysTick->VAL );
+}
+
+/*******************************************************************************
+* Function Name  : WWDG_ITCfg
+* Description    : 看门狗定时器溢出中断使能
+* Input          : DISABLE-溢出不中断      ENABLE-溢出中断
+* Return         : None
+*******************************************************************************/
+void  WWDG_ITCfg( UINT8 s )
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    if(s == DISABLE)        R8_RST_WDOG_CTRL&=~RB_WDOG_INT_EN;
+    else                    R8_RST_WDOG_CTRL|=RB_WDOG_INT_EN;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : WWDG_ResetCfg
+* Description    : 看门狗定时器复位功能
+* Input          : DISABLE-溢出不复位      ENABLE-溢出系统复位
+* Return         : None
+*******************************************************************************/
+void WWDG_ResetCfg( UINT8 s )
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    if(s == DISABLE)        R8_RST_WDOG_CTRL&=~RB_WDOG_RST_EN;
+    else                    R8_RST_WDOG_CTRL|=RB_WDOG_RST_EN;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+/*******************************************************************************
+* Function Name  : WWDG_ClearFlag
+* Description    : 清除看门狗中断标志,重新加载计数值也可清除
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void WWDG_ClearFlag( void )
+{
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
+    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
+    R8_RST_WDOG_CTRL |= RB_WDOG_INT_FLAG;
+    R8_SAFE_ACCESS_SIG = 0;
+}
+
+
+/*******************************************************************************
+* Function Name  : mDelayuS
+* Description    : uS 延时
+* Input          : t: 时间参数
+* Return         : None
+*******************************************************************************/
+void mDelayuS( UINT16 t )
+{
+    UINT16 i, j;
+
+    for(j=0; j<t; j++)
+    {
+
+#if     (FREQ_SYS == 40000000)
+    for(i=0; i<4; i++)      __nop();
+
+#elif       (FREQ_SYS == 32000000)
+    i = 2;
+    while(i--)  { __nop();  __nop(); }
+
+#elif       (FREQ_SYS == 24000000)
+    i = 1;
+    while(i--)  { __nop();  __nop(); }
+
+ #elif       (FREQ_SYS == 20000000)
+    for(i=0; i<1; i++)      __nop();
+
+ #elif       (FREQ_SYS == 16000000)
+    __nop(); __nop();   __nop(); __nop();
+    __nop(); __nop();   __nop(); __nop(); __nop();
+
+#elif       (FREQ_SYS == 8000000)
+    __nop(); __nop();
+
+#endif
+
+    }
+}
+
+/*******************************************************************************
+* Function Name  : mDelaymS
+* Description    : mS 延时
+* Input          : t: 时间参数
+* Return         : None
+*******************************************************************************/
+void mDelaymS( UINT16 t )
+{
+    UINT16 i;
+
+    for(i=0; i<t; i++)
+        mDelayuS(1000);
+}
+
+
+#if( defined  DEBUG)
+int fputc( int c, FILE *f )
+{
+#if  DEBUG == Debug_UART0
+  while( R8_UART0_TFC == UART_FIFO_SIZE );                        /* 等待数据发送 */
+  R8_UART0_THR = c;                                               /* 发送数据 */
+#elif DEBUG == Debug_UART1
+  while( R8_UART1_TFC == UART_FIFO_SIZE );                        /* 等待数据发送 */
+  R8_UART1_THR = c;                                               /* 发送数据 */
+#elif DEBUG == Debug_UART2
+  while( R8_UART2_TFC == UART_FIFO_SIZE );                        /* 等待数据发送 */
+  R8_UART2_THR = c;                                               /* 发送数据 */
+#elif DEBUG == Debug_UART3
+  while( R8_UART3_TFC == UART_FIFO_SIZE );                        /* 等待数据发送 */
+  R8_UART3_THR = c;                                               /* 发送数据 */
+#endif
+  return( c );
+}
+#endif

+ 96 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer0.c

@@ -0,0 +1,96 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_timer0.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : TMR0_TimerInit
+* Description    : 定时功能初始化
+* Input          : t: 定时时间,基于当前系统时钟Tsys, 最长定时周期 67108864
+
+* Return         : None
+*******************************************************************************/
+void TMR0_TimerInit( UINT32 t )
+{
+    R32_TMR0_CNT_END = t;
+    R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR0_EXTSingleCounterInit
+* Description    : 外部信号计数功能初始化
+* Input          : c: 外部送入信号脉冲计数, 最长计数 67108864
+* Return         : None
+*******************************************************************************/
+void TMR0_EXTSingleCounterInit( UINT32 c )
+{
+    R32_TMR0_CNT_END = c;
+    R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR0_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR0_CountInit
+* Description    : 边沿计数功能初始化
+* Input          : cap: 采集计数类型
+                    CAP_NULL - 不计数
+                    Edge_To_Edge - 计数任意边沿
+                    FallEdge_To_FallEdge - 计数下降沿
+                    RiseEdge_To_RiseEdge - 计数上升沿
+* Return         : None
+*******************************************************************************/
+void TMR0_CountInit( CapModeTypeDef cap )
+{
+    R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN      \
+                      |RB_TMR_CAP_COUNT     \
+                      |RB_TMR_MODE_IN       \
+                      |(cap<<6);
+}
+
+/*******************************************************************************
+* Function Name  : TMR0_PWMInit
+* Description    : PWM 输出初始化
+* Input          : pr:  select wave polar
+                    refer to PWMX_PolarTypeDef
+                   ts:  set pwm repeat times
+                    refer to PWM_RepeatTsTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR0_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
+{
+//    R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN      \
+                        |RB_TMR_OUT_EN      \
+                        |(pr<<4)            \
+                        |(ts<<6);
+}
+
+
+/*******************************************************************************
+* Function Name  : TMR0_CapInit
+* Description    : 外部信号捕捉功能初始化
+* Input          : cap:  select capture mode
+                    refer to CapModeTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR0_CapInit( CapModeTypeDef cap )
+{
+        R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
+        R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN      \
+                            |RB_TMR_MODE_IN     \
+                            |(cap<<6);
+}
+
+
+
+
+
+

+ 118 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer1.c

@@ -0,0 +1,118 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_timer1.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : TMR1_TimerInit
+* Description    : 定时功能初始化
+* Input          : t: 定时时间,基于当前系统时钟Tsys, 最长定时周期 67108864
+
+* Return         : None
+*******************************************************************************/
+void TMR1_TimerInit( UINT32 t )
+{
+    R32_TMR1_CNT_END = t;
+    R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR1_EXTSingleCounterInit
+* Description    : 外部信号计数功能初始化
+* Input          : c: 外部送入信号脉冲计数, 最长计数 67108864
+* Return         : None
+*******************************************************************************/
+void TMR1_EXTSingleCounterInit( UINT32 c )
+{
+    R32_TMR1_CNT_END = c;
+    R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR1_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR1_CountInit
+* Description    : 边沿计数功能初始化
+* Input          : cap: 采集计数类型
+                    CAP_NULL - 不计数
+                    Edge_To_Edge - 计数任意边沿
+                    FallEdge_To_FallEdge - 计数下降沿
+                    RiseEdge_To_RiseEdge - 计数上升沿
+* Return         : None
+*******************************************************************************/
+void TMR1_CountInit( CapModeTypeDef cap )
+{
+    R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN      \
+                      |RB_TMR_CAP_COUNT     \
+                      |RB_TMR_MODE_IN       \
+                      |(cap<<6);
+}
+
+/*******************************************************************************
+* Function Name  : TMR1_PWMInit
+* Description    : PWM 输出初始化
+* Input          : pr:  select wave polar
+                    refer to PWMX_PolarTypeDef
+                   ts:  set pwm repeat times
+                    refer to PWM_RepeatTsTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR1_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
+{
+//    R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN      \
+                        |RB_TMR_OUT_EN      \
+                        |(pr<<4)            \
+                        |(ts<<6);
+}
+
+
+/*******************************************************************************
+* Function Name  : TMR1_CapInit
+* Description    : 外部信号捕捉功能初始化
+* Input          : cap:  select capture mode
+                    refer to CapModeTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR1_CapInit( CapModeTypeDef cap )
+{
+        R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
+        R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN      \
+                            |RB_TMR_MODE_IN     \
+                            |(cap<<6);
+}
+
+/*******************************************************************************
+* Function Name  : TMR1_DMACfg
+* Description    : 配置DMA功能
+* Input          : s:
+                    ENABLE  - 打开
+                    DISABLE - 关闭
+                   startAddr: DMA 起始地址
+                   endAddr: DMA结束地址
+                   m:配置DMA模式
+* Return         : None
+*******************************************************************************/
+void TMR1_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m )
+{
+        if(s == DISABLE){
+            R8_TMR1_CTRL_DMA = 0;
+        }
+        else{
+            R16_TMR1_DMA_BEG = startAddr;
+            R16_TMR1_DMA_END = endAddr;
+            if(m)   R8_TMR1_CTRL_DMA = RB_TMR_DMA_LOOP|RB_TMR_DMA_ENABLE;
+            else    R8_TMR1_CTRL_DMA = RB_TMR_DMA_ENABLE;
+        }
+}
+
+
+
+

+ 118 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer2.c

@@ -0,0 +1,118 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_timer2.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : TMR2_TimerInit
+* Description    : 定时功能初始化
+* Input          : t: 定时时间,基于当前系统时钟Tsys, 最长定时周期 67108864
+
+* Return         : None
+*******************************************************************************/
+void TMR2_TimerInit( UINT32 t )
+{
+    R32_TMR2_CNT_END = t;
+    R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR2_EXTSingleCounterInit
+* Description    : 外部信号计数功能初始化
+* Input          : c: 外部送入信号脉冲计数, 最长计数 67108864
+* Return         : None
+*******************************************************************************/
+void TMR2_EXTSingleCounterInit( UINT32 c )
+{
+    R32_TMR2_CNT_END = c;
+    R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR2_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR2_CountInit
+* Description    : 边沿计数功能初始化
+* Input          : cap: 采集计数类型
+                    CAP_NULL - 不计数
+                    Edge_To_Edge - 计数任意边沿
+                    FallEdge_To_FallEdge - 计数下降沿
+                    RiseEdge_To_RiseEdge - 计数上升沿
+* Return         : None
+*******************************************************************************/
+void TMR2_CountInit( CapModeTypeDef cap )
+{
+    R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN      \
+                      |RB_TMR_CAP_COUNT     \
+                      |RB_TMR_MODE_IN       \
+                      |(cap<<6);
+}
+
+/*******************************************************************************
+* Function Name  : TMR2_PWMInit
+* Description    : PWM 输出初始化
+* Input          : pr:  select wave polar
+                    refer to PWMX_PolarTypeDef
+                   ts:  set pwm repeat times
+                    refer to PWM_RepeatTsTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR2_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
+{
+//    R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN      \
+                        |RB_TMR_OUT_EN      \
+                        |(pr<<4)            \
+                        |(ts<<6);
+}
+
+
+/*******************************************************************************
+* Function Name  : TMR2_CapInit
+* Description    : 外部信号捕捉功能初始化
+* Input          : cap:  select capture mode
+                    refer to CapModeTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR2_CapInit( CapModeTypeDef cap )
+{
+        R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
+        R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN      \
+                            |RB_TMR_MODE_IN     \
+                            |(cap<<6);
+}
+
+/*******************************************************************************
+* Function Name  : TMR2_DMACfg
+* Description    : 配置DMA功能
+* Input          : s:
+                    ENABLE  - 打开
+                    DISABLE - 关闭
+                   startAddr: DMA 起始地址
+                   endAddr: DMA结束地址
+                   m:配置DMA模式
+* Return         : None
+*******************************************************************************/
+void TMR2_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m )
+{
+        if(s == DISABLE){
+            R8_TMR2_CTRL_DMA = 0;
+        }
+        else{
+            R16_TMR2_DMA_BEG = startAddr;
+            R16_TMR2_DMA_END = endAddr;
+            if(m)   R8_TMR2_CTRL_DMA = RB_TMR_DMA_LOOP|RB_TMR_DMA_ENABLE;
+            else    R8_TMR2_CTRL_DMA = RB_TMR_DMA_ENABLE;
+        }
+}
+
+
+
+

+ 96 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_timer3.c

@@ -0,0 +1,96 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_timer3.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+
+/*******************************************************************************
+* Function Name  : TMR3_TimerInit
+* Description    : 定时功能初始化
+* Input          : t: 定时时间,基于当前系统时钟Tsys, 最长定时周期 67108864
+
+* Return         : None
+*******************************************************************************/
+void TMR3_TimerInit( UINT32 t )
+{
+    R32_TMR3_CNT_END = t;
+    R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR3_EXTSingleCounterInit
+* Description    : 外部信号计数功能初始化
+* Input          : c: 外部送入信号脉冲计数, 最长计数 67108864
+* Return         : None
+*******************************************************************************/
+void TMR3_EXTSingleCounterInit( UINT32 c )
+{
+    R32_TMR3_CNT_END = c;
+    R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR3_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
+}
+
+/*******************************************************************************
+* Function Name  : TMR3_CountInit
+* Description    : 边沿计数功能初始化
+* Input          : cap: 采集计数类型
+                    CAP_NULL - 不计数
+                    Edge_To_Edge - 计数任意边沿
+                    FallEdge_To_FallEdge - 计数下降沿
+                    RiseEdge_To_RiseEdge - 计数上升沿
+* Return         : None
+*******************************************************************************/
+void TMR3_CountInit( CapModeTypeDef cap )
+{
+    R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN      \
+                      |RB_TMR_CAP_COUNT     \
+                      |RB_TMR_MODE_IN       \
+                      |(cap<<6);
+}
+
+/*******************************************************************************
+* Function Name  : TMR3_PWMInit
+* Description    : PWM 输出初始化
+* Input          : pr:  select wave polar
+                    refer to PWMX_PolarTypeDef
+                   ts:  set pwm repeat times
+                    refer to PWM_RepeatTsTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR3_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
+{
+//    R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
+    R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN      \
+                        |RB_TMR_OUT_EN      \
+                        |(pr<<4)            \
+                        |(ts<<6);
+}
+
+
+/*******************************************************************************
+* Function Name  : TMR3_CapInit
+* Description    : 外部信号捕捉功能初始化
+* Input          : cap:  select capture mode
+                    refer to CapModeTypeDef
+* Return         : None
+*******************************************************************************/
+void TMR3_CapInit( CapModeTypeDef cap )
+{
+        R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
+        R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN      \
+                            |RB_TMR_MODE_IN     \
+                            |(cap<<6);
+}
+
+
+
+
+
+

+ 130 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart0.c

@@ -0,0 +1,130 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_uart0.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+/*******************************************************************************
+* Function Name  : UART0_DefInit
+* Description    : 串口默认初始化配置
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART0_DefInit( void )
+{
+    UART0_BaudRateCfg( 115200 );
+    R8_UART0_FCR = (2<<6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;       // FIFO打开,触发点4字节
+    R8_UART0_LCR = RB_LCR_WORD_SZ;
+    R8_UART0_IER = RB_IER_TXD_EN;
+    R8_UART0_DIV = 1;
+}
+
+/*******************************************************************************
+* Function Name  : UART0_BaudRateCfg
+* Description    : 串口波特率配置
+* Input          :
+* Return         :
+*******************************************************************************/
+void UART0_BaudRateCfg( UINT32 baudrate )
+{
+    UINT32  x;
+
+    x = 10 * GetSysClock() / 8 / baudrate;
+    x = ( x + 5 ) / 10;
+    R16_UART0_DL = (UINT16)x;
+}
+
+/*******************************************************************************
+* Function Name  : UART0_ByteTrigCfg
+* Description    : 串口字节触发中断配置
+* Input          : b: 触发字节数
+                    refer to UARTByteTRIGTypeDef
+* Return         :
+*******************************************************************************/
+void UART0_ByteTrigCfg( UARTByteTRIGTypeDef b )
+{
+    R8_UART0_FCR = (R8_UART0_FCR&~RB_FCR_FIFO_TRIG)|(b<<6);
+}
+
+/*******************************************************************************
+* Function Name  : UART0_INTCfg
+* Description    : 串口中断配置
+* Input          : s:  中断控制状态
+                    ENABLE  - 使能相应中断
+                    DISABLE - 关闭相应中断
+                   i:  中断类型
+                    RB_IER_MODEM_CHG  - 调制解调器输入状态变化中断使能位(仅 UART0 支持)
+                    RB_IER_LINE_STAT  - 接收线路状态中断
+                    RB_IER_THR_EMPTY  - 发送保持寄存器空中断
+                    RB_IER_RECV_RDY   - 接收数据中断
+* Return         : None
+*******************************************************************************/
+void UART0_INTCfg( UINT8 s,  UINT8 i )
+{
+    if( s )
+    {
+        R8_UART0_IER |= i;
+        R8_UART0_MCR |= RB_MCR_INT_OE;
+    }
+    else
+    {
+        R8_UART0_IER &= ~i;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART0_Reset
+* Description    : 串口软件复位
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART0_Reset( void )
+{
+    R8_UART0_IER = RB_IER_RESET;
+}
+
+/*******************************************************************************
+* Function Name  : UART0_SendString
+* Description    : 串口多字节发送
+* Input          : buf - 待发送的数据内容首地址
+                     l - 待发送的数据长度
+* Return         : None
+*******************************************************************************/
+void UART0_SendString( PUINT8 buf, UINT16 l )
+{
+    UINT16 len = l;
+
+    while(len)
+    {
+        if(R8_UART0_TFC != UART_FIFO_SIZE)
+        {
+            R8_UART0_THR = *buf++;
+            len--;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART0_RecvString
+* Description    : 串口读取多字节
+* Input          : buf - 读取数据存放缓存区首地址
+* Return         : 读取数据长度
+*******************************************************************************/
+UINT16 UART0_RecvString( PUINT8 buf )
+{
+    UINT16 len = 0;
+
+    while( R8_UART0_RFC )
+    {
+        *buf++ = R8_UART0_RBR;
+        len ++;
+    }
+
+    return (len);
+}
+
+

+ 130 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart1.c

@@ -0,0 +1,130 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_uart1.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+/*******************************************************************************
+* Function Name  : UART1_DefInit
+* Description    : 串口默认初始化配置
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART1_DefInit( void )
+{
+    UART1_BaudRateCfg( 115200 );
+    R8_UART1_FCR = (2<<6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;       // FIFO打开,触发点4字节
+    R8_UART1_LCR = RB_LCR_WORD_SZ;
+    R8_UART1_IER = RB_IER_TXD_EN;
+    R8_UART1_DIV = 1;
+}
+
+/*******************************************************************************
+* Function Name  : UART1_BaudRateCfg
+* Description    : 串口波特率配置
+* Input          :
+* Return         :
+*******************************************************************************/
+void UART1_BaudRateCfg( UINT32 baudrate )
+{
+    UINT32  x;
+
+    x = 10 * GetSysClock() / 8 / baudrate;
+    x = ( x + 5 ) / 10;
+    R16_UART1_DL = (UINT16)x;
+}
+
+/*******************************************************************************
+* Function Name  : UART1_ByteTrigCfg
+* Description    : 串口字节触发中断配置
+* Input          : b: 触发字节数
+                    refer to UARTByteTRIGTypeDef
+* Return         :
+*******************************************************************************/
+void UART1_ByteTrigCfg( UARTByteTRIGTypeDef b )
+{
+    R8_UART1_FCR = (R8_UART1_FCR&~RB_FCR_FIFO_TRIG)|(b<<6);
+}
+
+/*******************************************************************************
+* Function Name  : UART1_INTCfg
+* Description    : 串口中断配置
+* Input          : s:  中断控制状态
+                    ENABLE  - 使能相应中断
+                    DISABLE - 关闭相应中断
+                   i:  中断类型
+                    RB_IER_MODEM_CHG  - 调制解调器输入状态变化中断使能位(仅 UART0 支持)
+                    RB_IER_LINE_STAT  - 接收线路状态中断
+                    RB_IER_THR_EMPTY  - 发送保持寄存器空中断
+                    RB_IER_RECV_RDY   - 接收数据中断
+* Return         : None
+*******************************************************************************/
+void UART1_INTCfg( UINT8 s,  UINT8 i )
+{
+    if( s )
+    {
+        R8_UART1_IER |= i;
+        R8_UART1_MCR |= RB_MCR_INT_OE;
+    }
+    else
+    {
+        R8_UART1_IER &= ~i;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART1_Reset
+* Description    : 串口软件复位
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART1_Reset( void )
+{
+    R8_UART1_IER = RB_IER_RESET;
+}
+
+/*******************************************************************************
+* Function Name  : UART1_SendString
+* Description    : 串口多字节发送
+* Input          : buf - 待发送的数据内容首地址
+                     l - 待发送的数据长度
+* Return         : None
+*******************************************************************************/
+void UART1_SendString( PUINT8 buf, UINT16 l )
+{
+    UINT16 len = l;
+
+    while(len)
+    {
+        if(R8_UART1_TFC != UART_FIFO_SIZE)
+        {
+            R8_UART1_THR = *buf++;
+            len--;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART1_RecvString
+* Description    : 串口读取多字节
+* Input          : buf - 读取数据存放缓存区首地址
+* Return         : 读取数据长度
+*******************************************************************************/
+UINT16 UART1_RecvString( PUINT8 buf )
+{
+    UINT16 len = 0;
+
+    while( R8_UART1_RFC )
+    {
+        *buf++ = R8_UART1_RBR;
+        len ++;
+    }
+
+    return (len);
+}
+
+

+ 130 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart2.c

@@ -0,0 +1,130 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_uart2.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+/*******************************************************************************
+* Function Name  : UART2_DefInit
+* Description    : 串口默认初始化配置
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART2_DefInit( void )
+{
+    UART2_BaudRateCfg( 115200 );
+    R8_UART2_FCR = (2<<6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;       // FIFO打开,触发点4字节
+    R8_UART2_LCR = RB_LCR_WORD_SZ;
+    R8_UART2_IER = RB_IER_TXD_EN;
+    R8_UART2_DIV = 1;
+}
+
+/*******************************************************************************
+* Function Name  : UART2_BaudRateCfg
+* Description    : 串口波特率配置
+* Input          :
+* Return         :
+*******************************************************************************/
+void UART2_BaudRateCfg( UINT32 baudrate )
+{
+    UINT32  x;
+
+    x = 10 * GetSysClock() / 8 / baudrate;
+    x = ( x + 5 ) / 10;
+    R16_UART2_DL = (UINT16)x;
+}
+
+/*******************************************************************************
+* Function Name  : UART2_ByteTrigCfg
+* Description    : 串口字节触发中断配置
+* Input          : b: 触发字节数
+                    refer to UARTByteTRIGTypeDef
+* Return         :
+*******************************************************************************/
+void UART2_ByteTrigCfg( UARTByteTRIGTypeDef b )
+{
+    R8_UART2_FCR = (R8_UART2_FCR&~RB_FCR_FIFO_TRIG)|(b<<6);
+}
+
+/*******************************************************************************
+* Function Name  : UART2_INTCfg
+* Description    : 串口中断配置
+* Input          : s:  中断控制状态
+                    ENABLE  - 使能相应中断
+                    DISABLE - 关闭相应中断
+                   i:  中断类型
+                    RB_IER_MODEM_CHG  - 调制解调器输入状态变化中断使能位(仅 UART0 支持)
+                    RB_IER_LINE_STAT  - 接收线路状态中断
+                    RB_IER_THR_EMPTY  - 发送保持寄存器空中断
+                    RB_IER_RECV_RDY   - 接收数据中断
+* Return         : None
+*******************************************************************************/
+void UART2_INTCfg( UINT8 s,  UINT8 i )
+{
+    if( s )
+    {
+        R8_UART2_IER |= i;
+        R8_UART2_MCR |= RB_MCR_INT_OE;
+    }
+    else
+    {
+        R8_UART2_IER &= ~i;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART2_Reset
+* Description    : 串口软件复位
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART2_Reset( void )
+{
+    R8_UART2_IER = RB_IER_RESET;
+}
+
+/*******************************************************************************
+* Function Name  : UART2_SendString
+* Description    : 串口多字节发送
+* Input          : buf - 待发送的数据内容首地址
+                     l - 待发送的数据长度
+* Return         : None
+*******************************************************************************/
+void UART2_SendString( PUINT8 buf, UINT16 l )
+{
+    UINT16 len = l;
+
+    while(len)
+    {
+        if(R8_UART2_TFC != UART_FIFO_SIZE)
+        {
+            R8_UART2_THR = *buf++;
+            len--;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART2_RecvString
+* Description    : 串口读取多字节
+* Input          : buf - 读取数据存放缓存区首地址
+* Return         : 读取数据长度
+*******************************************************************************/
+UINT16 UART2_RecvString( PUINT8 buf )
+{
+    UINT16 len = 0;
+
+    while( R8_UART2_RFC )
+    {
+        *buf++ = R8_UART2_RBR;
+        len ++;
+    }
+
+    return (len);
+}
+
+

+ 130 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_uart3.c

@@ -0,0 +1,130 @@
+/********************************** (C) COPYRIGHT *******************************
+* File Name          : CH57x_uart3.c
+* Author             : WCH
+* Version            : V1.0
+* Date               : 2018/12/15
+* Description
+*******************************************************************************/
+
+#include "CH57x_common.h"
+
+/*******************************************************************************
+* Function Name  : UART3_DefInit
+* Description    : 串口默认初始化配置
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART3_DefInit( void )
+{
+    UART3_BaudRateCfg( 115200 );
+    R8_UART3_FCR = (2<<6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;       // FIFO打开,触发点4字节
+    R8_UART3_LCR = RB_LCR_WORD_SZ;
+    R8_UART3_IER = RB_IER_TXD_EN;
+    R8_UART3_DIV = 1;
+}
+
+/*******************************************************************************
+* Function Name  : UART3_BaudRateCfg
+* Description    : 串口波特率配置
+* Input          :
+* Return         :
+*******************************************************************************/
+void UART3_BaudRateCfg( UINT32 baudrate )
+{
+    UINT32  x;
+
+    x = 10 * GetSysClock() / 8 / baudrate;
+    x = ( x + 5 ) / 10;
+    R16_UART3_DL = (UINT16)x;
+}
+
+/*******************************************************************************
+* Function Name  : UART3_ByteTrigCfg
+* Description    : 串口字节触发中断配置
+* Input          : b: 触发字节数
+                    refer to UARTByteTRIGTypeDef
+* Return         :
+*******************************************************************************/
+void UART3_ByteTrigCfg( UARTByteTRIGTypeDef b )
+{
+    R8_UART3_FCR = (R8_UART3_FCR&~RB_FCR_FIFO_TRIG)|(b<<6);
+}
+
+/*******************************************************************************
+* Function Name  : UART3_INTCfg
+* Description    : 串口中断配置
+* Input          : s:  中断控制状态
+                    ENABLE  - 使能相应中断
+                    DISABLE - 关闭相应中断
+                   i:  中断类型
+                    RB_IER_MODEM_CHG  - 调制解调器输入状态变化中断使能位(仅 UART0 支持)
+                    RB_IER_LINE_STAT  - 接收线路状态中断
+                    RB_IER_THR_EMPTY  - 发送保持寄存器空中断
+                    RB_IER_RECV_RDY   - 接收数据中断
+* Return         : None
+*******************************************************************************/
+void UART3_INTCfg( UINT8 s,  UINT8 i )
+{
+    if( s )
+    {
+        R8_UART3_IER |= i;
+        R8_UART3_MCR |= RB_MCR_INT_OE;
+    }
+    else
+    {
+        R8_UART3_IER &= ~i;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART3_Reset
+* Description    : 串口软件复位
+* Input          : None
+* Return         : None
+*******************************************************************************/
+void UART3_Reset( void )
+{
+    R8_UART3_IER = RB_IER_RESET;
+}
+
+/*******************************************************************************
+* Function Name  : UART3_SendString
+* Description    : 串口多字节发送
+* Input          : buf - 待发送的数据内容首地址
+                     l - 待发送的数据长度
+* Return         : None
+*******************************************************************************/
+void UART3_SendString( PUINT8 buf, UINT16 l )
+{
+    UINT16 len = l;
+
+    while(len)
+    {
+        if(R8_UART3_TFC != UART_FIFO_SIZE)
+        {
+            R8_UART3_THR = *buf++;
+            len--;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name  : UART3_RecvString
+* Description    : 串口读取多字节
+* Input          : buf - 读取数据存放缓存区首地址
+* Return         : 读取数据长度
+*******************************************************************************/
+UINT16 UART3_RecvString( PUINT8 buf )
+{
+    UINT16 len = 0;
+
+    while( R8_UART3_RFC )
+    {
+        *buf++ = R8_UART3_RBR;
+        len ++;
+    }
+
+    return (len);
+}
+
+

+ 1934 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH579SFR.h

@@ -0,0 +1,1934 @@
+/* Define for CH579         */
+/* Website:  http://wch.cn  */
+/* Email:    tech@wch.cn    */
+/* Author:   W.ch 2016.10   */
+/* V0.2 SpecialFunctionRegister */
+
+// multi-blocks: __BASE_TYPE__, __CH579SFR_H__, __CH579ETHSFR_H__, __CH579USBSFR_H__, __USB_TYPE__...
+
+#ifndef __BASE_TYPE__
+#define __BASE_TYPE__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ********************************************************************************************************************* */
+/* Base types & constants */
+
+#ifndef TRUE
+#define TRUE                    1
+#define FALSE                   0
+#endif
+#ifndef NULL
+#define NULL                    0
+#endif
+
+#ifndef VOID
+#define VOID                    void
+#endif
+#ifndef CONST
+#define CONST                   const
+#endif
+#ifndef BOOL
+typedef unsigned char           BOOL;
+#endif
+#ifndef BOOLEAN
+typedef unsigned char           BOOLEAN;
+#endif
+#ifndef CHAR
+typedef char                    CHAR;
+#endif
+#ifndef INT8
+typedef char                    INT8;
+#endif
+#ifndef INT16
+typedef short                   INT16;
+#endif
+#ifndef INT32
+typedef long                    INT32;
+#endif
+#ifndef UINT8
+typedef unsigned char           UINT8;
+#endif
+#ifndef UINT16
+typedef unsigned short          UINT16;
+#endif
+#ifndef UINT32
+typedef unsigned long           UINT32;
+#endif
+#ifndef UINT8V
+typedef unsigned char volatile  UINT8V;
+#endif
+#ifndef UINT16V
+typedef unsigned short volatile UINT16V;
+#endif
+#ifndef UINT32V
+typedef unsigned long volatile  UINT32V;
+#endif
+
+#ifndef PVOID
+typedef void                    *PVOID;
+#endif
+#ifndef PCHAR
+typedef char                    *PCHAR;
+#endif
+#ifndef PCHAR
+typedef const char              *PCCHAR;
+#endif
+#ifndef PINT8
+typedef char                    *PINT8;
+#endif
+#ifndef PINT16
+typedef short                   *PINT16;
+#endif
+#ifndef PINT32
+typedef long                    *PINT32;
+#endif
+#ifndef PUINT8
+typedef unsigned char           *PUINT8;
+#endif
+#ifndef PUINT16
+typedef unsigned short          *PUINT16;
+#endif
+#ifndef PUINT32
+typedef unsigned long           *PUINT32;
+#endif
+#ifndef PUINT8V
+typedef volatile unsigned char  *PUINT8V;
+#endif
+#ifndef PUINT16V
+typedef volatile unsigned short *PUINT16V;
+#endif
+#ifndef PUINT32V
+typedef volatile unsigned long  *PUINT32V;
+#endif
+
+/* ********************************************************************************************************************* */
+/* Base macros */
+
+#ifndef min
+#define min(a,b)                (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b)                (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifdef  DEBUG
+#define PRINT(X...) printf(X)
+#else
+#define PRINT(X...)
+#endif
+
+/* Calculate the byte offset of a field in a structure of type */
+#define FIELD_OFFSET(Type, Field)    ((UINT16)&(((Type *)0)->Field))
+
+/* Calculate the size of a field in a structure of type */
+#define FIELD_SIZE(Type, Field)      (sizeof(((Type *)0)->Field))
+
+/* An expression that yields the type of a field in a struct */
+#define FIELD_TYPE(Type, Field)      (((Type *)0)->Field)
+
+/* Return the number of elements in a statically sized array */
+#define NUMBER_OF(Array)             (sizeof(Array)/sizeof((Array)[0]))
+#define NUMBER_OF_FIELD(Type, Field) (NUMBER_OF(FIELD_TYPE(Type, Field)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __BASE_TYPE__
+
+
+#ifndef __CH579SFR_H__
+#define __CH579SFR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ********************************************************************************************************************* */
+
+// Address Space
+//    CODE:   00000000H - 0003FFFFH   256K
+//    DATA:   20000000H - 20007FFFH   32KB
+//    SFR:    40000000H - 4000FFFFH   64KB
+//    PPB:    E0000000H - E000FFFFH   64KB
+//
+//    SFR:    40000000H - 4000FFFFH,  64KB
+//      SYS:     +1000H - 1BFFH, include base configuration, interrupt, GPIO, etc...
+//      TMR0:    +2000H - 23FFH
+//      TMR1:    +2400H - 27FFH
+//      TMR2:    +2800H - 2BFFH
+//      TMR3:    +2C00H - 2FFFH
+//      UART0:   +3000H - 33FFH
+//      UART1:   +3400H - 37FFH
+//      UART2:   +3800H - 3BFFH
+//      UART3:   +3C00H - 3FFFH
+//      SPI0:    +4000H - 43FFH
+//      SPI1:    +4400H - 47FFH
+//      PWMx:    +5000H - 53FFH
+//      LCD:     +6000H - 63FFH
+//      LED:     +6400H - 67FFH
+//      USB:     +8000H - 83FFH
+//      ETH:     +9000H - 93FFH
+//      BLE:     +C000H - D3FFH
+
+// Register Bit Attribute / Bit Access Type
+//   RF:    Read only for Fixed value
+//   RO:    Read Only (internal change)
+//   RZ:    Read only with auto clear Zero
+//   WO:    Write Only (read zero or different)
+//   WA:    Write only under safe Accessing mode (read zero or different)
+//   WZ:    Write only with auto clear Zero
+//   RW:    Read / Write
+//   RWA:   Read / Write under safe Accessing mode
+//   RW1:   Read / Write 1 to Clear
+
+/* Register name rule:
+   R32_* for 32 bits register (UINT32,ULONG)
+   R16_* for 16 bits register (UINT16,USHORT)
+   R8_*  for  8 bits register (UINT8,UCHAR)
+   RB_*  for bit or bit mask of 8 bit register
+   BA_*  for base address point
+   b*    for GPIO bit mask
+   Others for register address offset */
+
+/* ********************************************************************************************************************* */
+
+/* System: safe accessing register */
+#define R32_SAFE_ACCESS     (*((PUINT32V)0x40001040)) // RW, safe accessing
+#define R8_SAFE_ACCESS_SIG  (*((PUINT8V)0x40001040))  // WO, safe accessing sign register, must write SAFE_ACCESS_SIG1 then SAFE_ACCESS_SIG2 to enter safe accessing mode
+#define  RB_SAFE_ACC_MODE   0x03                      // RO, current safe accessing mode: 11=safe/unlocked (SAM), other=locked (00..01..10..11)
+#define  RB_SAFE_ACC_ACT    0x08                      // RO, indicate safe accessing status now: 0=locked, read only, 1=safe/unlocked (SAM), write enabled
+#define  RB_SAFE_ACC_TIMER  0x70                      // RO, safe accessing timer bit mask (16*clock number)
+#define SAFE_ACCESS_SIG1    0x57                      // WO: safe accessing sign value step 1
+#define SAFE_ACCESS_SIG2    0xA8                      // WO: safe accessing sign value step 2
+#define SAFE_ACCESS_SIG0    0x00                      // WO: safe accessing sign value for disable
+#define R8_CHIP_ID          (*((PUINT8V)0x40001041))  // RF, chip ID register, always is ID_CH57*
+#define R8_SAFE_ACCESS_ID   (*((PUINT8V)0x40001042))  // RF, safe accessing ID register, always 0x04
+#define R8_WDOG_COUNT       (*((PUINT8V)0x40001043))  // RW, watch-dog count, count by clock frequency Fsys/131072
+
+/* System: global configuration register */
+#define R32_GLOBAL_CONFIG   (*((PUINT32V)0x40001044)) // RW, global configuration
+#define R8_RESET_STATUS     (*((PUINT8V)0x40001044))  // RWA, reset status, SAM
+#define  RB_RESET_FLAG      0x07                      // RO: recent reset flag
+#define  RST_FLAG_SW        0x00
+#define  RST_FLAG_RPOR      0x01
+#define  RST_FLAG_WTR       0x02
+#define  RST_FLAG_MR        0x03
+//#define  RST_FLAG_GPWSM     0x04                      // RO, power on reset flag during sleep/shutdown: 0=no power on reset during sleep/shutdown, 1=power on reset occurred during sleep/shutdown
+#define  RST_FLAG_GPWSM     0x05
+#define  RB_ROM_CODE_OFS    0x10                      // RWA, code offset address selection in Flash ROM: 0=start address 0x000000, 1=start address 0x008000
+// RB_RESET_FLAG: recent reset flag
+//   000 - SR, software reset, by RB_SOFTWARE_RESET=1 @RB_WDOG_RST_EN=0
+//   001 - RPOR, real power on reset
+//   010 - WTR, watch-dog timer-out reset
+//   011 - MR, external manual reset by RST pin input low
+//   101 - GRWSM, global reset by waking under shutdown mode
+//   1?? - LRW, power on reset occurred during sleep
+#define R8_GLOB_CFG_INFO    (*((PUINT8V)0x40001045))  // RO, global configuration information and status
+#define  RB_CFG_ROM_READ    0x01                      // RO, indicate protected status of Flash ROM code and data: 0=reading protect, 1=enable read by external programmer
+#define  RB_CFG_RESET_EN    0x04                      // RO, manual reset input enable status
+#define  RB_CFG_BOOT_EN     0x08                      // RO, boot-loader enable status
+#define  RB_CFG_DEBUG_EN    0x10                      // RO, debug enable status
+#define  RB_BOOT_LOADER     0x20                      // RO, indicate boot loader status: 0=application status (by software reset), 1=boot loader status
+#define R8_RST_WDOG_CTRL    (*((PUINT8V)0x40001046))  // RWA, reset and watch-dog control, SAM
+#define  RB_SOFTWARE_RESET  0x01                      // WA/WZ, global software reset, high action, auto clear
+#define  RB_WDOG_RST_EN     0x02                      // RWA, enable watch-dog reset if watch-dog timer overflow: 0=as timer only, 1=enable reset if timer overflow
+#define  RB_WDOG_INT_EN     0x04                      // RWA, watch-dog timer overflow interrupt enable: 0=disable, 1=enable
+#define  RB_WDOG_INT_FLAG   0x10                      // RW1, watch-dog timer overflow interrupt flag, cleared by RW1 or reload watch-dog count or __SEV(Send-Event)
+#define R8_GLOB_RESET_KEEP  (*((PUINT8V)0x40001047))  // RW, value keeper during global reset
+
+/* System: clock configuration register */
+#define R32_CLOCK_CONFIG    (*((PUINT32V)0x40001008)) // RWA, clock configuration, SAM
+#define R16_CLK_SYS_CFG     (*((PUINT16V)0x40001008)) // RWA, system clock configuration, SAM
+#define  RB_CLK_PLL_DIV     0x1F                      // RWA, output clock divider from PLL or CK32M
+#define  RB_CLK_SYS_MOD     0xC0                      // RWA, system clock source mode: 00=divided from 32MHz, 01=divided from PLL-480MHz, 10=directly from 32MHz, 11=directly from 32KHz
+#define  RB_CLK_OSC32M_XT   0x0200                    // RWA, 32MHz clock source selection: 0=internal 32MHz oscillator, 1=external 32MHz oscillator
+#define  RB_XO_DI           0x8000                    // RO, X32MO input status sample value
+#define R8_HFCK_PWR_CTRL    (*((PUINT8V)0x4000100A))  // RWA, high frequency clock module power control, SAM
+#define  RB_CLK_XT32M_PON   0x04                      // RWA, external 32MHz oscillator power control: 0=power down, 1-power on
+#define  RB_CLK_INT32M_PON  0x08                      // RWA, internal 32MHz oscillator power control: 0=power down, 1-power on
+#define  RB_CLK_PLL_PON     0x10                      // RWA, PLL power control: 0=power down, 1-power on
+// Fck32m = RB_CLK_OSC32M_XT ? XT_32MHz : RC_32MHz
+// Fck32k = RB_CLK_OSC32K_XT ? XT_32KHz : RC_32KHz
+// Fpll = Fck32m * 15 = 480MHz
+// Fsys = RB_CLK_SYS_MOD[1] ? ( RB_CLK_SYS_MOD[0] ? Fck32k : Fck32m ) : ( ( RB_CLK_SYS_MOD[0] ? Fpll : Fck32m ) / RB_CLK_PLL_DIV )
+// default: Fsys = Fck32m / RB_CLK_PLL_DIV = 32MHz / 5 = 6.4MHz
+//   range: 32KHz, 1MHz~16MHz, 32MHz, 15MHz~48MHz
+
+/* System: sleep control register */
+#define R32_SLEEP_CONTROL   (*((PUINT32V)0x4000100C)) // RWA, sleep control, SAM
+#define R8_SLP_CLK_OFF0     (*((PUINT8V)0x4000100C))  // RWA, sleep clock off control byte 0, SAM
+#define  RB_SLP_CLK_TMR0    0x01                      // RWA, close TMR0 clock
+#define  RB_SLP_CLK_TMR1    0x02                      // RWA, close TMR1 clock
+#define  RB_SLP_CLK_TMR2    0x04                      // RWA, close TMR2 clock
+#define  RB_SLP_CLK_TMR3    0x08                      // RWA, close TMR3 clock
+#define  RB_SLP_CLK_UART0   0x10                      // RWA, close UART0 clock
+#define  RB_SLP_CLK_UART1   0x20                      // RWA, close UART1 clock
+#define  RB_SLP_CLK_UART2   0x40                      // RWA, close UART2 clock
+#define  RB_SLP_CLK_UART3   0x80                      // RWA, close UART3 clock
+#define R8_SLP_CLK_OFF1     (*((PUINT8V)0x4000100D))  // RWA, sleep clock off control byte 1, SAM
+#define  RB_SLP_CLK_SPI0    0x01                      // RWA, close SPI0 clock
+#define  RB_SLP_CLK_SPI1    0x02                      // RWA, close SPI1 clock
+#define  RB_SLP_CLK_PWMX    0x04                      // RWA, close PWMx clock
+#define  RB_SLP_CLK_LCD     0x08                      // RWA, close LCD clock
+#define  RB_SLP_CLK_USB     0x10                      // RWA, close USB clock
+#define  RB_SLP_CLK_ETH     0x20                      // RWA, close ETH clock
+#define  RB_SLP_CLK_LED     0x40                      // RWA, close LED clock
+#define  RB_SLP_CLK_BLE     0x80                      // RWA, close BLE clock
+#define R8_SLP_WAKE_CTRL    (*((PUINT8V)0x4000100E))  // RWA, wake control, SAM
+#define  RB_SLP_USB_WAKE    0x01                      // RWA, enable USB waking
+#define  RB_SLP_ETH_WAKE    0x02                      // RWA, enable ETH waking
+//#define  RB_SLP_BLE_WAKE    0x04                      // RWA, enable BLE waking
+#define  RB_SLP_RTC_WAKE    0x08                      // RWA, enable RTC waking
+#define  RB_SLP_GPIO_WAKE   0x10                      // RWA, enable GPIO waking
+#define  RB_SLP_BAT_WAKE    0x20                      // RWA, enable BAT waking
+#define R8_SLP_POWER_CTRL   (*((PUINT8V)0x4000100F))  // RWA, peripherals power down control, SAM
+//#define  RB_SLP_USB_PWR_DN  0x01                      // RWA, enable USB power down
+#define  RB_SLP_ETH_PWR_DN  0x02                      // RWA, enable ETH PHY power down
+//#define  RB_SLP_BLE_PWR_DN  0x04                      // RWA, enable BLE power down
+#define  RB_SLP_ROM_PWR_DN  0x08                      // RWA, enable Flash ROM power down during halt
+#define  RB_SLP_CLK_RAMX    0x10                      // RWA, close main SRAM clock
+#define  RB_SLP_CLK_RAM2K   0x20                      // RWA, close retention 2KB SRAM clock
+
+/* System: I/O pin configuration register */
+#define R32_PIN_CONFIG      (*((PUINT32V)0x40001018)) // RW, I/O pin configuration
+#define R16_PIN_ALTERNATE   (*((PUINT16V)0x40001018)) // RW, function pin alternate configuration
+#define  RB_PIN_TMR0        0x01                      // RW, TMR0 alternate pin enable: 0=TMR0/PWM0/CAP0 on PA[3], 1=TMR0_/PWM0_/CAP0_ on PB[19]
+#define  RB_PIN_TMR1        0x02                      // RW, TMR1 alternate pin enable: 0=TMR1/PWM1/CAP1 on PA[10], 1=TMR1_/PWM1_/CAP1_ on PB[10]
+#define  RB_PIN_TMR2        0x04                      // RW, TMR2 alternate pin enable: 0=TMR2/PWM2/CAP2 on PA[11], 1=TMR2_/PWM2_/CAP2_ on PB[11]
+#define  RB_PIN_TMR3        0x08                      // RW, TMR3 alternate pin enable: 0=TMR3/PWM3/CAP3 on PA[2], 1=TMR3_/PWM3_/CAP3_ on PB[18]
+#define  RB_PIN_UART0       0x10                      // RW, RXD0/TXD0 alternate pin enable: 0=RXD0/TXD0 on PB[4]/PB[7], 1=RXD0_/TXD0_ on PA[15]/PA[14]
+#define  RB_PIN_UART1       0x20                      // RW, RXD1/TXD1 alternate pin enable: 0=RXD1/TXD1 on PA[8]/PA[9], 1=RXD1_/TXD1_ on PB[8]/PB[9]
+#define  RB_PIN_UART2       0x40                      // RW, RXD2/TXD2 alternate pin enable: 0=RXD2/TXD2 on PA[6]/PA[7], 1=RXD2_/TXD2_ on PB[22]/PB[23]
+#define  RB_PIN_UART3       0x80                      // RW, RXD3/TXD3 alternate pin enable: 0=RXD3/TXD3 on PA[4]/PA[5], 1=RXD3_/TXD3_ on PB[20]/PB[21]
+#define  RB_PIN_SPI0        0x100                     // RW, SCS/SCK0/MOSI/MISO alternate pin enable: 0=SCS/SCK0/MOSI/MISO on PA[12]/PA[13]/PA[14]/PA[15], 1=SCS_/SCK0_/MOSI_/MISO_ on PB[12]/PB[13]/PB[14]/PB[15]
+#define R16_PIN_ANALOG_IE   (*((PUINT16V)0x4000101A)) // RW, analog pin enable and digital input disable
+#define  RB_PIN_SEG0_3_IE   0x01                      // RW, LCD segment 0~3 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_SEG4_7_IE   0x02                      // RW, LCD segment 4~7 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_SEG8_11_IE  0x04                      // RW, LCD segment 8~11 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_SEG12_15_IE 0x08                      // RW, LCD segment 12~15 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_SEG16_19_IE 0x10                      // RW, LCD segment 16~19 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_SEG20_23_IE 0x20                      // RW, LCD segment 20~23 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ETH_IE      0x40                      // RW, ETH analog I/O enable and digital input disable: 0=analog I/O disable and digital input enable, 1=analog I/O enable and digital input disable
+#define  RB_PIN_USB_IE      0x80                      // RW, USB analog I/O enable: 0=analog I/O disable, 1=analog I/O enable
+#define  RB_PIN_ADC8_9_IE   0x0100                    // RW, ADC/TouchKey channel 9/8 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ADC6_7_IE   0x0200                    // RW, ADC/TouchKey channel 7/6 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ADC0_1_IE   0x0400                    // RW, ADC/TouchKey channel 0/1 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ADC10_11_IE 0x0800                    // RW, ADC/TouchKey channel 10/11 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ADC12_13_IE 0x1000                    // RW, ADC/TouchKey channel 12/13 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_XT32K_IE    0x2000                    // RW, external 32KHz oscillator digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ADC2_3_IE   0x4000                    // RW, ADC/TouchKey channel 2/3 digital input disable: 0=digital input enable, 1=digital input disable
+#define  RB_PIN_ADC4_5_IE   0x8000                    // RW, ADC/TouchKey channel 4/5 digital input disable: 0=digital input enable, 1=digital input disable
+
+/* System: parallel slave configuration register */
+#define R32_PARA_SLV_CFG    (*((PUINT32V)0x4000101C)) // RW, parallel slave configuration
+#define R8_SLV_CONFIG       (*((PUINT8V)0x4000101C))  // RW, parallel slave configuration
+#define  RB_SLV_ENABLE      0x01                      // RW, parallel slave enable
+#define  RB_SLV_IE_CMD      0x02                      // RW, enable interrupt for slave writing command event
+#define  RB_SLV_IE_WR       0x04                      // RW, enable interrupt for slave writing event
+#define  RB_SLV_IE_RD       0x08                      // RW, enable interrupt for slave reading event
+#define  RB_IF_SLV_CMD      0x20                      // RO, parallel slave command synchronous flag
+#define  RB_IF_SLV_WR       0x40                      // RW1, interrupt flag of parallel slave writing event
+#define  RB_IF_SLV_RD       0x80                      // RW1, interrupt flag of parallel slave reading event
+#define R8_SLV_RD_DATA      (*((PUINT8V)0x400010C8))  // RW, data for parallel slave read
+#define R8_SLV_RD_STAT      (*((PUINT8V)0x40001096))  // RW, status for parallel slave read
+#define R8_SLV_WR_DATA      (*((PUINT8V)0x40001097))  // RW, data or command from parallel slave write
+
+/* System: power management register */
+#define R32_POWER_MANAG     (*((PUINT32V)0x40001020)) // RWA, power management register, SAM
+#define R16_POWER_PLAN      (*((PUINT16V)0x40001020)) // RWA, power plan before sleep instruction, SAM
+#define  RB_PWR_RAM2K       0x02                      // RWA, power for retention 2KB SRAM
+#define  RB_PWR_CORE        0x04                      // RWA, power retention for core and base peripherals
+#define  RB_PWR_EXTEND      0x08                      // RWA, power retention for USB and BLE
+#define  RB_PWR_RAM14K      0x10                      // RWA, power for main SRAM
+#define  RB_PWR_SYS_EN      0x80                      // RWA, power for system
+#define  RB_PWR_LDO_EN      0x0100                    // RWA, LDO enable
+#define  RB_PWR_DCDC_EN     0x0200                    // RWA, DC/DC converter enable: 0=DC/DC disable and bypass, 1=DC/DC enable
+#define  RB_PWR_DCDC_PRE    0x0400                    // RWA, DC/DC converter pre-enable
+#define  RB_PWR_PLAN_EN     0x8000                    // RWA/WZ, power plan enable, auto clear after sleep executed
+#define  RB_PWR_MUST_0010   0x1000                    // RWA, must write 0010
+#define R8_AUX_POWER_ADJ    (*((PUINT8V)0x40001022))  // RWA, aux power adjust control, SAM
+#define  RB_ULPLDO_ADJ      0x0007                    // RWA, Ultra-Low-Power LDO voltage adjust
+
+/* System: battery detector register */
+#define R32_BATTERY_CTRL    (*((PUINT32V)0x40001024)) // RWA, battery voltage detector, SAM
+#define R8_BAT_DET_CTRL     (*((PUINT8V)0x40001024))  // RWA, battery voltage detector control, SAM
+#define  RB_BAT_DET_EN      0x01                      // RWA, battery voltage detector enable
+#define  RB_BAT_LOWER_IE    0x04                      // RWA, interrupt enable for battery lower voltage
+#define  RB_BAT_LOW_IE      0x08                      // RWA, interrupt enable for battery low voltage
+// request NMI interrupt if both RB_BAT_LOWER_IE and RB_BAT_LOW_IE enabled
+#define R8_BAT_DET_CFG      (*((PUINT8V)0x40001025))  // RWA, battery voltage detector configuration, SAM
+#define  RB_BAT_LOW_VTH     0x03                      // RWA, select threshold voltage of battery voltage low
+#define R8_BAT_STATUS       (*((PUINT8V)0x40001026))  // RO, battery status
+#define  RB_BAT_STAT_LOWER  0x01                      // RO, battery lower voltage status, high action
+#define  RB_BAT_STAT_LOW    0x02                      // RO, battery low voltage status, high action
+
+/* System: 32KHz oscillator control register */
+#define R32_OSC32K_CTRL     (*((PUINT32V)0x4000102C)) // RWA, 32KHz oscillator control, SAM
+#define R16_INT32K_TUNE     (*((PUINT16V)0x4000102C)) // RWA, internal 32KHz oscillator tune control, SAM
+#define  RB_INT32K_TUNE     0x03FF                    // RWA, internal 32KHz oscillator frequency tune
+#define R8_XT32K_TUNE       (*((PUINT8V)0x4000102E))  // RWA, external 32KHz oscillator tune control, SAM
+#define  RB_XT32K_I_TUNE    0x03                      // RWA, external 32KHz oscillator current tune: 00=75% current, 01=standard current, 10=150% current, 11=200% current
+#define  RB_XT32K_C_LOAD    0xF0                      // RWA, external 32KHz oscillator load capacitor tune: Cap = RB_XT32K_C_LOAD + 12pF
+#define R8_CK32K_CONFIG     (*((PUINT8V)0x4000102F))  // RWA, 32KHz oscillator configure
+#define  RB_CLK_XT32K_PON   0x01                      // RWA, external 32KHz oscillator power on
+#define  RB_CLK_INT32K_PON  0x02                      // RWA, internal 32KHz oscillator power on
+#define  RB_CLK_OSC32K_XT   0x04                      // RWA, 32KHz oscillator source selection: 0=RC, 1=XT
+#define  RB_32K_CLK_PIN     0x80                      // RO, 32KHz oscillator clock pin status
+
+/* System: real-time clock register */
+#define R32_RTC_CTRL        (*((PUINT32V)0x40001030)) // RWA, RTC control, SAM
+#define R8_RTC_FLAG_CTRL    (*((PUINT8V)0x40001030))  // RW, RTC flag and clear control
+#define  RB_RTC_TMR_CLR     0x10                      // RW, set 1 to clear RTC timer action flag, auto clear
+#define  RB_RTC_TRIG_CLR    0x20                      // RW, set 1 to clear RTC trigger action flag, auto clear
+#define  RB_RTC_TMR_FLAG    0x40                      // RO, RTC timer action flag
+#define  RB_RTC_TRIG_FLAG   0x80                      // RO, RTC trigger action flag
+#define R8_RTC_MODE_CTRL    (*((PUINT8V)0x40001031))  // RWA, RTC mode control, SAM
+#define  RB_RTC_TMR_MODE    0x07                      // RWA, RTC timer mode: 000=0.125S, 001=0.25S, 010=0.5S, 011=1S, 100=2S, 101=4S, 110=8S, 111=16S
+#define  RB_RTC_IGNORE_B0   0x08                      // RWA, force ignore bit0 for trigger mode: 0=compare bit0, 1=ignore bit0
+#define  RB_RTC_TMR_EN      0x10                      // RWA, RTC timer mode enable
+#define  RB_RTC_TRIG_EN     0x20                      // RWA, RTC trigger mode enable
+#define  RB_RTC_LOAD_LO     0x40                      // RWA, set 1 to load RTC count low word R32_RTC_CNT_32K, auto clear after loaded
+#define  RB_RTC_LOAD_HI     0x80                      // RWA, set 1 to load RTC count high word R32_RTC_CNT_DAY, auto clear after loaded
+#define R32_RTC_TRIG        (*((PUINT32V)0x40001034)) // RWA, RTC trigger value, SAM
+#define R32_RTC_CNT_32K     (*((PUINT32V)0x40001038)) // RO, RTC count based 32KHz
+#define R16_RTC_CNT_32K     (*((PUINT16V)0x40001038)) // RO, RTC count based 32KHz
+#define R16_RTC_CNT_2S      (*((PUINT16V)0x4000103A)) // RO, RTC count based 2 second
+#define R32_RTC_CNT_DAY     (*((PUINT32V)0x4000103C)) // RO, RTC count based one day, only low 14 bit
+
+/*System: Miscellaneous Control register */
+#define R32_MISC_CTRL       (*((PUINT32V)0x40001048)) // RWA, miscellaneous control register
+#define R8_CFG_FLASH        (*((PUINT8V)0x4000104A))  // RWA, Flash ROM configure register
+#define  RB_CFG_FLASH_X     0x0F                      // RWA, Flash ROM configure data, keep the value unchanged if write
+#define  RB_FLASH_BUSY_EN   0x80                      // RWA, enable ROM busy if burst reading: 1-enable(suggest), 0-disable
+#define R8_PLL_CONFIG       (*((PUINT8V)0x4000104B))  // RWA, PLL configuration control, SAM
+#define  RB_PLL_CFG_DAT     0x03                      // RWA, PLL configure data
+#define  RB_PLL_LOCKED      0x80                      // RO, indicate PLL locked
+
+/* System: 32MHz oscillator control register */
+#define R32_OSC32M_CTRL     (*((PUINT32V)0x4000104C)) // RWA, 32MHz oscillator control, SAM
+#define R8_INT32M_CALIB     (*((PUINT8V)0x4000104C))  // RWA, internal 32MHz oscillator tune control, SAM
+#define R8_XT32M_TUNE       (*((PUINT8V)0x4000104E))  // RWA, external 32MHz oscillator tune control, SAM
+#define  RB_XT32M_I_BIAS    0x03                      // RWA, external 32MHz oscillator bias current tune: 00=75% current, 01=standard current, 10=125% current, 11=150% current
+#define  RB_XT32M_C_LOAD    0x70                      // RWA, external 32MHz oscillator load capacitor tune: Cap = RB_XT32M_C_LOAD * 2 + 10pF
+
+/* System: oscillator frequency calibration register */
+#define R32_OSC_CALIB       (*((PUINT32V)0x40001050)) // RWA, oscillator frequency calibration, SAM
+#define R16_OSC_CAL_CNT     (*((PUINT16V)0x40001050)) // RO, system clock count value for 32KHz 5 cycles
+#define  RB_OSC_CAL_CNT     0x0FFF                    // RO, system clock count value for 32KHz 5 cycles
+#define R8_OSC_CAL_CTRL     (*((PUINT8V)0x40001052))  // RWA, oscillator frequency calibration control, SAM
+#define  RB_OSC_CNT_EN      0x01                      // RWA, calibration counter enable
+#define  RB_OSC_CNT_HALT    0x02                      // RO, calibration counter halt status: 0=counting, 1=halt for reading count value
+
+/* System: ADC and Touch-key register */
+#define R32_ADC_CTRL        (*((PUINT32V)0x40001058)) // RW, ADC control
+#define R8_ADC_CHANNEL      (*((PUINT8V)0x40001058))  // RW, ADC input channel selection
+#define  RB_ADC_CH_INX      0x0F                      // RW, ADC input channel index
+#define R8_ADC_CFG          (*((PUINT8V)0x40001059))  // RW, ADC configure
+#define  RB_ADC_POWER_ON    0x01                      // RW, ADC power control: 0=power down, 1=power on
+#define  RB_ADC_BUF_EN      0x02                      // RW, ADC input buffer enable
+#define  RB_ADC_DIFF_EN     0x04                      // RW, ADC input channel mode: 0=single-end, 1=differnetial
+#define  RB_ADC_OFS_TEST    0x08                      // RW, enable ADC offset test mode: 0=normal mode, 1=short port4 to test offset
+#define  RB_ADC_PGA_GAIN    0x30                      // RW, set ADC input PGA gain: 00=-12dB, 01=-6dB, 10=0dB, 11=6dB
+#define  RB_ADC_CLK_DIV     0xC0                      // RW, select ADC clock frequency: 00=3.2MHz, 01=2.67MHz, 10=5.33MHz, 11=4MHz
+#define R8_ADC_CONVERT      (*((PUINT8V)0x4000105A))  // RW, ADC convert control
+#define  RB_ADC_START       0x01                      // RW, ADC convert start control: 0=stop ADC convert, 1=start an ADC convert, auto clear
+#define  RB_ADC_EOC_X       0x80                      // RO, end of ADC conversion flag
+#define R8_TEM_SENSOR       (*((PUINT8V)0x4000105B))  // RW, temperature sensor control
+#define  RB_TEM_SEN_CALIB   0x07                      // RW, temperature sensor calibration
+#define  RB_TEM_SEN_PWR_ON  0x80                      // RW, temperature sensor power control: 0=power down, 1=power on
+#define R32_ADC_DATA        (*((PUINT32V)0x4000105C)) // RO, ADC data and status
+#define R16_ADC_DATA        (*((PUINT16V)0x4000105C)) // RO, ADC data
+#define  RB_ADC_DATA        0x0FFF                    // RO, ADC conversion data
+#define R8_ADC_INT_FLAG     (*((PUINT8V)0x4000105E))  // RO, ADC interrupt flag register
+#define  RB_ADC_IF_EOC      0x80                      // RO, ADC conversion interrupt flag: 0=free or converting, 1=end of conversion, interrupt action, write R8_ADC_CONVERT to clear flag
+#define R8_TKEY_CTRL        (*((PUINT8V)0x4000105A))  // RW, Touchkey capacity charge and discharge status
+#define  RB_TKEY_PWR_ON     0x08                      // RW, Touchkey power on: 0=power down, 1=power on
+#define  RB_TKEY_ACTION     0x10                      // RO, Touchkey action status: 0=free, 1=discharge or charge or ADC
+#define  RB_TKEY_CHG_ACT    0x20                      // RO, Touchkey capacity charge status: 0=free, 1=charge
+#define R8_TKEY_CNT         (*((PUINT8V)0x4000105F))  // WO, Touch-key charge and discharge count
+
+/* System: Flash ROM control register */
+#define R32_FLASH_DATA      (*((PUINT32V)0x40001800)) // RW, Flash ROM data
+#define R32_FLASH_ADDR      (*((PUINT32V)0x40001804)) // RW, Flash ROM address
+#define R32_FLASH_CTRL      (*((PUINT32V)0x40001808)) // RW, Flash ROM control and status
+#define R8_FLASH_COMMAND    (*((PUINT8V)0x40001808))  // WO, Flash ROM operation command
+#define ROM_CMD_PROG        0x9A                      // WO: Flash ROM word program operation command, for changing some ROM bit of a word from 1 to 0
+#define ROM_CMD_ERASE       0xA6                      // WO: Flash ROM sector erase operation command, for changing all ROM bit of 512Bytes from 0 to 1
+#define R8_FLASH_PROTECT    (*((PUINT8V)0x40001809))  // RW, Flash ROM protect control
+#define  RB_ROM_DATA_WE     0x04                      // RW, enable Flash ROM data area being erase/write: 0=writing protect, 1=enable program and erase
+#define  RB_ROM_CODE_WE     0x08                      // RW, enable Flash ROM code area being erase/write: 0=writing protect, 1=enable program and erase
+#define  RB_ROM_WE_MUST_10  0x80                      // RW, must write 10
+#define R16_FLASH_STATUS    (*((PUINT16V)0x4000180A))  // RO, Flash ROM operation status
+#define R8_FLASH_STATUS     (*((PUINT8V)0x4000180A))  // RO, Flash ROM operation status
+#define  RB_ROM_CMD_TOUT    0x01                      // RO, Flash ROM operation result: 0=success, 1=operation time out
+#define  RB_ROM_CMD_ERR     0x02                      // RO, Flash ROM operation command error flag: 0=command accepted, 1=unknown command
+#define  RB_ROM_ADDR_OK     0x40                      // RO, Flash ROM erase/write operation address valid flag, can be reviewed before or after operation: 0=invalid parameter, 1=address valid
+#define  RB_ROM_READ_FREE   0x100                     // RO, indicate protected status of Flash ROM code and data: 0=reading protect, 1=enable read by external programmer
+
+/* System: GPIO interrupt control register */
+#define R32_GPIO_INT_EN     (*((PUINT32V)0x40001090)) // RW, GPIO interrupt enable
+#define R16_PA_INT_EN       (*((PUINT16V)0x40001090)) // RW, GPIO PA interrupt enable
+#define R16_PB_INT_EN       (*((PUINT16V)0x40001092)) // RW, GPIO PB interrupt enable
+#define R32_GPIO_INT_MODE   (*((PUINT32V)0x40001094)) // RW, GPIO interrupt mode: 0=level action, 1=edge action
+#define R16_PA_INT_MODE     (*((PUINT16V)0x40001094)) // RW, GPIO PA interrupt mode: 0=level action, 1=edge action
+#define R16_PB_INT_MODE     (*((PUINT16V)0x40001096)) // RW, GPIO PB interrupt mode: 0=level action, 1=edge action
+#define R32_GPIO_INT_IF     (*((PUINT32V)0x4000109C)) // RW1, GPIO interrupt flag
+#define R16_PA_INT_IF       (*((PUINT16V)0x4000109C)) // RW1, GPIO PA interrupt flag
+#define R16_PB_INT_IF       (*((PUINT16V)0x4000109E)) // RW1, GPIO PB interrupt flag
+
+/* GPIO PA register */
+#define R32_PA_DIR          (*((PUINT32V)0x400010A0)) // RW, GPIO PA I/O direction: 0=in, 1=out
+#define R8_PA_DIR_0         (*((PUINT8V)0x400010A0))  // RW, GPIO PA I/O direction byte 0
+#define R8_PA_DIR_1         (*((PUINT8V)0x400010A1))  // RW, GPIO PA I/O direction byte 1
+#define R32_PA_PIN          (*((PUINT32V)0x400010A4)) // RO, GPIO PA input
+#define R8_PA_PIN_0         (*((PUINT8V)0x400010A4))  // RO, GPIO PA input byte 0
+#define R8_PA_PIN_1         (*((PUINT8V)0x400010A5))  // RO, GPIO PA input byte 1
+#define R32_PA_OUT          (*((PUINT32V)0x400010A8)) // RW, GPIO PA output
+#define R8_PA_OUT_0         (*((PUINT8V)0x400010A8))  // RW, GPIO PA output byte 0
+#define R8_PA_OUT_1         (*((PUINT8V)0x400010A9))  // RW, GPIO PA output byte 1
+#define R32_PA_CLR          (*((PUINT32V)0x400010AC)) // WZ, GPIO PA clear output: 0=keep, 1=clear
+#define R8_PA_CLR_0         (*((PUINT8V)0x400010AC))  // WZ, GPIO PA clear output byte 0
+#define R8_PA_CLR_1         (*((PUINT8V)0x400010AD))  // WZ, GPIO PA clear output byte 1
+#define R32_PA_PU           (*((PUINT32V)0x400010B0)) // RW, GPIO PA pullup resistance enable
+#define R8_PA_PU_0          (*((PUINT8V)0x400010B0))  // RW, GPIO PA pullup resistance enable byte 0
+#define R8_PA_PU_1          (*((PUINT8V)0x400010B1))  // RW, GPIO PA pullup resistance enable byte 1
+#define R32_PA_PD_DRV       (*((PUINT32V)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output
+#define R8_PA_PD_DRV_0      (*((PUINT8V)0x400010B4))  // RW, PA pulldown for input or PA driving capability for output byte 0
+#define R8_PA_PD_DRV_1      (*((PUINT8V)0x400010B5))  // RW, PA pulldown for input or PA driving capability for output byte 1
+
+/* GPIO PB register */
+#define R32_PB_DIR          (*((PUINT32V)0x400010C0)) // RW, GPIO PB I/O direction: 0=in, 1=out
+#define R8_PB_DIR_0         (*((PUINT8V)0x400010C0))  // RW, GPIO PB I/O direction byte 0
+#define R8_PB_DIR_1         (*((PUINT8V)0x400010C1))  // RW, GPIO PB I/O direction byte 1
+#define R8_PB_DIR_2         (*((PUINT8V)0x400010C2))  // RW, GPIO PB I/O direction byte 2
+#define R32_PB_PIN          (*((PUINT32V)0x400010C4)) // RO, GPIO PB input
+#define R8_PB_PIN_0         (*((PUINT8V)0x400010C4))  // RO, GPIO PB input byte 0
+#define R8_PB_PIN_1         (*((PUINT8V)0x400010C5))  // RO, GPIO PB input byte 1
+#define R8_PB_PIN_2         (*((PUINT8V)0x400010C6))  // RO, GPIO PB input byte 2
+#define R32_PB_OUT          (*((PUINT32V)0x400010C8)) // RW, GPIO PB output
+#define R8_PB_OUT_0         (*((PUINT8V)0x400010C8))  // RW, GPIO PB output byte 0
+#define R8_PB_OUT_1         (*((PUINT8V)0x400010C9))  // RW, GPIO PB output byte 1
+#define R8_PB_OUT_2         (*((PUINT8V)0x400010CA))  // RW, GPIO PB output byte 2
+#define R32_PB_CLR          (*((PUINT32V)0x400010CC)) // WZ, GPIO PB clear output: 0=keep, 1=clear
+#define R8_PB_CLR_0         (*((PUINT8V)0x400010CC))  // WZ, GPIO PB clear output byte 0
+#define R8_PB_CLR_1         (*((PUINT8V)0x400010CD))  // WZ, GPIO PB clear output byte 1
+#define R8_PB_CLR_2         (*((PUINT8V)0x400010CE))  // WZ, GPIO PB clear output byte 2
+#define R32_PB_PU           (*((PUINT32V)0x400010D0)) // RW, GPIO PB pullup resistance enable
+#define R8_PB_PU_0          (*((PUINT8V)0x400010D0))  // RW, GPIO PB pullup resistance enable byte 0
+#define R8_PB_PU_1          (*((PUINT8V)0x400010D1))  // RW, GPIO PB pullup resistance enable byte 1
+#define R8_PB_PU_2          (*((PUINT8V)0x400010D2))  // RW, GPIO PB pullup resistance enable byte 2
+#define R32_PB_PD_DRV       (*((PUINT32V)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output
+#define R8_PB_PD_DRV_0      (*((PUINT8V)0x400010D4))  // RW, PB pulldown for input or PB driving capability for output byte 0
+#define R8_PB_PD_DRV_1      (*((PUINT8V)0x400010D5))  // RW, PB pulldown for input or PB driving capability for output byte 1
+#define R8_PB_PD_DRV_2      (*((PUINT8V)0x400010D6))  // RW, PB pulldown for input or PB driving capability for output byte 2
+
+/* GPIO register address offset and bit define */
+#define BA_PA               ((PUINT8V)0x400010A0)     // point GPIO PA base address
+#define BA_PB               ((PUINT8V)0x400010C0)     // point GPIO PB base address
+#define GPIO_DIR            0x00
+#define GPIO_DIR_0          0x00
+#define GPIO_DIR_1          0x01
+#define GPIO_DIR_2          0x02
+#define GPIO_PIN            0x04
+#define GPIO_PIN_0          0x04
+#define GPIO_PIN_1          0x05
+#define GPIO_PIN_2          0x06
+#define GPIO_OUT            0x08
+#define GPIO_OUT_0          0x08
+#define GPIO_OUT_1          0x09
+#define GPIO_OUT_2          0x0A
+#define GPIO_CLR            0x0C
+#define GPIO_CLR_0          0x0C
+#define GPIO_CLR_1          0x0D
+#define GPIO_CLR_2          0x0E
+#define GPIO_PU             0x10
+#define GPIO_PU_0           0x10
+#define GPIO_PU_1           0x11
+#define GPIO_PU_2           0x12
+#define GPIO_PD_DRV         0x14
+#define GPIO_PD_DRV_0       0x14
+#define GPIO_PD_DRV_1       0x15
+#define GPIO_PD_DRV_2       0x16
+
+/* GPIO alias name */
+#define  bSCK1              (1<<0)                    // PA0
+#define  bPADDR             (1<<0)                    // PA0
+#define  bLED0              (1<<0)                    // PA0
+#define  bCOM0              (1<<0)                    // PA0
+#define  bSDO               (1<<1)                    // PA1
+#define  bMOSI1             bSDO
+#define  bPCS               (1<<1)                    // PA1
+#define  bLED1              (1<<1)                    // PA1
+#define  bCOM1              (1<<1)                    // PA1
+#define  bTMR3              (1<<2)                    // PA2
+#define  bCAP3              bTMR3
+#define  bPWM3              bTMR3
+#define  bSDI               (1<<2)                    // PA2
+#define  bMISO1             bSDI
+#define  bLED2              (1<<2)                    // PA2
+#define  bCOM2              (1<<2)                    // PA2
+#define  bTMR0              (1<<3)                    // PA3
+#define  bCAP0              bTMR0
+#define  bPWM0              bTMR0
+#define  bPINT              (1<<3)                    // PA3
+#define  bLED3              (1<<3)                    // PA3
+#define  bCOM3              (1<<3)                    // PA3
+#define  bUBUS1             (1<<4)                    // PA4
+#define  bAIN0              (1<<4)                    // PA4
+#define  bRXD3              (1<<4)                    // PA4
+#define  bLEDC              (1<<4)                    // PA4
+#define  bUCC1              (1<<5)                    // PA5
+#define  bAIN1              (1<<5)                    // PA5
+#define  bTXD3              (1<<5)                    // PA5
+#define  bUCC2              (1<<6)                    // PA6
+#define  bAIN2              (1<<6)                    // PA6
+#define  bRXD2              (1<<6)                    // PA6
+#define  bPWM4              (1<<6)                    // PA6
+#define  bTIN3              (1<<7)                    // PA7
+#define  bTXD2              (1<<7)                    // PA7
+#define  bPWM5              (1<<7)                    // PA7
+#define  bTIN4              (1<<8)                    // PA8
+#define  bRXD1              (1<<8)                    // PA8
+#define  bTIN5              (1<<9)                    // PA9
+#define  bTXD1              (1<<9)                    // PA9
+#define  bX32KI             (1<<10)                   // PA10
+#define  bTMR1              (1<<10)                   // PA10
+#define  bCAP1              bTMR1
+#define  bPWM1              bTMR1
+#define  bX32KO             (1<<11)                   // PA11
+#define  bTMR2              (1<<11)                   // PA11
+#define  bCAP2              bTMR2
+#define  bPWM2              bTMR2
+#define  bTIN2              (1<<12)                   // PA12
+#define  bSCS               (1<<12)                   // PA12
+#define  bTIN1              (1<<13)                   // PA13
+#define  bSCK0              (1<<13)                   // PA13
+#define  bUBUS2             (1<<14)                   // PA14
+#define  bAIN3              (1<<14)                   // PA14
+#define  bMOSI              (1<<14)                   // PA14
+#define  bTXD0_             (1<<14)                   // PA14
+#define  bTIN0              (1<<15)                   // PA15
+#define  bMISO              (1<<15)                   // PA15
+#define  bRXD0_             (1<<15)                   // PA15
+#define  bCTS               (1<<0)                    // PB0
+#define  bPWM6              (1<<0)                    // PB0
+#define  bSEG0              (1<<0)                    // PB0
+#define  bDSR               (1<<1)                    // PB1
+#define  bPWM7              (1<<1)                    // PB1
+#define  bSEG1              (1<<1)                    // PB1
+#define  bRI                (1<<2)                    // PB2
+#define  bPWM8              (1<<2)                    // PB2
+#define  bSEG2              (1<<2)                    // PB2
+#define  bDCD               (1<<3)                    // PB3
+#define  bPWM9              (1<<3)                    // PB3
+#define  bSEG3              (1<<3)                    // PB3
+#define  bRXD0              (1<<4)                    // PB4
+#define  bSEG4              (1<<4)                    // PB4
+#define  bDTR               (1<<5)                    // PB5
+#define  bSEG5              (1<<5)                    // PB5
+#define  bRTS               (1<<6)                    // PB6
+#define  bSEG6              (1<<6)                    // PB6
+#define  bTXD0              (1<<7)                    // PB7
+#define  bSEG7              (1<<7)                    // PB7
+#define  bPBUS              (0xFF<<0)                 // PB0~PB7
+#define  bTIN8              (1<<8)                    // PB8
+#define  bRXD1_             (1<<8)                    // PB8
+#define  bPRD               (1<<8)                    // PB8
+#define  bSEG8              (1<<8)                    // PB8
+#define  bTIN9              (1<<9)                    // PB9
+#define  bTXD1_             (1<<9)                    // PB9
+#define  bPWR               (1<<9)                    // PB9
+#define  bSEG9              (1<<9)                    // PB9
+#define  bUDM               (1<<10)                   // PB10
+#define  bTMR1_             (1<<10)                   // PB10
+#define  bCAP1_             bTMR1_
+#define  bPWM1_             bTMR1_
+#define  bSEG10             (1<<10)                   // PB10
+#define  bUDP               (1<<11)                   // PB11
+#define  bTMR2_             (1<<11)                   // PB11
+#define  bCAP2_             bTMR2_
+#define  bPWM2_             bTMR2_
+#define  bSEG11             (1<<11)                   // PB11
+#define  bETM               (1<<12)                   // PB12
+#define  bSCS_              (1<<12)                   // PB12
+#define  bSEG12             (1<<12)                   // PB12
+#define  bETP               (1<<13)                   // PB13
+#define  bSCK0_             (1<<13)                   // PB13
+#define  bSEG13             (1<<13)                   // PB13
+#define  bERM               (1<<14)                   // PB14
+#define  bMOSI_             (1<<14)                   // PB14
+#define  bPWM10             (1<<14)                   // PB14
+#define  bSEG14             (1<<14)                   // PB14
+#define  bERP               (1<<15)                   // PB15
+#define  bMISO_             (1<<15)                   // PB15
+#define  bSEG15             (1<<15)                   // PB15
+#define  bTIN6              (1<<16)                   // PB16
+#define  bTIO               (1<<16)                   // PB16
+#define  bSEG16             (1<<16)                   // PB16
+#define  bTIN7              (1<<17)                   // PB17
+#define  bTCK               (1<<17)                   // PB17
+#define  bSEG17             (1<<17)                   // PB17
+#define  bTMR3_             (1<<18)                   // PB18
+#define  bCAP3_             bTMR3_
+#define  bPWM3_             bTMR3_
+#define  bSEG18             (1<<18)                   // PB18
+#define  bTMR0_             (1<<19)                   // PB19
+#define  bCAP0_             bTMR0_
+#define  bPWM0_             bTMR0_
+#define  bSEG19             (1<<19)                   // PB19
+#define  bRXD3_             (1<<20)                   // PB20
+#define  bSEG20             (1<<20)                   // PB20
+#define  bTXD3_             (1<<21)                   // PB21
+#define  bSEG21             (1<<21)                   // PB21
+#define  bRXD2_             (1<<22)                   // PB22
+#define  bSEG22             (1<<22)                   // PB22
+#define  bRST               (1<<23)                   // PB23
+#define  bTXD2_             (1<<23)                   // PB23
+#define  bPWM11             (1<<23)                   // PB23
+#define  bSEG23             (1<<23)                   // PB23
+
+/* Timer0 register */
+#define R32_TMR0_CONTROL    (*((PUINT32V)0x40002000)) // RW, TMR0 control
+#define R8_TMR0_CTRL_MOD    (*((PUINT8V)0x40002000))  // RW, TMR0 mode control
+#define R8_TMR0_INTER_EN    (*((PUINT8V)0x40002002))  // RW, TMR0 interrupt enable
+#define R32_TMR0_STATUS     (*((PUINT32V)0x40002004)) // RW, TMR0 status
+#define R8_TMR0_INT_FLAG    (*((PUINT8V)0x40002006))  // RW1, TMR0 interrupt flag
+#define R8_TMR0_FIFO_COUNT  (*((PUINT8V)0x40002007))  // RO, TMR0 FIFO count status
+#define R32_TMR0_COUNT      (*((PUINT32V)0x40002008)) // RO, TMR0 current count
+#define R16_TMR0_COUNT      (*((PUINT16V)0x40002008)) // RO, TMR0 current count
+#define R8_TMR0_COUNT       (*((PUINT8V)0x40002008))  // RO, TMR0 current count
+#define R32_TMR0_CNT_END    (*((PUINT32V)0x4000200C)) // RW, TMR0 end count value, only low 26 bit
+#define R32_TMR0_FIFO       (*((PUINT32V)0x40002010)) // RO/WO, TMR0 FIFO register, only low 26 bit
+#define R16_TMR0_FIFO       (*((PUINT16V)0x40002010)) // RO/WO, TMR0 FIFO register
+#define R8_TMR0_FIFO        (*((PUINT8V)0x40002010))  // RO/WO, TMR0 FIFO register
+
+/* Timer1 register */
+#define R32_TMR1_CONTROL    (*((PUINT32V)0x40002400)) // RW, TMR1 control
+#define R8_TMR1_CTRL_MOD    (*((PUINT8V)0x40002400))  // RW, TMR1 mode control
+#define R8_TMR1_CTRL_DMA    (*((PUINT8V)0x40002401))  // RW, TMR1 DMA control
+#define R8_TMR1_INTER_EN    (*((PUINT8V)0x40002402))  // RW, TMR1 interrupt enable
+#define R32_TMR1_STATUS     (*((PUINT32V)0x40002404)) // RW, TMR1 status
+#define R8_TMR1_INT_FLAG    (*((PUINT8V)0x40002406))  // RW1, TMR1 interrupt flag
+#define R8_TMR1_FIFO_COUNT  (*((PUINT8V)0x40002407))  // RO, TMR1 FIFO count status
+#define R32_TMR1_COUNT      (*((PUINT32V)0x40002408)) // RO, TMR1 current count
+#define R16_TMR1_COUNT      (*((PUINT16V)0x40002408)) // RO, TMR1 current count
+#define R8_TMR1_COUNT       (*((PUINT8V)0x40002408))  // RO, TMR1 current count
+#define R32_TMR1_CNT_END    (*((PUINT32V)0x4000240C)) // RW, TMR1 end count value, only low 26 bit
+#define R32_TMR1_FIFO       (*((PUINT32V)0x40002410)) // RO/WO, TMR1 FIFO register, only low 26 bit
+#define R16_TMR1_FIFO       (*((PUINT16V)0x40002410)) // RO/WO, TMR1 FIFO register
+#define R8_TMR1_FIFO        (*((PUINT8V)0x40002410))  // RO/WO, TMR1 FIFO register
+#define R32_TMR1_DMA_NOW    (*((PUINT32V)0x40002414)) // RW, TMR1 DMA current address
+#define R16_TMR1_DMA_NOW    (*((PUINT16V)0x40002414)) // RW, TMR1 DMA current address
+#define R32_TMR1_DMA_BEG    (*((PUINT32V)0x40002418)) // RW, TMR1 DMA begin address
+#define R16_TMR1_DMA_BEG    (*((PUINT16V)0x40002418)) // RW, TMR1 DMA begin address
+#define R32_TMR1_DMA_END    (*((PUINT32V)0x4000241C)) // RW, TMR1 DMA end address
+#define R16_TMR1_DMA_END    (*((PUINT16V)0x4000241C)) // RW, TMR1 DMA end address
+
+/* Timer2 register */
+#define R32_TMR2_CONTROL    (*((PUINT32V)0x40002800)) // RW, TMR2 control
+#define R8_TMR2_CTRL_MOD    (*((PUINT8V)0x40002800))  // RW, TMR2 mode control
+#define R8_TMR2_CTRL_DMA    (*((PUINT8V)0x40002801))  // RW, TMR2 DMA control
+#define R8_TMR2_INTER_EN    (*((PUINT8V)0x40002802))  // RW, TMR2 interrupt enable
+#define R32_TMR2_STATUS     (*((PUINT32V)0x40002804)) // RW, TMR2 status
+#define R8_TMR2_INT_FLAG    (*((PUINT8V)0x40002806))  // RW1, TMR2 interrupt flag
+#define R8_TMR2_FIFO_COUNT  (*((PUINT8V)0x40002807))  // RO, TMR2 FIFO count status
+#define R32_TMR2_COUNT      (*((PUINT32V)0x40002808)) // RO, TMR2 current count
+#define R16_TMR2_COUNT      (*((PUINT16V)0x40002808)) // RO, TMR2 current count
+#define R8_TMR2_COUNT       (*((PUINT8V)0x40002808))  // RO, TMR2 current count
+#define R32_TMR2_CNT_END    (*((PUINT32V)0x4000280C)) // RW, TMR2 end count value, only low 26 bit
+#define R32_TMR2_FIFO       (*((PUINT32V)0x40002810)) // RO/WO, TMR2 FIFO register, only low 26 bit
+#define R16_TMR2_FIFO       (*((PUINT16V)0x40002810)) // RO/WO, TMR2 FIFO register
+#define R8_TMR2_FIFO        (*((PUINT8V)0x40002810))  // RO/WO, TMR2 FIFO register
+#define R32_TMR2_DMA_NOW    (*((PUINT32V)0x40002814)) // RW, TMR2 DMA current address
+#define R16_TMR2_DMA_NOW    (*((PUINT16V)0x40002814)) // RW, TMR2 DMA current address
+#define R32_TMR2_DMA_BEG    (*((PUINT32V)0x40002818)) // RW, TMR2 DMA begin address
+#define R16_TMR2_DMA_BEG    (*((PUINT16V)0x40002818)) // RW, TMR2 DMA begin address
+#define R32_TMR2_DMA_END    (*((PUINT32V)0x4000281C)) // RW, TMR2 DMA end address
+#define R16_TMR2_DMA_END    (*((PUINT16V)0x4000281C)) // RW, TMR2 DMA end address
+
+/* Timer3 register */
+#define R32_TMR3_CONTROL    (*((PUINT32V)0x40002C00)) // RW, TMR3 control
+#define R8_TMR3_CTRL_MOD    (*((PUINT8V)0x40002C00))  // RW, TMR3 mode control
+#define R8_TMR3_INTER_EN    (*((PUINT8V)0x40002C02))  // RW, TMR3 interrupt enable
+#define R32_TMR3_STATUS     (*((PUINT32V)0x40002C04)) // RW, TMR3 status
+#define R8_TMR3_INT_FLAG    (*((PUINT8V)0x40002C06))  // RW1, TMR3 interrupt flag
+#define R8_TMR3_FIFO_COUNT  (*((PUINT8V)0x40002C07))  // RO, TMR3 FIFO count status
+#define R32_TMR3_COUNT      (*((PUINT32V)0x40002C08)) // RO, TMR3 current count
+#define R16_TMR3_COUNT      (*((PUINT16V)0x40002C08)) // RO, TMR3 current count
+#define R8_TMR3_COUNT       (*((PUINT8V)0x40002C08))  // RO, TMR3 current count
+#define R32_TMR3_CNT_END    (*((PUINT32V)0x40002C0C)) // RW, TMR3 end count value, only low 26 bit
+#define R32_TMR3_FIFO       (*((PUINT32V)0x40002C10)) // RO/WO, TMR3 FIFO register, only low 26 bit
+#define R16_TMR3_FIFO       (*((PUINT16V)0x40002C10)) // RO/WO, TMR3 FIFO register
+#define R8_TMR3_FIFO        (*((PUINT8V)0x40002C10))  // RO/WO, TMR3 FIFO register
+
+/* Timer register address offset and bit define */
+#define TMR_FIFO_SIZE       8                         // timer FIFO size (depth)
+#define BA_TMR0             ((PUINT8V)0x40002000)     // point TMR0 base address
+#define BA_TMR1             ((PUINT8V)0x40002400)     // point TMR1 base address
+#define BA_TMR2             ((PUINT8V)0x40002800)     // point TMR2 base address
+#define BA_TMR3             ((PUINT8V)0x40002C00)     // point TMR3 base address
+#define TMR_CTRL_MOD        0
+#define  RB_TMR_MODE_IN     0x01                      // RW, timer in mode: 0=timer/PWM, 1=capture/count
+#define  RB_TMR_ALL_CLEAR   0x02                      // RW, force clear timer FIFO and count
+#define  RB_TMR_COUNT_EN    0x04                      // RW, timer count enable
+#define  RB_TMR_OUT_EN      0x08                      // RW, timer output enable
+#define  RB_TMR_OUT_POLAR   0x10                      // RW, timer PWM output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_TMR_CAP_COUNT   0x10                      // RW, count sub-mode if RB_TMR_MODE_IN=1: 0=capture, 1=count
+#define  RB_TMR_PWM_REPEAT  0xC0                      // RW, timer PWM repeat mode: 00=1, 01=4, 10=8, 11-16
+#define  RB_TMR_CAP_EDGE    0xC0                      // RW, timer capture edge mode: 00=disable, 01=edge change, 10=fall to fall, 11-rise to rise
+#define TMR_CTRL_DMA        1
+#define  RB_TMR_DMA_ENABLE  0x01                      // RW, timer1/2 DMA enable
+#define  RB_TMR_DMA_LOOP    0x04                      // RW, timer1/2 DMA address loop enable
+#define TMR_INTER_EN        2
+#define  RB_TMR_IE_CYC_END  0x01                      // RW, enable interrupt for timer capture count timeout or PWM cycle end
+#define  RB_TMR_IE_DATA_ACT 0x02                      // RW, enable interrupt for timer capture input action or PWM trigger
+#define  RB_TMR_IE_FIFO_HF  0x04                      // RW, enable interrupt for timer FIFO half (capture fifo >=4 or PWM fifo <=3)
+#define  RB_TMR_IE_DMA_END  0x08                      // RW, enable interrupt for timer1/2 DMA completion
+#define  RB_TMR_IE_FIFO_OV  0x10                      // RW, enable interrupt for timer FIFO overflow
+#define TMR_INT_FLAG        6
+#define  RB_TMR_IF_CYC_END  0x01                      // RW1, interrupt flag for timer capture count timeout or PWM cycle end
+#define  RB_TMR_IF_DATA_ACT 0x02                      // RW1, interrupt flag for timer capture input action or PWM trigger
+#define  RB_TMR_IF_FIFO_HF  0x04                      // RW1, interrupt flag for timer FIFO half (capture fifo >=4 or PWM fifo <=3)
+#define  RB_TMR_IF_DMA_END  0x08                      // RW1, interrupt flag for timer1/2 DMA completion
+#define  RB_TMR_IF_FIFO_OV  0x10                      // RW1, interrupt flag for timer FIFO overflow
+#define TMR_FIFO_COUNT      7
+#define TMR_COUNT           0x08
+#define TMR_CNT_END         0x0C
+#define TMR_FIFO            0x10
+#define TMR_DMA_NOW         0x14
+#define TMR_DMA_BEG         0x18
+#define TMR_DMA_END         0x1C
+
+/* UART0 register */
+#define R32_UART0_CTRL      (*((PUINT32V)0x40003000)) // RW, UART0 control
+#define R8_UART0_MCR        (*((PUINT8V)0x40003000))  // RW, UART0 modem control
+#define R8_UART0_IER        (*((PUINT8V)0x40003001))  // RW, UART0 interrupt enable
+#define R8_UART0_FCR        (*((PUINT8V)0x40003002))  // RW, UART0 FIFO control
+#define R8_UART0_LCR        (*((PUINT8V)0x40003003))  // RW, UART0 line control
+#define R32_UART0_STAT      (*((PUINT32V)0x40003004)) // RO, UART0 status
+#define R8_UART0_IIR        (*((PUINT8V)0x40003004))  // RO, UART0 interrupt identification
+#define R8_UART0_LSR        (*((PUINT8V)0x40003005))  // RO, UART0 line status
+#define R8_UART0_MSR        (*((PUINT8V)0x40003006))  // RO, UART0 modem status
+#define R32_UART0_FIFO      (*((PUINT32V)0x40003008)) // RW, UART0 data or FIFO port
+#define R8_UART0_RBR        (*((PUINT8V)0x40003008))  // RO, UART0 receiver buffer, receiving byte
+#define R8_UART0_THR        (*((PUINT8V)0x40003008))  // WO, UART0 transmitter holding, transmittal byte
+#define R8_UART0_RFC        (*((PUINT8V)0x4000300A))  // RO, UART0 receiver FIFO count
+#define R8_UART0_TFC        (*((PUINT8V)0x4000300B))  // RO, UART0 transmitter FIFO count
+#define R32_UART0_SETUP     (*((PUINT32V)0x4000300C)) // RW, UART0 setup
+#define R16_UART0_DL        (*((PUINT16V)0x4000300C)) // RW, UART0 divisor latch
+#define R8_UART0_DLL        (*((PUINT8V)0x4000300C))  // RW, UART0 divisor latch LSB byte
+#define R8_UART0_DLM        (*((PUINT8V)0x4000300D))  // RW, UART0 divisor latch MSB byte
+#define R8_UART0_DIV        (*((PUINT8V)0x4000300E))  // RW, UART0 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
+#define R8_UART0_ADR        (*((PUINT8V)0x4000300F))  // RW, UART0 slave address: 0xFF=disable, other=enable
+
+/* UART1 register */
+#define R32_UART1_CTRL      (*((PUINT32V)0x40003400)) // RW, UART1 control
+#define R8_UART1_MCR        (*((PUINT8V)0x40003400))  // RW, UART1 modem control
+#define R8_UART1_IER        (*((PUINT8V)0x40003401))  // RW, UART1 interrupt enable
+#define R8_UART1_FCR        (*((PUINT8V)0x40003402))  // RW, UART1 FIFO control
+#define R8_UART1_LCR        (*((PUINT8V)0x40003403))  // RW, UART1 line control
+#define R32_UART1_STAT      (*((PUINT32V)0x40003404)) // RO, UART1 status
+#define R8_UART1_IIR        (*((PUINT8V)0x40003404))  // RO, UART1 interrupt identification
+#define R8_UART1_LSR        (*((PUINT8V)0x40003405))  // RO, UART1 line status
+#define R32_UART1_FIFO      (*((PUINT32V)0x40003408)) // RW, UART1 data or FIFO port
+#define R8_UART1_RBR        (*((PUINT8V)0x40003408))  // RO, UART1 receiver buffer, receiving byte
+#define R8_UART1_THR        (*((PUINT8V)0x40003408))  // WO, UART1 transmitter holding, transmittal byte
+#define R8_UART1_RFC        (*((PUINT8V)0x4000340A))  // RO, UART1 receiver FIFO count
+#define R8_UART1_TFC        (*((PUINT8V)0x4000340B))  // RO, UART1 transmitter FIFO count
+#define R32_UART1_SETUP     (*((PUINT32V)0x4000340C)) // RW, UART1 setup
+#define R16_UART1_DL        (*((PUINT16V)0x4000340C)) // RW, UART1 divisor latch
+#define R8_UART1_DLL        (*((PUINT8V)0x4000340C))  // RW, UART1 divisor latch LSB byte
+#define R8_UART1_DLM        (*((PUINT8V)0x4000340D))  // RW, UART1 divisor latch MSB byte
+#define R8_UART1_DIV        (*((PUINT8V)0x4000340E))  // RW, UART1 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
+
+/* UART2 register */
+#define R32_UART2_CTRL      (*((PUINT32V)0x40003800)) // RW, UART2 control
+#define R8_UART2_MCR        (*((PUINT8V)0x40003800))  // RW, UART2 modem control
+#define R8_UART2_IER        (*((PUINT8V)0x40003801))  // RW, UART2 interrupt enable
+#define R8_UART2_FCR        (*((PUINT8V)0x40003802))  // RW, UART2 FIFO control
+#define R8_UART2_LCR        (*((PUINT8V)0x40003803))  // RW, UART2 line control
+#define R32_UART2_STAT      (*((PUINT32V)0x40003804)) // RO, UART2 status
+#define R8_UART2_IIR        (*((PUINT8V)0x40003804))  // RO, UART2 interrupt identification
+#define R8_UART2_LSR        (*((PUINT8V)0x40003805))  // RO, UART2 line status
+#define R32_UART2_FIFO      (*((PUINT32V)0x40003808)) // RW, UART2 data or FIFO port
+#define R8_UART2_RBR        (*((PUINT8V)0x40003808))  // RO, UART2 receiver buffer, receiving byte
+#define R8_UART2_THR        (*((PUINT8V)0x40003808))  // WO, UART2 transmitter holding, transmittal byte
+#define R8_UART2_RFC        (*((PUINT8V)0x4000380A))  // RO, UART2 receiver FIFO count
+#define R8_UART2_TFC        (*((PUINT8V)0x4000380B))  // RO, UART2 transmitter FIFO count
+#define R32_UART2_SETUP     (*((PUINT32V)0x4000380C)) // RW, UART2 setup
+#define R16_UART2_DL        (*((PUINT16V)0x4000380C)) // RW, UART2 divisor latch
+#define R8_UART2_DLL        (*((PUINT8V)0x4000380C))  // RW, UART2 divisor latch LSB byte
+#define R8_UART2_DLM        (*((PUINT8V)0x4000380D))  // RW, UART2 divisor latch MSB byte
+#define R8_UART2_DIV        (*((PUINT8V)0x4000380E))  // RW, UART2 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
+
+/* UART3 register */
+#define R32_UART3_CTRL      (*((PUINT32V)0x40003C00)) // RW, UART3 control
+#define R8_UART3_MCR        (*((PUINT8V)0x40003C00))  // RW, UART3 modem control
+#define R8_UART3_IER        (*((PUINT8V)0x40003C01))  // RW, UART3 interrupt enable
+#define R8_UART3_FCR        (*((PUINT8V)0x40003C02))  // RW, UART3 FIFO control
+#define R8_UART3_LCR        (*((PUINT8V)0x40003C03))  // RW, UART3 line control
+#define R32_UART3_STAT      (*((PUINT32V)0x40003C04)) // RO, UART3 status
+#define R8_UART3_IIR        (*((PUINT8V)0x40003C04))  // RO, UART3 interrupt identification
+#define R8_UART3_LSR        (*((PUINT8V)0x40003C05))  // RO, UART3 line status
+#define R32_UART3_FIFO      (*((PUINT32V)0x40003C08)) // RW, UART3 data or FIFO port
+#define R8_UART3_RBR        (*((PUINT8V)0x40003C08))  // RO, UART3 receiver buffer, receiving byte
+#define R8_UART3_THR        (*((PUINT8V)0x40003C08))  // WO, UART3 transmitter holding, transmittal byte
+#define R8_UART3_RFC        (*((PUINT8V)0x40003C0A))  // RO, UART3 receiver FIFO count
+#define R8_UART3_TFC        (*((PUINT8V)0x40003C0B))  // RO, UART3 transmitter FIFO count
+#define R32_UART3_SETUP     (*((PUINT32V)0x40003C0C)) // RW, UART3 setup
+#define R16_UART3_DL        (*((PUINT16V)0x40003C0C)) // RW, UART3 divisor latch
+#define R8_UART3_DLL        (*((PUINT8V)0x40003C0C))  // RW, UART3 divisor latch LSB byte
+#define R8_UART3_DLM        (*((PUINT8V)0x40003C0D))  // RW, UART3 divisor latch MSB byte
+#define R8_UART3_DIV        (*((PUINT8V)0x40003C0E))  // RW, UART3 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
+
+/* UART register address offset and bit define */
+#define UART_FIFO_SIZE      8                         // UART FIFO size (depth)
+#define UART_RECV_RDY_SZ    7                         // the max FIFO trigger level for UART receiver data available
+#define BA_UART0            ((PUINT8V)0x40003000)     // point UART0 base address
+#define BA_UART1            ((PUINT8V)0x40003400)     // point UART1 base address
+#define BA_UART2            ((PUINT8V)0x40003800)     // point UART2 base address
+#define BA_UART3            ((PUINT8V)0x40003C00)     // point UART3 base address
+#define UART_MCR            0
+#define  RB_MCR_DTR         0x01                      // RW, UART0 control DTR
+#define  RB_MCR_RTS         0x02                      // RW, UART0 control RTS
+#define  RB_MCR_OUT1        0x04                      // RW, UART0 control OUT1
+#define  RB_MCR_OUT2        0x08                      // RW, UART control OUT2
+#define  RB_MCR_INT_OE      0x08                      // RW, UART interrupt output enable
+#define  RB_MCR_LOOP        0x10                      // RW, UART0 enable local loop back
+#define  RB_MCR_AU_FLOW_EN  0x20                      // RW, UART0 enable autoflow control
+#define  RB_MCR_TNOW        0x40                      // RW, UART0 enable TNOW output on DTR pin
+#define  RB_MCR_HALF        0x80                      // RW, UART0 enable half-duplex
+#define UART_IER            1
+#define  RB_IER_RECV_RDY    0x01                      // RW, UART interrupt enable for receiver data ready
+#define  RB_IER_THR_EMPTY   0x02                      // RW, UART interrupt enable for THR empty
+#define  RB_IER_LINE_STAT   0x04                      // RW, UART interrupt enable for receiver line status
+#define  RB_IER_MODEM_CHG   0x08                      // RW, UART0 interrupt enable for modem status change
+#define  RB_IER_DTR_EN      0x10                      // RW, UART0 DTR/TNOW output pin enable
+#define  RB_IER_RTS_EN      0x20                      // RW, UART0 RTS output pin enable
+#define  RB_IER_TXD_EN      0x40                      // RW, UART TXD pin enable
+#define  RB_IER_RESET       0x80                      // WZ, UART software reset control, high action, auto clear
+#define UART_FCR            2
+#define  RB_FCR_FIFO_EN     0x01                      // RW, UART FIFO enable
+#define  RB_FCR_RX_FIFO_CLR 0x02                      // WZ, clear UART receiver FIFO, high action, auto clear
+#define  RB_FCR_TX_FIFO_CLR 0x04                      // WZ, clear UART transmitter FIFO, high action, auto clear
+#define  RB_FCR_FIFO_TRIG   0xC0                      // RW, UART receiver FIFO trigger level: 00-1byte, 01-2bytes, 10-4bytes, 11-7bytes
+#define UART_LCR            3
+#define  RB_LCR_WORD_SZ     0x03                      // RW, UART word bit length: 00-5bit, 01-6bit, 10-7bit, 11-8bit
+#define  RB_LCR_STOP_BIT    0x04                      // RW, UART stop bit length: 0-1bit, 1-2bit
+#define  RB_LCR_PAR_EN      0x08                      // RW, UART parity enable
+#define  RB_LCR_PAR_MOD     0x30                      // RW, UART parity mode: 00-odd, 01-even, 10-mark, 11-space
+#define  RB_LCR_BREAK_EN    0x40                      // RW, UART break control enable
+#define  RB_LCR_DLAB        0x80                      // RW, UART reserved bit
+#define  RB_LCR_GP_BIT      0x80                      // RW, UART general purpose bit
+#define UART_IIR            4
+#define  RB_IIR_NO_INT      0x01                      // RO, UART no interrupt flag: 0=interrupt action, 1=no interrupt
+#define  RB_IIR_INT_MASK    0x0F                      // RO, UART interrupt flag bit mask
+#define  RB_IIR_FIFO_ID     0xC0                      // RO, UART FIFO enabled flag
+#define UART_LSR            5
+#define  RB_LSR_DATA_RDY    0x01                      // RO, UART receiver fifo data ready status
+#define  RB_LSR_OVER_ERR    0x02                      // RZ, UART receiver overrun error
+#define  RB_LSR_PAR_ERR     0x04                      // RZ, UART receiver parity error
+#define  RB_LSR_FRAME_ERR   0x08                      // RZ, UART receiver frame error
+#define  RB_LSR_BREAK_ERR   0x10                      // RZ, UART receiver break error
+#define  RB_LSR_TX_FIFO_EMP 0x20                      // RO, UART transmitter fifo empty status
+#define  RB_LSR_TX_ALL_EMP  0x40                      // RO, UART transmitter all empty status
+#define  RB_LSR_ERR_RX_FIFO 0x80                      // RO, indicate error in UART receiver fifo
+#define UART_MSR            6
+#define  RB_MSR_CTS_CHG     0x01                      // RZ, UART0 CTS changed status, high action
+#define  RB_MSR_DSR_CHG     0x02                      // RZ, UART0 DSR changed status, high action
+#define  RB_MSR_RI_CHG      0x04                      // RZ, UART0 RI changed status, high action
+#define  RB_MSR_DCD_CHG     0x08                      // RZ, UART0 DCD changed status, high action
+#define  RB_MSR_CTS         0x10                      // RO, UART0 CTS action status
+#define  RB_MSR_DSR         0x20                      // RO, UART0 DSR action status
+#define  RB_MSR_RI          0x40                      // RO, UART0 RI action status
+#define  RB_MSR_DCD         0x80                      // RO, UART0 DCD action status
+#define UART_RBR            8
+#define UART_THR            8
+#define UART_RFC            0x0A
+#define UART_TFC            0x0B
+#define UART_DLL            0x0C
+#define UART_DLM            0x0D
+#define UART_DIV            0x0E
+#define UART_ADR            0x0F
+
+/* UART interrupt identification values for IIR bits 3:0 */
+#define UART_II_SLV_ADDR    0x0E                      // RO, UART0 slave address match
+#define UART_II_LINE_STAT   0x06                      // RO, UART interrupt by receiver line status
+#define UART_II_RECV_RDY    0x04                      // RO, UART interrupt by receiver data available
+#define UART_II_RECV_TOUT   0x0C                      // RO, UART interrupt by receiver fifo timeout
+#define UART_II_THR_EMPTY   0x02                      // RO, UART interrupt by THR empty
+#define UART_II_MODEM_CHG   0x00                      // RO, UART0 interrupt by modem status change
+#define UART_II_NO_INTER    0x01                      // RO, no UART interrupt is pending
+
+/* SPI0 register */
+#define R32_SPI0_CONTROL    (*((PUINT32V)0x40004000)) // RW, SPI0 control
+#define R8_SPI0_CTRL_MOD    (*((PUINT8V)0x40004000))  // RW, SPI0 mode control
+#define R8_SPI0_CTRL_CFG    (*((PUINT8V)0x40004001))  // RW, SPI0 configuration control
+#define R8_SPI0_INTER_EN    (*((PUINT8V)0x40004002))  // RW, SPI0 interrupt enable
+#define R8_SPI0_CLOCK_DIV   (*((PUINT8V)0x40004003))  // RW, SPI0 master clock divisor
+#define R8_SPI0_SLAVE_PRE   (*((PUINT8V)0x40004003))  // RW, SPI0 slave preset value
+#define R32_SPI0_STATUS     (*((PUINT32V)0x40004004)) // RW, SPI0 status
+#define R8_SPI0_BUFFER      (*((PUINT8V)0x40004004))  // RO, SPI0 data buffer
+#define R8_SPI0_RUN_FLAG    (*((PUINT8V)0x40004005))  // RO, SPI0 work flag
+#define R8_SPI0_INT_FLAG    (*((PUINT8V)0x40004006))  // RW1, SPI0 interrupt flag
+#define R8_SPI0_FIFO_COUNT  (*((PUINT8V)0x40004007))  // RO, SPI0 FIFO count status
+#define R32_SPI0_TOTAL_CNT  (*((PUINT32V)0x4000400C)) // RW, SPI0 total byte count, only low 12 bit
+#define R16_SPI0_TOTAL_CNT  (*((PUINT16V)0x4000400C)) // RW, SPI0 total byte count, only low 12 bit
+#define R32_SPI0_FIFO       (*((PUINT32V)0x40004010)) // RW, SPI0 FIFO register
+#define R8_SPI0_FIFO        (*((PUINT8V)0x40004010))  // RO/WO, SPI0 FIFO register
+#define R8_SPI0_FIFO_COUNT1 (*((PUINT8V)0x40004013))  // RO, SPI0 FIFO count status
+#define R32_SPI0_DMA_NOW    (*((PUINT32V)0x40004014)) // RW, SPI0 DMA current address
+#define R16_SPI0_DMA_NOW    (*((PUINT16V)0x40004014)) // RW, SPI0 DMA current address
+#define R32_SPI0_DMA_BEG    (*((PUINT32V)0x40004018)) // RW, SPI0 DMA begin address
+#define R16_SPI0_DMA_BEG    (*((PUINT16V)0x40004018)) // RW, SPI0 DMA begin address
+#define R32_SPI0_DMA_END    (*((PUINT32V)0x4000401C)) // RW, SPI0 DMA end address
+#define R16_SPI0_DMA_END    (*((PUINT16V)0x4000401C)) // RW, SPI0 DMA end address
+
+/* SPI1 register */
+#define R32_SPI1_CONTROL    (*((PUINT32V)0x40004400)) // RW, SPI1 control
+#define R8_SPI1_CTRL_MOD    (*((PUINT8V)0x40004400))  // RW, SPI1 mode control
+#define R8_SPI1_CTRL_CFG    (*((PUINT8V)0x40004401))  // RW, SPI1 configuration control
+#define R8_SPI1_INTER_EN    (*((PUINT8V)0x40004402))  // RW, SPI1 interrupt enable
+#define R8_SPI1_CLOCK_DIV   (*((PUINT8V)0x40004403))  // RW, SPI1 master clock divisor
+#define R32_SPI1_STATUS     (*((PUINT32V)0x40004404)) // RW, SPI1 status
+#define R8_SPI1_BUFFER      (*((PUINT8V)0x40004404))  // RO, SPI1 data buffer
+#define R8_SPI1_RUN_FLAG    (*((PUINT8V)0x40004405))  // RO, SPI1 work flag
+#define R8_SPI1_INT_FLAG    (*((PUINT8V)0x40004406))  // RW1, SPI1 interrupt flag
+#define R8_SPI1_FIFO_COUNT  (*((PUINT8V)0x40004407))  // RO, SPI1 FIFO count status
+#define R32_SPI1_TOTAL_CNT  (*((PUINT32V)0x4000440C)) // RW, SPI1 total byte count, only low 12 bit
+#define R16_SPI1_TOTAL_CNT  (*((PUINT16V)0x4000440C)) // RW, SPI1 total byte count, only low 12 bit
+#define R32_SPI1_FIFO       (*((PUINT32V)0x40004410)) // RW, SPI1 FIFO register
+#define R8_SPI1_FIFO        (*((PUINT8V)0x40004410))  // RO/WO, SPI1 FIFO register
+#define R8_SPI1_FIFO_COUNT1 (*((PUINT8V)0x40004413))  // RO, SPI1 FIFO count status
+
+/* SPI register address offset and bit define */
+#define SPI_FIFO_SIZE       8                         // SPI FIFO size (depth)
+#define BA_SPI0             ((PUINT8V)0x40004000)     // point SPI0 base address
+#define BA_SPI1             ((PUINT8V)0x40004400)     // point SPI1 base address
+#define SPI_CTRL_MOD        0
+#define  RB_SPI_MODE_SLAVE  0x01                      // RW, SPI0 slave mode: 0=master/host, 1=slave/device
+#define  RB_SPI_ALL_CLEAR   0x02                      // RW, force clear SPI FIFO and count
+#define  RB_SPI_2WIRE_MOD   0x04                      // RW, SPI0 enable 2 wire mode for slave: 0=3wire(SCK0,MOSI,MISO), 1=2wire(SCK0,MISO=MXSX)
+#define  RB_SPI_MST_SCK_MOD 0x08                      // RW, SPI master clock mode: 0=mode 0, 1=mode 3
+#define  RB_SPI_SLV_CMD_MOD 0x08                      // RW, SPI0 slave command mode: 0=byte stream, 1=first byte command
+#define  RB_SPI_FIFO_DIR    0x10                      // RW, SPI FIFO direction: 0=out(write @master mode), 1=in(read @master mode)
+#define  RB_SPI_SCK_OE      0x20                      // RW, SPI SCK output enable
+#define  RB_SPI_MOSI_OE     0x40                      // RW, SPI MOSI output enable
+#define  RB_SPI1_SDO_OE     0x40                      // RW, SPI1 SDO output enable
+#define  RB_SPI_MISO_OE     0x80                      // RW, SPI MISO output enable
+#define  RB_SPI1_SDI_OE     0x80                      // RW, SPI1 SDI output enable, SPI1 enable 2 wire mode: 0=3wire(SCK1,SDO,SDI), 1=2wire(SCK1,SDI=SDX)
+#define SPI_CTRL_CFG        1
+#define  RB_SPI_DMA_ENABLE  0x01                      // RW, SPI0 DMA enable
+#define  RB_SPI_DMA_LOOP    0x04                      // RW, SPI0 DMA address loop enable
+#define  RB_SPI_AUTO_IF     0x10                      // RW, enable buffer/FIFO accessing to auto clear RB_SPI_IF_BYTE_END interrupt flag
+#define  RB_SPI_BIT_ORDER   0x20                      // RW, SPI bit data order: 0=MSB first, 1=LSB first
+#define  RB_SPI_MST_DLY_EN  0x40                      // RW, SPI master input delay enable
+#define SPI_INTER_EN        2
+#define  RB_SPI_IE_CNT_END  0x01                      // RW, enable interrupt for SPI total byte count end
+#define  RB_SPI_IE_BYTE_END 0x02                      // RW, enable interrupt for SPI byte exchanged
+#define  RB_SPI_IE_FIFO_HF  0x04                      // RW, enable interrupt for SPI FIFO half
+#define  RB_SPI_IE_DMA_END  0x08                      // RW, enable interrupt for SPI0 DMA completion
+#define  RB_SPI_IE_FIFO_OV  0x10                      // RW, enable interrupt for SPI0 FIFO overflow
+#define  RB_SPI_IE_FST_BYTE 0x80                      // RW, enable interrupt for SPI0 slave mode first byte received
+#define SPI_CLOCK_DIV       3
+#define SPI_SLAVE_PRESET    3
+#define SPI_BUFFER          4
+#define SPI_RUN_FLAG        5
+#define  RB_SPI_SLV_CMD_ACT 0x10                      // RO, SPI0 slave first byte / command flag
+#define  RB_SPI_FIFO_READY  0x20                      // RO, SPI FIFO ready status
+#define  RB_SPI_SLV_CS_LOAD 0x40                      // RO, SPI0 slave chip-select loading status
+#define  RB_SPI_SLV_SELECT  0x80                      // RO, SPI0 slave selection status
+#define SPI_INT_FLAG        6
+#define  RB_SPI_IF_CNT_END  0x01                      // RW1, interrupt flag for SPI total byte count end
+#define  RB_SPI_IF_BYTE_END 0x02                      // RW1, interrupt flag for SPI byte exchanged
+#define  RB_SPI_IF_FIFO_HF  0x04                      // RW1, interrupt flag for SPI FIFO half (RB_SPI_FIFO_DIR ? >=4bytes : <4bytes)
+#define  RB_SPI_IF_DMA_END  0x08                      // RW1, interrupt flag for SPI0 DMA completion
+#define  RB_SPI_IF_FIFO_OV  0x10                      // RW1, interrupt flag for SPI0 FIFO overflow
+#define  RB_SPI_FREE        0x40                      // RO, current SPI free status
+#define  RB_SPI_IF_FST_BYTE 0x80                      // RW1, interrupt flag for SPI0 slave mode first byte received
+#define SPI_FIFO_COUNT      7
+#define SPI_TOTAL_CNT       0x0C
+#define SPI_FIFO            0x10
+#define SPI_DMA_NOW         0x14
+#define SPI_DMA_BEG         0x18
+#define SPI_DMA_END         0x1C
+
+/* PWM4/5/6/7/8/9/10/11 register */
+#define R32_PWM_CONTROL     (*((PUINT32V)0x40005000)) // RW, PWM control
+#define R8_PWM_OUT_EN       (*((PUINT8V)0x40005000))  // RW, PWM output enable control
+#define R8_PWM_POLAR        (*((PUINT8V)0x40005001))  // RW, PWM output polarity control
+#define R8_PWM_CONFIG       (*((PUINT8V)0x40005002))  // RW, PWM configuration
+#define R8_PWM_CLOCK_DIV    (*((PUINT8V)0x40005003))  // RW, PWM clock divisor
+#define R32_PWM4_7_DATA     (*((PUINT32V)0x40005004)) // RW, PWM4-7 data holding
+#define R8_PWM4_DATA        (*((PUINT8V)0x40005004))  // RW, PWM4 data holding
+#define R8_PWM5_DATA        (*((PUINT8V)0x40005005))  // RW, PWM5 data holding
+#define R8_PWM6_DATA        (*((PUINT8V)0x40005006))  // RW, PWM6 data holding
+#define R8_PWM7_DATA        (*((PUINT8V)0x40005007))  // RW, PWM7 data holding
+#define R32_PWM8_11_DATA    (*((PUINT32V)0x40005008)) // RW, PWM8-11 data holding
+#define R8_PWM8_DATA        (*((PUINT8V)0x40005008))  // RW, PWM8 data holding
+#define R8_PWM9_DATA        (*((PUINT8V)0x40005009))  // RW, PWM9 data holding
+#define R8_PWM10_DATA       (*((PUINT8V)0x4000500A))  // RW, PWM10 data holding
+#define R8_PWM11_DATA       (*((PUINT8V)0x4000500B))  // RW, PWM11 data holding
+
+/* PWM4/5/6/7/8/9/10/11 register address offset and bit define */
+#define BA_PWMX             ((PUINT8V)0x40005000)     // point PWM4/5/6/7/8/9/10/11 base address
+#define PWM_OUT_EN          0
+#define  RB_PWM4_OUT_EN     0x01                      // RW, PWM4 output enable
+#define  RB_PWM5_OUT_EN     0x02                      // RW, PWM5 output enable
+#define  RB_PWM6_OUT_EN     0x04                      // RW, PWM6 output enable
+#define  RB_PWM7_OUT_EN     0x08                      // RW, PWM7 output enable
+#define  RB_PWM8_OUT_EN     0x10                      // RW, PWM8 output enable
+#define  RB_PWM9_OUT_EN     0x20                      // RW, PWM9 output enable
+#define  RB_PWM10_OUT_EN    0x40                      // RW, PWM10 output enable
+#define  RB_PWM11_OUT_EN    0x80                      // RW, PWM11 output enable
+#define PWM_POLAR           1
+#define  RB_PWM4_POLAR      0x01                      // RW, PWM4 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM5_POLAR      0x02                      // RW, PWM5 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM6_POLAR      0x04                      // RW, PWM6 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM7_POLAR      0x08                      // RW, PWM7 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM8_POLAR      0x10                      // RW, PWM8 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM9_POLAR      0x20                      // RW, PWM9 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM10_POLAR     0x40                      // RW, PWM10 output polarity: 0=default low and high action, 1=default high and low action
+#define  RB_PWM11_POLAR     0x80                      // RW, PWM11 output polarity: 0=default low and high action, 1=default high and low action
+#define PWM_CONFIG          2
+#define  RB_PWM_CYCLE_SEL   0x01                      // RW, PWM cycle selection: 0=256/128/64/32 clocks, 1=255/127/63/31 clocks
+#define  RB_PWM_STAG_ST     0x02                      // RO, PWM stagger cycle status
+#define  RB_PWM_CYC_MOD     0x0c                      // RW, PWM data width mode: 00=8 bits data, 01=7 bits data, 10=6 bits data, 11=5 bits data
+#define  RB_PWM4_5_STAG_EN  0x10                      // RW, PWM4/5 stagger output enable: 0=independent output, 1=stagger output
+#define  RB_PWM6_7_STAG_EN  0x20                      // RW, PWM6/7 stagger output enable: 0=independent output, 1=stagger output
+#define  RB_PWM8_9_STAG_EN  0x40                      // RW, PWM8/9 stagger output enable: 0=independent output, 1=stagger output
+#define  RB_PWM10_11_STAG_EN 0x80                     // RW, PWM10/11 stagger output enable: 0=independent output, 1=stagger output
+#define PWM_CLOCK_DIV       3
+#define PWM4_DATA_HOLD      4
+#define PWM5_DATA_HOLD      5
+#define PWM6_DATA_HOLD      6
+#define PWM7_DATA_HOLD      7
+#define PWM8_DATA_HOLD      8
+#define PWM9_DATA_HOLD      9
+#define PWM10_DATA_HOLD     10
+#define PWM11_DATA_HOLD     11
+
+/* LED register */
+#define R32_LED_CONTROL     (*((PUINT32V)0x40006400)) // RW, LED control
+#define R8_LED_CTRL_MOD     (*((PUINT8V)0x40006400))  // RW, LED mode control
+#define R8_LED_CLOCK_DIV    (*((PUINT8V)0x40006401))  // RW, LED serial clock divisor
+#define R8_LED_STATUS       (*((PUINT8V)0x40006404))  // RO, LED status
+#define R32_LED_FIFO        (*((PUINT32V)0x40006408)) // WO, LED FIFO register, width is half-word, only low 16 bit
+#define R16_LED_FIFO        (*((PUINT16V)0x40006408)) // WO, LED FIFO register, width is half-word
+#define R32_LED_DMA_CNT     (*((PUINT32V)0x40006410)) // RW, LED DMA main buffer remainder half-word count, exclude auxiliary buffer, automatic decreasing after DMA, only low 12 bit
+#define R16_LED_DMA_CNT     (*((PUINT16V)0x40006410)) // RW, LED DMA main buffer remainder half-word count, exclude auxiliary buffer, automatic decreasing after DMA, only low 12 bit
+#define R32_LED_DMA_MAIN    (*((PUINT32V)0x40006414)) // RW, LED main buffer DMA begin & current address, automatic increasing after DMA
+#define R16_LED_DMA_MAIN    (*((PUINT16V)0x40006414)) // RW, LED main buffer DMA begin & current address, automatic increasing after DMA
+#define R32_LED_DMA_AUX     (*((PUINT32V)0x40006418)) // RW, LED auxiliary buffer DMA begin & current address, automatic increasing after DMA
+#define R16_LED_DMA_AUX     (*((PUINT16V)0x40006418)) // RW, LED auxiliary buffer DMA begin & current address, automatic increasing after DMA
+
+/* LED register address offset and bit define */
+#define LED_FIFO_SIZE       2                         // LED FIFO size (depth), width is half-word
+#define BA_LED              ((PUINT8V)0x40006400)     // point LED base address
+#define LED_CTRL_MOD        0
+#define  RB_LED_BIT_ORDER   0x01                      // RW, LED bit data order: 0=LSB first, 1=MSB first
+#define  RB_LED_ALL_CLEAR   0x02                      // RW, force clear LED FIFO and count
+#define  RB_LED_OUT_POLAR   0x04                      // RW, LED output polarity: 0=pass, 1=invert
+#define  RB_LED_OUT_EN      0x08                      // RW, LED output enable
+#define  RB_LED_DMA_EN      0x10                      // RW, LED DMA enable and DMA interrupt enable
+#define  RB_LED_IE_FIFO     0x20                      // RW, enable interrupt for LED FIFO <=2
+#define  RB_LED_CHAN_MOD    0xC0                      // RW, LED channel mode: 00=LED0, 01=LED0/1, 10=LED0~3, 11=LED0~3 and LED2/3 from auxiliary buffer
+// RB_LED_CHAN_MOD: LED channel mode
+//   00: single channel output, LED0
+//   01: dual channels output, LED0/1
+//   10: 4 channels output, LED0~3
+//   11: 4 channels output and LED2/3 from aux buffer, LED0~3
+#define LED_CLOCK_DIV       1
+#define LED_STATUS          4
+#define  RB_LED_FIFO_COUNT  0x07                      // RO, LED FIFO byte count status, must divided by 2 for width half-word
+#define  RB_LED_CLOCK       0x10                      // RO, current LED clock level
+#define  RB_LED_IF_FIFO     0x20                      // RW1, interrupt flag for LED FIFO <=2, cleared by RW1 or write R32/R16_LED_FIFO
+#define  RB_LED_FIFO_EMPTY  0x40                      // RO: indicate FIFO empty status
+#define  RB_LED_IF_DMA_END  0x80                      // RW1, interrupt flag for LED DMA completion, cleared by RW1 or write R32/R16_LED_DMA_CNT
+#define LED_FIFO            8
+#define LED_DMA_CNT         0x10
+#define LED_DMA_BEG         0x14
+#define LED_DMA_END         0x18
+
+/* LCD register */
+#define R32_LCD_CONTROL     (*((PUINT32V)(0x40006000)))
+#define R8_LCD_CTRL_MOD     (*((PUINT8V)(0x40006000)))
+#define  RB_SYS_POWER_ON    0x01                      // RW, LCD digital system enable
+#define  RB_LCD_POWER_ON    0x02                      // RW, LCD analog system enable
+#define  RB_LCD_BIAS        0x04                      // RW, LCD bias select:  0=1/2 bias,  1=1/3 bias
+#define  RB_LCD_DUTY        0x18                      // RW, LCD duty select:  00=1/2 duty,  01=1/3 duty,  10=1/4 duty
+#define  RB_LCD_SCAN_CLK    0x60                      // RW, LCD scan clock select: 00=256Hz, 01=512Hz, 10=1KHz, 11=128Hz
+#define  RB_LCD_V_SEL       0x80                      // RW, LCD drive voltage:0=VIO33*100%(3.3V),1=VIO33*76%(2.5V)
+
+#define R32_LCD_RAM0        (*((PUINT32V)(0x40006004))) // RW, LCD driver data0, address 0-3
+#define R32_LCD_RAM1        (*((PUINT32V)(0x40006008))) // RW, LCD driver data1, address 4-7
+#define R32_LCD_RAM2        (*((PUINT32V)(0x4000600C))) // RW, LCD driver data2, address 8-12
+
+
+/* Address space define */
+#define BA_CODE             ((PUINT32)0x00000000)     // point code base address
+#define SZ_CODE             0x00040000                // code size
+#define BA_SFR              ((PUINT32)0x40000000)     // point SFR base address
+#define SZ_SFR              0x00010000                // SFR size
+#define BA_RAM              ((PUINT32)0x20000000)     // point RAM base address
+#define SZ_RAM              0x00008000                // RAM size
+#define BA_PPB              ((PUINT32)0xE0000000)     // point PPB base address
+#define SZ_PPB              0x00010000                // PPB size
+
+/* Special Program Space */
+#define DATA_FLASH_ADDR     0x3E800                   // start address of Data-Flash
+#define DATA_FLASH_SIZE     0x0800                    // size of Data-Flash
+#define BOOT_LOAD_ADDR      0x3F000                   // start address of boot loader program
+#define BOOT_LOAD_SIZE      0x1000                    // size of boot loader program
+#define BOOT_LOAD_CFG       0x40000                   // start address of configuration information for boot loader program
+#define ROM_CFG_ADDR        0x40010                   // chip configuration information address
+
+/*----- Reference Information --------------------------------------------*/
+#define ID_CH579            0x79                      // chip ID
+
+/* Interrupt routine address and interrupt number */
+#define INT_ID_TMR0         0                         // interrupt number for Timer0
+#define INT_ID_GPIO         1                         // interrupt number for GPIO
+#define INT_ID_SLAVE        2                         // interrupt number for Slave
+#define INT_ID_SPI0         3                         // interrupt number for SPI0
+#define INT_ID_BLEB         4                         // interrupt number for BLEBB
+#define INT_ID_BLEL         5                         // interrupt number for BLELLE
+#define INT_ID_USB          6                         // interrupt number for USB
+#define INT_ID_ETH          7                         // interrupt number for ETH
+#define INT_ID_TMR1         8                         // interrupt number for Timer1
+#define INT_ID_TMR2         9                         // interrupt number for Timer2
+#define INT_ID_UART0        10                        // interrupt number for UART0
+#define INT_ID_UART1        11                        // interrupt number for UART1
+#define INT_ID_RTC          12                        // interrupt number for RTC
+#define INT_ID_ADC          13                        // interrupt number for ADC and TouchKey
+#define INT_ID_SPI1         14                        // interrupt number for SPI1
+#define INT_ID_LED          15                        // interrupt number for LED
+#define INT_ID_TMR3         16                        // interrupt number for Timer3
+#define INT_ID_UART2        17                        // interrupt number for UART2
+#define INT_ID_UART3        18                        // interrupt number for UART3
+#define INT_ID_WDOG_BAT     19                        // interrupt number for Watch-Dog timer and Battery low voltage
+#define INT_VEC_ENTRY_SZ    4                         // size of each interrupt vector entry
+#define INT_ADDR_TMR0       (INT_ID_TMR0*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for Timer0
+#define INT_ADDR_GPIO       (INT_ID_GPIO*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for GPIO
+#define INT_ADDR_SLAVE      (INT_ID_SLAVE*INT_VEC_ENTRY_SZ+64)   // interrupt vector address for Slave
+#define INT_ADDR_SPI0       (INT_ID_SPI0*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for SPI0
+#define INT_ADDR_BLEB       (INT_ID_BLEB*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for BLEBB
+#define INT_ADDR_BLEL       (INT_ID_BLEL*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for BLELLE
+#define INT_ADDR_USB        (INT_ID_USB*INT_VEC_ENTRY_SZ+64)     // interrupt vector address for USB
+#define INT_ADDR_ETH        (INT_ID_ETH*INT_VEC_ENTRY_SZ+64)     // interrupt vector address for ETH
+#define INT_ADDR_TMR1       (INT_ID_TMR1*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for Timer1
+#define INT_ADDR_TMR2       (INT_ID_TMR2*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for Timer2
+#define INT_ADDR_UART0      (INT_ID_UART0*INT_VEC_ENTRY_SZ+64)   // interrupt vector address for UART0
+#define INT_ADDR_UART1      (INT_ID_UART1*INT_VEC_ENTRY_SZ+64)   // interrupt vector address for UART1
+#define INT_ADDR_RTC        (INT_ID_RTC*INT_VEC_ENTRY_SZ+64)     // interrupt vector address for RTC
+#define INT_ADDR_AD         (INT_ID_ADC*INT_VEC_ENTRY_SZ+64)     // interrupt vector address for ADC and TouchKey
+#define INT_ADDR_SPI1       (INT_ID_SPI1*INT_VEC_ENTRY_SZ+64)    // interrupt vector address for SPI1
+#define INT_ADDR_LED        (INT_ID_LED*INT_VEC_ENTRY_SZ+64)     // interrupt vector address for LED
+#define INT_ADDR_Timer3     (INT_ID_Timer3*INT_VEC_ENTRY_SZ+64)  // interrupt vector address for Timer3
+#define INT_ADDR_UART2      (INT_ID_UART2*INT_VEC_ENTRY_SZ+64)   // interrupt vector address for UART2
+#define INT_ADDR_UART3      (INT_ID_UART3*INT_VEC_ENTRY_SZ+64)   // interrupt vector address for UART3
+#define INT_ADDR_WDOG_BAT   (INT_ID_WDOG_BAT*INT_VEC_ENTRY_SZ+64) // interrupt vector address for Watch-Dog timer and Battery low voltage
+
+#ifndef TABLE_IRQN
+#define __NVIC_PRIO_BITS          2 /*!< uses 2 Bits for the Priority Levels    */
+#define __Vendor_SysTickConfig    0 /*!< Set to 1 if different SysTick Config is used */
+typedef enum IRQn
+{
+/* -------------------  Cortex-M0 Processor Exceptions Numbers  ------------------- */
+  NonMaskableInt_IRQn          = -14,      /*!<  2 Non Maskable Interrupt          */
+  HardFault_IRQn               = -13,      /*!<  3 HardFault Interrupt             */
+  SVCall_IRQn                  =  -5,      /*!< 11 SV Call Interrupt               */
+  PendSV_IRQn                  =  -2,      /*!< 14 Pend SV Interrupt               */
+  SysTick_IRQn                 =  -1,      /*!< 15 System Tick Interrupt           */
+/* ----------------------  ARMCM0 Specific Interrupt Numbers  --------------------- */
+  TMR0_IRQn                    =   0,      /*!< Timer0 Interrupt                    */
+  GPIO_IRQn                    =   1,      /*!< GPIO A/B Interrupt                  */
+  SLAVE_IRQn                   =   2,      /*!< Slave parallel port Interrupt       */
+  SPI0_IRQn                    =   3,      /*!< SPI0 Interrupt                      */
+  BLEB_IRQn                    =   4,      /*!< BB  Interrupt                       */
+  BLEL_IRQn                    =   5,      /*!< LLE Interrupt                       */
+  USB_IRQn                     =   6,      /*!< USB Interrupt                       */
+  ETH_IRQn                     =   7,      /*!< Ethernet Interrupt                  */
+  TMR1_IRQn                    =   8,      /*!< Timer1 Interrupt                    */
+  TMR2_IRQn                    =   9,      /*!< Timer2 Interrupt                    */
+  UART0_IRQn                   =  10,      /*!< UART0 Interrupt                     */
+  UART1_IRQn                   =  11,      /*!< UART1 Interrupt                     */
+  RTC_IRQn                     =  12,      /*!< Real Time Clock Interrupt           */
+  ADC_IRQn                     =  13,      /*!< ADC Interrupt                       */
+  SPI1_IRQn                    =  14,      /*!< SPI1 Interrupt                      */
+  LED_IRQn                     =  15,      /*!< LED control Interrupt               */
+  TMR3_IRQn                    =  16,      /*!< Timer3 Interrupt                    */
+  UART2_IRQn                   =  17,      /*!< UART2 Interrupt                     */
+  UART3_IRQn                   =  18,      /*!< UART3 Interrupt                     */
+  WDOG_BAT_IRQn                =  19,      /*!< Watch Dog Interrupt                 */
+} IRQn_Type;
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH579SFR_H__
+
+
+#ifndef __CH579ETHSFR_H__
+#define __CH579ETHSFR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/*                       ETH  Peripheral memory map                              */
+/******************************************************************************/
+/* ETH addresses
+//      ETH:     +9000H - 93FFH                                                    */
+#define ETH_BASE_ADDR           (0x40009000)
+
+/* ETH register */
+#define R8_ETH_EIE              (*((PUINT8V)(0x40009003))) /* 中断使能寄存器 */
+#define  RB_ETH_EIE_INTIE       0x80                  /* RW 中断使能 */
+#define  RB_ETH_EIE_RXIE        0x40                  /* RW 接收完成中断使能 */
+#define  RB_ETH_EIE_LINKIE      0x10                  /* RW Link 变化中断使能 */
+#define  RB_ETH_EIE_TXIE        0x08                  /* RW 发送完成中断使能 */
+#define  RB_ETH_EIE_R_EN50      0x04                  /* RW TX 50Ω电阻调节。1:片内 50Ω连接 0:片内 50Ω断开 */
+#define  RB_ETH_EIE_TXERIE      0x02                  /* RW 发送错误中断使能 */
+#define  RB_ETH_EIE_RXERIE      0x01                  /* RW1 接收错误标志 */
+#define R32_ETH_CON             (*((PUINT32V)(0x40009004)))
+#define R8_ETH_EIR              (*((PUINT8V)(0x40009004))) /* 中断标志寄存器 */
+#define  RB_ETH_EIR_RXIF        0x40                  /* RW1 接收完成标志 */
+#define  RB_ETH_EIR_LINKIF      0x10                  /* RW1 Link 变化标志 */
+#define  RB_ETH_EIR_TXIF        0x08                  /* RW1 发送完成标志 */
+#define  RB_ETH_EIR_TXERIF      0x02                  /* RW1 发送错误标志 */
+#define  RB_ETH_EIR_RXERIF      0x01
+#define R8_ETH_ESTAT            (*((PUINT8V)(0x40009005))) /* 状态寄存器 */
+#define  RB_ETH_ESTAT_INT       0x80                  /* RW1 中断 */
+#define  RB_ETH_ESTAT_BUFER     0x40                  /* RW1 Buffer 错误,理论上 mcu 主频太低才会发生 */
+#define  RB_ETH_ESTAT_RXCRCER   0x20                  /* RO 接收 crc 出错 */
+#define  RB_ETH_ESTAT_RXNIBBLE  0x10                  /* RO 接收 nibble 错误 */
+#define  RB_ETH_ESTAT_RXMORE    0x08                  /* RO 接收超过最大数据包 */
+#define  RB_ETH_ESTAT_RXBUSY    0x04                  /* RO 接收进行中 */
+#define  RB_ETH_ESTAT_TXABRT    0x02                  /* RO 发送被 mcu 打断 */
+#define R8_ETH_ECON2            (*((PUINT8V)(0x40009006))) /* ETH PHY模拟模块控制寄存器 */
+#define  RB_ETH_ECON2_RX        0x0E                  /* 必须写入011 */
+#define  RB_ETH_ECON2_TX        0x01
+#define  RB_ETH_ECON2_MUST      0x06                  /* 必须写入011 */
+#define R8_ETH_ECON1            (*((PUINT8V)(0x40009007))) /* 收发控制寄存器 */
+#define  RB_ETH_ECON1_TXRST     0x80                  /* RW 发送模块复位 */
+#define  RB_ETH_ECON1_RXRST     0x40                  /* RW 接收模块复位 */
+#define  RB_ETH_ECON1_TXRTS     0x08                  /* RW 发送开始,发送完成后自动清零,如主动清零会使发送错误标志TXERIF和TXABRT变1 */
+#define  RB_ETH_ECON1_RXEN      0x04                  /* RW 接收使能,清零时如正在接受则错误标志RXERIF变1 */
+
+#define R32_ETH_TX              (*((PUINT32V)(0x40009008))) /* 发送控制 */
+#define R16_ETH_ETXST           (*((PUINT16V)(0x40009008))) /* RW 发送 DMA 缓冲区起始地址 */
+#define R16_ETH_ETXLN           (*((PUINT16V)(0x4000900A))) /* RW 发送长度 */
+#define R32_ETH_RX              (*((PUINT32V)(0x4000900C))) /* 接收控制 */
+#define R16_ETH_ERXST           (*((PUINT16V)(0x4000900C))) /* RW 接收 DMA 缓冲区起始地址 */
+#define R16_ETH_ERXLN           (*((PUINT16V)(0x4000900E))) /* RO 接收长度 */
+
+#define R32_ETH_HTL             (*((PUINT32V)(0x40009010)))
+#define R8_ETH_EHT0             (*((PUINT8V)(0x40009010))) /* RW Hash Table Byte0 */
+#define R8_ETH_EHT1             (*((PUINT8V)(0x40009011))) /* RW Hash Table Byte1 */
+#define R8_ETH_EHT2             (*((PUINT8V)(0x40009012))) /* RW Hash Table Byte2 */
+#define R8_ETH_EHT3             (*((PUINT8V)(0x40009013))) /* RW Hash Table Byte3 */
+#define R32_ETH_HTH             (*((PUINT32V)(0x40009014)))
+#define R8_ETH_EHT4             (*((PUINT8V)(0x40009014))) /* RW Hash Table Byte4 */
+#define R8_ETH_EHT5             (*((PUINT8V)(0x40009015))) /* RW Hash Table Byte5 */
+#define R8_ETH_EHT6             (*((PUINT8V)(0x40009016))) /* RW Hash Table Byte6 */
+#define R8_ETH_EHT7             (*((PUINT8V)(0x40009017))) /* RW Hash Table Byte7 */
+
+#define R32_ETH_MACON           (*((PUINT32V)(0x40009018)))
+#define R8_ETH_ERXFCON          (*((PUINT8V)(0x40009018))) /* 接收包过滤控制寄存器 */
+#define  RB_ETH_ERXFCON_UCEN    0x80                  /* RW 0=不启用该过滤条件,1=当ANDOR=1,目标地址不匹配将被过滤,当ANDOR=0,目标地址匹配将被接收 */
+#define  RB_ETH_ERXFCON_ANDOR   0x40                  /* RW 1=AND,所有过滤条件都满足包才被接收 0=OR,任一过滤条件满足包均被接收 */
+#define  RB_ETH_ERXFCON_CRCEN   0x20                  /* RW 0=不启用该过滤条件,1=当ANDOR=1,CRC校验错将被过滤,当ANDOR=0,CRC校验正确将被接收 */
+#define  RB_ETH_ERXFCON_MPEN    0x08                  /* RW 0=不启用该过滤条件,1=当ANDOR=1,非魔法包将被过滤,当ANDOR=0,魔法包将被接收 */
+#define  RB_ETH_ERXFCON_HTEN    0x04                  /* RW 0=不启用该过滤条件,1=当ANDOR=1,hash table不匹配将被过滤,当ANDOR=0,hash table匹配将被接收 */
+#define  RB_ETH_ERXFCON_MCEN    0x02                  /* RW 0=不启用该过滤条件,1=当ANDOR=1,组播包不匹配将被过滤,当ANDOR=0,组播包匹配将被接收 */
+#define  RB_ETH_ERXFCON_BCEN    0x01                  /* RW 0=不启用该过滤条件,1=当ANDOR=1,非广播包将被过滤,当ANDOR=0,广播包将被接收 */
+#define R8_ETH_MACON1           (*((PUINT8V)(0x40009019))) /* Mac 层流控制寄存器 */
+#define  RB_ETH_MACON1_FCEN     0x30                  /* RW 当FULDPX=0均无效,当FULDPX=1,11=发送0 timer暂停帧,然后停止发送,10=周期性发送暂停帧,01=发送一次暂停帧,然后停止发送,00=停止发送暂停帧 */
+#define  RB_ETH_MACON1_TXPAUS   0x08                  /* RW 发送pause帧使能 */
+#define  RB_ETH_MACON1_RXPAUS   0x04                  /* RW 接收pause帧使能 */
+#define  RB_ETH_MACON1_PASSALL  0x02                  /* RW 1=没被过滤的控制帧将写入缓存,0=控制帧将被过滤 */
+#define  RB_ETH_MACON1_MARXEN   0x01                  /* RW MAC层接收使能 */
+#define R8_ETH_MACON2           (*((PUINT8V)(0x4000901A))) /* Mac 层封包控制寄存器 */
+#define  RB_ETH_MACON2_PADCFG   0xE0                  /* RW 短包填充设置 */
+#define  RB_ETH_MACON2_TXCRCEN  0x10                  /* RW 发送添加crc,PADCFG中如需要添加crc,该位置1 */
+#define  RB_ETH_MACON2_PHDREN   0x08                  /* RW 特殊4字节不参与crc校验 */
+#define  RB_ETH_MACON2_HFRMEN   0x04                  /* RW 允许接收巨型帧 */
+#define  RB_ETH_MACON2_FULDPX   0x01                  /* RW 全双工 */
+#define R8_ETH_MABBIPG          (*((PUINT8V)(0x4000901B))) /* 最小包间间隔寄存器 */
+#define  RB_ETH_MABBIPG_MABBIPG 0x7F                  /* RW 最小包间间隔字节数 */
+
+#define R32_ETH_TIM             (*((PUINT32V)(0x4000901C)))
+#define R16_ETH_EPAUS           (*((PUINT16V)(0x4000901C))) /* RW 流控制暂停帧时间寄存器 */
+#define R16_ETH_MAMXFL          (*((PUINT16V)(0x4000901E))) /* RW 最大接收包长度寄存器 */
+#define R16_ETH_MIRD            (*((PUINT16V)(0x40009020))) /* RW MII 读数据寄存器 */
+
+#define R32_ETH_MIWR            (*((PUINT32V)(0x40009024)))
+#define R8_ETH_MIREGADR         (*((PUINT8V)(0x40009024))) /* MII 地址寄存器 */
+#define  RB_ETH_MIREGADR_MASK   0x1F                  /* RW PHY 寄存器地址掩码 */
+#define R8_ETH_MISTAT           (*((PUINT8V)(0x40009025))) /* MII 状态寄存器 */
+//#define  RB_ETH_MIREGADR_MIIWR  0x20                  /* WO MII 写命令 */
+#define R16_ETH_MIWR            (*((PUINT16V)(0x40009026))) /* WO MII 写数据寄存器 */
+#define R32_ETH_MAADRL          (*((PUINT32V)(0x40009028))) /* RW MAC 1-4 */
+#define R16_ETH_MAADRH          (*((PUINT16V)(0x4000902C))) /* RW MAC 5-6 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH579ETHSFR_H__
+
+
+#ifndef __CH579USBSFR_H__
+#define __CH579USBSFR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/*                         Peripheral memory map                              */
+/******************************************************************************/
+/* usb addresses
+//      USB:     +8000H - 83FFH                                                    */
+#define USB_BASE_ADDR        (0x40008000)
+
+/*       USB  */
+#define R32_USB_CONTROL      (*((PUINT32V)(0x40008000))) // USB control & interrupt enable & device address
+#define R8_USB_CTRL          (*((PUINT8V)(0x40008000))) // USB base control
+#define  RB_UC_HOST_MODE     0x80      // enable USB host mode: 0=device mode, 1=host mode
+#define  RB_UC_LOW_SPEED     0x40      // enable USB low speed: 0=12Mbps, 1=1.5Mbps
+#define  RB_UC_DEV_PU_EN     0x20      // USB device enable and internal pullup resistance enable
+#define  RB_UC_SYS_CTRL1     0x20      // USB system control high bit
+#define  RB_UC_SYS_CTRL0     0x10      // USB system control low bit
+#define  MASK_UC_SYS_CTRL    0x30      // bit mask of USB system control
+// bUC_HOST_MODE & bUC_SYS_CTRL1 & bUC_SYS_CTRL0: USB system control
+//   0 00: disable USB device and disable internal pullup resistance
+//   0 01: enable USB device and disable internal pullup resistance, need external pullup resistance
+//   0 1x: enable USB device and enable internal pullup resistance
+//   1 00: enable USB host and normal status
+//   1 01: enable USB host and force UDP/UDM output SE0 state
+//   1 10: enable USB host and force UDP/UDM output J state
+//   1 11: enable USB host and force UDP/UDM output resume or K state
+#define  RB_UC_INT_BUSY      0x08      // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
+#define  RB_UC_RESET_SIE     0x04      // force reset USB SIE, need software clear
+#define  RB_UC_CLR_ALL       0x02      // force clear FIFO and count of USB
+#define  RB_UC_DMA_EN        0x01      // DMA enable and DMA interrupt enable for USB
+
+#define R8_UDEV_CTRL         (*((PUINT8V)(0x40008001))) // USB device physical prot control
+#define  RB_UD_PD_DIS        0x80      // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
+#define  RB_UD_DP_PIN        0x20      // ReadOnly: indicate current UDP pin level
+#define  RB_UD_DM_PIN        0x10      // ReadOnly: indicate current UDM pin level
+#define  RB_UD_LOW_SPEED     0x04      // enable USB physical port low speed: 0=full speed, 1=low speed
+#define  RB_UD_GP_BIT        0x02      // general purpose bit
+#define  RB_UD_PORT_EN       0x01      // enable USB physical port I/O: 0=disable, 1=enable
+
+#define R8_UHOST_CTRL        R8_UDEV_CTRL // USB host physical prot control
+#define  RB_UH_PD_DIS        0x80      // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
+#define  RB_UH_DP_PIN        0x20      // ReadOnly: indicate current UDP pin level
+#define  RB_UH_DM_PIN        0x10      // ReadOnly: indicate current UDM pin level
+#define  RB_UH_LOW_SPEED     0x04      // enable USB port low speed: 0=full speed, 1=low speed
+#define  RB_UH_BUS_RESET     0x02      // control USB bus reset: 0=normal, 1=force bus reset
+#define  RB_UH_PORT_EN       0x01      // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
+
+#define R8_USB_INT_EN        (*((PUINT8V)(0x40008002))) // USB interrupt enable
+#define  RB_UIE_DEV_SOF      0x80      // enable interrupt for SOF received for USB device mode
+#define  RB_UIE_DEV_NAK      0x40      // enable interrupt for NAK responded for USB device mode
+#define  RB_UIE_FIFO_OV      0x10      // enable interrupt for FIFO overflow
+#define  RB_UIE_HST_SOF      0x08      // enable interrupt for host SOF timer action for USB host mode
+#define  RB_UIE_SUSPEND      0x04      // enable interrupt for USB suspend or resume event
+#define  RB_UIE_TRANSFER     0x02      // enable interrupt for USB transfer completion
+#define  RB_UIE_DETECT       0x01      // enable interrupt for USB device detected event for USB host mode
+#define  RB_UIE_BUS_RST      0x01      // enable interrupt for USB bus reset event for USB device mode
+
+#define R8_USB_DEV_AD        (*((PUINT8V)(0x40008003))) // USB device address
+#define  RB_UDA_GP_BIT       0x80      // general purpose bit
+#define  MASK_USB_ADDR       0x7F      // bit mask for USB device address
+
+#define R32_USB_STATUS       (*((PUINT32V)(0x40008004))) // USB miscellaneous status & interrupt flag & interrupt status
+#define R8_USB_MIS_ST        (*((PUINT8V)(0x40008005))) // USB miscellaneous status
+#define  RB_UMS_SOF_PRES     0x80      // RO, indicate host SOF timer presage status
+#define  RB_UMS_SOF_ACT      0x40      // RO, indicate host SOF timer action status for USB host
+#define  RB_UMS_SIE_FREE     0x20      // RO, indicate USB SIE free status
+#define  RB_UMS_R_FIFO_RDY   0x10      // RO, indicate USB receiving FIFO ready status (not empty)
+#define  RB_UMS_BUS_RESET    0x08      // RO, indicate USB bus reset status
+#define  RB_UMS_SUSPEND      0x04      // RO, indicate USB suspend status
+#define  RB_UMS_DM_LEVEL     0x02      // RO, indicate UDM level saved at device attached to USB host
+#define  RB_UMS_DEV_ATTACH   0x01      // RO, indicate device attached status on USB host
+
+#define R8_USB_INT_FG        (*((PUINT8V)(0x40008006))) // USB interrupt flag
+#define  RB_U_IS_NAK         0x80      // RO, indicate current USB transfer is NAK received
+#define  RB_U_TOG_OK         0x40      // RO, indicate current USB transfer toggle is OK
+#define  RB_U_SIE_FREE       0x20      // RO, indicate USB SIE free status
+#define  RB_UIF_FIFO_OV      0x10      // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
+#define  RB_UIF_HST_SOF      0x08      // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
+#define  RB_UIF_SUSPEND      0x04      // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
+#define  RB_UIF_TRANSFER     0x02      // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
+#define  RB_UIF_DETECT       0x01      // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
+#define  RB_UIF_BUS_RST      0x01      // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
+
+#define R8_USB_INT_ST        (*((PUINT8V)(0x40008007))) // USB interrupt status
+#define  RB_UIS_IS_NAK       0x80      // RO, indicate current USB transfer is NAK received for USB device mode
+#define  RB_UIS_TOG_OK       0x40      // RO, indicate current USB transfer toggle is OK
+#define  RB_UIS_TOKEN1       0x20      // RO, current token PID code bit 1 received for USB device mode
+#define  RB_UIS_TOKEN0       0x10      // RO, current token PID code bit 0 received for USB device mode
+#define  MASK_UIS_TOKEN      0x30      // RO, bit mask of current token PID code received for USB device mode
+#define  UIS_TOKEN_OUT       0x00
+#define  UIS_TOKEN_SOF       0x10
+#define  UIS_TOKEN_IN        0x20
+#define  UIS_TOKEN_SETUP     0x30
+// bUIS_TOKEN1 & bUIS_TOKEN0: current token PID code received for USB device mode
+//   00: OUT token PID received
+//   01: SOF token PID received
+//   10: IN token PID received
+//   11: SETUP token PID received
+#define  MASK_UIS_ENDP       0x0F      // RO, bit mask of current transfer endpoint number for USB device mode
+#define  MASK_UIS_H_RES      0x0F      // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
+
+#define R8_USB_RX_LEN        (*((PUINT8V)(0x40008008))) // USB receiving length
+#define R32_USB_BUF_MODE     (*((PUINT32V)(0x4000800c))) // USB endpoint buffer mode
+#define R8_UEP4_1_MOD        (*((PUINT8V)(0x4000800c))) // endpoint 4/1 mode
+#define  RB_UEP1_RX_EN       0x80      // enable USB endpoint 1 receiving (OUT)
+#define  RB_UEP1_TX_EN       0x40      // enable USB endpoint 1 transmittal (IN)
+#define  RB_UEP1_BUF_MOD     0x10      // buffer mode of USB endpoint 1
+// bUEPn_RX_EN & bUEPn_TX_EN & bUEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
+//   0 0 x:  disable endpoint and disable buffer
+//   1 0 0:  64 bytes buffer for receiving (OUT endpoint)
+//   1 0 1:  dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
+//   0 1 0:  64 bytes buffer for transmittal (IN endpoint)
+//   0 1 1:  dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
+//   1 1 0:  64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
+//   1 1 1:  dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
+#define  RB_UEP4_RX_EN       0x08      // enable USB endpoint 4 receiving (OUT)
+#define  RB_UEP4_TX_EN       0x04      // enable USB endpoint 4 transmittal (IN)
+// bUEP4_RX_EN & bUEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
+//   0 0:  single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
+//   1 0:  single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
+//   0 1:  single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
+//   1 1:  single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
+//           + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
+
+#define R8_UEP2_3_MOD        (*((PUINT8V)(0x4000800d))) // endpoint 2/3 mode
+#define  RB_UEP3_RX_EN       0x80      // enable USB endpoint 3 receiving (OUT)
+#define  RB_UEP3_TX_EN       0x40      // enable USB endpoint 3 transmittal (IN)
+#define  RB_UEP3_BUF_MOD     0x10      // buffer mode of USB endpoint 3
+#define  RB_UEP2_RX_EN       0x08      // enable USB endpoint 2 receiving (OUT)
+#define  RB_UEP2_TX_EN       0x04      // enable USB endpoint 2 transmittal (IN)
+#define  RB_UEP2_BUF_MOD     0x01      // buffer mode of USB endpoint 2
+
+#define R8_UH_EP_MOD         R8_UEP2_3_MOD //host endpoint mode
+#define  RB_UH_EP_TX_EN      0x40      // enable USB host OUT endpoint transmittal
+#define  RB_UH_EP_TBUF_MOD   0x10      // buffer mode of USB host OUT endpoint
+// bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
+//   0 x:  disable endpoint and disable buffer
+//   1 0:  64 bytes buffer for transmittal (OUT endpoint)
+//   1 1:  dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
+#define  RB_UH_EP_RX_EN      0x08      // enable USB host IN endpoint receiving
+#define  RB_UH_EP_RBUF_MOD   0x01      // buffer mode of USB host IN endpoint
+// bUH_EP_RX_EN & bUH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA
+//   0 x:  disable endpoint and disable buffer
+//   1 0:  64 bytes buffer for receiving (IN endpoint)
+//   1 1:  dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes
+
+#define R16_UEP0_DMA         (*((PUINT16V)(0x40008010))) // endpoint 0 DMA buffer address
+#define R16_UEP1_DMA         (*((PUINT16V)(0x40008014))) // endpoint 1 DMA buffer address
+#define R16_UEP2_DMA         (*((PUINT16V)(0x40008018))) // endpoint 2 DMA buffer address
+#define R16_UH_RX_DMA        R16_UEP2_DMA // host rx endpoint buffer high address
+#define R16_UEP3_DMA         (*((PUINT16V)(0x4000801C))) // endpoint 3 DMA buffer address
+#define R16_UH_TX_DMA        R16_UEP3_DMA // host tx endpoint buffer high address
+#define R32_USB_EP0_CTRL     (*((PUINT32V)(0x40008020))) // endpoint 0 control & transmittal length
+#define R8_UEP0_T_LEN        (*((PUINT8V)(0x40008020))) // endpoint 0 transmittal length
+#define R8_UEP0_CTRL         (*((PUINT8V)(0x40008022))) // endpoint 0 control
+#define R32_USB_EP1_CTRL     (*((PUINT32V)(0x40008024))) // endpoint 1 control & transmittal length
+#define R8_UEP1_T_LEN        (*((PUINT8V)(0x40008024))) // endpoint 1 transmittal length
+#define R8_UEP1_CTRL         (*((PUINT8V)(0x40008026))) // endpoint 1 control
+#define  RB_UEP_R_TOG        0x80      // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
+#define  RB_UEP_T_TOG        0x40      // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
+#define  RB_UEP_AUTO_TOG     0x10      // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
+#define  RB_UEP_R_RES1       0x08      // handshake response type high bit for USB endpoint X receiving (OUT)
+#define  RB_UEP_R_RES0       0x04      // handshake response type low bit for USB endpoint X receiving (OUT)
+#define  MASK_UEP_R_RES      0x0C      // bit mask of handshake response type for USB endpoint X receiving (OUT)
+#define  UEP_R_RES_ACK       0x00
+#define  UEP_R_RES_TOUT      0x04
+#define  UEP_R_RES_NAK       0x08
+#define  UEP_R_RES_STALL     0x0C
+// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
+//   00: ACK (ready)
+//   01: no response, time out to host, for non-zero endpoint isochronous transactions
+//   10: NAK (busy)
+//   11: STALL (error)
+#define  RB_UEP_T_RES1       0x02      // handshake response type high bit for USB endpoint X transmittal (IN)
+#define  RB_UEP_T_RES0       0x01      // handshake response type low bit for USB endpoint X transmittal (IN)
+#define  MASK_UEP_T_RES      0x03      // bit mask of handshake response type for USB endpoint X transmittal (IN)
+#define  UEP_T_RES_ACK       0x00
+#define  UEP_T_RES_TOUT      0x01
+#define  UEP_T_RES_NAK       0x02
+#define  UEP_T_RES_STALL     0x03
+// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
+//   00: DATA0 or DATA1 then expecting ACK (ready)
+//   01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
+//   10: NAK (busy)
+//   11: STALL (error)
+
+#define R8_UH_SETUP          R8_UEP1_CTRL // host aux setup
+#define  RB_UH_PRE_PID_EN    0x80      // USB host PRE PID enable for low speed device via hub
+#define  RB_UH_SOF_EN        0x40      // USB host automatic SOF enable
+
+#define R32_USB_EP2_CTRL     (*((PUINT32V)(0x40008028))) // endpoint 2 control & transmittal length
+#define R8_UEP2_T_LEN        (*((PUINT8V)(0x40008028))) // endpoint 2 transmittal length
+#define R8_UEP2_CTRL         (*((PUINT8V)(0x4000802a))) // endpoint 2 control
+
+#define R8_UH_EP_PID         R8_UEP2_T_LEN // host endpoint and PID
+#define  MASK_UH_TOKEN       0xF0      // bit mask of token PID for USB host transfer
+#define  MASK_UH_ENDP        0x0F      // bit mask of endpoint number for USB host transfer
+
+#define R8_UH_RX_CTRL        R8_UEP2_CTRL // host receiver endpoint control
+#define  RB_UH_R_TOG         0x80      // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
+#define  RB_UH_R_AUTO_TOG    0x10      // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
+#define  RB_UH_R_RES         0x04      // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
+
+#define R32_USB_EP3_CTRL     (*((PUINT32V)(0x4000802c))) // endpoint 3 control & transmittal length
+#define R8_UEP3_T_LEN        (*((PUINT8V)(0x4000802c))) // endpoint 3 transmittal length
+#define R8_UEP3_CTRL         (*((PUINT8V)(0x4000802e))) // endpoint 3 control
+#define R8_UH_TX_LEN         R8_UEP3_T_LEN // host transmittal endpoint transmittal length
+
+#define R8_UH_TX_CTRL        R8_UEP3_CTRL // host transmittal endpoint control
+#define  RB_UH_T_TOG         0x40      // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
+#define  RB_UH_T_AUTO_TOG    0x10      // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
+#define  RB_UH_T_RES         0x01      // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
+
+#define R32_USB_EP4_CTRL     (*((PUINT32V)(0x40008030))) // endpoint 4 control & transmittal length
+#define R8_UEP4_T_LEN        (*((PUINT8V)(0x40008030))) // endpoint 4 transmittal length
+#define R8_UEP4_CTRL         (*((PUINT8V)(0x40008032))) // endpoint 4 control
+
+#define R8_USB_TYPE_C_CTRL   (*((PUINT8V)(0x40008038))) // USB type-C control
+#define  RB_UTCC_GP_BIT      0x80      // USB general purpose bit
+#define  RB_UCC2_PD_EN       0x40      // USB CC2 5.1K pulldown resistance: 0=disable, 1=enable pulldown
+#define  RB_UCC2_PU1_EN      0x20      // USB CC2 pullup resistance control high bit
+#define  RB_UCC2_PU0_EN      0x10      // USB CC2 pullup resistance control low bit
+#define  RB_VBUS_PD_EN       0x08      // USB VBUS 10K pulldown resistance: 0=disable, 1=enable pullup
+#define  RB_UCC1_PD_EN       0x04      // USB CC1 5.1K pulldown resistance: 0=disable, 1=enable pulldown
+#define  RB_UCC1_PU1_EN      0x02      // USB CC1 pullup resistance control high bit
+#define  RB_UCC1_PU0_EN      0x01      // USB CC1 pullup resistance control low bit
+// RB_UCC?_PU1_EN & RB_UCC?_PU0_EN: USB CC pullup resistance selection
+//   00: disable pullup resistance
+//   01: enable 36K pullup resistance for default USB power
+//   10: enable 12K pullup resistance for 1.5A USB power
+//   11: enable 4.7K pullup resistance for 3A USB power
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__CH579USBSFR_H__
+
+
+#ifndef __USB_TYPE__
+#define __USB_TYPE__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----- USB constant and structure define --------------------------------*/
+
+/* USB PID */
+#ifndef USB_PID_SETUP
+#define USB_PID_NULL            0x00    /* reserved PID */
+#define USB_PID_SOF             0x05
+#define USB_PID_SETUP           0x0D
+#define USB_PID_IN              0x09
+#define USB_PID_OUT             0x01
+#define USB_PID_ACK             0x02
+#define USB_PID_NAK                         0x0A
+#define USB_PID_STALL           0x0E
+#define USB_PID_DATA0           0x03
+#define USB_PID_DATA1           0x0B
+#define USB_PID_PRE             0x0C
+#endif
+
+/* USB standard device request code */
+#ifndef USB_GET_DESCRIPTOR
+#define USB_GET_STATUS          0x00
+#define USB_CLEAR_FEATURE       0x01
+#define USB_SET_FEATURE         0x03
+#define USB_SET_ADDRESS         0x05
+#define USB_GET_DESCRIPTOR      0x06
+#define USB_SET_DESCRIPTOR      0x07
+#define USB_GET_CONFIGURATION   0x08
+#define USB_SET_CONFIGURATION   0x09
+#define USB_GET_INTERFACE       0x0A
+#define USB_SET_INTERFACE       0x0B
+#define USB_SYNCH_FRAME         0x0C
+#endif
+
+/* USB hub class request code */
+#ifndef HUB_GET_DESCRIPTOR
+#define HUB_GET_STATUS          0x00
+#define HUB_CLEAR_FEATURE       0x01
+#define HUB_GET_STATE           0x02
+#define HUB_SET_FEATURE         0x03
+#define HUB_GET_DESCRIPTOR      0x06
+#define HUB_SET_DESCRIPTOR      0x07
+#endif
+
+/* USB HID class request code */
+#ifndef HID_GET_REPORT
+#define HID_GET_REPORT          0x01
+#define HID_GET_IDLE            0x02
+#define HID_GET_PROTOCOL        0x03
+#define HID_SET_REPORT          0x09
+#define HID_SET_IDLE            0x0A
+#define HID_SET_PROTOCOL        0x0B
+#endif
+
+/* Bit define for USB request type */
+#ifndef USB_REQ_TYP_MASK
+#define USB_REQ_TYP_IN          0x80            /* control IN, device to host */
+#define USB_REQ_TYP_OUT         0x00            /* control OUT, host to device */
+#define USB_REQ_TYP_READ        0x80            /* control read, device to host */
+#define USB_REQ_TYP_WRITE       0x00            /* control write, host to device */
+#define USB_REQ_TYP_MASK        0x60            /* bit mask of request type */
+#define USB_REQ_TYP_STANDARD    0x00
+#define USB_REQ_TYP_CLASS       0x20
+#define USB_REQ_TYP_VENDOR      0x40
+#define USB_REQ_TYP_RESERVED    0x60
+#define USB_REQ_RECIP_MASK      0x1F            /* bit mask of request recipient */
+#define USB_REQ_RECIP_DEVICE    0x00
+#define USB_REQ_RECIP_INTERF    0x01
+#define USB_REQ_RECIP_ENDP      0x02
+#define USB_REQ_RECIP_OTHER     0x03
+#endif
+
+/* USB request type for hub class request */
+#ifndef HUB_GET_HUB_DESCRIPTOR
+#define HUB_CLEAR_HUB_FEATURE   0x20
+#define HUB_CLEAR_PORT_FEATURE  0x23
+#define HUB_GET_BUS_STATE       0xA3
+#define HUB_GET_HUB_DESCRIPTOR  0xA0
+#define HUB_GET_HUB_STATUS      0xA0
+#define HUB_GET_PORT_STATUS     0xA3
+#define HUB_SET_HUB_DESCRIPTOR  0x20
+#define HUB_SET_HUB_FEATURE     0x20
+#define HUB_SET_PORT_FEATURE    0x23
+#endif
+
+/* Hub class feature selectors */
+#ifndef HUB_PORT_RESET
+#define HUB_C_HUB_LOCAL_POWER   0
+#define HUB_C_HUB_OVER_CURRENT  1
+#define HUB_PORT_CONNECTION     0
+#define HUB_PORT_ENABLE         1
+#define HUB_PORT_SUSPEND        2
+#define HUB_PORT_OVER_CURRENT   3
+#define HUB_PORT_RESET          4
+#define HUB_PORT_POWER          8
+#define HUB_PORT_LOW_SPEED      9
+#define HUB_C_PORT_CONNECTION   16
+#define HUB_C_PORT_ENABLE       17
+#define HUB_C_PORT_SUSPEND      18
+#define HUB_C_PORT_OVER_CURRENT 19
+#define HUB_C_PORT_RESET        20
+#endif
+
+/* USB descriptor type */
+#ifndef USB_DESCR_TYP_DEVICE
+#define USB_DESCR_TYP_DEVICE    0x01
+#define USB_DESCR_TYP_CONFIG    0x02
+#define USB_DESCR_TYP_STRING    0x03
+#define USB_DESCR_TYP_INTERF    0x04
+#define USB_DESCR_TYP_ENDP      0x05
+#define USB_DESCR_TYP_QUALIF    0x06
+#define USB_DESCR_TYP_SPEED     0x07
+#define USB_DESCR_TYP_OTG       0x09
+#define USB_DESCR_TYP_HID       0x21
+#define USB_DESCR_TYP_REPORT    0x22
+#define USB_DESCR_TYP_PHYSIC    0x23
+#define USB_DESCR_TYP_CS_INTF   0x24
+#define USB_DESCR_TYP_CS_ENDP   0x25
+#define USB_DESCR_TYP_HUB       0x29
+#endif
+
+/* USB device class */
+#ifndef USB_DEV_CLASS_HUB
+#define USB_DEV_CLASS_RESERVED  0x00
+#define USB_DEV_CLASS_AUDIO     0x01
+#define USB_DEV_CLASS_COMMUNIC  0x02
+#define USB_DEV_CLASS_HID       0x03
+#define USB_DEV_CLASS_MONITOR   0x04
+#define USB_DEV_CLASS_PHYSIC_IF 0x05
+#define USB_DEV_CLASS_POWER     0x06
+#define USB_DEV_CLASS_PRINTER   0x07
+#define USB_DEV_CLASS_STORAGE   0x08
+#define USB_DEV_CLASS_HUB       0x09
+#define USB_DEV_CLASS_VEN_SPEC  0xFF
+#endif
+
+/* USB endpoint type and attributes */
+#ifndef USB_ENDP_TYPE_MASK
+#define USB_ENDP_DIR_MASK       0x80
+#define USB_ENDP_ADDR_MASK      0x0F
+#define USB_ENDP_TYPE_MASK      0x03
+#define USB_ENDP_TYPE_CTRL      0x00
+#define USB_ENDP_TYPE_ISOCH     0x01
+#define USB_ENDP_TYPE_BULK      0x02
+#define USB_ENDP_TYPE_INTER     0x03
+#endif
+
+#ifndef USB_DEVICE_ADDR
+#define USB_DEVICE_ADDR         0x02    /* 默认的USB设备地址 */
+#endif
+#ifndef DEFAULT_ENDP0_SIZE
+#define DEFAULT_ENDP0_SIZE      8       /* default maximum packet size for endpoint 0 */
+#endif
+#ifndef MAX_PACKET_SIZE
+#define MAX_PACKET_SIZE         64      /* maximum packet size */
+#endif
+#ifndef USB_BO_CBW_SIZE
+#define USB_BO_CBW_SIZE         0x1F    /* 命令块CBW的总长度 */
+#define USB_BO_CSW_SIZE         0x0D    /* 命令状态块CSW的总长度 */
+#endif
+#ifndef USB_BO_CBW_SIG
+#define USB_BO_CBW_SIG          0x43425355    /* 命令块CBW识别标志'USBC' */
+#define USB_BO_CSW_SIG          0x53425355    /* 命令状态块CSW识别标志'USBS' */
+#endif
+
+//#define __PACKED
+#ifndef __PACKED
+#define __PACKED                __packed
+#endif
+
+__PACKED typedef struct _USB_SETUP_REQ {
+    UINT8 bRequestType;
+    UINT8 bRequest;
+    UINT16 wValue;
+    UINT16 wIndex;
+    UINT16 wLength;
+} USB_SETUP_REQ, *PUSB_SETUP_REQ;
+
+
+__PACKED typedef struct _USB_DEVICE_DESCR {
+    UINT8 bLength;
+    UINT8 bDescriptorType;
+    UINT16 bcdUSB;
+    UINT8 bDeviceClass;
+    UINT8 bDeviceSubClass;
+    UINT8 bDeviceProtocol;
+    UINT8 bMaxPacketSize0;
+    UINT16 idVendor;
+    UINT16 idProduct;
+    UINT16 bcdDevice;
+    UINT8 iManufacturer;
+    UINT8 iProduct;
+    UINT8 iSerialNumber;
+    UINT8 bNumConfigurations;
+} USB_DEV_DESCR, *PUSB_DEV_DESCR;
+
+
+__PACKED typedef struct _USB_CONFIG_DESCR {
+    UINT8 bLength;
+    UINT8 bDescriptorType;
+    UINT16 wTotalLength;
+    UINT8 bNumInterfaces;
+    UINT8 bConfigurationValue;
+    UINT8 iConfiguration;
+    UINT8 bmAttributes;
+    UINT8 MaxPower;
+} USB_CFG_DESCR, *PUSB_CFG_DESCR;
+
+
+__PACKED typedef struct _USB_INTERF_DESCR {
+    UINT8 bLength;
+    UINT8 bDescriptorType;
+    UINT8 bInterfaceNumber;
+    UINT8 bAlternateSetting;
+    UINT8 bNumEndpoints;
+    UINT8 bInterfaceClass;
+    UINT8 bInterfaceSubClass;
+    UINT8 bInterfaceProtocol;
+    UINT8 iInterface;
+} USB_ITF_DESCR, *PUSB_ITF_DESCR;
+
+
+__PACKED typedef struct _USB_ENDPOINT_DESCR {
+    UINT8 bLength;
+    UINT8 bDescriptorType;
+    UINT8 bEndpointAddress;
+    UINT8 bmAttributes;
+    UINT16 wMaxPacketSize;
+    UINT8 bInterval;
+} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
+
+
+__PACKED typedef struct _USB_CONFIG_DESCR_LONG {
+    USB_CFG_DESCR   cfg_descr;
+    USB_ITF_DESCR   itf_descr;
+    USB_ENDP_DESCR  endp_descr[1];
+} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
+
+typedef USB_CFG_DESCR_LONG *PXUSB_CFG_DESCR_LONG;
+
+__PACKED typedef struct _USB_HUB_DESCR {
+    UINT8 bDescLength;
+    UINT8 bDescriptorType;
+    UINT8 bNbrPorts;
+    UINT8 wHubCharacteristicsL;
+    UINT8 wHubCharacteristicsH;
+    UINT8 bPwrOn2PwrGood;
+    UINT8 bHubContrCurrent;
+    UINT8 DeviceRemovable;
+    UINT8 PortPwrCtrlMask;
+} USB_HUB_DESCR, *PUSB_HUB_DESCR;
+
+typedef USB_HUB_DESCR  *PXUSB_HUB_DESCR;
+
+__PACKED typedef struct _USB_HID_DESCR {
+    UINT8 bLength;
+    UINT8 bDescriptorType;
+    UINT16 bcdHID;
+    UINT8 bCountryCode;
+    UINT8 bNumDescriptors;
+    UINT8 bDescriptorTypeX;
+    UINT8 wDescriptorLengthL;
+    UINT8 wDescriptorLengthH;
+} USB_HID_DESCR, *PUSB_HID_DESCR;
+
+typedef USB_HID_DESCR *PXUSB_HID_DESCR;
+
+
+__PACKED typedef struct _UDISK_BOC_CBW { /* command of BulkOnly USB-FlashDisk */
+    UINT32 mCBW_Sig;
+    UINT32 mCBW_Tag;
+    UINT32 mCBW_DataLen;                /* uppest byte of data length, always is 0 */
+    UINT8 mCBW_Flag;                    /* transfer direction and etc. */
+    UINT8 mCBW_LUN;
+    UINT8 mCBW_CB_Len;                  /* length of command block */
+    UINT8 mCBW_CB_Buf[16];              /* command block buffer */
+} UDISK_BOC_CBW, *PUDISK_BOC_CBW;
+
+typedef UDISK_BOC_CBW  *PXUDISK_BOC_CBW;
+
+__PACKED typedef struct _UDISK_BOC_CSW { /* status of BulkOnly USB-FlashDisk */
+    UINT32 mCSW_Sig;
+    UINT32 mCSW_Tag;
+    UINT32 mCSW_Residue;                /* return: remainder bytes */  /* uppest byte of remainder length, always is 0 */
+    UINT8 mCSW_Status;                  /* return: result status */
+} UDISK_BOC_CSW, *PUDISK_BOC_CSW;
+
+typedef UDISK_BOC_CSW  *PXUDISK_BOC_CSW;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __USB_TYPE__

+ 112 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_adc.h

@@ -0,0 +1,112 @@
+
+
+
+#ifndef __CH57x_ADC_H__
+#define __CH57x_ADC_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+
+#define ROM_TMP_85C_ADDR    0x40634
+#define ROM_TMP_25C_ADDR    0x40638
+
+
+/**
+  * @brief  adc single channel define
+  */
+typedef enum
+{
+    CH_EXTIN_0 = 0,         // ADC 外部模拟通道 0
+    CH_EXTIN_1,             // ADC 外部模拟通道 1
+    CH_EXTIN_2,             // ADC 外部模拟通道 2
+    CH_EXTIN_3,             // ADC 外部模拟通道 3
+    CH_EXTIN_4,             // ADC 外部模拟通道 4
+    CH_EXTIN_5,             // ADC 外部模拟通道 5
+    CH_EXTIN_6,             // ADC 外部模拟通道 6
+    CH_EXTIN_7,             // ADC 外部模拟通道 7
+    CH_EXTIN_8,             // ADC 外部模拟通道 8
+    CH_EXTIN_9,             // ADC 外部模拟通道 9
+    CH_EXTIN_10,            // ADC 外部模拟通道 10
+    CH_EXTIN_11,            // ADC 外部模拟通道 11
+    CH_EXTIN_12,            // ADC 外部模拟通道 12
+    CH_EXTIN_13,            // ADC 外部模拟通道 13
+
+    CH_INTE_VBAT,           // ADC 内部电池检测通道
+    CH_INTE_VTEMP,          // ADC 内部温度传感器检测通道
+
+}ADC_SingleChannelTypeDef;
+
+/**
+  * @brief  adc differential channel define
+  */
+typedef enum
+{
+    CH_DIFF_0_2 = 0,            // ADC 差分通道 #0-#2
+    CH_DIFF_1_3,                // ADC 差分通道 #1-#3
+
+}ADC_DiffChannelTypeDef;
+
+/**
+  * @brief  adc sampling clock
+  */
+typedef enum
+{
+    SampleFreq_3_2 = 0,         // 3.2M 采样频率
+    SampleFreq_2_67,            // 2.67M 采样频率
+    SampleFreq_5_33,            // 5.33M 采样频率
+    SampleFreq_4,               // 4M 采样频率
+}ADC_SampClkTypeDef;
+
+
+/**
+  * @brief  adc signal PGA
+  */
+typedef enum
+{
+    ADC_PGA_1_4 = 0,            // -12dB, 1/4倍
+    ADC_PGA_1_2,                // -6dB, 1/2倍
+    ADC_PGA_0,                  // 0dB, 1倍,无增益
+    ADC_PGA_2,                  // 6dB, 2倍
+}ADC_SignalPGATypeDef;
+
+
+// refer to ADC_SingleChannelTypeDef
+#define     ADC_ChannelCfg( d )     (R8_ADC_CHANNEL = d)                                                /* 设置 ADC 采样通道 */
+// refer to ADC_SampClkTypeDef
+#define     ADC_SampClkCfg( d )     (R8_ADC_CFG=R8_ADC_CFG&(~RB_ADC_CLK_DIV)|(d<<6))                    /* 设置 ADC 采样时钟 */
+// refer to ADC_SignalPGATypeDef
+#define     ADC_PGACfg( d )         (R8_ADC_CFG=R8_ADC_CFG&(~RB_ADC_PGA_GAIN)|(d<<4))               /* 设置 ADC 信号增益 */
+#define     ADC_TempCalibCfg( d )   (R8_TEM_SENSOR=R8_TEM_SENSOR&(~RB_TEM_SEN_CALIB)|d)             /* 设置内部温度传感器校准值 */
+
+void ADC_ExtSingleChSampInit( ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga );                     /* 外部信号单通道采样初始化 */
+void ADC_ExtDiffChSampInit( ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga );                       /* 外部信号差分通道采样初始化 */
+void TouchKey_ChSampInit( void );                                                                   /* 触摸按键通道采样初始化 */
+void ADC_InterTSSampInit( void );                                                                   /* 内置温度传感器采样初始化 */
+void ADC_InterBATSampInit( void );                                                                  /* 内置电池电压采样初始化 */
+
+UINT16 ADC_ExcutSingleConver( void );                                                               /* ADC执行单次转换 */
+signed short ADC_DataCalib_Rough( void );
+void ADC_DataCalib_Fine( PUINT16 dat, ADC_SignalPGATypeDef ga );
+UINT16 TouchKey_ExcutSingleConver( UINT8 d );                                                       /* TouchKey转换后数据 */
+int ADC_GetCurrentTS( UINT16 ts_v );                                                              /* 获取当前采样的温度值(℃) */
+
+#define ADC_ReadConverValue()       (R16_ADC_DATA)                                                  /* 读取转换后的数值 */
+#define ADC_StartUp()               (R8_ADC_CONVERT = RB_ADC_START)                                 /* ADC启动转换 */
+#define ADC_GetITStatus()           ( R8_ADC_INT_FLAG & RB_ADC_IF_EOC )                             /* 获取ADC转换完成标志 */
+#define ADC_ClearITFlag()           (R8_ADC_CONVERT = 0)                                            /* 清除ADC转换完成标志 */
+
+#define TouchKey_GetITStatus()      ( R8_ADC_INT_FLAG & RB_ADC_IF_EOC )                             /* 获取TouchKey转换完成标志 */
+#define TouchKey_ClearITFlag()      (R8_TKEY_CTRL |= RB_TKEY_PWR_ON)                                /* 清除TouchKey转换完成标志 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_ADC_H__
+

+ 164 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_clk.h

@@ -0,0 +1,164 @@
+
+
+
+#ifndef __CH57x_CLK_H__
+#define __CH57x_CLK_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+typedef enum
+{
+    CLK_SOURCE_LSI = 0,
+    CLK_SOURCE_LSE,
+    CLK_SOURCE_HSE_32MHz,
+    CLK_SOURCE_HSE_16MHz,
+    CLK_SOURCE_HSE_8MHz,
+    CLK_SOURCE_HSI_32MHz,               //上电默认情况
+    CLK_SOURCE_HSI_16MHz,
+    CLK_SOURCE_HSI_8MHz,
+    CLK_SOURCE_PLL_40MHz,
+    CLK_SOURCE_PLL_32MHz,
+    CLK_SOURCE_PLL_24MHz,
+    CLK_SOURCE_PLL_20MHz,
+    CLK_SOURCE_PLL_16MHz,
+
+}SYS_CLKTypeDef;
+
+
+typedef enum
+{
+    Clk32M_HSI = 0,
+    Clk32M_HSE,
+
+}HClk32MTypeDef;
+
+typedef enum
+{
+    Clk32K_LSI = 0,
+    Clk32K_LSE,
+
+}LClk32KTypeDef;
+
+typedef enum
+{
+    HSE_RCur_75 = 0,
+    HSE_RCur_100,
+    HSE_RCur_125,
+    HSE_RCur_150
+
+}HSECurrentTypeDef;
+
+typedef enum
+{
+    HSECap_10p = 0,
+    HSECap_12p,  HSECap_14p,  HSECap_16p,  HSECap_18p,
+    HSECap_20p,  HSECap_22p,  HSECap_24p
+
+}HSECapTypeDef;
+
+typedef enum
+{
+    LSE_RCur_70 = 0,
+    LSE_RCur_100,
+    LSE_RCur_140,
+    LSE_RCur_200
+
+}LSECurrentTypeDef;
+
+typedef enum
+{
+    LSECap_2p = 0,
+    LSECap_13p,  LSECap_14p,  LSECap_15p,  LSECap_16p,
+    LSECap_17p,  LSECap_18p,  LSECap_19p,  LSECap_20p,
+    LSECap_21p,  LSECap_22p,  LSECap_23p,  LSECap_24p,
+    LSECap_25p,  LSECap_26p,  LSECap_27p
+
+}LSECapTypeDef;
+
+#define  MAX_DAY        0x00004000
+#define  MAX_2_SEC      0x0000A8C0
+//#define    MAX_SEC        0x545FFFFF
+
+#define BEGYEAR                                                 2020
+#define IsLeapYear(yr)                                  (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
+#define YearLength(yr)                                  (IsLeapYear(yr) ? 366 : 365)
+#define monthLength(lpyr,mon)                       ((mon==1) ? (28+lpyr) : ((mon>6) ? ((mon&1)?31:30) : ((mon&1)?30:31)))
+
+/**
+  * @brief  rtc timer mode period define
+  */
+typedef enum
+{
+    Period_0_125_S = 0,         // 0.125s 周期
+    Period_0_25_S,              // 0.25s 周期
+    Period_0_5_S,               // 0.5s 周期
+    Period_1_S,                 // 1s 周期
+    Period_2_S,                 // 2s 周期
+    Period_4_S,                 // 4s 周期
+    Period_8_S,                 // 8s 周期
+    Period_16_S,                // 16s 周期
+}RTC_TMRCycTypeDef;
+
+
+/**
+  * @brief  rtc interrupt event define
+  */
+typedef enum
+{
+    RTC_TRIG_EVENT = 0,         // RTC 触发事件
+    RTC_TMR_EVENT,              // RTC 周期定时事件
+
+}RTC_EVENTTypeDef;
+
+/**
+  * @brief  rtc interrupt event define
+  */
+typedef enum
+{
+    RTC_TRIG_MODE = 0,          // RTC 触发模式
+    RTC_TMR_MODE,               // RTC 周期定时模式
+
+}RTC_MODETypeDef;
+
+
+void SystemInit(void);                          /* 系统时钟初始化 */
+void SetSysClock( SYS_CLKTypeDef sc);           /* 重设系统运行时钟 */
+UINT32 GetSysClock( void );                     /* 获取当前系统时钟 */
+void HClk32M_Select( HClk32MTypeDef hc);        /* 32M 高频时钟来源 */
+void LClk32K_Select( LClk32KTypeDef hc);        /* 32K 低频时钟来源 */
+
+void HSECFG_Current( HSECurrentTypeDef c );     /* HSE晶体 偏置电流配置 */
+void HSECFG_Capacitance( HSECapTypeDef c );     /* HSE晶体 负载电容配置 */
+void LSECFG_Current( LSECurrentTypeDef c );     /* LSE晶体 偏置电流配置 */
+void LSECFG_Capacitance( LSECapTypeDef c );     /* LSE晶体 负载电容配置 */
+
+UINT16 Calibration_LSI( void );             /* 外部32M时钟校准内部32K时钟 */
+
+
+void RTC_InitTime( UINT16 y, UINT16 mon, UINT16 d, UINT16 h, UINT16 m, UINT16 s );          /* RTC时钟初始化当前时间 */
+void RTC_GetTime( PUINT16 py, PUINT16 pmon, PUINT16 pd, PUINT16 ph, PUINT16 pm, PUINT16 ps );       /* 获取当前时间 */
+
+void RTC_SetCycle32k( UINT32 cyc );                         /* 基于LSE/LSI时钟,配置当前RTC 周期数 */
+UINT32 RTC_GetCycle32k( void );                             /* 基于LSE/LSI时钟,获取当前RTC 周期数 */
+
+void RTC_TRIGFunCfg( UINT32 cyc );                          /* RTC触发模式配置间隔时间,基于LSE/LSI时钟,匹配周期数 */
+void RTC_TMRFunCfg( RTC_TMRCycTypeDef t );                  /* RTC定时模式配置 */
+void RTC_ModeFunDisable( RTC_MODETypeDef m );               /* RTC 模式功能关闭 */
+
+UINT8 RTC_GetITFlag( RTC_EVENTTypeDef f );                  /* 获取RTC中断标志 */
+void RTC_ClearITFlag( RTC_EVENTTypeDef f );                 /* 清除RTC中断标志 */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_CLK_H__
+

+ 71 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_common.h

@@ -0,0 +1,71 @@
+
+
+#ifndef __CH57x_COMM_H__
+#define __CH57x_COMM_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#define  NULL           0
+#define  ALL            0xFFFF
+
+#ifndef  SUCCESS
+#define  SUCCESS        0
+#define  FAILED         (!SUCCESS)
+#endif
+
+#ifndef  ENABLE
+#define  DISABLE        0
+#define  ENABLE         (!DISABLE)
+#endif
+
+#define Debug_UART0        0
+#define Debug_UART1        1
+#define Debug_UART2        2
+#define Debug_UART3        3
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifndef  FREQ_SYS
+#define  FREQ_SYS       32000000
+#endif
+
+#if ( CLK_OSC32K == 1 )
+#define CAB_LSIFQ       32000
+#else
+#define CAB_LSIFQ       32768
+#endif
+
+#include <string.h>
+#include "CH57x_clk.h"
+#include "CH57x_uart.h"
+#include "CH57x_gpio.h"
+#include "CH57x_lcd.h"
+#include "CH57x_flash.h"
+#include "CH57x_pwr.h"
+#include "CH57x_pwm.h"
+#include "CH57x_adc.h"
+#include "CH57x_sys.h"
+#include "CH57x_timer.h"
+#include "CH57x_spi.h"
+#include "CH57x_usbdev.h"
+#include "CH57x_usbhost.h"
+
+
+
+
+
+#define DelayMs(x)      mDelaymS(x)
+#define DelayUs(x)      mDelayuS(x)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_COMM_H__
+

+ 35 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_flash.h

@@ -0,0 +1,35 @@
+
+
+
+#ifndef __CH57x_FLASH_H__
+#define __CH57x_FLASH_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+#define ROM_UUID_ADDR        0x40608         // chip UID address ( ID-48bit + CKS-16bit )
+#define ROM_MAC_ADDR         0x40608         // NET MAC address 48bit
+
+// 获取唯一ID
+void GetUniqueID(PUINT8 buf);                                           /* 获取芯片唯一ID,小端模式,6B-ID, 2B-CKS */
+
+// 获取网络MAC
+void GetMACAddress(PUINT8 buf);                                         /* 获取网络MAC,小端模式,6B-MAC */
+
+
+UINT8 FlashBlockErase(UINT32 addr);
+UINT8 FlashWriteDW(UINT32 addr, UINT32 dat);
+UINT8 FlashWriteBuf(UINT32 addr, PUINT32 pdat, UINT16 len);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_FLASH_H__
+

+ 102 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_gpio.h

@@ -0,0 +1,102 @@
+
+
+
+#ifndef __CH57x_GPIO_H__
+#define __CH57x_GPIO_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/**
+  * @brief  GPIO_pins_define
+  */
+#define GPIO_Pin_0                 (0x00000001)  /*!< Pin 0 selected */
+#define GPIO_Pin_1                 (0x00000002)  /*!< Pin 1 selected */
+#define GPIO_Pin_2                 (0x00000004)  /*!< Pin 2 selected */
+#define GPIO_Pin_3                 (0x00000008)  /*!< Pin 3 selected */
+#define GPIO_Pin_4                 (0x00000010)  /*!< Pin 4 selected */
+#define GPIO_Pin_5                 (0x00000020)  /*!< Pin 5 selected */
+#define GPIO_Pin_6                 (0x00000040)  /*!< Pin 6 selected */
+#define GPIO_Pin_7                 (0x00000080)  /*!< Pin 7 selected */
+#define GPIO_Pin_8                 (0x00000100)  /*!< Pin 8 selected */
+#define GPIO_Pin_9                 (0x00000200)  /*!< Pin 9 selected */
+#define GPIO_Pin_10                (0x00000400)  /*!< Pin 10 selected */
+#define GPIO_Pin_11                (0x00000800)  /*!< Pin 11 selected */
+#define GPIO_Pin_12                (0x00001000)  /*!< Pin 12 selected */
+#define GPIO_Pin_13                (0x00002000)  /*!< Pin 13 selected */
+#define GPIO_Pin_14                (0x00004000)  /*!< Pin 14 selected */
+#define GPIO_Pin_15                (0x00008000)  /*!< Pin 15 selected */
+#define GPIO_Pin_16                (0x00010000)  /*!< Pin 16 selected */
+#define GPIO_Pin_17                (0x00020000)  /*!< Pin 17 selected */
+#define GPIO_Pin_18                (0x00040000)  /*!< Pin 18 selected */
+#define GPIO_Pin_19                (0x00080000)  /*!< Pin 19 selected */
+#define GPIO_Pin_20                (0x00100000)  /*!< Pin 20 selected */
+#define GPIO_Pin_21                (0x00200000)  /*!< Pin 21 selected */
+#define GPIO_Pin_22                (0x00400000)  /*!< Pin 22 selected */
+#define GPIO_Pin_23                (0x00800000)  /*!< Pin 23 selected */
+#define GPIO_Pin_All               (0xFFFFFFFF)  /*!< All pins selected */
+
+/**
+  * @brief  Configuration GPIO Mode
+  */
+typedef enum
+{
+    GPIO_ModeIN_Floating,           //浮空输入
+    GPIO_ModeIN_PU,                 //上拉输入
+    GPIO_ModeIN_PD,                 //下拉输入
+    GPIO_ModeOut_PP_5mA,            //推挽输出最大5mA
+    GPIO_ModeOut_PP_20mA,           //推挽输出最大20mA
+
+}GPIOModeTypeDef;
+
+/**
+  * @brief  Configuration GPIO IT Mode
+  */
+typedef enum
+{
+    GPIO_ITMode_LowLevel,           //低电平触发
+    GPIO_ITMode_HighLevel,          //高电平触发
+    GPIO_ITMode_FallEdge,           //下降沿触发
+    GPIO_ITMode_RiseEdge,           //上升沿触发
+
+}GPIOITModeTpDef;
+
+
+
+
+void GPIOA_ModeCfg( UINT32 pin, GPIOModeTypeDef mode );             /* GPIOA端口引脚模式配置 */
+void GPIOB_ModeCfg( UINT32 pin, GPIOModeTypeDef mode );             /* GPIOB端口引脚模式配置 */
+#define GPIOA_ResetBits( pin )          (R32_PA_CLR |= pin)         /* GPIOA端口引脚输出置低 */
+#define GPIOA_SetBits( pin )            (R32_PA_OUT |= pin)         /* GPIOA端口引脚输出置高 */
+#define GPIOB_ResetBits( pin )          (R32_PB_CLR |= pin)         /* GPIOB端口引脚输出置低 */
+#define GPIOB_SetBits( pin )            (R32_PB_OUT |= pin)         /* GPIOB端口引脚输出置高 */
+#define GPIOA_InverseBits( pin )        (R32_PA_OUT ^= pin)         /* GPIOA端口引脚输出电平翻转 */
+#define GPIOB_InverseBits( pin )        (R32_PB_OUT ^= pin)         /* GPIOB端口引脚输出电平翻转 */
+#define GPIOA_ReadPort()                (R32_PA_PIN)                /* GPIOA端口32位数据返回,低16位有效 */
+#define GPIOB_ReadPort()                (R32_PB_PIN)                /* GPIOB端口32位数据返回,低24位有效 */
+#define GPIOA_ReadPortPin( pin )        (R32_PA_PIN&pin)            /* GPIOA端口引脚状态,0-引脚低电平,(!0)-引脚高电平 */
+#define GPIOB_ReadPortPin( pin )        (R32_PB_PIN&pin)            /* GPIOB端口引脚状态,0-引脚低电平,(!0)-引脚高电平 */
+
+void GPIOA_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode );           /* GPIOA引脚中断模式配置 */
+void GPIOB_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode );           /* GPIOB引脚中断模式配置 */
+#define GPIOA_ReadITFlagPort()          (R16_PA_INT_IF)             /* 读取GPIOA端口中断标志状态 */
+#define GPIOB_ReadITFlagPort()          (R16_PB_INT_IF)             /* 读取GPIOB端口中断标志状态 */
+#define GPIOA_ReadITFlagBit( pin )      (R16_PA_INT_IF&pin)         /* 读取GPIOA端口引脚中断标志状态 */
+#define GPIOB_ReadITFlagBit( pin )      (R16_PB_INT_IF&pin)         /* 读取GPIOB端口引脚中断标志状态 */
+#define GPIOA_ClearITFlagBit( pin )     (R16_PA_INT_IF = pin)       /* 清除GPIOA端口引脚中断标志状态 */
+#define GPIOB_ClearITFlagBit( pin )     (R16_PB_INT_IF = pin)       /* 清除GPIOB端口引脚中断标志状态 */
+
+void GPIOPinRemap( UINT8 s, UINT16 perph );             /* 外设功能引脚映射 */
+void GPIOAGPPCfg( UINT8 s, UINT16 perph );              /* 模拟外设GPIO引脚功能控制 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_GPIO_H__
+

+ 91 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_lcd.h

@@ -0,0 +1,91 @@
+
+
+
+#ifndef __CH57x_LCD_H__
+#define __CH57x_LCD_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/**
+  * @brief  Configuration LCD driver power
+  */
+typedef enum
+{
+    LCD_PS_3V3 = 0,                 // 3.3V 驱动
+    LCD_PS_2V5,                     // 2.5V 驱动
+}LCDDrvPowerTypeDef;
+
+
+/**
+  * @brief  Configuration LCD bias
+  */
+typedef enum
+{
+    LCD_1_2_Bias = 0,               // 2级分压
+    LCD_1_3_Bias,                   // 3级分压
+}LCDBiasTypeDef;
+
+/**
+  * @brief  Configuration LCD duty
+  */
+typedef enum
+{
+    LCD_1_2_Duty = 0,               // COM0-COM1
+    LCD_1_3_Duty,                   // COM0-COM2
+    LCD_1_4_Duty,                   // COM0-COM3
+}LCDDutyTypeDef;
+
+/**
+  * @brief  Configuration LCD scan clk
+  */
+typedef enum
+{
+    LCD_CLK_256 = 0,                // 256Hz
+    LCD_CLK_512,                    // 512Hz
+    LCD_CLK_1000,                   // 1KHz
+    LCD_CLK_128                     // 128Hz
+}LCDSCANCLKTypeDef;
+
+
+void LCD_DefInit( void );               /* LCD段式屏驱动默认初始化配置 */
+
+#define LCD_PowerDown()         (R8_LCD_CTRL_MOD &= ~(RB_LCD_POWER_ON|RB_SYS_POWER_ON))     /* LCD功能模块关闭 */
+#define LCD_PowerOn()           (R8_LCD_CTRL_MOD |= (RB_LCD_POWER_ON|RB_SYS_POWER_ON))      /* LCD功能模块开启 */
+
+// 输入值参考 LCDDrvPowerTypeDef
+#define LCD_PowerCfg( d )       (R8_LCD_CTRL_MOD=R8_LCD_CTRL_MOD&0x7F|(d<<7))               /* 配置LCD的 供电电压选择 */
+// 输入值参考 LCDSCANCLKTypeDef
+#define LCD_ScanCLKCfg( d )     (R8_LCD_CTRL_MOD=R8_LCD_CTRL_MOD&0x9F|(d<<5))               /* 配置LCD的 扫描时钟选择 */
+// 输入值参考 LCDDutyTypeDef
+#define LCD_DutyCfg( d )        (R8_LCD_CTRL_MOD=R8_LCD_CTRL_MOD&0xE7|(d<<3))               /* 配置LCD的 duty选择 */
+// 输入值参考 LCDBiasTypeDef
+#define LCD_BiasCfg( d )        (R8_LCD_CTRL_MOD=R8_LCD_CTRL_MOD&0xFB|(d<<2))               /* 配置LCD的 bias选择 */
+
+#define LCD_WriteData0( d )     (R32_LCD_RAM0=R32_LCD_RAM0&0xffffff00|((UINT32)d))          /* 填充SEG0驱动数值 */
+#define LCD_WriteData1( d )     (R32_LCD_RAM0=R32_LCD_RAM0&0xffff00ff|((UINT32)d<<8))       /* 填充SEG1驱动数值 */
+#define LCD_WriteData2( d )     (R32_LCD_RAM0=R32_LCD_RAM0&0xff00ffff|((UINT32)d<<16))      /* 填充SEG2驱动数值 */
+#define LCD_WriteData3( d )     (R32_LCD_RAM0=R32_LCD_RAM0&0x00ffffff|((UINT32)d<<24))      /* 填充SEG3驱动数值 */
+
+#define LCD_WriteData4( d )     (R32_LCD_RAM1=R32_LCD_RAM1&0xffffff00|((UINT32)d))          /* 填充SEG4驱动数值 */
+#define LCD_WriteData5( d )     (R32_LCD_RAM1=R32_LCD_RAM1&0xffff00ff|((UINT32)d<<8))       /* 填充SEG5驱动数值 */
+#define LCD_WriteData6( d )     (R32_LCD_RAM1=R32_LCD_RAM1&0xff00ffff|((UINT32)d<<16))      /* 填充SEG6驱动数值 */
+#define LCD_WriteData7( d )     (R32_LCD_RAM1=R32_LCD_RAM1&0x00ffffff|((UINT32)d<<24))      /* 填充SEG7驱动数值 */
+
+#define LCD_WriteData8( d )     (R32_LCD_RAM2=R32_LCD_RAM2&0xffffff00|((UINT32)d))          /* 填充SEG8驱动数值 */
+#define LCD_WriteData9( d )     (R32_LCD_RAM2=R32_LCD_RAM2&0xffff00ff|((UINT32)d<<8))       /* 填充SEG9驱动数值 */
+#define LCD_WriteData10( d )        (R32_LCD_RAM2=R32_LCD_RAM2&0xff00ffff|((UINT32)d<<16))      /* 填充SEG10驱动数值 */
+#define LCD_WriteData11( d )        (R32_LCD_RAM2=R32_LCD_RAM2&0x00ffffff|((UINT32)d<<24))      /* 填充SEG11驱动数值 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_LCD_H__
+

+ 80 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_pwm.h

@@ -0,0 +1,80 @@
+
+
+
+#ifndef __CH57x_PWM_H__
+#define __CH57x_PWM_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/**
+  * @brief  channel of PWM define
+  */
+
+#define CH_PWM4     0x01                // PWM4 通道
+#define CH_PWM5     0x02                // PWM5 通道
+#define CH_PWM6     0x04                // PWM6 通道
+#define CH_PWM7     0x08                // PWM7 通道
+#define CH_PWM8     0x10                // PWM8 通道
+#define CH_PWM9     0x20                // PWM9 通道
+#define CH_PWM10    0x40                // PWM10 通道
+#define CH_PWM11    0x80                // PWM11 通道
+
+
+
+/**
+  * @brief  channel of PWM define
+  */
+typedef enum
+{
+    High_Level = 0,                     // 默认低电平,高电平有效
+    Low_Level,                          // 默认高电平,低电平有效
+}PWMX_PolarTypeDef;
+
+
+/**
+  * @brief  Configuration PWM4_11 Cycle size
+  */
+typedef enum
+{
+    PWMX_Cycle_256 = 0,                 // 256 个PWMX周期
+    PWMX_Cycle_255,                     // 255 个PWMX周期
+    PWMX_Cycle_128,                     // 128 个PWMX周期
+    PWMX_Cycle_127,                     // 127 个PWMX周期
+    PWMX_Cycle_64,                      // 64 个PWMX周期
+    PWMX_Cycle_63,                      // 63 个PWMX周期
+    PWMX_Cycle_32,                      // 32 个PWMX周期
+    PWMX_Cycle_31,                      // 31 个PWMX周期
+}PWMX_CycleTypeDef;
+
+
+#define PWMX_CLKCfg( d )            (R8_PWM_CLOCK_DIV=d)                /* PWM4-PWM11 通道基准时钟配置,= d*Tsys */
+void PWMX_CycleCfg( PWMX_CycleTypeDef cyc );                            /* PWM4-PWM11 通道输出波形周期配置 */
+
+#define PWM4_ActDataWidth( d )      (R8_PWM4_DATA = d)                  /* PWM4 有效数据脉宽 */
+#define PWM5_ActDataWidth( d )      (R8_PWM5_DATA = d)                  /* PWM5 有效数据脉宽 */
+#define PWM6_ActDataWidth( d )      (R8_PWM6_DATA = d)                  /* PWM6 有效数据脉宽 */
+#define PWM7_ActDataWidth( d )      (R8_PWM7_DATA = d)                  /* PWM7 有效数据脉宽 */
+#define PWM8_ActDataWidth( d )      (R8_PWM8_DATA = d)                  /* PWM8 有效数据脉宽 */
+#define PWM9_ActDataWidth( d )      (R8_PWM9_DATA = d)                  /* PWM9 有效数据脉宽 */
+#define PWM10_ActDataWidth( d )     (R8_PWM10_DATA = d)                 /* PWM10 有效数据脉宽 */
+#define PWM11_ActDataWidth( d )     (R8_PWM11_DATA = d)                 /* PWM11 有效数据脉宽 */
+
+// 占空比 = 数据有效脉宽/波形周期
+void PWMX_ACTOUT( UINT8 ch, UINT8 da, PWMX_PolarTypeDef pr, UINT8 s);   /* PWM4-PWM11通道输出波形配置 */
+void PWMX_AlterOutCfg( UINT8 ch, UINT8 s);          /* PWM 交替输出模式配置 */
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_PWM_H__
+

+ 69 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_pwr.h

@@ -0,0 +1,69 @@
+
+
+
+#ifndef __CH57x_PWR_H__
+#define __CH57x_PWR_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/**
+  * @brief  Peripher CLK control bit define
+  */
+#define BIT_SLP_CLK_TMR0                 (0x00000001)  /*!< TMR0 peripher clk bit */
+#define BIT_SLP_CLK_TMR1                 (0x00000002)  /*!< TMR1 peripher clk bit */
+#define BIT_SLP_CLK_TMR2                 (0x00000004)  /*!< TMR2 peripher clk bit */
+#define BIT_SLP_CLK_TMR3                 (0x00000008)  /*!< TMR3 peripher clk bit */
+#define BIT_SLP_CLK_UART0                (0x00000010)  /*!< UART0 peripher clk bit */
+#define BIT_SLP_CLK_UART1                (0x00000020)  /*!< UART1 peripher clk bit */
+#define BIT_SLP_CLK_UART2                (0x00000040)  /*!< UART2 peripher clk bit */
+#define BIT_SLP_CLK_UART3                (0x00000080)  /*!< UART3 peripher clk bit */
+#define BIT_SLP_CLK_SPI0                 (0x00000100)  /*!< SPI0 peripher clk bit */
+#define BIT_SLP_CLK_SPI1                 (0x00000200)  /*!< SPI1 peripher clk bit */
+#define BIT_SLP_CLK_PWMX                 (0x00000400)  /*!< PWMX peripher clk bit */
+#define BIT_SLP_CLK_LCD                  (0x00000800)  /*!< LCD peripher clk bit */
+#define BIT_SLP_CLK_USB                  (0x00001000)  /*!< USB peripher clk bit */
+#define BIT_SLP_CLK_ETH                  (0x00002000)  /*!< ETH peripher clk bit */
+#define BIT_SLP_CLK_LED                  (0x00004000)  /*!< LED peripher clk bit */
+#define BIT_SLP_CLK_BLE                  (0x00008000)  /*!< BLE peripher clk bit */
+#define BIT_SLP_CLK_RAMX                 (0x10000000)  /*!< RAM14K peripher clk bit */
+#define BIT_SLP_CLK_RAM2K                (0x20000000)  /*!< RAM2K peripher clk bit */
+#define BIT_SLP_CLK_ALL                  (0x3000FFFF)  /*!< All peripher clk bit */
+
+/**
+  * @brief  unit of controllable power supply
+  */
+#define UNIT_SYS_LSE                RB_CLK_XT32K_PON        // 外部32K 时钟振荡
+#define UNIT_SYS_LSI                RB_CLK_INT32K_PON       // 内部32K 时钟振荡
+#define UNIT_SYS_HSE                RB_CLK_XT32M_PON        // 外部32M 时钟振荡
+#define UNIT_SYS_HSI                RB_CLK_INT32M_PON       // 内部32M 时钟振荡
+#define UNIT_SYS_PLL                RB_CLK_PLL_PON          // PLL 时钟振荡
+#define UNIT_ETH_PHY                (0x80)                  // 以太网收发器 ETH-PHY
+
+
+void PWR_DCDCCfg( UINT8 s );                                  /* 内部DC/DC电源控制 */
+void PWR_UnitModCfg( UINT8 s, UINT8 unit );                   /* 可控单元模块的电源控制 */
+void PWR_PeriphClkCfg( UINT8 s, UINT16 perph );               /* 外设时钟控制位 */
+
+void PowerMonitor( UINT8 s );                                 /* 电源电压监控功能控制 */
+
+void PWR_PeriphWakeUpCfg( UINT8 s, UINT16 perph );              /* 睡眠唤醒源配置 */
+void LowPower_Idle( void );                                 /* 低功耗-IDLE模式 */
+void LowPower_Halt_1( void );                               /* 低功耗-Halt_1模式 */
+void LowPower_Halt_2( void );                               /* 低功耗-Halt_2模式 */
+void LowPower_Sleep( UINT8 rm );                            /* 低功耗-Sleep模式 */
+void LowPower_Shutdown( UINT8 rm );                         /* 低功耗-Shutdown模式 */
+void EnterCodeUpgrade( void );                              /* 跳入BOOT程序,准备代码升级 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_PWR_H__
+

+ 108 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_spi.h

@@ -0,0 +1,108 @@
+
+
+
+#ifndef __CH57x_SPI_H__
+#define __CH57x_SPI_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/**
+  * @brief  SPI0 interrupt bit define
+  */
+
+#define SPI0_IT_FST_BYTE        RB_SPI_IE_FST_BYTE              // 从机模式的首字节命令模式下,接收到首字节中断
+#define SPI0_IT_FIFO_OV         RB_SPI_IE_FIFO_OV               // FIFO 溢出
+#define SPI0_IT_DMA_END         RB_SPI_IE_DMA_END               // DMA 传输结束
+#define SPI0_IT_FIFO_HF         RB_SPI_IE_FIFO_HF               // FIFO 使用过半
+#define SPI0_IT_BYTE_END        RB_SPI_IE_BYTE_END              // 单字节传输完成
+#define SPI0_IT_CNT_END         RB_SPI_IE_CNT_END               // 全部字节传输完成
+
+
+
+/**
+  * @brief  Configuration data mode
+  */
+typedef enum
+{
+    Mode0_LowBitINFront = 0,                    // 模式0,低位在前
+    Mode0_HighBitINFront,                       // 模式0,高位在前
+    Mode3_LowBitINFront,                        // 模式3,低位在前
+    Mode3_HighBitINFront,                       // 模式3,高位在前
+}ModeBitOrderTypeDef;
+
+
+/**
+  * @brief  Configuration SPI0 slave mode
+  */
+typedef enum
+{
+    Mode_DataStream = 0,                // 数据流模式
+    Mose_FirstCmd,                      // 首字节命令模式
+}Slave_ModeTypeDef;
+
+
+/**************** SPI0 */
+void SPI0_MasterDefInit( void );                            /* 主机模式默认初始化:模式0+3线全双工+8MHz */
+void SPI0_CLKCfg( UINT8 c );                                /* SPI0 基准时钟配置,= d*Tsys */
+void SPI0_DataMode( ModeBitOrderTypeDef m );                /* 设置数据流模式 */
+
+void SPI0_MasterSendByte( UINT8 d );                        /* 发送单字节 (buffer) */
+UINT8 SPI0_MasterRecvByte( void );                          /* 接收单字节 (buffer) */
+
+void SPI0_MasterTrans( UINT8 *pbuf, UINT16 len );           /* 使用FIFO连续发送多字节 */
+void SPI0_MasterRecv( UINT8 *pbuf, UINT16 len );            /* 使用FIFO连续接收多字节 */
+
+void SPI0_MasterDMATrans( PUINT8 pbuf, UINT16 len);         /* DMA方式连续发送数据   */
+void SPI0_MasterDMARecv( PUINT8 pbuf, UINT16 len);          /* DMA方式连续接收数据  */
+
+
+void SPI0_SlaveInit( void );                                /* 设备模式默认初始化,建议设置MISO的GPIO对应为输入模式 */
+#define SetFirstData(d)         (R8_SPI0_SLAVE_PRE = d)     /* 加载首字节数据内容 */
+void SPI0_SlaveSendByte( UINT8 d );                         /* 从机模式,发送一字节数据 */
+UINT8 SPI0_SlaveRecvByte( void );                           /* 从机模式,接收一字节数据 */
+
+void SPI0_SlaveTrans( UINT8 *pbuf, UINT16 len );            /* 从机模式,发送多字节数据 */
+void SPI0_SlaveRecv( PUINT8 pbuf, UINT16 len );             /* 从机模式,接收多字节数据  */
+
+void SPI0_SlaveDMATrans( PUINT8 pbuf, UINT16 len);          /* 从机模式,DMA方式发送多字节数据 */
+void SPI0_SlaveDMARecv( PUINT8 pbuf, UINT16 len);           /* 从机模式,DMA方式接收多字节数据 */
+
+// refer to SPI0 interrupt bit define
+#define SPI0_ITCfg(s,f)         ((s)?(R8_SPI0_INTER_EN|=f):(R8_SPI0_INTER_EN&=~f))
+#define SPI0_GetITFlag(f)       (R8_SPI0_INT_FLAG&f)        /* 获取中断标志状态,0-未置位,(!0)-触发 */
+#define SPI0_ClearITFlag(f)     (R8_SPI0_INT_FLAG = f)      /* 清除当前中断标志 */
+
+
+
+
+/**************** SPI1 */
+void SPI1_MasterDefInit( void );                            /* 主机模式默认初始化:模式0+3线全双工+8MHz */
+void SPI1_CLKCfg( UINT8 c );                                /* SPI1 基准时钟配置,= d*Tsys */
+void SPI1_DataMode( ModeBitOrderTypeDef m );                /* 设置数据流模式 */
+
+void SPI1_MasterSendByte( UINT8 d );                        /* 发送单字节 (buffer) */
+UINT8 SPI1_MasterRecvByte( void );                          /* 接收单字节 (buffer) */
+
+void SPI1_MasterTrans( UINT8 *pbuf, UINT16 len );           /* 使用FIFO连续发送多字节 */
+void SPI1_MasterRecv( UINT8 *pbuf, UINT16 len );            /* 使用FIFO连续接收多字节 */
+
+
+// refer to SPI1 interrupt bit define
+#define SPI1_ITCfg(s,f)         ((s)?(R8_SPI1_INTER_EN|=f):(R8_SPI1_INTER_EN&=~f))
+#define SPI1_GetITFlag(f)       (R8_SPI1_INT_FLAG&f)        /* 获取中断标志状态,0-未置位,(!0)-触发 */
+#define SPI1_ClearITFlag(f)     (R8_SPI1_INT_FLAG = f)      /* 清除当前中断标志 */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_SPI_H__
+

+ 76 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_sys.h

@@ -0,0 +1,76 @@
+
+
+
+#ifndef __CH57x_SYS_H__
+#define __CH57x_SYS_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+
+
+/**
+  * @brief  rtc interrupt event define
+  */
+typedef enum
+{
+    RST_STATUS_SW = 0,          // 软件复位
+    RST_STATUS_RPOR,            // 上电复位
+    RST_STATUS_WTR,             // 看门狗超时复位
+    RST_STATUS_MR,              // 外部手动复位
+    RST_STATUS_LRM0,            // 唤醒复位-软复位引起
+    RST_STATUS_GPWSM,           // 下电模式唤醒复位
+    RST_STATUS_LRM1,            //  唤醒复位-看门狗引起
+    RST_STATUS_LRM2,            //  唤醒复位-手动复位引起
+
+}SYS_ResetStaTypeDef;
+
+/**
+  * @brief  rtc interrupt event define
+  */
+typedef enum
+{
+    INFO_ROM_READ = 0,          // FlashROM 代码和数据区 是否可读
+    INFO_RESET_EN = 2,          // RST#外部手动复位输入功能是否开启
+    INFO_BOOT_EN,               // 系统引导程序 BootLoader 是否开启
+    INFO_DEBUG_EN,              // 系统仿真调试接口是否开启
+    INFO_LOADER,                // 当前系统是否处于Bootloader 区
+    STA_SAFEACC_ACT,            // 当前系统是否处于安全访问状态,否则RWA属性区域不可访问
+
+}SYS_InfoStaTypeDef;
+
+
+#define SYS_GetChipID()             R8_CHIP_ID                                  /* 获取芯片ID类,一般为固定值 */
+#define SYS_GetAccessID()           R8_SAFE_ACCESS_ID                           /* 获取安全访问ID,一般为固定值 */
+UINT8 SYS_GetInfoSta( SYS_InfoStaTypeDef i );                                   /* 获取当前系统信息状态 */
+// refer to SYS_ResetStaTypeDef
+#define SYS_GetLastResetSta()       (R8_RESET_STATUS&RB_RESET_FLAG)             /* 获取系统上次复位状态 */
+void SYS_ResetExecute( void );                                                  /* 执行系统软件复位 */
+#define SYS_ResetKeepBuf( d )       (R8_GLOB_RESET_KEEP = d)                    /* 不受手动复位、 软件复位、 看门狗复位或者普通唤醒复位的影响 */
+
+void SYS_DisableAllIrq( PUINT32 pirqv);                                         /* 关闭所有中断,并保留当前中断值 */
+void SYS_RecoverIrq( UINT32 irq_status );                                       /* 恢复之前关闭的中断值 */
+UINT32 SYS_GetSysTickCnt( void );                                               /* 获取当前系统(SYSTICK)计数值 */
+
+#define  WWDG_SetCounter( c )       (R8_WDOG_COUNT = c)                         /* 加载看门狗计数初值,递增型 */
+void  WWDG_ITCfg( UINT8 s );                            /* 看门狗溢出中断使能 */
+void  WWDG_ResetCfg( UINT8 s );                         /* 看门狗溢出复位使能 */
+#define  WWDG_GetFlowFlag()         (R8_RST_WDOG_CTRL&RB_WDOG_INT_FLAG)         /* 获取当前看门狗定时器溢出标志 */
+void WWDG_ClearFlag(void);                                                      /* 清除看门狗中断标志,重新加载计数值也可清除 */
+
+
+void mDelayuS( UINT16 t );      /* uS 延时 */
+void mDelaymS( UINT16 t );      /* mS 延时 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_SYS_H__
+

+ 197 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_timer.h

@@ -0,0 +1,197 @@
+
+
+
+#ifndef __CH57x_TIMER_H__
+#define __CH57x_TIMER_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+#define DataBit_25  (1<<25)
+
+
+/**
+  * @brief  TMR0 interrupt bit define
+  */
+
+#define TMR0_3_IT_CYC_END       0x01                // 周期结束标志:捕捉-超时,定时-周期结束,PWM-周期结束
+#define TMR0_3_IT_DATA_ACT      0x02                // 数据有效标志:捕捉-新数据,PWM-有效电平结束
+#define TMR0_3_IT_FIFO_HF       0x04                // FIFO 使用过半:捕捉- FIFO>=4, PWM- FIFO<4
+#define TMR1_2_IT_DMA_END       0x08                // DMA 结束,支持TMR1和TMR2
+#define TMR0_3_IT_FIFO_OV       0x10                // FIFO 溢出:捕捉- FIFO满, PWM- FIFO空
+
+
+/**
+  * @brief  Configuration PWM effective level repeat times
+  */
+typedef enum
+{
+    PWM_Times_1 = 0,                    // PWM 有效输出重复1次数
+    PWM_Times_4,                        // PWM 有效输出重复4次数
+    PWM_Times_8,                        // PWM 有效输出重复8次数
+    PWM_Times_16,                       // PWM 有效输出重复16次数
+}PWM_RepeatTsTypeDef;
+
+
+/**
+  * @brief  Configuration Cap mode
+  */
+typedef enum
+{
+    CAP_NULL = 0,                       // 不捕捉 & 不计数
+    Edge_To_Edge,                       // 任意边沿之间  &  计数任意边沿
+    FallEdge_To_FallEdge,               // 下降沿到下降沿  & 计数下降沿
+    RiseEdge_To_RiseEdge,               // 上升沿到上升沿  &  计数上升沿
+}CapModeTypeDef;
+
+/**
+  * @brief  Configuration DMA mode
+  */
+typedef enum
+{
+    Mode_Single = 0,                // 单次模式
+    Mode_LOOP,                      // 循环模式
+}DMAModeTypeDef;
+
+
+/****************** TMR0 */
+// 定时功能
+void TMR0_TimerInit( UINT32 t );                                    /* 定时功能初始化 */
+void TMR0_EXTSingleCounterInit( UINT32 c );                         /* 外部信号计数功能初始化 */
+#define  TMR0_GetCurrentTimer()     R32_TMR0_COUNT                  /* 获取当前定时器值,最大67108864 */
+
+//计数功能
+void TMR0_CountInit( CapModeTypeDef cap );                          /* 外部信号边沿计数初始化 */
+#define TMR0_CountOverflowCfg( cyc )   (R32_TMR0_CNT_END=(cyc+2))   /* 计数统计溢出大小,最大67108862 */
+#define  TMR0_GetCurrentCount()     R32_TMR0_COUNT                  /* 获取当前计数值,最大67108862 */
+
+// PWM功能
+#define TMR0_PWMCycleCfg( cyc )     (R32_TMR0_CNT_END=cyc)          /* PWM0 通道输出波形周期配置, 最大67108864 */
+void TMR0_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts );  /* PWM 输出初始化 */
+#define TMR0_PWMActDataWidth( d )   (R32_TMR0_FIFO = d)         /* PWM0 有效数据脉宽, 最大67108864 */
+
+// 捕捉脉宽
+#define TMR0_CAPTimeoutCfg( cyc )   (R32_TMR0_CNT_END=cyc)          /* CAP0 捕捉电平超时配置, 最大33554432 */
+void TMR0_CapInit( CapModeTypeDef cap );                            /* 外部信号捕捉功能初始化 */
+#define TMR0_CAPGetData()           R32_TMR0_FIFO                   /* 获取脉冲数据 */
+#define TMR0_CAPDataCounter()       R8_TMR0_FIFO_COUNT              /* 获取当前已捕获数据个数 */
+
+
+#define TMR0_Disable()              (R8_TMR0_CTRL_MOD &= ~RB_TMR_COUNT_EN)      /* 关闭 TMR0 */
+#define TMR0_Enable()                   (R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN)       /* 开启 TMR0 */
+// refer to TMR0 interrupt bit define
+#define TMR0_ITCfg(s,f)             ((s)?(R8_TMR0_INTER_EN|=f):(R8_TMR0_INTER_EN&=~f))      /* TMR0 相应中断位开启与关闭 */
+// refer to TMR0 interrupt bit define
+#define TMR0_ClearITFlag(f)         (R8_TMR0_INT_FLAG = f)          /* 清除中断标志 */
+#define TMR0_GetITFlag(f)           (R8_TMR0_INT_FLAG&f)            /* 查询中断标志状态 */
+
+
+/****************** TMR1 */
+// 定时和计数
+void TMR1_TimerInit( UINT32 t );                                    /* 定时功能初始化 */
+void TMR1_EXTSingleCounterInit( UINT32 c );                         /* 外部信号计数功能初始化 */
+#define  TMR1_GetCurrentTimer()     R32_TMR1_COUNT                  /* 获取当前定时器值,最大67108864 */
+
+//计数功能
+void TMR1_CountInit( CapModeTypeDef cap );                          /* 外部信号边沿计数初始化 */
+#define TMR1_CountOverflowCfg( cyc )   (R32_TMR1_CNT_END=(cyc+2))   /* 计数统计溢出大小,最大67108862 */
+#define  TMR1_GetCurrentCount()     R32_TMR1_COUNT                  /* 获取当前计数值,最大67108862 */
+
+// PWM功能
+#define TMR1_PWMCycleCfg( cyc )     (R32_TMR1_CNT_END=cyc)          /* PWM1 通道输出波形周期配置, 最大67108864 */
+void TMR1_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts );  /* PWM1 输出初始化 */
+#define TMR1_PWMActDataWidth( d )   (R32_TMR1_FIFO = d)         /* PWM1 有效数据脉宽, 最大67108864 */
+
+// 捕捉脉宽
+#define TMR1_CAPTimeoutCfg( cyc )   (R32_TMR1_CNT_END=cyc)          /* CAP1 捕捉电平超时配置, 最大33554432 */
+void TMR1_CapInit( CapModeTypeDef cap );                            /* 外部信号捕捉功能初始化 */
+#define TMR1_CAPGetData()           R32_TMR1_FIFO                   /* 获取脉冲数据 */
+#define TMR1_CAPDataCounter()       R8_TMR1_FIFO_COUNT              /* 获取当前已捕获数据个数 */
+
+void TMR1_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m );    /* DMA配置  */
+
+#define TMR1_Disable()              (R8_TMR1_CTRL_MOD &= ~RB_TMR_COUNT_EN)      /* 关闭 TMR1 */
+#define TMR1_Enable()                   (R8_TMR1_CTRL_MOD |= RB_TMR_COUNT_EN)       /* 开启 TMR1 */
+// refer to TMR1 interrupt bit define
+#define TMR1_ITCfg(s,f)             ((s)?(R8_TMR1_INTER_EN|=f):(R8_TMR1_INTER_EN&=~f))      /* TMR1 相应中断位开启与关闭 */
+// refer to TMR1 interrupt bit define
+#define TMR1_ClearITFlag(f)         (R8_TMR1_INT_FLAG = f)          /* 清除中断标志 */
+#define TMR1_GetITFlag(f)           (R8_TMR1_INT_FLAG&f)            /* 查询中断标志状态 */
+
+
+/****************** TMR2 */
+// 定时和计数
+void TMR2_TimerInit( UINT32 t );                                    /* 定时功能初始化 */
+void TMR2_EXTSingleCounterInit( UINT32 c );                         /* 外部信号计数功能初始化 */
+#define  TMR2_GetCurrentTimer()     R32_TMR2_COUNT                  /* 获取当前定时器值,最大67108864 */
+
+//计数功能
+void TMR2_CountInit( CapModeTypeDef cap );                          /* 外部信号边沿计数初始化 */
+#define TMR2_CountOverflowCfg( cyc )   (R32_TMR2_CNT_END=(cyc+2))   /* 计数统计溢出大小,最大67108862 */
+#define  TMR2_GetCurrentCount()     R32_TMR2_COUNT                  /* 获取当前计数值,最大67108862 */
+
+// PWM功能
+#define TMR2_PWMCycleCfg( cyc )     (R32_TMR2_CNT_END=cyc)          /* PWM2 通道输出波形周期配置, 最大67108864 */
+void TMR2_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts );  /* PWM2 输出初始化 */
+#define TMR2_PWMActDataWidth( d )   (R32_TMR2_FIFO = d)         /* PWM2 有效数据脉宽, 最大67108864 */
+
+// 捕捉脉宽
+#define TMR2_CAPTimeoutCfg( cyc )   (R32_TMR2_CNT_END=cyc)          /* CAP2 捕捉电平超时配置, 最大33554432 */
+void TMR2_CapInit( CapModeTypeDef cap );                            /* 外部信号捕捉功能初始化 */
+#define TMR2_CAPGetData()           R32_TMR2_FIFO                   /* 获取脉冲数据 */
+#define TMR2_CAPDataCounter()       R8_TMR2_FIFO_COUNT              /* 获取当前已捕获数据个数 */
+
+void TMR2_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m );    /* DMA配置  */
+
+#define TMR2_Disable()              (R8_TMR2_CTRL_MOD &= ~RB_TMR_COUNT_EN)      /* 关闭 TMR2 */
+#define TMR2_Enable()                   (R8_TMR2_CTRL_MOD |= RB_TMR_COUNT_EN)       /* 开启 TMR2 */
+// refer to TMR2 interrupt bit define
+#define TMR2_ITCfg(s,f)             ((s)?(R8_TMR2_INTER_EN|=f):(R8_TMR2_INTER_EN&=~f))      /* TMR2 相应中断位开启与关闭 */
+// refer to TMR2 interrupt bit define
+#define TMR2_ClearITFlag(f)         (R8_TMR2_INT_FLAG = f)          /* 清除中断标志 */
+#define TMR2_GetITFlag(f)           (R8_TMR2_INT_FLAG&f)            /* 查询中断标志状态 */
+
+
+/****************** TMR3 */
+// 定时和计数
+void TMR3_TimerInit( UINT32 t );                                    /* 定时功能初始化 */
+void TMR3_EXTSingleCounterInit( UINT32 c );                         /* 外部信号计数功能初始化 */
+#define  TMR3_GetCurrentTimer()     R32_TMR3_COUNT                  /* 获取当前定时器值,最大67108864 */
+
+//计数功能
+void TMR3_CountInit( CapModeTypeDef cap );                          /* 外部信号边沿计数初始化 */
+#define TMR3_CountOverflowCfg( cyc )   (R32_TMR3_CNT_END=(cyc+2))   /* 计数统计溢出大小,最大67108862 */
+#define  TMR3_GetCurrentCount()     R32_TMR3_COUNT                  /* 获取当前计数值,最大67108862 */
+
+// PWM功能
+#define TMR3_PWMCycleCfg( cyc )     (R32_TMR3_CNT_END=cyc)          /* PWM3 通道输出波形周期配置, 最大67108864 */
+void TMR3_PWMInit( PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts );  /* PWM3 输出初始化 */
+#define TMR3_PWMActDataWidth( d )   (R32_TMR3_FIFO = d)         /* PWM3 有效数据脉宽, 最大67108864 */
+
+// 捕捉脉宽
+#define TMR3_CAPTimeoutCfg( cyc )   (R32_TMR3_CNT_END=cyc)          /* CAP3 捕捉电平超时配置, 最大33554432 */
+void TMR3_CapInit( CapModeTypeDef cap );                            /* 外部信号捕捉功能初始化 */
+#define TMR3_CAPGetData()           R32_TMR3_FIFO                   /* 获取脉冲数据 */
+#define TMR3_CAPDataCounter()       R8_TMR3_FIFO_COUNT              /* 获取当前已捕获数据个数 */
+
+
+#define TMR3_Disable()              (R8_TMR3_CTRL_MOD &= ~RB_TMR_COUNT_EN)      /* 关闭 TMR3 */
+#define TMR3_Enable()                   (R8_TMR3_CTRL_MOD |= RB_TMR_COUNT_EN)       /* 开启 TMR3 */
+// refer to TMR3 interrupt bit define
+#define TMR3_ITCfg(s,f)             ((s)?(R8_TMR3_INTER_EN|=f):(R8_TMR3_INTER_EN&=~f))      /* TMR3 相应中断位开启与关闭 */
+// refer to TMR3 interrupt bit define
+#define TMR3_ClearITFlag(f)         (R8_TMR3_INT_FLAG = f)          /* 清除中断标志 */
+#define TMR3_GetITFlag(f)           (R8_TMR3_INT_FLAG&f)            /* 查询中断标志状态 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_TIMER_H__
+

+ 131 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_uart.h

@@ -0,0 +1,131 @@
+
+
+
+#ifndef __CH57x_UART_H__
+#define __CH57x_UART_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+
+/**
+  * @brief  LINE error and status define
+  */
+#define  STA_ERR_BREAK      RB_LSR_BREAK_ERR       // 数据间隔错误
+#define  STA_ERR_FRAME      RB_LSR_FRAME_ERR       // 数据帧错误
+#define  STA_ERR_PAR        RB_LSR_PAR_ERR         // 奇偶校验位出错
+#define  STA_ERR_FIFOOV     RB_LSR_OVER_ERR        // 接收数据溢出
+
+#define  STA_TXFIFO_EMP     RB_LSR_TX_FIFO_EMP     // 当前发送FIFO空,可以继续填充发送数据
+#define  STA_TXALL_EMP      RB_LSR_TX_ALL_EMP      // 当前所有发送数据都发送完成
+#define  STA_RECV_DATA      RB_LSR_DATA_RDY        // 当前有接收到数据
+
+
+/**
+  * @brief  Configuration UART TrigByte num
+  */
+typedef enum
+{
+    UART_1BYTE_TRIG = 0,        // 1字节触发
+    UART_2BYTE_TRIG,            // 2字节触发
+    UART_4BYTE_TRIG,            // 4字节触发
+    UART_7BYTE_TRIG,            // 7字节触发
+
+}UARTByteTRIGTypeDef;
+
+
+/****************** UART0 */
+void UART0_DefInit( void );                             /* 串口默认初始化配置 */
+void UART0_BaudRateCfg( UINT32 baudrate );              /* 串口波特率配置 */
+void UART0_ByteTrigCfg( UARTByteTRIGTypeDef b );        /* 串口字节触发中断配置 */
+void UART0_INTCfg( UINT8 s,  UINT8 i );                 /* 串口中断配置 */
+void UART0_Reset( void );                               /* 串口软件复位 */
+
+#define UART0_CLR_RXFIFO()       (R8_UART0_FCR |= RB_FCR_RX_FIFO_CLR)          /* 清除当前接收FIFO */
+#define UART0_CLR_TXFIFO()       (R8_UART0_FCR |= RB_FCR_TX_FIFO_CLR)          /* 清除当前发送FIFO */
+
+#define UART0_GetITFlag()       (R8_UART0_IIR&RB_IIR_INT_MASK)          /* 获取当前中断标志 */
+// please refer to LINE error and status define
+#define UART0_GetLinSTA()       (R8_UART0_LSR)          /* 获取当前通讯状态 */
+
+#define UART0_SendByte(b)       (R8_UART0_THR = b)      /* 串口单字节发送 */
+void UART0_SendString( PUINT8 buf, UINT16 l );          /* 串口多字节发送 */
+#define UART0_RecvByte()        ( R8_UART0_RBR )        /* 串口读取单字节 */
+UINT16 UART0_RecvString( PUINT8 buf );                  /* 串口读取多字节 */
+
+
+
+/****************** UART1 */
+void UART1_DefInit( void );                             /* 串口默认初始化配置 */
+void UART1_BaudRateCfg( UINT32 baudrate );              /* 串口波特率配置 */
+void UART1_ByteTrigCfg( UARTByteTRIGTypeDef b );        /* 串口字节触发中断配置 */
+void UART1_INTCfg( UINT8 s,  UINT8 i );                 /* 串口中断配置 */
+void UART1_Reset( void );                               /* 串口软件复位 */
+
+#define UART1_CLR_RXFIFO()       (R8_UART1_FCR |= RB_FCR_RX_FIFO_CLR)          /* 清除当前接收FIFO */
+#define UART1_CLR_TXFIFO()       (R8_UART1_FCR |= RB_FCR_TX_FIFO_CLR)          /* 清除当前发送FIFO */
+
+#define UART1_GetITFlag()       (R8_UART1_IIR&RB_IIR_INT_MASK)          /* 获取当前中断标志 */
+// please refer to LINE error and status define
+#define UART1_GetLinSTA()       (R8_UART1_LSR)          /* 获取当前通讯状态 */
+
+#define UART1_SendByte(b)       (R8_UART1_THR = b)      /* 串口单字节发送 */
+void UART1_SendString( PUINT8 buf, UINT16 l );          /* 串口多字节发送 */
+#define UART1_RecvByte()        ( R8_UART1_RBR )        /* 串口读取单字节 */
+UINT16 UART1_RecvString( PUINT8 buf );                  /* 串口读取多字节 */
+
+
+
+/****************** UART2 */
+void UART2_DefInit( void );                             /* 串口默认初始化配置 */
+void UART2_BaudRateCfg( UINT32 baudrate );              /* 串口波特率配置 */
+void UART2_ByteTrigCfg( UARTByteTRIGTypeDef b );        /* 串口字节触发中断配置 */
+void UART2_INTCfg( UINT8 s,  UINT8 i );                 /* 串口中断配置 */
+void UART2_Reset( void );                               /* 串口软件复位 */
+
+#define UART2_CLR_RXFIFO()       (R8_UART2_FCR |= RB_FCR_RX_FIFO_CLR)          /* 清除当前接收FIFO */
+#define UART2_CLR_TXFIFO()       (R8_UART2_FCR |= RB_FCR_TX_FIFO_CLR)          /* 清除当前发送FIFO */
+
+#define UART2_GetITFlag()       (R8_UART2_IIR&RB_IIR_INT_MASK)          /* 获取当前中断标志 */
+// please refer to LINE error and status define
+#define UART2_GetLinSTA()       (R8_UART2_LSR)          /* 获取当前通讯状态 */
+
+#define UART2_SendByte(b)       (R8_UART2_THR = b)      /* 串口单字节发送 */
+void UART2_SendString( PUINT8 buf, UINT16 l );          /* 串口多字节发送 */
+#define UART2_RecvByte()        ( R8_UART2_RBR )        /* 串口读取单字节 */
+UINT16 UART2_RecvString( PUINT8 buf );                  /* 串口读取多字节 */
+
+
+
+
+/****************** UART3 */
+void UART3_DefInit( void );                             /* 串口默认初始化配置 */
+void UART3_BaudRateCfg( UINT32 baudrate );              /* 串口波特率配置 */
+void UART3_ByteTrigCfg( UARTByteTRIGTypeDef b );        /* 串口字节触发中断配置 */
+void UART3_INTCfg( UINT8 s,  UINT8 i );                 /* 串口中断配置 */
+void UART3_Reset( void );                               /* 串口软件复位 */
+
+#define UART3_CLR_RXFIFO()       (R8_UART3_FCR |= RB_FCR_RX_FIFO_CLR)          /* 清除当前接收FIFO */
+#define UART3_CLR_TXFIFO()       (R8_UART3_FCR |= RB_FCR_TX_FIFO_CLR)          /* 清除当前发送FIFO */
+
+#define UART3_GetITFlag()       (R8_UART3_IIR&RB_IIR_INT_MASK)          /* 获取当前中断标志 */
+// please refer to LINE error and status define
+#define UART3_GetLinSTA()       (R8_UART3_LSR)          /* 获取当前通讯状态 */
+
+#define UART3_SendByte(b)       (R8_UART3_THR = b)      /* 串口单字节发送 */
+void UART3_SendString( PUINT8 buf, UINT16 l );          /* 串口多字节发送 */
+#define UART3_RecvByte()        ( R8_UART3_RBR )        /* 串口读取单字节 */
+UINT16 UART3_RecvString( PUINT8 buf );                  /* 串口读取多字节 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_UART_H__
+

+ 59 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_usbdev.h

@@ -0,0 +1,59 @@
+
+
+
+#ifndef __CH57x_USBDEV_H__
+#define __CH57x_USBDEV_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/* 以下缓存区是USB模块收发使用的数据缓冲区,总共9个通道(9块缓存),用户可根据实际使用的通道数定义相应缓存区 */
+extern PUINT8  pEP0_RAM_Addr;       //ep0(64)+ep4_out(64)+ep4_in(64)
+extern PUINT8  pEP1_RAM_Addr;       //ep1_out(64)+ep1_in(64)
+extern PUINT8  pEP2_RAM_Addr;       //ep2_out(64)+ep2_in(64)
+extern PUINT8  pEP3_RAM_Addr;       //ep3_out(64)+ep3_in(64)
+
+#define pSetupReqPak        ((PUSB_SETUP_REQ)pEP0_RAM_Addr)
+#define pEP0_DataBuf        (pEP0_RAM_Addr)
+#define pEP1_OUT_DataBuf    (pEP1_RAM_Addr)
+#define pEP1_IN_DataBuf     (pEP1_RAM_Addr+64)
+#define pEP2_OUT_DataBuf    (pEP2_RAM_Addr)
+#define pEP2_IN_DataBuf     (pEP2_RAM_Addr+64)
+#define pEP3_OUT_DataBuf    (pEP3_RAM_Addr)
+#define pEP3_IN_DataBuf     (pEP3_RAM_Addr+64)
+#define pEP4_OUT_DataBuf    (pEP0_RAM_Addr+64)
+#define pEP4_IN_DataBuf     (pEP0_RAM_Addr+128)
+
+
+
+void USB_DeviceInit( void );            /* USB设备功能初始化,4个端点,8个通道 */
+void USB_DevTransProcess( void );       /* USB设备应答传输处理 */
+
+void DevEP1_OUT_Deal( UINT8 l );        /* 设备端点1下传通道处理 */
+void DevEP2_OUT_Deal( UINT8 l );        /* 设备端点2下传通道处理 */
+void DevEP3_OUT_Deal( UINT8 l );        /* 设备端点3下传通道处理 */
+void DevEP4_OUT_Deal( UINT8 l );        /* 设备端点4下传通道处理 */
+
+void DevEP1_IN_Deal( UINT8 l );     /* 设备端点1上传通道处理 */
+void DevEP2_IN_Deal( UINT8 l );     /* 设备端点2上传通道处理 */
+void DevEP3_IN_Deal( UINT8 l );     /* 设备端点3上传通道处理 */
+void DevEP4_IN_Deal( UINT8 l );     /* 设备端点4上传通道处理 */
+
+// 0-未完成  (!0)-已完成
+#define EP1_GetINSta()      (R8_UEP1_CTRL&UEP_T_RES_NAK)        /* 查询端点1是否上传完成 */
+#define EP2_GetINSta()      (R8_UEP2_CTRL&UEP_T_RES_NAK)        /* 查询端点2是否上传完成 */
+#define EP3_GetINSta()      (R8_UEP3_CTRL&UEP_T_RES_NAK)        /* 查询端点3是否上传完成 */
+#define EP4_GetINSta()      (R8_UEP4_CTRL&UEP_T_RES_NAK)        /* 查询端点4是否上传完成 */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_USBDEV_H__
+

+ 130 - 0
bsp/wch/arm/ch579m/libraries/StdPeriphDriver/inc/CH57x_usbhost.h

@@ -0,0 +1,130 @@
+
+
+
+#ifndef __CH57x_USBHOST_H__
+#define __CH57x_USBHOST_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "CH579SFR.h"
+#include "core_cm0.h"
+
+/***************************************** 不使用U盘文件系统库或者U盘挂载USBhub下面,需要关闭下面定义 */
+#define FOR_ROOT_UDISK_ONLY
+/***************************************** 使用U盘文件系统库,需要开启下面定义, 不使用请关闭 */
+#define DISK_BASE_BUF_LEN       512         /* 默认的磁盘数据缓冲区大小为512字节,建议选择为2048甚至4096以支持某些大扇区的U盘,为0则禁止在.H文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */
+
+
+
+// 各子程序返回状态码
+#define ERR_SUCCESS         0x00    // 操作成功
+#define ERR_USB_CONNECT     0x15    /* 检测到USB设备连接事件,已经连接 */
+#define ERR_USB_DISCON      0x16    /* 检测到USB设备断开事件,已经断开 */
+#define ERR_USB_BUF_OVER    0x17    /* USB传输的数据有误或者数据太多缓冲区溢出 */
+#define ERR_USB_DISK_ERR    0x1F    /* USB存储器操作失败,在初始化时可能是USB存储器不支持,在读写操作中可能是磁盘损坏或者已经断开 */
+#define ERR_USB_TRANSFER    0x20    /* NAK/STALL等更多错误码在0x20~0x2F */
+#define ERR_USB_UNSUPPORT   0xFB    /*不支持的USB设备*/
+#define ERR_USB_UNKNOWN     0xFE    /*设备操作出错*/
+#define ERR_AOA_PROTOCOL    0x41    /*协议版本出错 */
+
+/*USB设备相关信息表,最多支持1个设备*/
+#define ROOT_DEV_DISCONNECT  0
+#define ROOT_DEV_CONNECTED   1
+#define ROOT_DEV_FAILED      2
+#define ROOT_DEV_SUCCESS     3
+#define DEV_TYPE_KEYBOARD   ( USB_DEV_CLASS_HID | 0x20 )
+#define DEV_TYPE_MOUSE      ( USB_DEV_CLASS_HID | 0x30 )
+#define DEF_AOA_DEVICE       0xF0
+#define DEV_TYPE_UNKNOW      0xFF
+
+
+/*
+约定: USB设备地址分配规则(参考USB_DEVICE_ADDR)
+地址值  设备位置
+0x02    内置Root-HUB下的USB设备或外部HUB
+0x1x    内置Root-HUB下的外部HUB的端口x下的USB设备,x为1~n
+*/
+#define HUB_MAX_PORTS           4
+#define WAIT_USB_TOUT_200US     800   // 等待USB中断超时时间
+
+
+typedef struct
+{
+    UINT8   DeviceStatus;              // 设备状态,0-无设备,1-有设备但尚未初始化,2-有设备但初始化枚举失败,3-有设备且初始化枚举成功
+    UINT8   DeviceAddress;             // 设备被分配的USB地址
+    UINT8   DeviceSpeed;               // 0为低速,非0为全速
+    UINT8   DeviceType;                // 设备类型
+    UINT16  DeviceVID;
+    UINT16  DevicePID;
+    UINT8   GpVar[4];                    // 通用变量,存放端点
+    UINT8   GpHUBPortNum;                // 通用变量,如果是HUB,表示HUB端口数
+} _RootHubDev;
+
+
+extern _RootHubDev  ThisUsbDev;
+extern UINT8  UsbDevEndp0Size;              // USB设备的端点0的最大包尺寸 */
+extern UINT8  FoundNewDev;
+
+extern PUINT8  pHOST_RX_RAM_Addr;
+extern PUINT8  pHOST_TX_RAM_Addr;
+#define pSetupReq   ((PUSB_SETUP_REQ)pHOST_TX_RAM_Addr)
+extern UINT8  Com_Buffer[];
+
+/* 以下为USB主机请求包 */
+extern const UINT8  SetupGetDevDescr[];    //*获取设备描述符*/
+extern const UINT8  SetupGetCfgDescr[];    //*获取配置描述符*/
+extern const UINT8  SetupSetUsbAddr[];     //*设置USB地址*/
+extern const UINT8  SetupSetUsbConfig[];   //*设置USB配置*/
+extern const UINT8  SetupSetUsbInterface[];//*设置USB接口配置*/
+extern const UINT8  SetupClrEndpStall[];   //*清除端点STALL*/
+
+
+void  DisableRootHubPort(void)  ;                   // 关闭ROOT-HUB端口,实际上硬件已经自动关闭,此处只是清除一些结构状态
+UINT8   AnalyzeRootHub( void ) ;         // 分析ROOT-HUB状态,处理ROOT-HUB端口的设备插拔事件
+// 返回ERR_SUCCESS为没有情况,返回ERR_USB_CONNECT为检测到新连接,返回ERR_USB_DISCON为检测到断开
+void    SetHostUsbAddr( UINT8 addr );                 // 设置USB主机当前操作的USB设备地址
+void    SetUsbSpeed( UINT8 FullSpeed );               // 设置当前USB速度
+void    ResetRootHubPort(void);                          // 检测到设备后,复位相应端口的总线,为枚举设备准备,设置为默认为全速
+UINT8   EnableRootHubPort(void);                          // 使能ROOT-HUB端口,相应的bUH_PORT_EN置1开启端口,设备断开可能导致返回失败
+void    SelectHubPort( UINT8 HubPortIndex );// HubPortIndex=0选择操作指定的ROOT-HUB端口,否则选择操作指定的ROOT-HUB端口的外部HUB的指定端口
+UINT8   WaitUSB_Interrupt( void );                    // 等待USB中断
+// 传输事务,输入目的端点地址/PID令牌,同步标志,以20uS为单位的NAK重试总时间(0则不重试,0xFFFF无限重试),返回0成功,超时/出错重试
+UINT8   USBHostTransact( UINT8 endp_pid, UINT8 tog, UINT32 timeout );  // endp_pid: 高4位是token_pid令牌, 低4位是端点地址
+UINT8   HostCtrlTransfer( PUINT8 DataBuf, PUINT8 RetLen );  // 执行控制传输,8字节请求码在pSetupReq中,DataBuf为可选的收发缓冲区
+// 如果需要接收和发送数据,那么DataBuf需指向有效缓冲区用于存放后续数据,实际成功收发的总长度返回保存在ReqLen指向的字节变量中
+
+
+void CopySetupReqPkg( PCCHAR pReqPkt );            // 复制控制传输的请求包
+UINT8 CtrlGetDeviceDescr( void );                    // 获取设备描述符,返回在 pHOST_TX_RAM_Addr 中
+UINT8 CtrlGetConfigDescr( void );                    // 获取配置描述符,返回在 pHOST_TX_RAM_Addr 中
+UINT8 CtrlSetUsbAddress( UINT8 addr );                         // 设置USB设备地址
+UINT8 CtrlSetUsbConfig( UINT8 cfg );                           // 设置USB设备配置
+UINT8 CtrlClearEndpStall( UINT8 endp ) ;                       // 清除端点STALL
+UINT8 CtrlSetUsbIntercace( UINT8 cfg );                        // 设置USB设备接口
+
+
+void    USB_HostInit( void );                                  // 初始化USB主机
+
+
+
+/*************************************************************/
+
+
+UINT8 InitRootDevice( void );
+
+UINT8   CtrlGetHIDDeviceReport( UINT8 infc );          // HID类命令,SET_IDLE和GET_REPORT
+UINT8   CtrlGetHubDescr( void );                       // 获取HUB描述符,返回在TxBuffer中
+UINT8   HubGetPortStatus( UINT8 HubPortIndex );        // 查询HUB端口状态,返回在TxBuffer中
+UINT8   HubSetPortFeature( UINT8 HubPortIndex, UINT8 FeatureSelt );  // 设置HUB端口特性
+UINT8   HubClearPortFeature( UINT8 HubPortIndex, UINT8 FeatureSelt );  // 清除HUB端口特性
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __CH57x_USBHOST_H__
+

+ 19 - 0
bsp/wch/arm/ch579m/libraries/sct/CH57x.sct

@@ -0,0 +1,19 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+LR_IROM1 0x00000000 0x0003E800  {    ; load region size_region
+  ER_IROM1 0x00000000 0x0003E800  {  ; load address = execution address
+   *.o (RESET, +First)
+   *(InRoot$$Sections)
+   .ANY (+RO)
+  }
+  RW_IRAM1 0x20000000 0x00004000  {  ; RW data
+   .ANY (+RW +ZI)
+  }
+  RW_IRAM2 0x20004000 0x00004000  {
+   *.o (NMICode)
+   .ANY (+RW +ZI)
+  }
+}
+

+ 977 - 0
bsp/wch/arm/ch579m/project.uvprojx

@@ -0,0 +1,977 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>rtthread-ch579m</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARMCC</pCCUsed>
+      <uAC6>0</uAC6>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>CH579M</Device>
+          <Vendor>WCH</Vendor>
+          <PackID>Keil.WCH57x_DFP.1.1.0</PackID>
+          <PackURL>http://wch.cn/pack</PackURL>
+          <Cpu>IRAM(0x20000000,0x8000) IROM(0x00000000,0x3E800) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0CH57x -FS00 -FL03F000 -FP0($$Device:CH579M$CMSIS\Flash\CH57x.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:CH579M$Drivers\CMSIS\Device\WCH\CH57x\Include\CH579SFR.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:CH579M$CMSIS\SVD\CH579SFR.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\build\keil\Obj\</OutputDirectory>
+          <OutputName>rt-thread</OutputName>
+          <CreateExecutable>1</CreateExecutable>
+          <CreateLib>0</CreateLib>
+          <CreateHexFile>1</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\build\keil\List\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  </SimDllArguments>
+          <SimDlgDll>DARMCM1.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM0</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> </TargetDllArguments>
+          <TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM0</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3>"" ()</Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>1</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>1</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M0"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <RvdsMve>0</RvdsMve>
+            <RvdsCdeCp>0</RvdsCdeCp>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>1</useUlib>
+            <EndSel>0</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x8000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x3e800</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x3e800</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x8000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>4</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>1</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>2</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>1</uC99>
+            <uGnu>0</uGnu>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>3</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <v6Rtti>0</v6Rtti>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define>__RTTHREAD__, RT_USING_ARM_LIBC, __CLK_TCK=RT_TICK_PER_SECOND</Define>
+              <Undefine></Undefine>
+              <IncludePath>applications;.;..\..\..\..\components\libc\compilers\common;..\..\..\..\components\libc\compilers\common\extension;..\..\..\..\libcpu\arm\common;..\..\..\..\libcpu\arm\cortex-m0;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\include;board;..\..\..\..\components\finsh;.;..\..\..\..\include;libraries\StdPeriphDriver\inc;libraries\CMSIS\Include;..\..\..\..\components\net\lwip-2.1.2\src;..\..\..\..\components\net\lwip-2.1.2\src\include;..\..\..\..\components\net\lwip-2.1.2\src\arch\include;..\..\..\..\components\net\lwip-2.1.2\src\include\netif;..\..\..\..\components\net\lwip-2.1.2\src\include\compat\posix;..\..\..\..\components\libc\posix\io\poll;..\..\..\..\components\libc\posix\io\stdio;..\..\..\..\components\libc\posix\ipc;..\..\..\..\components\drivers\usb\usbhost;..\..\..\..\components\drivers\usb\usbhost\class;..\..\..\..\components\drivers\usb\usbhost\core;..\..\..\..\components\drivers\usb\usbhost\include;..\..\..\..\components\drivers\include;..\..\..\..\components\net\netdev\include</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>0</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <ClangAsOpt>1</ClangAsOpt>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>1</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange>0x08000000</TextAddressRange>
+            <DataAddressRange>0x20000000</DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile>.\board\linker_scripts\link.sct</ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Applications</GroupName>
+          <Files>
+            <File>
+              <FileName>main.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>applications\main.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Compiler</GroupName>
+          <Files>
+            <File>
+              <FileName>syscall_mem.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\libc\compilers\armlibc\syscall_mem.c</FilePath>
+            </File>
+            <File>
+              <FileName>syscalls.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\libc\compilers\armlibc\syscalls.c</FilePath>
+            </File>
+            <File>
+              <FileName>stdlib.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\libc\compilers\common\stdlib.c</FilePath>
+            </File>
+            <File>
+              <FileName>time.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\libc\compilers\common\time.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>CPU</GroupName>
+          <Files>
+            <File>
+              <FileName>showmem.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\libcpu\arm\common\showmem.c</FilePath>
+            </File>
+            <File>
+              <FileName>div0.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\libcpu\arm\common\div0.c</FilePath>
+            </File>
+            <File>
+              <FileName>backtrace.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\libcpu\arm\common\backtrace.c</FilePath>
+            </File>
+            <File>
+              <FileName>cpuport.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\libcpu\arm\cortex-m0\cpuport.c</FilePath>
+            </File>
+            <File>
+              <FileName>context_rvds.S</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\..\libcpu\arm\cortex-m0\context_rvds.S</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>DeviceDrivers</GroupName>
+          <Files>
+            <File>
+              <FileName>ringblk_buf.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\ringblk_buf.c</FilePath>
+            </File>
+            <File>
+              <FileName>dataqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\dataqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>workqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\workqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>waitqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\waitqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>ringbuffer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\ringbuffer.c</FilePath>
+            </File>
+            <File>
+              <FileName>pipe.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\pipe.c</FilePath>
+            </File>
+            <File>
+              <FileName>completion.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\ipc\completion.c</FilePath>
+            </File>
+            <File>
+              <FileName>serial.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\serial\serial.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Drivers</GroupName>
+          <Files>
+            <File>
+              <FileName>board.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>board\board.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_uart.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>board\drv_uart.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_usbh.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>board\drv_usbh.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_eth.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>board\drv_eth.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Finsh</GroupName>
+          <Files>
+            <File>
+              <FileName>shell.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\finsh\shell.c</FilePath>
+            </File>
+            <File>
+              <FileName>msh.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\finsh\msh.c</FilePath>
+            </File>
+            <File>
+              <FileName>cmd.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\finsh\cmd.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Kernel</GroupName>
+          <Files>
+            <File>
+              <FileName>mem.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\mem.c</FilePath>
+            </File>
+            <File>
+              <FileName>kservice.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\kservice.c</FilePath>
+            </File>
+            <File>
+              <FileName>scheduler.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\scheduler.c</FilePath>
+            </File>
+            <File>
+              <FileName>components.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\components.c</FilePath>
+            </File>
+            <File>
+              <FileName>idle.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\idle.c</FilePath>
+            </File>
+            <File>
+              <FileName>ipc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\ipc.c</FilePath>
+            </File>
+            <File>
+              <FileName>thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>device.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\device.c</FilePath>
+            </File>
+            <File>
+              <FileName>object.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\object.c</FilePath>
+            </File>
+            <File>
+              <FileName>timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>clock.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\clock.c</FilePath>
+            </File>
+            <File>
+              <FileName>irq.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\src\irq.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Libraries</GroupName>
+          <Files>
+            <File>
+              <FileName>CH57x_pwm.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_pwm.c</FilePath>
+            </File>
+            <File>
+              <FileName>startup_ARMCM0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>libraries\Startup\startup_ARMCM0.s</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_pwr.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_pwr.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_sys.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_sys.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_spi1.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_spi1.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_uart0.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_uart0.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_flash.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_flash.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_uart1.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_uart1.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_gpio.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_gpio.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_timer1.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_timer1.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_adc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_adc.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_lcd.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_lcd.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_uart3.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_uart3.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_uart2.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_uart2.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_spi0.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_spi0.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_timer3.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_timer3.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_int.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_int.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_clk.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_clk.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_timer2.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_timer2.c</FilePath>
+            </File>
+            <File>
+              <FileName>CH57x_timer0.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>libraries\StdPeriphDriver\CH57x_timer0.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>lwIP</GroupName>
+          <Files>
+            <File>
+              <FileName>netdb.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\netdb.c</FilePath>
+            </File>
+            <File>
+              <FileName>ip.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ip.c</FilePath>
+            </File>
+            <File>
+              <FileName>autoip.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\autoip.c</FilePath>
+            </File>
+            <File>
+              <FileName>ethernet.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\netif\ethernet.c</FilePath>
+            </File>
+            <File>
+              <FileName>netif.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\netif.c</FilePath>
+            </File>
+            <File>
+              <FileName>sys.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\sys.c</FilePath>
+            </File>
+            <File>
+              <FileName>sockets.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\sockets.c</FilePath>
+            </File>
+            <File>
+              <FileName>altcp_alloc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\altcp_alloc.c</FilePath>
+            </File>
+            <File>
+              <FileName>netifapi.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\netifapi.c</FilePath>
+            </File>
+            <File>
+              <FileName>tcpip.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\tcpip.c</FilePath>
+            </File>
+            <File>
+              <FileName>ip4_addr.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\ip4_addr.c</FilePath>
+            </File>
+            <File>
+              <FileName>dhcp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\dhcp.c</FilePath>
+            </File>
+            <File>
+              <FileName>init.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\init.c</FilePath>
+            </File>
+            <File>
+              <FileName>ethernetif.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\netif\ethernetif.c</FilePath>
+            </File>
+            <File>
+              <FileName>etharp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\etharp.c</FilePath>
+            </File>
+            <File>
+              <FileName>memp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\memp.c</FilePath>
+            </File>
+            <File>
+              <FileName>ip4.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\ip4.c</FilePath>
+            </File>
+            <File>
+              <FileName>netbuf.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\netbuf.c</FilePath>
+            </File>
+            <File>
+              <FileName>raw.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\raw.c</FilePath>
+            </File>
+            <File>
+              <FileName>ip4_frag.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\ip4_frag.c</FilePath>
+            </File>
+            <File>
+              <FileName>tcp_out.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\tcp_out.c</FilePath>
+            </File>
+            <File>
+              <FileName>lowpan6.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\netif\lowpan6.c</FilePath>
+            </File>
+            <File>
+              <FileName>icmp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\icmp.c</FilePath>
+            </File>
+            <File>
+              <FileName>api_lib.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\api_lib.c</FilePath>
+            </File>
+            <File>
+              <FileName>inet_chksum.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\inet_chksum.c</FilePath>
+            </File>
+            <File>
+              <FileName>stats.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\stats.c</FilePath>
+            </File>
+            <File>
+              <FileName>err.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\err.c</FilePath>
+            </File>
+            <File>
+              <FileName>altcp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\altcp.c</FilePath>
+            </File>
+            <File>
+              <FileName>tcp_in.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\tcp_in.c</FilePath>
+            </File>
+            <File>
+              <FileName>dns.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\dns.c</FilePath>
+            </File>
+            <File>
+              <FileName>sys_arch.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\arch\sys_arch.c</FilePath>
+            </File>
+            <File>
+              <FileName>timeouts.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\timeouts.c</FilePath>
+            </File>
+            <File>
+              <FileName>igmp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\ipv4\igmp.c</FilePath>
+            </File>
+            <File>
+              <FileName>udp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\udp.c</FilePath>
+            </File>
+            <File>
+              <FileName>altcp_tcp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\altcp_tcp.c</FilePath>
+            </File>
+            <File>
+              <FileName>pbuf.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\pbuf.c</FilePath>
+            </File>
+            <File>
+              <FileName>def.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\def.c</FilePath>
+            </File>
+            <File>
+              <FileName>api_msg.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\api_msg.c</FilePath>
+            </File>
+            <File>
+              <FileName>ping.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\apps\ping\ping.c</FilePath>
+            </File>
+            <File>
+              <FileName>if_api.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\api\if_api.c</FilePath>
+            </File>
+            <File>
+              <FileName>tcp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\lwip-2.1.2\src\core\tcp.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>rt_usbh</GroupName>
+          <Files>
+            <File>
+              <FileName>hub.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\usb\usbhost\core\hub.c</FilePath>
+            </File>
+            <File>
+              <FileName>usbhost.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\usb\usbhost\core\usbhost.c</FilePath>
+            </File>
+            <File>
+              <FileName>usbhost_core.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\usb\usbhost\core\usbhost_core.c</FilePath>
+            </File>
+            <File>
+              <FileName>driver.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\drivers\usb\usbhost\core\driver.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>SAL</GroupName>
+          <Files>
+            <File>
+              <FileName>netdev.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\netdev\src\netdev.c</FilePath>
+            </File>
+            <File>
+              <FileName>netdev_ipaddr.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\..\components\net\netdev\src\netdev_ipaddr.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components/>
+    <files/>
+  </RTE>
+
+  <LayerInfo>
+    <Layers>
+      <Layer>
+        <LayName>template</LayName>
+        <LayPrjMark>1</LayPrjMark>
+      </Layer>
+    </Layers>
+  </LayerInfo>
+
+</Project>

+ 238 - 0
bsp/wch/arm/ch579m/rtconfig.h

@@ -0,0 +1,238 @@
+#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
+#define RT_ALIGN_SIZE 4
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 1000
+#define IDLE_THREAD_STACK_SIZE 256
+
+/* kservice optimization */
+
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+
+/* Memory Management */
+
+#define RT_USING_SMALL_MEM
+#define RT_USING_SMALL_MEM_AS_HEAP
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 128
+#define RT_CONSOLE_DEVICE_NAME "uart1"
+#define RT_VER_NUM 0x40100
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 1024
+#define RT_MAIN_THREAD_PRIORITY 10
+
+/* C++ features */
+
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define RT_USING_MSH
+#define FINSH_USING_MSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 2048
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_CMD_SIZE 80
+#define MSH_USING_BUILT_IN_COMMANDS
+#define FINSH_USING_DESCRIPTION
+#define FINSH_ARG_MAX 10
+
+/* Device virtual file system */
+
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_USING_SERIAL
+#define RT_USING_SERIAL_V1
+#define RT_SERIAL_RB_BUFSZ 64
+
+/* Using USB */
+
+#define RT_USING_USB
+#define RT_USING_USB_HOST
+#define RT_USBD_THREAD_STACK_SZ 512
+
+/* POSIX layer and C standard library */
+
+#define RT_LIBC_DEFAULT_TIMEZONE 8
+
+/* POSIX (Portable Operating System Interface) layer */
+
+
+/* Interprocess Communication (IPC) */
+
+
+/* Socket is in the 'Network' category */
+
+/* Network */
+
+/* Socket abstraction layer */
+
+
+/* Network interface device */
+
+#define RT_USING_NETDEV
+#define NETDEV_USING_IFCONFIG
+#define NETDEV_USING_PING
+#define NETDEV_IPV4 1
+#define NETDEV_IPV6 0
+
+/* light weight TCP/IP stack */
+
+#define RT_USING_LWIP
+#define RT_USING_LWIP212
+#define RT_LWIP_MEM_ALIGNMENT 4
+#define RT_LWIP_ICMP
+#define RT_LWIP_DNS
+
+/* Static IPv4 Address */
+
+#define RT_LWIP_IPADDR "19.111.115.250"
+#define RT_LWIP_GWADDR "19.111.115.254"
+#define RT_LWIP_MSKADDR "255.255.255.0"
+#define RT_LWIP_UDP
+#define RT_LWIP_TCP
+#define RT_LWIP_RAW
+#define RT_MEMP_NUM_NETCONN 4
+#define RT_LWIP_PBUF_NUM 4
+#define RT_LWIP_RAW_PCB_NUM 4
+#define RT_LWIP_UDP_PCB_NUM 4
+#define RT_LWIP_TCP_PCB_NUM 4
+#define RT_LWIP_TCP_SEG_NUM 8
+#define RT_LWIP_TCP_SND_BUF 3072
+#define RT_LWIP_TCP_WND 3072
+#define RT_LWIP_TCPTHREAD_PRIORITY 10
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE 4
+#define RT_LWIP_TCPTHREAD_STACKSIZE 1024
+#define LWIP_NO_TX_THREAD
+#define RT_LWIP_ETHTHREAD_PRIORITY 12
+#define RT_LWIP_ETHTHREAD_STACKSIZE 512
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE 4
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define SO_REUSE 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_SNDTIMEO 1
+#define LWIP_SO_RCVBUF 1
+#define LWIP_SO_LINGER 0
+#define LWIP_NETIF_LOOPBACK 0
+#define RT_LWIP_USING_PING
+
+/* AT commands */
+
+
+/* VBUS(Virtual Software BUS) */
+
+
+/* Utilities */
+
+
+/* RT-Thread Utestcases */
+
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+
+/* Wiced WiFi */
+
+
+/* IoT Cloud */
+
+
+/* security packages */
+
+
+/* language packages */
+
+
+/* multimedia packages */
+
+/* LVGL: powerful and easy-to-use embedded GUI library */
+
+
+/* u8g2: a monochrome graphic library */
+
+
+/* PainterEngine: A cross-platform graphics application framework written in C language */
+
+
+/* tools packages */
+
+
+/* system packages */
+
+/* enhanced kernel services */
+
+
+/* POSIX extension functions */
+
+
+/* acceleration: Assembly language or algorithmic acceleration packages */
+
+
+/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
+
+
+/* Micrium: Micrium software products porting for RT-Thread */
+
+
+/* peripheral libraries and drivers */
+
+
+/* AI packages */
+
+
+/* miscellaneous packages */
+
+/* samples: kernel and components samples */
+
+
+/* entertainment: terminal games and other interesting software packages */
+
+
+/* Hardware Drivers Config */
+
+#define SOC_CH579M
+
+/* On-chip Peripheral Drivers */
+
+#define BSP_USING_UART
+#define BSP_USING_UART1
+#define BSP_USING_USBH
+#define BSP_USING_ETH
+
+#endif

+ 150 - 0
bsp/wch/arm/ch579m/rtconfig.py

@@ -0,0 +1,150 @@
+import os
+
+# toolchains options
+ARCH='arm'
+CPU='cortex-m0'
+CROSS_TOOL='keil'
+
+# bsp lib config
+BSP_LIBRARY_TYPE = None
+
+if os.getenv('RTT_CC'):
+    CROSS_TOOL = os.getenv('RTT_CC')
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+
+# cross_tool provides the cross compiler
+# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
+if  CROSS_TOOL == 'gcc':
+    PLATFORM    = 'gcc'
+    EXEC_PATH   = r'C:/GCC'
+elif CROSS_TOOL == 'keil':
+    PLATFORM    = 'armcc'
+    EXEC_PATH   = r'C:/Keil_v5'
+elif CROSS_TOOL == 'iar':
+    PLATFORM    = 'iar'
+    EXEC_PATH   = r'C:/IAR'
+
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
+BUILD = 'debug'
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX = 'arm-none-eabi-'
+    CC = PREFIX + 'gcc'
+    AS = PREFIX + 'gcc'
+    AR = PREFIX + 'ar'
+    CXX = PREFIX + 'g++'
+    LINK = PREFIX + 'gcc'
+    TARGET_EXT = 'elf'
+    SIZE = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY = PREFIX + 'objcopy'
+
+    DEVICE = ' -mcpu=cortex-m0 -mthumb -ffunction-sections -fdata-sections'
+    CFLAGS = DEVICE + ' -std=gnu9x'
+    AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
+    LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds'
+
+    CPATH = ''
+    LPATH = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0 -gdwarf-2 -g'
+        AFLAGS += ' -gdwarf-2'
+    else:
+        CFLAGS += ' -O2'
+
+    CXXFLAGS = CFLAGS 
+
+    POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+
+elif PLATFORM == 'armcc':
+    # toolchains
+    CC = 'armcc'
+    CXX = 'armcc'
+    AS = 'armasm'
+    AR = 'armar'
+    LINK = 'armlink'
+    TARGET_EXT = 'axf'
+
+    DEVICE = ' --cpu Cortex-M3 '
+    CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99'
+    AFLAGS = DEVICE + ' --apcs=interwork '
+    LFLAGS = DEVICE + '  --info sizes --info totals --info unused --info veneers --list rt-thread.map'
+    LFLAGS += r' --strict --scatter "board\linker_scripts\link.sct" '
+    CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include'
+    LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib'
+
+    CFLAGS += ' -D__MICROLIB '
+    AFLAGS += ' --pd "__MICROLIB SETA 1" '
+    LFLAGS += ' --library_type=microlib '
+    EXEC_PATH += '/ARM/ARMCC/bin/'
+
+    if BUILD == 'debug':
+        CFLAGS += ' -g -O0'
+        AFLAGS += ' -g'
+    else:
+        CFLAGS += ' -O2'
+
+    CXXFLAGS = CFLAGS 
+
+    POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
+
+elif PLATFORM == 'iar':
+    # toolchains
+    CC = 'iccarm'
+    CXX = 'iccarm'
+    AS = 'iasmarm'
+    AR = 'iarchive'
+    LINK = 'ilinkarm'
+    TARGET_EXT = 'out'
+
+    DEVICE = '-Dewarm'
+
+    CFLAGS = DEVICE
+    CFLAGS += ' --diag_suppress Pa050'
+    CFLAGS += ' --no_cse'
+    CFLAGS += ' --no_unroll'
+    CFLAGS += ' --no_inline'
+    CFLAGS += ' --no_code_motion'
+    CFLAGS += ' --no_tbaa'
+    CFLAGS += ' --no_clustering'
+    CFLAGS += ' --no_scheduling'
+    CFLAGS += ' --endian=little'
+    CFLAGS += ' --cpu=Cortex-M3'
+    CFLAGS += ' -e'
+    CFLAGS += ' --fpu=None'
+    CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"'
+    CFLAGS += ' --silent'
+
+    AFLAGS = DEVICE
+    AFLAGS += ' -s+'
+    AFLAGS += ' -w+'
+    AFLAGS += ' -r'
+    AFLAGS += ' --cpu Cortex-M3'
+    AFLAGS += ' --fpu None'
+    AFLAGS += ' -S'
+
+    if BUILD == 'debug':
+        CFLAGS += ' --debug'
+        CFLAGS += ' -On'
+    else:
+        CFLAGS += ' -Oh'
+
+    LFLAGS = ' --config "board/linker_scripts/link.icf"'
+    LFLAGS += ' --entry __iar_program_start'
+
+    CXXFLAGS = CFLAGS
+    
+    EXEC_PATH = EXEC_PATH + '/arm/bin/'
+    POST_ACTION = 'ielftool --bin $TARGET rtthread.bin'
+
+def dist_handle(BSP_ROOT, dist_dir):
+    import sys
+    cwd_path = os.getcwd()
+    sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools'))
+    from sdk_dist import dist_do_building
+    dist_do_building(BSP_ROOT, dist_dir)

+ 404 - 0
bsp/wch/arm/ch579m/template.uvprojx

@@ -0,0 +1,404 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>rtthread-ch579m</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <uAC6>0</uAC6>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>CH579M</Device>
+          <Vendor>WCH</Vendor>
+          <PackID>Keil.WCH57x_DFP.1.1.0</PackID>
+          <PackURL>http://wch.cn/pack</PackURL>
+          <Cpu>IRAM(0x20000000,0x8000) IROM(0x00000000,0x3E800) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0CH57x -FS00 -FL03F000 -FP0($$Device:CH579M$CMSIS\Flash\CH57x.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:CH579M$Drivers\CMSIS\Device\WCH\CH57x\Include\CH579SFR.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:CH579M$CMSIS\SVD\CH579SFR.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\build\keil\Obj\</OutputDirectory>
+          <OutputName>rt-thread</OutputName>
+          <CreateExecutable>1</CreateExecutable>
+          <CreateLib>0</CreateLib>
+          <CreateHexFile>1</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\build\keil\List\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  </SimDllArguments>
+          <SimDlgDll>DARMCM1.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM0</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> </TargetDllArguments>
+          <TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM0</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3>"" ()</Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>1</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>1</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M0"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <RvdsMve>0</RvdsMve>
+            <RvdsCdeCp>0</RvdsCdeCp>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>1</useUlib>
+            <EndSel>0</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x8000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x3e800</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x3e800</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x8000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>4</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>1</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>2</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>1</uC99>
+            <uGnu>0</uGnu>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>3</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <v6Rtti>0</v6Rtti>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>0</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <ClangAsOpt>1</ClangAsOpt>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>1</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange>0x08000000</TextAddressRange>
+            <DataAddressRange>0x20000000</DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile>.\board\linker_scripts\link.sct</ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>main</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components/>
+    <files/>
+  </RTE>
+
+  <LayerInfo>
+    <Layers>
+      <Layer>
+        <LayName>template</LayName>
+        <LayPrjMark>1</LayPrjMark>
+      </Layer>
+    </Layers>
+  </LayerInfo>
+
+</Project>