luobeihai 2 éve
commit
e5989dd507
100 módosított fájl, 42592 hozzáadás és 0 törlés
  1. 1 0
      README.md
  2. BIN
      documents/APM32F405xG 407xExG datasheet V1.2.pdf
  3. BIN
      documents/APM32F407IG MINI Board User Manual V1.1.pdf
  4. BIN
      documents/APM32F407IG MINIBOARD V1.0.pdf
  5. BIN
      documents/images/APM32F407IG-large.png
  6. BIN
      documents/images/APM32F407IG-small.png
  7. 447 0
      project_0/.config
  8. 180 0
      project_0/.cproject
  9. 28 0
      project_0/.project
  10. 3 0
      project_0/.settings/org.eclipse.core.runtime.prefs
  11. 20 0
      project_0/.settings/projcfg.ini
  12. 22 0
      project_0/Kconfig
  13. 112 0
      project_0/README.md
  14. 15 0
      project_0/SConscript
  15. 64 0
      project_0/SConstruct
  16. 11 0
      project_0/applications/SConscript
  17. 34 0
      project_0/applications/main.c
  18. 204 0
      project_0/board/Kconfig
  19. 30 0
      project_0/board/SConscript
  20. 54 0
      project_0/board/board.c
  21. 81 0
      project_0/board/board.h
  22. 28 0
      project_0/board/linker_scripts/link.icf
  23. 141 0
      project_0/board/linker_scripts/link.lds
  24. 17 0
      project_0/board/linker_scripts/link.sct
  25. 18 0
      project_0/cconfig.h
  26. BIN
      project_0/figures/APM32F407IG.png
  27. BIN
      project_0/figures/JFlash_Leader_01.png
  28. BIN
      project_0/figures/JFlash_Leader_02.png
  29. BIN
      project_0/figures/JFlash_Leader_03.png
  30. BIN
      project_0/figures/JFlash_Leader_04.png
  31. 432 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_adc.h
  32. 349 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_can.h
  33. 66 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_crc.h
  34. 272 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_cryp.h
  35. 203 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dac.h
  36. 106 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dbgmcu.h
  37. 241 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dci.h
  38. 414 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dma.h
  39. 359 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dmc.h
  40. 139 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_eint.h
  41. 361 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_fmc.h
  42. 285 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_gpio.h
  43. 215 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_hash.h
  44. 352 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_i2c.h
  45. 123 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_iwdt.h
  46. 119 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_misc.h
  47. 142 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_pmu.h
  48. 485 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rcm.h
  49. 98 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rng.h
  50. 597 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rtc.h
  51. 377 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_sdio.h
  52. 370 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_smc.h
  53. 346 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_spi.h
  54. 132 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_syscfg.h
  55. 709 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_tmr.h
  56. 314 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_usart.h
  57. 94 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_wwdt.h
  58. 1028 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_adc.c
  59. 1072 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_can.c
  60. 125 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_crc.c
  61. 463 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp.c
  62. 553 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_aes.c
  63. 232 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_des.c
  64. 248 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_tdes.c
  65. 538 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dac.c
  66. 197 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dbgmcu.c
  67. 369 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dci.c
  68. 652 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dma.c
  69. 435 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dmc.c
  70. 324 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_eint.c
  71. 791 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_fmc.c
  72. 442 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_gpio.c
  73. 401 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash.c
  74. 253 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash_md5.c
  75. 253 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash_sha1.c
  76. 1070 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_i2c.c
  77. 150 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_iwdt.c
  78. 225 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_misc.c
  79. 339 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_pmu.c
  80. 1574 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rcm.c
  81. 195 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rng.c
  82. 1899 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rtc.c
  83. 720 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_sdio.c
  84. 969 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_smc.c
  85. 714 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_spi.c
  86. 194 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_syscfg.c
  87. 2300 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_tmr.c
  88. 862 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_usart.c
  89. 153 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_wwdt.c
  90. 176 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/LICENSE.txt
  91. 888 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/cmsis_armcc.h
  92. 283 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/cmsis_compiler.h
  93. 1858 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cm4.h
  94. 664 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmFunc.h
  95. 916 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmInstr.h
  96. 697 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmSimd.h
  97. 176 0
      project_0/libraries/APM32F4xx_Library/CMSIS/LICENSE.txt
  98. 7492 0
      project_0/libraries/APM32F4xx_Library/Device/Geehy/APM32F4xx/Include/apm32f4xx.h
  99. 68 0
      project_0/libraries/APM32F4xx_Library/Device/Geehy/APM32F4xx/Include/system_apm32f4xx.h
  100. 424 0
      project_0/libraries/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/arm/startup_apm32f40x.s

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# sdk-bsp-apm32f407ig-geehy-mini

BIN
documents/APM32F405xG 407xExG datasheet V1.2.pdf


BIN
documents/APM32F407IG MINI Board User Manual V1.1.pdf


BIN
documents/APM32F407IG MINIBOARD V1.0.pdf


BIN
documents/images/APM32F407IG-large.png


BIN
documents/images/APM32F407IG-small.png


+ 447 - 0
project_0/.config

@@ -0,0 +1,447 @@
+#
+# 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=y
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_HOOK_USING_FUNC_PTR=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
+
+#
+# kservice optimization
+#
+CONFIG_RT_KSERVICE_USING_STDLIB=y
+# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set
+# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
+# CONFIG_RT_USING_TINY_FFS is not set
+# CONFIG_RT_KPRINTF_USING_LONGLONG is not set
+CONFIG_RT_DEBUG=y
+# CONFIG_RT_DEBUG_COLOR is not set
+# CONFIG_RT_DEBUG_INIT_CONFIG is not set
+# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
+# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
+# CONFIG_RT_DEBUG_IPC_CONFIG is not set
+# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
+# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
+# CONFIG_RT_DEBUG_MEM_CONFIG is not set
+# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
+# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
+# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+CONFIG_RT_USING_MEMPOOL=y
+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=0x40101
+CONFIG_ARCH_ARM=y
+CONFIG_RT_USING_CPU_FFS=y
+CONFIG_ARCH_ARM_CORTEX_M=y
+CONFIG_ARCH_ARM_CORTEX_M4=y
+# 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=2048
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+# CONFIG_RT_USING_LEGACY is not set
+CONFIG_RT_USING_MSH=y
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_ARG_MAX=10
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_POSIX=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=4
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=4
+CONFIG_DFS_FD_MAX=16
+# CONFIG_RT_USING_DFS_MNTTABLE is not set
+# CONFIG_RT_USING_DFS_ELMFAT is not set
+# CONFIG_RT_USING_DFS_DEVFS is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_FAL is not set
+# CONFIG_RT_USING_LWP 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=y
+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=y
+# 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 is not set
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# C/C++ and POSIX layer
+#
+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
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# Network
+#
+# CONFIG_RT_USING_SAL is not set
+# CONFIG_RT_USING_NETDEV is not set
+# CONFIG_RT_USING_LWIP is not set
+# CONFIG_RT_USING_AT 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
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT 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_MQTTCLIENT 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_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
+
+#
+# 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_IOTHUB is not set
+# CONFIG_PKG_USING_JIOT-C-SDK is not set
+# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
+# CONFIG_PKG_USING_NIMBLE 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_ONNX_PARSER is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_DLT645 is not set
+# CONFIG_PKG_USING_QXWZ is not set
+# CONFIG_PKG_USING_SMTP_CLIENT is not set
+# 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
+
+#
+# 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
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# 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
+
+#
+# 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_RDB is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH 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_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
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_CMSIS is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_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
+
+#
+# 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_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_U8G2 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_WM_LIBRARIES is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_ROSSERIAL 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_EMBARC_BSP is not set
+
+#
+# miscellaneous packages
+#
+# 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_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_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
+
+#
+# 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
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_UKAL is not set
+CONFIG_SOC_FAMILY_APM32=y
+CONFIG_SOC_SERIES_APM32F4=y
+
+#
+# Hardware Drivers Config
+#
+CONFIG_SOC_APM32F407IG=y
+
+#
+# On-chip Peripheral Drivers
+#
+CONFIG_BSP_USING_GPIO=y
+CONFIG_BSP_USING_UART=y
+CONFIG_BSP_USING_UART1=y
+# CONFIG_BSP_USING_UART2 is not set
+# CONFIG_BSP_USING_ADC is not set
+# CONFIG_BSP_USING_DAC is not set
+# CONFIG_BSP_USING_ONCHIP_RTC is not set
+# CONFIG_BSP_USING_I2C1 is not set
+# CONFIG_BSP_USING_SPI is not set
+# CONFIG_BSP_USING_TMR is not set
+# CONFIG_BSP_USING_PWM is not set
+# CONFIG_BSP_USING_WDT is not set

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 180 - 0
project_0/.cproject


+ 28 - 0
project_0/.project

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+  <name>project_0</name>
+  <comment />
+  <projects>
+	</projects>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+      <triggers>clean,full,incremental,</triggers>
+      <arguments>
+			</arguments>
+    </buildCommand>
+    <buildCommand>
+      <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+      <triggers>full,incremental,</triggers>
+      <arguments>
+			</arguments>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.cdt.core.cnature</nature>
+    <nature>org.rt-thread.studio.rttnature</nature>
+    <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+    <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+  </natures>
+  <linkedResources />
+</projectDescription>

+ 3 - 0
project_0/.settings/org.eclipse.core.runtime.prefs

@@ -0,0 +1,3 @@
+content-types/enabled=true
+content-types/org.eclipse.cdt.core.asmSource/file-extensions=s
+eclipse.preferences.version=1

+ 20 - 0
project_0/.settings/projcfg.ini

@@ -0,0 +1,20 @@
+#RT-Thread Studio Project Configuration
+# Thu Jul 28 14:51:43 2022
+cfg_version=v3.0
+
+board_name=
+bsp_version=
+bsp_path=
+chip_name=
+project_base_rtt_bsp=true
+is_use_scons_build=true
+hardware_adapter=
+selected_rtt_version=latest
+board_base_nano_proj=false
+is_base_example_project=false
+example_name=
+project_type=rt-thread
+os_branch=master
+os_version=latest
+project_name=project_0
+output_project_path=C:\Users\apex\Documents\rt-thread\bsp\apm32\apm32f407ig-minibroard\rtt_studio

+ 22 - 0
project_0/Kconfig

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

+ 112 - 0
project_0/README.md

@@ -0,0 +1,112 @@
+# APM32F103ZE MINI BOARD BSP 说明
+
+## 简介
+
+本文档为 APM32F407IG MINI 开发板(MINI BOARD)的 BSP (板级支持包) 说明。
+
+主要内容如下:
+
+- 开发板资源介绍
+- BSP 快速上手
+
+通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。
+
+## 开发板介绍
+
+APM32F407IG MINI BOARD,采用标准JTAG/SWD调试接口,引出了全部的IO。开发板外观如下图所示:
+
+![board](figures/APM32F407IG.png)
+
+- 有关开发板和芯片的详情可至极海官网查阅。[官网开发板链接 ](https://www.geehy.com/support/apm32?id=192)
+
+
+该开发板常用 **板载资源** 如下:
+
+- MCU:APM32F407IGT6,主频 168MHz,1MKB FLASH ,192+4KB RAM
+- 外部 RAM:无
+- 外部 FLASH:无
+- 常用外设
+  - LED:2个,(黄色,PE5/PE6)
+  - 按键:2个,K1(PA1),K2(PA0)
+- 常用接口:RS232转串口、USB SLAVE
+- 调试接口:标准 JTAG/SWD
+
+
+
+## 外设支持
+
+本 BSP 目前对外设的支持情况如下:
+
+| **板载外设** | **支持情况** | **备注**                             |
+| :----------- | :----------: | :------------------------------------ |
+| RS232转串口  |     支持     | 使用 UART1/ UART2(通过跳线选择)       |
+| **片上外设** | **支持情况** | **备注**                             |
+| GPIO         |     支持     | PA0, PA1... PI11 ---> PIN: 0, 1...134 |
+| UART         |     支持     | UART1/2                               |
+| ADC          |     支持     | ADC1/2/3                              |
+| DAC          |     支持     | DAC1                                  |
+| RTC          |     支持     | 支持外部晶振和内部低速时钟            |
+| TMR          |     支持     | TMR1/2/3/4/5/6/7/8/9/10/11/12/13/14   |
+| PWM          |     支持     | TMR3 ->CH1/2/3/4                      |
+| I2C          |     支持     | 软件I2C                               |
+| SPI          |     支持     | SPI1/2/3                              |
+| WDT          |     支持     | IWDT                                  |
+
+## 使用说明
+
+本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。
+
+
+### 快速上手
+
+本 BSP 为开发者提供MDK5 工程。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。
+
+#### 硬件连接
+
+使用数据线连接开发板到 PC,打开电源开关。
+
+#### 编译下载
+- 方式一:MDK
+
+   双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。
+
+> 工程默认配置使用 J-Link 仿真器下载程序,在通过 J-Link 连接开发板的基础上,点击下载按钮即可下载程序到开发板
+
+- 方式二:J-Flash下载
+
+  通过ENV工具的scons指令或MDK编译出bin文件后,再使用J-Flash工具将bin文件下载至开发板即可,大致步骤如下:
+
+##### 1、建立J-Flash工程
+
+![board](figures/JFlash_Leader_01.png)
+
+##### 2、连接开发板
+
+![board](figures/JFlash_Leader_02.png)
+##### 3、将bin文件拖至工程,起始地址设为0x8000000
+![board](figures/JFlash_Leader_03.png)
+##### 4、点击下载
+![board](figures/JFlash_Leader_04.png)
+
+#### 运行结果
+
+下载程序成功之后,系统会自动运行,LED 闪烁
+
+连接开发板对应串口到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息:
+
+```bash
+ \ | /
+- RT -     Thread Operating System
+ / | \     4.1.0 build Aug 20 2021
+ 2006 - 2021 Copyright by rt-thread team
+msh >
+```
+## 注意事项
+
+- 可在极海官方网站进行所需资料下载,如pack安装包和MINI开发板原理图等(www.geehy.com);
+
+## 联系人信息
+
+-[abbbcc ](https://gitee.com/abbbcc)
+
+-[Aligagago ](https://github.com/Aligagago)

+ 15 - 0
project_0/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')

+ 64 - 0
project_0/SConstruct

@@ -0,0 +1,64 @@
+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() + '/../../..')
+
+# set RTT_ROOT
+if not os.getenv("RTT_ROOT"): 
+    RTT_ROOT="rt-thread"
+
+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, CFLAGS = rtconfig.CFLAGS,
+    AR = rtconfig.AR, ARFLAGS = '-rc',
+    CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
+    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+if rtconfig.PLATFORM == 'iar':
+    env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
+    env.Replace(ARFLAGS = [''])
+    env.Replace(LINKCOM = env["LINKCOM"] + ' --map rtthread.map')
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+SDK_ROOT = os.path.abspath('./')
+
+if os.path.exists(SDK_ROOT + '/libraries'):
+    libraries_path_prefix = SDK_ROOT + '/libraries'
+else:
+    libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'
+
+SDK_LIB = libraries_path_prefix
+Export('SDK_LIB')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
+
+apm32_library = 'APM32F4xx_Library'
+rtconfig.BSP_LIBRARY_TYPE = apm32_library
+
+# include libraries
+objs.extend(SConscript(os.path.join(libraries_path_prefix, apm32_library, 'SConscript')))
+
+# include drivers
+objs.extend(SConscript(os.path.join(libraries_path_prefix, 'Drivers', 'SConscript')))
+
+# make a building
+DoBuilding(TARGET, objs)

+ 11 - 0
project_0/applications/SConscript

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

+ 34 - 0
project_0/applications/main.c

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-08-20     Abbcc        first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <board.h>
+
+/* defined the LED2 pin: PE6 */
+#define LED2_PIN    GET_PIN(E, 6)
+
+int main(void)
+{
+    uint32_t sysclock = 0;
+    /* set LED2 pin mode to output */
+    rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);
+    /* Print system clock */
+    sysclock = RCM_ReadSYSCLKFreq();
+    rt_kprintf("System Clock: %d\n", sysclock);
+
+    while (1)
+    {
+        rt_pin_write(LED2_PIN, PIN_HIGH);
+        rt_thread_mdelay(500);
+        rt_pin_write(LED2_PIN, PIN_LOW);
+        rt_thread_mdelay(500);
+    }
+}

+ 204 - 0
project_0/board/Kconfig

@@ -0,0 +1,204 @@
+menu "Hardware Drivers Config"
+
+config SOC_APM32F407IG
+    bool
+    select SOC_SERIES_APM32F4
+    select RT_USING_COMPONENTS_INIT
+    select RT_USING_USER_MAIN
+    default y
+
+menu "On-chip Peripheral Drivers"
+
+    config BSP_USING_GPIO
+        bool "Enable GPIO"
+        select RT_USING_PIN
+        default y
+
+    menuconfig BSP_USING_UART
+        bool "Enable UART"
+        default y
+        select RT_USING_SERIAL
+        if BSP_USING_UART
+            config BSP_USING_UART1
+                bool "Enable UART1"
+                default y
+            config BSP_USING_UART2
+                bool "Enable UART2"
+                default n
+        endif
+
+    menuconfig BSP_USING_ADC
+        bool "Enable ADC"
+        default n
+        select RT_USING_ADC
+        if BSP_USING_ADC
+            config BSP_USING_ADC1
+                bool "Enable ADC1"
+                default n
+            config BSP_USING_ADC2
+                bool "Enable ADC2"
+                default n
+            config BSP_USING_ADC3
+                bool "Enable ADC3"
+                default n
+        endif
+
+    menuconfig BSP_USING_DAC
+        bool "Enable DAC"
+        default n
+        select RT_USING_DAC
+        if BSP_USING_DAC
+            config BSP_USING_DAC1
+                bool "Enable DAC1"
+                default n
+        endif
+
+    menuconfig BSP_USING_ONCHIP_RTC
+        bool "Enable RTC"
+        select RT_USING_RTC
+        default n
+        if BSP_USING_ONCHIP_RTC
+            choice
+                prompt "Select clock source"
+                default BSP_RTC_USING_LSE
+
+                config BSP_RTC_USING_LSE
+                    bool "RTC USING LSE"
+
+                config BSP_RTC_USING_LSI
+                    bool "RTC USING LSI"
+            endchoice
+        endif
+
+    menuconfig BSP_USING_I2C1
+        bool "Enable I2C1 BUS (software simulation)"
+        default n
+        select RT_USING_I2C
+        select RT_USING_I2C_BITOPS
+        select RT_USING_PIN
+        if BSP_USING_I2C1
+            config BSP_I2C1_SCL_PIN
+                int "i2c1 scl pin number"
+                range 0 63
+                default 22
+            config BSP_I2C1_SDA_PIN
+                int "I2C1 sda pin number"
+                range 0 63
+                default 23
+        endif
+
+    menuconfig BSP_USING_SPI
+        bool "Enable SPI"
+        default n
+        select RT_USING_SPI
+        if BSP_USING_SPI
+            config BSP_USING_SPI1
+                bool "Enable SPI1"
+                default n
+
+            config BSP_USING_SPI2
+                bool "Enable SPI2"
+                default n
+
+            config BSP_USING_SPI3
+                bool "Enable SPI3"
+                default n
+        endif
+
+    menuconfig BSP_USING_TMR
+        bool "Enable Timer"
+        default n
+        select RT_USING_HWTIMER
+        if BSP_USING_TMR
+            config BSP_USING_TMR1
+                bool "Enable TMR1"
+                default n
+
+            config BSP_USING_TMR2
+                bool "Enable TMR2"
+                default n
+
+            config BSP_USING_TMR3
+                bool "Enable TMR3"
+                default n
+
+            config BSP_USING_TMR4
+                bool "Enable TMR4"
+                default n
+
+            config BSP_USING_TMR5
+                bool "Enable TMR5"
+                default n
+
+            config BSP_USING_TMR6
+                bool "Enable TMR6"
+                default n
+
+            config BSP_USING_TMR7
+                bool "Enable TMR7"
+                default n
+
+            config BSP_USING_TMR8
+                bool "Enable TMR8"
+                default n
+
+            config BSP_USING_TMR9
+                bool "Enable TMR9"
+                default n
+
+            config BSP_USING_TMR10
+                bool "Enable TMR10"
+                default n
+
+            config BSP_USING_TMR11
+                bool "Enable TMR11"
+                default n
+
+            config BSP_USING_TMR12
+                bool "Enable TMR12"
+                default n
+
+            config BSP_USING_TMR13
+                bool "Enable TMR13"
+                default n
+
+            config BSP_USING_TMR14
+                bool "Enable TMR14"
+                default n
+        endif
+
+    menuconfig BSP_USING_PWM
+        bool "Enable PWM"
+        default n
+        select RT_USING_PWM
+        if BSP_USING_PWM
+        menuconfig BSP_USING_PWM3
+            bool "Enable timer3 output PWM"
+            default n
+            if BSP_USING_PWM3
+                config BSP_USING_PWM3_CH1
+                    bool "Enable PWM3 channel1"
+                    default n
+
+                config BSP_USING_PWM3_CH2
+                    bool "Enable PWM3 channel2"
+                    default n
+
+                config BSP_USING_PWM3_CH3
+                    bool "Enable PWM3 channel3"
+                    default n
+
+                config BSP_USING_PWM3_CH4
+                    bool "Enable PWM3 channel4"
+                    default n
+            endif
+        endif
+
+    config BSP_USING_WDT
+        bool "Enable Watchdog Timer"
+        select RT_USING_WDT
+        default n
+
+endmenu
+
+endmenu

+ 30 - 0
project_0/board/SConscript

@@ -0,0 +1,30 @@
+import os
+import rtconfig
+from building import *
+
+Import('SDK_LIB')
+
+cwd = GetCurrentDir()
+
+# add general drivers
+src = Split('''
+board.c
+''')
+
+path =  [cwd]
+
+startup_path_prefix = SDK_LIB
+
+if rtconfig.CROSS_TOOL == 'keil':
+    src += [startup_path_prefix + '/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/arm/startup_apm32f40x.s']
+
+if rtconfig.CROSS_TOOL == 'iar':
+    src += [startup_path_prefix + '/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/iar/startup_apm32f40x.s']
+
+if rtconfig.CROSS_TOOL == 'gcc':
+    src += [startup_path_prefix + '/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/gcc/startup_apm32f40x.s']
+
+# You can select chips from the list above
+CPPDEFINES = ['APM32F40X']
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
+Return('group')

+ 54 - 0
project_0/board/board.c

@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-08-20     Abbcc        first version
+ */
+
+#include "board.h"
+
+void apm32_usart_init(void)
+{
+    GPIO_Config_T GPIO_ConfigStruct;
+
+#ifdef BSP_USING_UART1
+    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);
+
+    GPIO_ConfigStruct.mode = GPIO_MODE_AF;
+    GPIO_ConfigStruct.pin = GPIO_PIN_9;
+    GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
+    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
+    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_9, GPIO_AF_USART1);
+
+    GPIO_ConfigStruct.mode = GPIO_MODE_IN;
+    GPIO_ConfigStruct.pin = GPIO_PIN_10;
+    GPIO_ConfigStruct.pupd = GPIO_PUPD_UP;
+    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
+    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_10, GPIO_AF_USART1);
+#endif
+
+#ifdef BSP_USING_UART2
+    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART2);
+
+    GPIO_ConfigStruct.mode = GPIO_MODE_AF;
+    GPIO_ConfigStruct.pin = GPIO_PIN_2;
+    GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
+    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
+    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_2, GPIO_AF_USART2);
+
+    GPIO_ConfigStruct.mode = GPIO_MODE_IN;
+    GPIO_ConfigStruct.pin = GPIO_PIN_3;
+    GPIO_ConfigStruct.pupd = GPIO_PUPD_UP;
+    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
+    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_3, GPIO_AF_USART2);
+#endif
+}

+ 81 - 0
project_0/board/board.h

@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2022-03-28     Abbcc          first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <rtthread.h>
+#include <apm32f4xx.h>
+
+#include "apm32f4xx_gpio.h"
+#include "apm32f4xx_rcm.h"
+#include "apm32f4xx_misc.h"
+#include "apm32f4xx_rcm.h"
+#include "apm32f4xx_eint.h"
+#include "apm32f4xx_usart.h"
+
+#if defined(RT_USING_ADC)
+    #include "apm32f4xx_adc.h"
+#endif
+#if defined(RT_USING_DAC)
+    #include "apm32f4xx_dac.h"
+#endif
+#if defined(RT_USING_RTC)
+    #include "apm32f4xx_rtc.h"
+    #include "apm32f4xx_pmu.h"
+#endif
+#if defined(RT_USING_SPI)
+    #include "apm32f4xx_spi.h"
+#endif
+#if defined(RT_USING_HWTIMER) || defined(RT_USING_PWM)
+    #include "apm32f4xx_tmr.h"
+#endif
+#if defined(RT_USING_WDT)
+    #include "apm32f4xx_iwdt.h"
+    #include "apm32f4xx_wwdt.h"
+#endif
+
+#include "drv_common.h"
+#include "drv_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define APM32_FLASH_START_ADRESS     ((uint32_t)0x08000000)
+#define APM32_FLASH_SIZE             (1024 * 1024)
+#define APM32_FLASH_END_ADDRESS      ((uint32_t)(APM32_FLASH_START_ADRESS + APM32_FLASH_SIZE))
+
+/* Internal SRAM memory size[Kbytes] <6-128>, Default: 128 */
+#define APM32_SRAM_SIZE      128
+#define APM32_SRAM_END       (0x20000000 + APM32_SRAM_SIZE * 1024)
+
+#if defined(__ARMCC_VERSION)
+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        APM32_SRAM_END
+
+void SystemClock_Config(void);
+
+void apm32_usart_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOARD_H__ */

+ 28 - 0
project_0/board/linker_scripts/link.icf

@@ -0,0 +1,28 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__   = 0x080FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__   = 0x2001FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x0400;
+define symbol __ICFEDIT_size_heap__   = 0x0000;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
+define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
+
+initialize by copy { readwrite };
+do not initialize  { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region   { readonly };
+place in RAM_region   { readwrite, last block CSTACK};

+ 141 - 0
project_0/board/linker_scripts/link.lds

@@ -0,0 +1,141 @@
+/*
+ * linker script for APM32F10x with GNU ld
+ */
+
+/* Program Entry, set to mark it as "used" and avoid gc */
+MEMORY
+{
+    CODE (rx) : ORIGIN = 0x08000000, LENGTH = 1024k /* 1024KB flash */
+    DATA (rw) : ORIGIN = 0x20000000, LENGTH = 128k  /* 128KB sram */
+}
+ENTRY(Reset_Handler)
+_system_stack_size = 0x200;
+
+SECTIONS
+{
+    .text :
+    {
+        . = ALIGN(4);
+        _stext = .;
+        KEEP(*(.isr_vector))            /* Startup code */
+        . = ALIGN(4);
+        *(.text)                        /* remaining code */
+        *(.text.*)                      /* remaining code */
+        *(.rodata)                      /* read-only data (constants) */
+        *(.rodata*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gnu.linkonce.t*)
+
+        /* section information for finsh shell */
+        . = ALIGN(4);
+        __fsymtab_start = .;
+        KEEP(*(FSymTab))
+        __fsymtab_end = .;
+        . = ALIGN(4);
+        __vsymtab_start = .;
+        KEEP(*(VSymTab))
+        __vsymtab_end = .;
+        . = ALIGN(4);
+
+        /* section information for initial. */
+        . = ALIGN(4);
+        __rt_init_start = .;
+        KEEP(*(SORT(.rti_fn*)))
+        __rt_init_end = .;
+        . = ALIGN(4);
+
+        . = ALIGN(4);
+        _etext = .;
+    } > CODE = 0
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+
+        /* This is used by the startup in order to initialize the .data secion */
+        _sidata = .;
+    } > CODE
+    __exidx_end = .;
+
+    /* .data section which is used for initialized data */
+
+    .data : AT (_sidata)
+    {
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _sdata = . ;
+
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d*)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _edata = . ;
+    } >DATA
+
+    .stack : 
+    {
+        . = . + _system_stack_size;
+        . = ALIGN(4);
+        _estack = .;
+    } >DATA
+
+    __bss_start = .;
+    .bss :
+    {
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _sbss = .;
+
+        *(.bss)
+        *(.bss.*)
+        *(COMMON)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _ebss = . ;
+        
+        *(.bss.init)
+    } > DATA
+    __bss_end = .;
+
+    _end = .;
+
+    /* Stabs debugging sections.  */
+    .stab          0 : { *(.stab) }
+    .stabstr       0 : { *(.stabstr) }
+    .stab.excl     0 : { *(.stab.excl) }
+    .stab.exclstr  0 : { *(.stab.exclstr) }
+    .stab.index    0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment       0 : { *(.comment) }
+    /* DWARF debug sections.
+     * Symbols in the DWARF debugging sections are relative to the beginning
+     * of the section so we begin them at 0.  */
+    /* DWARF 1 */
+    .debug          0 : { *(.debug) }
+    .line           0 : { *(.line) }
+    /* GNU DWARF 1 extensions */
+    .debug_srcinfo  0 : { *(.debug_srcinfo) }
+    .debug_sfnames  0 : { *(.debug_sfnames) }
+    /* DWARF 1.1 and DWARF 2 */
+    .debug_aranges  0 : { *(.debug_aranges) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    /* DWARF 2 */
+    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+    .debug_abbrev   0 : { *(.debug_abbrev) }
+    .debug_line     0 : { *(.debug_line) }
+    .debug_frame    0 : { *(.debug_frame) }
+    .debug_str      0 : { *(.debug_str) }
+    .debug_loc      0 : { *(.debug_loc) }
+    .debug_macinfo  0 : { *(.debug_macinfo) }
+    /* SGI/MIPS DWARF 2 extensions */
+    .debug_weaknames 0 : { *(.debug_weaknames) }
+    .debug_funcnames 0 : { *(.debug_funcnames) }
+    .debug_typenames 0 : { *(.debug_typenames) }
+    .debug_varnames  0 : { *(.debug_varnames) }
+}

+ 17 - 0
project_0/board/linker_scripts/link.sct

@@ -0,0 +1,17 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
+  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
+   *.o (RESET, +First)
+   *(InRoot$$Sections)
+   .ANY (+RO)
+   .ANY (+XO)
+  }
+  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
+   .ANY (+RW +ZI)
+  }
+}
+
+

+ 18 - 0
project_0/cconfig.h

@@ -0,0 +1,18 @@
+#ifndef CCONFIG_H__
+#define CCONFIG_H__
+/* Automatically generated file; DO NOT EDIT. */
+/* compiler configure file for RT-Thread in GCC*/
+
+#define HAVE_NEWLIB_H 1
+#define LIBC_VERSION "newlib 2.4.0"
+
+#define HAVE_SYS_SIGNAL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_PTHREAD_H 1
+
+#define HAVE_FDSET 1
+#define HAVE_SIGACTION 1
+#define GCC_VERSION_STR "5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]"
+#define STDC "2011"
+
+#endif

BIN
project_0/figures/APM32F407IG.png


BIN
project_0/figures/JFlash_Leader_01.png


BIN
project_0/figures/JFlash_Leader_02.png


BIN
project_0/figures/JFlash_Leader_03.png


BIN
project_0/figures/JFlash_Leader_04.png


+ 432 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_adc.h

@@ -0,0 +1,432 @@
+/*!
+ * @file        apm32f4xx_adc.h
+ *
+ * @brief       This file contains all the functions prototypes for the ADC firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_ADC_H
+#define __APM32F4XX_ADC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup ADC_Driver
+  @{
+*/
+
+/** @defgroup ADC_Enumerations
+  @{
+*/
+
+/**
+ * @brief ADC Common mode
+ */
+typedef enum
+{
+    /* All the ADCs independent */
+    ADC_MODE_INDEPENDENT                  = (uint8_t)0x00, /*!< Independent mode */
+
+    /* ADC1 and ADC2 working together but ADC3 is independent */
+    ADC_MODE_DUAL_REGSIMULT_INJECSIMULT = (uint8_t)0x01, /*!< regular simultaneous + injected simultaneous */
+    ADC_MODE_DUAL_REGSIMULT_ALTERTRIG   = (uint8_t)0x02, /*!< regular simultaneous + alternate trigger */
+    ADC_MODE_DUAL_INJECSIMULT           = (uint8_t)0x05, /*!< Injected simultaneous mode only */
+    ADC_MODE_DUAL_REGSIMULT             = (uint8_t)0x06, /*!< Regular simultaneous mode only */
+    ADC_MODE_DUAL_INTERL                = (uint8_t)0x07, /*!< Interleaved mode only */
+    ADC_MODE_DUAL_ALTERTRIG             = (uint8_t)0x09, /*!< Alternate trigger mode only */
+
+    /* ADC1, ADC2 and ADC3 working together */
+    ADC_MODE_TRIPLE_REGSIMULT_INJECSIMULT = (uint8_t)0x11, /*!< regular simultaneous + injected simultaneous */
+    ADC_MODE_TRIPLE_REGSIMULT_ALTERTRIG   = (uint8_t)0x12, /*!< regular simultaneous + alternate trigger */
+    ADC_MODE_TRIPLE_INJECSIMULT           = (uint8_t)0x15, /*!< Injected simultaneous mode only */
+    ADC_MODE_TRIPLE_REGSIMULT             = (uint8_t)0x16, /*!< Regular simultaneous mode only */
+    ADC_MODE_TRIPLE_INTERL                = (uint8_t)0x17, /*!< Interleaved mode only */
+    ADC_MODE_TRIPLE_ALTERTRIG             = (uint8_t)0x19  /*!< Alternate trigger mode only */
+} ADC_MODE_T;
+
+/**
+ * @brief ADC Prescaler
+ */
+typedef enum
+{
+    ADC_PRESCALER_DIV2, /*!< PCLK2 2 divided frequency */
+    ADC_PRESCALER_DIV4, /*!< PCLK2 4 divided frequency */
+    ADC_PRESCALER_DIV6, /*!< PCLK2 6 divided frequency */
+    ADC_PRESCALER_DIV8  /*!< PCLK2 8 divided frequency */
+} ADC_PRESCALER_T;
+
+/**
+ * @brief ADC Direct memory access mode for multi mode
+ */
+typedef enum
+{
+    ADC_ACCESS_MODE_DISABLED, /*!< DMA mode disabled */
+    ADC_ACCESS_MODE_1,        /*!< DMA mode 1 enabled (2/3 half-words one by one - 1 then 2 then 3) */
+    ADC_ACCESS_MODE_2,        /*!< DMA mode 2 enabled (2/3 half-words by pairs - 2&1 then 1&3 then 3&2) */
+    ADC_ACCESS_MODE_3         /*!< DMA mode 3 enabled (2/3 bytes by pairs - 2&1 then 1&3 then 3&2) */
+} ADC_ACCESS_MODE_T;
+
+/**
+ * @brief ADC Delay between 2 sampling phases
+ */
+typedef enum
+{
+    ADC_TWO_SAMPLING_5CYCLES,  /*!< 5*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_6CYCLES,  /*!< 6*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_7CYCLES,  /*!< 7*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_8CYCLES,  /*!< 8*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_9CYCLES,  /*!< 9*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_10CYCLES, /*!< 10*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_11CYCLES, /*!< 11*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_12CYCLES, /*!< 12*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_13CYCLES, /*!< 13*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_14CYCLES, /*!< 14*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_15CYCLES, /*!< 15*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_16CYCLES, /*!< 16*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_17CYCLES, /*!< 17*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_18CYCLES, /*!< 18*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_19CYCLES, /*!< 19*Tadcclk delay between 2 sampling phases */
+    ADC_TWO_SAMPLING_20CYCLES  /*!< 20*Tadcclk delay between 2 sampling phases */
+} ADC_TWO_SAMPLING_T;
+
+/**
+ * @brief ADC_resolution
+ */
+typedef enum
+{
+    ADC_RESOLUTION_12BIT, /*!< ADC Resolution is 12 bits */
+    ADC_RESOLUTION_10BIT, /*!< ADC Resolution is 10 bits */
+    ADC_RESOLUTION_8BIT,  /*!< ADC Resolution is 8 bits */
+    ADC_RESOLUTION_6BIT   /*!< ADC Resolution is 6 bits */
+} ADC_RESOLUTION_T;
+
+/**
+ * @brief ADC External trigger edge for regular channels conversion
+ */
+typedef enum
+{
+    ADC_EXT_TRIG_EDGE_NONE,             /*!<Trigger detection is disabled */
+    ADC_EXT_TRIG_EDGE_RISING,           /*!<Trigger detection on rising edge */
+    ADC_EXT_TRIG_EDGE_FALLING,          /*!<Trigger detection on falling edge */
+    ADC_EXT_TRIG_EDGE_RISING_FALLING,   /*!<Trigger detection on rising edge and falling edge */
+} ADC_EXT_TRIG_EDGE_T;
+
+/**
+ * @brief ADC External event trigger select for regular group
+ */
+typedef enum
+{
+    ADC_EXT_TRIG_CONV_TMR1_CC1,     /*!<Timer1 capture compare1 selected */
+    ADC_EXT_TRIG_CONV_TMR1_CC2,     /*!<Timer1 capture compare2 selected */
+    ADC_EXT_TRIG_CONV_TMR1_CC3,     /*!<Timer1 capture compare3 selected */
+    ADC_EXT_TRIG_CONV_TMR2_CC2,     /*!<Timer2 capture compare2 selected */
+    ADC_EXT_TRIG_CONV_TMR2_CC3,     /*!<Timer2 capture compare3 selected */
+    ADC_EXT_TRIG_CONV_TMR2_CC4,     /*!<Timer2 capture compare4 selected */
+    ADC_EXT_TRIG_CONV_TMR2_TRGO,    /*!<Timer2 TRGO event selected */
+    ADC_EXT_TRIG_CONV_TMR3_CC1,     /*!<Timer3 capture compare1 selected */
+    ADC_EXT_TRIG_CONV_TMR3_TRGO,    /*!<Timer3 TRGO event selected */
+    ADC_EXT_TRIG_CONV_TMR4_CC4,     /*!<Timer4 capture compare4 selected */
+    ADC_EXT_TRIG_CONV_TMR5_CC1,     /*!<Timer5 capture compare1 selected */
+    ADC_EXT_TRIG_CONV_TMR5_CC2,     /*!<Timer5 capture compare2 selected */
+    ADC_EXT_TRIG_CONV_TMR5_CC3,     /*!<Timer5 capture compare3 selected */
+    ADC_EXT_TRIG_CONV_TMR8_CC1,     /*!<Timer8 capture compare1 selected */
+    ADC_EXT_TRIG_CONV_TMR8_TRGO,    /*!<Timer8 TRGO event selected */
+    ADC_EXT_TRIG_CONV_EINT_11       /*!<External interrupt line 11 event selected */
+} ADC_EXT_TRIG_CONV_T;
+
+/**
+ * @brief ADC Data align
+ */
+typedef enum
+{
+    ADC_DATA_ALIGN_RIGHT,   /*!<Right alignment */
+    ADC_DATA_ALIGN_LEFT     /*!<Left alignment */
+} ADC_DATA_ALIGN_T;
+
+/**
+ * @brief ADC Channel number
+ */
+typedef enum
+{
+    ADC_CHANNEL_0,  /*!< ADC Channel 0 */
+    ADC_CHANNEL_1,  /*!< ADC Channel 1 */
+    ADC_CHANNEL_2,  /*!< ADC Channel 2 */
+    ADC_CHANNEL_3,  /*!< ADC Channel 3 */
+    ADC_CHANNEL_4,  /*!< ADC Channel 4 */
+    ADC_CHANNEL_5,  /*!< ADC Channel 5 */
+    ADC_CHANNEL_6,  /*!< ADC Channel 6 */
+    ADC_CHANNEL_7,  /*!< ADC Channel 7 */
+    ADC_CHANNEL_8,  /*!< ADC Channel 8 */
+    ADC_CHANNEL_9,  /*!< ADC Channel 9 */
+    ADC_CHANNEL_10, /*!< ADC Channel 10 */
+    ADC_CHANNEL_11, /*!< ADC Channel 11 */
+    ADC_CHANNEL_12, /*!< ADC Channel 12 */
+    ADC_CHANNEL_13, /*!< ADC Channel 13 */
+    ADC_CHANNEL_14, /*!< ADC Channel 14 */
+    ADC_CHANNEL_15, /*!< ADC Channel 15 */
+    ADC_CHANNEL_16, /*!< ADC Channel 16 */
+    ADC_CHANNEL_17, /*!< ADC Channel 17 */
+    ADC_CHANNEL_18, /*!< ADC Channel 18 */
+} ADC_CHANNEL_T;
+
+/**
+ * @brief ADC_sampling_times
+ */
+typedef enum
+{
+    ADC_SAMPLETIME_3CYCLES,     /*!< Config the channel as 3 sample cyscles */
+    ADC_SAMPLETIME_15CYCLES,    /*!< Config the channel as 15 sample cyscles */
+    ADC_SAMPLETIME_28CYCLES,    /*!< Config the channel as 28 sample cyscles */
+    ADC_SAMPLETIME_56CYCLES,    /*!< Config the channel as 56 sample cyscles */
+    ADC_SAMPLETIME_84CYCLES,    /*!< Config the channel as 84 sample cyscles */
+    ADC_SAMPLETIME_112CYCLES,   /*!< Config the channel as 112 sample cyscles */
+    ADC_SAMPLETIME_144CYCLES,   /*!< Config the channel as 144 sample cyscles */
+    ADC_SAMPLETIME_480CYCLES    /*!< Config the channel as 480 sample cyscles */
+} ADC_SAMPLETIME_T;
+
+/**
+ * @brief ADC external trigger edge for injected channels conversion
+ */
+typedef enum
+{
+    ADC_EXT_TRIG_INJEC_EDGE_NONE,           /*!< Disable the external trigger for injected channels */
+    ADC_EXT_TRIG_INJEC_EDGE_RISING,         /*!< Trigger detection on rising edge */
+    ADC_EXT_TRIG_INJEC_EDGE_FALLING,        /*!< Trigger detection on rising edge */
+    ADC_EXT_TRIG_INJEC_EDGE_RISING_FALLING  /*!< Trigger detection on rising edge and falling edge */
+} ADC_EXT_TRIG_INJEC_EDGE_T;
+
+/**
+ * @brief ADC extrenal trigger sources for injected channels conversion
+ */
+typedef enum
+{
+    ADC_EXT_TRIG_INJEC_CONV_TMR1_CC4,   /*!< Timer1 capture compare 4 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR1_TRGO,  /*!< Timer1 TRGO event selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR2_CC1,   /*!< Timer2 capture compare 1 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR2_TRGO,  /*!< Timer2 TRGO event selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR3_CC2,   /*!< Timer3 capture compare 2 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR3_CC4,   /*!< Timer3 capture compare 4 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR4_CC1,   /*!< Timer4 capture compare 1 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR4_CC2,   /*!< Timer4 capture compare 2 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR4_CC3,   /*!< Timer4 capture compare 3 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR4_TRGO,  /*!< Timer4 TRGO event selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR5_CC4,   /*!< Timer5 capture compare 4 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR5_TRGO,  /*!< Timer5 TRGO event selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR8_CC2,   /*!< Timer8 capture compare 2 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR8_CC3,   /*!< Timer8 capture compare 3 selected */
+    ADC_EXT_TRIG_INJEC_CONV_TMR8_CC4,   /*!< Timer8 capture compare 4 selected */
+    ADC_EXT_TRIG_INJEC_CONV_EINT15      /*!< External interrupt line 15 event selected */
+} ADC_EXT_TRIG_INJEC_CONV_T;
+
+/**
+ * @brief ADC injected channel selection
+ */
+typedef enum
+{
+    ADC_INJEC_CHANNEL_1 = (uint8_t)0x01,    /*!< Channel injected conversion Data */
+    ADC_INJEC_CHANNEL_2 = (uint8_t)0x02,    /*!< Channe2 injected conversion Data */
+    ADC_INJEC_CHANNEL_3 = (uint8_t)0x03,    /*!< Channe3 injected conversion Data */
+    ADC_INJEC_CHANNEL_4 = (uint8_t)0x04     /*!< Channe4 injected conversion Data */
+} ADC_INJEC_CHANNEL_T;
+
+/**
+ * @brief ADC analog watchdog selection
+ */
+typedef enum
+{
+    ADC_ANALOG_WATCHDOG_SINGLE_INJEC      = (uint8_t)0x11, /*!< Analog watchdog on a single injected channel */
+    ADC_ANALOG_WATCHDOG_SINGLE_REG        = (uint8_t)0x12, /*!< Analog watchdog on a single regular channel */
+    ADC_ANALOG_WATCHDOG_SINGLE_REG_INJEC  = (uint8_t)0x13, /*!< Analog watchdog on a single regular or injected channel */
+    ADC_ANALOG_WATCHDOG_ALL_INJEC         = (uint8_t)0x01, /*!< Analog watchdog on  all injected channel */
+    ADC_ANALOG_WATCHDOG_ALL_REG           = (uint8_t)0x02, /*!< Analog watchdog on  all regular channel */
+    ADC_ANALOG_WATCHDOG_ALL_REG_ALL_INJEC = (uint8_t)0x03, /*!< Analog watchdog on all regular and injected channels */
+    ADC_ANALOG_WATCHDOG_NONE              = (uint8_t)0x00  /*!< No Analog watchdog */
+} ADC_ANALOG_WATCHDOG_T;
+
+/**
+ * @brief ADC interrupts
+ */
+typedef enum
+{
+    ADC_INT_EOC         = BIT5,     /*!< End of conversion interrupt mask */
+    ADC_INT_AWD         = BIT6,     /*!< Analog watchdog interrupt mask */
+    ADC_INT_INJEOC      = BIT7,     /*!< End of injected conversion interrupt mask */
+    ADC_INT_OVR         = BIT26     /*!< Overrun interrupt enable */
+} ADC_INT_T;
+
+/**
+ * @brief ADC interrupt flags
+ */
+typedef enum
+{
+    ADC_INT_FLAG_AWD    = 0x0501,   /*!< Analog watchdog interrupt flag */
+    ADC_INT_FLAG_EOC    = 0x0602,   /*!< End of conversion interrupt flag */
+    ADC_INT_FLAG_INJEOC = 0x0704,   /*!< End of injected conversion interrupt flag */
+    ADC_INT_FLAG_OVR    = 0x1A20    /*!< Overrun interrupt flag */
+} ADC_INT_FLAG_T;
+
+/**
+ * @brief ADC status flags
+ */
+typedef enum
+{
+    ADC_FLAG_AWD        = BIT0, /*!< Analog watchdog flag */
+    ADC_FLAG_EOC        = BIT1, /*!< End of conversion flag */
+    ADC_FLAG_INJEOC     = BIT2, /*!< End of injected group conversion flag */
+    ADC_FLAG_INJCS      = BIT3, /*!< Start of injected group conversion flag */
+    ADC_FLAG_REGCS      = BIT4, /*!< Start of regular group conversion flag */
+    ADC_FLAG_OVR        = BIT5  /*!< Overrun flag */
+} ADC_FLAG_T;
+
+/**@} end of group ADC_Enumerations*/
+
+/** @defgroup ADC_Structure
+  @{
+*/
+
+/**
+ * @brief ADC configuration Mode
+ */
+typedef struct
+{
+    ADC_RESOLUTION_T    resolution; /*!< Configures the ADC resolution dual mode.
+                                         This parameter can be a value of @ref ADC_RESOLUTION_T */
+    uint8_t             scanConvMode;       /*!< This value can be ENABLE or DISABLE */
+    uint8_t             continuousConvMode; /*!< This value can be ENABLE or DISABLE */
+    ADC_EXT_TRIG_EDGE_T extTrigEdge;        /*!< Enable the External Trigger for Regular Channels */
+    ADC_EXT_TRIG_CONV_T extTrigConv;        /*!< Select the External Trigger Event to Start the
+                                                 Regular Group Conversion */
+    ADC_DATA_ALIGN_T    dataAlign;          /*!< Data Alignment Mode Configure */
+    uint8_t             nbrOfChannel; /*!< regular channel sequence length can be from 1 to 16 */
+} ADC_Config_T;
+
+/**
+ * @brief ADC Common Init structure definition
+ */
+typedef struct
+{
+    ADC_MODE_T         mode;        /*!< ADC mode selection */
+    ADC_PRESCALER_T    prescaler;   /*!< ADC Prescaler */
+    ADC_ACCESS_MODE_T  accessMode;  /*!< DMA Mode */
+    ADC_TWO_SAMPLING_T twoSampling; /*!< Delay Between 2 Sampling Phases */
+} ADC_CommonConfig_T;
+
+/**@} end of group ADC_Structure*/
+
+/** @defgroup ADC_Functions
+  @{
+*/
+
+/* ADC Reset */
+void ADC_Reset(void);
+
+/* Configuration */
+void ADC_Config(ADC_T* adc, ADC_Config_T* adcConfig);
+void ADC_ConfigStructInit(ADC_Config_T* adcConfig);
+void ADC_CommonConfig(ADC_CommonConfig_T* adcCommonConfig);
+void ADC_CommonConfigStructInit(ADC_CommonConfig_T* adcCommonConfig);
+void ADC_Enable(ADC_T* adc);
+void ADC_Disable(ADC_T* adc);
+
+/* Analog Watchdog */
+void ADC_EnableAnalogWatchdog(ADC_T* adc, ADC_ANALOG_WATCHDOG_T analogWatchdog);
+void ADC_DisableAnalogWatchdog(ADC_T* adc);
+void ADC_ConfigAnalogWatchdogThresholds(ADC_T* adc, uint16_t highThreshold, uint16_t lowThreshold);
+void ADC_ConfigAnalogWatchdogSingleChannel(ADC_T* adc, uint8_t channel);
+
+/* Temperature Sensor, Vrefint and VBAT management **/
+void ADC_EnableTempSensorVrefint(void);
+void ADC_DisableTempSensorVrefint(void);
+void ADC_EnableVbat(void);
+void ADC_DisableVbat(void);
+
+/* Regular Channels Configuration */
+void ADC_ConfigRegularChannel(ADC_T* adc, uint8_t channel,
+                              uint8_t rank, uint8_t sampleTime);
+void ADC_SoftwareStartConv(ADC_T* adc);
+uint8_t ADC_ReadSoftwareStartConvStatus(ADC_T* adc);
+
+void ADC_EnableEOCOnEachChannel(ADC_T* adc);
+void ADC_DisableEOCOnEachChannel(ADC_T* adc);
+
+/* Continuous Mode */
+void ADC_EnableContinuousMode(ADC_T* adc);
+void ADC_DisableContinuousMode(ADC_T* adc);
+
+/* Discontinuous Mode */
+void ADC_ConfigDiscMode(ADC_T* adc, uint8_t number);
+void ADC_EnableDiscMode(ADC_T* adc);
+void ADC_DisableDiscMode(ADC_T* adc);
+
+uint16_t ADC_ReadConversionValue(ADC_T* adc);
+uint32_t ADC_ReadMultiValue(void);
+
+/* Regular Channels DMA */
+void ADC_EnableDMA(ADC_T* adc);
+void ADC_DisableDMA(ADC_T* adc);
+
+void ADC_EnableDMARequest(ADC_T* adc);
+void ADC_DisableDMARequest(ADC_T* adc);
+
+void ADC_EnableMultiModeDMARequest(void);
+void ADC_DisableMultiModeDMARequest(void);
+
+/* Injected channels Configuration functions */
+void ADC_ConfigInjectedChannel(ADC_T* adc, uint8_t channel, uint8_t rank,
+                               uint8_t sampleTime);
+void ADC_ConfigInjectedSequencerLength(ADC_T* adc, uint8_t length);
+void ADC_ConfigInjectedOffset(ADC_T* adc, ADC_INJEC_CHANNEL_T channel, uint16_t offset);
+void ADC_ConfigExternalTrigInjectedConv(ADC_T* adc, ADC_EXT_TRIG_INJEC_CONV_T extTrigInjecConv);
+void ADC_ConfigExternalTrigInjectedConvEdge(ADC_T* adc, ADC_EXT_TRIG_INJEC_EDGE_T extTrigInjecConvEdge);
+void ADC_EnableSoftwareStartInjectedConv(ADC_T* adc);
+uint8_t ADC_ReadSoftwareStartInjectedConvStatus(ADC_T* adc);
+void ADC_EnableAutoInjectedConv(ADC_T* adc);
+void ADC_DisableAutoInjectedConv(ADC_T* adc);
+void ADC_EnableInjectedDiscMode(ADC_T* adc);
+void ADC_DisableInjectedDiscMode(ADC_T* adc);
+uint16_t ADC_ReadInjectedConversionValue(ADC_T* adc, ADC_INJEC_CHANNEL_T channel);
+
+/* Interrupts and flags */
+void ADC_EnableInterrupt(ADC_T* adc, uint32_t interrupt);
+void ADC_DisableInterrupt(ADC_T* adc, uint32_t interrupt);
+uint8_t ADC_ReadStatusFlag(ADC_T* adc,  ADC_FLAG_T flag);
+void ADC_ClearStatusFlag(ADC_T* adc, uint32_t flag);
+uint16_t ADC_ReadIntFlag(ADC_T* adc, ADC_INT_FLAG_T flag);
+void ADC_ClearIntFlag(ADC_T* adc, uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_ADC_H */
+
+/**@} end of group ADC_Functions */
+/**@} end of group ADC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 349 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_can.h

@@ -0,0 +1,349 @@
+/*!
+ * @file        apm32f4xx_can.h
+ *
+ * @brief       This file contains all the functions prototypes for the CAN firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_CAN_H
+#define __APM32F4XX_CAN_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup CAN_Driver
+  @{
+*/
+
+/** @defgroup CAN_Enumerations
+  @{
+*/
+
+/**
+ * @brief CAN mode
+ */
+typedef enum
+{
+    CAN_MODE_NORMAL          = ((uint8_t)0x00),  /*!< normal mode */
+    CAN_MODE_LOOPBACK        = ((uint8_t)0x01),  /*!< loopback mode */
+    CAN_MODE_SILENT          = ((uint8_t)0x02),  /*!< silent mode */
+    CAN_MODE_SILENT_LOOPBACK = ((uint8_t)0x03)   /*!< loopback combined with silent mode */
+} CAN_MODE_T;
+
+/**
+ * @brief CAN Operating Mode
+ */
+typedef enum
+{
+    CAN_OPERATING_MODE_INIT   = ((uint8_t)0x00), /*!< Initialization mode */
+    CAN_OPERATING_MODE_NORMAL = ((uint8_t)0x01), /*!< Normal mode */
+    CAN_OPERATING_MODE_SLEEP  = ((uint8_t)0x02)  /*!< sleep mode */
+} CAN_OPERATING_MODE_T;
+
+/**
+ * @brief CAN synchronisation jump width
+ */
+typedef enum
+{
+    CAN_SJW_1 = ((uint8_t)0x00),  /*!< 1 time quantum */
+    CAN_SJW_2 = ((uint8_t)0x01),  /*!< 2 time quantum */
+    CAN_SJW_3 = ((uint8_t)0x02),  /*!< 3 time quantum */
+    CAN_SJW_4 = ((uint8_t)0x03)   /*!< 4 time quantum */
+} CAN_SJW_T;
+
+/**
+ * @brief CAN time quantum in bit segment 1
+ */
+typedef enum
+{
+    CAN_TIME_SEGMENT1_1  = ((uint8_t)0x00),  /*!< 1  time quanta */
+    CAN_TIME_SEGMENT1_2  = ((uint8_t)0x01),  /*!< 2  time quanta */
+    CAN_TIME_SEGMENT1_3  = ((uint8_t)0x02),  /*!< 3  time quanta */
+    CAN_TIME_SEGMENT1_4  = ((uint8_t)0x03),  /*!< 4  time quanta */
+    CAN_TIME_SEGMENT1_5  = ((uint8_t)0x04),  /*!< 5  time quanta */
+    CAN_TIME_SEGMENT1_6  = ((uint8_t)0x05),  /*!< 6  time quanta */
+    CAN_TIME_SEGMENT1_7  = ((uint8_t)0x06),  /*!< 7  time quanta */
+    CAN_TIME_SEGMENT1_8  = ((uint8_t)0x07),  /*!< 8  time quanta */
+    CAN_TIME_SEGMENT1_9  = ((uint8_t)0x08),  /*!< 9  time quanta */
+    CAN_TIME_SEGMENT1_10 = ((uint8_t)0x09),  /*!< 10 time quanta */
+    CAN_TIME_SEGMENT1_11 = ((uint8_t)0x0A),  /*!< 11 time quanta */
+    CAN_TIME_SEGMENT1_12 = ((uint8_t)0x0B),  /*!< 12 time quanta */
+    CAN_TIME_SEGMENT1_13 = ((uint8_t)0x0C),  /*!< 13 time quanta */
+    CAN_TIME_SEGMENT1_14 = ((uint8_t)0x0D),  /*!< 14 time quanta */
+    CAN_TIME_SEGMENT1_15 = ((uint8_t)0x0E),  /*!< 15 time quanta */
+    CAN_TIME_SEGMENT1_16 = ((uint8_t)0x0F)   /*!< 16 time quanta */
+} CAN_TIME_SEGMENT1_T;
+
+/**
+ * @brief CAN time quantum in bit segment 2
+ */
+typedef enum
+{
+    CAN_TIME_SEGMENT2_1 = (uint8_t)0x00,     /*!< 1  time quanta */
+    CAN_TIME_SEGMENT2_2 = (uint8_t)0x01,     /*!< 2  time quanta */
+    CAN_TIME_SEGMENT2_3 = (uint8_t)0x02,     /*!< 3  time quanta */
+    CAN_TIME_SEGMENT2_4 = (uint8_t)0x03,     /*!< 4  time quanta */
+    CAN_TIME_SEGMENT2_5 = (uint8_t)0x04,     /*!< 5  time quanta */
+    CAN_TIME_SEGMENT2_6 = (uint8_t)0x05,     /*!< 6  time quanta */
+    CAN_TIME_SEGMENT2_7 = (uint8_t)0x06,     /*!< 7  time quanta */
+    CAN_TIME_SEGMENT2_8 = (uint8_t)0x07      /*!< 8  time quanta */
+} CAN_TIME_SEGMENT2_T;
+
+/**
+ * @brief CAN filter mode
+ */
+typedef enum
+{
+    CAN_FILTER_MODE_IDMASK = ((uint8_t)0x00), /*!< identifier/mask mode */
+    CAN_FILTER_MODE_IDLIST = ((uint8_t)0x01)  /*!< identifier list mode */
+} CAN_FILTER_MODE_T;
+
+/**
+ * @brief CAN filter scale
+ */
+typedef enum
+{
+    CAN_FILTER_SCALE_16BIT = ((uint8_t)0x00), /*!< Two 16-bit filters */
+    CAN_FILTER_SCALE_32BIT = ((uint8_t)0x01)  /*!< One 32-bit filter */
+} CAN_FILTER_SCALE_T;
+
+/**
+ * @brief CAN filter FIFO
+ */
+typedef enum
+{
+    CAN_FILTER_FIFO_0 = ((uint8_t)0x00),     /*!< filter FIFO 0 */
+    CAN_FILTER_FIFO_1 = ((uint8_t)0x01)      /*!< filter FIFO 1 */
+} CAN_FILTER_FIFO_T;
+
+/**
+ * @brief CAN identifier type
+ */
+typedef enum
+{
+    CAN_TYPEID_STD = ((uint32_t)0x00000000), /*!< Standard Id */
+    CAN_TYPEID_EXT = ((uint32_t)0x00000004)  /*!< Extended Id */
+} CAN_TYPEID_T;
+
+/**
+ * @brief CAN_remote_transmission_request
+ */
+typedef enum
+{
+    CAN_RTXR_DATA   = ((uint32_t)0x00000000), /*!< Data frame */
+    CAN_RTXR_REMOTE = ((uint32_t)0x00000002)  /*!< Remote frame */
+} CAN_RTXR_T;
+
+/**
+ * @brief Mailboxes definition
+ */
+typedef enum
+{
+    CAN_TX_MAILBIX_0 = ((uint8_t)0x00), /*!< Tx mailbox0 */
+    CAN_TX_MAILBIX_1 = ((uint8_t)0x01), /*!< Tx mailbox1 */
+    CAN_TX_MAILBIX_2 = ((uint8_t)0x02)  /*!< Tx mailbox2 */
+} CAN_TX_MAILBIX_T;
+
+/**
+ * @brief CAN receive FIFO number constants
+ */
+typedef enum
+{
+    CAN_RX_FIFO_0 = ((uint8_t)0x00), /*!< receive FIFO 0 */
+    CAN_RX_FIFO_1 = ((uint8_t)0x01)  /*!< receive FIFO 1 */
+} CAN_RX_FIFO_T;
+
+/**
+ * @brief CAN Flags
+ */
+typedef enum
+{
+    /* Error flag*/
+    CAN_FLAG_ERRW   = ((uint32_t)0x10F00001),  /*!< Error Warning Flag */
+    CAN_FLAG_ERRP   = ((uint32_t)0x10F00002),  /*!< Error Passive Flag */
+    CAN_FLAG_BOF    = ((uint32_t)0x10F00004),  /*!< Bus-Off Flag */
+    CAN_FLAG_LERRC  = ((uint32_t)0x30F00070),  /*!< Last error record code Flag */
+    /* Operating Mode Flags */
+    CAN_FLAG_WUPI   = ((uint32_t)0x31000008),  /*!< Wake up Flag */
+    CAN_FLAG_SLEEP  = ((uint32_t)0x31000012),  /*!< Sleep acknowledge Flag */
+    /* Receive Flags */
+    CAN_FLAG_F0MP   = ((uint32_t)0x12000003),  /*!< FIFO 0 Message Pending Flag */
+    CAN_FLAG_F0FULL = ((uint32_t)0x32000008),  /*!< FIFO 0 Full Flag */
+    CAN_FLAG_F0OVR  = ((uint32_t)0x32000010),  /*!< FIFO 0 Overrun Flag */
+    CAN_FLAG_F1MP   = ((uint32_t)0x14000003),  /*!< FIFO 1 Message Pending Flag */
+    CAN_FLAG_F1FULL = ((uint32_t)0x34000008),  /*!< FIFO 1 Full Flag */
+    CAN_FLAG_F1OVR  = ((uint32_t)0x34000010),  /*!< FIFO 1 Overrun Flag */
+    /* Transmit Flags */
+    CAN_FLAG_REQC0  = ((uint32_t)0x38000001),  /*!< Request MailBox0 Flag */
+    CAN_FLAG_REQC1  = ((uint32_t)0x38000100),  /*!< Request MailBox1 Flag */
+    CAN_FLAG_REQC2  = ((uint32_t)0x38010000)   /*!< Request MailBox2 Flag */
+} CAN_FLAG_T;
+
+/**
+ * @brief CAN Interrupts
+ */
+typedef enum
+{
+    CAN_INT_TXME   = ((uint32_t)0x00000001), /*!< Transmit mailbox empty Interrupt */
+    CAN_INT_F0MP   = ((uint32_t)0x00000002), /*!< FIFO 0 message pending Interrupt */
+    CAN_INT_F0FULL = ((uint32_t)0x00000004), /*!< FIFO 0 full Interrupt */
+    CAN_INT_F0OVR  = ((uint32_t)0x00000008), /*!< FIFO 0 overrun Interrupt */
+    CAN_INT_F1MP   = ((uint32_t)0x00000010), /*!< FIFO 1 message pending Interrupt */
+    CAN_INT_F1FULL = ((uint32_t)0x00000020), /*!< FIFO 1 full Interrupt */
+    CAN_INT_F1OVR  = ((uint32_t)0x00000040), /*!< FIFO 1 overrun Interrupt */
+    CAN_INT_ERRW   = ((uint32_t)0x00000100), /*!< Error warning Interrupt */
+    CAN_INT_ERRP   = ((uint32_t)0x00000200), /*!< Error passive Interrupt */
+    CAN_INT_BOF    = ((uint32_t)0x00000400), /*!< Bus-off Interrupt */
+    CAN_INT_LEC    = ((uint32_t)0x00000800), /*!< Last error record code Interrupt */
+    CAN_INT_ERR    = ((uint32_t)0x00008000), /*!< Error Interrupt */
+    CAN_INT_WUP    = ((uint32_t)0x00010000), /*!< Wake-up Interrupt */
+    CAN_INT_SLEEP  = ((uint32_t)0x00020000)  /*!< Sleep acknowledge Interrupt */
+} CAN_INT_T;
+
+/**@} end of group CAN_Enumerations*/
+
+/** @defgroup CAN_Structure
+  @{
+*/
+
+/**
+ * @brief CAN config structure definition
+ */
+typedef struct
+{
+    uint8_t      autoBusOffManage;    /*!< Enable or disable the automatic bus-off management. */
+    uint8_t      autoWakeUpMode;      /*!< Enable or disable the automatic wake-up mode. */
+    uint8_t      nonAutoRetran;       /*!< Enable or disable the non-automatic retransmission mode. */
+    uint8_t      rxFIFOLockMode;      /*!< Enable or disable the Receive FIFO Locked mode. */
+    uint8_t      txFIFOPriority;      /*!< Enable or disable the transmit FIFO priority. */
+    CAN_MODE_T   mode;                /*!< Specifies the CAN operating mode. */
+    CAN_SJW_T    syncJumpWidth;       /*!< Specifies the maximum number of time quanta the CAN hardware
+                                           is allowed to lengthen or shorten a bit to perform resynchronization.
+                                       */
+    CAN_TIME_SEGMENT1_T timeSegment1; /*!< Specifies the number of time quanta in Bit Segment 1. */
+    CAN_TIME_SEGMENT2_T timeSegment2; /*!< Specifies the number of time quanta in Bit Segment 2. */
+    uint16_t            prescaler;    /*!< Specifies the length of a time quantum. It can be 1 to 1024. */
+} CAN_Config_T;
+
+/**
+ * @brief     CAN filter config structure definition
+ */
+typedef struct
+{
+    uint8_t             filterNumber;      /*!< It ranges from 0 to 27. */
+    uint16_t            filterIdHigh;      /*!< This parameter can be a value between 0x0000 and 0xFFFF */
+    uint16_t            filterIdLow;       /*!< This parameter can be a value between 0x0000 and 0xFFFF */
+    uint16_t            filterMaskIdHigh;  /*!< This parameter can be a value between 0x0000 and 0xFFFF */
+    uint16_t            filterMaskIdLow;   /*!< This parameter can be a value between 0x0000 and 0xFFFF */
+    uint16_t            filterActivation;  /*!< This parameter can be set either to ENABLE or DISABLE. */
+    CAN_FILTER_FIFO_T   filterFIFO;
+    CAN_FILTER_MODE_T   filterMode;
+    CAN_FILTER_SCALE_T  filterScale;
+} CAN_FilterConfig_T;
+
+/**
+ * @brief  CAN Tx message structure definition
+ */
+typedef struct
+{
+    uint32_t            stdID;          /*!< Standard Identifier */
+    uint32_t            extID;          /*!< Extended Identifier */
+    CAN_TYPEID_T        typeID;         /*!< Identifier Type Select */
+    CAN_RTXR_T          remoteTxReq;    /*!< Transmit Remote Frame Request */
+    uint8_t             dataLengthCode; /*!< Transmit Data Length Code Setup */
+    uint8_t             data[8];        /*!< Data of the Message */
+} CAN_TxMessage_T;
+
+/**
+ * @brief  CAN Rx message structure definition
+ */
+typedef struct
+{
+    uint32_t            stdID;              /*!< Standard Identifier */
+    uint32_t            extID;              /*!< Extended Identifier */
+    uint32_t            typeID;             /*!< Identifier Type Select */
+    uint32_t            remoteTxReq;        /*!< Remote Frame Transmission Request */
+    uint8_t             dataLengthCode;     /*!< Transmit Data Length Code Setup */
+    uint8_t             data[8];            /*!< Data of the Message */
+    uint8_t             filterMatchIndex;   /*!< Filter Match Index Setup */
+} CAN_RxMessage_T;
+
+/**@} end of group CAN_Structure*/
+
+/** @defgroup CAN_Functions
+  @{
+*/
+
+/* CAN reset and configuration */
+void CAN_Reset(CAN_T* can);
+uint8_t CAN_Config(CAN_T* can, CAN_Config_T* canConfig);
+void CAN_ConfigFilter(CAN_FilterConfig_T* filterConfig);
+void CAN_ConfigStructInit(CAN_Config_T* canConfig);
+void CAN_SlaveStartBank(CAN_T* can, uint8_t bankNum);
+void CAN_EnableDBGFreeze(CAN_T* can);
+void CAN_DisableDBGFreeze(CAN_T* can);
+
+/* CAN frames transmit */
+uint8_t CAN_TxMessage(CAN_T* can, CAN_TxMessage_T* TxMessage);
+uint8_t CAN_TxMessageStatus(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox);
+void CAN_CancelTxMailbox(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox);
+
+/* CAN frames receive */
+void CAN_RxMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber, CAN_RxMessage_T* RxMessage);
+void CAN_ReleaseFIFO(CAN_T* can, CAN_RX_FIFO_T FIFONumber);
+uint8_t CAN_PendingMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber);
+
+/* CAN operation modes */
+uint8_t CAN_OperatingMode(CAN_T* can, CAN_OPERATING_MODE_T operatingMode);
+uint8_t CAN_SleepMode(CAN_T* can);
+uint8_t CAN_WakeUpMode(CAN_T* can);
+
+/* CAN bus error management */
+uint8_t CAN_ReadLastErrorCode(CAN_T* can);
+uint8_t CAN_ReadRxErrorCounter(CAN_T* can);
+uint8_t CAN_ReadLSBTxErrorCounter(CAN_T* can);
+
+/* CAN interrupt and flag */
+void CAN_EnableInterrupt(CAN_T* can, uint32_t interrupt);
+void CAN_DisableInterrupt(CAN_T* can, uint32_t interrupt);
+uint8_t CAN_ReadStatusFlag(CAN_T* can, CAN_FLAG_T flag);
+void CAN_ClearStatusFlag(CAN_T* can, CAN_FLAG_T flag);
+uint8_t CAN_ReadIntFlag(CAN_T* can, CAN_INT_T flag);
+void CAN_ClearIntFlag(CAN_T* can, CAN_INT_T flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_CAN_H */
+
+/**@} end of group CAN_Enumerations */
+/**@} end of group CAN_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 66 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_crc.h

@@ -0,0 +1,66 @@
+/*!
+ * @file        apm32f4xx_crc.h
+ *
+ * @brief       This file contains all the functions prototypes for the CRC firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_CRC_H
+#define __APM32F4XX_CRC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup CRC_Driver
+  @{
+*/
+
+/** @defgroup CRC_Functions
+  @{
+*/
+
+/* Reset DATA */
+void CRC_ResetDATA(void);
+
+/* Operation functions */
+uint32_t CRC_CalculateCRC(uint32_t data);
+uint32_t CRC_CalculateBlockCRC(uint32_t *buf, uint32_t bufLen);
+uint32_t CRC_ReadCRC(void);
+void CRC_WriteIDRegister(uint8_t inData);
+uint8_t CRC_ReadIDRegister(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_CRC_H */
+
+/**@} end of group CRC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 272 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_cryp.h

@@ -0,0 +1,272 @@
+/*!
+ * @file        apm32f4xx_cryp.h
+ *
+ * @brief       This file contains all the functions prototypes for the CRYP firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_CRYP_H
+#define __APM32F4XX_CRYP_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup CRYP_Driver
+  @{
+*/
+
+/** @defgroup CRYP_Enumerations
+  @{
+*/
+
+/**
+ * @brief CRYP Algorithm Direction
+ */
+typedef enum
+{
+    CRYP_ALGODIR_ENCRYPT,   /*!< Encryption */
+    CRYP_ALGODIR_DECRYPT    /*!< Decryption */
+} CRYP_ALGODIR_T;
+
+/**
+ * @brief CRYP Algorithm Mode
+ */
+typedef enum
+{
+    CRYP_ALGOMODE_TDES_ECB = 0x00,  /*!< TDES ECB Mode */
+    CRYP_ALGOMODE_TDES_CBC = 0x01,  /*!< TDES CBC Mode */
+    CRYP_ALGOMODE_DES_ECB  = 0x02,  /*!< DES ECB Mode */
+    CRYP_ALGOMODE_DES_CBC  = 0x03,  /*!< DES CBC Mode */
+    CRYP_ALGOMODE_AES_ECB  = 0x04,  /*!< AES ECB Mode */
+    CRYP_ALGOMODE_AES_CBC  = 0x05,  /*!< AES CBC Mode */
+    CRYP_ALGOMODE_AES_CTR  = 0x06,  /*!< AES CTR Mode */
+    CRYP_ALGOMODE_AES_KEY  = 0x07   /*!< AES KEY Mode */
+} CRYP_ALGOMODE_T;
+
+/**
+ * @brief CRYP Data Type
+ */
+typedef enum
+{
+    CRYP_DATATYPE_32B,  /*!< 32-bit data */
+    CRYP_DATATYPE_16B,  /*!< 16-bit or half-word data */
+    CRYP_DATATYPE_8B,   /*!< 8-bit or byte data */
+    CRYP_DATATYPE_1B    /*!< bit or bits */
+} CRYP_DATATYPE_T;
+
+/**
+ * @brief CRYP Key Size (only AES)
+ */
+typedef enum
+{
+    CRYP_KEYSIZE_128B,  /*!< 128-bit key size */
+    CRYP_KEYSIZE_192B,  /*!< 192-bit key size */
+    CRYP_KEYSIZE_256B   /*!< 256-bit key size */
+} CRYP_KEYSIZE_T;
+
+/**
+  * @brief CRYP flag
+  */
+typedef enum
+{
+    CRYP_FLAG_IFEMPT   =  0x01, /*!< Input FIFO Empty */
+    CRYP_FLAG_IFFULL   =  0x02, /*!< Input FIFO not Full */
+    CRYP_FLAG_OFEMPT   =  0x04, /*!< Output FIFO not Empty */
+    CRYP_FLAG_OFFULL   =  0x08, /*!< Output FIFO Full */
+    CRYP_FLAG_BUSY     =  0x10, /*!< Busy Bit */
+    CRYP_FLAG_INISTS   =  0x21, /*!< Input FIFO Service Raw Interrupt Status */
+    CRYP_FLAG_OUTISTS  =  0x22  /*!< Output FIFO Service Raw Interrupt Status */
+} CRYP_FLAG_T;
+
+/**
+ * @brief CRYP interrupt
+ */
+typedef enum
+{
+    CRYP_INT_IN  = 0x01,    /*!< Input FIFO interrupt */
+    CRYP_INT_OUT = 0x02     /*!< Output FIFO interrupt */
+} CRYP_INT_T;
+
+/**
+ * @brief CRYP Encryption/Decryption_mode
+ */
+typedef enum
+{
+    CRYP_MODE_DECRYPT  = 0x00,  /*!< Encryption */
+    CRYP_MODE_ENCRYPT  = 0x01   /*!< Decryption */
+} CRYP_MODE_T;
+
+/**
+ * @brief CRYP DMA transfer request
+ */
+typedef enum
+{
+    CRYP_DMAREQ_DATAIN  =  0x01,    /*!< DMA Input Enable */
+    CRYP_DMAREQ_DATAOUT =  0x02     /*!< DMA Output Enable */
+} CRYP_DMAREQ_T;
+
+/**@} end of group CRYP_Enumerations*/
+
+/** @addtogroup CRYP_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief CRYP Config structure definition
+ */
+typedef struct
+{
+    CRYP_ALGODIR_T      algoDir;    /*!< Algorithm Direction Select */
+    CRYP_ALGOMODE_T     algoMode;   /*!< Algorithm Mode Select */
+    CRYP_DATATYPE_T     dataType;   /*!< Data Type Select */
+    CRYP_KEYSIZE_T      keySize;    /*!< Key Size Select */
+} CRYP_Config_T;
+
+/**
+ * @brief   CRYP KeyConfig structure definition
+ */
+typedef struct
+{
+    uint32_t          key0Left;     /*!< key0 left */
+    uint32_t          key0Right;    /*!< key0 right */
+    uint32_t          key1Left;     /*!< key1 left */
+    uint32_t          key1Right;    /*!< key1 right */
+    uint32_t          key2Left;     /*!< key2 left */
+    uint32_t          key2Right;    /*!< key2 right */
+    uint32_t          key3Left;     /*!< key3 left */
+    uint32_t          key3Right;    /*!< key3 right */
+} CRYP_KeyConfig_T;
+
+/**
+ * @brief   CRYP Initialization Vectors (IV) structure definition
+ */
+typedef struct
+{
+    uint32_t          IV0Left;      /*!< Initialization Vector0 left */
+    uint32_t          IV0Right;     /*!< Initialization Vector0 right */
+    uint32_t          IV1Left;      /*!< Initialization Vector1 left */
+    uint32_t          IV1Right;     /*!< Initialization Vector1 right */
+} CRYP_IVConfig_T;
+
+/**
+ * @brief  CRYP context swapping structure definition
+ */
+typedef struct
+{
+    /* Current Configuration */
+    uint32_t    curCTRL;    /*!< Current Configuration */
+    /* IV */
+    uint32_t    IV0L;       /*!< Initialization Vector0 left */
+    uint32_t    IV0R;       /*!< Initialization Vector0 right */
+    uint32_t    IV1L;       /*!< Initialization Vector1 left */
+    uint32_t    IV1R;       /*!< Initialization Vector1 right */
+    /* KEY */
+    uint32_t    K0L;        /*!< key0 left */
+    uint32_t    K0R;        /*!< key0 right */
+    uint32_t    K1L;        /*!< key1 left */
+    uint32_t    K1R;        /*!< key1 right */
+    uint32_t    K2L;        /*!< key2 left */
+    uint32_t    K2R;        /*!< key2 right */
+    uint32_t    K3L;        /*!< key3 left */
+    uint32_t    K3R;        /*!< key3 right */
+} CRYP_Context_T;
+
+/**@} end of group CRYP_Structure*/
+
+/** @defgroup CRYP_Functions
+  @{
+*/
+
+/* CRYP Configuration */
+void CRYP_Reset(void);
+void CRYP_Config(CRYP_Config_T* crypConfig);
+void CRYP_ConfigStructInit(CRYP_Config_T* crypConfig);
+void CRYP_ConfigKey(CRYP_KeyConfig_T* keyConfig);
+void CRYP_ConfigKeyStructInit(CRYP_KeyConfig_T* keyConfig);
+void CRYP_ConfigIV(CRYP_IVConfig_T* IVConfig);
+void CRYP_ConfigIVStructInit(CRYP_IVConfig_T* IVConfig);
+void CRYP_Enable(void);
+void CRYP_Disable(void);
+void CRYP_FlushFIFO(void);
+
+/* CRYP Data processing */
+void CRYP_InData(uint32_t Data);
+uint32_t CRYP_OutData(void);
+
+/* CRYP Context swapping */
+uint32_t CRYP_SaveContext(CRYP_Context_T* context, CRYP_KeyConfig_T* keyConfig);
+void CRYP_RestoreContext(CRYP_Context_T* context);
+
+/* CRYP DMA */
+void CRYP_EnableDMA(CRYP_DMAREQ_T dmaReq);
+void CRYP_DisableDMA(CRYP_DMAREQ_T dmaReq);
+
+/* CRYP Interrupt and flag */
+void CRYP_EnableInterrupt(uint8_t interrupt);
+void CRYP_DisableInterrupt(uint8_t interrupt);
+uint8_t CRYP_ReadIntFlag(CRYP_INT_T flag);
+uint8_t CRYP_ReadStatusFlag(CRYP_FLAG_T flag);
+uint8_t CRYP_ReadCmdStatus(void);
+
+/* High Level AES */
+uint8_t CRYP_AES_ECB(CRYP_MODE_T mode, uint8_t *key,    uint16_t keysize,
+                       uint8_t *input, uint32_t length, uint8_t  *output);
+
+uint8_t CRYP_AES_CBC(CRYP_MODE_T mode, uint8_t *key,    uint16_t keysize,
+                                       uint8_t IV[16],  uint8_t  *input,
+                                       uint32_t length, uint8_t  *output);
+
+uint8_t CRYP_AES_CTR(CRYP_MODE_T mode, uint8_t  *key,   uint16_t keysize,
+                                       uint8_t  IV[16], uint8_t  *input,
+                                       uint32_t length, uint8_t  *output);
+
+/* High Level DES */
+uint8_t CRYP_DES_ECB(CRYP_MODE_T mode, uint8_t key[8], uint8_t *input,
+                                      uint32_t length, uint8_t *output);
+
+uint8_t CRYP_DES_CBC(CRYP_MODE_T mode, uint8_t key[8],  uint8_t *input,
+                        uint8_t IV[8], uint32_t length, uint8_t *output);
+
+/* High Level TDES */
+uint8_t CRYP_TDES_ECB(CRYP_MODE_T mode, uint8_t key[24], uint8_t *input,
+                                       uint32_t length,  uint8_t *output);
+
+uint8_t CRYP_TDES_CBC(CRYP_MODE_T mode,uint8_t key[24], uint8_t *input,
+                        uint8_t IV[8], uint32_t length, uint8_t *output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_CRYP_H */
+
+/**@} end of group CRYP_Enumerations */
+/**@} end of group CRYP_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 203 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dac.h

@@ -0,0 +1,203 @@
+/*!
+ * @file        apm32f4xx_dac.h
+ *
+ * @brief       This file contains all the functions prototypes for the DAC firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_DAC_H
+#define __APM32F4XX_DAC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup DAC_Driver
+  @{
+*/
+
+/** @defgroup DAC_Enumerations
+  @{
+*/
+
+/**
+ * @brief DAC Channel selection
+ */
+typedef enum
+{
+    DAC_CHANNEL_1 = 0x00000000, /*!< DAC channel 1 */
+    DAC_CHANNEL_2 = 0x00000010  /*!< DAC channel 2 */
+} DAC_CHANNEL_T;
+
+/**
+ * @brief DAC trigger selection
+ */
+typedef enum
+{
+    DAC_TRIGGER_NONE       = 0x00000000,    /*!< DAC channel trigger disable */
+    DAC_TRIGGER_TMR6_TRGO  = 0x00000004,    /*!< Enable trigger and select TMR6 TRGO event to trigger */
+    DAC_TRIGGER_TMR8_TRGO  = 0x0000000C,    /*!< Enable trigger and select TMR8 TRGO event to trigger */
+    DAC_TRIGGER_TMR7_TRGO  = 0x00000014,    /*!< Enable trigger and select TMR7 TRGO event to trigger */
+    DAC_TRIGGER_TMR5_TRGO  = 0x0000001C,    /*!< Enable trigger and select TMR5 TRGO event to trigger */
+    DAC_TRIGGER_TMR2_TRGO  = 0x00000024,    /*!< Enable trigger and select TMR2 TRGO event to trigger */
+    DAC_TRIGGER_TMR4_TRGO  = 0x0000002C,    /*!< Enable trigger and select TMR4 TRGO event to trigger */
+    DAC_TRIGGER_EINT9      = 0x00000034,    /*!< Enable trigger and select EINT9 to trigger */
+    DAC_TRIGGER_SOFT       = 0x0000003C     /*!< Enable trigger and select software to trigger */
+} DAC_TRIGGER_T;
+
+/**
+ * @brief DAC wave generation
+ */
+typedef enum
+{
+    DAC_WAVE_GENERATION_NONE     = 0x00000000,  /*!< Disable wave generation */
+    DAC_WAVE_GENERATION_NOISE    = 0x00000040,  /*!< Enable generate noise wave */
+    DAC_WAVE_GENERATION_TRIANGLE = 0x00000080   /*!< Enable generate triangle wave */
+} DAC_WAVE_GENERATION_T;
+
+/**
+ * @brief DAC channelx mask/amplitude selector
+ */
+typedef enum
+{
+    DAC_LFSR_MASK_BIT11_1  = 0x00000000, /*!< Mask bit[11:1] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_2  = 0x00000100, /*!< Mask bit[11:2] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_3  = 0x00000200, /*!< Mask bit[11:3] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_4  = 0x00000300, /*!< Mask bit[11:4] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_5  = 0x00000400, /*!< Mask bit[11:5] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_6  = 0x00000500, /*!< Mask bit[11:6] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_7  = 0x00000600, /*!< Mask bit[11:7] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_8  = 0x00000700, /*!< Mask bit[11:8] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_9  = 0x00000800, /*!< Mask bit[11:9] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11_10 = 0x00000900, /*!< Mask bit[11:10] of LFSR for noise wave generation */
+    DAC_LFSR_MASK_BIT11    = 0x00000A00, /*!< Mask bit11 of LFSR for noise wave generation */
+    DAC_LFSR_MASK_NONE     = 0x00000B00, /*!< Mask none bit of LFSR for noise wave generation */
+
+    DAC_TRIANGLE_AMPLITUDE_1    = 0x00000000, /*!< Triangle amplitude equal to 1 */
+    DAC_TRIANGLE_AMPLITUDE_3    = 0x00000100, /*!< Triangle amplitude equal to 3 */
+    DAC_TRIANGLE_AMPLITUDE_7    = 0x00000200, /*!< Triangle amplitude equal to 7 */
+    DAC_TRIANGLE_AMPLITUDE_15   = 0x00000300, /*!< Triangle amplitude equal to 15 */
+    DAC_TRIANGLE_AMPLITUDE_31   = 0x00000400, /*!< Triangle amplitude equal to 31 */
+    DAC_TRIANGLE_AMPLITUDE_63   = 0x00000500, /*!< Triangle amplitude equal to 63 */
+    DAC_TRIANGLE_AMPLITUDE_127  = 0x00000600, /*!< Triangle amplitude equal to 127 */
+    DAC_TRIANGLE_AMPLITUDE_255  = 0x00000700, /*!< Triangle amplitude equal to 255 */
+    DAC_TRIANGLE_AMPLITUDE_511  = 0x00000800, /*!< Triangle amplitude equal to 511 */
+    DAC_TRIANGLE_AMPLITUDE_1023 = 0x00000900, /*!< Triangle amplitude equal to 1023 */
+    DAC_TRIANGLE_AMPLITUDE_2047 = 0x00000A00, /*!< Triangle amplitude equal to 2047 */
+    DAC_TRIANGLE_AMPLITUDE_4095 = 0x00000B00  /*!< Triangle amplitude equal to 4095 */
+} DAC_MASK_AMPLITUDE_SEL_T;
+
+/**
+ * @brief DAC output buffer
+ */
+typedef enum
+{
+    DAC_OUTPUT_BUFFER_ENBALE  = 0x00000000, /*!< DAC Channel Output Buffer Enable */
+    DAC_OUTPUT_BUFFER_DISABLE = 0x00000002  /*!< DAC Channel1 Output Buffer Disable */
+} DAC_OUTPUT_BUFFER_T;
+
+/**
+ * @brief DAC data align
+ */
+typedef enum
+{
+    DAC_ALIGN_12BIT_R = 0x00000000, /*!< 12-bit right-aligned data */
+    DAC_ALIGN_12BIT_L = 0x00000004, /*!< 12-bit left-aligned data */
+    DAC_ALIGN_8BIT_R  = 0x00000008  /*!< 8-bit right-aligned data */
+} DAC_ALIGN_T;
+
+/**@} end of group DAC_Enumerations*/
+
+/** @addtogroup DAC_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief DAC Config structure definition
+ */
+typedef struct
+{
+    DAC_TRIGGER_T               trigger;                /*!< DAC trigger selection */
+    DAC_OUTPUT_BUFFER_T         outputBuffer;           /*!< DAC output buffer configuration */
+    DAC_WAVE_GENERATION_T       waveGeneration;         /*!< DAC wave generation configuration*/
+    DAC_MASK_AMPLITUDE_SEL_T    maskAmplitudeSelect;    /*!< DAC channelx mask/amplitude selector */
+} DAC_Config_T;
+
+/**@} end of group DAC_Structure*/
+
+/** @defgroup DAC_Functions
+  @{
+*/
+
+/* DAC Reset and Configuration */
+void DAC_Reset(void);
+void DAC_Config(uint32_t channel, DAC_Config_T* dacConfig);
+void DAC_ConfigStructInit(DAC_Config_T* dacConfig);
+void DAC_Enable(DAC_CHANNEL_T channel);
+void DAC_Disable(DAC_CHANNEL_T channel);
+
+/* DAC channel for DAM */
+void DAC_DMA_Enable(DAC_CHANNEL_T channel);
+void DAC_DMA_Disable(DAC_CHANNEL_T channel);
+
+/* DAC channel software trigger */
+void DAC_EnableSoftwareTrigger(DAC_CHANNEL_T channel);
+void DAC_DisableSoftwareTrigger(DAC_CHANNEL_T channel);
+void DAC_EnableDualSoftwareTrigger(void);
+void DAC_DisableDualSoftwareTrigger(void);
+
+/* DAC channel wave generation */
+void DAC_EnableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave);
+void DAC_DisableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave);
+
+/* DAC set channel data */
+void DAC_ConfigChannel1Data(DAC_ALIGN_T align, uint16_t data);
+void DAC_ConfigChannel2Data(DAC_ALIGN_T align, uint16_t data);
+void DAC_ConfigDualChannelData(DAC_ALIGN_T align, uint16_t data2, uint16_t data1);
+
+/* DAC read data output value */
+uint16_t DAC_ReadDataOutputValue(DAC_CHANNEL_T channel);
+
+/* DAC Interrupts and flag */
+void DAC_EnableInterrupt(DAC_CHANNEL_T channel);
+void DAC_DisableInterrupt(DAC_CHANNEL_T channel);
+uint8_t DAC_ReadStatusFlag(DAC_CHANNEL_T channel);
+void DAC_ClearStatusFlag(DAC_CHANNEL_T channel);
+uint8_t DAC_ReadIntFlag(DAC_CHANNEL_T channel);
+void DAC_ClearIntFlag(DAC_CHANNEL_T channel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_DAC_H */
+
+/**@} end of group DAC_Enumerations */
+/**@} end of group DAC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 106 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dbgmcu.h

@@ -0,0 +1,106 @@
+/*!
+ * @file        apm324xx_dbgmcu.h
+ *
+ * @brief       This file contains all the functions prototypes for the DBUGMCU firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_DBGMCU_H
+#define __APM32F4XX_DBGMCU_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup DBGMCU_Driver
+  @{
+*/
+
+/** @defgroup DBGMCU_Enumerations
+  @{
+*/
+
+/**
+ * @brief DBGMCU_STOP description
+ */
+typedef enum
+{
+    DBGMCU_SLEEP                 = ((uint32_t)0x00000001),  /*!< Keep debugger connection during SLEEP mode */
+    DBGMCU_STOP                  = ((uint32_t)0x00000002),  /*!< Keep debugger connection during STOP mode */
+    DBGMCU_STANDBY               = ((uint32_t)0x00000004),  /*!< Keep debugger connection during STANDBY mode */
+    /** APB1 Peripheral */
+    DBGMCU_TMR2_STOP             = ((uint32_t)0x00000001),  /*!< TMR2 counter stopped when Core is halted */
+    DBGMCU_TMR3_STOP             = ((uint32_t)0x00000002),  /*!< TMR3 counter stopped when Core is halted */
+    DBGMCU_TMR4_STOP             = ((uint32_t)0x00000004),  /*!< TMR4 counter stopped when Core is halted */
+    DBGMCU_TMR5_STOP             = ((uint32_t)0x00000008),  /*!< TMR5 counter stopped when Core is halted */
+    DBGMCU_TMR6_STOP             = ((uint32_t)0x00000010),  /*!< TMR6 counter stopped when Core is halted */
+    DBGMCU_TMR7_STOP             = ((uint32_t)0x00000020),  /*!< TMR7 counter stopped when Core is halted */
+    DBGMCU_TMR12_STOP            = ((uint32_t)0x00000040),  /*!< TMR12 counter stopped when Core is halted */
+    DBGMCU_TMR13_STOP            = ((uint32_t)0x00000080),  /*!< TMR13 counter stopped when Core is halted */
+    DBGMCU_TMR14_STOP            = ((uint32_t)0x00000100),  /*!< TMR14 counter stopped when Core is halted */
+    DBGMCU_RTC_STOP              = ((uint32_t)0x00000400),  /*!< RTC Calendar and Wakeup counter stopped when Core is halted */
+    DBGMCU_WWDT_STOP             = ((uint32_t)0x00000800),  /*!< Debug WWDG stopped when Core is halted */
+    DBGMCU_IWDT_STOP             = ((uint32_t)0x00001000),  /*!< Debug IWDG stopped when Core is halted */
+    DBGMCU_I2C1_SMBUS_TIMEOUT    = ((uint32_t)0x00200000),  /*!< I2C1 SMBUS timeout mode stopped when Core is halted */
+    DBGMCU_I2C2_SMBUS_TIMEOUT    = ((uint32_t)0x00400000),  /*!< I2C2 SMBUS timeout mode stopped when Core is halted */
+    DBGMCU_I2C3_SMBUS_TIMEOUT    = ((uint32_t)0x00800000),  /*!< I2C3 SMBUS timeout mode stopped when Core is halted */
+    DBGMCU_CAN1_STOP             = ((uint32_t)0x02000000),  /*!< Debug CAN1 stopped when Core is halted */
+    DBGMCU_CAN2_STOP             = ((uint32_t)0x04000000),  /*!< Debug CAN2 stopped when Core is halted */
+    /** APB2 Peripheral */
+    DBGMCU_TMR1_STOP             = ((uint32_t)0x00000001),  /*!< TMR1 counter stopped when Core is halted */
+    DBGMCU_TMR8_STOP             = ((uint32_t)0x00000002),  /*!< TMR8 counter stopped when Core is halted */
+    DBGMCU_TMR9_STOP             = ((uint32_t)0x00010000),  /*!< TMR9 counter stopped when Core is halted */
+    DBGMCU_TMR10_STOP            = ((uint32_t)0x00020000),  /*!< TMR10 counter stopped when Core is halted */
+    DBGMCU_TMR11_STOP            = ((uint32_t)0x00040000)   /*!< TMR11 counter stopped when Core is halted */
+} DBGMCU_STOP_T;
+
+/**@} end of group DBGMCU_Enumerations*/
+
+/** @defgroup DBGMCU_Functions
+  @{
+*/
+
+uint32_t DBGMCU_ReadDEVID(void);
+uint32_t DBGMCU_ReadREVID(void);
+void DBGMCU_Enable(uint32_t periph);
+void DBGMCU_Disable(uint32_t periph);
+void DBGMCU_DisableAPB1Periph(uint32_t periph);
+void DBGMCU_EnableAPB1Periph(uint32_t periph);
+void DBGMCU_DisableAPB2Periph(uint32_t periph);
+void DBGMCU_EnableAPB2Periph(uint32_t periph);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_DBGMCU_H */
+
+/**@} end of group DBGMCU_Enumerations */
+/**@} end of group DBGMCU_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 241 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dci.h

@@ -0,0 +1,241 @@
+/*!
+ * @file        apm32f4xx_dci.h
+ *
+ * @brief       This file contains all the functions prototypes for the DCI firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_DCI_H
+#define __APM32F4XX_DCI_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup DCI_Driver
+  @{
+*/
+
+/** @defgroup DCI_Enumerations
+  @{
+*/
+
+/**
+ * @brief DCI Capture Mode
+ */
+typedef enum
+{
+    DCI_CAPTURE_MODE_CONTINUOUS,    /*!< Continuous capture mode    */
+    DCI_CAPTURE_MODE_SNAPSHOT       /*!< Snapshot mode */
+} DCI_CAPTURE_MODE_T;
+
+/**
+ * @brief DCI Synchronization Mode
+ */
+typedef enum
+{
+    DCI_SYNCHRO_MODE_HARDWARE,  /*!< Hardware synchronization */
+    DCI_SYNCHRO_MODE_EMBEDDED   /*!< Embedded code synchronization */
+} DCI_SYNCHRO_MODEVAL_T;
+
+/**
+ * @brief DCI Pixel Clock Polarity
+ */
+typedef enum
+{
+    DCI_PCK_POL_FALLING,        /*!< Falling edge capture */
+    DCI_PCK_POL_RISING          /*!< Rising edge capture */
+} DCI_PCK_POL_T;
+
+/**
+ * @brief DCI VSYNC Polarity
+ */
+typedef enum
+{
+    DCI_VSYNC_POL_LOW,  /*!< VSYNC low-level valid */
+    DCI_VSYNC_POL_HIGH  /*!< VSYNC high-level valid */
+} DCI_VSYNC_POL_T;
+
+/**
+ * @brief DCI HSYNC Polarity
+ */
+typedef enum
+{
+    DCI_HSYNC_POL_LOW,  /*!< HSYNC low-level valid */
+    DCI_HSYNC_POL_HIGH  /*!< HSYNC high-level valid */
+} DCI_HSYNC_POL_T;
+
+/**
+ * @brief DCI Capture Rate
+ */
+typedef enum
+{
+    DCI_CAPTURE_RATE_ALL_FRAME,     /*!< Capture all frame */
+    DCI_CAPTURE_RATE_1OF2_FRAME,    /*!< Capture every other frame */
+    DCI_CAPTURE_RATE_1OF4_FRAME     /*!< Capture every three frame */
+} DCI_CAPTURE_RATE_T;
+
+/**
+ * @brief DCI Extended Data Mode
+ */
+typedef enum
+{
+    DCI_EXTENDED_DATA_MODE_8B,      /*!< Extended 8-bit data mode */
+    DCI_EXTENDED_DATA_MODE_10B,     /*!< Extended 10-bit data mode */
+    DCI_EXTENDED_DATA_MODE_12B,     /*!< Extended 12-bit data mode */
+    DCI_EXTENDED_DATA_MODE_14B      /*!< Extended 14-bit data mode */
+} DCI_EXTENDED_DATA_MODE_T;
+
+/**
+ * @brief DCI interrupt sources
+ */
+typedef enum
+{
+    DCI_INT_CC    =((uint16_t)0x0001),  /*!< Frame capture complete interrupt mask */
+    DCI_INT_OVR   =((uint16_t)0x0002),  /*!< Overflow interrupt mask */
+    DCI_INT_ERR   =((uint16_t)0x0004),  /*!< Synchronization error interrupt mask */
+    DCI_INT_VSYNC =((uint16_t)0x0008),  /*!< VSYNC interrupt mask */
+    DCI_INT_LINE  =((uint16_t)0x0010),  /*!< Line interrupt mask */
+} DCI_INT_T;
+
+/**
+ * @brief DCI flags
+ */
+typedef enum
+{
+    /* DCI RINTSTS register */
+    DCI_FLAG_CCI        =((uint16_t)0x0001),    /*!< Frame capture complete Raw flag mask */
+    DCI_FLAG_OVRI       =((uint16_t)0x0002),    /*!< Overflow Raw flag mask */
+    DCI_FLAG_ERRI       =((uint16_t)0x0004),    /*!< Synchronization error Raw flag mask */
+    DCI_FLAG_VSYNCI     =((uint16_t)0x0008),    /*!< VSYNC Raw flag mask */
+    DCI_FLAG_LINEI      =((uint16_t)0x0010),    /*!< Line Raw flag mask */
+    /* DCI MINTSTS register */
+    DCI_FLAG_CCMI       =((uint16_t)0x1001),    /*!< Frame capture complete Masked flag mask */
+    DCI_FLAG_OVRMI      =((uint16_t)0x1002),    /*!< Overflow Masked flag mask */
+    DCI_FLAG_ERRMI      =((uint16_t)0x1004),    /*!< Synchronization error Masked flag mask */
+    DCI_FLAG_VSYNCMI    =((uint16_t)0x1008),    /*!< VSYNC Masked flag mask */
+    DCI_FLAG_LINEMI     =((uint16_t)0x1010),    /*!< Line Masked flag mask */
+    /* DCI STS register */
+    DCI_FLAG_HSYNC      =((uint16_t)0x2001),    /*!< HSYNC flag mask */
+    DCI_FLAG_VSYNC      =((uint16_t)0x2002),    /*!< VSYNC flag mask */
+    DCI_FLAG_FNE        =((uint16_t)0x2004),    /*!< Fifo not empty flag mask */
+} DCI_FLAG_T;
+
+/**@} end of group DCI_Enumerations*/
+
+/** @addtogroup DCI_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief DCI Config structure definition
+ */
+typedef struct
+{
+    DCI_CAPTURE_MODE_T        captureMode;      /*!< Specifies the Capture Mode: Continuous or Snapshot */
+
+    DCI_SYNCHRO_MODEVAL_T     synchroMode;      /*!< Specifies the Synchronization Mode: Hardware or Embedded */
+
+    DCI_PCK_POL_T             pckPolarity;      /*!< Specifies the Pixel clock polarity: Falling or Rising */
+
+    DCI_VSYNC_POL_T           vsyncPolarity;    /*!< Specifies the Vertical synchronization polarity: High or Low */
+
+    DCI_HSYNC_POL_T           hsyncPolarity;    /*!< Specifies the Horizontal synchronization polarity: High or Low */
+
+    DCI_CAPTURE_RATE_T        capturerate;      /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4 */
+
+    DCI_EXTENDED_DATA_MODE_T  extendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit */
+} DCI_Config_T;
+
+/**
+ * @brief DCI CROP Init structure definition
+ */
+typedef struct
+{
+    uint16_t    verticalStartLine;      /*!< Vertical start line count from which the image capture(between 0x00 and 0x1FFF) */
+
+    uint16_t    horizontalOffsetCount;  /*!< number of pixel clocks to count before starting a capture(between 0x00 and 0x3FFF) */
+
+    uint16_t    verticalLineCount;      /*!< number of lines to be captured from the starting point(between 0x00 and 0x3FFF) */
+
+    uint16_t    captureCount;           /*!< number of pixel clocks to be captured from the starting(between 0x00 and 0x3FFF) */
+} DCI_CropConfig_T;
+
+/**
+  * @brief   DCI Embedded Synchronisation CODE Init structure definition
+  */
+typedef struct
+{
+    uint8_t     frameStartCode;      /*!< Specifies the code of the frame start delimiter */
+    uint8_t     lineStartCode;       /*!< Specifies the code of the line start delimiter */
+    uint8_t     lineEndCode;         /*!< Specifies the code of the line end delimiter */
+    uint8_t     frameEndCode;        /*!< Specifies the code of the frame end delimiter */
+} DCI_CodeConfig_T;
+
+/**@} end of group DCI_Structure*/
+
+/** @defgroup DCI_Functions
+  @{
+*/
+
+/** DCI Configuration */
+void DCI_Rest(void);
+void DCI_Config(DCI_Config_T* dciConfig);
+void DCI_ConfigStructInit(DCI_Config_T* dciConfig);
+void DCI_ConfigCROP(DCI_CropConfig_T* cropConfig);
+void DCI_EnableCROP(void);
+void DCI_DisableCROP(void);
+void DCI_ConfigSynchroCode(DCI_CodeConfig_T* codeConfig);
+void DCI_EnableJPEG(void);
+void DCI_DisableJPEG(void);
+
+/** DCI Image capture */
+void DCI_Enable(void);
+void DCI_Disable(void);
+void DCI_EnableCapture(void);
+void DCI_DisableCapture(void);
+uint32_t DCI_ReadData(void);
+
+/** Interrupts and flags */
+void DCI_EnableInterrupt(uint32_t interrupt);
+void DCI_DisableInterrupt(uint32_t interrupt);
+uint16_t DCI_ReadStatusFlag(DCI_FLAG_T flag);
+void DCI_ClearStatusFlag(uint16_t flag);
+uint16_t DCI_ReadIntFlag(DCI_INT_T flag);
+void DCI_ClearIntFlag(uint16_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_DCI_H */
+
+/**@} end of group DCI_Enumerations */
+/**@} end of group DCI_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 414 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dma.h

@@ -0,0 +1,414 @@
+/*!
+ * @file        apm32f4xx_dma.h
+ *
+ * @brief       This file contains all the functions prototypes for the DMA firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_DMA_H
+#define __APM32F4XX_DMA_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup DMA_Driver
+  @{
+*/
+
+/** @defgroup DMA_Enumerations
+  @{
+*/
+
+/**
+ * @brief DMA channel
+ */
+typedef enum
+{
+    DMA_CHANNEL_0,  /*!< Select DMA channel 0 */
+    DMA_CHANNEL_1,  /*!< Select DMA channel 1 */
+    DMA_CHANNEL_2,  /*!< Select DMA channel 2 */
+    DMA_CHANNEL_3,  /*!< Select DMA channel 3 */
+    DMA_CHANNEL_4,  /*!< Select DMA channel 4 */
+    DMA_CHANNEL_5,  /*!< Select DMA channel 5 */
+    DMA_CHANNEL_6,  /*!< Select DMA channel 6 */
+    DMA_CHANNEL_7   /*!< Select DMA channel 7 */
+} DMA_CHANNEL_T;
+
+/**
+ * @brief DMA Transmission direction
+ */
+typedef enum
+{
+    DMA_DIR_PERIPHERALTOMEMORY, /*!< Peripheral to memory */
+    DMA_DIR_MEMORYTOPERIPHERAL, /*!< Memory to peripheral */
+    DMA_DIR_MEMORYTOMEMORY      /*!< Memory to memory */
+} DMA_DIR_T;
+
+/**
+ * @brief DMA Peripheral address increment
+ */
+typedef enum
+{
+    DMA_PERIPHERAL_INC_DISABLE, /*!< Disable peripheral increment mode */
+    DMA_PERIPHERAL_INC_ENABLE   /*!< Enable peripheral increment mode */
+} DMA_PERIPHERAL_INC_T;
+
+/**
+ * @brief DMA Memory address increment
+ */
+typedef enum
+{
+    DMA_MEMORY_INC_DISABLE, /*!< Disable memory increment mode */
+    DMA_MEMORY_INC_ENABLE   /*!< Enable memory increment mode */
+} DMA_MEMORY_INC_T;
+
+/**
+ * @brief DMA Peripheral Data Size
+ */
+typedef enum
+{
+    DMA_PERIPHERAL_DATA_SIZE_BYTE,      /*!< Set peripheral data size to byte */
+    DMA_PERIPHERAL_DATA_SIZE_HALFWORD,  /*!< Set peripheral data size to half-word */
+    DMA_PERIPHERAL_DATA_SIZE_WORD       /*!< Set peripheral data size to word */
+} DMA_PERIPHERAL_DATA_SIZE_T;
+
+/**
+ * @brief DMA Memory Data Size
+ */
+typedef enum
+{
+    DMA_MEMORY_DATA_SIZE_BYTE,          /*!< Set memory data size to byte */
+    DMA_MEMORY_DATA_SIZE_HALFWORD,      /*!< Set memory data size to half-word */
+    DMA_MEMORY_DATA_SIZE_WORD           /*!< Set memory data size to word */
+} DMA_MEMORY_DATA_SIZE_T;
+
+/**
+ * @brief DMA Mode
+ */
+typedef enum
+{
+    DMA_MODE_NORMAL,    /*!< Disable circular mode */
+    DMA_MODE_CIRCULAR   /*!< Enable circular mode */
+} DMA_LOOP_MODE_T;
+
+/**
+ * @brief DMA priority level
+ */
+typedef enum
+{
+    DMA_PRIORITY_LOW,       /*!< Set priority level to low */
+    DMA_PRIORITY_MEDIUM,    /*!< Set priority level to medium */
+    DMA_PRIORITY_HIGH,      /*!< Set priority level to high */
+    DMA_PRIORITY_VERYHIGH   /*!< Set priority level to very high */
+} DMA_PRIORITY_T;
+
+/**
+ * @brief DMA fifo direct mode
+ */
+typedef enum
+{
+    DMA_FIFOMODE_DISABLE,   /*!< Enable fifo mode */
+    DMA_FIFOMODE_ENABLE     /*!< Disable fifo mode */
+} DMA_FIFOMODE_T;
+
+/**
+ * @brief DMA fifo threshold select
+ */
+typedef enum
+{
+    DMA_FIFOTHRESHOLD_QUARTER,      /*!< Select quarter FIFO threshold */
+    DMA_FIFOTHRESHOLD_HALFFULL,     /*!< Select half-full FIFO threshold */
+    DMA_FIFOTHRESHOLD_3QUARTERS,    /*!< Select three quarters FIFO threshold */
+    DMA_FIFOTHRESHOLD_FULL          /*!< Select full FIFO threshold */
+} DMA_FIFOTHRESHOLD_T;
+
+/**
+ * @brief DMA memory burst
+ */
+typedef enum
+{
+    DMA_MEMORYBURST_SINGLE, /*!< Single memory burst transfer */
+    DMA_MEMORYBURST_INC4,   /*!< INC4 memory burst transfer */
+    DMA_MEMORYBURST_INC8,   /*!< INC8 memory burst transfer */
+    DMA_MEMORYBURST_INC16   /*!< INC16 memory burst transfer */
+} DMA_MEMORYBURST_T;
+
+/**
+ * @brief DMA peripheral burst
+ */
+typedef enum
+{
+    DMA_PERIPHERALBURST_SINGLE, /*!< Single peripheral burst transfer */
+    DMA_PERIPHERALBURST_INC4,   /*!< INC4 peripheral burst transfer */
+    DMA_PERIPHERALBURST_INC8,   /*!< INC8 peripheral burst transfer */
+    DMA_PERIPHERALBURST_INC16   /*!< INC16 peripheral burst transfer */
+} DMA_PERIPHERALBURST_T;
+
+/**
+ * @brief DMA fifo status level
+ */
+typedef enum
+{
+    DMA_FIFOSTATUS_LESS1QUARTER,    /*!< When FIFO is less than 1 quarter-full and not empty */
+    DMA_FIFOSTATUS_1QUARTER,        /*!< If more than 1 quarter-full */
+    DMA_FIFOSTATUS_HalfFull,        /*!< If more than 1 half-full */
+    DMA_FIFOSTATUS_3QUARTERS,       /*!< If more than 3 quarters-full */
+    DMA_FIFOSTATUS_EMPTY,           /*!< When FIFO is empty */
+    DMA_FIFOSTATUS_FULL             /*!< When FIFO is full */
+} DMA_FIFOSTATUS_T;
+
+/**
+ * @brief DMA Flag
+ */
+typedef enum
+{
+    DMA_FLAG_FEIFLG0   =  0x10000001,   /*!< Channel0 FIFO error flag */
+    DMA_FLAG_DMEIFLG0  =  0x10000004,   /*!< Channel0 direct mode error flag */
+    DMA_FLAG_TEIFLG0   =  0x10000008,   /*!< Channel0 transfer error flag */
+    DMA_FLAG_HTIFLG0   =  0x10000010,   /*!< Channel0 half transfer complete flag */
+    DMA_FLAG_TCIFLG0   =  0x10000020,   /*!< Channel0 transfer complete flag */
+
+    DMA_FLAG_FEIFLG1   =  0x10000040,   /*!< Channel1 FIFO error flag */
+    DMA_FLAG_DMEIFLG1  =  0x10000100,   /*!< Channel1 direct mode error flag */
+    DMA_FLAG_TEIFLG1   =  0x10000200,   /*!< Channel1 transfer error flag */
+    DMA_FLAG_HTIFLG1   =  0x10000400,   /*!< Channel1 half transfer complete flag */
+    DMA_FLAG_TCIFLG1   =  0x10000800,   /*!< Channel1 transfer complete flag */
+
+    DMA_FLAG_FEIFLG2   =  0x10010000,   /*!< Channel2 FIFO error flag */
+    DMA_FLAG_DMEIFLG2  =  0x10040000,   /*!< Channel2 direct mode error flag */
+    DMA_FLAG_TEIFLG2   =  0x10080000,   /*!< Channel2 transfer error flag */
+    DMA_FLAG_HTIFLG2   =  0x10100000,   /*!< Channel2 half transfer complete flag */
+    DMA_FLAG_TCIFLG2   =  0x10200000,   /*!< Channel2 transfer complete flag */
+
+    DMA_FLAG_FEIFLG3   =  0x10400000,   /*!< Channel3 FIFO error flag */
+    DMA_FLAG_DMEIFLG3  =  0x11000000,   /*!< Channel3 direct mode error flag */
+    DMA_FLAG_TEIFLG3   =  0x12000000,   /*!< Channel3 transfer error flag */
+    DMA_FLAG_HTIFLG3   =  0x14000000,   /*!< Channel3 half transfer complete flag */
+    DMA_FLAG_TCIFLG3   =  0x18000000,   /*!< Channel3 transfer complete flag */
+
+    DMA_FLAG_FEIFLG4   =  0x20000001,   /*!< Channel4 FIFO error flag */
+    DMA_FLAG_DMEIFLG4  =  0x20000004,   /*!< Channel4 direct mode error flag */
+    DMA_FLAG_TEIFLG4   =  0x20000008,   /*!< Channel4 transfer error flag */
+    DMA_FLAG_HTIFLG4   =  0x20000010,   /*!< Channel4 half transfer complete flag */
+    DMA_FLAG_TCIFLG4   =  0x20000020,   /*!< Channel4 transfer complete flag */
+
+    DMA_FLAG_FEIFLG5   =  0x20000040,   /*!< Channel5 FIFO error flag */
+    DMA_FLAG_DMEIFLG5  =  0x20000100,   /*!< Channel5 direct mode error flag */
+    DMA_FLAG_TEIFLG5   =  0x20000200,   /*!< Channel5 transfer error flag */
+    DMA_FLAG_HTIFLG5   =  0x20000400,   /*!< Channel5 half transfer complete flag */
+    DMA_FLAG_TCIFLG5   =  0x20000800,   /*!< Channel5 transfer complete flag */
+
+    DMA_FLAG_FEIFLG6   =  0x20010000,   /*!< Channel6 FIFO error flag */
+    DMA_FLAG_DMEIFLG6  =  0x20040000,   /*!< Channel6 direct mode error flag */
+    DMA_FLAG_TEIFLG6   =  0x20080000,   /*!< Channel6 transfer error flag */
+    DMA_FLAG_HTIFLG6   =  0x20100000,   /*!< Channel6 half transfer complete flag */
+    DMA_FLAG_TCIFLG6   =  0x20200000,   /*!< Channel6 transfer complete flag */
+
+    DMA_FLAG_FEIFLG7   =  0x20400000,   /*!< Channel7 FIFO error flag */
+    DMA_FLAG_DMEIFLG7  =  0x21000000,   /*!< Channel7 direct mode error flag */
+    DMA_FLAG_TEIFLG7   =  0x22000000,   /*!< Channel7 transfer error flag */
+    DMA_FLAG_HTIFLG7   =  0x24000000,   /*!< Channel7 half transfer complete flag */
+    DMA_FLAG_TCIFLG7   =  0x28000000    /*!< Channel7 transfer complete flag */
+} DMA_FLAG_T;
+
+/**
+ * @brief DMA Interrupt Flag
+ */
+typedef enum
+{
+    DMA_INT_FEIFLG  = 0x01, /*!< FIFO error interrupt mask */
+    DMA_INT_DMEIFLG = 0x02, /*!< Direct mode error interrupt mask */
+    DMA_INT_TEIFLG  = 0x04, /*!< Transfer error interrupt mask */
+    DMA_INT_HTIFLG  = 0x08, /*!< Half transfer complete interrupt mask */
+    DMA_INT_TCIFLG  = 0x10  /*!< Transfer complete interrupt mask */
+} DMA_INT_T;
+
+/**
+ * @brief DMA Interrupts Flag
+ */
+typedef enum
+{
+    DMA_INT_FEIFLG0   =  0x20000001,    /*!< Stream0 FIFO error flag */
+    DMA_INT_DMEIFLG0  =  0x00001004,    /*!< Stream0 direct mode error flag */
+    DMA_INT_TEIFLG0   =  0x00002008,    /*!< Stream0 transfer error flag */
+    DMA_INT_HTIFLG0   =  0x00004010,    /*!< Stream0 half transfer complete flag */
+    DMA_INT_TCIFLG0   =  0x00008020,    /*!< Stream0 transfer complete flag */
+
+    DMA_INT_FEIFLG1   =  0x20000040,    /*!< Stream1 FIFO error flag */
+    DMA_INT_DMEIFLG1  =  0x00001100,    /*!< Stream1 direct mode error flag */
+    DMA_INT_TEIFLG1   =  0x00002200,    /*!< Stream1 transfer error flag */
+    DMA_INT_HTIFLG1   =  0x00004400,    /*!< Stream1 half transfer complete flag */
+    DMA_INT_TCIFLG1   =  0x00008800,    /*!< Stream1 transfer complete flag */
+
+    DMA_INT_FEIFLG2   =  0x20010000,    /*!< Stream2 FIFO error flag */
+    DMA_INT_DMEIFLG2  =  0x00041000,    /*!< Stream2 direct mode error flag */
+    DMA_INT_TEIFLG2   =  0x00082000,    /*!< Stream2 transfer error flag */
+    DMA_INT_HTIFLG2   =  0x00104000,    /*!< Stream2 half transfer complete flag */
+    DMA_INT_TCIFLG2   =  0x00208000,    /*!< Stream2 transfer complete flag */
+
+    DMA_INT_FEIFLG3   =  0x20400000,    /*!< Stream3 FIFO error flag */
+    DMA_INT_DMEIFLG3  =  0x01001000,    /*!< Stream3 direct mode error flag */
+    DMA_INT_TEIFLG3   =  0x02002000,    /*!< Stream3 transfer error flag */
+    DMA_INT_HTIFLG3   =  0x04004000,    /*!< Stream3 half transfer complete flag */
+    DMA_INT_TCIFLG3   =  0x08008000,    /*!< Stream3 transfer complete flag */
+
+    DMA_INT_FEIFLG4   =  0x50000001,    /*!< Stream4 FIFO error flag */
+    DMA_INT_DMEIFLG4  =  0x10001004,    /*!< Stream4 direct mode error flag */
+    DMA_INT_TEIFLG4   =  0x10002008,    /*!< Stream4 transfer error flag */
+    DMA_INT_HTIFLG4   =  0x10004010,    /*!< Stream4 half transfer complete flag */
+    DMA_INT_TCIFLG4   =  0x10008020,    /*!< Stream4 transfer complete flag */
+
+    DMA_INT_FEIFLG5   =  0x50000040,    /*!< Stream5 FIFO error flag */
+    DMA_INT_DMEIFLG5  =  0x10001100,    /*!< Stream5 direct mode error flag */
+    DMA_INT_TEIFLG5   =  0x10002200,    /*!< Stream5 transfer error flag */
+    DMA_INT_HTIFLG5   =  0x10004400,    /*!< Stream5 half transfer complete flag */
+    DMA_INT_TCIFLG5   =  0x10008800,    /*!< Stream5 transfer complete flag */
+
+    DMA_INT_FEIFLG6   =  0x50010000,    /*!< Stream6 FIFO error flag */
+    DMA_INT_DMEIFLG6  =  0x10041000,    /*!< Stream6 direct mode error flag */
+    DMA_INT_TEIFLG6   =  0x10082000,    /*!< Stream6 transfer error flag */
+    DMA_INT_HTIFLG6   =  0x10104000,    /*!< Stream6 half transfer complete flag */
+    DMA_INT_TCIFLG6   =  0x10208000,    /*!< Stream6 transfer complete flag */
+
+    DMA_INT_FEIFLG7   =  0x50400000,    /*!< Stream7 FIFO error flag */
+    DMA_INT_DMEIFLG7  =  0x11001000,    /*!< Stream7 direct mode error flag */
+    DMA_INT_TEIFLG7   =  0x12002000,    /*!< Stream7 transfer error flag */
+    DMA_INT_HTIFLG7   =  0x14004000,    /*!< Stream7 half transfer complete flag */
+    DMA_INT_TCIFLG7   =  0x18008000     /*!< Stream7 transfer complete flag */
+} DMA_INT_FLAG_T;
+
+/**
+ * @brief DMA peripheral increment offset
+ */
+typedef enum
+{
+    DMA_PERIOSIZE_PSIZE,        /*!< Peripheral address increment is done
+                                    accordingly to PSIZE parameter */
+    DMA_PERIOSIZE_WORDALIGNED   /*!< Peripheral address increment offset is
+                                    fixed to 4 (32-bit aligned addresses). */
+} DMA_PERIOSIZE_T;
+
+/**
+ * @brief DMA flow controller
+ */
+typedef enum
+{
+    DMA_FLOWCTRL_MEMORY,        /*!< DMAy_Channelx transactions flow controller is
+                                    the DMA controller */
+    DMA_FLOWCTRL_PERIPHERAL     /*!< DMAy_Channelx transactions flow controller
+                                    is the peripheral */
+} DMA_FLOWCTRL_T;
+
+/**
+ * @brief DMA memory targets
+ */
+typedef enum
+{
+    DMA_MEMORY_0,   /*!< Memory 0 Address */
+    DMA_MEMORY_1    /*!< Memory 1 Address */
+} DMA_MEMORY_T;
+
+/**@} end of group DMA_Enumerations*/
+
+/** @addtogroup DMA_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief DMA Config struct definition
+ */
+typedef struct
+{
+    DMA_CHANNEL_T              channel;             /*!< Channel selection */
+    uint32_t                   peripheralBaseAddr;  /*!< Peripheral base address */
+    uint32_t                   memoryBaseAddr;      /*!< Memory base address */
+    DMA_DIR_T                  dir;                 /*!< Direction */
+    uint32_t                   bufferSize;          /*!< Buffer size */
+    DMA_PERIPHERAL_INC_T       peripheralInc;       /*!< Peripheral increment mode selection */
+    DMA_MEMORY_INC_T           memoryInc;           /*!< Memory increment mode selection */
+    DMA_PERIPHERAL_DATA_SIZE_T peripheralDataSize;  /*!< Peripheral data size */
+    DMA_MEMORY_DATA_SIZE_T     memoryDataSize;      /*!< Memory data size */
+    DMA_LOOP_MODE_T            loopMode;            /*!< Loop mode */
+    DMA_PRIORITY_T             priority;            /*!< DMA priority level */
+    DMA_FIFOMODE_T             fifoMode;            /*!< FIFO mode selection */
+    DMA_FIFOTHRESHOLD_T        fifoThreshold;       /*!< FIFO threshold configuration */
+    DMA_MEMORYBURST_T          memoryBurst;         /*!< Memory burst configuration */
+    DMA_PERIPHERALBURST_T      peripheralBurst;     /*!< Peripheral burst configuration */
+} DMA_Config_T;
+
+/**@} end of group DMA_Structure*/
+
+/** @defgroup DMA_Functions
+  @{
+*/
+
+/* DMA Reset and Configuration */
+void DMA_Reset(DMA_Stream_T* stream);
+void DMA_Config(DMA_Stream_T* stream, DMA_Config_T* dmaConfig);
+void DMA_ConfigStructInit( DMA_Config_T* dmaConfig);
+void DMA_Enable(DMA_Stream_T* stream);
+void DMA_Disable(DMA_Stream_T* stream);
+
+/* Stream Configuration  */
+void DMA_ConfigPeriphIncOffsetSize(DMA_Stream_T* stream, DMA_PERIOSIZE_T perioSize);
+void DMA_ConfigFlowController(DMA_Stream_T* stream, DMA_FLOWCTRL_T flowController);
+
+/* DMA Data Number */
+void DMA_ConfigDataNumber(DMA_Stream_T* stream, uint16_t dataNumber);
+uint16_t DMA_ReadDataNumber(DMA_Stream_T* stream);
+
+/* DMA Double Buffer mode */
+void DMA_ConfigBufferMode(DMA_Stream_T* stream, uint32_t memory1BaseAddr, DMA_MEMORY_T currentMemory);
+void DMA_EnableDoubleBufferMode(DMA_Stream_T* stream);
+void DMA_DisableDoubleBufferMode(DMA_Stream_T* stream);
+void DMA_ConfigMemoryTarget(DMA_Stream_T* stream, uint32_t memoryBaseAddr, DMA_MEMORY_T memoryTarget);
+uint32_t DMA_ReadCurrentMemoryTarget(DMA_Stream_T* stream);
+
+/* DMA Interrupts and flags */
+uint8_t DMA_ReadCmdStatus(DMA_Stream_T* stream);
+uint32_t DMA_ReadFIFOFlag(DMA_Stream_T* stream);
+
+uint8_t DMA_ReadStatusFlag(DMA_Stream_T* stream, DMA_FLAG_T flag);
+void DMA_ClearStatusFlag(DMA_Stream_T* stream, uint32_t flag);
+
+void DMA_EnableInterrupt(DMA_Stream_T* stream, uint32_t interrupt);
+void DMA_DisableInterrupt(DMA_Stream_T* stream, uint32_t interrupt);
+uint8_t DMA_ReadIntFlag(DMA_Stream_T* stream, DMA_INT_FLAG_T flag);
+void DMA_ClearIntFlag(DMA_Stream_T* stream, uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__APM32F4XX_DMA_H */
+
+/**@} end of group DMA_Enumerations */
+/**@} end of group DMA_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 359 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dmc.h

@@ -0,0 +1,359 @@
+/*!
+ * @file        apm32f4xx_dmc.h
+ *
+ * @brief       This file contains all the prototypes,enumeration and macros for the DMC peripheral
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_DMC_H
+#define __APM32F4XX_DMC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup DMC_Driver
+  @{
+*/
+
+/** @defgroup DMC_Enumerations
+  @{
+*/
+
+/**
+ * @brief Bank Address Width
+ */
+typedef enum
+{
+    DMC_BANK_WIDTH_1,   /*!< Set bank address width to 1-bit */
+    DMC_BANK_WIDTH_2    /*!< Set bank address width to 2-bit */
+} DMC_BANK_WIDTH_T;
+
+/**
+ * @brief Row Address Width
+ */
+typedef enum
+{
+    DMC_ROW_WIDTH_11 = 0x0A,    /*!< Set row address width to 11-bit */
+    DMC_ROW_WIDTH_12,           /*!< Set row address width to 12-bit */
+    DMC_ROW_WIDTH_13,           /*!< Set row address width to 13-bit */
+    DMC_ROW_WIDTH_14,           /*!< Set row address width to 14-bit */
+    DMC_ROW_WIDTH_15,           /*!< Set row address width to 15-bit */
+    DMC_ROW_WIDTH_16            /*!< Set row address width to 16-bit */
+} DMC_ROW_WIDTH_T;
+
+/**
+ * @brief Column Address Width
+ */
+typedef enum
+{
+    DMC_COL_WIDTH_8 = 0x07, /*!< Set column address width to 8-bit */
+    DMC_COL_WIDTH_9,        /*!< Set column address width to 9-bit */
+    DMC_COL_WIDTH_10,       /*!< Set column address width to 10-bit */
+    DMC_COL_WIDTH_11,       /*!< Set column address width to 11-bit */
+    DMC_COL_WIDTH_12,       /*!< Set column address width to 12-bit */
+    DMC_COL_WIDTH_13,       /*!< Set column address width to 13-bit */
+    DMC_COL_WIDTH_14,       /*!< Set column address width to 14-bit */
+    DMC_COL_WIDTH_15        /*!< Set column address width to 15-bit */
+} DMC_COL_WIDTH_T;
+
+/**
+ * @brief CAS Latency Select
+ */
+typedef enum
+{
+    DMC_CAS_LATENCY_1,  /*!< Set CAS lantency to 1 clock */
+    DMC_CAS_LATENCY_2,  /*!< Set CAS lantency to 2 clock */
+    DMC_CAS_LATENCY_3,  /*!< Set CAS lantency to 3 clock */
+    DMC_CAS_LATENCY_4   /*!< Set CAS lantency to 4 clock */
+} DMC_CAS_LATENCY_T;
+
+/**
+ * @brief RAS Minimun Time Select
+ */
+typedef enum
+{
+    DMC_RAS_MINIMUM_1,  /*!< Set RAS minimun time to 1 clock */
+    DMC_RAS_MINIMUM_2,  /*!< Set RAS minimun time to 2 clock */
+    DMC_RAS_MINIMUM_3,  /*!< Set RAS minimun time to 3 clock */
+    DMC_RAS_MINIMUM_4,  /*!< Set RAS minimun time to 4 clock */
+    DMC_RAS_MINIMUM_5,  /*!< Set RAS minimun time to 5 clock */
+    DMC_RAS_MINIMUM_6,  /*!< Set RAS minimun time to 6 clock */
+    DMC_RAS_MINIMUM_7,  /*!< Set RAS minimun time to 7 clock */
+    DMC_RAS_MINIMUM_8,  /*!< Set RAS minimun time to 8 clock */
+    DMC_RAS_MINIMUM_9,  /*!< Set RAS minimun time to 9 clock */
+    DMC_RAS_MINIMUM_10, /*!< Set RAS minimun time to 10 clock */
+    DMC_RAS_MINIMUM_11, /*!< Set RAS minimun time to 11 clock */
+    DMC_RAS_MINIMUM_12, /*!< Set RAS minimun time to 12 clock */
+    DMC_RAS_MINIMUM_13, /*!< Set RAS minimun time to 13 clock */
+    DMC_RAS_MINIMUM_14, /*!< Set RAS minimun time to 14 clock */
+    DMC_RAS_MINIMUM_15, /*!< Set RAS minimun time to 15 clock */
+    DMC_RAS_MINIMUM_16  /*!< Set RAS minimun time to 16 clock */
+} DMC_RAS_MINIMUM_T;
+
+/**
+ * @brief RAS To CAS Delay Time Select
+ */
+typedef enum
+{
+    DMC_DELAY_TIME_1,   /*!< Set RAS to CAS delay time to 1 clock */
+    DMC_DELAY_TIME_2,   /*!< Set RAS to CAS delay time to 2 clock */
+    DMC_DELAY_TIME_3,   /*!< Set RAS to CAS delay time to 3 clock */
+    DMC_DELAY_TIME_4,   /*!< Set RAS to CAS delay time to 4 clock */
+    DMC_DELAY_TIME_5,   /*!< Set RAS to CAS delay time to 5 clock */
+    DMC_DELAY_TIME_6,   /*!< Set RAS to CAS delay time to 6 clock */
+    DMC_DELAY_TIME_7,   /*!< Set RAS to CAS delay time to 7 clock */
+    DMC_DELAY_TIME_8    /*!< Set RAS to CAS delay time to 8 clock */
+} DMC_DELAY_TIME_T;
+
+/**
+ * @brief Precharge Period Select
+ */
+typedef enum
+{
+    DMC_PRECHARGE_1,    /*!< Set precharge period to 1 clock */
+    DMC_PRECHARGE_2,    /*!< Set precharge period to 2 clock */
+    DMC_PRECHARGE_3,    /*!< Set precharge period to 3 clock */
+    DMC_PRECHARGE_4,    /*!< Set precharge period to 4 clock */
+    DMC_PRECHARGE_5,    /*!< Set precharge period to 5 clock */
+    DMC_PRECHARGE_6,    /*!< Set precharge period to 6 clock */
+    DMC_PRECHARGE_7,    /*!< Set precharge period to 7 clock */
+    DMC_PRECHARGE_8     /*!< Set precharge period to 8 clock */
+} DMC_PRECHARGE_T;
+
+/**
+ * @brief Last Data Next Precharge For Write Time Select
+ */
+typedef enum
+{
+    DMC_NEXT_PRECHARGE_1,   /*!< Set time between the last data and
+                                next precharge for write to 1 clock */
+    DMC_NEXT_PRECHARGE_2,   /*!< Set time between the last data and
+                                next precharge for write to 2 clock */
+    DMC_NEXT_PRECHARGE_3,   /*!< Set time between the last data and
+                                next precharge for write to 3 clock */
+    DMC_NEXT_PRECHARGE_4    /*!< Set time between the last data and
+                                next precharge for write to 4 clock */
+} DMC_NEXT_PRECHARGE_T;
+
+/**
+ * @brief Auto-Refresh Period Select
+ */
+typedef enum
+{
+    DMC_AUTO_REFRESH_1,     /*!< Set auto-refresh period to 1 clock */
+    DMC_AUTO_REFRESH_2,     /*!< Set auto-refresh period to 2 clock */
+    DMC_AUTO_REFRESH_3,     /*!< Set auto-refresh period to 3 clock */
+    DMC_AUTO_REFRESH_4,     /*!< Set auto-refresh period to 4 clock */
+    DMC_AUTO_REFRESH_5,     /*!< Set auto-refresh period to 5 clock */
+    DMC_AUTO_REFRESH_6,     /*!< Set auto-refresh period to 6 clock */
+    DMC_AUTO_REFRESH_7,     /*!< Set auto-refresh period to 7 clock */
+    DMC_AUTO_REFRESH_8,     /*!< Set auto-refresh period to 8 clock */
+    DMC_AUTO_REFRESH_9,     /*!< Set auto-refresh period to 9 clock */
+    DMC_AUTO_REFRESH_10,    /*!< Set auto-refresh period to 10 clock */
+    DMC_AUTO_REFRESH_11,    /*!< Set auto-refresh period to 11 clock */
+    DMC_AUTO_REFRESH_12,    /*!< Set auto-refresh period to 12 clock */
+    DMC_AUTO_REFRESH_13,    /*!< Set auto-refresh period to 13 clock */
+    DMC_AUTO_REFRESH_14,    /*!< Set auto-refresh period to 14 clock */
+    DMC_AUTO_REFRESH_15,    /*!< Set auto-refresh period to 15 clock */
+    DMC_AUTO_REFRESH_16,    /*!< Set auto-refresh period to 16 clock */
+} DMC_AUTO_REFRESH_T;
+
+/**
+ * @brief Active-to-active Command Period Select
+ */
+typedef enum
+{
+    DMC_ATA_CMD_1,  /*!< Set active to active command period to 1 clock */
+    DMC_ATA_CMD_2,  /*!< Set active to active command period to 2 clock */
+    DMC_ATA_CMD_3,  /*!< Set active to active command period to 3 clock */
+    DMC_ATA_CMD_4,  /*!< Set active to active command period to 4 clock */
+    DMC_ATA_CMD_5,  /*!< Set active to active command period to 5 clock */
+    DMC_ATA_CMD_6,  /*!< Set active to active command period to 6 clock */
+    DMC_ATA_CMD_7,  /*!< Set active to active command period to 7 clock */
+    DMC_ATA_CMD_8,  /*!< Set active to active command period to 8 clock */
+    DMC_ATA_CMD_9,  /*!< Set active to active command period to 9 clock */
+    DMC_ATA_CMD_10, /*!< Set active to active command period to 10 clock */
+    DMC_ATA_CMD_11, /*!< Set active to active command period to 11 clock */
+    DMC_ATA_CMD_12, /*!< Set active to active command period to 12 clock */
+    DMC_ATA_CMD_13, /*!< Set active to active command period to 13 clock */
+    DMC_ATA_CMD_14, /*!< Set active to active command period to 14 clock */
+    DMC_ATA_CMD_15, /*!< Set active to active command period to 15 clock */
+    DMC_ATA_CMD_16, /*!< Set active to active command period to 16 clock */
+} DMC_ATA_CMD_T;
+
+/**
+ * @brief Clock PHASE
+ */
+typedef enum
+{
+    DMC_CLK_PHASE_NORMAL,   /*!< Clock phase is normal */
+    DMC_CLK_PHASE_REVERSE   /*!< Clock phase is reverse */
+} DMC_CLK_PHASE_T;
+
+/**
+ * @brief    Open Banks Of Number
+ */
+typedef enum
+{
+    DMC_BANK_NUMBER_1,  /*!< Set 1 bank be opened */
+    DMC_BANK_NUMBER_2,  /*!< Set 2 banks be opened */
+    DMC_BANK_NUMBER_3,  /*!< Set 3 banks be opened */
+    DMC_BANK_NUMBER_4,  /*!< Set 4 banks be opened */
+    DMC_BANK_NUMBER_5,  /*!< Set 5 banks be opened */
+    DMC_BANK_NUMBER_6,  /*!< Set 6 banks be opened */
+    DMC_BANK_NUMBER_7,  /*!< Set 7 banks be opened */
+    DMC_BANK_NUMBER_8,  /*!< Set 8 banks be opened */
+    DMC_BANK_NUMBER_9,  /*!< Set 9 banks be opened */
+    DMC_BANK_NUMBER_10, /*!< Set 10 banks be opened */
+    DMC_BANK_NUMBER_11, /*!< Set 11 banks be opened */
+    DMC_BANK_NUMBER_12, /*!< Set 12 banks be opened */
+    DMC_BANK_NUMBER_13, /*!< Set 13 banks be opened */
+    DMC_BANK_NUMBER_14, /*!< Set 14 banks be opened */
+    DMC_BANK_NUMBER_15, /*!< Set 15 banks be opened */
+    DMC_BANK_NUMBER_16, /*!< Set 16 banks be opened */
+} DMC_BANK_NUMBER_T;
+
+/**
+ * @brief Full refresh type
+ */
+typedef enum
+{
+    DMC_REFRESH_ROW_ONE,        /*!< Refresh one row */
+    DMC_REFRESH_ROW_ALL,        /*!< Refresh all row */
+} DMC_REFRESH_T;
+
+/**
+ * @brief Precharge type
+ */
+typedef enum
+{
+    DMC_PRECHARGE_IM,        /*!< Immediate precharge */
+    DMC_PRECHARGE_DELAY,     /*!< Delayed precharge */
+} DMC_PRECHARE_T;
+
+/**
+ * @brief WRAP Burst Type
+ */
+typedef enum
+{
+    DMC_WRAPB_4,    /*!< Wrap4 burst transfer */
+    DMC_WRAPB_8,    /*!< Wrap8 burst transfer */
+} DMC_WRPB_T;
+
+/**@} end of group DMC_Enumerations*/
+
+/** @addtogroup DMC_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief Timing config definition
+ */
+typedef struct
+{
+    uint32_t    latencyCAS  : 2;       /*!< DMC_CAS_LATENCY_T */
+    uint32_t    tRAS        : 4;       /*!< DMC_RAS_MINIMUM_T */
+    uint32_t    tRCD        : 3;       /*!< DMC_DELAY_TIME_T */
+    uint32_t    tRP         : 3;       /*!< DMC_PRECHARGE_T */
+    uint32_t    tWR         : 2;       /*!< DMC_NEXT_PRECHARGE_T */
+    uint32_t    tARP        : 4;       /*!< DMC_AUTO_REFRESH_T */
+    uint32_t    tCMD        : 4;       /*!< DMC_ATA_CMD_T */
+    uint32_t    tXSR        : 9;       /*!< auto-refresh commands, can be 0x000 to 0x1FF */
+    uint16_t    tRFP        : 16;      /*!< Refresh period, can be 0x0000 to 0xFFFF */
+} DMC_TimingConfig_T;
+
+/**
+ * @brief Config struct definition
+ */
+typedef struct
+{
+    DMC_BANK_WIDTH_T        bankWidth;     /*!< Number of bank bits */
+    DMC_ROW_WIDTH_T         rowWidth;      /*!< Number of row address bits */
+    DMC_COL_WIDTH_T         colWidth;      /*!< Number of col address bits */
+    DMC_CLK_PHASE_T         clkPhase;      /*!< Clock phase */
+    DMC_TimingConfig_T      timing;        /*!< Timing */
+} DMC_Config_T;
+
+/**@} end of group DMC_Structure*/
+
+/** @defgroup DMC_Functions
+  @{
+*/
+
+/* Enable / Disable */
+void DMC_Enable(void);
+void DMC_Disable(void);
+void DMC_EnableInit(void);
+
+/* Global config */
+void DMC_Config(DMC_Config_T* dmcConfig);
+void DMC_ConfigStructInit(DMC_Config_T* dmcConfig);
+
+/* Address */
+void DMC_ConfigBankWidth(DMC_BANK_WIDTH_T bankWidth);
+void DMC_ConfigAddrWidth(DMC_ROW_WIDTH_T rowWidth, DMC_COL_WIDTH_T colWidth);
+
+/* Timing */
+void DMC_ConfigTiming(DMC_TimingConfig_T* timingConfig);
+void DMC_ConfigTimingStructInit(DMC_TimingConfig_T* timingConfig);
+void DMC_ConfigStableTimePowerup(uint16_t stableTime);
+void DMC_ConfigAutoRefreshNumDuringInit(DMC_AUTO_REFRESH_T num);
+void DMC_ConfigRefreshPeriod(uint16_t period);
+
+/* Refresh mode */
+void DMC_EixtSlefRefreshMode(void);
+void DMC_EnterSlefRefreshMode(void);
+
+/* Accelerate Module */
+void DMC_EnableAccelerateModule(void);
+void DMC_DisableAccelerateModule(void);
+
+/* Config */
+void DMC_ConfigOpenBank(DMC_BANK_NUMBER_T num);
+void DMC_EnableUpdateMode(void);
+void DMC_EnterPowerdownMode(void);
+void DMC_ConfigFullRefreshBeforeSR(DMC_REFRESH_T refresh);
+void DMC_ConfigFullRefreshAfterSR(DMC_REFRESH_T refresh);
+void DMC_ConfigPrechargeType(DMC_PRECHARE_T precharge);
+void DMC_ConfigClockPhase(DMC_CLK_PHASE_T clkPhase);
+void DMC_ConfigWRAPB(DMC_WRPB_T burst);
+
+/* read flag */
+uint8_t DMC_ReadSelfRefreshStatus(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __APM32F4XX_DMC_H */
+
+/**@} end of group DMC_Enumerations */
+/**@} end of group DMC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 139 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_eint.h

@@ -0,0 +1,139 @@
+/*!
+ * @file        apm32f4xx_eint.h
+ *
+ * @brief       This file contains all the functions prototypes for the EINT firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_EINT_H
+#define __APM32F4XX_EINT_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup EINT_Driver
+  @{
+*/
+
+/** @defgroup EINT_Enumerations
+  @{
+*/
+
+/**
+ * @brief EINT mode enumeration
+ */
+typedef enum
+{
+    EINT_MODE_INTERRUPT = 0x00, /*!< Interrupt request mode */
+    EINT_MODE_EVENT     = 0x04  /*!< Event request mode */
+} EINT_MODE_T;
+
+/**
+ * @brief EINT Trigger enumeration
+ */
+typedef enum
+{
+    EINT_TRIGGER_RISING         = 0x08, /*!< Rising trigger */
+    EINT_TRIGGER_FALLING        = 0x0C, /*!< Falling trigger */
+    EINT_TRIGGER_RISING_FALLING = 0x10  /*!< Rising and falling trigger */
+} EINT_TRIGGER_T;
+
+typedef enum
+{
+    EINT_LINENONE = 0x00000,      /*!< No interrupt selected */
+    EINT_LINE_0   = 0x00001,      /*!< External interrupt line 0 */
+    EINT_LINE_1   = 0x00002,      /*!< External interrupt line 1 */
+    EINT_LINE_2   = 0x00004,      /*!< External interrupt line 2 */
+    EINT_LINE_3   = 0x00008,      /*!< External interrupt line 3 */
+    EINT_LINE_4   = 0x00010,      /*!< External interrupt line 4 */
+    EINT_LINE_5   = 0x00020,      /*!< External interrupt line 5 */
+    EINT_LINE_6   = 0x00040,      /*!< External interrupt line 6 */
+    EINT_LINE_7   = 0x00080,      /*!< External interrupt line 7 */
+    EINT_LINE_8   = 0x00100,      /*!< External interrupt line 8 */
+    EINT_LINE_9   = 0x00200,      /*!< External interrupt line 9 */
+    EINT_LINE_10  = 0x00400,      /*!< External interrupt line 10 */
+    EINT_LINE_11  = 0x00800,      /*!< External interrupt line 11 */
+    EINT_LINE_12  = 0x01000,      /*!< External interrupt line 12 */
+    EINT_LINE_13  = 0x02000,      /*!< External interrupt line 13 */
+    EINT_LINE_14  = 0x04000,      /*!< External interrupt line 14 */
+    EINT_LINE_15  = 0x08000,      /*!< External interrupt line 15 */
+    EINT_LINE_16  = 0x10000,      /*!< External interrupt line 16 Connected to the PVD Output */
+    EINT_LINE_17  = 0x20000,      /*!< External interrupt line 17 Connected to the RTC Alarm event */
+    EINT_LINE_18  = 0x40000,      /*!< External interrupt line 18 Connected to the USB Device */
+    EINT_LINE_19  = 0x80000,      /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
+    EINT_LINE_20  = 0x00100000,   /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) */
+    EINT_LINE_21  = 0x00200000,   /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp even */
+    EINT_LINE_22  = 0x00400000,   /*!< External interrupt line 22 Connected to the RTC Wakeup event */
+} EINT_LINE_T;
+
+/**@} end of group EINT_Enumerations*/
+
+/** @addtogroup EINT_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief    EINT Config structure definition
+ */
+typedef struct
+{
+    EINT_LINE_T     line;       /*!< External interrupt line selection */
+    EINT_MODE_T     mode;       /*!< External interrupt or event mode selection */
+    EINT_TRIGGER_T  trigger;    /*!< External trigger mode */
+    uint8_t         lineCmd;    /*!< External interrupt line command */
+} EINT_Config_T;
+
+/**@} end of group EINT_Structure*/
+
+/** @defgroup EINT_Functions
+  @{
+*/
+
+/* Reset and configuration */
+void EINT_Reset(void);
+void EINT_Config( EINT_Config_T* eintConfig);
+void EINT_ConfigStructInit(EINT_Config_T* eintConfig);
+
+/* Interrupt and flag */
+void EINT_SelectSWInterrupt(uint32_t line);
+uint8_t EINT_ReadStatusFlag(EINT_LINE_T line);
+void EINT_ClearStatusFlag(uint32_t line);
+uint8_t EINT_ReadIntFlag(EINT_LINE_T line);
+void EINT_ClearIntFlag(uint32_t line);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_EINT_H */
+
+/**@} end of group EINT_Enumerations */
+/**@} end of group EINT_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 361 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_fmc.h

@@ -0,0 +1,361 @@
+/*!
+ * @file       apm32f4xx_fmc.h
+ *
+ * @brief      This file contains all the functions prototypes for the FMC firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_FMC_H
+#define __APM32F4XX_FMC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup FMC_Driver
+  @{
+*/
+
+/** @defgroup FMC_Enumerations
+  @{
+*/
+
+/**
+ * @brief FMC Status
+ */
+typedef enum
+{
+    FMC_BUSY = 1,           /*!< Busy */
+    FMC_ERROR_RD,           /*!< Reserved */
+    FMC_ERROR_PGS,          /*!< Programming Sequence Error */
+    FMC_ERROR_PGP,          /*!< Programming Parallelism Error */
+    FMC_ERROR_PGA,          /*!< Programming Alignment Error */
+    FMC_ERROR_WRP,          /*!< Write Protection Error */
+    FMC_ERROR_PROGRAM,      /*!< Programming Error */
+    FMC_ERROR_OPERATION,    /*!< Operation Error */
+    FMC_COMPLETE            /*!< Operation Complete */
+} FMC_STATUS_T;
+
+/**
+ * @brief FMC Latency
+ */
+typedef enum
+{
+    FMC_LTNCY_0    = ((uint8_t)0x0000), /*!< FMC 0 Latency cycle */
+    FMC_LTNCY_1    = ((uint8_t)0x0001), /*!< FMC 1 Latency cycle */
+    FMC_LTNCY_2    = ((uint8_t)0x0002), /*!< FMC 2 Latency cycles */
+    FMC_LTNCY_3    = ((uint8_t)0x0003), /*!< FMC 3 Latency cycles */
+    FMC_LTNCY_4    = ((uint8_t)0x0004), /*!< FMC 4 Latency cycles */
+    FMC_LTNCY_5    = ((uint8_t)0x0005), /*!< FMC 5 Latency cycles */
+    FMC_LTNCY_6    = ((uint8_t)0x0006), /*!< FMC 6 Latency cycles */
+    FMC_LTNCY_7    = ((uint8_t)0x0007), /*!< FMC 7 Latency cycles */
+    FMC_LTNCY_8    = ((uint8_t)0x0008), /*!< FMC 8 Latency cycles */
+    FMC_LTNCY_9    = ((uint8_t)0x0009), /*!< FMC 9 Latency cycles */
+    FMC_LTNCY_10   = ((uint8_t)0x000A), /*!< FMC 10 Latency cycles */
+    FMC_LTNCY_11   = ((uint8_t)0x000B), /*!< FMC 11 Latency cycles */
+    FMC_LTNCY_12   = ((uint8_t)0x000C), /*!< FMC 12 Latency cycles */
+    FMC_LTNCY_13   = ((uint8_t)0x000D), /*!< FMC 13 Latency cycles */
+    FMC_LTNCY_14   = ((uint8_t)0x000E), /*!< FMC 14 Latency cycles */
+    FMC_LTNCY_15   = ((uint8_t)0x000F)  /*!< FMC 15 Latency cycles */
+} FMC_LATENCY_T;
+
+/**
+ * @brief FMC Voltage Range
+ */
+typedef enum
+{
+    FMC_VOLTAGE_1  = (uint8_t)0x00, /*!< when the device voltage range is 1.8V to 2.1V,
+                                        the operation will be done by byte (8-bit) */
+    FMC_VOLTAGE_2  = (uint8_t)0x01, /*!< when the device voltage range is 2.1V to 2.7V,
+                                        the operation will be done by half word (16-bit) */
+    FMC_VOLTAGE_3  = (uint8_t)0x02, /*!< when the device voltage range is 2.7V to 3.6V,
+                                        the operation will be done by word (32-bit) */
+    FMC_VOLTAGE_4  = (uint8_t)0x03, /*!< when the device voltage range is 2.7V to 3.6V + External Vpp,
+                                        the operation will be done by double word (64-bit) */
+} FMC_VOLTAGE_T;
+
+/**
+ * @brief FMC Sectors
+ */
+typedef enum
+{
+    FMC_SECTOR_0   = ((uint16_t)0x0000),    /*!< Sector number 0 */
+    FMC_SECTOR_1   = ((uint16_t)0x0008),    /*!< Sector number 1 */
+    FMC_SECTOR_2   = ((uint16_t)0x0010),    /*!< Sector number 2 */
+    FMC_SECTOR_3   = ((uint16_t)0x0018),    /*!< Sector number 3 */
+    FMC_SECTOR_4   = ((uint16_t)0x0020),    /*!< Sector number 4 */
+    FMC_SECTOR_5   = ((uint16_t)0x0028),    /*!< Sector number 5 */
+    FMC_SECTOR_6   = ((uint16_t)0x0030),    /*!< Sector number 6 */
+    FMC_SECTOR_7   = ((uint16_t)0x0038),    /*!< Sector number 7 */
+    FMC_SECTOR_8   = ((uint16_t)0x0040),    /*!< Sector number 8 */
+    FMC_SECTOR_9   = ((uint16_t)0x0048),    /*!< Sector number 9 */
+    FMC_SECTOR_10  = ((uint16_t)0x0050),    /*!< Sector number 10 */
+    FMC_SECTOR_11  = ((uint16_t)0x0058),    /*!< Sector number 11 */
+    FMC_SECTOR_12  = ((uint16_t)0x0080),    /*!< Sector number 12 */
+    FMC_SECTOR_13  = ((uint16_t)0x0088),    /*!< Sector number 13 */
+    FMC_SECTOR_14  = ((uint16_t)0x0090),    /*!< Sector number 14 */
+    FMC_SECTOR_15  = ((uint16_t)0x0098),    /*!< Sector number 15 */
+    FMC_SECTOR_16  = ((uint16_t)0x00A0),    /*!< Sector number 16 */
+    FMC_SECTOR_17  = ((uint16_t)0x00A8),    /*!< Sector number 17 */
+    FMC_SECTOR_18  = ((uint16_t)0x00B0),    /*!< Sector number 18 */
+    FMC_SECTOR_19  = ((uint16_t)0x00B8),    /*!< Sector number 19 */
+    FMC_SECTOR_20  = ((uint16_t)0x00C0),    /*!< Sector number 20 */
+    FMC_SECTOR_21  = ((uint16_t)0x00C8),    /*!< Sector number 21 */
+    FMC_SECTOR_22  = ((uint16_t)0x00D0),    /*!< Sector number 22 */
+    FMC_SECTOR_23  = ((uint16_t)0x00D8)     /*!< Sector number 23 */
+} FMC_SECTOR_T;
+
+/**
+ * @brief Option Bytes Write Protection
+ */
+typedef enum
+{
+    FMC_OPT_WRP_SECTOR_0   = (uint32_t)0x00000001,  /*!< Write protection of sector 0 */
+    FMC_OPT_WRP_SECTOR_1   = (uint32_t)0x00000002,  /*!< Write protection of sector 1 */
+    FMC_OPT_WRP_SECTOR_2   = (uint32_t)0x00000004,  /*!< Write protection of sector 2 */
+    FMC_OPT_WRP_SECTOR_3   = (uint32_t)0x00000008,  /*!< Write protection of sector 3 */
+    FMC_OPT_WRP_SECTOR_4   = (uint32_t)0x00000010,  /*!< Write protection of sector 4 */
+    FMC_OPT_WRP_SECTOR_5   = (uint32_t)0x00000020,  /*!< Write protection of sector 5 */
+    FMC_OPT_WRP_SECTOR_6   = (uint32_t)0x00000040,  /*!< Write protection of sector 6 */
+    FMC_OPT_WRP_SECTOR_7   = (uint32_t)0x00000080,  /*!< Write protection of sector 7 */
+    FMC_OPT_WRP_SECTOR_8   = (uint32_t)0x00000100,  /*!< Write protection of sector 8 */
+    FMC_OPT_WRP_SECTOR_9   = (uint32_t)0x00000200,  /*!< Write protection of sector 9 */
+    FMC_OPT_WRP_SECTOR_10  = (uint32_t)0x00000400,  /*!< Write protection of sector 10 */
+    FMC_OPT_WRP_SECTOR_11  = (uint32_t)0x00000800,  /*!< Write protection of sector 11 */
+
+    FMC_OPT_WRP_SECTOR_12  = (uint32_t)0x00000001,  /*!< Write protection of sector 12 */
+    FMC_OPT_WRP_SECTOR_13  = (uint32_t)0x00000002,  /*!< Write protection of sector 13 */
+    FMC_OPT_WRP_SECTOR_14  = (uint32_t)0x00000004,  /*!< Write protection of sector 14 */
+    FMC_OPT_WRP_SECTOR_15  = (uint32_t)0x00000008,  /*!< Write protection of sector 15 */
+    FMC_OPT_WRP_SECTOR_16  = (uint32_t)0x00000010,  /*!< Write protection of sector 16 */
+    FMC_OPT_WRP_SECTOR_17  = (uint32_t)0x00000020,  /*!< Write protection of sector 17 */
+    FMC_OPT_WRP_SECTOR_18  = (uint32_t)0x00000040,  /*!< Write protection of sector 18 */
+    FMC_OPT_WRP_SECTOR_19  = (uint32_t)0x00000080,  /*!< Write protection of sector 19 */
+    FMC_OPT_WRP_SECTOR_20  = (uint32_t)0x00000100,  /*!< Write protection of sector 20 */
+    FMC_OPT_WRP_SECTOR_21  = (uint32_t)0x00000200,  /*!< Write protection of sector 21 */
+    FMC_OPT_WRP_SECTOR_22  = (uint32_t)0x00000400,  /*!< Write protection of sector 22 */
+    FMC_OPT_WRP_SECTOR_23  = (uint32_t)0x00000800,  /*!< Write protection of sector 23 */
+    FMC_OPT_WRP_SECTOR_All = (uint32_t)0x00000FFF   /*!< Write protection of sector 24 */
+} FMC_OPT_WRP_T;
+
+/**
+ * @brief FMC Option Bytes Read Protection
+ */
+typedef enum
+{
+    FMC_OPT_RDP_LV0 =(uint8_t)0xAA,     /*!< No protection */
+    FMC_OPT_RDP_LV1 =(uint8_t)0x55      /*!< Read protection of the memory */
+} FMC_OPT_RDP_T;
+
+/**
+ * @brief FMC Option Bytes Independent Watchdog
+ */
+typedef enum
+{
+    FMC_OPT_IWDT_SOFT = (uint8_t)0x20,  /*!< Software IWDT selected */
+    FMC_OPT_IWDT_HARD = (uint8_t)0x00   /*!< Hardware IWDT selected */
+} FMC_OPT_IWDT_T;
+
+/**
+ * @brief FMC Option Bytes nRST STOP
+ */
+typedef enum
+{
+    FMC_OPT_STOP_NORST = (uint8_t)0x40, /*!< No reset generated when entering in STOP */
+    FMC_OPT_STOP_RST   = (uint8_t)0x00  /*!< Reset generated when entering in STOP */
+} FMC_OPT_STOP_T;
+
+/**
+ * @brief FMC Option Bytes nRST STDBY
+ */
+typedef enum
+{
+    FMC_OPT_STDBY_NORST = (uint8_t)0x80,    /*!< No reset generated when entering in STANDBY */
+    FMC_OPT_STDBY_RST   = (uint8_t)0x00     /*!< Reset generated when entering in STANDBY */
+} FMC_OPT_STDBY_T;
+
+/**
+ * @brief FMC BOR Reset Level
+ */
+typedef enum
+{
+    FMC_OPT_BOR_LV3 = (uint8_t)0x00,    /*!< Supply voltage ranges from 2.7 to 3.6 V */
+    FMC_OPT_BOR_LV2 = (uint8_t)0x04,    /*!< Supply voltage ranges from 2.4 to 2.7 V */
+    FMC_OPT_BOR_LV1 = (uint8_t)0x08,    /*!< Supply voltage ranges from 2.1 to 2.4 V */
+    FMC_OPT_BOR_OFF = (uint8_t)0x0C     /*!< Supply voltage ranges from 1.62 to 2.1 V */
+} FMC_OPT_BOR_T;
+
+/**
+ * @brief FMC Dual Boot
+ */
+typedef enum
+{
+    FMC_OPT_BOOTEN  = (uint8_t)0x10,    /*!< Dual boot mode enable */
+    FMC_OPT_BOOTDIS = (uint8_t)0x00     /*!< Dual boot mode disable */
+} FMC_OPT_BOOT_T;
+
+/**
+ * @brief FMC Interrupts
+ */
+typedef enum
+{
+    FMC_INT_OC  = (uint32_t)0x01000000, /*!< Operation Complete Interrupt */
+    FMC_INT_ERR = (uint32_t)0x02000000  /*!< Error Interrupt */
+} FMC_INT_T;
+
+/**
+ * @brief FMC Flags
+ */
+typedef enum
+{
+    FMC_FLAG_ENDOP  = (uint32_t)0x00000001, /*!< FMC End of Operation flag */
+    FMC_FLAG_ERROP  = (uint32_t)0x00000002, /*!< FMC operation Error flag */
+    FMC_FLAG_ERRWRP = (uint32_t)0x00000010, /*!< FMC Write protected error flag */
+    FMC_FLAG_ERRPGA = (uint32_t)0x00000020, /*!< FMC Programming Alignment error flag */
+    FMC_FLAG_ERRPGP = (uint32_t)0x00000040, /*!< FMC Programming Parallelism error flag */
+    FMC_FLAG_ERRPGS = (uint32_t)0x00000080, /*!< FMC Programming Sequence error flag */
+    FMC_FLAG_BUSY   = (uint32_t)0x00010000  /*!< FMC Busy flag */
+} FMC_FLAG_T;
+
+/**
+ * @brief FMC Program Parallelism
+ */
+typedef enum
+{
+    FMC_PSIZE_BYTE        = (uint32_t)0x00000000,   /*!< Set program parallelism to 8-bit */
+    FMC_PSIZE_HALF_WORD   = (uint32_t)0x00000100,   /*!< Set program parallelism to 16-bit */
+    FMC_PSIZE_WORD        = (uint32_t)0x00000200,   /*!< Set program parallelism to 32-bit */
+    FMC_PSIZE_DOUBLE_WORD = (uint32_t)0x00000300    /*!< Set program parallelism to 64-bit */
+} FMC_PSIZE_T;
+
+/**@} end of group FMC_Enumerations*/
+
+/** @defgroup FMC_Macros Macros
+  @{
+*/
+
+#define PMC_RDP_KEY            ((uint16_t)0x00A5)
+#define FMC_KEY1               ((uint32_t)0x45670123)
+#define FMC_KEY2               ((uint32_t)0xCDEF89AB)
+#define FMC_OPT_KEY1           ((uint32_t)0x08192A3B)
+#define FMC_OPT_KEY2           ((uint32_t)0x4C5D6E7F)
+
+/* FMC ACCTRL register Bits definition */
+#define FMC_ACCTRL_PREFEN      ((uint32_t)0x00000100)
+#define FMC_ACCTRL_ICACHEEN    ((uint32_t)0x00000200)
+#define FMC_ACCTRL_DCACHEEN    ((uint32_t)0x00000400)
+#define FMC_ACCTRL_ICACHERST   ((uint32_t)0x00000800)
+#define FMC_ACCTRL_DCACHERST   ((uint32_t)0x00001000)
+
+/* FMC CTRL register Bits definition */
+#define FMC_CTRL_PG            ((uint32_t)0x00000001)
+#define FMC_CTRL_SERS          ((uint32_t)0x00000002)
+#define FMC_CTRL_MERS          ((uint32_t)0x00000004)
+#define FMC_CTRL_SNUM          ((uint32_t)0x00000008)
+#define FMC_CTRL_START         ((uint32_t)0x00010000)
+#define FMC_CTRL_LOCK          ((uint32_t)0x80000000)
+
+/* FMC OPTCTRL register Bits definition */
+#define FMC_OPTCTRL_OPTLOCK    ((uint32_t)0x00000001)
+#define FMC_OPTCTRL_OPTSTART   ((uint32_t)0x00000002)
+#define FMC_OPTCTRL_BORLVL     ((uint32_t)0x0000000C)
+
+/* ACCTRL  register byte 0 (Bits[7:0]) base address */
+#define ACCTRL_BYTE0_ADDRESS          ((uint32_t)0x40023C00)
+
+/* OPTCTRL register byte 0 (Bits[7:0]) base address */
+#define OPTCTRL_BYTE0_ADDRESS         ((uint32_t)0x40023C14)
+
+/* OPTCTRL register byte 1 (Bits[15:8]) base address */
+#define OPTCTRL_BYTE1_ADDRESS         ((uint32_t)0x40023C15)
+
+/* OPTCTRL register byte 2 (Bits[23:16]) base address */
+#define OPTCTRL_BYTE2_ADDRESS         ((uint32_t)0x40023C16)
+
+/* OPTCTRL register byte 3 (Bits[31:24]) base address */
+#define OPTCTRL_BYTE3_ADDRESS         ((uint32_t)0x40023C17)
+
+/**@} end of group FMC_Macros*/
+
+/** @defgroup FMC_Functions
+  @{
+*/
+
+/* FMC Interface configuration functions */
+void FMC_ConfigLatency(FMC_LATENCY_T latency);
+void FMC_EnablePrefetchBuffer(void);
+void FMC_DisablePrefetchBuffer(void);
+void FMC_EnableInstructionCache(void);
+void FMC_DisableInstructionCache(void);
+void FMC_EnableDataCache(void);
+void FMC_DisableDataCache(void);
+void FMC_ResetInstructionCache(void);
+void FMC_ResetDataCache(void);
+
+/* FMC Memory Programming functions */
+void FMC_Unlock(void);
+void FMC_Lock(void);
+FMC_STATUS_T FMC_EraseSector(FMC_SECTOR_T sector, FMC_VOLTAGE_T voltageRange);
+FMC_STATUS_T FMC_EraseAllSectors(FMC_VOLTAGE_T voltageRange);
+FMC_STATUS_T FMC_ProgramDoubleWord(uint32_t address, uint64_t data);
+FMC_STATUS_T FMC_ProgramWord(uint32_t address, uint32_t data);
+FMC_STATUS_T FMC_ProgramHalfWord(uint32_t address, uint16_t data);
+FMC_STATUS_T FMC_ProgramByte(uint32_t address, uint8_t data);
+
+/* Option Bytes Programming functions */
+void FMC_UnlockOptionByte(void);
+void FMC_LockOptionByte(void);
+void FMC_OPT_EnableWriteProtect(FMC_OPT_WRP_T wrp);
+void FMC_OPT_DisableWriteProtect(FMC_OPT_WRP_T wrp);
+void FMC_OPT_ConfigReadProtect(FMC_OPT_RDP_T rdp);
+void FMC_OPT_ConfigUser(FMC_OPT_IWDT_T iwdt, FMC_OPT_STOP_T stop, FMC_OPT_STDBY_T stdby);
+void FMC_OPT_ConfigBrownoutReset(FMC_OPT_BOR_T bor);
+FMC_STATUS_T FMC_OPT_Launch(void);
+uint8_t FMC_OPT_ReadUser(void);
+uint16_t FMC_OPT_ReadWriteProtect(void);
+uint8_t FMC_OPT_ReadProtectLevel(void);
+uint8_t FMC_OPT_ReadBrownoutReset(void);
+
+/* Interrupts and flags management functions */
+void FMC_EnableInterrupt(uint32_t interrupt);
+void FMC_DisableInterrupt(uint32_t interrupt);
+uint8_t FMC_ReadStatusFlag(FMC_FLAG_T flag);
+void FMC_ClearStatusFlag(uint32_t flag);
+FMC_STATUS_T FMC_ReadStatus(void);
+FMC_STATUS_T FMC_WaitForLastOperation(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_FMC_H */
+
+/**@} end of group FMC_Enumerations */
+/**@} end of group FMC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 285 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_gpio.h

@@ -0,0 +1,285 @@
+/*!
+ * @file        apm32f4xx_gpio.h
+ *
+ * @brief       This file provides all the GPIO firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_GPIO_H
+#define __APM32F4XX_GPIO_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup GPIO_Driver
+  @{
+*/
+
+/** @defgroup GPIO_Enumerations
+  @{
+*/
+
+/**
+ * @brief GPIO Configuration Mode enumeration
+ */
+typedef enum
+{
+    GPIO_MODE_IN   = 0x00, /*!< GPIO Input Mode */
+    GPIO_MODE_OUT  = 0x01, /*!< GPIO Output Mode */
+    GPIO_MODE_AF   = 0x02, /*!< GPIO Alternate function Mode */
+    GPIO_MODE_AN   = 0x03  /*!< GPIO Analog Mode */
+} GPIO_MODE_T;
+
+/**
+ * @brief GPIO Output type enumeration
+ */
+typedef enum
+{
+    GPIO_OTYPE_PP = 0x00,   /*!< GPIO push-pull mode */
+    GPIO_OTYPE_OD = 0x01    /*!< GPIO open drain mode */
+} GPIO_OTYPE_T;
+
+/**
+ * @brief GPIO Output Maximum frequency enumeration
+ */
+typedef enum
+{
+    GPIO_SPEED_2MHz      = 0x00,      /*!< Low speed */
+    GPIO_SPEED_25MHz     = 0x01,      /*!< Medium speed */
+    GPIO_SPEED_50MHz     = 0x02,      /*!< Fast speed */
+    GPIO_SPEED_100MHz    = 0x03       /*!< High speed */
+} GPIO_SPEED_T;
+
+/**
+ * @brief GPIO Configuration PullUp PullDown enumeration
+ */
+typedef enum
+{
+    GPIO_PUPD_NOPULL = 0x00,    /*!< GPIO no pull mode */
+    GPIO_PUPD_UP     = 0x01,    /*!< GPIO pull-up mode */
+    GPIO_PUPD_DOWN   = 0x02     /*!< GPIO pull-down mode */
+} GPIO_PUPD_T;
+
+/**
+ * @brief GPIO Pins
+ */
+typedef enum
+{
+    GPIO_PIN_0   = ((uint16_t)BIT0),    /*!< GPIO pin 0 selected */
+    GPIO_PIN_1   = ((uint16_t)BIT1),    /*!< GPIO pin 1 selected */
+    GPIO_PIN_2   = ((uint16_t)BIT2),    /*!< GPIO pin 2 selected */
+    GPIO_PIN_3   = ((uint16_t)BIT3),    /*!< GPIO pin 3 selected */
+    GPIO_PIN_4   = ((uint16_t)BIT4),    /*!< GPIO pin 4 selected */
+    GPIO_PIN_5   = ((uint16_t)BIT5),    /*!< GPIO pin 5 selected */
+    GPIO_PIN_6   = ((uint16_t)BIT6),    /*!< GPIO pin 6 selected */
+    GPIO_PIN_7   = ((uint16_t)BIT7),    /*!< GPIO pin 7 selected */
+    GPIO_PIN_8   = ((uint16_t)BIT8),    /*!< GPIO pin 8 selected */
+    GPIO_PIN_9   = ((uint16_t)BIT9),    /*!< GPIO pin 9 selected */
+    GPIO_PIN_10  = ((uint16_t)BIT10),   /*!< GPIO pin 10 selected */
+    GPIO_PIN_11  = ((uint16_t)BIT11),   /*!< GPIO pin 11 selected */
+    GPIO_PIN_12  = ((uint16_t)BIT12),   /*!< GPIO pin 12 selected */
+    GPIO_PIN_13  = ((uint16_t)BIT13),   /*!< GPIO pin 13 selected */
+    GPIO_PIN_14  = ((uint16_t)BIT14),   /*!< GPIO pin 14 selected */
+    GPIO_PIN_15  = ((uint16_t)BIT15),   /*!< GPIO pin 15 selected */
+    GPIO_PIN_ALL = ((uint32_t)0XFFFF),  /*!< GPIO all pins selected */
+} GPIO_PIN_T;
+
+/**
+ * @brief GPIO Pin sources
+ */
+typedef enum
+{
+    GPIO_PIN_SOURCE_0,  /*!< GPIO pin source 0 */
+    GPIO_PIN_SOURCE_1,  /*!< GPIO pin source 1 */
+    GPIO_PIN_SOURCE_2,  /*!< GPIO pin source 2 */
+    GPIO_PIN_SOURCE_3,  /*!< GPIO pin source 3 */
+    GPIO_PIN_SOURCE_4,  /*!< GPIO pin source 4 */
+    GPIO_PIN_SOURCE_5,  /*!< GPIO pin source 5 */
+    GPIO_PIN_SOURCE_6,  /*!< GPIO pin source 6 */
+    GPIO_PIN_SOURCE_7,  /*!< GPIO pin source 7 */
+    GPIO_PIN_SOURCE_8,  /*!< GPIO pin source 8 */
+    GPIO_PIN_SOURCE_9,  /*!< GPIO pin source 9 */
+    GPIO_PIN_SOURCE_10, /*!< GPIO pin source 10 */
+    GPIO_PIN_SOURCE_11, /*!< GPIO pin source 11 */
+    GPIO_PIN_SOURCE_12, /*!< GPIO pin source 12 */
+    GPIO_PIN_SOURCE_13, /*!< GPIO pin source 13 */
+    GPIO_PIN_SOURCE_14, /*!< GPIO pin source 14 */
+    GPIO_PIN_SOURCE_15, /*!< GPIO pin source 15 */
+} GPIO_PIN_SOURCE_T;
+
+/**
+ * @brief GPIO Alternat function selection
+ */
+typedef enum
+{
+    GPIO_AF_RTC_50Hz            = 0x00, /*!< RTC_50Hz Alternate Function mapping */
+    GPIO_AF_MCO                 = 0x00, /*!< MCO (MCO1 and MCO2) Alternate Function mapping */
+    GPIO_AF_TAMPER              = 0x00, /*!< TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */
+    GPIO_AF_SWJ                 = 0x00, /*!< SWJ (SWD and JTAG) Alternate Function mapping */
+    GPIO_AF_TRACE               = 0x00, /*!< TRACE Alternate Function mapping */
+
+    GPIO_AF_TMR1                = 0x01, /*!< TMR1 Alternate Function mapping */
+    GPIO_AF_TMR2                = 0x01, /*!< TMR2 Alternate Function mapping */
+    GPIO_AF_LPTMR               = 0x01, /*!< LPTMR Alternate Function mapping */
+
+    GPIO_AF_TMR3                = 0x02, /*!< TMR3 Alternate Function mapping */
+    GPIO_AF_TMR4                = 0x02, /*!< TMR4 Alternate Function mapping */
+    GPIO_AF_TMR5                = 0x02, /*!< TMR5 Alternate Function mapping */
+
+    GPIO_AF_TMR8                = 0x03, /*!< TMR8 Alternate Function mapping */
+    GPIO_AF_TMR9                = 0x03, /*!< TMR9 Alternate Function mapping */
+    GPIO_AF_TMR10               = 0x03, /*!< TMR10 Alternate Function mapping */
+    GPIO_AF_TMR11               = 0x03, /*!< TMR11 Alternate Function mapping */
+
+    GPIO_AF_I2C1                = 0x04, /*!< I2C1 Alternate Function mapping */
+    GPIO_AF_I2C2                = 0x04, /*!< I2C2 Alternate Function mapping */
+    GPIO_AF_I2C3                = 0x04, /*!< I2C3 Alternate Function mapping */
+    GPIO_AF_FMPI2C              = 0x04, /*!< FMPI2C Alternate Function mapping */
+
+    GPIO_AF_SPI1                = 0x05, /*!< SPI1/I2S1 Alternate Function mapping */
+    GPIO_AF_SPI2                = 0x05, /*!< SPI2/I2S2 Alternate Function mapping */
+    GPIO_AF5_SPI3               = 0x05, /*!< SPI3/I2S3 Alternate Function mapping */
+    GPIO_AF_SPI4                = 0x05, /*!< SPI4/I2S4 Alternate Function mapping */
+    GPIO_AF_SPI5                = 0x05, /*!< SPI5 Alternate Function mapping */
+    GPIO_AF_SPI6                = 0x05, /*!< SPI6 Alternate Function mapping */
+
+    GPIO_AF_SPI3                = 0x06, /*!< SPI3/I2S3 Alternate Function mapping */
+    GPIO_AF6_SPI1               = 0x06, /*!< SPI1 Alternate Function mapping */
+    GPIO_AF6_SPI2               = 0x06, /*!< SPI2 Alternate Function mapping */
+    GPIO_AF6_SPI4               = 0x06, /*!< SPI4 Alternate Function mapping */
+    GPIO_AF6_SPI5               = 0x06, /*!< SPI5 Alternate Function mapping */
+    GPIO_AF_SAI1                = 0x06, /*!< SAI1 Alternate Function mapping */
+    GPIO_AF_I2S2ext             = 0x06, /*!< I2S2ext_SD Alternate Function mapping */
+
+    GPIO_AF_USART1              = 0x07, /*!< USART1 Alternate Function mapping */
+    GPIO_AF_USART2              = 0x07, /*!< USART2 Alternate Function mapping */
+    GPIO_AF_USART3              = 0x07, /*!< USART3 Alternate Function mapping */
+    GPIO_AF7_SPI3               = 0x07, /*!< SPI3/I2S3ext Alternate Function mapping */
+
+    GPIO_AF_UART4               = 0x08, /*!< UART4 Alternate Function mapping */
+    GPIO_AF_UART5               = 0x08, /*!< UART5 Alternate Function mapping */
+    GPIO_AF_USART6              = 0x08, /*!< USART6 Alternate Function mapping */
+    GPIO_AF_UART7               = 0x08, /*!< UART7 Alternate Function mapping */
+    GPIO_AF_UART8               = 0x08, /*!< UART8 Alternate Function mapping */
+    GPIO_AF8_USART3             = 0x08, /*!< USART3 Alternate Function mapping */
+    GPIO_AF8_CAN1               = 0x08, /*!< CAN1 Alternate Function mapping */
+
+    GPIO_AF_CAN1                = 0x09, /*!< CAN1 Alternate Function mapping */
+    GPIO_AF_CAN2                = 0x09, /*!< CAN2 Alternate Function mapping */
+    GPIO_AF_TMR12               = 0x09, /*!< TMR12 Alternate Function mapping */
+    GPIO_AF_TMR13               = 0x09, /*!< TMR13 Alternate Function mapping */
+    GPIO_AF_TMR14               = 0x09, /*!< TMR14 Alternate Function mapping */
+    GPIO_AF9_I2C2               = 0x09, /*!< I2C2 Alternate Function mapping */
+    GPIO_AF9_I2C3               = 0x09, /*!< I2C3 Alternate Function mapping */
+
+    GPIO_AF_OTG_FS              = 0x0A, /*!< OTG_FS Alternate Function mapping */
+    GPIO_AF_OTG_HS              = 0x0A, /*!< OTG_HS Alternate Function mapping */
+
+    GPIO_AF_ETH                 = 0x0B, /*!< ETHERNET Alternate Function mapping */
+
+    GPIO_AF_FSMC                = 0x0C, /*!< FSMC Alternate Function mapping */
+    GPIO_AF_OTG_HS_FS           = 0x0C, /*!< OTG HS configured in FS, Alternate Function mapping */
+    GPIO_AF_SDIO                = 0x0C, /*!< SDIO Alternate Function mapping */
+
+    GPIO_AF_DCMI                = 0x0D, /*!< DCMI Alternate Function mapping */
+
+    GPIO_AF14_RNG               = 0x0E, /*!< RNG Alternate Function mapping */
+
+    GPIO_AF_EVENTOUT            = 0x0F, /*!< EVENTOUT Alternate Function mapping */
+} GPIO_AF_T;
+
+/**@} end of group GPIO_Enumerations*/
+
+/** @addtogroup GPIO_Macros Macros
+  @{
+*/
+#define GPIO_Mode_AIN           GPIO_Mode_AN
+
+#define GPIO_AF_I2S3ext         GPIO_AF7_SPI3
+#define GPIO_AF_OTG1_FS         GPIO_AF_OTG_FS
+#define GPIO_AF_OTG2_HS         GPIO_AF_OTG_HS
+#define GPIO_AF_OTG2_FS         GPIO_AF_OTG_HS_FS
+
+/**@} end of group GPIO_Macros*/
+
+/** @addtogroup GPIO_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief GPIO Init structure definition
+ */
+typedef struct
+{
+    uint16_t      pin;      //!< Specifies the GPIO pins to be configured.
+    GPIO_MODE_T   mode;     //!< Specifies the operating mode for the selected pins.
+    GPIO_SPEED_T  speed;    //!< Specifies the speed for the selected pins.
+    GPIO_OTYPE_T  otype;    //!< Specifies the operating output type for the selected pins.
+    GPIO_PUPD_T   pupd;     //!< Specifies the operating Pull-up/Pull down for the selected pins.
+} GPIO_Config_T;
+
+/**@} end of group GPIO_Structure*/
+
+/** @defgroup GPIO_Functions
+  @{
+*/
+
+/* Reset and common Configuration */
+void GPIO_Reset(GPIO_T* port);
+void GPIO_Config(GPIO_T* port, GPIO_Config_T* gpioConfig);
+void GPIO_ConfigStructInit(GPIO_Config_T* gpioConfig);
+
+/* GPIO Read functions */
+uint8_t GPIO_ReadInputBit(GPIO_T* port, uint16_t pin);
+uint8_t GPIO_ReadOutputBit(GPIO_T* port, uint16_t pin);
+
+uint16_t GPIO_ReadInputPort(GPIO_T* port);
+uint16_t GPIO_ReadOutputPort(GPIO_T* port);
+
+/* GPIO Write functions */
+void GPIO_SetBit(GPIO_T* port, uint16_t pin);
+void GPIO_ResetBit(GPIO_T* port, uint16_t pin);
+void GPIO_WriteBitValue(GPIO_T* port, uint16_t pin, uint8_t bitVal);
+void GPIO_WriteOutputPort(GPIO_T* port, uint16_t portValue);
+
+/* GPIO Other functions */
+void GPIO_ToggleBit(GPIO_T* port, uint16_t pin);
+void GPIO_ConfigPinLock(GPIO_T* port, uint16_t pin);
+void GPIO_ConfigPinAF(GPIO_T* port, GPIO_PIN_SOURCE_T gpioPinSource, GPIO_AF_T gpioAf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__APM32F4XX_GPIO_H */
+
+/**@} end of group GPIO_Enumerations */
+/**@} end of group GPIO_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 215 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_hash.h

@@ -0,0 +1,215 @@
+/*!
+ * @file        apm32f4xx_hash.c
+ *
+ * @brief       This file provides all the HASH firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_HASH_H
+#define __APM32F4XX_HASH_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup HASH_Driver
+  @{
+*/
+
+/** @defgroup HASH_Enumerations
+  @{
+*/
+
+/**
+ * @brief HASH Algo Selection
+ */
+typedef enum
+{
+    HASH_ALGO_SELECTION_SHA1,   /*!< Select SHA-1 algorithm */
+    HASH_ALGO_SELECTION_MD5     /*!< Select MD5 algorithm */
+} HASH_ALGO_SELECTION_T;
+
+/**
+ * @brief HASH processor Algorithm Mode
+ */
+typedef enum
+{
+    HASH_ALGO_MODE_HASH,    /*!< HASH mode */
+    HASH_ALGO_MODE_HMAC     /*!< HMAC mode */
+} HASH_ALGO_MODE_T;
+
+/**
+ * @brief HASH Data Type
+ */
+typedef enum
+{
+    HASH_DATA_TYPE_32B, /*!< 32-bit data type */
+    HASH_DATA_TYPE_16B, /*!< 16-bit data type */
+    HASH_DATA_TYPE_8B,  /*!< 8-bit data type */
+    HASH_DATA_TYPE_1B   /*!< 1-bit data type */
+} HASH_DATA_TYPE_T;
+
+/**
+ * @brief HASH HMAC Long key only for HMAC mode
+ */
+typedef enum
+{
+    HASH_HMAC_KEY_TYPE_SHORTKEY,    /*!< Short key type */
+    HASH_HMAC_KEY_TYPE_LONGKEY      /*!< Long key type */
+} HASH_HMAC_KEY_TYPE_T;
+
+/**
+ * @brief HASH interrupts
+ */
+typedef enum
+{
+    HASH_INT_INDATAINT  = BIT0, /*!< Input Data interrupt mask */
+    HASH_INT_DCALCINT   = BIT1, /*!< Digest calculation completion Data interrupt mask */
+} HASH_INT_T;
+
+/**
+ * @brief HASH flag
+ */
+typedef enum
+{
+    HASH_FLAG_INDATAINT    = BIT0,  /*!< Data input interrupt status flag */
+    HASH_FLAG_DCALCINT     = BIT1,  /*!< Digest calculation completion interrupt status flag */
+    HASH_FLAG_DMA          = BIT2,  /*!< DMAS Status flag */
+    HASH_FLAG_BUSY         = BIT3,  /*!< Busy flag */
+    HASH_FLAG_DINNEMPT     = BIT12  /*!< Data Input register (DIN) not empty status flag */
+} HASH_FLAG_T;
+
+/**
+ * @brief HASH interrupt flag
+ */
+typedef enum
+{
+    HASH_INT_FLAG_INDATA    = BIT0, /*!< Input Data interrupt */
+    HASH_INT_FLAG_DCALC     = BIT1  /*!< Digest Calculation Completion Interrupt */
+} HASH_INT_FLAG_T;
+
+/**@} end of group HASH_Enumerations*/
+
+/** @addtogroup HASH_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief HASH Init structure
+ */
+typedef struct
+{
+    HASH_ALGO_SELECTION_T    algoSelect;    /*!< SHA-1 or MD5 */
+    HASH_ALGO_MODE_T         algoMode;      /*!< HASH or HMAC */
+    HASH_DATA_TYPE_T         dataType;      /*!< 32-bit data, 16-bit data, 8-bit data or bit string */
+    HASH_HMAC_KEY_TYPE_T     hmacKeyType;   /*!< HMAC Short key or HMAC Long Key */
+} HASH_Config_T;
+
+/**
+ * @brief HASH message digest result structure
+ */
+typedef struct
+{
+    uint32_t Data[5];     /*!< Message digest result :
+                             5x 32bit words for SHA-1 or
+                             4x 32bit words for MD5 */
+} HASH_MessageDigest_T;
+
+/**
+ * @brief HASH context swapping structure
+ */
+typedef struct
+{
+    uint32_t HASH_INT;          /*!< HASH interrupt register */
+    uint32_t HASH_START;        /*!< HASH shart register */
+    uint32_t HASH_CTRL;         /*!< HASH CTRL register */
+    uint32_t HASH_CTSWAP[51];   /*!< HASH CTSWAP register */
+} HASH_Context_T;
+
+/**@} end of group HASH_Structure*/
+
+/** @defgroup HASH_Functions
+  @{
+*/
+
+/* HASH Reset */
+void HASH_Reset(void);
+
+/* Configuration */
+void HASH_Config(HASH_Config_T* hashConfig);
+void HASH_ConfigStructInit(HASH_Config_T* hashConfig);
+void HASH_ResetProceCore(void);
+
+/* Message Digest start */
+void HASH_ConfigLastWordValidBitsNbr(uint16_t validNumber);
+void HASH_WritesInputData(uint32_t data);
+uint8_t HASH_ReadInFIFOWordsNbr(void);
+void HASH_ReadDigest(HASH_MessageDigest_T* messageDigest);
+void HASH_StartDigest(void);
+
+/* Context swapping */
+void HASH_ReadContext(HASH_Context_T* contextRead);
+void HASH_WriteContext(HASH_Context_T* contextWrite);
+
+/* Regular Channels DMA */
+void HASH_EnableDMA(void);
+void HASH_DisableDMA(void);
+
+/* Injected channels Configuration */
+void HASH_EnableInterrupt(uint32_t interrupt);
+void HASH_DisableInterrupt(uint32_t interrupt);
+uint8_t HASH_ReadFlagStatus(HASH_FLAG_T flag);
+void HASH_ClearStatusFlag(HASH_FLAG_T flag);
+uint8_t HASH_ReadIntFlag(HASH_INT_FLAG_T flag);
+void HASH_ClearIntFlag(HASH_INT_FLAG_T flag);
+
+/* Waits for processing data */
+uint8_t HASH_WaitForCompute(uint32_t timeOut);
+
+/* High Level SHA1 Compute */
+uint8_t HASH_ComputeSHA1(uint8_t* inBuffer, uint32_t lenBuffer,
+                         uint8_t outBuffer[20]);
+uint8_t HMAC_ComputeSHA1(uint8_t* key, uint32_t lenkey, uint8_t* inBuffer,
+                         uint32_t lenBuffer, uint8_t outBuffer[20]);
+
+/* High Level MD5 Compute */
+uint8_t HASH_ComputeMD5(uint8_t* inBuffer, uint32_t lenBuffer,
+                        uint8_t outBuffer[16]);
+uint8_t HMAC_ComputeMD5(uint8_t* key, uint32_t keylen, uint8_t* inBuffer,
+                        uint32_t lenBuffer, uint8_t outBuffer[16]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__APM32F4XX_HASH_H */
+
+/**@} end of group HASH_Enumerations */
+/**@} end of group HASH_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 352 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_i2c.h

@@ -0,0 +1,352 @@
+/*!
+ * @file        apm32f4xx_i2c.h
+ *
+ * @brief       This file contains all the functions prototypes for the I2C firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_I2C_H
+#define __APM32F4XX_I2C_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup I2C_Driver
+  @{
+*/
+
+/** @defgroup I2C_Enumerations
+  @{
+*/
+
+/**
+ * @brief I2C Mode
+ */
+typedef enum
+{
+    I2C_MODE_I2C          = 0x0000, /*!< I2C mode */
+    I2C_MODE_SMBUUSDEVICE = 0x0002, /*!< SMBus device mode */
+    I2C_MODE_SMBUSHOST    = 0x000A  /*!< SMBus host mode */
+} I2C_MODE_T;
+
+/**
+ * @brief I2C duty cycle in fast mode
+ */
+typedef enum
+{
+    I2C_DUTYCYCLE_16_9 = 0x4000,    /*!< I2C fast mode Tlow/Thigh = 16/9 */
+    I2C_DUTYCYCLE_2    = 0xBFFF     /*!< I2C fast mode Tlow/Thigh = 2 */
+} I2C_DUTYCYCLE_T;
+
+/**
+ * @brief I2C acknowledgement
+ */
+typedef enum
+{
+    I2C_ACK_DISABLE,    /*!< Send acknowledge */
+    I2C_ACK_ENABLE      /*!< Do not send acknowledge */
+} I2C_ACK_T;
+
+/**
+ * @brief I2C transfer direction
+ */
+
+typedef enum
+{
+    I2C_DIRECTION_TX,   /*!< Transmitter mode */
+    I2C_DIRECTION_RX    /*!< Receiver mode */
+} I2C_DIRECTION_T;
+
+/**
+ * @brief I2C acknowledged address
+ */
+typedef enum
+{
+    I2C_ACK_ADDRESS_7BIT  = 0x4000, /*!< Set slave address length to 7-bit */
+    I2C_ACK_ADDRESS_10BIT = 0xC000  /*!< Set slave address length to 10-bit */
+} I2C_ACK_ADDRESS_T;
+
+/**
+ * @brief I2C Register
+ */
+typedef enum
+{
+    I2C_REGISTER_CTRL1,     /*!< CTRL1 register */
+    I2C_REGISTER_CTRL2,     /*!< CTRL2 register */
+    I2C_REGISTER_SADDR1,    /*!< SADDR1 register */
+    I2C_REGISTER_SADDR2,    /*!< SADDR2 register */
+    I2C_REGISTER_DATA,      /*!< DATA register */
+    I2C_REGISTER_STS1,      /*!< STS1 register */
+    I2C_REGISTER_STS2,      /*!< STS2 register */
+    I2C_REGISTER_CLKCTRL,   /*!< CLKCTRL register */
+    I2C_REGISTER_RISETMAX,  /*!< RISETMAX register */
+} I2C_REGISTER_T;
+
+/**
+ * @brief I2C NCAK position
+ */
+typedef enum
+{
+    I2C_NACK_POSITION_NEXT,     /*!< Set NACK signal to next receive byte */
+    I2C_NACK_POSITION_CURRENT   /*!< Set NACK signal to current receive byte */
+} I2C_NACK_POSITION_T;
+
+/**
+ * @brief I2C SMBus alert pin level
+ */
+typedef enum
+{
+    I2C_SMBUSALER_LOW,  /*!< SMBus Alert pin low */
+    I2C_SMBUSALER_HIGH  /*!< SMBus Alert pin high */
+} I2C_SMBUSALER_T;
+
+/**
+ * @brief I2C PEC position
+ */
+typedef enum
+{
+    I2C_PEC_POSITION_NEXT,      /*!< Indicates that the next byte is PEC */
+    I2C_PEC_POSITION_CURRENT    /*!< Indicates that current byte is PEC */
+} I2C_PEC_POSITION_T;
+
+/**
+ * @brief I2C interrupts definition
+ */
+typedef enum
+{
+    I2C_INT_BUF = 0x0400,   /*!< Buffer interrupt */
+    I2C_INT_EVT = 0x0200,   /*!< Event interrupt */
+    I2C_INT_ERR = 0x0100    /*!< Error interrupt */
+} I2C_INT_T;
+
+/**
+ * @brief I2C interrupt
+ */
+typedef enum
+{
+    I2C_INT_FLAG_SMBALT  = 0x01008000,  /*!< SMBus Alert flag */
+    I2C_INT_FLAG_TTE     = 0x01004000,  /*!< Timeout or Tlow error flag */
+    I2C_INT_FLAG_PECE    = 0x01001000,  /*!< PEC error in reception flag */
+    I2C_INT_FLAG_OVRUR   = 0x01000800,  /*!< Overrun/Underrun flag (Slave mode) */
+    I2C_INT_FLAG_AE      = 0x01000400,  /*!< Acknowledge error flag */
+    I2C_INT_FLAG_AL      = 0x01000200,  /*!< Arbitration lost flag (Master mode) */
+    I2C_INT_FLAG_BERR    = 0x01000100,  /*!< Bus error flag */
+    I2C_INT_FLAG_TXBE    = 0x06000080,  /*!< Transmitter data register empty flag */
+    I2C_INT_FLAG_RXBNE   = 0x06000040,  /*!< Receiver data register not empty flag */
+    I2C_INT_FLAG_STOP    = 0x02000010,  /*!< Stop detection flag (Slave mode) */
+    I2C_INT_FLAG_ADDR10  = 0x02000008,  /*!< 10-bit header sent flag (Master mode) */
+    I2C_INT_FLAG_BTC     = 0x02000004,  /*!< Byte transfer complete flag */
+    I2C_INT_FLAG_ADDR    = 0x02000002,  /*!< Address sent flag (Master mode) */
+    I2C_INT_FLAG_START   = 0x02000001,  /*!< Start bit flag (Master mode) */
+} I2C_INT_FLAG_T;
+
+/**
+ * @brief I2C  flags
+ */
+typedef enum
+{
+    /* STS2 register flags */
+    I2C_FLAG_DUALADDR,      /*!< Dual flag (Slave mode) */
+    I2C_FLAG_SMMHADDR,      /*!< SMBus host header (Slave mode) */
+    I2C_FLAG_SMBDADDR,      /*!< SMBus default header (Slave mode) */
+    I2C_FLAG_GENCALL,       /*!< General call header flag (Slave mode) */
+    I2C_FLAG_TR,            /*!< Transmitter/Receiver flag */
+    I2C_FLAG_BUSBSY,        /*!< Bus busy flag */
+    I2C_FLAG_MS,            /*!< Master/Slave flag */
+
+    /* STS1 register flags */
+    I2C_FLAG_SMBALT,        /*!< SMBus Alert flag */
+    I2C_FLAG_TTE,           /*!< Timeout or Tlow error flag */
+    I2C_FLAG_PECE,          /*!< PEC error in reception flag */
+    I2C_FLAG_OVRUR,         /*!< Overrun/Underrun flag (Slave mode) */
+    I2C_FLAG_AE,            /*!< Acknowledge error flag */
+    I2C_FLAG_AL,            /*!< Arbitration lost flag (Master mode) */
+    I2C_FLAG_BERR,          /*!< Bus error flag */
+    I2C_FLAG_TXBE,          /*!< Transmitter data register empty flag */
+    I2C_FLAG_RXBNE,         /*!< Receiver data register not empty flag */
+    I2C_FLAG_STOP,          /*!< Stop detection flag (Slave mode) */
+    I2C_FLAG_ADDR10,        /*!< 10-bit header sent flag (Master mode) */
+    I2C_FLAG_BTC,           /*!< Byte transfer complete flag */
+    I2C_FLAG_ADDR,          /*!< Address sent flag (Master mode) */
+    I2C_FLAG_START,         /*!< Start bit flag (Master mode) */
+} I2C_FLAG_T;
+
+/**
+ * @brief I2C Events
+ */
+typedef enum
+{
+    /* I2C Master Events */
+    /* Event 5: Communication start event */
+    I2C_EVENT_MASTER_MODE_SELECT                       = 0x00030001,  /*!< BUSBSYFLG, MSFLG and STARTFLG flag */
+
+    /* Event 6: 7-bit Address Acknowledge
+       in case of master receiver
+     */
+    I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED         = 0x00070082,  /*!< BUSBSYFLG, MSFLG, ADDRFLG, TXBEFLG and TRFLG flags */
+    I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED            = 0x00030002,  /*!< BUSBSYFLG, MSFLG and ADDRFLG flags */
+    /* Event 9: Master has sent the first byte
+       in 10-bit address mode
+     */
+    I2C_EVENT_MASTER_MODE_ADDRESS10                    = 0x00030008,  /*!< BUSBSYFLG, MSFLG and ADDR10FLG flags */
+
+    /* Master RECEIVER mode */
+    /* Event 7 */
+    I2C_EVENT_MASTER_BYTE_RECEIVED                     = 0x00030040,  /*!< BUSBSYFLG, MSFLG and RXBNEFLG flags */
+
+    /* Master TRANSMITTER mode */
+    /* Event 8 */
+    I2C_EVENT_MASTER_BYTE_TRANSMITTING                 = 0x00070080,  /*!< TRFLG, BUSBSYFLG, MSFLG, TXBEFLG flags */
+    /* Event 8_2 */
+    I2C_EVENT_MASTER_BYTE_TRANSMITTED                  = 0x00070084,  /*!< TRFLG, BUSBSYFLG, MSFLG, TXBEFLG and BTCFLG flags */
+
+
+    /* EV1 (all the events below are variants of EV1) */
+    /* 1, Case of One Single Address managed by the slave */
+    I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED           = 0x00020002, /*!< BUSBSYFLG and ADDRFLG flags */
+    I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED        = 0x00060082, /*!< TRFLG, BUSBSYFLG, TXBEFLG and ADDRFLG flags */
+
+    /* 2, Case of Dual address managed by the slave */
+    I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED     = 0x00820000, /*!< DUALF and BUSBSYFLG flags */
+    I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED  = 0x00860080, /*!< DUALF, TRFLG, BUSBSYFLG and TXBEFLG flags */
+
+    /* 3, Case of General Call enabled for the slave */
+    I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED         = 0x00120000, /*!< GENCALL and BUSBSYFLG flags */
+
+
+    /* Slave RECEIVER mode */
+    /* EV2 */
+    I2C_EVENT_SLAVE_BYTE_RECEIVED                      = 0x00020040, /*!< BUSBSYFLG and RXBNEFLG flags */
+    I2C_EVENT_SLAVE_BYTE_RECEIVED1                     = 0x00820040, /*!< DUALADDRFLG, BUSBSYFLG and RXBNEFLG flags */
+    I2C_EVENT_SLAVE_BYTE_RECEIVED2                     = 0x00120040, /*!< GENCALLFLG, BUSBSYFLG and RXBNEFLG flags */
+    /* EV4  */
+    I2C_EVENT_SLAVE_STOP_DETECTED                      = 0x00000010, /*!< STOPFLG flag */
+
+    /* Slave TRANSMITTER mode */
+    /* EV3 */
+    I2C_EVENT_SLAVE_BYTE_TRANSMITTED                   = 0x00060084, /*!< TRFLG, BUSBSYFLG, TXBEFLG and BTCFLG flags */
+    I2C_EVENT_SLAVE_BYTE_TRANSMITTED1                  = 0x00860084, /*!< DUALADDRFLG, TRFLG, BUSBSYFLG, TXBEFLG and BTCFLG flags */
+    I2C_EVENT_SLAVE_BYTE_TRANSMITTED2                  = 0x00160084, /*!< GENCALLFLG, TRFLG, BUSBSYFLG, TXBEFLG and BTCFLG flags */
+    I2C_EVENT_SLAVE_BYTE_TRANSMITTING                  = 0x00060080, /*!< TRFLG, BUSBSYFLG and TXBEFLG flags */
+    /* EV3_2 */
+    I2C_EVENT_SLAVE_ACK_FAILURE                        = 0x00000400, /*!< AEFLG flag */
+} I2C_EVENT_T;
+
+/**@} end of group I2C_Enumerations*/
+
+/** @addtogroup I2C_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief I2C Config structure definition
+ */
+typedef struct
+{
+    uint32_t            clockSpeed;     /*!< I2C clock speed */
+    I2C_MODE_T          mode;           /*!< I2C mode */
+    I2C_DUTYCYCLE_T     dutyCycle;      /*!< I2C duty cycle */
+    uint16_t            ownAddress1;    /*!< I2C own address */
+    I2C_ACK_T           ack;            /*!< Acknowledge */
+    I2C_ACK_ADDRESS_T   ackAddress;     /*!< I2C acknowledged address */
+} I2C_Config_T;
+
+/**@} end of group I2C_Structure*/
+
+/** @defgroup I2C_Functions
+  @{
+*/
+
+/* I2C reset and configuration */
+void I2C_Reset(I2C_T* i2c);
+void I2C_Config(I2C_T* i2c, I2C_Config_T* i2cConfig);
+void I2C_ConfigStructInit(I2C_Config_T* i2cConfig);
+void I2C_Enable(I2C_T* i2c);
+void I2C_Disable(I2C_T* i2c);
+void I2C_EnableGenerateStart(I2C_T* i2c);
+void I2C_DisableGenerateStart(I2C_T* i2c);
+void I2C_EnableGenerateStop(I2C_T* i2c);
+void I2C_DisableGenerateStop(I2C_T* i2c);
+void I2C_EnableAcknowledge(I2C_T* i2c);
+void I2C_DisableAcknowledge(I2C_T* i2c);
+void I2C_ConfigOwnAddress2(I2C_T* i2c, uint8_t address);
+void I2C_EnableDualAddress(I2C_T* i2c);
+void I2C_DisableDualAddress(I2C_T* i2c);
+void I2C_EnableGeneralCall(I2C_T* i2c);
+void I2C_DisableGeneralCall(I2C_T* i2c);
+void I2C_EnableSoftwareReset(I2C_T* i2c);
+void I2C_DisableSoftwareReset(I2C_T* i2c);
+void I2C_EnableStretchClock(I2C_T* i2c);
+void I2C_DisableStretchClock(I2C_T* i2c);
+void I2C_ConfigFastModeDutyCycle(I2C_T* i2c, I2C_DUTYCYCLE_T dutyCycle);
+void I2C_ConfigNACKPosition(I2C_T* i2c, I2C_NACK_POSITION_T NACKPosition);
+void I2C_ConfigSMBusAlert(I2C_T* i2c, I2C_SMBUSALER_T SMBusState);
+void I2C_EnableARP(I2C_T* i2c);
+void I2C_DisableARP(I2C_T* i2c);
+uint16_t I2C_ReadRegister(I2C_T* i2c, I2C_REGISTER_T i2cRegister);
+
+/* Transmit Configuration */
+void I2C_TxData(I2C_T* i2c, uint8_t data);
+uint8_t I2C_RxData(I2C_T* i2c);
+void I2C_Tx7BitAddress(I2C_T* i2c, uint8_t address, I2C_DIRECTION_T direction);
+
+/* PEC */
+void I2C_EnablePECTransmit(I2C_T* i2c);
+void I2C_DisablePECTransmit(I2C_T* i2c);
+void I2C_ConfigPECPosition(I2C_T* i2c, I2C_PEC_POSITION_T PECPosition);
+void I2C_EnablePEC(I2C_T* i2c);
+void I2C_DisablePEC(I2C_T* i2c);
+uint8_t I2C_ReadPEC(I2C_T* i2c);
+
+/* DMA */
+void I2C_EnableDMA(I2C_T* i2c);
+void I2C_DisableDMA(I2C_T* i2c);
+void I2C_EnableDMALastTransfer(I2C_T* i2c);
+void I2C_DisableDMALastTransfer(I2C_T* i2c);
+
+/* Interrupts and flags */
+void I2C_EnableInterrupt(I2C_T* i2c, uint16_t interrupt);
+void I2C_DisableInterrupt(I2C_T* i2c, uint16_t interrupt);
+uint8_t  I2C_ReadEventStatus(I2C_T* i2c, I2C_EVENT_T i2cEvent);
+uint32_t I2C_ReadLastEvent(I2C_T* i2c);
+uint8_t I2C_ReadStatusFlag(I2C_T* i2c, I2C_FLAG_T flag);
+void I2C_ClearStatusFlag(I2C_T* i2c, I2C_FLAG_T flag);
+uint8_t I2C_ReadIntFlag(I2C_T* i2c, I2C_INT_FLAG_T flag);
+void I2C_ClearIntFlag(I2C_T* i2c, uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_I2C_H */
+
+/**@} end of group I2C_Enumerations */
+/**@} end of group I2C_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 123 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_iwdt.h

@@ -0,0 +1,123 @@
+/*!
+ * @file        apm32f4xx_iwdt.h
+ *
+ * @brief       This file contains all the functions prototypes for the IWDT  firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_IWDT_H
+#define __APM32F4XX_IWDT_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup IWDT_Driver
+  @{
+*/
+
+/** @defgroup IWDT_Enumerations
+  @{
+*/
+
+/**
+ * @brief IWDT KEYWORD define
+ */
+typedef enum
+{
+    IWDT_KEYWORD_RELOAD = 0xAAAA,   /*!< Reload IWDT_CNTRLD register */
+    IWDT_KEYWORD_ENABLE = 0xCCCC    /*!< Activate watchdog */
+} IWDT_KEYWORD_T;
+
+/**
+ * @brief IWDT Write Access define
+ */
+typedef enum
+{
+    IWDT_WRITEACCESS_ENABLE  = 0x5555,  /*!< Allow access IWDT register */
+    IWDT_WRITEACCESS_DISABLE = 0x0000   /*!< Disable access IWDT register */
+} IWDT_WRITEACCESS_T;
+
+/**
+ * @brief IWDT Divider
+ */
+typedef enum
+{
+    IWDT_DIVIDER_4   = 0x00,    /*!< Prescaler divider equal to 4 */
+    IWDT_DIVIDER_8   = 0x01,    /*!< Prescaler divider equal to 8 */
+    IWDT_DIVIDER_16  = 0x02,    /*!< Prescaler divider equal to 16 */
+    IWDT_DIVIDER_32  = 0x03,    /*!< Prescaler divider equal to 32 */
+    IWDT_DIVIDER_64  = 0x04,    /*!< Prescaler divider equal to 64 */
+    IWDT_DIVIDER_128 = 0x05,    /*!< Prescaler divider equal to 128 */
+    IWDT_DIVIDER_256 = 0x06     /*!< Prescaler divider equal to 256 */
+} IWDT_DIVIDER_T;
+
+/**
+ * @brief IWDT Flag
+ */
+typedef enum
+{
+    IWDT_FLAG_PSCU = BIT0,  /*!< Watchdog Prescaler Factor Update flag */
+    IWDT_FLAG_CNTU = BIT1   /*!< Watchdog Counter Reload Value Update flag */
+} IWDT_FLAG_T;
+
+/**@} end of group IWDT_Enumerations*/
+
+/** @defgroup IWDT_Functions
+  @{
+*/
+
+/* Enable IWDT */
+void IWDT_Enable(void);
+
+/* Refresh IWDT */
+void IWDT_Refresh(void);
+
+/* Counter reload */
+void IWDT_ConfigReload(uint16_t reload);
+
+/* Divider */
+void IWDT_ConfigDivider(uint8_t div);
+
+/* Write Access */
+void IWDT_EnableWriteAccess(void);
+void IWDT_DisableWriteAccess(void);
+
+/* flag */
+uint8_t IWDT_ReadStatusFlag(uint16_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_IWDT_H */
+
+/**@} end of group IWDT_Enumerations */
+/**@} end of group IWDT_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 119 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_misc.h

@@ -0,0 +1,119 @@
+/*!
+ * @file        apm32f4xx_misc.h
+ *
+ * @brief       This file provides all the miscellaneous firmware functions.
+ *              Include NVIC,SystemTick and Power management.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_MISC_H
+#define __APM32F4XX_MISC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup MISC_Driver
+  @{
+*/
+
+/** @defgroup MISC_Enumerations
+  @{
+*/
+
+/**
+ * @brief NVIC Vect table
+ */
+typedef enum
+{
+    NVIC_VECT_TAB_RAM   = 0x20000000,    /*!< NVIC vector table base address launch from RAM */
+    NVIC_VECT_TAB_FLASH = 0x08000000,    /*!< NVIC vector table base address launch from flash */
+} NVIC_VECT_TAB_T;
+
+/**
+ * @brief System low power mode
+ */
+typedef enum
+{
+    NVIC_LOWPOWER_SEVONPEND   = 0x10,    /*!< Wake up according to pending request */
+    NVIC_LOWPOWER_SLEEPDEEP   = 0x04,    /*!< Enable sleep deep */
+    NVIC_LOWPOWER_SLEEPONEXIT = 0x02     /*!< Sleep after exit ISR */
+} NVIC_LOWPOWER_T;
+
+/**
+ * @brief NVIC priority group
+ */
+typedef enum
+{
+    NVIC_PRIORITY_GROUP_0 = 0x700,  /*!< 0 bits for pre-emption priority,4 bits for subpriority */
+    NVIC_PRIORITY_GROUP_1 = 0x600,  /*!< 1 bits for pre-emption priority,3 bits for subpriority */
+    NVIC_PRIORITY_GROUP_2 = 0x500,  /*!< 2 bits for pre-emption priority,2 bits for subpriority */
+    NVIC_PRIORITY_GROUP_3 = 0x400,  /*!< 3 bits for pre-emption priority,1 bits for subpriority */
+    NVIC_PRIORITY_GROUP_4 = 0x300   /*!< 4 bits for pre-emption priority,0 bits for subpriority */
+} NVIC_PRIORITY_GROUP_T;
+
+/**
+ * @brief SysTick Clock source
+ */
+typedef enum
+{
+    SYSTICK_CLK_SOURCE_HCLK_DIV8 = 0x00,    /*!< AHB clock divided by 8 selected as SysTick clock source */
+    SYSTICK_CLK_SOURCE_HCLK      = 0x01     /*!< AHB clock selected as SysTick clock source */
+} SYSTICK_CLK_SOURCE_T;
+
+/**@} end of group MISC_Enumerations*/
+
+/** @defgroup MISC_Functions
+  @{
+*/
+
+/* NVIC */
+void NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_T priorityGroup);
+void NVIC_EnableIRQRequest(IRQn_Type irq, uint8_t preemptionPriority, uint8_t subPriority);
+void NVIC_DisableIRQRequest(IRQn_Type irq);
+
+/* Vector Table */
+void NVIC_ConfigVectorTable(NVIC_VECT_TAB_T vectTab, uint32_t offset);
+
+/* Power */
+void NVIC_SetSystemLowPower(NVIC_LOWPOWER_T lowPowerMode);
+void NVIC_ResetystemLowPower(NVIC_LOWPOWER_T lowPowerMode);
+
+/* Systick */
+void SysTick_ConfigCLKSource(SYSTICK_CLK_SOURCE_T clkSource);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_MISC_H */
+
+/**@} end of group MISC_Enumerations */
+/**@} end of group MISC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 142 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_pmu.h

@@ -0,0 +1,142 @@
+/*!
+ * @file        apm32f4xx_pmu.h
+ *
+ * @brief       This file contains all the functions prototypes for the PMU firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_PMU_H
+#define __APM32F4XX_PMU_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup PMU_Driver
+  @{
+*/
+
+/** @defgroup PMU_Enumerations
+  @{
+*/
+
+/**
+ * @brief PMU PVD detection level
+ */
+typedef enum
+{
+    PMU_PVD_LEVEL_2V0    = 0x00,    /*!< PVD detection level set to 2.0V */
+    PMU_PVD_LEVEL_2V1    = 0x01,    /*!< PVD detection level set to 2.1V */
+    PMU_PVD_LEVEL_2V3    = 0x02,    /*!< PVD detection level set to 2.3V */
+    PMU_PVD_LEVEL_2V5    = 0x03,    /*!< PVD detection level set to 2.5V */
+    PMU_PVD_LEVEL_2V6    = 0x04,    /*!< PVD detection level set to 2.6V */
+    PMU_PVD_LEVEL_2V7    = 0x05,    /*!< PVD detection level set to 2.7V */
+    PMU_PVD_LEVEL_2V8    = 0x06,    /*!< PVD detection level set to 2.8V */
+    PMU_PVD_LEVEL_2V9    = 0x07,    /*!< PVD detection level set to 2.9V */
+} PMU_PVD_LEVEL_T;
+
+/**
+ * @brief PMU Regulator state in STOP mode
+ */
+typedef enum
+{
+    PMU_REGULATOR_ON       = 0x00,  /*!< STOP mode with regulator ON */
+    PMU_REGULATOR_LOWPOWER = 0x01   /*!< STOP mode with regulator in low power mode */
+} PMU_REGULATOR_T;
+
+/**
+ * @brief PMU STOP mode entry
+ */
+typedef enum
+{
+    PMU_STOP_ENTRY_WFI     = 0x01,  /*!< Enter STOP mode with WFI instruction */
+    PMU_STOP_ENTRY_WFE     = 0x02   /*!< Enter STOP mode with WFE instruction */
+} PMU_STOP_ENTRY_T;
+
+/**
+ * @brief PMU Regulator Voltage Scale
+ */
+typedef enum
+{
+    PMU_REGULATOR_VOLTAGE_SCALE1 = 0x03,    /*!< Select regulator voltage scale 1 */
+    PMU_REGULATOR_VOLTAGE_SCALE2 = 0x02,    /*!< Select regulator voltage scale 2 */
+    PMU_REGULATOR_VOLTAGE_SCALE3 = 0x01,    /*!< Select regulator voltage scale 3 */
+} PMU_REGULATOR_VOLTAGE_SCALE_T;
+
+/**
+ * @brief PMU Flag
+ */
+typedef enum
+{
+    PMU_FLAG_WUE,   /*!< Wake Up flag */
+    PMU_FLAG_SB,    /*!< StandBy flag */
+    PMU_FLAG_PVDO,  /*!< PVD Output */
+    PMU_FLAG_BKPR,  /*!< Backup regulator ready flag */
+    PMU_FLAG_VOSR   /*!< This flag indicates that the Regulator voltage
+                            scaling output selection is ready */
+} PMU_FLAG_T;
+
+/**@} end of group PMU_Enumerations*/
+
+/** @defgroup PMU_Functions
+  @{
+*/
+
+/* PMU Reset */
+void PMU_Reset(void);
+
+/* Configuration and Operation modes */
+void PMU_EnableBackupAccess(void);
+void PMU_DisableBackupAccess(void);
+void PMU_EnablePVD(void);
+void PMU_DisablePVD(void);
+void PMU_ConfigPVDLevel(PMU_PVD_LEVEL_T level);
+void PMU_EnableWakeUpPin(void);
+void PMU_DisableWakeUpPin(void);
+void PMU_EnableBackupRegulator(void);
+void PMU_DisableBackupRegulator(void);
+void PMU_ConfigMainRegulatorMode(PMU_REGULATOR_VOLTAGE_SCALE_T scale);
+void PMU_EnableFlashPowerDown(void);
+void PMU_DisableFlashPowerDown(void);
+void PMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOP_ENTRY_T entry);
+void PMU_EnterSTANDBYMode(void);
+
+/* flags */
+uint8_t PMU_ReadStatusFlag(PMU_FLAG_T flag);
+void PMU_ClearStatusFlag(PMU_FLAG_T flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_PMU_H */
+
+/**@} end of group PMU_Enumerations */
+/**@} end of group PMU_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 485 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rcm.h

@@ -0,0 +1,485 @@
+/*!
+ * @file        apm32f4xx_rcm.h
+ *
+ * @brief       This file contains all the functions prototypes for the RCM firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_RCM_H
+#define __APM32F4XX_RCM_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup RCM_Driver
+  @{
+*/
+
+/** @defgroup RCM_Enumerations
+  @{
+*/
+
+/**
+ * @brief HSE state
+ */
+typedef enum
+{
+    RCM_HSE_CLOSE,    /*!< Turn off the HSE oscillator */
+    RCM_HSE_OPEN,     /*!< Turn on the HSE oscillator */
+    RCM_HSE_BYPASS    /*!< HSE oscillator bypassed with external clock */
+} RCM_HSE_T;
+
+/**
+ * @brief LSE State
+ */
+typedef enum
+{
+    RCM_LSE_CLOSE,  /*!< Close the LSE */
+    RCM_LSE_OPEN,   /*!< Open the LSE */
+    RCM_LSE_BYPASS  /*!< LSE bypass */
+} RCM_LSE_T;
+
+/**
+ * @brief RCM PLL source select
+ */
+typedef enum
+{
+    RCM_PLLSEL_HSI, /*!< HSI oscillator clock selected as PLL clock entry */
+    RCM_PLLSEL_HSE  /*!< HSE oscillator clock selected as PLL clock entry */
+} RCM_PLLSEL_T;
+
+/**
+ * @brief RCM PLL System Division
+ */
+typedef enum
+{
+    RCM_PLL_SYS_DIV_2,  /*!< System clock Division factor is 2 */
+    RCM_PLL_SYS_DIV_4,  /*!< System clock Division factor is 4 */
+    RCM_PLL_SYS_DIV_6,  /*!< System clock Division factor is 6 */
+    RCM_PLL_SYS_DIV_8   /*!< System clock Division factor is 8 */
+} RCM_PLL_SYS_DIV_T;
+
+/**
+ * @brief RCM MCO1 Source Selece
+ */
+typedef enum
+{
+    RCM_MCO1_SEL_HSICLK,    /*!< HSI clock selected as MCO1 source */
+    RCM_MCO1_SEL_LSECLK,    /*!< LSE clock selected as MCO1 source */
+    RCM_MCO1_SEL_HSECLK,    /*!< HSE clock selected as MCO1 source */
+    RCM_MCO1_SEL_PLLCLK     /*!< Main PLL clock selected as MCO1 source */
+} RCM_MCO1_SEL_T;
+
+/**
+ * @brief RCM MCO1 Div
+ */
+typedef enum
+{
+    RCM_MCO1_DIV_1,     /*!< No division applied to MCO1 clock */
+    RCM_MCO1_DIV_2 = 4, /*!< Division by 2 applied to MCO1 clock */
+    RCM_MCO1_DIV_3,     /*!< Division by 3 applied to MCO1 clock */
+    RCM_MCO1_DIV_4,     /*!< Division by 4 applied to MCO1 clock */
+    RCM_MCO1_DIV_5      /*!< Division by 5 applied to MCO1 clock */
+} RCM_MCO1_DIV_T;
+
+/**
+ * @brief RCM MCO2 Source Selece
+ */
+typedef enum
+{
+    RCM_MCO2_SEL_SYSCLK,    /*!< SYS clock selected as MCO2 source */
+    RCM_MCO2_SEL_PLL2CLK,   /*!< PLL2 clock selected as MCO2 source */
+    RCM_MCO2_SEL_HSECLK,    /*!< HSE clock selected as MCO2 source */
+    RCM_MCO2_SEL_PLLCLK     /*!< PLL clock selected as MCO2 source */
+} RCM_MCO2_SEL_T;
+
+/**
+ * @brief RCM MCO2 Division
+ */
+typedef enum
+{
+    RCM_MCO2_DIV_1,         /*!< No division applied to MCO2 clock */
+    RCM_MCO2_DIV_2 = 4,     /*!< Division by 2 applied to MCO2 clock */
+    RCM_MCO2_DIV_3,         /*!< Division by 3 applied to MCO2 clock */
+    RCM_MCO2_DIV_4,         /*!< Division by 4 applied to MCO2 clock */
+    RCM_MCO2_DIV_5          /*!< Division by 5 applied to MCO2 clock */
+} RCM_MCO2_DIV_T;
+
+/**
+ * @brief System clock select
+ */
+typedef enum
+{
+    RCM_SYSCLK_SEL_HSI, /*!< HSI is selected as system clock source */
+    RCM_SYSCLK_SEL_HSE, /*!< HSE is selected as system clock source */
+    RCM_SYSCLK_SEL_PLL  /*!< PLL is selected as system clock source */
+} RCM_SYSCLK_SEL_T;
+
+/**
+ * @brief AHB divider Number
+ */
+typedef enum
+{
+    RCM_AHB_DIV_1 = 7,  /*!< HCLK = SYSCLK */
+    RCM_AHB_DIV_2,      /*!< HCLK = SYSCLK / 2 */
+    RCM_AHB_DIV_4,      /*!< HCLK = SYSCLK / 4 */
+    RCM_AHB_DIV_8,      /*!< HCLK = SYSCLK / 8 */
+    RCM_AHB_DIV_16,     /*!< HCLK = SYSCLK / 16 */
+    RCM_AHB_DIV_64,     /*!< HCLK = SYSCLK / 64 */
+    RCM_AHB_DIV_128,    /*!< HCLK = SYSCLK / 128 */
+    RCM_AHB_DIV_256,    /*!< HCLK = SYSCLK / 256 */
+    RCM_AHB_DIV_512     /*!< HCLK = SYSCLK / 512 */
+} RCM_AHB_DIV_T;
+
+/**
+ * @brief APB divider Number
+ */
+typedef enum
+{
+    RCM_APB_DIV_1 = 3,  /*!< PCLK1 = HCLK */
+    RCM_APB_DIV_2,      /*!< PCLK1 = HCLK / 2 */
+    RCM_APB_DIV_4,      /*!< PCLK1 = HCLK / 4 */
+    RCM_APB_DIV_8,      /*!< PCLK1 = HCLK / 8 */
+    RCM_APB_DIV_16      /*!< PCLK1 = HCLK / 16 */
+} RCM_APB_DIV_T;
+
+/**
+ * @brief SDRAM divider Number
+ */
+typedef enum
+{
+    RCM_SDRAM_DIV_1 = 0,    /*!< SDRAM clock = DMC clock */
+    RCM_SDRAM_DIV_2 = 1,    /*!< SDRAM clock = DMC clock / 2 */
+    RCM_SDRAM_DIV_4 = 2,    /*!< SDRAM clock = DMC clock / 4 */
+} RCM_SDRAM_DIV_T;
+
+/**
+ * @brief RTC clock select
+ */
+typedef enum
+{
+    RCM_RTCCLK_LSE,         /*!< RTCCLK = LSE clock */
+    RCM_RTCCLK_LSI,         /*!< RTCCLK = LSI clock */
+    RCM_RTCCLK_HSE_DIV2,    /*!< RTCCLK = HSE / 2 */
+    RCM_RTCCLK_HSE_DIV3,    /*!< RTCCLK = HSE / 3 */
+    RCM_RTCCLK_HSE_DIV4,    /*!< RTCCLK = HSE / 4 */
+    RCM_RTCCLK_HSE_DIV5,    /*!< RTCCLK = HSE / 5 */
+    RCM_RTCCLK_HSE_DIV6,    /*!< RTCCLK = HSE / 6 */
+    RCM_RTCCLK_HSE_DIV7,    /*!< RTCCLK = HSE / 7 */
+    RCM_RTCCLK_HSE_DIV8,    /*!< RTCCLK = HSE / 8 */
+    RCM_RTCCLK_HSE_DIV9,    /*!< RTCCLK = HSE / 9 */
+    RCM_RTCCLK_HSE_DIV10,   /*!< RTCCLK = HSE / 10 */
+    RCM_RTCCLK_HSE_DIV11,   /*!< RTCCLK = HSE / 11 */
+    RCM_RTCCLK_HSE_DIV12,   /*!< RTCCLK = HSE / 12 */
+    RCM_RTCCLK_HSE_DIV13,   /*!< RTCCLK = HSE / 13 */
+    RCM_RTCCLK_HSE_DIV14,   /*!< RTCCLK = HSE / 14 */
+    RCM_RTCCLK_HSE_DIV15,   /*!< RTCCLK = HSE / 15 */
+    RCM_RTCCLK_HSE_DIV16,   /*!< RTCCLK = HSE / 16 */
+    RCM_RTCCLK_HSE_DIV17,   /*!< RTCCLK = HSE / 17 */
+    RCM_RTCCLK_HSE_DIV18,   /*!< RTCCLK = HSE / 18 */
+    RCM_RTCCLK_HSE_DIV19,   /*!< RTCCLK = HSE / 19 */
+    RCM_RTCCLK_HSE_DIV20,   /*!< RTCCLK = HSE / 20 */
+    RCM_RTCCLK_HSE_DIV21,   /*!< RTCCLK = HSE / 21 */
+    RCM_RTCCLK_HSE_DIV22,   /*!< RTCCLK = HSE / 22 */
+    RCM_RTCCLK_HSE_DIV23,   /*!< RTCCLK = HSE / 23 */
+    RCM_RTCCLK_HSE_DIV24,   /*!< RTCCLK = HSE / 24 */
+    RCM_RTCCLK_HSE_DIV25,   /*!< RTCCLK = HSE / 25 */
+    RCM_RTCCLK_HSE_DIV26,   /*!< RTCCLK = HSE / 26 */
+    RCM_RTCCLK_HSE_DIV27,   /*!< RTCCLK = HSE / 27 */
+    RCM_RTCCLK_HSE_DIV28,   /*!< RTCCLK = HSE / 28 */
+    RCM_RTCCLK_HSE_DIV29,   /*!< RTCCLK = HSE / 29 */
+    RCM_RTCCLK_HSE_DIV30,   /*!< RTCCLK = HSE / 30 */
+    RCM_RTCCLK_HSE_DIV31    /*!< RTCCLK = HSE / 31 */
+} RCM_RTCCLK_T;
+
+/**
+ * @brief I2S Clock Source
+ */
+typedef enum
+{
+    RCM_I2S_CLK_PLLI2S, /*!< PLLI2S is selected as I2S clock source */
+    RCM_I2S_CLK_EXT     /*!< EXT is selected as I2S clock source */
+} RCM_I2S_CLK_T;
+
+/**
+ * @brief RCM Interrupt Source
+ */
+typedef enum
+{
+    RCM_INT_LSIRDY   = BIT0, /*!< LSI ready interrupt */
+    RCM_INT_LSERDY   = BIT1, /*!< LSE ready interrupt */
+    RCM_INT_HSIRDY   = BIT2, /*!< HSI ready interrupt */
+    RCM_INT_HSERDY   = BIT3, /*!< HSE ready interrupt */
+    RCM_INT_PLL1RDY  = BIT4, /*!< PLL1 ready interrupt */
+    RCM_INT_PLL2RDY  = BIT5, /*!< PLL2 ready interrupt */
+    RCM_INT_CSS      = BIT7  /*!< Clock security system interrupt */
+} RCM_INT_T;
+
+/**
+ * @brief AHB1 peripheral
+ */
+typedef enum
+{
+    RCM_AHB1_PERIPH_GPIOA        = BIT0,    /*!< Select GPIOA clock */
+    RCM_AHB1_PERIPH_GPIOB        = BIT1,    /*!< Select GPIOB clock */
+    RCM_AHB1_PERIPH_GPIOC        = BIT2,    /*!< Select GPIOC clock */
+    RCM_AHB1_PERIPH_GPIOD        = BIT3,    /*!< Select GPIOD clock */
+    RCM_AHB1_PERIPH_GPIOE        = BIT4,    /*!< Select GPIOE clock */
+    RCM_AHB1_PERIPH_GPIOF        = BIT5,    /*!< Select GPIOF clock */
+    RCM_AHB1_PERIPH_GPIOG        = BIT6,    /*!< Select GPIOG clock */
+    RCM_AHB1_PERIPH_GPIOH        = BIT7,    /*!< Select GPIOH clock */
+    RCM_AHB1_PERIPH_GPIOI        = BIT8,    /*!< Select GPIOI clock */
+    RCM_AHB1_PERIPH_GPIOJ        = BIT9,    /*!< Select GPIOJ clock */
+    RCM_AHB1_PERIPH_GPIOK        = BIT10,   /*!< Select GPIOK clock */
+    RCM_AHB1_PERIPH_CRC          = BIT12,   /*!< Select CRC clock */
+    RCM_AHB1_PERIPH_FLITF        = BIT15,   /*!< Select FLITF clock */
+    RCM_AHB1_PERIPH_SRAM1        = BIT16,   /*!< Select SRAM1 clock */
+    RCM_AHB1_PERIPH_SRAM2        = BIT17,   /*!< Select SRAM2 clock */
+    RCM_AHB1_PERIPH_BKPSRAM      = BIT18,   /*!< Select BKPSRAM clock */
+    RCM_AHB1_PERIPH_SRAM3        = BIT19,   /*!< Select SRAM3 clock */
+    RCM_AHB1_PERIPH_CCMDATARAMEN = BIT20,   /*!< Select CCMDATARAMEN clock */
+    RCM_AHB1_PERIPH_DMA1         = BIT21,   /*!< Select DMA1 clock */
+    RCM_AHB1_PERIPH_DMA2         = BIT22,   /*!< Select DMA2 clock */
+    RCM_AHB1_PERIPH_ETH_MAC      = BIT25,   /*!< Select ETH MAC clock */
+    RCM_AHB1_PERIPH_ETH_MAC_Tx   = BIT26,   /*!< Select ETH MAC TX clock */
+    RCM_AHB1_PERIPH_ETH_MAC_Rx   = BIT27,   /*!< Select ETH MAC RX clock */
+    RCM_AHB1_PERIPH_ETH_MAC_PTP  = BIT28,   /*!< Select ETH MAC PTP clock */
+    RCM_AHB1_PERIPH_OTG_HS       = BIT29,   /*!< Select OTG HS clock */
+    RCM_AHB1_PERIPH_OTG_HS_ULPI  = BIT30    /*!< Select OTG HS ULPI clock */
+} RCM_AHB1_PERIPH_T;
+
+/**
+ * @brief AHB2 peripheral
+ */
+typedef enum
+{
+    RCM_AHB2_PERIPH_DCI    = BIT0,  /*!< Select DCI clock */
+    RCM_AHB2_PERIPH_FPU    = BIT1,  /*!< Select FPU clock */
+    RCM_AHB2_PERIPH_BN     = BIT2,  /*!< Select BN clock */
+    RCM_AHB2_PERIPH_SM     = BIT3,  /*!< Select SM clock */
+    RCM_AHB2_PERIPH_CRYP   = BIT4,  /*!< Select CRYP clock */
+    RCM_AHB2_PERIPH_HASH   = BIT5,  /*!< Select HASH clock */
+    RCM_AHB2_PERIPH_RNG    = BIT6,  /*!< Select RNG clock */
+    RCM_AHB2_PERIPH_OTG_FS = BIT7   /*!< Select OTG FS clock */
+} RCM_AHB2_PERIPH_T;
+
+/**
+ * @brief APB1 peripheral
+ */
+typedef enum
+{
+    RCM_APB1_PERIPH_TMR2   = BIT0,              /*!< Select TMR2 clock */
+    RCM_APB1_PERIPH_TMR3   = BIT1,              /*!< Select TMR3 clock */
+    RCM_APB1_PERIPH_TMR4   = BIT2,              /*!< Select TMR4 clock */
+    RCM_APB1_PERIPH_TMR5   = BIT3,              /*!< Select TMR5 clock */
+    RCM_APB1_PERIPH_TMR6   = BIT4,              /*!< Select TMR6 clock */
+    RCM_APB1_PERIPH_TMR7   = BIT5,              /*!< Select TMR7 clock */
+    RCM_APB1_PERIPH_TMR12  = BIT6,              /*!< Select TMR12 clock */
+    RCM_APB1_PERIPH_TMR13  = BIT7,              /*!< Select TMR13 clock */
+    RCM_APB1_PERIPH_TMR14  = BIT8,              /*!< Select TMR14 clock */
+    RCM_APB1_PERIPH_WWDT   = BIT11,             /*!< Select WWDT clock */
+    RCM_APB1_PERIPH_SPI2   = BIT14,             /*!< Select SPI2 clock */
+    RCM_APB1_PERIPH_SPI3   = BIT15,             /*!< Select SPI3 clock */
+    RCM_APB1_PERIPH_USART2 = BIT17,             /*!< Select USART2 clock */
+    RCM_APB1_PERIPH_USART3 = BIT18,             /*!< Select USART3 clock */
+    RCM_APB1_PERIPH_UART4  = BIT19,             /*!< Select UART4 clock */
+    RCM_APB1_PERIPH_UART5  = BIT20,             /*!< Select UART5 clock */
+    RCM_APB1_PERIPH_I2C1   = BIT21,             /*!< Select I2C1 clock */
+    RCM_APB1_PERIPH_I2C2   = BIT22,             /*!< Select I2C2 clock */
+    RCM_APB1_PERIPH_I2C3   = BIT23,             /*!< Select I2C3 clock */
+    RCM_APB1_PERIPH_CAN1   = BIT25,             /*!< Select CAN1 clock */
+    RCM_APB1_PERIPH_CAN2   = BIT26,             /*!< Select CAN2 clock */
+    RCM_APB1_PERIPH_PMU    = BIT28,             /*!< Select PMU clock */
+    RCM_APB1_PERIPH_DAC    = BIT29,             /*!< Select DAC clock */
+    RCM_APB1_PERIPH_UART7  = BIT30,             /*!< Select UART7 clock */
+    RCM_APB1_PERIPH_UART8  = (int32_t)BIT31     /*!< Select UART8 clock */
+} RCM_APB1_PERIPH_T;
+
+/**
+ * @brief APB2 peripheral
+ */
+typedef enum
+{
+    RCM_APB2_PERIPH_TMR1   = BIT0,      /*!< Select TMR1 clock */
+    RCM_APB2_PERIPH_TMR8   = BIT1,      /*!< Select TMR8 clock */
+    RCM_APB2_PERIPH_USART1 = BIT4,      /*!< Select USART1 clock */
+    RCM_APB2_PERIPH_USART6 = BIT5,      /*!< Select USART6 clock */
+    RCM_APB2_PERIPH_ADC    = BIT8,      /*!< Select ADC clock */
+    RCM_APB2_PERIPH_ADC1   = BIT8,      /*!< Select ADC1 clock */
+    RCM_APB2_PERIPH_ADC2   = BIT9,      /*!< Select ADC2 clock */
+    RCM_APB2_PERIPH_ADC3   = BIT10,     /*!< Select ADC3 clock */
+    RCM_APB2_PERIPH_SDIO   = BIT11,     /*!< Select SDIO clock */
+    RCM_APB2_PERIPH_SPI1   = BIT12,     /*!< Select SPI1 clock */
+    RCM_APB2_PERIPH_SPI4   = BIT13,     /*!< Select SPI4 clock */
+    RCM_APB2_PERIPH_SYSCFG = BIT14,     /*!< Select SYSCFG clock */
+    RCM_APB2_PERIPH_EXTIT  = BIT15,     /*!< Select EXTIT clock */
+    RCM_APB2_PERIPH_TMR9   = BIT16,     /*!< Select TMR9 clock */
+    RCM_APB2_PERIPH_TMR10  = BIT17,     /*!< Select TMR10 clock */
+    RCM_APB2_PERIPH_TMR11  = BIT18,     /*!< Select TMR11 clock */
+    RCM_APB2_PERIPH_SPI5   = BIT20,     /*!< Select SPI5 clock */
+    RCM_APB2_PERIPH_SPI6   = BIT21,     /*!< Select SPI6 clock */
+    RCM_APB2_PERIPH_SAI1   = BIT22,     /*!< Select SAI1 clock */
+    RCM_APB2_PERIPH_LTDC   = BIT26      /*!< Select LTDC clock */
+} RCM_APB2_PERIPH_T;
+
+/**
+ * @brief RCM FLAG define
+ */
+typedef enum
+{
+    RCM_FLAG_HSIRDY  = 0x001,   /*!< HSI Ready Flag */
+    RCM_FLAG_HSERDY  = 0x011,   /*!< HSE Ready Flag */
+    RCM_FLAG_PLL1RDY = 0x019,   /*!< PLL1 Ready Flag */
+    RCM_FLAG_PLL2RDY = 0x01B,   /*!< PLL2 Ready Flag */
+
+    RCM_FLAG_LSERDY  = 0x101,   /*!< LSE Ready Flag */
+
+    RCM_FLAG_LSIRDY  = 0x201,   /*!< LSI Ready Flag */
+    RCM_FLAG_BORRST  = 0x219,   /*!< POR/PDR or BOR reset Flag */
+    RCM_FLAG_PINRST  = 0x21A,   /*!< PIN reset flag */
+    RCM_FLAG_PORRST  = 0x21B,   /*!< POR/PDR reset flag */
+    RCM_FLAG_SWRST   = 0x21C,   /*!< Software reset flag */
+    RCM_FLAG_IWDTRST = 0x21D,   /*!< Independent watchdog reset flag */
+    RCM_FLAG_WWDTRST = 0x21E,   /*!< Window watchdog reset flag */
+    RCM_FLAG_LPRRST  = 0x21F,   /*!< Low-power reset flag */
+} RCM_FLAG_T;
+
+/**@} end of group RCM_Enumerations*/
+
+/** @defgroup RCM_Functions
+  @{
+*/
+
+/* Function description */
+
+/* RCM Reset */
+void RCM_Reset(void);
+
+/* HSE clock */
+void RCM_ConfigHSE(RCM_HSE_T state);
+uint8_t RCM_WaitHSEReady(void);
+
+/* HSI clock */
+void RCM_ConfigHSITrim(uint8_t HSITrim);
+void RCM_EnableHSI(void);
+void RCM_DisableHSI(void);
+
+/* LSE and LSI clock */
+void RCM_ConfigLSE(RCM_LSE_T state);
+void RCM_EnableLSI(void);
+void RCM_DisableLSI(void);
+
+/* PLL clock */
+void RCM_ConfigPLL1(uint32_t pllSelect, uint32_t inputDiv, uint32_t vcoMul,
+                   RCM_PLL_SYS_DIV_T sysDiv, uint32_t appDiv);
+void RCM_EnablePLL1(void);
+void RCM_DisablePLL1(void);
+void RCM_ConfigPLL2(uint32_t i2sVcoMul, uint32_t i2sDiv);
+void RCM_EnablePLL2(void);
+void RCM_DisablePLL2(void);
+
+/* Clock Security System */
+void RCM_EnableCSS(void);
+void RCM_DisableCSS(void);
+
+void RCM_ConfigMCO1(RCM_MCO1_SEL_T mco1Select, RCM_MCO1_DIV_T mco1Div);
+void RCM_ConfigMCO2(RCM_MCO2_SEL_T mco2Select, RCM_MCO2_DIV_T mco2Div);
+void RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect);
+RCM_SYSCLK_SEL_T RCM_ReadSYSCLKSource(void);
+
+/* Config clock prescaler of AHB, APB1, APB2, SDRAM, USB and ADC */
+void RCM_ConfigAHB(RCM_AHB_DIV_T AHBDiv);
+void RCM_ConfigAPB1(RCM_APB_DIV_T APB1Div);
+void RCM_ConfigAPB2(RCM_APB_DIV_T APB2Div);
+void RCM_ConfigSDRAM(RCM_SDRAM_DIV_T SDRAMDiv);
+
+/* Reads the clock frequency */
+uint32_t RCM_ReadSYSCLKFreq(void);
+uint32_t RCM_ReadHCLKFreq(void);
+void RCM_ReadPCLKFreq(uint32_t* PCLK1, uint32_t* PCLK2);
+
+/* RTC clock */
+void RCM_ConfigRTCCLK(RCM_RTCCLK_T rtcClkSelect);
+void RCM_EnableRTCCLK(void);
+void RCM_DisableRTCCLK(void);
+
+/* Backup domain reset */
+void RCM_EnableBackupReset(void);
+void RCM_DisableBackupReset(void);
+
+void RCM_ConfigI2SCLK(RCM_I2S_CLK_T i2sClkSource);
+
+/* Enable or disable Periph Clock */
+void RCM_EnableAHB1PeriphClock(uint32_t AHB1Periph);
+void RCM_DisableAHB1PeriphClock(uint32_t AHB1Periph);
+void RCM_EnableAHB2PeriphClock(uint32_t AHB2Periph);
+void RCM_DisableAHB2PeriphClock(uint32_t AHB2Periph);
+void RCM_EnableAPB1PeriphClock(uint32_t APB1Periph);
+void RCM_DisableAPB1PeriphClock(uint32_t APB1Periph);
+void RCM_EnableAPB2PeriphClock(uint32_t APB2Periph);
+void RCM_DisableAPB2PeriphClock(uint32_t APB2Periph);
+
+/* Enable or disable Periph Reset */
+void RCM_EnableAHB1PeriphReset(uint32_t AHB1Periph);
+void RCM_DisableAHB1PeriphReset(uint32_t AHB1Periph);
+void RCM_EnableAHB2PeriphReset(uint32_t AHB2Periph);
+void RCM_DisableAHB2PeriphReset(uint32_t AHB2Periph);
+void RCM_EnableAPB1PeriphReset(uint32_t APB1Periph);
+void RCM_DisableAPB1PeriphReset(uint32_t APB1Periph);
+void RCM_EnableAPB2PeriphReset(uint32_t APB2Periph);
+void RCM_DisableAPB2PeriphReset(uint32_t APB2Periph);
+
+/* Enable or disable Periph clock during Low Power (Sleep) mode */
+void RCM_EnableAHB1PeriphClockLPMode(uint32_t AHB1Periph);
+void RCM_DisableAHB1PeriphClockLPMode(uint32_t AHB1Periph);
+void RCM_EnableAHB2PeriphClockLPMode(uint32_t AHB2Periph);
+void RCM_DisableAHB2PeriphClockLPMode(uint32_t AHB2Periph);
+void RCM_EnableAPB1PeriphClockLPMode(uint32_t APB1Periph);
+void RCM_DisableAPB1PeriphClockLPMode(uint32_t APB1Periph);
+void RCM_EnableAPB2PeriphClockLPMode(uint32_t APB2Periph);
+void RCM_DisableAPB2PeriphClockLPMode(uint32_t APB2Periph);
+
+/* Interrupts and flags */
+void RCM_EnableInterrupt(uint32_t interrupt);
+void RCM_DisableInterrupt(uint32_t interrupt);
+uint8_t RCM_ReadStatusFlag(RCM_FLAG_T flag);
+void RCM_ClearStatusFlag(void);
+uint8_t RCM_ReadIntFlag(RCM_INT_T flag);
+void RCM_ClearIntFlag(uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_RCM_H */
+
+/**@} end of group RCM_Enumerations */
+/**@} end of group RCM_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 98 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rng.h

@@ -0,0 +1,98 @@
+/*!
+ * @file        apm32f4xx_rng.h
+ *
+ * @brief       This file contains all the functions prototypes for the Random Number Generator(RNG) firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_RNG_H
+#define __APM32F4XX_RNG_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup RNG_Driver
+  @{
+*/
+
+/** @defgroup RNG_Enumerations
+  @{
+*/
+
+/**
+ * @brief RNG flags definition
+ */
+typedef enum
+{
+    RNG_FLAG_DATARDY    = (uint8_t)BIT0, /*!< Data ready flag */
+    RNG_FLAG_CLKERCSTS  = (uint8_t)BIT1, /*!< RNG clock error flag */
+    RNG_FLAG_FSCSTS     = (uint8_t)BIT2, /*!< Faulty sequence flag */
+}RNG_FLAG_T;
+
+/**
+ * @brief RNG interrupts definition
+ */
+ typedef enum
+{
+    RNG_INT_FLAG_CLKERINT  = (uint8_t)BIT5, /*!< RNG clock Error interrupt */
+    RNG_INT_FLAG_FSINT     = (uint8_t)BIT6, /*!< Faulty Sequence Interrupt */
+}RNG_INT_FLAG_T;
+
+/**@} end of group RNG_Enumerations*/
+
+/** @defgroup RNG_Functions
+  @{
+*/
+
+/* RNG Reset and Configuration */
+void RNG_Reset(void);
+void RNG_Enable(void);
+void RNG_Disable(void);
+
+/* Get 32 bit Random number */
+uint32_t RNG_ReadRandomNumber(void);
+
+/* Interrupts and flags */
+void EnableInterrupt(void);
+void DisableInterrupt(void);
+uint8_t RNG_ReadStatusFlag(RNG_FLAG_T flag);
+void RNG_ClearStatusFlag(uint8_t flag);
+uint8_t RNG_ReadIntFlag(RNG_INT_FLAG_T flag);
+void RNG_ClearIntFlag(uint8_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__APM32F4XX_RNG_H */
+
+/**@} end of group RNG_Enumerations */
+/**@} end of group RNG_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 597 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rtc.h

@@ -0,0 +1,597 @@
+/*!
+ * @file        apm32f4xx_rtc.h
+ *
+ * @brief       This file contains all the functions prototypes for the RTC firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_RTC_H
+#define __APM32F4XX_RTC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup RTC_Driver
+  @{
+*/
+
+/** @defgroup RTC_Enumerations
+  @{
+*/
+
+/**
+ * @brief RTC Hour Formats
+ */
+typedef enum
+{
+    RTC_HOURFORMAT_24,  /*!< 24 hour/day format */
+    RTC_HOURFORMAT_12   /*!< AM/PM hour format */
+} RTC_HOUR_FORMAT_T;
+
+/**
+ * @brief RTC Input parameter format
+ */
+typedef enum
+{
+    RTC_FORMAT_BIN, /*!< Format in BIN */
+    RTC_FORMAT_BCD  /*!< Format in BCD */
+} RTC_FORMAT_T;
+
+/**
+ * @brief RTC AM PM
+ */
+typedef enum
+{
+    RTC_H12_AM, /*!< Set RTC time to AM */
+    RTC_H12_PM  /*!< Set RTC time to PM */
+} RTC_H12_T;
+
+/**
+ * @brief RTC MONTH
+ */
+typedef enum
+{
+    RTC_MONTH_JANUARY   = 0x01, /*!< January */
+    RTC_MONTH_FEBRUARY  = 0x02, /*!< February */
+    RTC_MONTH_MARCH     = 0x03, /*!< March */
+    RTC_MONTH_APRIL     = 0x04, /*!< April */
+    RTC_MONTH_MAY       = 0x05, /*!< May */
+    RTC_MONTH_JUNE      = 0x06, /*!< June */
+    RTC_MONTH_JULY      = 0x07, /*!< July */
+    RTC_MONTH_AUGUST    = 0x08, /*!< August */
+    RTC_MONTH_SEPTEMBER = 0x09, /*!< September */
+    RTC_MONTH_OCTOBER   = 0x10, /*!< October */
+    RTC_MONTH_NOVEMBER  = 0x11, /*!< November */
+    RTC_MONTH_DECEMBER  = 0x12  /*!< December */
+} RTC_MONTH_T;
+
+/**
+ * @brief RTC WEEKDAY
+ */
+typedef enum
+{
+    RTC_WEEKDAY_MONDAY    = 0x01,   /*!< Set Monday as the weekend */
+    RTC_WEEKDAY_TUESDAY   = 0x02,   /*!< Set Tuesday as the weekend */
+    RTC_WEEKDAY_WEDNESDAY = 0x03,   /*!< Set Wednesday as the weekend */
+    RTC_WEEKDAY_THURSDAY  = 0x04,   /*!< Set Thursday as the weekend */
+    RTC_WEEKDAY_FRIDAY    = 0x05,   /*!< Set Friday as the weekend */
+    RTC_WEEKDAY_SATURDAY  = 0x06,   /*!< Set Saturday as the weekend */
+    RTC_WEEKDAY_SUNDAY    = 0x07    /*!< Set sunday as the weekend */
+} RTC_WEEKDAY_T;
+
+/**
+ * @brief RTC AlarmDateWeekDay
+ */
+typedef enum
+{
+    RTC_WEEKDAY_SEL_DATE,       /*!< Select DAYU to represent the date */
+    RTC_WEEKDAY_SEL_WEEKDAY     /*!< Select DAYU to represent the weekday */
+} RTC_WEEKDAY_SEL_T;
+
+/**
+ * @brief  RTC AlarmMask
+ */
+typedef enum
+{
+    RTC_MASK_NONE        = (uint32_t)0x00000000,    /*!< No mask */
+    RTC_MASK_DATEWEEK    = (int32_t)0x80000000,     /*!< Dateweek mask */
+    RTC_MASK_HOURS       = (uint32_t)0x00800000,    /*!< Hours mask */
+    RTC_MASK_MINUTES     = (uint32_t)0x00008000,    /*!< Minutes mask */
+    RTC_MASK_SECONDS     = (uint32_t)0x00000080,    /*!< Seconds mask */
+    RTC_MASK_ALL         = (int32_t)0x80808080      /*!< All mask  */
+} RTC_MASK_T;
+
+/**
+ * @brief RTC ALARMA ALARMB
+ */
+typedef enum
+{
+    RTC_ALARM_A = 0x0100,   /*!< Select Alarm A */
+    RTC_ALARM_B = 0x0200    /*!< Select Alarm B */
+} RTC_ALARM_T;
+
+/**
+ * @brief RTC_ALARM_SS description
+ */
+typedef enum
+{
+    RTC_ALARM_SUBSEC_MASK_ALL ,   /*!< All Alarm SUBSEC fields are masked */
+    RTC_ALARM_SUBSEC_MASK_14_1,   /*!< Mask SUBSEC[14:1] and Alarm comparison is SUBSEC[0] */
+    RTC_ALARM_SUBSEC_MASK_14_2,   /*!< Mask SUBSEC[14:2] and Alarm comparison is SUBSEC[1:0] */
+    RTC_ALARM_SUBSEC_MASK_14_3,   /*!< Mask SUBSEC[14:3] and Alarm comparison is SUBSEC[2:0] */
+    RTC_ALARM_SUBSEC_MASK_14_4,   /*!< Mask SUBSEC[14:4] and Alarm comparison is SUBSEC[3:0] */
+    RTC_ALARM_SUBSEC_MASK_14_5,   /*!< Mask SUBSEC[14:5] and Alarm comparison is SUBSEC[4:0] */
+    RTC_ALARM_SUBSEC_MASK_14_6,   /*!< Mask SUBSEC[14:6] and Alarm comparison is SUBSEC[5:0] */
+    RTC_ALARM_SUBSEC_MASK_14_7,   /*!< Mask SUBSEC[14:7] and Alarm comparison is SUBSEC[6:0] */
+    RTC_ALARM_SUBSEC_MASK_14_8,   /*!< Mask SUBSEC[14:8] and Alarm comparison is SUBSEC[7:0] */
+    RTC_ALARM_SUBSEC_MASK_14_9,   /*!< Mask SUBSEC[14:9] and Alarm comparison is SUBSEC[8:0] */
+    RTC_ALARM_SUBSEC_MASK_14_10,  /*!< Mask SUBSEC[14:10] and Alarm comparison is SUBSEC[9:0] */
+    RTC_ALARM_SUBSEC_MASK_14_11,  /*!< Mask SUBSEC[14:11] and Alarm comparison is SUBSEC[10:0] */
+    RTC_ALARM_SUBSEC_MASK_14_12,  /*!< Mask SUBSEC[14:12] and Alarm comparison is SUBSEC[11:0] */
+    RTC_ALARM_SUBSEC_MASK_14_13,  /*!< Mask SUBSEC[14:13] and Alarm comparison is SUBSEC[12:0] */
+    RTC_ALARM_SUBSEC_MASK_14,     /*!< Mask SUBSEC[14] and Alarm comparison is SUBSEC[13:0] */
+    RTC_ALARM_SUBSEC_MASK_NONE    /*!< Alarm comparison is all the SUBSEC bit */
+} RTC_ALARM_SUBSEC_MASK_T;
+
+/**
+ * @brief RTC Wakeup clock select
+ */
+typedef enum
+{
+    RTC_WAKEUP_CLOCK_RTC_DIV16   = 0x00, /*!<  Wakeup Clock select to RTC/16 */
+    RTC_WAKEUP_CLOCK_RTC_DIV8    = 0x01, /*!<  Wakeup Clock select to RTC/8 */
+    RTC_WAKEUP_CLOCK_RTC_DIV4    = 0x02, /*!<  Wakeup Clock select to RTC/4 */
+    RTC_WAKEUP_CLOCK_RTC_DIV2    = 0x03, /*!<  Wakeup Clock select to RTC/2 */
+    RTC_WAKEUP_CLOCK_CK_SPRE_16B = 0x04, /*!<  Wakeup Clock select to clk_spre */
+    RTC_WAKEUP_CLOCK_CK_SPRE_17B = 0x06  /*!<  Wakeup Clock select to clk_spre */
+} RTC_WAKEUP_CLOCK_T;
+
+/**
+ * @brief RTC Time Stamp Edges
+ */
+typedef enum
+{
+    RTC_TIMESTAMP_EDGE_RISING,  /*!< Rising edge generates a timestamp event */
+    RTC_TIMESTAMP_EDGE_FALLING  /*!< Falling edge generates a timestamp event */
+} RTC_TIMESTAMP_EDGE_T;
+
+/**
+ * @brief RTC Output selection
+ */
+typedef enum
+{
+    RTC_OUT_SEL_DISABLE,    /*!< Disable RTC output */
+    RTC_OUT_SEL_ALARM_A,    /*!< Select alarm A as RTC output */
+    RTC_OUT_SEL_ALARM_B,    /*!< Select alarm B as RTC output */
+    RTC_OUT_SEL_WAKEUP      /*!< Select wake up as RTC output */
+} RTC_OUT_SEL_T;
+
+/**
+ * @brief RTC Output Polarity
+ */
+typedef enum
+{
+    RTC_OUT_POLARITY_HIGH,  /*!< The output polarity is high */
+    RTC_OUT_POLARITY_LOW    /*!< The output polarity is low */
+} RTC_OUT_POLARITY_T;
+
+/**
+ * @brief RTC Digital Calibration sign
+ */
+typedef enum
+{
+    RTC_CALIB_SIGN_POSITIVE,    /*!< The Calibration sign is positive */
+    RTC_CALIB_SIGN_NEGATIVE     /*!< The Calibration sign is negative */
+} RTC_CALIB_SIGN_T;
+
+/**
+ * @brief RTC Calibration Output selection
+ */
+typedef enum
+{
+    RTC_CALIB_OUTPUT_512HZ, /*!< Calibration output is 512 Hz */
+    RTC_CALIB_OUTPUT_1HZ    /*!< Calibration output is 1 Hz */
+} RTC_CALIB_OUTPUT_T;
+
+/**
+ * @brief RTC Smooth Calibration period
+ */
+typedef enum
+{
+    RTC_SCP_32SEC, /*!< if RTCCLK is 32768 Hz, Smooth calibration period will be 32s,
+                        else 2exp20 RTCCLK seconds */
+    RTC_SCP_16SEC, /*!< if RTCCLK is 32768 Hz, Smooth calibration period will be 16s,
+                        else 2exp19 RTCCLK seconds */
+    RTC_SCP_8SEC   /*!< if RTCCLK is 32768 Hz, Smooth calibration period will be 8s,
+                        else 2exp18 RTCCLK seconds */
+} RTC_SCP_T;
+
+/**
+ * @brief  RTC Smooth Calibration Plus pulses
+ */
+typedef enum
+{
+    RTC_SCPP_RESET, /*!< Add one RTCCLK puls every 2**11 pulses */
+    RTC_SCPP_SET    /*!< No RTCCLK pulses are added */
+} RTC_SCPP_T;
+
+/**
+ * @brief RTC DayLight Saving
+ */
+typedef enum
+{
+    RTC_DLS_SUB_1H, /*!< Winter time change */
+    RTC_DLS_ADD_1H  /*!< Summer time change */
+} RTC_DLS_T;
+
+/**
+ * @brief RTC Store Operation to Backup bit
+ */
+typedef enum
+{
+    RTC_BACKUP_RESET,   /*!< Reset backup value */
+    RTC_BACKUP_SET      /*!< Set backup value */
+} RTC_BACKUP_T;
+
+/**
+ * @brief RTC Tamper Trigger
+ */
+typedef enum
+{
+    RTC_TAMPER_TRIGGER_EDGE_RISING  = 0,    /*!< Rising Edge of the tamper pin causes tamper event */
+    RTC_TAMPER_TRIGGER_EDGE_FALLING = 1,    /*!< Falling Edge of the tamper pin causes tamper event */
+    RTC_TAMPER_TRIGGER_LEVEL_LOW    = 0,    /*!< Low Level of the tamper pin causes tamper event */
+    RTC_TAMPER_TRIGGER_LEVEL_HIGH   = 1     /*!< High Level of the tamper pin causes tamper event */
+} RTC_TAMPER_TRIGGER_T;
+
+/**
+ * @brief Tampers Filter
+ */
+typedef enum
+{
+    RTC_TAMPER_FILTER_DISABLE,  /*!< Tamper filter is disabled */
+    RTC_TAMPER_FILTER_2SAMPLE,  /*!< Tamper is activated after 2 consecutive samples at the active level */
+    RTC_TAMPER_FILTER_4SAMPLE,  /*!< Tamper is activated after 4 consecutive samples at the active level */
+    RTC_TAMPER_FILTER_8SAMPLE   /*!< Tamper is activated after 8 consecutive samples at the active level */
+} RTC_TAMPER_FILTER_T;
+
+/**
+ * @brief Tampers Sampling Frequency
+ */
+typedef enum
+{
+    RTC_TSF_DIV_32768, /*!< Tampers Sampling Frequency = RTC_CLK / 32768 */
+    RTC_TSF_DIV_16384, /*!< Tampers Sampling Frequency = RTC_CLK / 16384 */
+    RTC_TSF_DIV_8192,  /*!< Tampers Sampling Frequency = RTC_CLK / 8192 */
+    RTC_TSF_DIV_4096,  /*!< Tampers Sampling Frequency = RTC_CLK / 4096 */
+    RTC_TSF_DIV_2048,  /*!< Tampers Sampling Frequency = RTC_CLK / 2048 */
+    RTC_TSF_DIV_1024,  /*!< Tampers Sampling Frequency = RTC_CLK / 1024 */
+    RTC_TSF_DIV_512,   /*!< Tampers Sampling Frequency = RTC_CLK / 512 */
+    RTC_TSF_DIV_256    /*!< Tampers Sampling Frequency = RTC_CLK / 256 */
+} RTC_TSF_DIV_T;
+
+/**
+ * @brief Tamper Precharge Duration
+ */
+typedef enum
+{
+    RTC_TPD_RTCCLK_1, /*!< Duration is 1 RTCCLK cycle */
+    RTC_TPD_RTCCLK_2, /*!< Duration is 2 RTCCLK cycle */
+    RTC_TPD_RTCCLK_4, /*!< Duration is 4 RTCCLK cycle */
+    RTC_TPD_RTCCLK_8  /*!< Duration is 8 RTCCLK cycle */
+} RTC_TPD_RTCCLK_T;
+
+/**
+ * @brief RTC Tamper Pin Selection
+ */
+typedef enum
+{
+    RTC_TAMPER_PIN_AF1, /*!< RTC_TAMP1 is mapped to PC13 */
+    RTC_TAMPER_PIN_AF2  /*!< RTC_TAMP1 is mapped to PI8 */
+} RTC_TAMPER_PIN_T;
+
+/**
+ * @brief RTC TimeStamp Pin Selection
+ */
+typedef enum
+{
+    RTC_TIMESTAMP_PIN_AF1, /*!< TimeStamp Pin is mapped to PC13 */
+    RTC_TIMESTAMP_PIN_AF2  /*!< TimeStamp Pin is mapped to PI8 */
+} RTC_TIMESTAMP_PIN_T;
+
+/**
+ * @brief RTC Output Type ALARM OUT
+ */
+typedef enum
+{
+    RTC_OUTPUT_OD, /*!< RTC_ALARM output Open-drain */
+    RTC_OUTPUT_PP  /*!< RTC_ALARM output Push-pull */
+} RTC_OUTPUT_T;
+
+/**
+ * @brief RTC Add 1 Second Parameter
+ */
+typedef enum
+{
+    RTC_SHIFT_ADD1S_RESET,  /*!< No effect */
+    RTC_SHIFT_ADD1S_SET     /*!< Add one second to the clock calendar */
+} RTC_SHIFT_ADD1S_T;
+
+/**
+ * @brief RTC_Backup register
+ */
+typedef enum
+{
+    RTC_BAKP_REG_0,  /*!< Backup register 0 */
+    RTC_BAKP_REG_1,  /*!< Backup register 1 */
+    RTC_BAKP_REG_2,  /*!< Backup register 2 */
+    RTC_BAKP_REG_3,  /*!< Backup register 3 */
+    RTC_BAKP_REG_4,  /*!< Backup register 4 */
+    RTC_BAKP_REG_5,  /*!< Backup register 5 */
+    RTC_BAKP_REG_6,  /*!< Backup register 6 */
+    RTC_BAKP_REG_7,  /*!< Backup register 7 */
+    RTC_BAKP_REG_8,  /*!< Backup register 8 */
+    RTC_BAKP_REG_9,  /*!< Backup register 9 */
+    RTC_BAKP_REG_10, /*!< Backup register 10 */
+    RTC_BAKP_REG_11, /*!< Backup register 11 */
+    RTC_BAKP_REG_12, /*!< Backup register 12 */
+    RTC_BAKP_REG_13, /*!< Backup register 13 */
+    RTC_BAKP_REG_14, /*!< Backup register 14 */
+    RTC_BAKP_REG_15, /*!< Backup register 15 */
+    RTC_BAKP_REG_16, /*!< Backup register 16 */
+    RTC_BAKP_REG_17, /*!< Backup register 17 */
+    RTC_BAKP_REG_18, /*!< Backup register 18 */
+    RTC_BAKP_REG_19  /*!< Backup register 19 */
+} RTC_BAKP_REG_T;
+
+/**
+ * @brief RTC flag
+ */
+typedef enum
+{
+    RTC_FLAG_AAWF  = BIT0,  /*!< Alarm A Write Flag */
+    RTC_FLAG_ABWF  = BIT1,  /*!< Alarm B Write Flag */
+    RTC_FLAG_WTWF  = BIT2,  /*!< Wakeup Timer Write Flag */
+    RTC_FLAG_SOPF  = BIT3,  /*!< Shift Operation Pending Flag */
+    RTC_FLAG_ISF   = BIT4,  /*!< Initialization State Flag */
+    RTC_FLAG_RSF   = BIT5,  /*!< Registers Synchronization Flag */
+    RTC_FLAG_INTF  = BIT6,  /*!< Register Initialization Flag */
+    RTC_FLAG_ALRAF = BIT8,  /*!< Alarm A Match Flag */
+    RTC_FLAG_ALRBF = BIT9,  /*!< Alarm B Match Flag */
+    RTC_FLAG_WTF   = BIT10, /*!< Wakeup Timer Flag */
+    RTC_FLAG_TSF   = BIT11, /*!< Time Stamp Flag */
+    RTC_FLAG_TSOF  = BIT12, /*!< Time Stamp Overflow Flag */
+    RTC_FLAG_TP1F  = BIT13, /*!< Tamper 1 event Detection Flag */
+    RTC_FLAG_TP2F  = BIT14, /*!< Tamper 2 event Detection Flag */
+    RTC_FLAG_RPF   = BIT16  /*!< Recalibration Pending Flag */
+} RTC_FLAG_T;
+
+/**
+ * @brief RTC Interrupts  Flag
+ */
+typedef enum
+{
+    RTC_INT_FLAG_ALRA  = (uint32_t)0x00001000, /*!< Alarm A interrupt flag */
+    RTC_INT_FLAG_ALRB  = (uint32_t)0x00002000, /*!< Alarm B interrupt flag */
+    RTC_INT_FLAG_WT    = (uint32_t)0x00004000, /*!< Time Stamp interrupt flag */
+    RTC_INT_FLAG_TS    = (uint32_t)0x00008000, /*!< WakeUp Timer interrupt flag */
+    RTC_INT_FLAG_TAMP1 = (uint32_t)0x00020001, /*!< Tamper1 event interrupt flag */
+    RTC_INT_FLAG_TAMP2 = (uint32_t)0x00040001  /*!< Tamper2 event interrupt flag */
+} RTC_INT_FLAG_T;
+
+/**
+ * @brief RTC Interrupts
+ */
+typedef enum
+{
+    RTC_INT_ALRA = BIT12, /*!< Alarm A interrupt */
+    RTC_INT_ALRB = BIT13, /*!< Alarm B interrupt */
+    RTC_INT_WT   = BIT14, /*!< WakeUp Timer interrupt */
+    RTC_INT_TS   = BIT15, /*!< Time Stamp interrupt */
+    RTC_INT_TAMP = BIT2   /*!< Tamper Interrupt in TACFG register */
+} RTC_INT_T;
+
+/**
+ * @brief Selected RTC Tamper Pin
+ */
+typedef enum
+{
+    RTC_TAMPER_1,   /*!< Select Tamper 1 */
+    RTC_TAMPER_2    /*!< Select Tamper 2 */
+} RTC_TAMPER_T;
+
+/**@} end of group RTC_Enumerations*/
+
+/** @addtogroup RTC_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief  RTC Init structures definition
+ */
+typedef struct
+{
+    RTC_HOUR_FORMAT_T format;       /*!< RTC hour formats selection */
+    uint32_t          asynchPrediv; /*!< Asynchronous prescaler coefficient setting */
+    uint32_t          synchPrediv;  /*!< Synchronous prescaler coefficient setting */
+} RTC_Config_T;
+
+/**
+  * @brief  RTC Time structure definition
+  */
+typedef struct
+{
+    uint8_t   hours;    /*!< Set hours of RTC time */
+    uint8_t   minutes;  /*!< Set minutes of RTC time */
+    uint8_t   seconds;  /*!< Set seconds of RTC time */
+    RTC_H12_T h12;      /*!< Set RTC time to AM or PM */
+} RTC_TimeConfig_T;
+
+/**
+  * @brief  RTC Date structure definition
+  */
+typedef struct
+{
+    RTC_WEEKDAY_T weekday;  /*!< Set weekday of RTC date */
+    RTC_MONTH_T   month;    /*!< Set month of RTC date */
+    uint8_t       date;     /*!< Set date of RTC date */
+    uint8_t       year;     /*!< Set year of RTC date */
+} RTC_DateConfig_T;
+
+/**
+  * @brief  RTC ALRMA structure definition
+  */
+typedef struct
+{
+    RTC_TimeConfig_T  time;                 /*!< Set RTC time */
+    uint32_t          alarmMask;            /*!< Set alarm mask */
+    RTC_WEEKDAY_SEL_T alarmDateWeekDaySel;  /*!< Set weekday's DAYU of alarm date */
+    uint8_t           alarmDateWeekDay;     /*!< Set weekday of alarm date */
+} RTC_AlarmConfig_T;
+
+/**@} end of group RTC_Structure*/
+
+/** @addtogroup RTC_Functions
+  @{
+*/
+
+/* RTC reset */
+uint8_t RTC_Reset(void);
+
+/* Initialization and Configuration */
+uint8_t RTC_Config(RTC_Config_T* rtcConfig);
+void RTC_ConfigStructInit(RTC_Config_T* rtcConfig);
+void RTC_EnableWriteProtection(void);
+void RTC_DisableWriteProtection(void);
+uint8_t RTC_EnableInit(void);
+void RTC_DisableInit(void);
+uint8_t RTC_WaitForSynchro(void);
+uint8_t RTC_EnableRefClock(void);
+uint8_t RTC_DisableRefClock(void);
+void RTC_EnableBypassShadow(void);
+void RTC_DisableBypassShadow(void);
+
+/* Time */
+uint8_t RTC_ConfigTime(RTC_FORMAT_T format, RTC_TimeConfig_T* timeConfig);
+void RTC_ConfigTimeStructInit(RTC_TimeConfig_T* timeConfig);
+void RTC_ReadTime(RTC_FORMAT_T format, RTC_TimeConfig_T* time);
+uint32_t RTC_ReadSubSecond(void);
+
+/* Date */
+uint8_t RTC_ConfigDate(RTC_FORMAT_T format, RTC_DateConfig_T* dateConfig);
+void RTC_ConfigDateStructInit(RTC_DateConfig_T* dateConfig);
+void RTC_ReadDate(RTC_FORMAT_T format, RTC_DateConfig_T* date);
+
+/* Alarms (Alarm A and Alarm B)*/
+void RTC_ConfigAlarm(RTC_FORMAT_T format, RTC_ALARM_T alarm, RTC_AlarmConfig_T* alarmConfig);
+void RTC_ConfigAlarmStructInit(RTC_AlarmConfig_T* alarmConfig);
+void RTC_ReadAlarm(RTC_FORMAT_T format, RTC_ALARM_T alarm, RTC_AlarmConfig_T* alarmConfig);
+void RTC_EnableAlarmA(void);
+uint8_t RTC_DisableAlarmA(void);
+void RTC_EnableAlarmB(void);
+uint8_t RTC_DisableAlarmB(void);
+void RTC_ConfigAlarmSubSecond(RTC_ALARM_T alarm, uint32_t val, RTC_ALARM_SUBSEC_MASK_T mask);
+uint16_t RTC_ReadAlarmSubSecond(RTC_ALARM_T alarm);
+
+/* WakeUp Timer */
+void RTC_ConfigWakeUpClock(RTC_WAKEUP_CLOCK_T wakeUpClock);
+void RTC_ConfigWakeUpValue(uint16_t wakeUpValue);
+uint16_t RTC_ReadWakeUpValue(void);
+void RTC_EnableWakeUp(void);
+uint8_t RTC_DisableWakeUp(void);
+
+/* Daylight Saving */
+void RTC_ConfigDayLightSaving(RTC_DLS_T saving, RTC_BACKUP_T bit);
+uint8_t RTC_ReadStoreOperation(void);
+
+/* Alarm Output */
+void RTC_ConfigOutput(RTC_OUT_SEL_T outputSel, RTC_OUT_POLARITY_T polarity);
+
+/* Coarse Digital Calibration */
+uint8_t RTC_ConfigCoarseCalib(RTC_CALIB_SIGN_T calibSign, uint32_t value);
+uint8_t RTC_EnableCoarseCalib(void);
+uint8_t RTC_DisableCoarseCalib(void);
+
+/* Calibration Output */
+void RTC_EnableCalibOutput(void);
+void RTC_DisableCalibOutput(void);
+void RTC_ConfigCalibOutput(RTC_CALIB_OUTPUT_T calib);
+
+/* Smooth Digital Calibration */
+uint8_t RTC_ConfigSmoothCalib(RTC_SCP_T period, RTC_SCPP_T calibPulse, uint16_t value);
+
+/* TimeStamp */
+void RTC_EnableTimeStamp(RTC_TIMESTAMP_EDGE_T edge);
+void RTC_DisableTimeStamp(void);
+void RTC_ReadTimeDate(RTC_FORMAT_T format, RTC_TimeConfig_T* time, RTC_DateConfig_T* date);
+uint16_t RTC_ReadTimeStampSubSecond(void);
+
+/* Tamper */
+void RTC_ConfigTamperTrigger(RTC_TAMPER_T tamper, RTC_TAMPER_TRIGGER_T trigger);
+void RTC_EnableTamper(RTC_TAMPER_T tamper);
+void RTC_DisableTamper(RTC_TAMPER_T tamper);
+void RTC_ConfigFilter(RTC_TAMPER_FILTER_T filter);
+void RTC_ConfigSamplingFreq(RTC_TSF_DIV_T freq);
+void RTC_PinsPrechargeDuration(RTC_TPD_RTCCLK_T duration);
+void RTC_EnableTDE(void);
+void RTC_DisableTDE(void);
+void RTC_EnablePullUp(void);
+void RTC_DisablePullUp(void);
+
+/* Backup Data Registers */
+void RTC_WriteBackup(RTC_BAKP_REG_T backupReg, uint32_t data);
+uint32_t RTC_ReadBackup(RTC_BAKP_REG_T backup);
+
+/* Tamper and TimeStamp Pins mapping */
+void RTC_ConfigTamperPin(RTC_TAMPER_PIN_T tamperPin);
+void RTC_ConfigTimeStampPin(RTC_TIMESTAMP_PIN_T timeStampPin);
+/* Output Type */
+void RTC_ConfigOutputType(RTC_OUTPUT_T outputType);
+
+/* Shift control synchonisation */
+uint8_t RTC_ConfigSynchroShift(RTC_SHIFT_ADD1S_T add1S, uint16_t subFS);
+
+/* Interrupts and flags */
+void RTC_EnableInterrupt(uint32_t interrupt);
+void RTC_DisableInterrupt(uint32_t interrupt);
+uint8_t RTC_ReadStatusFlag(RTC_FLAG_T flag);
+void RTC_ClearStatusFlag(uint32_t flag);
+uint8_t RTC_ReadIntFlag(RTC_INT_FLAG_T flag);
+void RTC_ClearIntFlag(uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_RTC_H */
+
+/**@} end of group RTC_Enumerations */
+/**@} end of group RTC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 377 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_sdio.h

@@ -0,0 +1,377 @@
+/*!
+ * @file        apm32f4xx_sdio.h
+ *
+ * @brief       This file contains all the functions prototypes for the SDIO firmware
+ *              library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_SDIO_H
+#define __APM32F4XX_SDIO_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup SDIO_Driver
+  @{
+*/
+
+/** @defgroup SDIO_Enumerations
+  @{
+*/
+
+/**
+ * @brief SDIO clock edge
+ */
+typedef enum
+{
+    SDIO_CLOCK_EDGE_RISING, /*!< Select rising edge of SDIOCLK to generate SDIO_CLK */
+    SDIO_CLOCK_EDGE_FALLING /*!< Select falling edge of SDIOCLK to generate SDIO_CLK */
+} SDIO_CLOCK_EDGE_T;
+
+/**
+ * @brief SDIO clock bypass
+ */
+typedef enum
+{
+    SDIO_CLOCK_BYPASS_DISABLE,  /*!< Disable divider bypass */
+    SDIO_CLOCK_BYPASS_ENABLE    /*!< Enable divider bypass */
+} SDIO_CLOCK_BYPASS_T;
+
+/**
+ * @brief    SDIO clock power save
+ */
+typedef enum
+{
+    SDIO_CLOCK_POWER_SAVE_DISABLE,  /*!< Disable power saving mode */
+    SDIO_CLOCK_POWER_SAVE_ENABLE    /*!< Enable power saving mode */
+} SDIO_CLOCK_POWER_SAVE_T;
+
+/**
+ * @brief SDIO bus wide
+ */
+typedef enum
+{
+    SDIO_BUS_WIDE_1B,   /*!< 1-bit wide bus mode */
+    SDIO_BUS_WIDE_4B,   /*!< 4-bit wide bus mode */
+    SDIO_BUS_WIDE_8B    /*!< 8-bit wide bus mode */
+} SDIO_BUS_WIDE_T;
+
+/**
+ * @brief SDIO hardware flow control
+ */
+typedef enum
+{
+    SDIO_HARDWARE_FLOW_CONTROL_DISABLE, /*!< Disable hardware flow control */
+    SDIO_HARDWARE_FLOW_CONTROL_ENABLE   /*!< Enable hardware flow control */
+} SDIO_HARDWARE_FLOW_CONTROL_T;
+
+/**
+ * @brief SDIO power state
+ */
+typedef enum
+{
+    SDIO_POWER_STATE_OFF = 0x00,    /*!< Power off */
+    SDIO_POWER_STATE_ON  = 0x03     /*!< Power on */
+} SDIO_POWER_STATE_T;
+
+/**
+ * @brief SDIO response
+ */
+typedef enum
+{
+    SDIO_RESPONSE_NO    = (uint8_t)0x00,    /*!< No response */
+    SDIO_RESPONSE_SHORT = (uint8_t)0x01,    /*!< Short response */
+    SDIO_RESPONSE_LONG  = (uint8_t)0x03     /*!< Long response */
+} SDIO_RESPONSE_T;
+
+/**
+ * @brief SDIO wait interrupt state
+ */
+typedef enum
+{
+    SDIO_WAIT_NO   = (uint8_t)0x00, /*!< No wait */
+    SDIO_WAIT_INT  = (uint8_t)0x01, /*!< Wait interrupt request */
+    SDIO_WAIT_PEND = (uint8_t)0x02  /*!< Wait CmdPend */
+} SDIO_WAIT_T;
+
+/**
+ * @brief SDIO CPSM state
+ */
+typedef enum
+{
+    SDIO_CPSM_DISABLE,  /*!< Disable CPSM */
+    SDIO_CPSM_ENABLE    /*!< Enable CPSM */
+} SDIO_CPSM_T;
+
+/**
+ * @brief SDIO response registers
+ */
+typedef enum
+{
+    SDIO_RES1 = ((uint8_t)0x00),    /*!< Response Register 1 */
+    SDIO_RES2 = ((uint8_t)0x04),    /*!< Response Register 2 */
+    SDIO_RES3 = ((uint8_t)0x08),    /*!< Response Register 3 */
+    SDIO_RES4 = ((uint8_t)0x0C)     /*!< Response Register 4 */
+} SDIO_RES_T;
+
+/**
+ * @brief SDIO data block size
+ */
+typedef enum
+{
+    SDIO_DATA_BLOCKSIZE_1B,     /*!< block size = 1 byte */
+    SDIO_DATA_BLOCKSIZE_2B,     /*!< block size = 2 bytes */
+    SDIO_DATA_BLOCKSIZE_4B,     /*!< block size = 4 bytes */
+    SDIO_DATA_BLOCKSIZE_8B,     /*!< block size = 8 bytes */
+    SDIO_DATA_BLOCKSIZE_16B,    /*!< block size = 16 bytes */
+    SDIO_DATA_BLOCKSIZE_32B,    /*!< block size = 32 bytes */
+    SDIO_DATA_BLOCKSIZE_64B,    /*!< block size = 64 bytes */
+    SDIO_DATA_BLOCKSIZE_128B,   /*!< block size = 128 bytes */
+    SDIO_DATA_BLOCKSIZE_256B,   /*!< block size = 256 bytes */
+    SDIO_DATA_BLOCKSIZE_512B,   /*!< block size = 512 bytes */
+    SDIO_DATA_BLOCKSIZE_1024B,  /*!< block size = 1024 bytes */
+    SDIO_DATA_BLOCKSIZE_2048B,  /*!< block size = 2048 bytes */
+    SDIO_DATA_BLOCKSIZE_4096B,  /*!< block size = 4096 bytes */
+    SDIO_DATA_BLOCKSIZE_8192B,  /*!< block size = 8192 bytes */
+    SDIO_DATA_BLOCKSIZE_16384B  /*!< block size = 16384 bytes */
+} SDIO_DATA_BLOCKSIZE_T;
+
+/**
+ * @brief SDIO transfer direction
+ */
+typedef enum
+{
+    SDIO_TRANSFER_DIR_TO_CARD,  /*!< Controller to SD card */
+    SDIO_TRANSFER_DIR_TO_SDIO   /*!< SD card to controller */
+} SDIO_TRANSFER_DIR_T;
+
+/**
+ * @brief SDIO transfer type
+ */
+typedef enum
+{
+    SDIO_TRANSFER_MODE_BLOCK,   /*!< Block data mode */
+    SDIO_TRANSFER_MODE_STREAM   /*!< Stream data mode */
+} SDIO_TRANSFER_MODE_T;
+
+/**
+ * @brief SDIO DPSM state
+ */
+typedef enum
+{
+    SDIO_DPSM_DISABLE,  /*!< Disable DPSM */
+    SDIO_DPSM_ENABLE    /*!< Enable DPSM */
+} SDIO_DPSM_T;
+
+/**
+ * @brief SDIO flag
+ */
+typedef enum
+{
+    SDIO_FLAG_COMRESP  = ((uint32_t)0x00000001),    /*!< Command response received (CRC check failed) flag */
+    SDIO_FLAG_DBDR     = ((uint32_t)0x00000002),    /*!< Data block sent/received (CRC check failed) flag */
+    SDIO_FLAG_CMDRESTO = ((uint32_t)0x00000004),    /*!< Command response timeout flag */
+    SDIO_FLAG_DATATO   = ((uint32_t)0x00000008),    /*!< Data timeout flag */
+    SDIO_FLAG_TXUDRER  = ((uint32_t)0x00000010),    /*!< Transmit FIFO underrun error flag */
+    SDIO_FLAG_RXOVRER  = ((uint32_t)0x00000020),    /*!< Received FIFO overrun error flag */
+    SDIO_FLAG_CMDRES   = ((uint32_t)0x00000040),    /*!< Command response received (CRC check passed) flag */
+    SDIO_FLAG_CMDSENT  = ((uint32_t)0x00000080),    /*!< Command sent (no response required) flag */
+    SDIO_FLAG_DATAEND  = ((uint32_t)0x00000100),    /*!< Data end (data counter is zero) flag */
+    SDIO_FLAG_SBE      = ((uint32_t)0x00000200),    /*!< Start bit not detected on all data signals in wide bus mode flag */
+    SDIO_FLAG_DBCP     = ((uint32_t)0x00000400),    /*!< Data block sent/received (CRC check passed) flag */
+    SDIO_FLAG_CMDACT   = ((uint32_t)0x00000800),    /*!< Command transfer in progress flag */
+    SDIO_FLAG_TXACT    = ((uint32_t)0x00001000),    /*!< Data transmit in progress flag */
+    SDIO_FLAG_RXACT    = ((uint32_t)0x00002000),    /*!< Data receive in progress flag */
+    SDIO_FLAG_TXFHF    = ((uint32_t)0x00004000),    /*!< Transmit FIFO Half Empty flag */
+    SDIO_FLAG_RXFHF    = ((uint32_t)0x00008000),    /*!< Receive FIFO Half Full flag */
+    SDIO_FLAG_TXFF     = ((uint32_t)0x00010000),    /*!< Transmit FIFO full flag */
+    SDIO_FLAG_RXFF     = ((uint32_t)0x00020000),    /*!< Receive FIFO full flag */
+    SDIO_FLAG_TXFE     = ((uint32_t)0x00040000),    /*!< Transmit FIFO empty flag */
+    SDIO_FLAG_RXFE     = ((uint32_t)0x00080000),    /*!< Receive FIFO empty flag */
+    SDIO_FLAG_TXDA     = ((uint32_t)0x00100000),    /*!< Data available in transmit FIFO flag */
+    SDIO_FLAG_RXDA     = ((uint32_t)0x00200000),    /*!< Data available in receive FIFO flag */
+    SDIO_FLAG_SDIOINT  = ((uint32_t)0x00400000),    /*!< SD I/O interrupt received flag */
+    SDIO_FLAG_ATAEND   = ((uint32_t)0x00800000)     /*!< CE-ATA command completion signal received for CMD61 flag */
+} SDIO_FLAG_T;
+
+/**
+ * @brief SDIO interrupt sources
+ */
+typedef enum
+{
+    SDIO_INT_COMRESP  = ((uint32_t)0x00000001), /*!< Command response received (CRC check failed) interrupt */
+    SDIO_INT_DBDR     = ((uint32_t)0x00000002), /*!< Data block sent/received (CRC check failed) interrupt */
+    SDIO_INT_CMDRESTO = ((uint32_t)0x00000004), /*!< Command response timeout interrupt */
+    SDIO_INT_DATATO   = ((uint32_t)0x00000008), /*!< Data timeout interrupt */
+    SDIO_INT_TXUDRER  = ((uint32_t)0x00000010), /*!< Transmit FIFO underrun error interrupt */
+    SDIO_INT_RXOVRER  = ((uint32_t)0x00000020), /*!< Received FIFO overrun error interrupt */
+    SDIO_INT_CMDRES   = ((uint32_t)0x00000040), /*!< Command response received (CRC check passed) interrupt */
+    SDIO_INT_CMDSENT  = ((uint32_t)0x00000080), /*!< Command sent (no response required) interrupt */
+    SDIO_INT_DATAEND  = ((uint32_t)0x00000100), /*!< Data end (data counter, SDIDCOUNT, is zero) interrupt */
+    SDIO_INT_SBE      = ((uint32_t)0x00000200), /*!< Start bit not detected on all data signals in wide bus mode interrupt */
+    SDIO_INT_DBCP     = ((uint32_t)0x00000400), /*!< Data block sent/received (CRC check passed) interrupt */
+    SDIO_INT_CMDACT   = ((uint32_t)0x00000800), /*!< Command transfer in progress interrupt */
+    SDIO_INT_TXACT    = ((uint32_t)0x00001000), /*!< Data transmit in progress interrupt */
+    SDIO_INT_RXACT    = ((uint32_t)0x00002000), /*!< Data receive in progress interrupt */
+    SDIO_INT_TXFHF    = ((uint32_t)0x00004000), /*!< Transmit FIFO Half Empty interrupt */
+    SDIO_INT_RXFHF    = ((uint32_t)0x00008000), /*!< Receive FIFO Half Full interrupt */
+    SDIO_INT_TXFF     = ((uint32_t)0x00010000), /*!< Transmit FIFO full interrupt */
+    SDIO_INT_RXFF     = ((uint32_t)0x00020000), /*!< Receive FIFO full interrupt */
+    SDIO_INT_TXFE     = ((uint32_t)0x00040000), /*!< Transmit FIFO empty interrupt */
+    SDIO_INT_RXFE     = ((uint32_t)0x00080000), /*!< Receive FIFO empty interrupt */
+    SDIO_INT_TXDA     = ((uint32_t)0x00100000), /*!< Data available in transmit FIFO interrupt */
+    SDIO_INT_RXDA     = ((uint32_t)0x00200000), /*!< Data available in receive FIFO interrupt */
+    SDIO_INT_SDIOINT  = ((uint32_t)0x00400000), /*!< SD I/O interrupt received interrupt */
+    SDIO_INT_ATAEND   = ((uint32_t)0x00800000)  /*!< CE-ATA command completion signal received for CMD61 interrupt */
+} SDIO_INT_T;
+
+/**
+ * @brief SDIO read wait mode
+ */
+typedef enum
+{
+    SDIO_READ_WAIT_MODE_DATA2,  /*!< Read Wait control using SDIO_DATA2 */
+    SDIO_READ_WAIT_MODE_CLK     /*!< Read Wait control by stopping SDIOCLK */
+} SDIO_READ_WAIT_MODE_T;
+
+/**@} end of group SDIO_Enumerations*/
+
+/** @addtogroup SDIO_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief SDIO Config structure definition
+ */
+typedef struct
+{
+    SDIO_CLOCK_EDGE_T            clockEdge;           /*!< Specifies the clock transition on which the bit capture is made */
+    SDIO_CLOCK_BYPASS_T          clockBypass;         /*!< Specifies whether the SDIO Clock divider bypass is enabled or disabled */
+    SDIO_CLOCK_POWER_SAVE_T      clockPowerSave;      /*!< Specifies whether SDIO Clock output is enabled or disabled when the bus is idle */
+    SDIO_BUS_WIDE_T              busWide;             /*!< Specifies the SDIO bus width */
+    SDIO_HARDWARE_FLOW_CONTROL_T hardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled */
+    uint8_t                      clockDiv;            /*!< This parameter can be a value between 0x00 and 0xFF */
+} SDIO_Config_T;
+
+/**
+ * @brief SDIO Command Config structure definition
+ */
+typedef struct
+{
+    uint32_t           argument; /*!< Specifies the SDIO command argument which is sentto a card as part of a command message.
+                                        If a command contains an argument, it must be loaded into this register before writing
+                                        the command to the command register */
+    uint32_t           cmdIndex; /*!< It must be lower than 0x40 */
+    SDIO_RESPONSE_T    response; /*!< SDIO response */
+    SDIO_WAIT_T        wait;     /*!< Specifies whether SDIO wait for interrupt request */
+    SDIO_CPSM_T        CPSM;     /*!< Specifies whether SDIO Command path state machine (CPSM) */
+} SDIO_CmdConfig_T;
+
+/**
+ * @brief SDIO Data Config
+ */
+typedef struct
+{
+    uint32_t              dataTimeOut;      /*!< SDIO data timeout period */
+    uint32_t              dataLength;       /*!< SDIO data length */
+    SDIO_DATA_BLOCKSIZE_T dataBlockSize;    /*!< SDIO data block size */
+    SDIO_TRANSFER_DIR_T   transferDir;      /*!< SDIO transfer direction */
+    SDIO_TRANSFER_MODE_T  transferMode;     /*!< SDIO transfer type */
+    SDIO_DPSM_T           DPSM;             /*!< Specifies whether SDIO Data path state machine(DPSM) */
+} SDIO_DataConfig_T;
+
+/**@} end of group SDIO_Structure*/
+
+/** @defgroup SDIO_Functions
+  @{
+*/
+
+/* SDIO reset and configuration */
+void SDIO_Reset(void);
+void SDIO_Config(SDIO_Config_T* sdioConfig);
+void SDIO_ConfigStructInit(SDIO_Config_T* sdioConfig);
+void SDIO_EnableClock(void);
+void SDIO_DisableClock(void);
+void SDIO_ConfigPowerState(SDIO_POWER_STATE_T powerState);
+uint32_t SDIO_ReadPowerState(void);
+
+/* DMA */
+void SDIO_EnableDMA(void);
+void SDIO_DisableDMA(void);
+
+/* Command */
+void SDIO_TxCommand(SDIO_CmdConfig_T *cmdConfig);
+void SDIO_TxCommandStructInit(SDIO_CmdConfig_T* cmdconfig);
+uint8_t SDIO_ReadCommandResponse(void);
+uint32_t SDIO_ReadResponse(SDIO_RES_T res);
+
+/* SDIO data configuration */
+void SDIO_ConfigData(SDIO_DataConfig_T* dataConfig);
+void SDIO_ConfigDataStructInit(SDIO_DataConfig_T* dataConfig);
+uint32_t SDIO_ReadDataCounter(void);
+void SDIO_WriteData(uint32_t data);
+uint32_t SDIO_ReadData(void);
+uint32_t SDIO_ReadFIFOCount(void);
+
+/* SDIO mode */
+void SDIO_EnableStartReadWait(void);
+void SDIO_DisableStartReadWait(void);
+void SDIO_EnableStopReadWait(void);
+void SDIO_DisableStopReadWait(void);
+void SDIO_ConfigSDIOReadWaitMode(SDIO_READ_WAIT_MODE_T readWaitMode);
+void SDIO_EnableSDIO(void);
+void SDIO_DisableSDIO(void);
+void SDIO_EnableTxSDIOSuspend(void);
+void SDIO_DisableTxSDIOSuspend(void);
+void SDIO_EnableCommandCompletion(void);
+void SDIO_DisableCommandCompletion(void);
+void SDIO_EnableCEATAInterrupt(void);
+void SDIO_DisableCEATAInterrupt(void);
+void SDIO_EnableTxCEATA(void);
+void SDIO_DisableTxCEATA(void);
+
+/* Interrupt and flags */
+void SDIO_EnableInterrupt(uint32_t interrupt);
+void SDIO_DisableInterrupt(uint32_t interrupt);
+uint8_t SDIO_ReadStatusFlag(SDIO_FLAG_T flag);
+void SDIO_ClearStatusFlag(uint32_t flag);
+uint8_t SDIO_ReadIntFlag(SDIO_INT_T flag);
+void SDIO_ClearIntFlag(uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_SDIO_H */
+
+/**@} end of group SDIO_Enumerations */
+/**@} end of group SDIO_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 370 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_smc.h

@@ -0,0 +1,370 @@
+/*!
+ * @file        apm32f4xx_smc.h
+ *
+ * @brief       This file contains all the functions prototypes for the SMC firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_SMC_H
+#define __APM32F4XX_SMC_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup SMC_Driver
+  @{
+*/
+
+/** @defgroup SMC_Enumerations
+  @{
+*/
+
+/**
+ * @brief SMC NORSRAM Bank
+ */
+typedef enum
+{
+    SMC_BANK1_NORSRAM_1,    /*!< SMC Bank1 NOR/SRAM1 */
+    SMC_BANK1_NORSRAM_2,    /*!< SMC Bank1 NOR/SRAM2 */
+    SMC_BANK1_NORSRAM_3,    /*!< SMC Bank1 NOR/SRAM3 */
+    SMC_BANK1_NORSRAM_4     /*!< SMC Bank1 NOR/SRAM4 */
+} SMC_BANK1_NORSRAM_T;
+
+/**
+ * @brief SMC NAND and PC Card Bank
+ */
+typedef enum
+{
+    SMC_BANK2_NAND,     /*!< SMC Bank2 NAND */
+    SMC_BANK3_NAND,     /*!< SMC Bank3 NAND */
+    SMC_BANK4_PCCARD    /*!< SMC Bank4 PCCARD */
+} SMC_BANK_NAND_T;
+
+/**
+ * @brief SMC_Data_Address_Bus_Multiplexing
+ */
+typedef enum
+{
+    SMC_DATA_ADDRESS_MUX_DISABLE,   /*!< Disable data address multiplexing */
+    SMC_DATA_ADDRESS_MUX_ENABLE     /*!< Enable data address multiplexing */
+} SMC_DATA_ADDRESS_MUX_T;
+
+/**
+ * @brief SMC_Memory_Type
+ */
+typedef enum
+{
+    SMC_MEMORY_TYPE_SRAM,   /*!< SRAM memory */
+    SMC_MEMORY_TYPE_PSRAM,  /*!< PSRAM memory */
+    SMC_MEMORY_TYPE_NOR     /*!< NORFlash memory */
+} SMC_MEMORY_TYPE_T;
+
+/**
+ * @brief SMC_Data_Width
+ */
+typedef enum
+{
+    SMC_MEMORY_DATA_WIDTH_8BIT, /*!< Set memory data width to 8-bit */
+    SMC_MEMORY_DATA_WIDTH_16BIT /*!< Set memory data width to 16-bit */
+} SMC_MEMORY_DATA_WIDTH_T;
+
+/**
+ * @brief SMC_Burst_Access_Mode
+ */
+typedef enum
+{
+    SMC_BURST_ACCESS_MODE_DISABLE,  /*!< Disable burst access mode */
+    SMC_BURST_ACCESS_MODE_ENABLE    /*!< Enable burst access mode */
+} SMC_BURST_ACCESS_MODE_T;
+
+/**
+ * @brief SMC_AsynchronousWait
+ */
+typedef enum
+{
+    SMC_ASYNCHRONOUS_WAIT_DISABLE,  /*!< Disable asynchronous wait */
+    SMC_ASYNCHRONOUS_WAIT_ENABLE    /*!< Enable asynchronous wait */
+} SMC_ASYNCHRONOUS_WAIT_T;
+
+/**
+ * @brief SMC_Wait_Signal_Polarity
+ */
+typedef enum
+{
+    SMC_WAIT_SIGNAL_POLARITY_LOW,   /*!< Set low polarity valid */
+    SMC_WAIT_SIGNAL_POLARITY_HIGH   /*!< Set high polarity valid */
+} SMC_WAIT_SIGNAL_POLARITY_T;
+
+/**
+ * @brief SMC Wrapped burst Mode
+ */
+typedef enum
+{
+    SMC_WRAP_MODE_DISABLE,  /*!< Disable wrapped burst mode */
+    SMC_WRAP_MODE_ENABLE    /*!< Enable wrapped burst mode */
+} SMC_WRAP_MODE_T;
+
+/**
+ * @brief SMC Wait Timing
+ */
+typedef enum
+{
+    SMC_WAIT_SIGNAL_ACTIVE_BEFORE_WAIT_STATE,   /*!< Set wait active before wait state */
+    SMC_WAIT_SIGNAL_ACTIVE_DURING_WAIT_STATE    /*!< Set wait active during wait state */
+} SMC_WAIT_SIGNAL_ACTIVE_T;
+
+/**
+ * @brief SMC Write Operation
+ */
+typedef enum
+{
+    SMC_WRITE_OPERATION_DISABLE,    /*!< Disable write operation */
+    SMC_WRITE_OPERATION_ENABLE      /*!< Enable write operation  */
+} SMC_WRITE_OPERATION_T;
+
+/**
+ * @brief SMC Wait Signal
+ */
+typedef enum
+{
+    SMC_WAITE_SIGNAL_DISABLE,   /*!< Disable wait signal */
+    SMC_WAITE_SIGNAL_ENABLE     /*!< Enable wait signal */
+} SMC_WAITE_SIGNAL_T;
+
+/**
+ * @brief SMC Extended Mode
+ */
+typedef enum
+{
+    SMC_EXTENDEN_MODE_DISABLE,  /*!< Disable extended mode */
+    SMC_EXTENDEN_MODE_ENABLE    /*!< Enable extended mode */
+} SMC_EXTENDEN_MODE_T;
+
+/**
+ * @brief SMC Write Burst
+ */
+typedef enum
+{
+    SMC_WRITE_BURST_DISABLE,    /*!< Disable write PSRAM burst */
+    SMC_WRITE_BURST_ENABLE      /*!< Enable write PSRAM burst */
+} SMC_WRITE_BURST_T;
+
+/**
+ * @brief SMC WAIT FEATURE
+ */
+typedef enum
+{
+    SMC_WAIT_FEATURE_DISABLE,   /*!< Disable wait feature */
+    SMC_WAIT_FEATURE_ENABLE     /*!< Enable wait feature */
+} SMC_WAIT_FEATURE_T;
+
+/**
+ * @brief SMC ECC
+ */
+typedef enum
+{
+    SMC_ECC_DISABLE,    /*!< Disable ECC */
+    SMC_ECC_ENABLE      /*!< Enable ECC */
+} SMC_ECC_T;
+
+/**
+ * @brief SMC ECC Page Size
+ */
+typedef enum
+{
+    SMC_ECC_PAGE_SIZE_BYTE_256,     /*!< ECC page size = 256 bytes */
+    SMC_ECC_PAGE_SIZE_BYTE_512,     /*!< ECC page size = 512 bytes */
+    SMC_ECC_PAGE_SIZE_BYTE_1024,    /*!< ECC page size = 1024 bytes */
+    SMC_ECC_PAGE_SIZE_BYTE_2048,    /*!< ECC page size = 2048 bytes */
+    SMC_ECC_PAGE_SIZE_BYTE_4096,    /*!< ECC page size = 4096 bytes */
+    SMC_ECC_PAGE_SIZE_BYTE_8192     /*!< ECC page size = 8192 bytes */
+} SMC_ECC_PAGE_SIZE_BYTE_T;
+
+/**
+ * @brief SMC Access Mode
+ */
+typedef enum
+{
+    SMC_ACCESS_MODE_A,  /*!< Access mode A */
+    SMC_ACCESS_MODE_B,  /*!< Access mode B */
+    SMC_ACCESS_MODE_C,  /*!< Access mode C */
+    SMC_ACCESS_MODE_D   /*!< Access mode D */
+} SMC_ACCESS_MODE_T;
+
+/**
+ * @brief SMC Interrupt sources
+ */
+typedef enum
+{
+    SMC_INT_EDGE_RISING  = 0x00000008,  /*!< Rising edge detection interrupt */
+    SMC_INT_LEVEL_HIGH   = 0x00000010,  /*!< High level detection interrupt */
+    SMC_INT_EDGE_FALLING = 0x00000020   /*!< Falling edge detection interrupt */
+} SMC_INT_T;
+
+/**
+ * @brief SMC Flags
+ */
+typedef enum
+{
+    SMC_FLAG_EDGE_RISING  = 0x00000001, /*!< Rising egde detection Flag */
+    SMC_FLAG_LEVEL_HIGH   = 0x00000002, /*!< High level detection Flag */
+    SMC_FLAG_EDGE_FALLING = 0x00000004, /*!< Falling egde detection Flag */
+    SMC_FLAG_FIFO_EMPTY   = 0x00000040  /*!< FIFO empty Flag */
+} SMC_FLAG_T;
+
+/**@} end of group SMC_Enumerations*/
+
+/** @addtogroup SMC_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief Timing parameters for NOR/SRAM Banks
+ */
+typedef struct
+{
+    uint8_t           addressSetupTime;     /*!< Set address setup time */
+    uint8_t           addressHodeTime;      /*!< Set address-hold setup time */
+    uint8_t           dataSetupTime;        /*!< Set data setup time */
+    uint8_t           busTurnaroundTime;    /*!< Set bus turnaround time */
+    uint8_t           clockDivision;        /*!< Set clock divide radio */
+    uint8_t           dataLatency;          /*!< Set data latency */
+    SMC_ACCESS_MODE_T accessMode;           /*!< Set access mode */
+} SMC_NORSRAMTimingConfig_T;
+
+/**
+ * @brief SMC NOR/SRAM Config structure
+ */
+typedef struct
+{
+    SMC_BANK1_NORSRAM_T        bank;                    /*!< NORSRAM bank selection */
+    SMC_DATA_ADDRESS_MUX_T     dataAddressMux;          /*!< Data address bus multiplexing selection */
+    SMC_MEMORY_TYPE_T          memoryType;              /*!< Memory type selection */
+    SMC_MEMORY_DATA_WIDTH_T    memoryDataWidth;         /*!< Data width selection */
+    SMC_BURST_ACCESS_MODE_T    burstAcceesMode;         /*!< Set burst access mode */
+    SMC_ASYNCHRONOUS_WAIT_T    asynchronousWait;        /*!< Set asynchronous wait */
+    SMC_WAIT_SIGNAL_POLARITY_T waitSignalPolarity;      /*!< Set wait signal polarity */
+    SMC_WRAP_MODE_T            wrapMode;                /*!< Set wrapped burst mode */
+    SMC_WAIT_SIGNAL_ACTIVE_T   waitSignalActive;        /*!< Set wait timing */
+    SMC_WRITE_OPERATION_T      writeOperation;          /*!< Set write operation */
+    SMC_WAITE_SIGNAL_T         waiteSignal;             /*!< Set wait signal */
+    SMC_EXTENDEN_MODE_T        extendedMode;            /*!< Set extended mode */
+    SMC_WRITE_BURST_T          writeBurst;              /*!< Set write burst */
+    SMC_NORSRAMTimingConfig_T* readWriteTimingStruct;   /*!< Read and write timing */
+    SMC_NORSRAMTimingConfig_T* writeTimingStruct;       /*!< Write timing */
+} SMC_NORSRAMConfig_T;
+
+/**
+ * @brief Timing parameters for NAND and PCCARD Banks
+ */
+typedef struct
+{
+    uint8_t setupTime;      /*!< Set setup address time( 0x01 ~ 0xFE ) */
+    uint8_t waitSetupTime;  /*!< Set assert the command time ( 0x01 ~ 0xFE ) */
+    uint8_t holdSetupTime;  /*!< Set hold address time ( 0x01 ~ 0xFE ) */
+    uint8_t HiZSetupTime;   /*!< Set the time of keep in HiZ ( 0x00 ~ 0xFE ) */
+} SMC_NAND_PCCARDTimingConfig_T;
+
+/**
+ * @brief SMC NAND Config structure
+ */
+typedef struct
+{
+    SMC_BANK_NAND_T                bank;                        /*!< SMC NAND and PC Card Bank */
+    SMC_WAIT_FEATURE_T             waitFeature;                 /*!< Set wait feature */
+    SMC_MEMORY_DATA_WIDTH_T        memoryDataWidth;             /*!< Data width selection */
+    SMC_ECC_T                      ECC;                         /*!< Set ECC */
+    SMC_ECC_PAGE_SIZE_BYTE_T       ECCPageSize;                 /*!< Set ECC page size */
+    uint8_t                        TCLRSetupTime;               /*!< Set the delay time of CLE to RE */
+    uint8_t                        TARSetupTime;                /*!< Set the delay time of ALE to RE */
+    SMC_NAND_PCCARDTimingConfig_T* commonSpaceTimingStruct;     /*!< Common space timing */
+    SMC_NAND_PCCARDTimingConfig_T* attributeSpaceTimingStruct;  /*!< Attribute space timing */
+} SMC_NANDConfig_T;
+
+/**
+ * @brief SMC PCCARD Config structure
+ */
+typedef struct
+{
+    SMC_WAIT_FEATURE_T             waitFeature;                 /*!< Set wait feature */
+    uint32_t                       TCLRSetupTime;               /*!< Set the delay time of CLE to RE */
+    uint32_t                       TARSetupTime;                /*!< Set the delay time of ALE to RE */
+    SMC_NAND_PCCARDTimingConfig_T* commonSpaceTimingStruct;     /*!< Common space timing */
+    SMC_NAND_PCCARDTimingConfig_T* attributeSpaceTimingStruct;  /*!< Attribute space timing */
+    SMC_NAND_PCCARDTimingConfig_T* IOSpaceTimingStruct;         /*!< IO space timing */
+} SMC_PCCARDConfig_T;
+
+/**@} end of group SMC_Structure*/
+
+/** @defgroup SMC_Functions
+  @{
+*/
+
+/* SMC reset */
+void SMC_ResetNORSRAM(SMC_BANK1_NORSRAM_T bank);
+void SMC_ResetNAND(SMC_BANK_NAND_T bank);
+void SMC_ResetPCCard(void);
+
+/* SMC Configuration */
+void SMC_ConfigNORSRAM(SMC_NORSRAMConfig_T* smcNORSRAMConfig);
+void SMC_ConfigNAND(SMC_NANDConfig_T* smcNANDConfig);
+void SMC_ConfigPCCard(SMC_PCCARDConfig_T* smcPCCardConfig);
+void SMC_ConfigNORSRAMStructInit(SMC_NORSRAMConfig_T* smcNORSRAMConfig);
+void SMC_ConfigNANDStructInit(SMC_NANDConfig_T* smcNANDConfig);
+void SMC_ConfigPCCardStructInit(SMC_PCCARDConfig_T* smcPCCardConfig);
+
+/* SMC bank control */
+void SMC_EnableNORSRAM(SMC_BANK1_NORSRAM_T bank);
+void SMC_DisableNORSRAM(SMC_BANK1_NORSRAM_T bank);
+void SMC_EnableNAND(SMC_BANK_NAND_T bank);
+void SMC_DisableNAND(SMC_BANK_NAND_T bank);
+void SMC_EnablePCCARD(void);
+void SMC_DisablePCCARD(void);
+void SMC_EnableNANDECC(SMC_BANK_NAND_T bank);
+void SMC_DisableNANDECC(SMC_BANK_NAND_T bank);
+uint32_t SMC_ReadECC(SMC_BANK_NAND_T bank);
+
+/* Interrupt and flag */
+void SMC_EnableInterrupt(SMC_BANK_NAND_T bank, uint32_t interrupt);
+void SMC_DisableInterrupt(SMC_BANK_NAND_T bank, uint32_t interrupt);
+uint16_t SMC_ReadStatusFlag(SMC_BANK_NAND_T bank, SMC_FLAG_T flag);
+void SMC_ClearStatusFlag(SMC_BANK_NAND_T bank, uint32_t flag);
+uint16_t SMC_ReadIntFlag(SMC_BANK_NAND_T bank, SMC_INT_T flag);
+void SMC_ClearIntFlag(SMC_BANK_NAND_T bank, uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_SMC_H */
+
+/**@} end of group SMC_Enumerations */
+/**@} end of group SMC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 346 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_spi.h

@@ -0,0 +1,346 @@
+/*!
+ * @file        apm32f4x_spi.h
+ *
+ * @brief       This file contains all the functions prototypes for the SPI firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_SPI_H
+#define __APM32F4XX_SPI_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup SPI_Driver
+  @{
+*/
+
+/** @defgroup SPI_Enumerations
+  @{
+*/
+
+/**
+ * @brief   SPI data direction mode
+ *
+ * @note    BIT0 refer to 1 line or 2 lines
+ *          BIT4 refer to Tx or Rx in 1 line
+ *          BIT8 refer to receive only or full-duplex in 2 lines
+ */
+typedef enum
+{
+    SPI_DIRECTION_2LINES_FULLDUPLEX = 0x0000,   /*!< 2 lines full duplex */
+    SPI_DIRECTION_2LINES_RXONLY     = 0x0100,   /*!< 2 lines but receive only */
+    SPI_DIRECTION_1LINE_RX          = 0x0001,   /*!< 1 line receive only */
+    SPI_DIRECTION_1LINE_TX          = 0x0011    /*!< 1 line send only */
+} SPI_DIRECTION_T;
+
+/**
+ * @brief SPI mode
+ */
+typedef enum
+{
+    SPI_MODE_SLAVE,     /*!< Slave mode */
+    SPI_MODE_MASTER     /*!< Master mode */
+} SPI_MODE_T;
+
+/**
+ * @brief SPI Data length
+ */
+typedef enum
+{
+    SPI_DATA_LENGTH_8B, /*!< Set data frame format to 8bit */
+    SPI_DATA_LENGTH_16B /*!< Set data frame format to 16bit */
+} SPI_DATA_LENGTH_T;
+
+/**
+ * @brief SPI Clock Polarity
+ */
+typedef enum
+{
+    SPI_CLKPOL_LOW,     /*!< Set SCK polarity to low in idle state */
+    SPI_CLKPOL_HIGH     /*!< Set SCK polarity to high in idle state */
+} SPI_CLKPOL_T;
+
+/**
+ * @brief SPI Clock Phase
+ */
+typedef enum
+{
+    SPI_CLKPHA_1EDGE,   /*!< Sample value in the first clock edge */
+    SPI_CLKPHA_2EDGE    /*!< Sample value in the second clock edge */
+} SPI_CLKPHA_T;
+
+/**
+ * @brief SPI Slave Select management
+ */
+typedef enum
+{
+    SPI_NSS_HARD,   /*!< Disable software NSS mode */
+    SPI_NSS_SOFT    /*!< Enable software NSS mode */
+} SPI_NSS_T;
+
+/**
+ * @brief SPI BaudRate Prescaler
+ */
+typedef enum
+{
+    SPI_BAUDRATE_DIV_2,     /*!< BaudRate DIV = 2 */
+    SPI_BAUDRATE_DIV_4,     /*!< BaudRate DIV = 4 */
+    SPI_BAUDRATE_DIV_8,     /*!< BaudRate DIV = 8 */
+    SPI_BAUDRATE_DIV_16,    /*!< BaudRate DIV = 16 */
+    SPI_BAUDRATE_DIV_32,    /*!< BaudRate DIV = 32 */
+    SPI_BAUDRATE_DIV_64,    /*!< BaudRate DIV = 64 */
+    SPI_BAUDRATE_DIV_128,   /*!< BaudRate DIV = 128 */
+    SPI_BAUDRATE_DIV_256,   /*!< BaudRate DIV = 256 */
+} SPI_BAUDRATE_DIV_T;
+
+/**
+ * @brief SPI MSB LSB transmission
+ */
+typedef enum
+{
+    SPI_FIRSTBIT_MSB,   /*!< MSB first */
+    SPI_FIRSTBIT_LSB    /*!< LSB first */
+} SPI_FIRSTBIT_T;
+
+/**
+ * @brief I2S Mode
+ */
+typedef enum
+{
+    I2S_MODE_SLAVE_TX,  /*!< Slave transmit mode */
+    I2S_MODE_SLAVE_RX,  /*!< Slave receive mode */
+    I2S_MODE_MASTER_TX, /*!< Master transmit mode */
+    I2S_MODE_MASTER_RX  /*!< Master receive mode */
+} I2S_MODE_T;
+
+/**
+ * @brief I2S Standard
+ */
+typedef enum
+{
+    I2S_STANDARD_PHILLIPS = 0x00,   /*!< I2S phillips mode */
+    I2S_STANDARD_MSB      = 0x01,   /*!< MSB alignment mode */
+    I2S_STANDARD_LSB      = 0x02,   /*!< LSB alignment mode */
+    I2S_STANDARD_PCMSHORT = 0x03,   /*!< PCB short frame synchronization mode */
+    I2S_STANDARD_PCMLONG  = 0x13    /*!< PCB long frame synchronization mode */
+} I2S_STANDARD_T;
+
+/**
+ * @brief I2S data length
+ */
+typedef enum
+{
+    I2S_DATA_LENGHT_16B   = 0x00,   /*!< Set the length of data to 16-bit */
+    I2S_DATA_LENGHT_16BEX = 0x01,   /*!< Set the length of data to 16-bit extended */
+    I2S_DATA_LENGHT_24B   = 0x03,   /*!< Set the length of data to 24-bit */
+    I2S_DATA_LENGHT_32B   = 0x05,   /*!< Set the length of data to 32-bit */
+} I2S_DATA_LENGTH_T;
+
+/**
+ * @brief I2S MCLK Output
+ */
+typedef enum
+{
+    I2S_MCLK_OUTPUT_DISABLE,    /*!< Disable I2S MCLK output */
+    I2S_MCLK_OUTPUT_ENABLE      /*!< Enable I2S MCLK output */
+} I2S_MCLK_OUTPUT_T;
+
+/**
+ * @brief I2S Audio divider
+ */
+typedef enum
+{
+    I2S_AUDIO_DIV_192K    = 192000, /*!< Audio div = 192K */
+    I2S_AUDIO_DIV_96K     = 96000,  /*!< Audio div = 96K */
+    I2S_AUDIO_DIV_48K     = 48000,  /*!< Audio div = 48K */
+    I2S_AUDIO_DIV_44K     = 44100,  /*!< Audio div = 44.1K */
+    I2S_AUDIO_DIV_32K     = 32000,  /*!< Audio div = 32K */
+    I2S_AUDIO_DIV_22K     = 22050,  /*!< Audio div = 22.05K */
+    I2S_AUDIO_DIV_16K     = 16000,  /*!< Audio div = 16K */
+    I2S_AUDIO_DIV_11K     = 11025,  /*!< Audio div = 11.025K */
+    I2S_AUDIO_DIV_8K      = 8000,   /*!< Audio div = 8K */
+    I2S_AUDIO_DIV_DEFAULT = 2       /*!< Audio div = 2 */
+} I2S_AUDIO_DIV_T;
+
+/**
+ * @brief I2S Clock Polarity
+ */
+typedef enum
+{
+    I2S_CLKPOL_LOW,     /*!< Set clock polarity to low */
+    I2S_CLKPOL_HIGH     /*!< Set clock polarity to high */
+} I2S_CLKPOL_T;
+
+/**
+ * @brief SPI I2S DMA requests
+ */
+typedef enum
+{
+    SPI_I2S_DMA_REQ_TX, /*!< Tx buffer DMA transfer request */
+    SPI_I2S_DMA_REQ_RX  /*!< Rx buffer DMA transfer request */
+} SPI_I2S_DMA_REQ_T;
+
+/**
+ * @brief SPI Direction select
+ */
+typedef enum
+{
+    SPI_DIRECTION_RX,   /*!< Selects Rx receive direction */
+    SPI_DIRECTION_TX    /*!< Selects Tx transmission direction */
+} SPI_DIRECTION_SELECT_T;
+
+/**
+ * @brief    SPI interrupts definition
+ */
+typedef enum
+{
+    SPI_I2S_INT_TXBE  = 0x8002, /*!< Tx buffer empty interrupt */
+    SPI_I2S_INT_RXBNE = 0x4001, /*!< Rx buffer not empty interrupt */
+    SPI_I2S_INT_ERR   = 0x2000, /*!< Error interrupt */
+    I2S_INT_UDR       = 0x2008, /*!< Underrun Error interrupt flag */
+    SPI_INT_CRCE      = 0x2010, /*!< CRC Error interrupt flag */
+    SPI_INT_ME        = 0x2020, /*!< Mode Error interrupt flag */
+    SPI_I2S_INT_OVR   = 0x2040  /*!< Overrun interrupt flag */
+} SPI_I2S_INT_T;
+
+/**
+ * @brief SPI flags definition
+ */
+typedef enum
+{
+    SPI_FLAG_RXBNE  = 0x0001,   /*!< Receive buffer not empty flag */
+    SPI_FLAG_TXBE   = 0x0002,   /*!< Transmit buffer empty flag */
+    I2S_FLAG_SCHDIR = 0x0004,   /*!< Side Channel flag */
+    I2S_FLAG_UDR    = 0x0008,   /*!< Underrun Error flag */
+    SPI_FLAG_CRCE   = 0x0010,   /*!< CRC Error flag */
+    SPI_FLAG_ME     = 0x0020,   /*!< Mode Error flag */
+    SPI_FLAG_OVR    = 0x0040,   /*!< Overrun flag */
+    SPI_FLAG_BSY    = 0x0080    /*!< Busy flag */
+} SPI_FLAG_T;
+
+/**@} end of group SPI_Enumerations*/
+
+/** @addtogroup SPI_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief SPI Config structure definition
+ */
+typedef struct
+{
+    SPI_MODE_T          mode;           /*!< SPI mode selection */
+    SPI_DATA_LENGTH_T   length;         /*!< SPI data length selection */
+    SPI_CLKPHA_T        phase;          /*!< SPI clock phase selection */
+    SPI_CLKPOL_T        polarity;       /*!< SPI clock polarity selection */
+    SPI_NSS_T           nss;            /*!< Set SPI software NSS */
+    SPI_FIRSTBIT_T      firstBit;       /*!< Set first bit */
+    SPI_DIRECTION_T     direction;      /*!< SPI data direction mode selection */
+    SPI_BAUDRATE_DIV_T  baudrateDiv;    /*!< SPI BaudRate Prescaler selection */
+    uint16_t            crcPolynomial;  /*!< Setup CRC polynomial value */
+} SPI_Config_T;
+
+/**
+ * @brief I2S Config structure definition
+ */
+typedef struct
+{
+    I2S_MODE_T          mode;       /*!< I2S mode selection */
+    I2S_STANDARD_T      standard;   /*!< I2S standard selection */
+    I2S_DATA_LENGTH_T   length;     /*!< Set I2S data length */
+    I2S_MCLK_OUTPUT_T   MCLKOutput; /*!< Set I2S MCLK output */
+    I2S_AUDIO_DIV_T     audioDiv;   /*!< I2S Audio divider selection */
+    I2S_CLKPOL_T        polarity;   /*!< I2S Clock polarity selection */
+} I2S_Config_T;
+
+/**@} end of group SPI_Structure*/
+
+/** @defgroup SPI_Functions
+  @{
+*/
+
+/* Reset */
+void SPI_I2S_Reset(SPI_T* spi);
+
+/* Initialization and Configuration */
+void SPI_Config(SPI_T* spi, SPI_Config_T* spiConfig);
+void I2S_Config(SPI_T* spi, I2S_Config_T* i2sConfig);
+void SPI_ConfigStructInit(SPI_Config_T* spiConfig);
+void I2S_ConfigStructInit(I2S_Config_T* i2sConfig);
+void SPI_Enable(SPI_T* spi);
+void SPI_Disable(SPI_T* spi);
+void I2S_Enable(SPI_T* spi);
+void I2S_Disable(SPI_T* spi);
+void SPI_ConfigDataSize(SPI_T* spi, SPI_DATA_LENGTH_T length);
+
+void SPI_SetSoftwareNSS(SPI_T* spi);
+void SPI_ResetSoftwareNSS(SPI_T* spi);
+void SPI_EnableSSOutput(SPI_T* spi);
+void SPI_DisableSSOutput(SPI_T* spi);
+void SPI_ConfigBiDirectionalLine(SPI_T* spi, SPI_DIRECTION_SELECT_T direction);
+
+void SPI_EnableTIMode(SPI_T* spi);
+void SPI_DisableTIMode(SPI_T* spi);
+void I2S_ConfigFullDuplex(SPI_T* spi, I2S_Config_T* i2sConfig);
+
+/* Data transfers */
+void SPI_I2S_TxData(SPI_T* spi, uint16_t data);
+uint16_t SPI_I2S_RxData(SPI_T* spi);
+
+/* Hardware CRC Calculation */
+void SPI_EnableCRC(SPI_T* spi);
+void SPI_DisableCRC(SPI_T* spi);
+void SPI_TxCRC(SPI_T* spi);
+uint16_t SPI_ReadTxCRC(SPI_T* spi);
+uint16_t SPI_ReadRxCRC(SPI_T* spi);
+uint16_t SPI_ReadCRCPolynomial(SPI_T* spi);
+
+/* DMA transfers */
+void SPI_I2S_EnableDMA(SPI_T* spi, SPI_I2S_DMA_REQ_T dmaReq);
+void SPI_I2S_DisableDMA(SPI_T* spi, SPI_I2S_DMA_REQ_T dmaReq);
+
+/* Interrupts and flags */
+void SPI_I2S_EnableInterrupt(SPI_T* spi, uint32_t interrupt);
+void SPI_I2S_DisableInterrupt(SPI_T* spi, uint32_t interrupt);
+uint8_t SPI_I2S_ReadStatusFlag(SPI_T* spi, SPI_FLAG_T flag);
+void SPI_I2S_ClearStatusFlag(SPI_T* spi, SPI_FLAG_T flag);
+uint8_t SPI_I2S_ReadIntFlag(SPI_T* spi, SPI_I2S_INT_T flag);
+void SPI_I2S_ClearIntFlag(SPI_T* spi, SPI_I2S_INT_T flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_SPI_H */
+
+/**@} end of group SPI_Enumerations */
+/**@} end of group SPI_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 132 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_syscfg.h

@@ -0,0 +1,132 @@
+/*!
+ * @file        apm32f4xx_syscfg.h
+ *
+ * @brief       This file contains all the functions prototypes for the SYSCFG firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_SYSCFG_H
+#define __APM32F4XX_SYSCFG_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup SYSCFG_Driver
+  @{
+*/
+
+/** @defgroup SYSCFG_Enumerations
+  @{
+*/
+
+/**
+ * @brief SYSCFG EINT Port Sources
+ */
+typedef enum
+{
+    SYSCFG_PORT_GPIOA, /*!< EXTI_Port Source GPIOA */
+    SYSCFG_PORT_GPIOB, /*!< EXTI_Port Source GPIOB */
+    SYSCFG_PORT_GPIOC, /*!< EXTI_Port Source GPIOC */
+    SYSCFG_PORT_GPIOD, /*!< EXTI_Port Source GPIOD */
+    SYSCFG_PORT_GPIOE, /*!< EXTI_Port Source GPIOE */
+    SYSCFG_PORT_GPIOF, /*!< EXTI_Port Source GPIOF */
+    SYSCFG_PORT_GPIOG, /*!< EXTI_Port Source GPIOG */
+    SYSCFG_PORT_GPIOH, /*!< EXTI_Port Source GPIOH */
+    SYSCFG_PORT_GPIOI  /*!< EXTI_Port Source GPIOI */
+} SYSCFG_PORT_T;
+
+/**
+ * @brief SYSCFG EINT Pin Sources
+ */
+typedef enum
+{
+    SYSCFG_PIN_0,  /*!< Pin Source 0 */
+    SYSCFG_PIN_1,  /*!< Pin Source 1 */
+    SYSCFG_PIN_2,  /*!< Pin Source 2 */
+    SYSCFG_PIN_3,  /*!< Pin Source 3 */
+    SYSCFG_PIN_4,  /*!< Pin Source 4 */
+    SYSCFG_PIN_5,  /*!< Pin Source 5 */
+    SYSCFG_PIN_6,  /*!< Pin Source 6 */
+    SYSCFG_PIN_7,  /*!< Pin Source 7 */
+    SYSCFG_PIN_8,  /*!< Pin Source 8 */
+    SYSCFG_PIN_9,  /*!< Pin Source 9 */
+    SYSCFG_PIN_10, /*!< Pin Source 10 */
+    SYSCFG_PIN_11, /*!< Pin Source 11 */
+    SYSCFG_PIN_12, /*!< Pin Source 12 */
+    SYSCFG_PIN_13, /*!< Pin Source 13 */
+    SYSCFG_PIN_14, /*!< Pin Source 14 */
+    SYSCFG_PIN_15  /*!< Pin Source 15 */
+} SYSCFG_PIN_T;
+
+/**
+ * @brief SYSCFG Memory Remap Config
+ */
+typedef enum
+{
+    SYSCFG_REMAP_FLASH,         /*!< Memory mapping to Flash */
+    SYSCFG_REMAP_SYSTEM_FLASH,  /*!< Memory mapping to SystemFlash */
+    SYSCFG_REMAP_SMC_BANK1,     /*!< Memory mapping to bank1 of SMC (NOR-flash/PSRAM) */
+    SYSCFG_REMAP_SRAM           /*!< Memory mapping to SRAM */
+} SYSCFG_REMAP_T;
+
+/**
+ * @brief SYSCFG Ethernet PHY interface selection
+ */
+typedef enum
+{
+    SYSCFG_INTERFACE_MII,  /*!< SYSCFG Media Interface MII */
+    SYSCFG_INTERFACE_RMII  /*!< SYSCFG Media Interface RMII */
+} SYSCFG_INTERFACE_T;
+
+/**@} end of group SYSCFG_Enumerations*/
+
+/** @defgroup SYSCFG_Functions
+  @{
+*/
+
+void SYSCFG_Reset(void);
+void SYSCFG_ConfigMemoryRemap(SYSCFG_REMAP_T memory);
+void SYSCFG_ConfigEINTLine(SYSCFG_PORT_T port, SYSCFG_PIN_T pin);
+void SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_T media);
+
+/* Compensation Cell */
+void SYSCFG_EnableCompensationCell(void);
+void SYSCFG_DisableCompensationCell(void);
+uint8_t SYSCFG_ReadCompensationCellStatus(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__APM32F4XX_SYSCFG_H */
+
+/**@} end of group SYSCFG_Enumerations */
+/**@} end of group SYSCFG_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 709 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_tmr.h

@@ -0,0 +1,709 @@
+/*!
+ * @file        apm32f4xx_tmr.h
+ *
+ * @brief       This file contains all the functions prototypes for the TMR firmware library.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_TMR_H
+#define __APM32F4XX_TMR_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup TMR_Driver
+  @{
+*/
+
+/** @defgroup TMR_Enumerations
+  @{
+*/
+
+/**
+ * @brief TMR Output Compare and PWM modes
+ */
+typedef enum
+{
+    TMR_OC_MODE_TMRING     = 0x00,  /*!< Frozen TMR output compare mode */
+    TMR_OC_MODE_ACTIVE     = 0x01,  /*!< Set output to high when matching */
+    TMR_OC_MODE_INACTIVE   = 0x02,  /*!< Set output to low when matching */
+    TMR_OC_MODE_TOGGLE     = 0x03,  /*!< Toggle output when matching */
+    TMR_OC_MODE_LOWLEVEL   = 0x04,  /*!< Force output to be low */
+    TMR_OC_MODE_HIGHLEVEL  = 0x05,  /*!< Force output to be high */
+    TMR_OC_MODE_PWM1       = 0x06,  /*!< PWM1 mode */
+    TMR_OC_MODE_PWM2       = 0x07   /*!< PWM2 mode */
+} TMR_OC_MODE_T;
+
+/**
+ * @brief TMR Single Pulse Mode
+ */
+typedef enum
+{
+    TMR_SPM_REPETITIVE, /*!< Enable repetitive pulse mode */
+    TMR_SPM_SINGLE      /*!< Enable single pulse mode */
+} TMR_SPM_T;
+
+/**
+ * @brief TMR Input Capture Init structure definition
+ */
+typedef enum
+{
+    TMR_CHANNEL_1 = 0x0000, /*!< Timer Channel 1 */
+    TMR_CHANNEL_2 = 0x0004, /*!< Timer Channel 2 */
+    TMR_CHANNEL_3 = 0x0008, /*!< Timer Channel 3 */
+    TMR_CHANNEL_4 = 0x000C  /*!< Timer Channel 4 */
+} TMR_CHANNEL_T;
+
+/**
+ * @brief TMR Clock division
+ */
+
+typedef enum
+{
+    TMR_CLOCK_DIV_1,    /*!< TDTS = Tck_tim */
+    TMR_CLOCK_DIV_2,    /*!< TDTS = 2 * Tck_tim */
+    TMR_CLOCK_DIV_4     /*!< TDTS = 4 * Tck_tim */
+} TMR_CLOCK_DIV_T;
+
+/**
+ * @brief TMR Counter Mode
+ */
+typedef enum
+{
+    TMR_COUNTER_MODE_UP              = 0x00,    /*!< Timer Up Counting Mode */
+    TMR_COUNTER_MODE_DOWN            = 0x01,    /*!< Timer Down Counting Mode */
+    TMR_COUNTER_MODE_CENTER_ALIGNED1 = 0x10,    /*!< Timer Center Aligned Mode1 */
+    TMR_COUNTER_MODE_CENTER_ALIGNED2 = 0x20,    /*!< Timer Center Aligned Mode2 */
+    TMR_COUNTER_MODE_CENTER_ALIGNED3 = 0x30     /*!< Timer Center Aligned Mode3 */
+} TMR_COUNTER_MODE_T;
+
+/**
+ * @brief TMR Output Compare Polarity
+ */
+typedef enum
+{
+    TMR_OC_POLARITY_HIGH,   /*!< Output Compare active high */
+    TMR_OC_POLARITY_LOW     /*!< Output Compare active low */
+} TMR_OC_POLARITY_T;
+
+/**
+ * @brief TMR Output Compare N Polarity
+ */
+typedef enum
+{
+    TMR_OC_NPOLARITY_HIGH,  /*!< Output Compare active high */
+    TMR_OC_NPOLARITY_LOW    /*!< Output Compare active low */
+} TMR_OC_NPOLARITY_T;
+
+/**
+ * @brief TMR Output Compare state
+ */
+typedef enum
+{
+    TMR_OC_STATE_DISABLE,   /*!< Disable output compare */
+    TMR_OC_STATE_ENABLE     /*!< Enable output compare */
+} TMR_OC_STATE_T;
+
+/**
+ * @brief TMR Output Compare N state
+ */
+typedef enum
+{
+    TMR_OC_NSTATE_DISABLE,  /*!< Disable complementary output */
+    TMR_OC_NSTATE_ENABLE    /*!< Enable complementary output */
+} TMR_OC_NSTATE_T;
+
+/**
+ * @brief TMR BRK state
+ */
+typedef enum
+{
+    TMR_BRK_STATE_DISABLE,  /*!< Disable brake function */
+    TMR_BRK_STATE_ENABLE    /*!< Enable brake function */
+} TMR_BRK_STATE_T;
+
+/**
+ * @brief TMR Specifies the Break Input pin polarity.
+ */
+typedef enum
+{
+    TMR_BRK_POLARITY_LOW,   /*!< BRK low level valid */
+    TMR_BRK_POLARITY_HIGH   /*!< BRK high level valid */
+} TMR_BRK_POLARITY_T;
+
+/**
+ * @brief TMR Specifies the Break Input pin polarity.
+ */
+typedef enum
+{
+    TMR_AUTOMATIC_OUTPUT_DISABLE,   /*!< Disable automatic output */
+    TMR_AUTOMATIC_OUTPUT_ENABLE     /*!< Enable automatic output */
+} TMR_AUTOMATIC_OUTPUT_T;
+
+/**
+ * @brief TMR Protect mode configuration values
+ */
+typedef enum
+{
+    TMR_LOCK_LEVEL_OFF, /*!< No lock write protection */
+    TMR_LOCK_LEVEL_1,   /*!< Lock write protection level 1 */
+    TMR_LOCK_LEVEL_2,   /*!< Lock write protection level 2 */
+    TMR_LOCK_LEVEL_3    /*!< Lock write protection level 3 */
+} TMR_LOCK_LEVEL_T;
+
+/**
+ * @brief TMR Specifies the Off-State selection used in Run mode
+ */
+typedef enum
+{
+    TMR_RMOS_STATE_DISABLE, /*!< Disable run mode off-state */
+    TMR_RMOS_STATE_ENABLE   /*!< Enable run mode off-state */
+} TMR_RMOS_STATE_T;
+
+/**
+ * @brief TMR Closed state configuration in idle mode
+ */
+typedef enum
+{
+    TMR_IMOS_STATE_DISABLE, /*!< Disable idle mode off-state */
+    TMR_IMOS_STATE_ENABLE   /*!< Enable idle mode off-state */
+} TMR_IMOS_STATE_T;
+
+/**
+ * @brief TMR Output Compare Idle State
+ */
+typedef enum
+{
+    TMR_OC_IDLE_STATE_RESET,    /*!< Reset output compare idle state */
+    TMR_OC_IDLE_STATE_SET       /*!< Set output compare idle state */
+} TMR_OC_IDLE_STATE_T;
+
+/**
+ * @brief TMR Output Compare N Idle State
+ */
+typedef enum
+{
+    TMR_OC_NIDLE_STATE_RESET,   /*!< Reset output complementary idle state */
+    TMR_OC_NIDLE_STATE_SET      /*!< Set output complementary idle state */
+} TMR_OC_NIDLE_STATE_T;
+
+/**
+ * @brief TMR Input Capture Polarity
+ */
+typedef enum
+{
+    TMR_IC_POLARITY_RISING   = 0x00,    /*!< Rising edge */
+    TMR_IC_POLARITY_FALLING  = 0x02,    /*!< Falling edge */
+    TMR_IC_POLARITY_BOTHEDGE = 0x0A     /*!< Both rising and falling edge */
+} TMR_IC_POLARITY_T;
+
+/**
+ * @brief TMR Input Capture Selection
+ */
+typedef enum
+{
+    TMR_IC_SELECTION_DIRECT_TI   = 0x01,    /*!< Input capture mapping in TI1 */
+    TMR_IC_SELECTION_INDIRECT_TI = 0x02,    /*!< Input capture mapping in TI2 */
+    TMR_IC_SELECTION_TRC         = 0x03     /*!< Input capture mapping in TRC */
+} TMR_IC_SELECTION_T;
+
+/**
+ * @brief TMR Input Capture Prescaler
+ */
+typedef enum
+{
+    TMR_IC_PSC_1,   /*!< No prescaler */
+    TMR_IC_PSC_2,   /*!< Capture is done once every 2 events */
+    TMR_IC_PSC_4,   /*!< capture is done once every 4 events */
+    TMR_IC_PSC_8    /*!< capture is done once every 8 events */
+} TMR_IC_PSC_T;
+
+/**
+ * @brief TMR_interrupt_sources
+ */
+typedef enum
+{
+    TMR_INT_UPDATE = 0x0001,    /*!< Timer update Interrupt source */
+    TMR_INT_CC1    = 0x0002,    /*!< Timer Capture Compare 1 Interrupt source */
+    TMR_INT_CC2    = 0x0004,    /*!< Timer Capture Compare 2 Interrupt source */
+    TMR_INT_CC3    = 0x0008,    /*!< Timer Capture Compare 3 Interrupt source */
+    TMR_INT_CC4    = 0x0010,    /*!< Timer Capture Compare 4 Interrupt source */
+    TMR_INT_COM    = 0x0020,    /*!< Timer Commutation Interrupt source (Only for TMR1 and TMR8) */
+    TMR_INT_TRG    = 0x0040,    /*!< Timer Trigger Interrupt source */
+    TMR_INT_BRK    = 0x0080     /*!< Timer Break Interrupt source (Only for TMR1 and TMR8) */
+} TMR_INT_T;
+
+/**
+ * @brief TMR DMA Base Address
+ */
+typedef enum
+{
+    TMR_DMA_BASE_CTRL1   = 0x0000,  /*!< TMR CTRL1 DMA base address setup */
+    TMR_DMA_BASE_CTRL2   = 0x0001,  /*!< TMR CTRL2 DMA base address setup */
+    TMR_DMA_BASE_SMCTRL  = 0x0002,  /*!< TMR SMCTRL DMA base address setup */
+    TMR_DMA_BASE_DIEN    = 0x0003,  /*!< TMR DIEN DMA base address setup */
+    TMR_DMA_BASE_STS     = 0x0004,  /*!< TMR STS DMA base address setup */
+    TMR_DMA_BASE_CEG     = 0x0005,  /*!< TMR CEG DMA base address setup */
+    TMR_DMA_BASE_CCM1    = 0x0006,  /*!< TMR CCM1 DMA base address setup */
+    TMR_DMA_BASE_CCM2    = 0x0007,  /*!< TMR CCM2 DMA base address setup */
+    TMR_DMA_BASE_CCEN    = 0x0008,  /*!< TMR CCEN DMA base address setup */
+    TMR_DMA_BASE_CNT     = 0x0009,  /*!< TMR CNT DMA base address setup */
+    TMR_DMA_BASE_PSC     = 0x000A,  /*!< TMR PSC DMA base address setup */
+    TMR_DMA_BASE_AUTORLD = 0x000B,  /*!< TMR AUTORLD DMA base address setup */
+    TMR_DMA_BASE_REPCNT  = 0x000C,  /*!< TMR REPCNT DMA base address setup */
+    TMR_DMA_BASE_CC1     = 0x000D,  /*!< TMR CC1 DMA base address setup */
+    TMR_DMA_BASE_CC2     = 0x000E,  /*!< TMR CC2 DMA base address setup */
+    TMR_DMA_BASE_CC3     = 0x000F,  /*!< TMR CC3 DMA base address setup */
+    TMR_DMA_BASE_CC4     = 0x0010,  /*!< TMR CC4 DMA base address setup */
+    TMR_DMA_BASE_BDT     = 0x0011,  /*!< TMR BDT DMA base address setup */
+    TMR_DMA_BASE_DCTRL   = 0x0012   /*!< TMR DCTRL DMA base address setup */
+} TMR_DMA_BASE_T;
+
+/**
+ * @brief TMR DMA Soueces
+ */
+typedef enum
+{
+    TMR_DMA_SOURCE_UPDATE    = 0x0100,  /*!< TMR update DMA souces */
+    TMR_DMA_SOURCE_CH1       = 0x0200,  /*!< TMR Capture Compare 1 DMA souces */
+    TMR_DMA_SOURCE_CH2       = 0x0400,  /*!< TMR Capture Compare 2 DMA souces */
+    TMR_DMA_SOURCE_CH3       = 0x0800,  /*!< TMR Capture Compare 3 DMA souces */
+    TMR_DMA_SOURCE_CH4       = 0x1000,  /*!< TMR Capture Compare 4 DMA souces */
+    TMR_DMA_SOURCE_COM       = 0x2000,  /*!< TMR Commutation DMA souces */
+    TMR_DMA_SOURCE_TRG       = 0x4000   /*!< TMR Trigger DMA souces */
+} TMR_DMA_SOURCE_T;
+
+/**
+ * @brief TMR  The external Trigger Prescaler.
+ */
+typedef enum
+{
+    TMR_EXTTRG_PSC_OFF   = 0x00,    /*!< ETRP Prescaler OFF */
+    TMR_EXTTRG_PSC_DIV2  = 0x01,    /*!< ETRP frequency divided by 2 */
+    TMR_EXTTRG_PSC_DIV4  = 0x02,    /*!< ETRP frequency divided by 4 */
+    TMR_EXTTRG_PSC_DIV8  = 0x03     /*!< ETRP frequency divided by 8 */
+} TMR_EXTTRG_PSC_T;
+
+/**
+ * @brief TMR Internal Trigger Selection
+ */
+typedef enum
+{
+    TMR_TRIGGER_SOURCE_ITR0     = 0x00, /*!< Internal Trigger 0 */
+    TMR_TRIGGER_SOURCE_ITR1     = 0x01, /*!< Internal Trigger 1 */
+    TMR_TRIGGER_SOURCE_ITR2     = 0x02, /*!< Internal Trigger 2 */
+    TMR_TRIGGER_SOURCE_ITR3     = 0x03, /*!< Internal Trigger 3 */
+    TMR_TRIGGER_SOURCE_TI1F_ED  = 0x04, /*!< TI1 Edge Detector */
+    TMR_TRIGGER_SOURCE_TI1FP1   = 0x05, /*!< Filtered Timer Input 1 */
+    TMR_TRIGGER_SOURCE_TI2FP2   = 0x06, /*!< Filtered Timer Input 2 */
+    TMR_TRIGGER_SOURCE_ETRF     = 0x07  /*!< External Trigger input */
+} TMR_TRIGGER_SOURCE_T;
+
+/**
+ * @brief TMR External Trigger Polarity
+ */
+typedef enum
+{
+    TMR_EXTTGR_POL_NONINVERTED, /*!< Active high or rising edge active */
+    TMR_EXTTRG_POL_INVERTED     /*!< Active low or falling edge active */
+} TMR_EXTTRG_POL_T;
+
+/**
+ * @brief TMR Prescaler Reload Mode
+ */
+typedef enum
+{
+    TMR_PSC_RELOAD_UPDATE,      /*!< The Prescaler reload at the update event */
+    TMR_PSC_RELOAD_IMMEDIATE    /*!< The Prescaler reload immediately */
+} TMR_PSC_RELOAD_T;
+
+/**
+ * @brief TMR Forced Action
+ */
+typedef enum
+{
+    TMR_FORCED_ACTION_INACTIVE = 0x04,  /*!< Force inactive level on OC1REF */
+    TMR_FORCED_ACTION_ACTIVE   = 0x05   /*!< Force active level on OC1REF */
+} TMR_FORCED_ACTION_T;
+
+/**
+ * @brief TMR Encoder Mode
+ */
+typedef enum
+{
+    TMR_ENCODER_MODE_TI1      = 0x01,   /*!< Encoder mode 1 */
+    TMR_ENCODER_MODE_TI2      = 0x02,   /*!< Encoder mode 2 */
+    TMR_ENCODER_MODE_TI12     = 0x03    /*!< Encoder mode 3 */
+} TMR_ENCODER_MODE_T;
+
+/**
+ * @brief TMR event sources
+ */
+typedef enum
+{
+    TMR_EVENT_UPDATE = 0x001,   /*!< Timer update Interrupt source */
+    TMR_EVENT_CH1    = 0x002,   /*!< Timer Capture Compare 1 Event source */
+    TMR_EVENT_CH2    = 0x004,   /*!< Timer Capture Compare 1 Event source */
+    TMR_EVENT_CH3    = 0x008,   /*!< Timer Capture Compare 3 Event source */
+    TMR_EVENT_CH4    = 0x010,   /*!< Timer Capture Compare 4 Event source */
+    TMR_EVENT_COM    = 0x020,   /*!< Timer Commutation Event source (Only for TMR1 and TMR8) */
+    TMR_EVENT_TRG    = 0x040,   /*!< Timer Trigger Event source */
+    TMR_EVENT_BRK    = 0x080    /*!< Timer Break Event source (Only for TMR1 and TMR8) */
+} TMR_EVENT_T;
+
+/**
+ * @brief TMR UpdateSource
+ */
+typedef enum
+{
+    TMR_UPDATE_SOURCE_GLOBAL,   /*!< Source of update is
+                                    - Counter overflow/underflow.
+                                    - UEG bit of Control event generation register(CEG) is set.
+                                    - Update generation through the slave mode controller. */
+    TMR_UPDATE_SOURCE_REGULAR   /*!< Source of update is Counter overflow/underflow */
+} TMR_UPDATE_SOURCE_T;
+
+/**
+ * @brief TMR Output Compare Preload State
+ */
+typedef enum
+{
+    TMR_OC_PRELOAD_DISABLE, /*!< Enable preload */
+    TMR_OC_PRELOAD_ENABLE   /*!< Disable preload */
+} TMR_OC_PRELOAD_T;
+
+/**
+ * @brief TMR Output Compare Preload State
+ */
+typedef enum
+{
+    TMR_OC_FAST_DISABLE,    /*!< Disable fast output compare */
+    TMR_OC_FAST_ENABLE      /*!< Enable fast output compare */
+} TMR_OC_FAST_T;
+
+/**
+ * @brief TMR Output Compare Preload State
+ */
+typedef enum
+{
+    TMR_OC_CLEAR_DISABLE,   /*!< Disable output compare clear */
+    TMR_OC_CLEAR_ENABLE     /*!< Enable output compare clear */
+} TMR_OC_CLEAR_T;
+
+/**
+ * @brief TMR Trigger Output Source
+ */
+typedef enum
+{
+    TMR_TRGO_SOURCE_RESET,  /*!< Select reset signal as TRGO source  */
+    TMR_TRGO_SOURCE_ENABLE, /*!< Select enable signal as TRGO source */
+    TMR_TRGO_SOURCE_UPDATE, /*!< Select update signal as TRGO source */
+    TMR_TRGO_SOURCE_OC1,    /*!< Select OC1 signal as TRGO source */
+    TMR_TRGO_SOURCE_OC1REF, /*!< Select OC1REF signal as TRGO source */
+    TMR_TRGO_SOURCE_OC2REF, /*!< Select OC2REF signal as TRGO source */
+    TMR_TRGO_SOURCE_OC3REF, /*!< Select OC3REF signal as TRGO source */
+    TMR_TRGO_SOURCE_OC4REF  /*!< Select OC4REF signal as TRGO source */
+} TMR_TRGO_SOURCE_T;
+
+/**
+ * @brief TMR Slave Mode
+ */
+typedef enum
+{
+    TMR_SLAVE_MODE_RESET     = 0x04,    /*!< Reset mode */
+    TMR_SLAVE_MODE_GATED     = 0x05,    /*!< Gated mode */
+    TMR_SLAVE_MODE_TRIGGER   = 0x06,    /*!< Trigger mode */
+    TMR_SLAVE_MODE_EXTERNAL1 = 0x07     /*!< External 1 mode */
+} TMR_SLAVE_MODE_T;
+
+/**
+ * @brief TMR Remap
+ */
+typedef enum
+{
+    TMR2_TMR8_TRGO     = 0x0000,    /*!< TMR2 ITR1 input is connected to TMR8 Trigger output(default) */
+    TMR2_PTP_TRG       = 0x0400,    /*!< TMR2 ITR1 input is connected to ETH PTP trigger output */
+    TMR2_OTG_FSUSB_SOF = 0x0800,    /*!< TMR2 ITR1 input is connected to OTG FS SOF */
+    TMR2_OTG_HSUSB_SOF = 0x0C00,    /*!< TMR2 ITR1 input is connected to OTG HS SOF */
+    TMR5_GPIO          = 0x0000,    /*!< TMR5 CH4 input is connected to GPIO */
+    TMR5_LSI           = 0x0040,    /*!< TMR5 CH4 input is connected to LSI clock */
+    TMR5_LSE           = 0x0080,    /*!< TMR5 CH4 input is connected to LSE clock */
+    TMR5_RTC           = 0x00C0,    /*!< TMR5 CH4 input is connected to RTC Output event */
+    TMRx_GPIO          = 0x0000,    /*!< TMR10/11/13/14 CH1 input is connected to GPIO */
+    TMRx_RTCCLK        = 0x0001,    /*!< TMR10/11/13/14 CH1 input is connected to RTC clock */
+    TMRx_HSECLK        = 0x0002,    /*!< TMR10/11/13/14 CH1 input is connected to HSE clock/32 */
+    TMRx_MCO           = 0x0003     /*!< TMR10/11/13/14 CH1 input is connected to MCO */
+} TMR_REMAP_T;
+
+/**
+ * @brief TMR Flag
+ */
+typedef enum
+{
+    TMR_FLAG_UPDATE  = 0x0001,  /*!< Timer update Flag */
+    TMR_FLAG_CC1     = 0x0002,  /*!< Timer Capture Compare 1 Flag */
+    TMR_FLAG_CC2     = 0x0004,  /*!< Timer Capture Compare 2 Flag */
+    TMR_FLAG_CC3     = 0x0008,  /*!< Timer Capture Compare 3 Flag */
+    TMR_FLAG_CC4     = 0x0010,  /*!< Timer Capture Compare 4 Flag */
+    TMR_FLAG_COM     = 0x0020,  /*!< Timer Commutation Flag (Only for TMR1 and TMR8) */
+    TMR_FLAG_TRG     = 0x0040,  /*!< Timer Trigger Flag */
+    TMR_FLAG_BRK     = 0x0080,  /*!< Timer Break Flag (Only for TMR1 and TMR8) */
+    TMR_FLAG_CC1RC   = 0x0200,  /*!< Timer Capture Compare 1 Repetition Flag */
+    TMR_FLAG_CC2RC   = 0x0400,  /*!< Timer Capture Compare 2 Repetition Flag */
+    TMR_FLAG_CC3RC   = 0x0800,  /*!< Timer Capture Compare 3 Repetition Flag */
+    TMR_FLAG_CC4RC   = 0x1000   /*!< Timer Capture Compare 4 Repetition Flag */
+} TMR_FLAG_T;
+
+/**
+ * @brief TMR DMA Burst Length
+ */
+typedef enum
+{
+    TMR_DMA_BURSTLENGTH_1TRANSFER   = 0x0000,   /*!< Select TMR DMA burst Length 1 */
+    TMR_DMA_BURSTLENGTH_2TRANSFERS  = 0x0100,   /*!< Select TMR DMA burst Length 2 */
+    TMR_DMA_BURSTLENGTH_3TRANSFERS  = 0x0200,   /*!< Select TMR DMA burst Length 3 */
+    TMR_DMA_BURSTLENGTH_4TRANSFERS  = 0x0300,   /*!< Select TMR DMA burst Length 4 */
+    TMR_DMA_BURSTLENGTH_5TRANSFERS  = 0x0400,   /*!< Select TMR DMA burst Length 5 */
+    TMR_DMA_BURSTLENGTH_6TRANSFERS  = 0x0500,   /*!< Select TMR DMA burst Length 6 */
+    TMR_DMA_BURSTLENGTH_7TRANSFERS  = 0x0600,   /*!< Select TMR DMA burst Length 7 */
+    TMR_DMA_BURSTLENGTH_8TRANSFERS  = 0x0700,   /*!< Select TMR DMA burst Length 8 */
+    TMR_DMA_BURSTLENGTH_9TRANSFERS  = 0x0800,   /*!< Select TMR DMA burst Length 9 */
+    TMR_DMA_BURSTLENGTH_10TRANSFERS = 0x0900,   /*!< Select TMR DMA burst Length 10 */
+    TMR_DMA_BURSTLENGTH_11TRANSFERS = 0x0A00,   /*!< Select TMR DMA burst Length 11 */
+    TMR_DMA_BURSTLENGTH_12TRANSFERS = 0x0B00,   /*!< Select TMR DMA burst Length 12 */
+    TMR_DMA_BURSTLENGTH_13TRANSFERS = 0x0C00,   /*!< Select TMR DMA burst Length 13 */
+    TMR_DMA_BURSTLENGTH_14TRANSFERS = 0x0D00,   /*!< Select TMR DMA burst Length 14 */
+    TMR_DMA_BURSTLENGTH_15TRANSFERS = 0x0E00,   /*!< Select TMR DMA burst Length 15 */
+    TMR_DMA_BURSTLENGTH_16TRANSFERS = 0x0F00,   /*!< Select TMR DMA burst Length 16 */
+    TMR_DMA_BURSTLENGTH_17TRANSFERS = 0x1000,   /*!< Select TMR DMA burst Length 17 */
+    TMR_DMA_BURSTLENGTH_18TRANSFERS = 0x1100    /*!< Select TMR DMA burst Length 18 */
+} TMR_DMA_BURSTLENGTH_T;
+
+/**@} end of group TMR_Enumerations*/
+
+/** @addtogroup TMR_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief TMR Time Base Init structure definition
+ * @note  This structure is used with all TMR except for TMR6 and TMR7.
+ */
+typedef struct
+{
+    TMR_COUNTER_MODE_T countMode;           /*!< TMR counter mode selection */
+    TMR_CLOCK_DIV_T    clockDivision;       /*!< TMR clock division selection */
+    uint16_t           period;              /*!< This must between 0x0000 and 0xFFFF */
+    uint16_t           division;            /*!< This must between 0x0000 and 0xFFFF */
+    uint8_t            repetitionCounter;   /*!< This must between 0x00 and 0xFF, only for TMR1 and TMR8. */
+} TMR_BaseConfig_T;
+
+/**
+ * @brief TMR Config struct definition
+ */
+typedef struct
+{
+    TMR_OC_MODE_T        mode;          /*!< TMR Output Compare and PWM modes selection */
+    TMR_OC_STATE_T       outputState;   /*!< TMR Output Compare state selection */
+    TMR_OC_NSTATE_T      outputNState;  /*!< TMR Output Compare N state selection */
+    TMR_OC_POLARITY_T    polarity;      /*!< TMR Output Compare Polarity selection */
+    TMR_OC_NPOLARITY_T   nPolarity;     /*!< TMR Output Compare N Polarity selection */
+    TMR_OC_IDLE_STATE_T  idleState;     /*!< TMR Output Compare Idle State selection */
+    TMR_OC_NIDLE_STATE_T nIdleState;    /*!< TMR Output Compare N Idle State selection */
+    uint16_t             pulse;         /*!< This must between 0x0000 and 0xFFFF */
+} TMR_OCConfig_T;
+
+/**
+ * @brief TMR Input Capture Config struct definition
+ */
+typedef struct
+{
+    TMR_CHANNEL_T      channel;     /*!< Timer channel selection */
+    TMR_IC_POLARITY_T  polarity;    /*!< TMR input capture polarity selection */
+    TMR_IC_SELECTION_T selection;   /*!< TMR Input capture selection */
+    TMR_IC_PSC_T       prescaler;   /*!< TMR Input Capture selection */
+    uint16_t           filter;      /*!< This must between 0x00 and 0x0F */
+} TMR_ICConfig_T;
+
+/**
+ * @brief TMR BDT structure definition
+ */
+typedef struct
+{
+    TMR_RMOS_STATE_T       RMOS;            /*!< TMR Specifies the Off-State selection used in Run mode selection */
+    TMR_IMOS_STATE_T       IMOS;            /*!< TMR Closed state configuration in idle mode selection */
+    TMR_LOCK_LEVEL_T       lockLevel;       /*!< TMR Protect mode configuration values selection */
+    uint16_t               deadTime;        /*!< Setup dead time */
+    TMR_BRK_STATE_T        BRKState;        /*!< Setup TMR BRK state */
+    TMR_BRK_POLARITY_T     BRKPolarity;     /*!< Setup TMR BRK polarity */
+    TMR_AUTOMATIC_OUTPUT_T automaticOutput; /*!< Setup break input pin polarity */
+} TMR_BDTConfig_T;
+
+/**@} end of group TMR_Structure*/
+
+/** @defgroup TMR_Functions
+  @{
+*/
+
+/* Reset and Configuration */
+void TMR_Reset(TMR_T* tmr);
+void TMR_ConfigTimeBase(TMR_T* tmr, TMR_BaseConfig_T* baseConfig);
+void TMR_ConfigTimeBaseStructInit(TMR_BaseConfig_T* baseConfig);
+void TMR_ConfigPrescaler(TMR_T* tmr, uint16_t prescaler, TMR_PSC_RELOAD_T reload);
+void TMR_ConfigCounterMode(TMR_T* tmr, TMR_COUNTER_MODE_T countMode);
+void TMR_ConfigCounter(TMR_T* tmr, uint16_t counter);
+void TMR_ConfigAutoreload(TMR_T* tmr, uint16_t autoReload);
+uint16_t TMR_ReadCounter(TMR_T* tmr);
+uint16_t TMR_ReadPrescaler(TMR_T* tmr);
+void TMR_EnableUpdate(TMR_T* tmr);
+void TMR_DisableUpdate(TMR_T* tmr);
+void TMR_ConfigUpdateRequest(TMR_T* tmr, TMR_UPDATE_SOURCE_T updateSource);
+void TMR_EnableAutoReload(TMR_T* tmr);
+void TMR_DisableAutoReload(TMR_T* tmr);
+void TMR_ConfigSinglePulseMode(TMR_T* tmr, TMR_SPM_T singlePulseMode);
+void TMR_ConfigClockDivision(TMR_T* tmr, TMR_CLOCK_DIV_T clockDivision);
+void TMR_Enable(TMR_T* tmr);
+void TMR_Disable(TMR_T* tmr);
+
+/* Output Compare */
+void TMR_ConfigOC1(TMR_T* tmr, TMR_OCConfig_T* OCConfig);
+void TMR_ConfigOC2(TMR_T* tmr, TMR_OCConfig_T* OCConfig);
+void TMR_ConfigOC3(TMR_T* tmr, TMR_OCConfig_T* OCConfig);
+void TMR_ConfigOC4(TMR_T* tmr, TMR_OCConfig_T* OCConfig);
+void TMR_ConfigOCStructInit(TMR_OCConfig_T* OCConfig);
+void TMR_SelectOCxMode(TMR_T* tmr, TMR_CHANNEL_T channel, TMR_OC_MODE_T mode);
+void TMR_ConfigCompare1(TMR_T* tmr, uint32_t compare1);
+void TMR_ConfigCompare2(TMR_T* tmr, uint32_t compare2);
+void TMR_ConfigCompare3(TMR_T* tmr, uint32_t compare3);
+void TMR_ConfigCompare4(TMR_T* tmr, uint32_t compare4);
+void TMR_ConfigForcedOC1(TMR_T* tmr, TMR_FORCED_ACTION_T forcesAction);
+void TMR_ConfigForcedOC2(TMR_T* tmr, TMR_FORCED_ACTION_T forcesAction);
+void TMR_ConfigForcedOC3(TMR_T* tmr, TMR_FORCED_ACTION_T forcesAction);
+void TMR_ConfigForcedOC4(TMR_T* tmr, TMR_FORCED_ACTION_T forcesAction);
+void TMR_ConfigOC1Preload(TMR_T* tmr, TMR_OC_PRELOAD_T OCPreload);
+void TMR_ConfigOC2Preload(TMR_T* tmr, TMR_OC_PRELOAD_T OCPreload);
+void TMR_ConfigOC3Preload(TMR_T* tmr, TMR_OC_PRELOAD_T OCPreload);
+void TMR_ConfigOC4Preload(TMR_T* tmr, TMR_OC_PRELOAD_T OCPreload);
+void TMR_ConfigOC1Fast(TMR_T* tmr, TMR_OC_FAST_T OCFast);
+void TMR_ConfigOC2Fast(TMR_T* tmr, TMR_OC_FAST_T OCFast);
+void TMR_ConfigOC3Fast(TMR_T* tmr, TMR_OC_FAST_T OCFast);
+void TMR_ConfigOC4Fast(TMR_T* tmr, TMR_OC_FAST_T OCFast);
+void TMR_ClearOC1Ref(TMR_T* tmr, TMR_OC_CLEAR_T OCClear);
+void TMR_ClearOC2Ref(TMR_T* tmr, TMR_OC_CLEAR_T OCClear);
+void TMR_ClearOC3Ref(TMR_T* tmr, TMR_OC_CLEAR_T OCClear);
+void TMR_ClearOC4Ref(TMR_T* tmr, TMR_OC_CLEAR_T OCClear);
+void TMR_ConfigOC1Polarity(TMR_T* tmr, TMR_OC_POLARITY_T OCPolarity);
+void TMR_ConfigOC1NPolarity(TMR_T* tmr, TMR_OC_NPOLARITY_T OCNPolarity);
+void TMR_ConfigOC2Polarity(TMR_T* tmr, TMR_OC_POLARITY_T OCPolarity);
+void TMR_ConfigOC2NPolarity(TMR_T* tmr, TMR_OC_NPOLARITY_T OCNPolarity);
+void TMR_ConfigOC3Polarity(TMR_T* tmr, TMR_OC_POLARITY_T OCPolarity);
+void TMR_ConfigOC3NPolarity(TMR_T* tmr, TMR_OC_NPOLARITY_T OCNPolarity);
+void TMR_ConfigOC4Polarity(TMR_T* tmr, TMR_OC_POLARITY_T OCPolarity);
+void TMR_EnableCCxChannel(TMR_T* tmr, TMR_CHANNEL_T channel);
+void TMR_DisableCCxChannel(TMR_T* tmr, TMR_CHANNEL_T channel);
+void TMR_EnableCCxNChannel(TMR_T* tmr, TMR_CHANNEL_T channel);
+void TMR_DisableCCxNChannel(TMR_T* tmr, TMR_CHANNEL_T channel);
+
+/* Input Capture */
+void TMR_ConfigIC(TMR_T* tmr, TMR_ICConfig_T* ICConfig);
+void TMR_ConfigICStructInit(TMR_ICConfig_T* ICConfig);
+void TMR_ConfigPWM(TMR_T* tmr, TMR_ICConfig_T* PWMConfig);
+uint32_t TMR_ReadCaputer1(TMR_T* tmr);
+uint32_t TMR_ReadCaputer2(TMR_T* tmr);
+uint32_t TMR_ReadCaputer3(TMR_T* tmr);
+uint32_t TMR_ReadCaputer4(TMR_T* tmr);
+void TMR_ConfigIC1Prescaler(TMR_T* tmr, TMR_IC_PSC_T prescaler);
+void TMR_ConfigIC2Prescaler(TMR_T* tmr, TMR_IC_PSC_T prescaler);
+void TMR_ConfigIC3Prescaler(TMR_T* tmr, TMR_IC_PSC_T prescaler);
+void TMR_ConfigIC4Prescaler(TMR_T* tmr, TMR_IC_PSC_T prescaler);
+
+/* Advanced-control timers (TMR1 and TMR8) specific features */
+void TMR_ConfigBDT(TMR_T* tmr, TMR_BDTConfig_T* BDTConfig);
+void TMR_ConfigBDTStructInit( TMR_BDTConfig_T* BDTConfig);
+void TMR_EnablePWMOutputs(TMR_T* tmr);
+void TMR_DisablePWMOutputs(TMR_T* tmr);
+void TMR_EnableSelectCOM(TMR_T* tmr);
+void TMR_DisableSelectCOM(TMR_T* tmr);
+void TMR_EnableCCPreload(TMR_T* tmr);
+void TMR_DisableCCPreload(TMR_T* tmr);
+
+/* DMA management */
+void TMR_ConfigDMA(TMR_T* tmr, TMR_DMA_BASE_T baseAddress, TMR_DMA_BURSTLENGTH_T burstLength);
+void TMR_EnableDMASoure(TMR_T* tmr, uint16_t dmaSource);
+void TMR_DisableDMASoure(TMR_T* tmr, uint16_t dmaSource);
+void TMR_EnableCCDMA(TMR_T* tmr);
+void TMR_DisableCCDMA(TMR_T* tmr);
+
+/* Clocks management */
+void TMR_ConfigInternalClock(TMR_T* tmr);
+void TMR_ConfigIntTrigExternalClock(TMR_T* tmr, TMR_TRIGGER_SOURCE_T triggerSource);
+void TMR_ConfigTrigExternalClock(TMR_T* tmr, TMR_TRIGGER_SOURCE_T triggerSource,
+                                 TMR_IC_POLARITY_T ICpolarity, uint16_t ICfilter);
+void TMR_ConfigETRClockMode1(TMR_T* tmr, TMR_EXTTRG_PSC_T prescaler,
+                             TMR_EXTTRG_POL_T polarity, uint16_t filter);
+void TMR_ConfigETRClockMode2(TMR_T* tmr, TMR_EXTTRG_PSC_T prescaler,
+                             TMR_EXTTRG_POL_T polarity, uint16_t filter);
+
+/* Synchronization management */
+void TMR_SelectInputTrigger(TMR_T* tmr, TMR_TRIGGER_SOURCE_T triggerSource);
+void TMR_SelectOutputTrigger(TMR_T* tmr, TMR_TRGO_SOURCE_T TRGOSource);
+void TMR_SelectSlaveMode(TMR_T* tmr, TMR_SLAVE_MODE_T slaveMode);
+void TMR_EnableMasterSlaveMode(TMR_T* tmr);
+void TMR_DisableMasterSlaveMode(TMR_T* tmr);
+void TMR_ConfigETR(TMR_T* tmr, TMR_EXTTRG_PSC_T prescaler,
+                   TMR_EXTTRG_POL_T polarity, uint16_t filter);
+
+/* Interface */
+void TMR_ConfigEncodeInterface(TMR_T* tmr, TMR_ENCODER_MODE_T encodeMode,  \
+                               TMR_IC_POLARITY_T IC1Polarity,TMR_IC_POLARITY_T IC2Polarity);
+void TMR_EnableHallSensor(TMR_T* tmr);
+void TMR_DisableHallSensor(TMR_T* tmr);
+
+/* Remapping  */
+void TMR_ConfigRemap(TMR_T* tmr, uint32_t remap);
+
+/* Interrupts and flags  */
+void TMR_EnableInterrupt(TMR_T* tmr, uint16_t interrupt);
+void TMR_DisableInterrupt(TMR_T* tmr, uint16_t interrupt);
+void TMR_GenerateEvent(TMR_T* tmr, uint16_t eventSources);
+uint16_t TMR_ReadStatusFlag(TMR_T* tmr, TMR_FLAG_T flag);
+void TMR_ClearStatusFlag(TMR_T* tmr, uint16_t flag);
+uint16_t TMR_ReadIntFlag(TMR_T* tmr,  TMR_INT_T flag);
+void TMR_ClearIntFlag(TMR_T* tmr,  uint16_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__APM32F4XX_TMR_H */
+
+/**@} end of group TMR_Enumerations */
+/**@} end of group TMR_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 314 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_usart.h

@@ -0,0 +1,314 @@
+/*!
+ * @file        apm32f4xx_usart.h
+ *
+ * @brief       This file contains all the functions prototypes for the USART firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_USART_H
+#define __APM32F4XX_USART_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup USART_Driver
+  @{
+*/
+
+/** @defgroup USART_Enumerations
+  @{
+*/
+
+/**
+ * @brief USART Word Length
+ */
+typedef enum
+{
+    USART_WORD_LEN_8B,  /*!< 8-bit data length */
+    USART_WORD_LEN_9B   /*!< 9-bit data length */
+} USART_WORD_LEN_T;
+
+/**
+ * @brief USART Stop bits
+ */
+typedef enum
+{
+    USART_STOP_BIT_1,       /*!< 1-bit stop bit */
+    USART_STOP_BIT_0_5,     /*!< 0.5-bit stop bit */
+    USART_STOP_BIT_2,       /*!< 2-bit stop bit */
+    USART_STOP_BIT_1_5      /*!< 1.5-bit stop bit */
+} USART_STOP_BIT_T;
+
+/**
+ * @brief USART Parity
+ */
+typedef enum
+{
+    USART_PARITY_NONE  = (uint8_t)0x00, /*!< Disable parity control */
+    USART_PARITY_EVEN  = (uint8_t)0x01, /*!< Enable even parity control */
+    USART_PARITY_ODD   = (uint8_t)0x03  /*!< Enable odd parity control*/
+} USART_PARITY_T;
+
+/**
+ * @brief USART mode
+ */
+typedef enum
+{
+    USART_MODE_RX    = (uint8_t)0x01,   /*!< Enable USART Receive mode */
+    USART_MODE_TX    = (uint8_t)0x02,   /*!< Enable USART transmit mode */
+    USART_MODE_TX_RX = (uint8_t)0x03    /*!< Enable USART receive and transmit mode */
+} USART_MODE_T;
+
+/**
+ * @brief USART hardware flow control
+ */
+typedef enum
+{
+    USART_HARDWARE_FLOW_NONE,   /*!< Disable hardware flow control */
+    USART_HARDWARE_FLOW_RTS,    /*!< Enable RTS hardware flow control */
+    USART_HARDWARE_FLOW_CTS,    /*!< Enable CTS hardware flow control */
+    USART_HARDWARE_FLOW_RTS_CTS /*!< Enable RTS and CTS hardware flow control */
+} USART_HARDWARE_FLOW_T;
+
+/**
+ * @brief USART Clock enable
+ */
+typedef enum
+{
+    USART_CLKEN_DISABLE,    /*!< Disable usart clock */
+    USART_CLKEN_ENABLE      /*!< Enable usart clock */
+} USART_CLKEN_T;
+
+/**
+ * @brief USART Clock polarity
+ */
+typedef enum
+{
+    USART_CLKPOL_LOW,   /*!< Set clock polarity to low */
+    USART_CLKPOL_HIGH   /*!< Set clock polarity to high */
+} USART_CLKPOL_T;
+
+/**
+ * @brief USART Clock phase
+ */
+typedef enum
+{
+    USART_CLKPHA_1EDGE, /*!< Set usart to sample at the edge of the first clock */
+    USART_CLKPHA_2EDGE  /*!< Set usart to sample at the edge of the second clock */
+} USART_CLKPHA_T;
+
+/**
+ * @brief USART Last bit clock pulse
+ */
+typedef enum
+{
+    USART_LBCP_DISABLE, /*!< Enable output last bit clock pulse */
+    USART_LBCP_ENABLE,  /*!< Disable output last bit clock pulse */
+} USART_LBCP_T;
+
+/**
+ * @brief USART Interrupt Source
+ */
+typedef enum
+{
+    USART_INT_PE       = 0x0010100, /*!< Parity error interrupt */
+    USART_INT_TXBE     = 0x7010080, /*!< Tansmit data buffer empty interrupt */
+    USART_INT_TXC      = 0x6010040, /*!< Transmission complete interrupt */
+    USART_INT_RXBNE    = 0x5010020, /*!< Receive data buffer not empty interrupt */
+    USART_INT_IDLE     = 0x4010010, /*!< Idle line detection interrupt */
+    USART_INT_OVRE_RX  = 0x3010008, /*!< OverRun Error interruptpt if the RXBNFLG bit is set */
+    USART_INT_LBD      = 0x8020040, /*!< LIN break detection interrupt */
+    USART_INT_CTS      = 0x9040400, /*!< CTS change interrupt */
+    USART_INT_ERR      = 0x0040001, /*!< Error interrupt(Frame error, noise error, overrun error) */
+    USART_INT_OVRE_ER  = 0x3040001, /*!< OverRun Error interruptpt if the EIE bit is set */
+    USART_INT_NE       = 0x2040001, /*!< Noise Error interrupt */
+    USART_INT_FE       = 0x1040001  /*!< Framing Error interrupt */
+} USART_INT_T;
+
+/**
+ * @brief USART DMA enable
+ */
+typedef enum
+{
+    USART_DMA_RX    = (uint8_t)0x01,    /*!< USART DMA transmit request */
+    USART_DMA_TX    = (uint8_t)0x02,    /*!< USART DMA receive request */
+    USART_DMA_TX_RX = (uint8_t)0x03     /*!< USART DMA transmit/receive request */
+} USART_DMA_T;
+
+/**
+ * @brief USART Wakeup method
+ */
+typedef enum
+{
+    USART_WAKEUP_IDLE_LINE,     /*!< WakeUp by an idle line detection */
+    USART_WAKEUP_ADDRESS_MARK   /*!< WakeUp by an address mark */
+} USART_WAKEUP_T;
+
+/**
+ * @brief USART LIN break detection length
+ */
+typedef enum
+{
+    USART_LBDL_10B, /*!< 10-bit break detection */
+    USART_LBDL_11B  /*!< 11-bit break detection */
+} USART_LBDL_T;
+
+/**
+ * @brief USART IrDA low-power
+ */
+typedef enum
+{
+    USART_IRDALP_NORMAL,    /*!< Normal */
+    USART_IRDALP_LOWPOWER   /*!< Low-Power */
+} USART_IRDALP_T;
+
+/**
+ * @brief USART flag
+ */
+typedef enum
+{
+    USART_FLAG_CTS       = 0x0200,  /*!< CTS Change flag (not available for UART4 and UART5) */
+    USART_FLAG_LBD       = 0x0100,  /*!< LIN Break detection flag */
+    USART_FLAG_TXBE      = 0x0080,  /*!< Transmit data buffer empty flag */
+    USART_FLAG_TXC       = 0x0040,  /*!< Transmission Complete flag */
+    USART_FLAG_RXBNE     = 0x0020,  /*!< Receive data buffer not empty flag */
+    USART_FLAG_IDLE      = 0x0010,  /*!< Idle Line detection flag */
+    USART_FLAG_OVRE      = 0x0008,  /*!< OverRun Error flag */
+    USART_FLAG_NE        = 0x0004,  /*!< Noise Error flag */
+    USART_FLAG_FE        = 0x0002,  /*!< Framing Error flag */
+    USART_FLAG_PE        = 0x0001   /*!< Parity Error flag */
+} USART_FLAG_T;
+
+/**@} end of group USART_Enumerations*/
+
+/** @addtogroup USART_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief USART Config struct definition
+ */
+typedef struct
+{
+    uint32_t                  baudRate;          /*!< Specifies the baud rate */
+    USART_WORD_LEN_T          wordLength;        /*!< Specifies the word length */
+    USART_STOP_BIT_T          stopBits;          /*!< Specifies the stop bits */
+    USART_PARITY_T            parity;            /*!< Specifies the parity */
+    USART_MODE_T              mode;              /*!< Specifies the mode */
+    USART_HARDWARE_FLOW_T     hardwareFlow;      /*!< Specifies the hardware flow control */
+} USART_Config_T;
+
+/**
+ * @brief USART synchronous communication clock config struct definition
+ */
+typedef struct
+{
+    USART_CLKEN_T             clock;             /*!< Enable or Disable Clock */
+    USART_CLKPOL_T            polarity;          /*!< Specifies the clock polarity */
+    USART_CLKPHA_T            phase;             /*!< Specifies the clock phase */
+    USART_LBCP_T              lastBit;           /*!< Enable or Disable last bit clock */
+} USART_ClockConfig_T;
+
+/**@} end of group USART_Structure*/
+
+/** @defgroup USART_Functions
+  @{
+*/
+
+/* USART Reset */
+void USART_Reset(USART_T* usart);
+
+/* USART Configuration */
+void USART_Config(USART_T* uart, USART_Config_T* usartConfig);
+void USART_ConfigStructInit(USART_Config_T* usartConfig);
+void USART_ConfigClock(USART_T* usart, USART_ClockConfig_T* clockConfig);
+void USART_ConfigClockStructInit(USART_ClockConfig_T* clockConfig);
+void USART_Enable(USART_T* usart);
+void USART_Disable(USART_T* usart);
+void USART_ConfigPrescaler(USART_T* usart, uint8_t div);
+void USART_EnableOverSampling8(USART_T* usart);
+void USART_DisableOverSampling8(USART_T* usart);
+void USART_EnableOverSampling(USART_T* usart);
+void USART_DisableOverSampling(USART_T* usart);
+
+/* Data transfers */
+void USART_TxData(USART_T* usart, uint16_t data);
+uint16_t USART_RxData(USART_T* usart);
+
+/* Multi-Processor Communication */
+void USART_Address(USART_T* usart, uint8_t address);
+void USART_EnableMuteMode(USART_T* usart);
+void USART_DisableMuteMode(USART_T* usart);
+void USART_ConfigWakeUp(USART_T* usart, USART_WAKEUP_T wakeup);
+
+/* LIN mode */
+void USART_ConfigLINBreakDetectLength(USART_T* usart, USART_LBDL_T length);
+void USART_EnableLIN(USART_T* usart);
+void USART_DisableLIN(USART_T* usart);
+void USART_TxBreak(USART_T* usart);
+
+/* Half-duplex mode */
+void USART_EnableHalfDuplex(USART_T* usart);
+void USART_DisableHalfDuplex(USART_T* usart);
+
+/* Smartcard mode */
+void USART_ConfigGuardTime(USART_T* usart, uint8_t guardTime);
+void USART_EnableSmartCard(USART_T* usart);
+void USART_DisableSmartCard(USART_T* usart);
+void USART_EnableSmartCardNACK(USART_T* usart);
+void USART_DisableSmartCardNACK(USART_T* usart);
+
+/* IrDA mode */
+void USART_ConfigIrDA(USART_T* usart, USART_IRDALP_T IrDAMode);
+
+void USART_EnableIrDA(USART_T* usart);
+void USART_DisableIrDA(USART_T* usart);
+
+/* DMA transfers management */
+void USART_EnableDMA(USART_T* usart, USART_DMA_T dmaReq);
+void USART_DisableDMA(USART_T* usart, USART_DMA_T dmaReq);
+
+/* Interrupts and flags management */
+void USART_EnableInterrupt(USART_T* usart, USART_INT_T interrupt);
+void USART_DisableInterrupt(USART_T* usart, USART_INT_T interrupt);
+uint8_t USART_ReadStatusFlag(USART_T* usart, USART_FLAG_T flag);
+void USART_ClearStatusFlag(USART_T* usart, USART_FLAG_T flag);
+uint8_t USART_ReadIntFlag(USART_T* usart, USART_INT_T flag);
+void USART_ClearIntFlag(USART_T* usart, USART_INT_T flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_USART_H */
+
+/**@} end of group USART_Enumerations */
+/**@} end of group USART_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 94 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_wwdt.h

@@ -0,0 +1,94 @@
+/*!
+ * @file        apm32f4xx_wwdt.h
+ *
+ * @brief       This file contains all the functions prototypes for the WWDT firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4XX_WWDT_H
+#define __APM32F4XX_WWDT_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @addtogroup WWDT_Driver
+  @{
+*/
+
+/** @defgroup WWDT_Enumerations
+  @{
+*/
+
+/**
+ * @brief WWDT Timebase(Prescaler)
+ */
+typedef enum
+{
+    WWDT_TIME_BASE_1,   /*!< WWDT counter clock = (PCLK1 / 4096) / 1 */
+    WWDT_TIME_BASE_2,   /*!< WWDT counter clock = (PCLK1 / 4096) / 2 */
+    WWDT_TIME_BASE_4,   /*!< WWDT counter clock = (PCLK1 / 4096) / 4 */
+    WWDT_TIME_BASE_8    /*!< WWDT counter clock = (PCLK1 / 4096) / 8 */
+} WWDT_TIME_BASE_T;
+
+/**@} end of group WWDT_Enumerations*/
+
+/** @defgroup WWDT_Functions
+  @{
+*/
+
+/* WWDT reset */
+void WWDT_Reset(void);
+
+/* Config WWDT Timebase */
+void WWDT_ConfigTimebase(WWDT_TIME_BASE_T timeBase);
+
+/* Config Window Data */
+void WWDT_ConfigWindowData(uint8_t windowData);
+
+/* Config Couter */
+void WWDT_ConfigCounter(uint8_t counter);
+
+/* Enable WWDT and Early Wakeup interrupt */
+void WWDT_EnableEWI(void); //5
+void WWDT_Enable(uint8_t count);
+
+/* Read Flag and Clear Flag */
+uint8_t WWDT_ReadFlag(void);
+void WWDT_ClearFlag(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_WWDT_H */
+
+/**@} end of group WWDT_Enumerations */
+/**@} end of group WWDT_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 1028 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_adc.c

@@ -0,0 +1,1028 @@
+/*!
+ * @file        apm32f4xx_adc.c
+ *
+ * @brief       This file contains all the functions for the ADC peripheral
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_adc.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup ADC_Driver
+  * @brief ADC driver modules
+  @{
+*/
+
+/** @defgroup ADC_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset ADC peripheral registers to their default reset values.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_Reset(void)
+{
+    RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_ADC);
+    RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_ADC);
+}
+
+/*!
+ * @brief     Config the ADC peripheral according to the specified parameters in the adcConfig.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     adcConfig: pointer to a ADC_Config_T structure.
+ *
+ * @retval    None
+ */
+void ADC_Config(ADC_T *adc, ADC_Config_T *adcConfig)
+{
+    adc->CTRL1_B.RESSEL = adcConfig->resolution;
+    adc->CTRL1_B.SCANEN = adcConfig->scanConvMode;
+
+    adc->CTRL2_B.REGEXTTRGEN = adcConfig->extTrigEdge;
+    adc->CTRL2_B.REGEXTTRGSEL = adcConfig->extTrigConv;
+    adc->CTRL2_B.DALIGNCFG = adcConfig->dataAlign;
+    adc->CTRL2_B.CONTCEN = adcConfig->continuousConvMode;
+
+    adc->REGSEQ1_B.REGSEQLEN = adcConfig->nbrOfChannel - 1;
+}
+
+/*!
+ * @brief     Fills each ADC_Config_T member with its default value.
+ *
+ * @param     adcConfig: pointer to an ADC_Config_T structure.
+ *
+ * @retval    None
+ */
+void ADC_ConfigStructInit(ADC_Config_T *adcConfig)
+{
+    adcConfig->resolution = ADC_RESOLUTION_12BIT;
+    adcConfig->scanConvMode = DISABLE;
+    adcConfig->continuousConvMode = DISABLE;
+    adcConfig->extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;
+    adcConfig->extTrigConv = ADC_EXT_TRIG_CONV_TMR1_CC1;
+    adcConfig->dataAlign = ADC_DATA_ALIGN_RIGHT;
+    adcConfig->nbrOfChannel = 1;
+}
+
+/*!
+ * @brief     Config the ADCs peripherals according to the specified parameters in
+ *             the adcCommonConfig.
+ *
+ * @param     adcCommonConfig: pointer to an ADC_CommonConfig_T structure
+ *
+ * @retval    None
+ */
+void ADC_CommonConfig(ADC_CommonConfig_T *adcCommonConfig)
+{
+    ADC->CCTRL_B.ADCMSEL = adcCommonConfig->mode;
+    ADC->CCTRL_B.ADCPRE = adcCommonConfig->prescaler;
+    ADC->CCTRL_B.DMAMODE = adcCommonConfig->accessMode;
+    ADC->CCTRL_B.SMPDEL2 = adcCommonConfig->twoSampling;
+}
+
+/*!
+ * @brief     Fills each ADC_CommonInitStruct member with its default value.
+ *
+ * @param     adccommonconfig: pointer to an ADC_CommonInitTypeDef structure.
+ *
+ * @retval    None
+ */
+void ADC_CommonConfigStructInit(ADC_CommonConfig_T *adccommonconfig)
+{
+    adccommonconfig->mode = ADC_MODE_INDEPENDENT;
+    adccommonconfig->prescaler = ADC_PRESCALER_DIV2;
+    adccommonconfig->accessMode = ADC_ACCESS_MODE_DISABLED;
+    adccommonconfig->twoSampling = ADC_TWO_SAMPLING_5CYCLES;
+}
+
+/*!
+ * @brief     Enables the specified ADC peripheral.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_Enable(ADC_T *adc)
+{
+    adc->CTRL2_B.ADCEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the specified ADC peripheral.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_Disable(ADC_T *adc)
+{
+    adc->CTRL2_B.ADCEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enable the specified ADC analog watchdog.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     analogWatchdog: The ADC analog watchdog configuration
+ *               This parameter can be one of the following values:
+ *               @arg ADC_ANALOG_WATCHDOG_SINGLE_REG        : Analog watchdog on a single regular channel
+ *               @arg ADC_ANALOG_WATCHDOG_SINGLE_INJEC      : Analog watchdog on a single injected channel
+ *               @arg ADC_ANALOG_WATCHDOG_SINGLE_REG_INJEC  : Analog watchdog on a single regular or injected channel
+ *               @arg ADC_ANALOG_WATCHDOG_ALL_REG           : Analog watchdog on  all regular channel
+ *               @arg ADC_ANALOG_WATCHDOG_ALL_INJEC         : Analog watchdog on  all injected channel
+ *               @arg ADC_ANALOG_WATCHDOG_ALL_REG_ALL_INJEC : Analog watchdog on all regular and injected channels
+ *
+ * @retval    None
+ */
+void ADC_EnableAnalogWatchdog(ADC_T *adc, ADC_ANALOG_WATCHDOG_T analogWatchdog)
+{
+    adc->CTRL1_B.INJAWDEN = analogWatchdog & 0x01;
+    adc->CTRL1_B.REGAWDEN = (analogWatchdog >> 1) & 0x01;
+    adc->CTRL1_B.AWDSGLEN = analogWatchdog >> 4;
+}
+
+/*!
+ * @brief     Disable the specified ADC analog watchdog.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_DisableAnalogWatchdog(ADC_T *adc)
+{
+    adc->CTRL1_B.AWDSGLEN = BIT_RESET;
+    adc->CTRL1_B.INJAWDEN = BIT_RESET;
+    adc->CTRL1_B.REGAWDEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the specified ADC high and low thresholds of the analog watchdog.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     highThreshold: The ADC analog watchdog High threshold value.
+ *                           This parameter must be a 12bit value.
+ *
+ * @param     lowThreshold:  The ADC analog watchdog Low threshold value.
+ *                           This parameter must be a 12bit value.
+ * @retval    None
+ */
+void ADC_ConfigAnalogWatchdogThresholds(ADC_T *adc, uint16_t highThreshold, uint16_t lowThreshold)
+{
+    adc->AWDHT = highThreshold;
+    adc->AWDLT = lowThreshold;
+}
+
+/*!
+ * @brief     Configures the specified ADC high and low thresholds of the analog watchdog.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     lowThreshold: The ADC analog watchdog Low threshold value.
+ *                          This parameter must be a 12bit value.
+ *
+ * @retval    None
+ */
+void ADC_AnalogWatchdogLowThresholds(ADC_T *adc,  uint16_t lowThreshold)
+{
+    adc->AWDLT = lowThreshold;
+}
+
+/*!
+ * @brief      Configures the specified ADC analog watchdog guarded single channel
+ *
+ * @param      adc: Select the ADC peripheral
+ *
+ * @param      channel: Select the ADC channel
+ *                      This parameter can be one of the following values:
+ *                        @arg ADC_CHANNEL_0:   Select ADC Channel 0
+ *                        @arg ADC_CHANNEL_1:   Select ADC Channel 1
+ *                        @arg ADC_CHANNEL_2:   Select ADC Channel 2
+ *                        @arg ADC_CHANNEL_3:   Select ADC Channel 3
+ *                        @arg ADC_CHANNEL_4:   Select ADC Channel 4
+ *                        @arg ADC_CHANNEL_5:   Select ADC Channel 5
+ *                        @arg ADC_CHANNEL_6:   Select ADC Channel 6
+ *                        @arg ADC_CHANNEL_7:   Select ADC Channel 7
+ *                        @arg ADC_CHANNEL_8:   Select ADC Channel 8
+ *                        @arg ADC_CHANNEL_9:   Select ADC Channel 9
+ *                        @arg ADC_CHANNEL_10:  Select ADC Channel 10
+ *                        @arg ADC_CHANNEL_11:  Select ADC Channel 11
+ *                        @arg ADC_CHANNEL_12:  Select ADC Channel 12
+ *                        @arg ADC_CHANNEL_13:  Select ADC Channel 13
+ *                        @arg ADC_CHANNEL_14:  Select ADC Channel 14
+ *                        @arg ADC_CHANNEL_15:  Select ADC Channel 15
+ *                        @arg ADC_CHANNEL_16:  Select ADC Channel 16
+ *                        @arg ADC_CHANNEL_17:  Select ADC Channel 17
+ *                        @arg ADC_CHANNEL_18:  Select ADC Channel 18
+ *
+ * @retval     None
+ *
+ * @note       adc can be ADC1, ADC2 or ADC3.
+ */
+void ADC_ConfigAnalogWatchdogSingleChannel(ADC_T *adc, uint8_t channel)
+{
+    adc->CTRL1_B.AWDCHSEL = channel;
+}
+
+/*!
+ * @brief     Enables the temperature sensor and Vrefint channels.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_EnableTempSensorVrefint(void)
+{
+    ADC->CCTRL_B.TSVREFEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the temperature sensor and Vrefint channel.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_DisableTempSensorVrefint(void)
+{
+    ADC->CCTRL_B.TSVREFEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables  the VBAT (Voltage Battery) channel.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_EnableVbat(void)
+{
+    ADC->CCTRL_B.VBATEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the VBAT (Voltage Battery) channel.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_DisableVbat(void)
+{
+    ADC->CCTRL_B.VBATEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the specified ADC regular channel.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     channel: the ADC channel to configure.
+ *                     This parameter can be one of the following values:
+ *                     @arg ADC_CHANNEL_0:  ADC channel 0
+ *                     @arg ADC_CHANNEL_1:  ADC channel 1
+ *                     @arg ADC_CHANNEL_2:  ADC channel 2
+ *                     @arg ADC_CHANNEL_3:  ADC channel 3
+ *                     @arg ADC_CHANNEL_4:  ADC channel 4
+ *                     @arg ADC_CHANNEL_5:  ADC channel 5
+ *                     @arg ADC_CHANNEL_6:  ADC channel 6
+ *                     @arg ADC_CHANNEL_7:  ADC channel 7
+ *                     @arg ADC_CHANNEL_8:  ADC channel 8
+ *                     @arg ADC_CHANNEL_9:  ADC channel 9
+ *                     @arg ADC_CHANNEL_10: ADC channel 10
+ *                     @arg ADC_CHANNEL_11: ADC channel 11
+ *                     @arg ADC_CHANNEL_12: ADC channel 12
+ *                     @arg ADC_CHANNEL_13: ADC channel 13
+ *                     @arg ADC_CHANNEL_14: ADC channel 14
+ *                     @arg ADC_CHANNEL_15: ADC channel 15
+ *                     @arg ADC_CHANNEL_16: ADC channel 16
+ *                     @arg ADC_CHANNEL_17: ADC channel 17
+ *                     @arg ADC_CHANNEL_18: ADC Channel 18
+ *
+ * @param     rank: The rank in the regular group sequencer
+ *                     This parameter must be between 1 to 16.
+ *
+ * @param     sampleTime: the specified ADC channel SampleTime
+ *                     The parameter can be one of following values:
+ *                     @arg ADC_SAMPLETIME_3CYCLES:   Sample time equal to 3 cycles
+ *                     @arg ADC_SAMPLETIME_15CYCLES:  Sample time equal to 15 cycles
+ *                     @arg ADC_SAMPLETIME_28CYCLES:  Sample time equal to 28 cycles
+ *                     @arg ADC_SAMPLETIME_56CYCLES:  Sample time equal to 56 cycles
+ *                     @arg ADC_SAMPLETIME_84CYCLES:  Sample time equal to 84 cycles
+ *                     @arg ADC_SAMPLETIME_112CYCLES: Sample time equal to 112 cycles
+ *                     @arg ADC_SAMPLETIME_144CYCLES: Sample time equal to 144 cycles
+ *                     @arg ADC_SAMPLETIME_480CYCLES: Sample time equal to 480 cycles
+ *
+ * @retval None
+ */
+
+void ADC_ConfigRegularChannel(ADC_T *adc, uint8_t channel, uint8_t rank, uint8_t sampleTime)
+{
+    uint32_t temp1 = 0;
+    uint32_t temp2 = 0;
+
+    if (channel > ADC_CHANNEL_9)
+    {
+        temp1 = adc->SMPTIM1;
+        temp2 = (uint32_t)7 << (3 * (channel - 10));
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)sampleTime << (3 * (channel - 10));
+        temp1 |= temp2;
+        adc->SMPTIM1 = temp1;
+    }
+    else
+    {
+        temp1 = adc->SMPTIM2;
+        temp2 = (uint32_t)7 << (3 * channel);
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)sampleTime << (3 * channel);
+        temp1 |= temp2;
+        adc->SMPTIM2 = temp1;
+    }
+
+    if (rank < 7)
+    {
+        temp1 = adc->REGSEQ3;
+        temp2 = (uint32_t)0x1F << (5 * (rank - 1));
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)channel << (5 * (rank - 1));
+        temp1 |= temp2;
+        adc->REGSEQ3 = temp1;
+    }
+    else if (rank < 13)
+    {
+        temp1 = adc->REGSEQ2;
+        temp2 = (uint32_t)0x1F << (5 * (rank - 7));
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)channel << (5 * (rank - 7));
+        temp1 |= temp2;
+        adc->REGSEQ2 = temp1;
+    }
+    else
+    {
+        temp1 = adc->REGSEQ1;
+        temp2 = (uint32_t)0x1F << (5 * (rank - 13));
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)channel << (5 * (rank - 13));
+        temp1 |= temp2;
+        adc->REGSEQ1 = temp1;
+    }
+}
+
+/*!
+ * @brief     Enables the selected ADC software start conversion of the regular channels.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_SoftwareStartConv(ADC_T *adc)
+{
+    adc->CTRL2_B.REGCHSC = BIT_SET;
+}
+
+/*!
+ * @brief     Reads the selected ADC Software start regular conversion Status.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The new state of ADC software start conversion (SET or RESET).
+ */
+uint8_t ADC_ReadSoftwareStartConvStatus(ADC_T *adc)
+{
+    return (uint8_t)adc->CTRL2_B.REGCHSC;
+}
+
+/**
+ * @brief     Enables the EOC on each regular channel conversion
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_EnableEOCOnEachChannel(ADC_T *adc)
+{
+    adc->CTRL2_B.EOCSEL = BIT_SET;
+
+}
+
+/**
+ * @brief     Disables the EOC on each regular channel conversion
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_DisableEOCOnEachChannel(ADC_T *adc)
+{
+    adc->CTRL2_B.EOCSEL = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the ADC continuous conversion mode
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_EnableContinuousMode(ADC_T *adc)
+{
+    adc->CTRL2_B.CONTCEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the ADC continuous conversion mode
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_DisableContinuousMode(ADC_T *adc)
+{
+    adc->CTRL2_B.CONTCEN = BIT_RESET;;
+}
+
+/*!
+ * @brief     Configures the discontinuous mode for the selected ADC regular group
+ *            channel.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     number: specifies the discontinuous mode regular channel count value.
+ *                    This number must be between 1 and 8.
+ *
+ * @retval    None
+ */
+void ADC_ConfigDiscMode(ADC_T *adc, uint8_t number)
+{
+    adc->CTRL1_B.DISCNUMCFG = number - 1;
+}
+
+/*!
+ * @brief     Enables the discontinuous mode on regular group channel.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_EnableDiscMode(ADC_T *adc)
+{
+    adc->CTRL1_B.REGDISCEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the discontinuous mode for injected group channel.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_DisableDiscMode(ADC_T *adc)
+{
+    adc->CTRL1_B.REGDISCEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Reads the specified ADC conversion result data.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The Data conversion value.
+ */
+uint16_t ADC_ReadConversionValue(ADC_T *adc)
+{
+    return (uint16_t) adc->REGDATA;
+}
+
+/*!
+ * @brief     Reads the specified ADC conversion result data in dual mode.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The Data conversion value.
+ *            - In dual mode:
+ *                Data[15:0] contain the regular data of ADC1.
+ *                Data[31:16] contain the regular data of ADC2.
+ *            - In triple mode:
+ *                Data[15:0] contain alternatively the regular data of ADC1, ADC3 and ADC2.
+ *                Data[31:16] contain alternatively the regular data of ADC2, ADC1 and ADC3.
+ */
+uint32_t ADC_ReadMultiValue(void)
+{
+    return ADC->CDATA;
+}
+
+/*!
+ * @brief     Enables the specified ADC DMA request.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The Data conversion value.
+ */
+void ADC_EnableDMA(ADC_T *adc)
+{
+    adc->CTRL2_B.DMAEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the specified ADC DMA request.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The Data conversion value.
+ */
+void ADC_DisableDMA(ADC_T *adc)
+{
+    adc->CTRL2_B.DMAEN = BIT_RESET;
+}
+/*!
+ * @brief     Enables  the ADC DMA request after last transfer (Single-ADC mode)
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The Data conversion value.
+ */
+void ADC_EnableDMARequest(ADC_T *adc)
+{
+    adc->CTRL2_B.DMADISSEL = BIT_SET;
+}
+/*!
+ * @brief     Disables  the ADC DMA request after last transfer (Single-ADC mode)
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    The Data conversion value.
+ */
+void ADC_DisableDMARequest(ADC_T *adc)
+{
+    adc->CTRL2_B.DMADISSEL = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the ADC DMA request after last transfer in multi ADC mode
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_EnableMultiModeDMARequest(void)
+{
+    ADC->CCTRL_B.DMADISSEL = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the ADC DMA request after last transfer in multi ADC mode
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ADC_DisableMultiModeDMARequest(void)
+{
+    ADC->CCTRL_B.DMADISSEL = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the specified ADC injected channel.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     channel: the ADC channel to configure.
+ *                    This parameter can be one of the following values:
+ *                    @arg ADC_CHANNEL_0:  ADC channel 0
+ *                    @arg ADC_CHANNEL_1:  ADC channel 1
+ *                    @arg ADC_CHANNEL_2:  ADC channel 2
+ *                    @arg ADC_CHANNEL_3:  ADC channel 3
+ *                    @arg ADC_CHANNEL_4:  ADC channel 4
+ *                    @arg ADC_CHANNEL_5:  ADC channel 5
+ *                    @arg ADC_CHANNEL_6:  ADC channel 6
+ *                    @arg ADC_CHANNEL_7:  ADC channel 7
+ *                    @arg ADC_CHANNEL_8:  ADC channel 8
+ *                    @arg ADC_CHANNEL_9:  ADC channel 9
+ *                    @arg ADC_CHANNEL_10: ADC channel 10
+ *                    @arg ADC_CHANNEL_11: ADC channel 11
+ *                    @arg ADC_CHANNEL_12: ADC channel 12
+ *                    @arg ADC_CHANNEL_13: ADC channel 13
+ *                    @arg ADC_CHANNEL_14: ADC channel 14
+ *                    @arg ADC_CHANNEL_15: ADC channel 15
+ *                    @arg ADC_CHANNEL_16: ADC channel 16
+ *                    @arg ADC_CHANNEL_17: ADC channel 17
+ *                    @arg ADC_CHANNEL_18: ADC Channel 18
+ *
+ * @param     rank: The rank in the regular group sequencer
+ *                     This parameter must be between 1 to 16.
+ *
+ * @param     sampleTime: the specified ADC channel SampleTime
+ *                     The parameter can be one of following values:
+ *                     @arg ADC_SAMPLETIME_3CYCLES:   Sample time equal to 3 cycles
+ *                     @arg ADC_SAMPLETIME_15CYCLES:  Sample time equal to 15 cycles
+ *                     @arg ADC_SAMPLETIME_28CYCLES:  Sample time equal to 28 cycles
+ *                     @arg ADC_SAMPLETIME_56CYCLES:  Sample time equal to 56 cycles
+ *                     @arg ADC_SAMPLETIME_84CYCLES:  Sample time equal to 84 cycles
+ *                     @arg ADC_SAMPLETIME_112CYCLES: Sample time equal to 112 cycles
+ *                     @arg ADC_SAMPLETIME_144CYCLES: Sample time equal to 144 cycles
+ *                     @arg ADC_SAMPLETIME_480CYCLES: Sample time equal to 480 cycles
+ *
+ * @retval    None
+ */
+
+void ADC_ConfigInjectedChannel(ADC_T *adc, uint8_t channel, uint8_t rank, uint8_t sampleTime)
+{
+    uint32_t temp1 = 0;
+    uint32_t temp2 = 0;
+
+    if (channel > ADC_CHANNEL_9)
+    {
+        temp1 = adc->SMPTIM1;
+        temp2 = (uint32_t)7 << (3 * (channel - 10));
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)sampleTime << (3 * (channel - 10));
+        temp1 |= temp2;
+        adc->SMPTIM1 = temp1;
+    }
+    else
+    {
+        temp1 = adc->SMPTIM2;
+        temp2 = (uint32_t)7 << (3 * channel);
+        temp1 &= ~temp2;
+        temp2 = (uint32_t)sampleTime << (3 * channel);
+        temp1 |= temp2;
+        adc->SMPTIM2 = temp1;
+    }
+
+    temp1 = adc->INJSEQ;
+    temp2 = (uint32_t)0x1F << (5 * ((rank + 3) - (adc->INJSEQ_B.INJSEQLEN + 1)));
+    temp1 &= ~temp2;
+    temp2 = (uint32_t)channel << (5 * ((rank + 3) - (adc->INJSEQ_B.INJSEQLEN + 1)));
+    temp1 |= temp2;
+    adc->INJSEQ = temp1;
+}
+
+/*!
+ * @brief     Configures the sequencer length for injected channels
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     length: The sequencer length.
+ *                    This parameter must be a number between 1 to 4.
+ *
+ * @retval    None
+ */
+void ADC_ConfigInjectedSequencerLength(ADC_T *adc, uint8_t length)
+{
+    adc->INJSEQ_B.INJSEQLEN = length - 1;
+}
+
+/*!
+ * @brief     Configures the specified ADC injected channel conversion value offset.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     channel: Select the ADC injected channel.
+ *                     This parameter can be one of the following values:
+ *                     @arg ADC_INJEC_CHANNEL_1: select Injected Channel 1
+ *                     @arg ADC_INJEC_CHANNEL_2: select Injected Channel 2
+ *                     @arg ADC_INJEC_CHANNEL_3: select Injected Channel 3
+ *                     @arg ADC_INJEC_CHANNEL_4: select Injected Channel 4
+ *
+ * @param     offset: The specified ADC injected channel offset.
+ *                    This parameter must be a 12bit value.
+ *
+ * @retval    None
+ */
+void ADC_ConfigInjectedOffset(ADC_T *adc, ADC_INJEC_CHANNEL_T channel, uint16_t offset)
+{
+    switch ((uint8_t)channel)
+    {
+    case 0x01:
+        adc->INJDOF1_B.INJDOF1 = offset;
+        break;
+    case 0x02:
+        adc->INJDOF2_B.INJDOF2 = offset;
+        break;
+    case 0x03:
+        adc->INJDOF3_B.INJDOF3 = offset;
+        break;
+    case 0x04:
+        adc->INJDOF4_B.INJDOF4 = offset;
+        break;
+    default :
+        break;
+    }
+}
+
+/*!
+ * @brief     Configures the specified ADC external trigger for injected channels conversion
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     extTrigInjecConv: Select the ADC trigger to start injected conversion
+ *                 This parameter can be one of the following values:
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR1_CC4:  Timer1 capture compare4 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR1_TRGO: Timer1 TRGO event selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR2_CC1:  Timer2 capture compare1 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR2_TRGO: Timer2 TRGO event selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR3_CC2:  Timer3 capture compare2 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR3_CC4:  Timer3 capture compare4 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_CC1:  Timer4 capture compare1 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_CC2:  Timer4 capture compare2 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_CC3:  Timer4 capture compare3 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_TRGO: Timer4 TRGO event selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR5_CC4:  Timer5 capture compare4 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR5_TRGO: Timer5 TRGO event selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR8_CC2:  Timer8 capture compare2 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR8_CC3:  Timer8 capture compare3 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR8_CC4:  Timer8 capture compare4 selected
+ *                 @arg ADC_EXT_TRIG_INJEC_CONV_EINT15: External interrupt line 15 event selected
+ *
+ * @retval    None
+ */
+void ADC_ConfigExternalTrigInjectedConv(ADC_T *adc, ADC_EXT_TRIG_INJEC_CONV_T extTrigInjecConv)
+{
+    adc->CTRL2_B.INJGEXTTRGSEL = extTrigInjecConv;
+}
+/*!
+ * @brief     Configures the ADCx external trigger edge for injected channels conversion.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     extTrigInjecConvEdge: Select the ADC trigger to start injected conversion
+ *                 This parameter can be one of the following values:
+ *                 @arg ADC_EXT_TRIG_INJEC_EDGE_NONE          :external trigger disabled for injected conversion
+ *                 @arg ADC_EXT_TRIG_INJEC_EDGE_RISING        :detection on rising edge
+ *                 @arg ADC_EXT_TRIG_INJEC_EDGE_FALLING       :detection on falling edge
+ *                 @arg ADC_EXT_TRIG_INJEC_EDGE_RISING_FALLING:detection on both rising and falling edge
+ *
+ * @retval    None
+ */
+void ADC_ConfigExternalTrigInjectedConvEdge(ADC_T *adc, ADC_EXT_TRIG_INJEC_EDGE_T extTrigInjecConvEdge)
+{
+    adc->CTRL2_B.INJEXTTRGEN = extTrigInjecConvEdge;
+}
+
+/*!
+ * @brief     Enables the selected ADC software start conversion of the injected channels.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_EnableSoftwareStartInjectedConv(ADC_T *adc)
+{
+    adc->CTRL2_B.INJCHSC = BIT_SET;
+}
+
+/*!
+ * @brief     Reads the selected ADC Software start injected conversion Status.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+uint8_t ADC_ReadSoftwareStartInjectedConvStatus(ADC_T *adc)
+{
+    return (uint8_t)(adc->CTRL2_B.INJCHSC);
+}
+
+/*!
+ * @brief     Enables the selected ADC automatic injected group conversion after regular one.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_EnableAutoInjectedConv(ADC_T *adc)
+{
+    adc->CTRL1_B.INJGACEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the selected ADC automatic injected group conversion after regular one.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_DisableAutoInjectedConv(ADC_T *adc)
+{
+    adc->CTRL1_B.INJGACEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enable the specified ADC discontinuous mode for injected group.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_EnableInjectedDiscMode(ADC_T *adc)
+{
+    adc->CTRL1_B.INJDISCEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the specified ADC discontinuous mode for injected group.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @retval    None
+ */
+void ADC_DisableInjectedDiscMode(ADC_T *adc)
+{
+    adc->CTRL1_B.INJDISCEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Reads the ADC injected channel conversion result
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     channel: the converted ADC injected channel.
+ *               This parameter can be one of the following values:
+ *               @arg ADC_INJEC_CHANNEL_1: Injected Channel1 selected
+ *               @arg ADC_INJEC_CHANNEL_2: Injected Channel2 selected
+ *               @arg ADC_INJEC_CHANNEL_3: Injected Channel3 selected
+ *               @arg ADC_INJEC_CHANNEL_4: Injected Channel4 selected
+ *
+ * @retval    The Data conversion value.
+ */
+uint16_t ADC_ReadInjectedConversionValue(ADC_T *adc, ADC_INJEC_CHANNEL_T channel)
+{
+    switch ((uint8_t)channel)
+    {
+    case 0x01:
+        return (uint16_t)adc->INJDATA1_B.INJDATA;
+    case 0x02:
+        return (uint16_t)adc->INJDATA2_B.INJDATA;
+    case 0x03:
+        return (uint16_t)adc->INJDATA3_B.INJDATA;
+    case 0x04:
+        return (uint16_t)adc->INJDATA4_B.INJDATA;
+    default :
+        return 0;
+    }
+}
+
+/*!
+ * @brief     Enable the specified ADC interrupt.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     interrupt: Select the ADC interrupt sources
+ *                       This parameter can be any combination of the following values:
+ *                       @arg ADC_INT_EOC: End of conversion interrupt mask
+ *                       @arg ADC_INT_AWD: Analog watchdog interrupt mask
+ *                       @arg ADC_INT_INJEOC: End of injected conversion interrupt mask
+ *                       @arg ADC_INT_OVR: Overrun interrupt enable
+ *
+ * @retval    None
+ */
+void ADC_EnableInterrupt(ADC_T *adc, uint32_t interrupt)
+{
+    adc->CTRL1 |= interrupt;
+}
+
+/*!
+ * @brief     Disables the specified ADC interrupt.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     interrupt: Select the ADC interrupt sources
+ *                       This parameter can be any combination of the following values:
+ *                       @arg ADC_INT_EOC: End of conversion interrupt mask
+ *                       @arg ADC_INT_AWD: Analog watchdog interrupt mask
+ *                       @arg ADC_INT_INJEOC: End of injected conversion interrupt mask
+ *                       @arg ADC_INT_OVR: Overrun interrupt enable
+ *
+ * @retval    None
+ */
+void ADC_DisableInterrupt(ADC_T *adc, uint32_t interrupt)
+{
+    adc->CTRL1 &= (uint32_t)~interrupt;
+}
+
+/*!
+ * @brief     Reads the pending ADC flag
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     flag: Select the flag to check
+ *                  This parameter can be one of the following values:
+ *                  @arg ADC_FLAG_AWD: Analog watchdog flag
+ *                  @arg ADC_FLAG_EOC: End of conversion flag
+ *                  @arg ADC_FLAG_INJEOC: End of injected group conversion flag
+ *                  @arg ADC_FLAG_INJCS: Start of injected group conversion flag
+ *                  @arg ADC_FLAG_REGCS: Start of regular group conversion flag
+ *                  @arg ADC_FLAG_OVR: Overrun flag
+ *
+ * @retval    SET or RESET
+ */
+uint8_t ADC_ReadStatusFlag(ADC_T *adc, ADC_FLAG_T flag)
+{
+    return (adc->STS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the pending ADC flag
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     flag: Select the flag to check
+ *                  This parameter can be one of the following values:
+ *                  @arg ADC_FLAG_AWD: Analog watchdog flag
+ *                  @arg ADC_FLAG_EOC: End of conversion flag
+ *                  @arg ADC_FLAG_INJEOC: End of injected group conversion flag
+ *                  @arg ADC_FLAG_INJCS: Start of injected group conversion flag
+ *                  @arg ADC_FLAG_REGCS: Start of regular group conversion flag
+ *                  @arg ADC_FLAG_OVR: Overrun flag
+ *
+ * @retval    None
+ */
+void ADC_ClearStatusFlag(ADC_T *adc, uint32_t flag)
+{
+    adc->STS = ~(uint32_t)flag;
+}
+
+/*!
+ * @brief     Reads the specified ADC Interrupt flag.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     flag: Select the ADC interrupt source.
+ *                  This parameter can be one of the following values:
+ *                  @arg ADC_INT_FLAG_EOC: End of conversion interrupt flag
+ *                  @arg ADC_INT_FLAG_AWD: Analog watchdog interrupt flag
+ *                  @arg ADC_INT_FLAG_INJEOC: End of injected conversion interrupt flag
+ *                  @arg ADC_INT_FLAG_OVR: Overrun interrupt flag
+ *
+ * @retval    SET or RESET
+ */
+uint16_t ADC_ReadIntFlag(ADC_T *adc, ADC_INT_FLAG_T flag)
+{
+    uint32_t itmask = 0;
+    uint32_t intStatus = 0;
+
+    itmask = (uint32_t)1 << (flag >> 8);
+    intStatus = adc->CTRL1 & itmask;
+
+    if (((adc->STS & (uint32_t)(flag & 0x3F)) != (uint32_t)RESET) && intStatus)
+    {
+        return SET;
+    }
+    else
+    {
+        return RESET;
+    }
+}
+
+/*!
+ * @brief     Clears the specified ADC Interrupt pending bits.
+ *
+ * @param     adc: Select ADCx where x can be 1, 2 or 3.
+ *
+ * @param     flag: Select the ADC interrupt source.
+ *                  This parameter can be any combination of the following values:
+ *                  @arg ADC_INT_FLAG_EOC: End of conversion interrupt flag
+ *                  @arg ADC_INT_FLAG_AWD: Analog watchdog interrupt flag
+ *                  @arg ADC_INT_FLAG_INJEOC: End of injected conversion interrupt flag
+ *                  @arg ADC_INT_FLAG_OVR: Overrun interrupt flag
+ *
+ * @retval    None
+ */
+void ADC_ClearIntFlag(ADC_T *adc, uint32_t flag)
+{
+    adc->STS = ~(uint32_t)(flag & 0x3F);
+}
+
+/**@} end of group ADC_Functions */
+/**@} end of group ADC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 1072 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_can.c

@@ -0,0 +1,1072 @@
+/*!
+ * @file        apm32f4xx_can.c
+ *
+ * @brief       This file provides all the CAN firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_can.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup CAN_Driver
+  * @brief CAN driver modules
+  @{
+*/
+
+/** @defgroup CAN_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset CAN registers
+ *
+ * @param     can: Select the CAN peripheral.
+ *
+ * @retval    None
+ */
+void CAN_Reset(CAN_T *can)
+{
+    if (can == CAN1)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN1);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN1);
+    }
+    else if (can == CAN2)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN2);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN2);
+    }
+}
+
+/*!
+ * @brief     Initialization parameter configuration
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     canConfig: Point to a CAN_Config_T structure.
+ *
+ * @retval    ERROR or SUCCEESS
+ */
+uint8_t CAN_Config(CAN_T *can, CAN_Config_T *canConfig)
+{
+    uint8_t  initStatus = ERROR;
+    uint32_t wait_ack = 0x00000000;
+
+    /* Exit from sleep mode */
+    can->MCTRL_B.SLEEPREQ = BIT_RESET;
+    /* Request initialisation */
+    can->MCTRL_B.INITREQ = BIT_SET;
+
+    /* Wait the acknowledge */
+    while (((can->MSTS_B.INITFLG) != BIT_SET) && (wait_ack != 0x0000FFFF))
+    {
+        wait_ack++;
+    }
+    /* Check acknowledge */
+    if (((can->MSTS_B.INITFLG) != BIT_SET))
+    {
+        initStatus = ERROR;
+    }
+    else
+    {
+        if (canConfig->autoBusOffManage == ENABLE)
+        {
+            can->MCTRL_B.ALBOFFM = BIT_SET;
+        }
+        else
+        {
+            can->MCTRL_B.ALBOFFM = BIT_RESET;
+        }
+
+        if (canConfig->autoWakeUpMode == ENABLE)
+        {
+            can->MCTRL_B.AWUPCFG = BIT_SET;
+        }
+        else
+        {
+            can->MCTRL_B.AWUPCFG = BIT_RESET;
+        }
+
+        if (canConfig->nonAutoRetran == ENABLE)
+        {
+            can->MCTRL_B.ARTXMD = BIT_SET;
+        }
+        else
+        {
+            can->MCTRL_B.ARTXMD = BIT_RESET;
+        }
+
+        if (canConfig->rxFIFOLockMode == ENABLE)
+        {
+            can->MCTRL_B.RXFLOCK = BIT_SET;
+        }
+        else
+        {
+            can->MCTRL_B.RXFLOCK = BIT_RESET;
+        }
+
+        if (canConfig->txFIFOPriority == ENABLE)
+        {
+            can->MCTRL_B.TXFPCFG = BIT_SET;
+        }
+        else
+        {
+            can->MCTRL_B.TXFPCFG = BIT_RESET;
+        }
+
+        /* Set the bit timing register */
+        can->BITTIM &= (uint32_t)0x3fffffff;
+        can->BITTIM |= (uint32_t)canConfig->mode << 30;
+        can->BITTIM_B.RSYNJW  = canConfig->syncJumpWidth;
+        can->BITTIM_B.TIMSEG1 = canConfig->timeSegment1;
+        can->BITTIM_B.TIMSEG2 = canConfig->timeSegment2;
+        can->BITTIM_B.BRPSC   = canConfig->prescaler - 1;
+
+        /* Request leave initialisation */
+        can->MCTRL_B.INITREQ = BIT_RESET;
+
+        wait_ack = 0;
+        /* Wait the acknowledge */
+        while (((can->MSTS_B.INITFLG) != BIT_RESET) && (wait_ack != 0x0000FFFF))
+        {
+            wait_ack++;
+        }
+        /* Check acknowledge */
+        if (((can->MSTS_B.INITFLG) != BIT_RESET))
+        {
+            initStatus = ERROR;
+        }
+        else
+        {
+            initStatus = SUCCESS;
+        }
+    }
+    return initStatus;
+}
+
+/*!
+ * @brief     Congig the CAN peripheral according to the specified parameters in the filterConfig.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     filterConfig :Point to a CAN_FilterConfig_T structure.
+ *
+ * @retval    None
+ */
+void CAN_ConfigFilter(CAN_FilterConfig_T *filterConfig)
+{
+    CAN1->FCTRL_B.FINITEN = BIT_SET;
+
+    CAN1->FACT &= ~(1 << filterConfig->filterNumber);
+
+    /* Filter Scale */
+    if (filterConfig->filterScale == CAN_FILTER_SCALE_16BIT)
+    {
+        /* 16-bit scale for the filter */
+        CAN1->FSCFG &= ~(1 << filterConfig->filterNumber);
+
+        CAN1->sFilterRegister[filterConfig->filterNumber].FBANK1 =
+            ((0x0000FFFF & filterConfig->filterMaskIdLow) << 16) |
+            (0x0000FFFF & filterConfig->filterIdLow);
+
+        CAN1->sFilterRegister[filterConfig->filterNumber].FBANK2 =
+            ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) |
+            (0x0000FFFF & filterConfig->filterIdHigh);
+    }
+
+    if (filterConfig->filterScale == CAN_FILTER_SCALE_32BIT)
+    {
+        CAN1->FSCFG |= (1 << filterConfig->filterNumber);
+
+        CAN1->sFilterRegister[filterConfig->filterNumber].FBANK1 =
+            ((0x0000FFFF & filterConfig->filterIdHigh) << 16) |
+            (0x0000FFFF & filterConfig->filterIdLow);
+
+        CAN1->sFilterRegister[filterConfig->filterNumber].FBANK2 =
+            ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) |
+            (0x0000FFFF & filterConfig->filterMaskIdLow);
+    }
+
+    /* Filter Mode */
+    if (filterConfig->filterMode == CAN_FILTER_MODE_IDMASK)
+    {
+        CAN1->FMCFG &= ~(1 << filterConfig->filterNumber);
+    }
+    else
+    {
+        CAN1->FMCFG |= (1 << filterConfig->filterNumber);
+    }
+
+    /* Filter FIFO assignment */
+    if (filterConfig->filterFIFO == CAN_FILTER_FIFO_0)
+    {
+        CAN1->FFASS &= ~(1 << filterConfig->filterNumber);
+    }
+    if (filterConfig->filterFIFO == CAN_FILTER_FIFO_1)
+    {
+        CAN1->FFASS |= (1 << filterConfig->filterNumber);
+    }
+
+    /* Filter activation */
+    if (filterConfig->filterActivation == ENABLE)
+    {
+        CAN1->FACT |= (1 << filterConfig->filterNumber);
+    }
+    CAN1->FCTRL_B.FINITEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Initialize a CAN_Config_T structure with the initial value.
+ *
+ * @param     canConfig :Point to a CAN_Config_T structure.
+ *
+ * @retval    None
+ */
+void CAN_ConfigStructInit(CAN_Config_T *canConfig)
+{
+    canConfig->autoBusOffManage = DISABLE;
+    canConfig->autoWakeUpMode   = DISABLE;
+    canConfig->nonAutoRetran    = DISABLE;
+    canConfig->rxFIFOLockMode   = DISABLE;
+    canConfig->txFIFOPriority   = DISABLE;
+    canConfig->mode             = CAN_MODE_NORMAL;
+    canConfig->syncJumpWidth    = CAN_SJW_1;
+    canConfig->timeSegment1     = CAN_TIME_SEGMENT1_4;
+    canConfig->timeSegment2     = CAN_TIME_SEGMENT2_3;
+    canConfig->prescaler        = 1;
+}
+
+/*!
+ * @brief     Select the start bank filter for slave CAN.
+ *
+ * @param     bankNum: the start slave bank filter from 1..27.
+ *
+ * @retval    None
+ */
+void CAN_SlaveStartBank(CAN_T *can, uint8_t bankNum)
+{
+    can->FCTRL_B.FINITEN = SET;
+    can->FCTRL_B.CAN2BN  = bankNum;
+    can->FCTRL_B.FINITEN = RESET;
+}
+
+/*!
+ * @brief     Enables the DBG Freeze for CAN.
+ *
+ * @param     can: Select the CAN peripheral.
+ *
+ * @retval    None
+ *
+ * @note      None
+ */
+void CAN_EnableDBGFreeze(CAN_T *can)
+{
+    can->MCTRL_B.DBGFRZE = ENABLE;
+}
+
+/*!
+ * @brief     Disable the DBG Freeze for CAN.
+ *
+ * @param     can: Select the CAN peripheral.
+ *
+ * @retval    None
+ *
+ * @note      None
+ */
+void CAN_DisableDBGFreeze(CAN_T *can)
+{
+    can->MCTRL_B.DBGFRZE = DISABLE;
+}
+
+/*!
+ * @brief     Initiates the transmission of a message.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     TxMessage: pointer to a CAN_TX_MESSAGE structure.
+ *
+ * @retval    The number of the mailbox which is used for transmission or 3 if No mailbox is empty.
+ */
+uint8_t CAN_TxMessage(CAN_T *can, CAN_TxMessage_T *TxMessage)
+{
+    uint8_t transmit_milbox = 0;
+
+    /* Select one empty transmit mailbox */
+    if ((can->TXSTS & 0x04000000) == 0x04000000)
+    {
+        transmit_milbox = 0;
+    }
+    else if ((can->TXSTS & 0x08000000) == 0x08000000)
+    {
+        transmit_milbox = 1;
+    }
+    else if ((can->TXSTS & 0x10000000) == 0x10000000)
+    {
+        transmit_milbox = 2;
+    }
+    else
+    {
+        /* No mailbox is empty*/
+        return 3;
+    }
+
+    /* Set up the Id */
+    can->sTxMailBox[transmit_milbox].TXMID &= 0x00000001;
+    if (TxMessage->typeID == CAN_TYPEID_STD)
+    {
+        can->sTxMailBox[transmit_milbox].TXMID |= (TxMessage->stdID << 21) | (TxMessage->remoteTxReq);
+    }
+    else
+    {
+        can->sTxMailBox[transmit_milbox].TXMID |= (TxMessage->extID << 3) | (TxMessage->typeID) | (TxMessage->remoteTxReq);
+    }
+
+    /* Set up the TXDLEN */
+    TxMessage->dataLengthCode &= 0x0F;
+    can->sTxMailBox[transmit_milbox].TXDLEN &= (uint32_t)0xFFFFFFF0;
+    can->sTxMailBox[transmit_milbox].TXDLEN |= TxMessage->dataLengthCode;
+
+    /* Set up the data field */
+    can->sTxMailBox[transmit_milbox].TXMDL = ((uint32_t)TxMessage->data[3] << 24) | ((uint32_t)TxMessage->data[2] << 16)
+            | ((uint32_t)TxMessage->data[1] << 8) | ((uint32_t)TxMessage->data[0]);
+    can->sTxMailBox[transmit_milbox].TXMDH = ((uint32_t)TxMessage->data[7] << 24) | ((uint32_t)TxMessage->data[6] << 16)
+            | ((uint32_t)TxMessage->data[5] << 8) | ((uint32_t)TxMessage->data[4]);
+    /* Request transmission */
+    can->sTxMailBox[transmit_milbox].TXMID |= 0x00000001;
+
+    return transmit_milbox;
+}
+
+/*!
+ * @brief     Checks the transmission of a message.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     TxMailbox: the number of the mailbox
+ *              This parameter can be one of the following values:
+ *              @arg CAN_TX_MAILBIX_0 : Tx mailbox0
+ *              @arg CAN_TX_MAILBIX_1 : Tx mailbox1
+ *              @arg CAN_TX_MAILBIX_2 : Tx mailbox2
+ *
+ * @retval    state: 0: Status of transmission is Failed
+ *                   1: Status of transmission is Ok
+ *                   2: transmit pending
+ */
+uint8_t CAN_TxMessageStatus(CAN_T *can, CAN_TX_MAILBIX_T TxMailbox)
+{
+    uint32_t state = 0;
+
+    switch (TxMailbox)
+    {
+    case (CAN_TX_MAILBIX_0):
+        state =   can->TXSTS & (0x00000001 | 0x00000002 | 0x04000000);
+        break;
+    case (CAN_TX_MAILBIX_1):
+        state =   can->TXSTS & (0x00000100 | 0x00000200 | 0x08000000);
+        break;
+    case (CAN_TX_MAILBIX_2):
+        state =   can->TXSTS & (0x00010000 | 0x00020000 | 0x10000000);
+        break;
+    default:
+        state = 0;
+        break;
+    }
+    switch (state)
+    {
+    /** transmit pending  */
+    case (0x0):
+        state = 2;
+        break;
+    /* transmit failed  */
+    case (0x00000001 | 0x04000000):
+        state = 0;
+        break;
+    case (0x00000100 | 0x08000000):
+        state = 0;
+        break;
+    case (0x00010000 | 0x10000000):
+        state = 0;
+        break;
+    /* transmit succeeded  */
+    case (0x00000001 | 0x00000002 | 0x04000000):
+        state = 1;
+        break;
+    case (0x00000100 | 0x00000200 | 0x08000000):
+        state = 1;
+        break;
+    case (0x00010000 | 0x00020000 | 0x10000000):
+        state = 1;
+        break;
+    default:
+        state = 0;
+        break;
+    }
+    return (uint8_t) state;
+}
+
+/*!
+ * @brief     Cancels a transmit request.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     mailBox: the number of the mailbox
+ *                     This parameter can be one of the following values:
+ *                     @arg CAN_TX_MAILBIX_0 : Tx mailbox 0
+ *                     @arg CAN_TX_MAILBIX_1 : Tx mailbox 1
+ *                     @arg CAN_TX_MAILBIX_2 : Tx mailbox 2
+ *
+ * @retval    None
+ */
+void CAN_CancelTxMailbox(CAN_T *can, CAN_TX_MAILBIX_T TxMailbox)
+{
+    switch (TxMailbox)
+    {
+    case CAN_TX_MAILBIX_0:
+        can->TXSTS_B.ABREQFLG0 = BIT_SET;
+        break;
+    case CAN_TX_MAILBIX_1:
+        can->TXSTS_B.ABREQFLG1 = BIT_SET;
+        break;
+    case CAN_TX_MAILBIX_2:
+        can->TXSTS_B.ABREQFLG2 = BIT_SET;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+ * @brief     Receives a message and save to a CAN_RxMessage_T structure.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     FIFONumber: Receive FIFO number.
+ *                        This parameter can be one of the following values:
+ *                        @arg CAN_RX_FIFO_0 : Receive FIFO 0
+ *                        @arg CAN_RX_FIFO_1 : Receive FIFO 1
+ *
+ * @param     RxMessage: pointer to a structure to receive the message.
+ *
+ * @retval    None
+ */
+void CAN_RxMessage(CAN_T *can, CAN_RX_FIFO_T FIFONumber, CAN_RxMessage_T *RxMessage)
+{
+    /* Get the Id */
+    RxMessage->typeID = ((uint8_t)0x04 & (can->sRxMailBox[FIFONumber].RXMID));
+    if (RxMessage->typeID == CAN_TYPEID_STD)
+    {
+        RxMessage->stdID = (can->sRxMailBox[FIFONumber].RXMID >> 21) & 0x000007FF;
+    }
+    else
+    {
+        RxMessage->extID = (can->sRxMailBox[FIFONumber].RXMID >> 3) & 0x1FFFFFFF;
+    }
+
+    RxMessage->remoteTxReq = can->sRxMailBox[FIFONumber].RXMID_B.RFTXREQ;
+    RxMessage->dataLengthCode = can->sRxMailBox[FIFONumber].RXDLEN_B.DLCODE;
+    RxMessage->filterMatchIndex = can->sRxMailBox[FIFONumber].RXDLEN_B.FMIDX;
+    /** Get the data field */
+    RxMessage->data[0] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE0;
+    RxMessage->data[1] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE1;
+    RxMessage->data[2] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE2;
+    RxMessage->data[3] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE3;
+    RxMessage->data[4] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE4;
+    RxMessage->data[5] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE5;
+    RxMessage->data[6] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE6;
+    RxMessage->data[7] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE7;
+
+    if (FIFONumber == CAN_RX_FIFO_0)
+    {
+        can->RXF0_B.RFOM0 = BIT_SET;
+    }
+    else
+    {
+        can->RXF1_B.RFOM1 = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Releases the specified FIFO.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     FIFONumber: Receive FIFO number
+ *                        This parameter can be one of the following values:
+ *                        @arg CAN_RX_FIFO_0 : Receive FIFO 0
+ *                        @arg CAN_RX_FIFO_1 : Receive FIFO 1
+ *
+ * @retval    None
+ */
+void CAN_ReleaseFIFO(CAN_T *can, CAN_RX_FIFO_T FIFONumber)
+{
+    if (FIFONumber == CAN_RX_FIFO_0)
+    {
+        can->RXF0_B.RFOM0 = BIT_SET;
+    }
+    else
+    {
+        can->RXF1_B.RFOM1 = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Returns the number of pending messages.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     FIFONumber: Receive FIFO number
+ *                        This parameter can be one of the following values:
+ *                        @arg CAN_RX_FIFO_0 : Receive FIFO 0
+ *                        @arg CAN_RX_FIFO_1 : Receive FIFO 1
+ *
+ * @retval    The number of pending message.
+ */
+uint8_t CAN_PendingMessage(CAN_T *can, CAN_RX_FIFO_T FIFONumber)
+{
+    if (FIFONumber == CAN_RX_FIFO_0)
+    {
+        return  can->RXF0 & 0x03;
+    }
+    else
+    {
+        return  can->RXF1 & 0x03;
+    }
+}
+
+/*!
+ * @brief     Select the CAN Operation mode
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     operatingMode: CAN Operating Mode
+ *                           This parameter can be one of the following values:
+ *                           @arg CAN_OPERATING_MODE_INIT  : Initialization mode
+ *                           @arg CAN_OPERATING_MODE_NORMAL: Normal mode
+ *                           @arg CAN_OPERATING_MODE_SLEEP : sleep mode
+ *
+ * @retval    modeState:status of the requested mode
+ *                      0:CAN failed entering the specific mode
+ *                      1:CAN Succeed entering the specific mode
+ */
+uint8_t CAN_OperatingMode(CAN_T *can, CAN_OPERATING_MODE_T operatingMode)
+{
+    uint8_t states = 0;
+    uint32_t time_out = 0x0000FFFF;
+
+    if (operatingMode == CAN_OPERATING_MODE_INIT)
+    {
+        /** Request initialisation */
+        can->MCTRL_B.SLEEPREQ = BIT_RESET;
+        can->MCTRL_B.INITREQ = BIT_SET;
+
+        /* Wait the acknowledge */
+        while ((can->MSTS_B.INITFLG != BIT_SET && can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
+        {
+            time_out --;
+        }
+        if ((can->MSTS_B.INITFLG == BIT_SET && can->MSTS_B.SLEEPFLG == BIT_RESET))
+        {
+            states = 1;
+        }
+    }
+    else if (operatingMode == CAN_OPERATING_MODE_NORMAL)
+    {
+        /** Request leave initialisation and sleep mode  and enter Normal mode */
+        can->MCTRL_B.SLEEPREQ = BIT_RESET;
+        can->MCTRL_B.INITREQ = BIT_RESET;
+
+        time_out = 0x0000FFFF;
+
+        while ((can->MSTS_B.INITFLG != BIT_RESET || can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
+        {
+            time_out --;
+        }
+        if ((can->MSTS_B.INITFLG == BIT_RESET || can->MSTS_B.SLEEPFLG == BIT_RESET))
+        {
+            states = 1;
+        }
+    }
+    else if (operatingMode == CAN_OPERATING_MODE_SLEEP)
+    {
+        /** Request Sleep mode */
+        can->MCTRL_B.SLEEPREQ = BIT_SET;
+        can->MCTRL_B.INITREQ = BIT_RESET;
+
+        time_out = 0x0000FFFF;
+
+        while ((can->MSTS_B.INITFLG != BIT_RESET && can->MSTS_B.SLEEPFLG != BIT_SET) && (time_out != 0))
+        {
+            time_out --;
+        }
+        if ((can->MSTS_B.INITFLG == BIT_RESET && can->MSTS_B.SLEEPFLG == BIT_SET))
+        {
+            states = 1;
+        }
+    }
+    return states ;
+}
+
+/*!
+ * @brief     Into the low power mode.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @retval    status: Status of entering sleep mode.
+ *                    0: Enter sleep fail
+ *                    1: Enter sleep success
+ */
+uint8_t CAN_SleepMode(CAN_T *can)
+{
+    /** Request Sleep mode */
+    can->MCTRL_B.SLEEPREQ = BIT_SET;
+    can->MCTRL_B.INITREQ = BIT_RESET;
+
+    if ((can->MSTS_B.INITFLG == BIT_RESET && can->MSTS_B.SLEEPFLG == BIT_SET))
+    {
+        return 1;
+    }
+    return 0;
+}
+
+/*!
+ * @brief     Wakes the CAN up.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @retval    status: Status of waking the CAN up
+ *                    0: WakeUp CAN fail,
+ *                    1: WakeUp CAN success
+ */
+uint8_t CAN_WakeUpMode(CAN_T *can)
+{
+    uint32_t time_out = 0x0000FFFF;
+
+    /** Wake up request */
+    can->MCTRL_B.SLEEPREQ = BIT_RESET;
+    while ((can->MSTS_B.SLEEPFLG == BIT_SET) && (time_out != 0))
+    {
+        time_out --;
+    }
+    if (can->MSTS_B.SLEEPFLG != BIT_SET)
+    {
+        return 1;
+    }
+    return 0;
+}
+
+/*!
+ * @brief     Read the can's last error code (LERRC)
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @retval    The Last Error Code.
+ */
+uint8_t CAN_ReadLastErrorCode(CAN_T *can)
+{
+    return can->ERRSTS_B.LERRC;
+}
+
+/*!
+ * @brief     Read the can Receive Error Counter(RXERRCNT)
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @retval    CAN Receive Error Counter.
+ */
+uint8_t CAN_ReadRxErrorCounter(CAN_T *can)
+{
+    return can->ERRSTS_B.RXERRCNT;
+}
+
+/*!
+ * @brief     Read the LSB of the 9-bit can Transmit Error Counter(TXERRCNT).
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @retval    Least Significant Byte Of The 9-Bit Transmit Error Counter.
+ */
+uint8_t CAN_ReadLSBTxErrorCounter(CAN_T *can)
+{
+    return can->ERRSTS_B.TXERRCNT;
+}
+
+/*!
+ * @brief     Enables the specified can interrupts.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     interrupts: specifies the CAN interrupt sources
+ *                        This parameter can be any combination of the following values:
+ *                        @arg CAN_INT_TXME   : Transmit mailbox empty Interrupt
+ *                        @arg CAN_INT_F0MP   : FIFO 0 message pending Interrupt
+ *                        @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
+ *                        @arg CAN_INT_F0OVR  : FIFO 0 overrun Interrupt
+ *                        @arg CAN_INT_F1MP   : FIFO 1 message pending Interrupt
+ *                        @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
+ *                        @arg CAN_INT_F1OVR  : FIFO 1 overrun Interrupt
+ *                        @arg CAN_INT_ERRW   : Error warning Interrupt
+ *                        @arg CAN_INT_ERRP   : Error passive Interrupt
+ *                        @arg CAN_INT_BOF    : Bus-off Interrupt
+ *                        @arg CAN_INT_LEC    : Last error record code Interrupt
+ *                        @arg CAN_INT_ERR    : Error Interrupt
+ *                        @arg CAN_INT_WUP    : Wake-up Interrupt
+ *                        @arg CAN_INT_SLEEP  : Sleep acknowledge Interrupt
+ *
+ * @retval    None
+ */
+void CAN_EnableInterrupt(CAN_T *can, uint32_t interrupts)
+{
+    can->INTEN |= interrupts;
+}
+
+/*!
+ * @brief     Disable the specified can interrupts.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     interrupts: specifies the CAN interrupt sources
+ *                        This parameter can be any combination of the following values:
+ *                        @arg CAN_INT_TXME   : Transmit mailbox empty Interrupt
+ *                        @arg CAN_INT_F0MP   : FIFO 0 message pending Interrupt
+ *                        @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
+ *                        @arg CAN_INT_F0OVR  : FIFO 0 overrun Interrupt
+ *                        @arg CAN_INT_F1MP   : FIFO 1 message pending Interrupt
+ *                        @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
+ *                        @arg CAN_INT_F1OVR  : FIFO 1 overrun Interrupt
+ *                        @arg CAN_INT_ERRW   : Error warning Interrupt
+ *                        @arg CAN_INT_ERRP   : Error passive Interrupt
+ *                        @arg CAN_INT_BOF    : Bus-off Interrupt
+ *                        @arg CAN_INT_LEC    : Last error record code Interrupt
+ *                        @arg CAN_INT_ERR    : Error Interrupt
+ *                        @arg CAN_INT_WUP    : Wake-up Interrupt
+ *                        @arg CAN_INT_SLEEP  : Sleep acknowledge Interrupt
+ *
+ * @retval    None
+ */
+void CAN_DisableInterrupt(CAN_T *can, uint32_t interrupts)
+{
+    can->INTEN &= ~interrupts;
+}
+
+/*!
+ * @brief     Read whether the specified CAN flag is set or not.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     flag: specifies the CAN flag.
+ *                  This parameter can be one of the following values:
+ *                  @arg CAN_FLAG_ERRW   : Error Warning Flag
+ *                  @arg CAN_FLAG_ERRP   : Error Passive Flag
+ *                  @arg CAN_FLAG_BOF    : Bus-Off Flag
+ *                  @arg CAN_FLAG_LERRC  : Last error record code Flag
+ *                  @arg CAN_FLAG_WUPI   : Wake up Flag
+ *                  @arg CAN_FLAG_SLEEP  : Sleep acknowledge Flag
+ *                  @arg CAN_FLAG_F0MP   : FIFO 0 Message Pending Flag
+ *                  @arg CAN_FLAG_F0FULL : FIFO 0 Full Flag
+ *                  @arg CAN_FLAG_F0OVR  : FIFO 0 Overrun Flag
+ *                  @arg CAN_FLAG_F1MP   : FIFO 1 Message Pending Flag
+ *                  @arg CAN_FLAG_F1FULL : FIFO 1 Full Flag
+ *                  @arg CAN_FLAG_F1OVR  : FIFO 1 Overrun Flag
+ *                  @arg CAN_FLAG_REQC0  : Request MailBox0 Flag
+ *                  @arg CAN_FLAG_REQC1  : Request MailBox1 Flag
+ *                  @arg CAN_FLAG_REQC2  : Request MailBox2 Flag
+ *
+ * @retval    flag staus:  RESET or SET
+ */
+uint8_t CAN_ReadStatusFlag(CAN_T *can, CAN_FLAG_T flag)
+{
+    uint8_t status = 0;
+
+    if ((flag & 0x00F00000) != RESET)
+    {
+        if ((can->ERRSTS & (flag & 0x000FFFFF)) != RESET)
+        {
+            status = SET;
+        }
+        else
+        {
+            status = RESET;
+        }
+    }
+    else if ((flag & 0x01000000) != RESET)
+    {
+        if ((can->MSTS & (flag & 0x000FFFFF)) != RESET)
+        {
+            status = SET;
+        }
+        else
+        {
+            status = RESET ;
+        }
+    }
+    else if ((flag & 0x08000000) != RESET)
+    {
+        if ((can->TXSTS & (flag & 0x000FFFFF)) != RESET)
+        {
+            status = SET;
+        }
+        else
+        {
+            status = RESET;
+        }
+    }
+    else if ((flag & 0x02000000) != RESET)
+    {
+        if ((can->RXF0 & (flag & 0x000FFFFF)) != RESET)
+        {
+            status = SET;
+        }
+        else
+        {
+            status = RESET;
+        }
+    }
+    else
+    {
+        if ((can->RXF1 & (flag & 0x000FFFFF)) != RESET)
+        {
+            status = SET;
+        }
+        else
+        {
+            status = RESET;
+        }
+    }
+    return status;
+}
+
+/*!
+ * @brief     Clears the CAN's pending flags.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     flag: specifies the CAN flag.
+ *                  This parameter can be one of the following values:
+ *                  @arg CAN_FLAG_LERRC : Last error record code Flag
+ *                  @arg CAN_FLAG_WUPI  : Wake up Flag
+ *                  @arg CAN_FLAG_SLEEP : Sleep acknowledge Flag
+ *                  @arg CAN_FLAG_F0FULL: FIFO 0 Full Flag
+ *                  @arg CAN_FLAG_F0OVR : FIFO 0 Overrun Flag
+ *                  @arg CAN_FLAG_F1FULL: FIFO 1 Full Flag
+ *                  @arg CAN_FLAG_F1OVR : FIFO 1 Overrun Flag
+ *                  @arg CAN_FLAG_REQC0 : Request MailBox0 Flag
+ *                  @arg CAN_FLAG_REQC1 : Request MailBox1 Flag
+ *                  @arg CAN_FLAG_REQC2 : Request MailBox2 Flag
+ *
+ * @retval    None
+ */
+void CAN_ClearStatusFlag(CAN_T *can, CAN_FLAG_T flag)
+{
+    uint32_t flagtmp = 0;
+
+    /** ERRSTS register */
+    if (flag == 0x30F00070)
+    {
+        can->ERRSTS = RESET;
+    }
+    else
+    {
+        flagtmp = flag & 0x000FFFFF;
+        if ((flag & 0x02000000) != RESET)
+        {
+            can->RXF0 = flagtmp;
+        }
+        else if ((flag & 0x04000000) != RESET)
+        {
+            can->RXF1 = flagtmp;
+        }
+        else if ((flag & 0x08000000) != RESET)
+        {
+            can->TXSTS = flagtmp;
+        }
+        else
+        {
+            can->MSTS = flagtmp;
+        }
+    }
+}
+
+/*!
+ * @brief     Read whether the specified can interrupt has occurred or not.
+ *
+ * @param     can: Select the CAN peripheral.
+ *
+ * @param     interrupts: specifies the CAN interrupt sources
+ *                        This parameter can be one of the following values:
+ *                        @arg CAN_INT_TXME   : Transmit mailbox empty Interrupt
+ *                        @arg CAN_INT_F0MP   : FIFO 0 message pending Interrupt
+ *                        @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
+ *                        @arg CAN_INT_F0OVR  : FIFO 0 overrun Interrupt
+ *                        @arg CAN_INT_F1MP   : FIFO 1 message pending Interrupt
+ *                        @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
+ *                        @arg CAN_INT_F1OVR  : FIFO 1 overrun Interrupt
+ *                        @arg CAN_INT_ERRW   : Error warning Interrupt
+ *                        @arg CAN_INT_ERRP   : Error passive Interrupt
+ *                        @arg CAN_INT_BOF    : Bus-off Interrupt
+ *                        @arg CAN_INT_LEC    : Last error record code Interrupt
+ *                        @arg CAN_INT_ERR    : Error Interrupt
+ *                        @arg CAN_INT_WUP    : Wake-up Interrupt
+ *                        @arg CAN_INT_SLEEP  : Sleep acknowledge Interrupt
+ *
+ * @retval    status : SET or RESET
+ */
+uint8_t CAN_ReadIntFlag(CAN_T *can, CAN_INT_T flag)
+{
+    uint8_t status = 0;
+
+    if ((can->INTEN & flag) != RESET)
+    {
+        switch (flag)
+        {
+        case CAN_INT_TXME:
+            status = can->TXSTS_B.REQCFLG0;
+            status |= can->TXSTS_B.REQCFLG1;
+            status |= can->TXSTS_B.REQCFLG2;
+            break;
+        case CAN_INT_F0MP:
+            status = can->RXF0_B.FMNUM0;
+            break;
+        case CAN_INT_F0FULL:
+            status = can->RXF0_B.FFULLFLG0;
+            break;
+        case CAN_INT_F0OVR:
+            status = can->RXF0_B.FOVRFLG0;
+            break;
+        case CAN_INT_F1MP:
+            status = can->RXF1_B.FMNUM1;
+            break;
+        case CAN_INT_F1FULL:
+            status = can->RXF1_B.FFULLFLG1;
+            break;
+        case CAN_INT_F1OVR:
+            status = can->RXF1_B.FOVRFLG1;
+            break;
+        case CAN_INT_WUP:
+            status = can->MSTS_B.WUPIFLG;
+            break;
+        case CAN_INT_SLEEP:
+            status = can->MSTS_B.SLEEPIFLG;
+            break;
+        case CAN_INT_ERRW:
+            status = can->ERRSTS_B.ERRWFLG;
+            break;
+        case CAN_INT_ERRP:
+            status = can->ERRSTS_B.ERRPFLG;
+            break;
+        case CAN_INT_BOF:
+            status = can->ERRSTS_B.BOFLG;
+            break;
+        case CAN_INT_LEC:
+            status = can->ERRSTS_B.LERRC;
+            break;
+        case CAN_INT_ERR:
+            status = can->MSTS_B.ERRIFLG;
+            break;
+        default:
+            status = RESET;
+            break;
+        }
+    }
+    else
+    {
+        status = RESET;
+    }
+    return status;
+}
+
+/*!
+ * @brief     Clears the can's interrupt flag.
+ *
+ * @param     can: Select the CAN peripheral which can be CAN1 or CAN2.
+ *
+ * @param     flag: Interrupt pending bit to clear
+ *                  This parameter can be one of the following values:
+ *                  @arg CAN_INT_TXME   : Transmit mailbox empty Interrupt
+ *                  @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
+ *                  @arg CAN_INT_F0OVR  : FIFO 0 overrun Interrupt
+ *                  @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
+ *                  @arg CAN_INT_F1OVR  : FIFO 1 overrun Interrupt
+ *                  @arg CAN_INT_ERRW   : Error warning Interrupt
+ *                  @arg CAN_INT_ERRP   : Error passive Interrupt
+ *                  @arg CAN_INT_BOF    : Bus-off Interrupt
+ *                  @arg CAN_INT_LEC    : Last error record code Interrupt
+ *                  @arg CAN_INT_ERR    : Error Interrupt
+ *                  @arg CAN_INT_WUP    : Wake-up Interrupt
+ *                  @arg CAN_INT_SLEEP  : Sleep acknowledge Interrupt
+ *
+ * @retval    None
+ */
+void CAN_ClearIntFlag(CAN_T *can, CAN_INT_T flag)
+{
+    switch (flag)
+    {
+    case CAN_INT_TXME:
+        can->TXSTS_B.REQCFLG0 = BIT_SET;
+        can->TXSTS_B.REQCFLG1 = BIT_SET;
+        can->TXSTS_B.REQCFLG2 = BIT_SET;
+        break;
+    case CAN_INT_F0FULL:
+        can->RXF0_B.FFULLFLG0 = BIT_SET;
+        break;
+    case CAN_INT_F0OVR:
+        can->RXF0_B.FOVRFLG0  = BIT_SET;
+        break;
+    case CAN_INT_F1FULL:
+        can->RXF1_B.FFULLFLG1 = BIT_SET;
+        break;
+    case CAN_INT_F1OVR:
+        can->RXF1_B.FOVRFLG1  = BIT_SET;
+        break;
+    case CAN_INT_WUP:
+        can->MSTS_B.WUPIFLG   = BIT_SET;
+        break;
+    case CAN_INT_SLEEP:
+        can->MSTS_B.SLEEPIFLG = BIT_SET;
+        break;
+    case CAN_INT_ERRW:
+        can->MSTS_B.ERRIFLG = BIT_SET;
+        break;
+    case CAN_INT_ERRP:
+        can->MSTS_B.ERRIFLG = BIT_SET;
+        break;
+    case CAN_INT_BOF:
+        can->MSTS_B.ERRIFLG = BIT_SET;
+        break;
+    case CAN_INT_LEC:
+        can->ERRSTS_B.LERRC = BIT_RESET;
+        can->MSTS_B.ERRIFLG = BIT_SET;
+        break;
+    case CAN_INT_ERR:
+        can->ERRSTS_B.LERRC = BIT_RESET;
+        can->MSTS_B.ERRIFLG = BIT_SET;
+        break;
+    default:
+        break;
+    }
+}
+
+/**@} end of group CAN_Functions */
+/**@} end of group CAN_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 125 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_crc.c

@@ -0,0 +1,125 @@
+/*!
+ * @file        apm32f4xx_crc.c
+ *
+ * @brief       This file provides all the CRC firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_crc.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup CRC_Driver
+  * @brief CRC driver modules
+  @{
+*/
+
+/** @defgroup CRC_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset CRC data register.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void CRC_ResetDATA(void)
+{
+    CRC->CTRL_B.RST = BIT_SET;
+}
+
+/*!
+ * @brief     Calculate CRC of a 32bit data word.
+ *
+ * @param     data: a data word to compute its CRC.
+ *                  This parameter can be a 32bit value:
+ *
+ * @retval    A 32-bit CRC value
+ */
+uint32_t CRC_CalculateCRC(uint32_t data)
+{
+    CRC->DATA = data;
+
+    return (CRC->DATA);
+}
+
+/*!
+ * @brief     Computes the 32-bit CRC of a given buffer of data word(32-bit).
+ *
+ * @param     buf: Pointer to the buffer containing the data to be computed.
+ *
+ * @param     bufLen: The length of buffer which is computed.
+ *
+ * @retval    A 32-bit CRC value
+ */
+uint32_t CRC_CalculateBlockCRC(uint32_t *buf, uint32_t bufLen)
+{
+    while (bufLen--)
+    {
+        CRC->DATA = *buf++;
+    }
+
+    return (CRC->DATA);
+}
+
+/*!
+ * @brief     Returns the current CRC value.
+ *
+ * @param     None
+ *
+ * @retval    A 32-bit CRC value
+ */
+uint32_t CRC_ReadCRC(void)
+{
+    return (CRC->DATA);
+}
+
+/*!
+ * @brief     Saves a 8bit data in the Independent Data register(INDATA).
+ *
+ * @param     inData: a 8-bit value to be stored in the ID register
+ *
+ * @retval    None
+ */
+void CRC_WriteIDRegister(uint8_t inData)
+{
+    CRC->INDATA = inData;
+}
+
+/*!
+ * @brief      Reads a 8-bit data saved in the Independent Data register(INDATA).
+ *
+ * @param      None
+ *
+ * @retval     a 8-bit value from the INDATA register
+ */
+uint8_t CRC_ReadIDRegister(void)
+{
+    return (CRC->INDATA);
+}
+
+/**@} end of group CRC_Functions */
+/**@} end of group CRC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 463 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp.c

@@ -0,0 +1,463 @@
+/*!
+ * @file        apm32f4xx_cryp.c
+ *
+ * @brief       This file provides all the CRYP firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_cryp.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup CRYP_Driver
+  * @brief CRYP driver modules
+  @{
+*/
+
+/** @defgroup CRYP_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset CRYP
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void CRYP_Reset(void)
+{
+    RCM_EnableAHB2PeriphReset(RCM_AHB2_PERIPH_CRYP);
+    RCM_DisableAHB2PeriphReset(RCM_AHB2_PERIPH_CRYP);
+}
+
+/*!
+ * @brief     Configure CRYP
+ *
+ * @param     crypConfig: pointer to a CRYP_Config_T structure
+ *
+ * @retval    None
+ */
+void CRYP_Config(CRYP_Config_T *crypConfig)
+{
+    CRYP->CTRL_B.ALGODIRSEL = crypConfig->algoDir;
+    CRYP->CTRL_B.ALGOMSEL   = crypConfig->algoMode;
+    CRYP->CTRL_B.DTSEL      = crypConfig->dataType;
+
+    /* select Key size (only AES algorithm)*/
+    if (crypConfig->algoMode >= CRYP_ALGOMODE_AES_ECB)
+    {
+        CRYP->CTRL_B.KSIZESEL = crypConfig->keySize;
+    }
+}
+
+/*!
+ * @brief     Default the CRYP_ConfigStructInit member value.
+ *
+ * @param     crcyConfig: pointer to a CRYP_Config_T structure
+ *
+ * @retval    None
+ */
+void CRYP_ConfigStructInit(CRYP_Config_T *crypConfig)
+{
+    crypConfig->algoDir  = CRYP_ALGODIR_ENCRYPT;
+    crypConfig->algoMode = CRYP_ALGOMODE_TDES_ECB;
+    crypConfig->dataType = CRYP_DATATYPE_32B;
+    crypConfig->keySize  = CRYP_KEYSIZE_128B;
+}
+
+/*!
+ * @brief     Configure CRYP Keys
+ *
+ * @param     keyConfig: pointer to a CRYP_KeyConfig_T structure.
+ *
+ * @retval    None
+ */
+void CRYP_ConfigKey(CRYP_KeyConfig_T *keyConfig)
+{
+    /* Key Initialisation */
+    CRYP->K0L = keyConfig->key0Left;
+    CRYP->K0R = keyConfig->key0Right;
+    CRYP->K1L = keyConfig->key1Left;
+    CRYP->K1R = keyConfig->key1Right;
+    CRYP->K2L = keyConfig->key2Left;
+    CRYP->K2R = keyConfig->key2Right;
+    CRYP->K3L = keyConfig->key3Left;
+    CRYP->K3R = keyConfig->key3Right;
+}
+
+/*!
+ * @brief     Default the CRYP_KeyConfigStructInit member value.
+ *
+ * @param     keyConfig: pointer to a CRYP_KeyConfig_T structure.
+ *
+ * @retval    None
+ */
+void CRYP_ConfigKeyStructInit(CRYP_KeyConfig_T *keyConfig)
+{
+    keyConfig->key0Left  = 0;
+    keyConfig->key0Right = 0;
+    keyConfig->key1Left  = 0;
+    keyConfig->key1Right = 0;
+    keyConfig->key2Left  = 0;
+    keyConfig->key2Right = 0;
+    keyConfig->key3Left  = 0;
+    keyConfig->key3Right = 0;
+}
+
+/*!
+ * @brief     Configure CRYP Initialization Vectors(IV)
+ *
+ * @param     IVConfig: pointer to a CRYP_IVConfig_T structure.
+ *
+ * @retval    None
+ */
+void CRYP_ConfigIV(CRYP_IVConfig_T *IVConfig)
+{
+    CRYP->IV0L = IVConfig->IV0Left;
+    CRYP->IV0R = IVConfig->IV0Right;
+    CRYP->IV1L = IVConfig->IV1Left;
+    CRYP->IV1R = IVConfig->IV1Right;
+}
+
+/*!
+ * @brief     Default the CRYP_ConfigIVStructInit member value.
+ *
+ * @param     keyConfig: pointer to a CRYP_IVConfig_T structure.
+ *
+ * @retval    None
+ */
+void CRYP_ConfigIVStructInit(CRYP_IVConfig_T *IVConfig)
+{
+    IVConfig->IV0Left  = 0;
+    IVConfig->IV0Right = 0;
+    IVConfig->IV1Left  = 0;
+    IVConfig->IV1Right = 0;
+}
+
+/*!
+ * @brief     Flushes the IN and OUT FIFOs
+ *
+ * @param     None
+ *
+ * @retval    None
+ *
+ * @note      The FIFOs must be flushed only when BUSY flag is reset.
+ */
+void CRYP_FlushFIFO(void)
+{
+    CRYP->CTRL_B.FFLUSH = SET;
+}
+
+/*!
+ * @brief     Enables the CRYP peripheral.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void CRYP_Enable(void)
+{
+    CRYP->CTRL_B.CRYPEN = SET;
+}
+/*!
+ * @brief     Disable the CRYP peripheral.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void CRYP_Disable(void)
+{
+    CRYP->CTRL_B.CRYPEN = RESET;
+}
+
+/*!
+ * @brief     Writes data in the Data Input register.
+ *
+ * @param     Data: data to write in Data Input register
+ *
+ * @retval    None
+ *
+ * @note      After the DATAIN register has been read once or several times,
+ *            the FIFO must be flushed (using CRYP_FlushFIFO()).
+ */
+void CRYP_InData(uint32_t Data)
+{
+    CRYP->DATAIN = Data;
+}
+
+/*!
+ * @brief     Returns the last data into the output FIFO.
+ *
+ * @param     None
+ *
+ * @retval    Last data into the output FIFO.
+ */
+uint32_t CRYP_OutData(void)
+{
+    return CRYP->DATAOUT;
+}
+
+/*!
+ * @brief     Saves the CRYP peripheral Context.
+ *
+ * @param     context: pointer to a CRYP_Context_T structure.
+ *
+ * @param     keyConfig: pointer to a CRYP_IVConfig_T structure.
+ *
+ * @retval    None
+ *
+ * @note      This function stops DMA transfer before to save the context. After
+ *            restoring the context, you have to enable the DMA again (if the DMA
+ *            was previously used).
+ */
+uint32_t CRYP_SaveContext(CRYP_Context_T *context, CRYP_KeyConfig_T *keyConfig)
+{
+    uint32_t flag = 0;
+    uint32_t bitstatus = 0;
+    uint32_t timeout = 0;
+    uint32_t status = 0;
+
+    /* Stop DMA transfers on the IN FIFO */
+    CRYP->DMACTRL_B.INEN = RESET;
+
+    if (CRYP->CTRL_B.ALGOMSEL <= 0x01)
+    {
+        flag =  CRYP_FLAG_IFEMPT | CRYP_FLAG_BUSY ;
+    }
+    else /* AES or DES */
+    {
+        flag =  CRYP_FLAG_IFEMPT | CRYP_FLAG_BUSY | CRYP_FLAG_OFEMPT;
+    }
+
+    do
+    {
+        bitstatus = CRYP->STS & flag;
+        timeout++;
+    }
+    while ((timeout != 0xFFFF) && (bitstatus != CRYP_FLAG_IFEMPT));
+
+    if ((CRYP->STS & flag) != CRYP_FLAG_IFEMPT)
+    {
+        status = ERROR;
+    }
+    else
+    {
+        /* Stop DMA transfers on the OUT FIFO  */
+        CRYP->DMACTRL_B.OUTEN = BIT_RESET;
+        CRYP->CTRL_B.CRYPEN = BIT_RESET;
+
+        /* Save the current configuration (bits [9:2] in the CRYP_CTRL register) */
+        context->curCTRL  = CRYP->CTRL & 0xFC;
+
+        /* Save the initialization vectors */
+        context->IV0L = CRYP->IV0L;
+        context->IV0R = CRYP->IV0R;
+        context->IV1L = CRYP->IV1L;
+        context->IV1R = CRYP->IV1R;
+
+        /* Save the key value */
+        context->K0L = keyConfig->key0Left;
+        context->K0R = keyConfig->key0Right;
+        context->K1L = keyConfig->key1Left;
+        context->K1R = keyConfig->key1Right;
+        context->K2L = keyConfig->key2Left;
+        context->K2R = keyConfig->key2Right;
+        context->K3L = keyConfig->key3Left;
+        context->K3R = keyConfig->key3Right;
+
+        status = SUCCESS;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Restores the CRYP peripheral Context.
+ *
+ * @param     context: pointer to a CRYP_Context_T structure
+ *
+ * @retval    None
+ *
+ * @note      Since the DMA transfer is stopped in CRYP_SaveContext() function,
+ *            after restoring the context, you have to enable the DMA again (if the
+ *            DMA was previously used).
+ */
+void CRYP_RestoreContext(CRYP_Context_T *context)
+{
+    /* Restore The CTRL value */
+    CRYP->CTRL = context->curCTRL;
+
+    /* Restore The key value */
+    CRYP->K0L = context->K0L;
+    CRYP->K0R = context->K0R;
+    CRYP->K1L = context->K1L;
+    CRYP->K1R = context->K1R;
+    CRYP->K2L = context->K2L;
+    CRYP->K2R = context->K2R;
+    CRYP->K3L = context->K3L;
+    CRYP->K3R = context->K3R;
+
+    /* Restore the IV */
+    CRYP->IV0L = context->IV0L;
+    CRYP->IV0R = context->IV0R;
+    CRYP->IV1L = context->IV1L;
+    CRYP->IV1R = context->IV1R;
+
+    /* Enable the cryptographic processor */
+    CRYP->CTRL_B.CRYPEN = BIT_SET;
+}
+/*!
+ * @brief     Enable the CRYP DMA.
+ *
+ * @param     dmaReq: CRYP DMA transfer request
+ *              This parameter can be one of the following values:
+ *              @arg CRYP_DMAREQ_DATAIN     : DMA Input Enable
+ *              @arg CRYP_DMAREQ_DATAOUT    : DMA Output Enable
+ *
+ * @retval    None
+ */
+void CRYP_EnableDMA(CRYP_DMAREQ_T dmaReq)
+{
+    if (dmaReq == CRYP_DMAREQ_DATAIN)
+    {
+        CRYP->DMACTRL_B.INEN = SET;
+    }
+    else if (dmaReq == CRYP_DMAREQ_DATAOUT)
+    {
+        CRYP->DMACTRL_B.OUTEN = SET;
+    }
+}
+
+/*!
+ * @brief     Disable  the CRYP DMA.
+ *
+ * @param     dmaReq: CRYP DMA transfer request
+ *              This parameter can be one of the following values:
+ *              @arg CRYP_DMAREQ_DATAIN     : DMA Input Enable
+ *              @arg CRYP_DMAREQ_DATAOUT    : DMA Output Enable
+ *
+ * @retval    None
+ */
+void CRYP_DisableDMA(CRYP_DMAREQ_T dmaReq)
+{
+    if (dmaReq == CRYP_DMAREQ_DATAIN)
+    {
+        CRYP->DMACTRL_B.INEN = RESET;
+    }
+    else if (dmaReq == CRYP_DMAREQ_DATAOUT)
+    {
+        CRYP->DMACTRL_B.OUTEN = RESET;
+    }
+}
+
+/*!
+ * @brief     Enable the CRYP Interrupt.
+ *
+ * @param     interrupt: specifies the CRYP interrupt sources
+ *            This parameter can be any combination of the following values:
+ *              @arg CRYP_INT_IN:  Input FIFO interrupt
+ *              @arg CRYP_INT_OUT: Output FIFO interrupt
+ *
+ * @retval    None
+ */
+void CRYP_EnableInterrupt(uint8_t interrupt)
+{
+    CRYP->INTMASK |= interrupt;
+}
+
+/*!
+ * @brief     Disable the CRYP Interrupt.
+ *
+ * @param     interrupt: specifies the CRYP interrupt sources
+ *            This parameter can be any combination of the following values:
+ *              @arg CRYP_INT_IN:  Input FIFO interrupt
+ *              @arg CRYP_INT_OUT: Output FIFO interrupt
+ *
+ * @retval    None
+ */
+void CRYP_DisableInterrupt(uint8_t interrupt)
+{
+    CRYP->INTMASK &= ~interrupt;
+}
+
+/*!
+ * @brief     Read the CRYP Interrupt flag.
+ *
+ * @param     flag: specifies the CRYP flag
+ *            This parameter can be one of the following values:
+ *              @arg CRYP_INT_IN:  Input FIFO interrupt
+ *              @arg CRYP_INT_OUT: Output FIFO interrupt
+ *
+ * @retval    SET or RESET
+ */
+
+uint8_t CRYP_ReadIntFlag(CRYP_INT_T flag)
+{
+    return (CRYP->INTMASK & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Reads the CRYP flag.
+ *
+ * @param     flag: specifies the flag to check.
+ *            This parameter can be one of the following values:
+ *              @arg CRYP_FLAG_IFEMPT:  Input FIFO Empty flag.
+ *              @arg CRYP_FLAG_IFFULL:  Input FIFO Not Full flag.
+ *              @arg CRYP_FLAG_OFEMPT:  Output FIFO Not Empty flag
+ *              @arg CRYP_FLAG_OFFULL:  Output FIFO Full flag.
+ *              @arg CRYP_FLAG_BUSY:    Busy flag.
+ *              @arg CRYP_FLAG_INISTS:  Input FIFO raw interrupt flag.
+ *              @arg CRYP_FLAG_OUTISTS: Output FIFO raw interrupt flag.
+ *
+ * @retval    SET or RESET.
+ */
+uint8_t CRYP_ReadStatusFlag(CRYP_FLAG_T flag)
+{
+    if (flag & 0x20)
+    {
+        return (CRYP->INTSTS & flag) ? SET : RESET;
+    }
+    else
+    {
+        return (CRYP->STS & flag) ? SET : RESET;
+    }
+}
+
+/*!
+ * @brief     Returns the CRYP peripheral Cmd
+ *
+ * @param     None
+ *
+ * @retval    ENABLE or DISABLE
+ */
+uint8_t CRYP_ReadCmdStatus(void)
+{
+    return (CRYP->CTRL_B.CRYPEN);
+}
+
+/**@} end of group CRYP_Functions */
+/**@} end of group CRYP_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 553 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_aes.c

@@ -0,0 +1,553 @@
+/*!
+ * @file        apm32f4xx_cryp_aes.c
+ *
+ * @brief       This file provides high level functions to encrypt and decrypt,
+ *              Input message using AES in ECB/CBC/CTR modes.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_cryp.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup CRYP_AES_Driver
+  * @brief CRYP AES driver modules
+  @{
+*/
+
+/** @defgroup CRYP_AES_Functions
+  @{
+*/
+
+/*!
+ * @brief     Encrypt and decrypt using AES in EBC Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:     Key used for AES algorithm.
+ * @param     keysize: length of the Key, must be a 128, 192 or 256.
+ * @param     input:   Input buffer.
+ * @param     length:  length of the Input buffer, must be a multiple of 16.
+ * @param     output:  Output buffer.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t CRYP_AES_ECB(CRYP_MODE_T mode, uint8_t *key,    uint16_t keysize,
+                     uint8_t *input, uint32_t length, uint8_t  *output)
+{
+    CRYP_Config_T    AES_crypConfig;
+    CRYP_KeyConfig_T AES_keyConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&AES_keyConfig);
+
+    switch (keysize)
+    {
+    case 128:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_128B;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    case 192:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_192B;
+        AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    case 256:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_256B;
+        AES_keyConfig.key0Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key0Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    default:
+        break;
+    }
+
+    if (mode == CRYP_MODE_DECRYPT)
+    {
+        CRYP_FlushFIFO();
+
+        AES_crypConfig.algoDir  = CRYP_ALGODIR_DECRYPT;
+        AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_KEY;
+        AES_crypConfig.dataType = CRYP_DATATYPE_32B;
+        CRYP_Config(&AES_crypConfig);
+        CRYP_ConfigKey(&AES_keyConfig);
+        CRYP_Enable();
+
+        counter = 0;
+        do
+        {
+            flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+            counter++;
+        }
+        while ((counter != 0x00010000) && (flag != RESET));
+
+        if (flag == SET)
+        {
+            status = ERROR;
+        }
+        else
+        {
+            AES_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
+        }
+    }
+    else
+    {
+        CRYP_ConfigKey(&AES_keyConfig);
+        AES_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+
+    AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_ECB;
+    AES_crypConfig.dataType = CRYP_DATATYPE_8B,
+    CRYP_Config(&AES_crypConfig);
+
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+
+    for (i = 0; i < length; i += 16)
+    {
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+
+        counter = 0;
+        do
+        {
+            flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+            counter++;
+        }
+        while ((counter != 0x00010000) && (flag != RESET));
+
+        if (flag == SET)
+        {
+            status = ERROR;
+        }
+        else
+        {
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+        }
+    }
+    CRYP_Disable();
+    return status;
+}
+
+/*!
+ * @brief     Encrypt and decrypt using AES in CBC Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:     Key used for AES algorithm.
+ * @param     keysize: length of the Key, must be a 128, 192 or 256.
+ * @param     IV:      Initialisation Vectors used for AES algorithm.
+ * @param     input:   Input buffer.
+ * @param     length:  length of the Input buffer, must be a multiple of 16.
+ * @param     output:  Output buffer.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t CRYP_AES_CBC(CRYP_MODE_T mode, uint8_t *key,    uint16_t keysize,
+                     uint8_t IV[16],  uint8_t  *input,
+                     uint32_t length, uint8_t  *output)
+{
+    CRYP_Config_T    AES_crypConfig;
+    CRYP_KeyConfig_T AES_keyConfig;
+    CRYP_IVConfig_T  AES_IVConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+    uint32_t IVAddr     = (uint32_t)IV;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&AES_keyConfig);
+
+    switch (keysize)
+    {
+    case 128:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_128B;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    case 192:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_192B;
+        AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    case 256:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_256B;
+        AES_keyConfig.key0Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key0Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    default:
+        break;
+    }
+
+    AES_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    AES_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    AES_IVConfig.IV1Left  = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    AES_IVConfig.IV1Right = __REV(*(uint32_t *)(IVAddr));
+
+    if (mode == CRYP_MODE_DECRYPT)
+    {
+        CRYP_FlushFIFO();
+
+        AES_crypConfig.algoDir  = CRYP_ALGODIR_DECRYPT;
+        AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_KEY;
+        AES_crypConfig.dataType = CRYP_DATATYPE_32B;
+        CRYP_Config(&AES_crypConfig);
+        CRYP_ConfigKey(&AES_keyConfig);
+        CRYP_Enable();
+
+        counter = 0;
+        do
+        {
+            flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+            counter++;
+        }
+        while ((counter != 0x00010000) && (flag != RESET));
+
+        if (flag == SET)
+        {
+            status = ERROR;
+        }
+        else
+        {
+            AES_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
+        }
+    }
+    else
+    {
+        CRYP_ConfigKey(&AES_keyConfig);
+        AES_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+
+    AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_CBC;
+    AES_crypConfig.dataType = CRYP_DATATYPE_8B,
+    CRYP_Config(&AES_crypConfig);
+    CRYP_ConfigIV(&AES_IVConfig);
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+
+    for (i = 0; i < length; i += 16)
+    {
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+
+        counter = 0;
+        do
+        {
+            flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+            counter++;
+        }
+        while ((counter != 0x00010000) && (flag != RESET));
+
+        if (flag == SET)
+        {
+            status = ERROR;
+        }
+        else
+        {
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+        }
+    }
+    CRYP_Disable();
+    return status;
+}
+
+/*!
+ * @brief     Encrypt and decrypt using AES in CTR Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:     Key used for AES algorithm.
+ * @param     keysize: length of the Key, must be a 128, 192 or 256.
+ * @param     IV:      Initialisation Vectors used for AES algorithm.
+ * @param     input:   Input buffer.
+ * @param     length:  length of the Input buffer, must be a multiple of 16.
+ * @param     output:  Output buffer.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t CRYP_AES_CTR(CRYP_MODE_T mode, uint8_t  *key,   uint16_t keysize,
+                     uint8_t  IV[16], uint8_t  *input,
+                     uint32_t length, uint8_t  *output)
+{
+    CRYP_Config_T    AES_crypConfig;
+    CRYP_KeyConfig_T AES_keyConfig;
+    CRYP_IVConfig_T  AES_IVConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+    uint32_t IVAddr     = (uint32_t)IV;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&AES_keyConfig);
+
+    switch (keysize)
+    {
+    case 128:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_128B;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    case 192:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_192B;
+        AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    case 256:
+        AES_crypConfig.keySize = CRYP_KEYSIZE_256B;
+        AES_keyConfig.key0Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key0Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+        keyAddr += 0x04;
+        AES_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+        break;
+
+    default:
+        break;
+    }
+
+    AES_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    AES_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    AES_IVConfig.IV1Left  = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    AES_IVConfig.IV1Right = __REV(*(uint32_t *)(IVAddr));
+
+    CRYP_ConfigKey(&AES_keyConfig);
+
+    if (mode == CRYP_MODE_DECRYPT)
+    {
+        AES_crypConfig.algoDir  = CRYP_ALGODIR_DECRYPT;
+    }
+    else
+    {
+        AES_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+
+    AES_crypConfig.algoMode = CRYP_ALGOMODE_AES_CTR;
+    AES_crypConfig.dataType = CRYP_DATATYPE_8B,
+
+    CRYP_Config(&AES_crypConfig);
+    CRYP_ConfigIV(&AES_IVConfig);
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+
+    for (i = 0; i < length; i += 16)
+    {
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+        CRYP_InData(*(uint32_t *)(inputAddr));
+        inputAddr += 0x04;
+
+        counter = 0;
+        do
+        {
+            flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+            counter++;
+        }
+        while ((counter != 0x00010000) && (flag != RESET));
+
+        if (flag == SET)
+        {
+            status = ERROR;
+        }
+        else
+        {
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+            *(uint32_t *)(outputAddr) = CRYP_OutData();
+            outputAddr += 0x04;
+        }
+    }
+    CRYP_Disable();
+    return status;
+}
+
+/**@} end of group CRYP_AES_Functions */
+/**@} end of group CRYP_AES_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 232 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_des.c

@@ -0,0 +1,232 @@
+/*!
+ * @file        apm32f4xx_cryp_des.c
+ *
+ * @brief       This file provides high level functions to encrypt and decrypt,
+ *              Input message using DES in ECB/CBC modes.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_cryp.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup CRYP_DES_Driver
+  * @brief CRYP DES driver modules
+  @{
+*/
+
+/** @defgroup CRYP_DES_Functions
+  @{
+*/
+
+/*!
+ * @brief     Encrypt and decrypt using DES in EBC Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:    Key used for DES algorithm.
+ * @param     input:  Input buffer.
+ * @param     length: length of the Input buffer, must be a multiple of 8.
+ * @param     output: Output buffer.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t CRYP_DES_ECB(CRYP_MODE_T mode, uint8_t key[8], uint8_t *input,
+                     uint32_t length, uint8_t *output)
+{
+    CRYP_Config_T    DEC_crypConfig;
+    CRYP_KeyConfig_T DEC_keyConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&DEC_keyConfig);
+
+    if (mode == CRYP_MODE_ENCRYPT)
+    {
+        DEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+    else
+    {
+        DEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
+    }
+    DEC_crypConfig.algoMode = CRYP_ALGOMODE_DES_ECB;
+    DEC_crypConfig.dataType = CRYP_DATATYPE_8B;
+    CRYP_Config(&DEC_crypConfig);
+
+    DEC_keyConfig.key1Left = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    DEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+    CRYP_ConfigKey(&DEC_keyConfig);
+
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+    else
+    {
+        for (i = 0; i < length; i += 8)
+        {
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+
+            counter = 0;
+            do
+            {
+                flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+                counter++;
+            }
+            while ((counter != 0x00010000) && (flag != RESET));
+
+            if (flag == SET)
+            {
+                status = ERROR;
+            }
+            else
+            {
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+            }
+        }
+        CRYP_Disable();
+    }
+    return status;
+}
+
+/*!
+ * @brief     Encrypt and decrypt using DES in CBC Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:    Key used for DES algorithm.
+ * @param     input:  Input buffer.
+ * @param     IV:     Initialisation Vectors used for DES algorithm.
+ * @param     length: length of the Input buffer, must be a multiple of 8.
+ * @param     output: Output buffer.
+ *
+ * @retval    None
+ */
+uint8_t CRYP_DES_CBC(CRYP_MODE_T mode, uint8_t key[8],  uint8_t *input,
+                     uint8_t IV[8], uint32_t length, uint8_t *output)
+{
+    CRYP_Config_T    DEC_crypConfig;
+    CRYP_KeyConfig_T DEC_keyConfig;
+    CRYP_IVConfig_T  DEC_IVConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+    uint32_t IVAddr     = (uint32_t)IV;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&DEC_keyConfig);
+
+    if (mode == CRYP_MODE_ENCRYPT)
+    {
+        DEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+    else
+    {
+        DEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
+    }
+    DEC_crypConfig.algoMode = CRYP_ALGOMODE_DES_CBC;
+    DEC_crypConfig.dataType = CRYP_DATATYPE_8B;
+    CRYP_Config(&DEC_crypConfig);
+
+    DEC_keyConfig.key1Left = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    DEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+    CRYP_ConfigKey(&DEC_keyConfig);
+
+    DEC_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    DEC_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
+    CRYP_ConfigIV(&DEC_IVConfig);
+
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+    else
+    {
+        for (i = 0; i < length; i += 8)
+        {
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+
+            counter = 0;
+            do
+            {
+                flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+                counter++;
+            }
+            while ((counter != 0x00010000) && (flag != RESET));
+
+            if (flag == SET)
+            {
+                status = ERROR;
+            }
+            else
+            {
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+            }
+        }
+        CRYP_Disable();
+    }
+    return status;
+}
+
+/**@} end of group CRYP_DES_Functions */
+/**@} end of group CRYP_DES_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 248 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_tdes.c

@@ -0,0 +1,248 @@
+/*!
+ * @file        apm32f4xx_cryp_tdes.c
+ *
+ * @brief       This file provides high level functions to encrypt and decrypt,
+ *              Input message using TDES in ECB/CBC modes.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_cryp.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup CRYP_TDES_Driver
+  * @brief CRYP TDES driver modules
+  @{
+*/
+
+/** @defgroup CRYP_TDES_Functions
+  @{
+*/
+
+/*!
+ * @brief     Encrypt and decrypt using TDES in EBC Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:    Key used for TDES algorithm.
+ * @param     input:  Input buffer.
+ * @param     length: length of the Input buffer, must be a multiple of 8.
+ * @param     output: Output buffer.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t CRYP_TDES_ECB(CRYP_MODE_T mode, uint8_t key[24], uint8_t *input,
+                      uint32_t length,  uint8_t *output)
+{
+    CRYP_Config_T    TDEC_crypConfig;
+    CRYP_KeyConfig_T TDEC_keyConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&TDEC_keyConfig);
+
+    if (mode == CRYP_MODE_ENCRYPT)
+    {
+        TDEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+    else
+    {
+        TDEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
+    }
+    TDEC_crypConfig.algoMode = CRYP_ALGOMODE_TDES_ECB;
+    TDEC_crypConfig.dataType = CRYP_DATATYPE_8B;
+    CRYP_Config(&TDEC_crypConfig);
+
+    TDEC_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+    CRYP_ConfigKey(&TDEC_keyConfig);
+
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+    else
+    {
+        for (i = 0; i < length; i += 8)
+        {
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+
+            counter = 0;
+            do
+            {
+                flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+                counter++;
+            }
+            while ((counter != 0x00010000) && (flag != RESET));
+
+            if (flag == SET)
+            {
+                status = ERROR;
+            }
+            else
+            {
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+            }
+        }
+        CRYP_Disable();
+    }
+    return status;
+}
+
+/*!
+ * @brief     Encrypt and decrypt using TDES in CBC Mode
+ *
+ * @param     mode: Pointer to a CRYP_MODE_T structure.
+ *            This parameter can be one of the following values:
+ *                @arg CRYP_MODE_DECRYPT: Encryption
+ *                @arg CRYP_MODE_ENCRYPT: Decryption
+ *
+ * @param     key:    Key used for TDES algorithm.
+ * @param     input:  Input buffer.
+ * @param     IV:     Initialisation Vectors used for TDES algorithm.
+ * @param     length: length of the Input buffer, must be a multiple of 8.
+ * @param     output: Output buffer.
+ *
+ * @retval    None
+ */
+uint8_t CRYP_TDES_CBC(CRYP_MODE_T mode, uint8_t key[24], uint8_t *input,
+                      uint8_t IV[8], uint32_t length, uint8_t *output)
+{
+    CRYP_Config_T    TDEC_crypConfig;
+    CRYP_KeyConfig_T TDEC_keyConfig;
+    CRYP_IVConfig_T  TDEC_IVConfig;
+
+    uint32_t keyAddr    = (uint32_t)key;
+    uint32_t inputAddr  = (uint32_t)input;
+    uint32_t outputAddr = (uint32_t)output;
+    uint32_t IVAddr     = (uint32_t)IV;
+
+    uint32_t i = 0;
+    uint32_t flag = 0;
+    uint32_t status = SUCCESS;
+    __IO uint32_t counter = 0;
+
+    CRYP_ConfigKeyStructInit(&TDEC_keyConfig);
+
+    if (mode == CRYP_MODE_ENCRYPT)
+    {
+        TDEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
+    }
+    else
+    {
+        TDEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
+    }
+    TDEC_crypConfig.algoMode = CRYP_ALGOMODE_TDES_CBC;
+    TDEC_crypConfig.dataType = CRYP_DATATYPE_8B;
+    CRYP_Config(&TDEC_crypConfig);
+
+    TDEC_keyConfig.key1Left  = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key2Left  = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key3Left  = __REV(*(uint32_t *)(keyAddr));
+    keyAddr += 0x04;
+    TDEC_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
+    CRYP_ConfigKey(&TDEC_keyConfig);
+
+    TDEC_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
+    keyAddr += 0x04;
+    TDEC_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
+    CRYP_ConfigIV(&TDEC_IVConfig);
+
+    CRYP_FlushFIFO();
+    CRYP_Enable();
+
+    if (CRYP_ReadCmdStatus() == DISABLE)
+    {
+        status = ERROR;
+    }
+    else
+    {
+        for (i = 0; i < length; i += 8)
+        {
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+            CRYP_InData(*(uint32_t *)(inputAddr));
+            inputAddr += 0x04;
+
+            counter = 0;
+            do
+            {
+                flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
+                counter++;
+            }
+            while ((counter != 0x00010000) && (flag != RESET));
+
+            if (flag == SET)
+            {
+                status = ERROR;
+            }
+            else
+            {
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+                *(uint32_t *)(outputAddr) = CRYP_OutData();
+                outputAddr += 0x04;
+            }
+        }
+        CRYP_Disable();
+    }
+    return status;
+}
+
+/**@} end of group CRYP_TDES_Functions */
+/**@} end of group CRYP_TDES_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 538 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dac.c

@@ -0,0 +1,538 @@
+/*!
+ * @file        apm32f4xx_dac.c
+ *
+ * @brief       This file contains all the functions prototypes for the DAC firmware library
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_dac.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup DAC_Driver
+  * @brief DAC driver modules
+  @{
+*/
+
+/** @defgroup DAC_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset dac peripheral registers to their default reset values.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DAC_Reset(void)
+{
+    RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_DAC);
+    RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_DAC);
+}
+
+/*!
+ * @brief     Config the DAC peripheral according to the specified parameters in the dacConfig
+ *
+ * @param     channel: Select the DAC channel.
+ *                        This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @param     dacConfig: pointer to a DAC_Config_T structure
+ *
+ * @retval    None
+ */
+void DAC_Config(uint32_t channel, DAC_Config_T *dacConfig)
+{
+    uint32_t temp1 = 0, temp2 = 0;
+
+    temp1 = DAC->CTRL;
+
+    temp1 &= ~(((uint32_t)0x00000FFE) << channel);
+
+    temp2 = ((uint32_t)dacConfig->trigger | \
+             (uint32_t)dacConfig->waveGeneration | \
+             (uint32_t)dacConfig->maskAmplitudeSelect | \
+             (uint32_t)dacConfig->outputBuffer);
+
+    temp1 |= temp2 << channel;
+
+    DAC->CTRL = temp1;
+}
+
+/*!
+ * @brief     Fills each DAC_Config_T member with its default value
+ *
+ * @param     dacConfig: pointer to a DAC_Config_T structure which will be initialized
+ *
+ * @retval    None
+ */
+void DAC_ConfigStructInit(DAC_Config_T *dacConfig)
+{
+    dacConfig->trigger = DAC_TRIGGER_NONE;
+    dacConfig->waveGeneration = DAC_WAVE_GENERATION_NONE;
+    dacConfig->maskAmplitudeSelect = DAC_LFSR_MASK_BIT11_1;
+    dacConfig->outputBuffer = DAC_OUTPUT_BUFFER_ENBALE;
+}
+
+/*!
+ * @brief     Enables the specified DAC peripheral
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_Enable(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->CTRL_B.ENCH1 = BIT_SET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->CTRL_B.ENCH2 = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disables the specified DAC peripheral
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_Disable(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->CTRL_B.ENCH1 = BIT_RESET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->CTRL_B.ENCH2 = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the specified DAC channel DMA request
+ *
+ * @param     channel: Select the DAC channel.
+ *                        This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_DMA_Enable(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->CTRL_B.DMAENCH1 = BIT_SET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->CTRL_B.DMAENCH2 = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disables the specified DAC channel DMA request
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_DMA_Disable(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->CTRL_B.DMAENCH1 = BIT_RESET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->CTRL_B.DMAENCH2 = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the selected DAC channel software trigger
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_EnableSoftwareTrigger(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->SWTRG_B.SWTRG1 = BIT_SET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->SWTRG_B.SWTRG2 = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disable the selected DAC channel software trigger
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_DisableSoftwareTrigger(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->SWTRG_B.SWTRG1 = BIT_RESET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->SWTRG_B.SWTRG2 = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables simultaneously the two DAC channels software
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DAC_EnableDualSoftwareTrigger(void)
+{
+    DAC->SWTRG_B.SWTRG1 = BIT_SET;
+    DAC->SWTRG_B.SWTRG2 = BIT_SET;
+}
+
+/*!
+ * @brief     Disables simultaneously the two DAC channels software
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DAC_DisableDualSoftwareTrigger(void)
+{
+    DAC->SWTRG_B.SWTRG1 = BIT_RESET;
+    DAC->SWTRG_B.SWTRG2 = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the selected DAC channel wave generation
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                     @arg DAC_CHANNEL_1 : DAC channel 1
+ *                     @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @param     wave: Select the wave
+ *                     This parameter can be one of the following values:
+ *                     @arg DAC_WAVE_GENERATION_NOISE    : Noise wave generation
+ *                     @arg DAC_WAVE_GENERATION_TRIANGLE : Triangle wave generation
+ *
+ * @retval    None
+ */
+void DAC_EnableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave)
+{
+    DAC->CTRL &= 0xFF3FFF3F;
+    DAC->CTRL |= wave << channel;
+}
+
+/*!
+ * @brief     Disables the selected DAC channel wave generation
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                     @arg DAC_CHANNEL_1 : DAC channel 1
+ *                     @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @param     wave: Select the wave
+ *                     This parameter can be one of the following values:
+ *                     @arg DAC_WAVE_GENERATION_NOISE    : Noise wave generation
+ *                     @arg DAC_WAVE_GENERATION_TRIANGLE : Triangle wave generation
+ *
+ * @retval    None
+ */
+void DAC_DisableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave)
+{
+    DAC->CTRL &= ~(wave << channel);
+}
+
+/*!
+ * @brief     Set the specified data holding register value for DAC channel 1
+ *
+ * @param     align: DAC channel 1 data alignment
+ *                   This parameter can be one of the following values:
+ *                      @arg DAC_ALIGN_12BIT_R : 12-bit right-aligned data
+ *                      @arg DAC_ALIGN_12BIT_L : 12-bit left-aligned data
+ *                      @arg DAC_ALIGN_8BIT_R  : 8-bit right-aligned data
+ *
+ * @param     data: The data to be loaded in the selected data register.
+ *
+ * @retval    None
+ */
+void DAC_ConfigChannel1Data(DAC_ALIGN_T align, uint16_t data)
+{
+    __IO uint32_t temp = 0;
+
+    temp = (uint32_t)DAC_BASE;
+    temp += 0x00000008 + align;
+
+    /* Set the DAC channel1 selected data holding register */
+    *(__IO uint32_t *) temp = data;
+}
+
+/*!
+ * @brief     Set the specified data holding register value for DAC channel 2
+ *
+ * @param     align: DAC channel 2 data alignment
+ *                      This parameter can be one of the following values:
+ *                      @arg DAC_ALIGN_12BIT_R : 12-bit right-aligned data
+ *                      @arg DAC_ALIGN_12BIT_L : 12-bit left-aligned data
+ *                      @arg DAC_ALIGN_8BIT_R  : 8-bit right-aligned data
+ *
+ * @param     data: The data to be loaded in the selected data register.
+ *
+ * @retval    None
+ */
+void DAC_ConfigChannel2Data(DAC_ALIGN_T align, uint16_t data)
+{
+    __IO uint32_t temp = 0;
+
+    temp = (uint32_t)DAC_BASE;
+    temp += 0x00000014 + align;
+
+    /* Set the DAC channel1 selected data holding register */
+    *(__IO uint32_t *) temp = data;
+}
+
+/*!
+ * @brief     Set the specified data holding register value for dual DAC channel
+ *
+ * @param     align: Dual DAC channel data alignment
+ *                   This parameter can be one of the following values:
+ *                      @arg DAC_ALIGN_12BIT_R : 12-bit right-aligned data
+ *                      @arg DAC_ALIGN_12BIT_L : 12-bit left-aligned data
+ *                      @arg DAC_ALIGN_8BIT_R  : 8-bit right-aligned data
+ *
+ * @param     data2: Data for channel2 to be loaded in the selected data register.
+ *
+ * @param     data1: Data for channel1 to be loaded in the selected data register.
+ *
+ * @retval    None
+ */
+void DAC_ConfigDualChannelData(DAC_ALIGN_T align, uint16_t data2, uint16_t data1)
+{
+    uint32_t data = 0, temp = 0;
+
+    /* Calculate and set dual DAC data holding register value */
+    if (align == DAC_ALIGN_8BIT_R)
+    {
+        data = ((uint32_t)data2 << 8) | data1;
+    }
+    else
+    {
+        data = ((uint32_t)data2 << 16) | data1;
+    }
+
+    temp = (uint32_t)DAC_BASE;
+    temp += 0x00000020 + align;
+
+    /* Set the dual DAC selected data holding register */
+    *(__IO uint32_t *)temp = data;
+}
+
+/*!
+ * @brief     Reads the specified DAC channel data output value.
+ *
+ * @param     channel: Select the DAC channel.
+ *                     This parameter can be one of the following values:
+ *                       @arg DAC_CHANNEL_1 : DAC channel 1
+ *                       @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    The data output value of the specified DAC channel.
+ */
+uint16_t DAC_ReadDataOutputValue(DAC_CHANNEL_T channel)
+{
+    __IO uint32_t temp = 0;
+
+    temp = (uint32_t) DAC_BASE ;
+    temp += 0x0000002C + ((uint32_t)channel >> 2);
+
+    /* Returns the DAC channel data output register value */
+    return (uint16_t)(*(__IO uint32_t *) temp);
+}
+
+/*!
+ * @brief     Enable the specified DAC underrun interrupt.
+ *
+ * @param     channel: The selected DAC channel.
+ *                        This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_EnableInterrupt(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->CTRL_B.DMAUDIEN1 = BIT_SET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->CTRL_B.DMAUDIEN2 = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disable the specified DAC underrun interrupt.
+ *
+ * @param     channel: The selected DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_DisableInterrupt(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->CTRL_B.DMAUDIEN1 = BIT_RESET;
+    }
+    else if (channel == DAC_CHANNEL_2)
+    {
+        DAC->CTRL_B.DMAUDIEN2 = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Reads the specified DAC underrun flag
+ *
+ * @param     channel: The selected DAC channel.
+ *                        This parameter can be one of the following values:
+ *                        @arg DAC_CHANNEL_1 : DAC channel 1
+ *                        @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    The new state of DAC_FLAG (SET or RESET).
+ */
+uint8_t DAC_ReadStatusFlag(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        return  DAC->STS_B.DMAUDFLG1;
+    }
+    else
+    {
+        return  DAC->STS_B.DMAUDFLG2;
+    }
+}
+
+/*!
+ * @brief     Clears the DAC channel's status flags.
+ *
+ * @param     channel: The selected DAC channel.
+ *                     This parameter can be one of the following values:
+ *                        @arg DAC_Channel_1: DAC Channel1 selected
+ *                        @arg DAC_Channel_2: DAC Channel2 selected
+ *
+ * @retval    None
+ */
+void DAC_ClearStatusFlag(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->STS_B.DMAUDFLG1 = SET;
+    }
+    else
+    {
+        DAC->STS_B.DMAUDFLG2 = SET;
+    }
+}
+
+/*!
+ * @brief     Reads the specified DAC Interrupt flag.
+ *
+ * @param     DAC_Channel: The selected DAC channel.
+ *                         This parameter can be one of the following values:
+ *                            @arg DAC_CHANNEL_1 : DAC channel 1
+ *                            @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    The new state of DAC_IT (SET or RESET).
+ */
+uint8_t DAC_ReadIntFlag(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        return (DAC->CTRL_B.DMAUDIEN1 && DAC->STS_B.DMAUDFLG1);
+    }
+    else
+    {
+        return (DAC->CTRL_B.DMAUDIEN2 && DAC->STS_B.DMAUDFLG2);
+    }
+}
+
+/*!
+ * @brief     Clears the DAC channel's interrupt flag.
+ *
+ * @param     channel: The selected DAC channel.
+ *                     This parameter can be one of the following values:
+ *                  @arg DAC_CHANNEL_1 : DAC channel 1
+ *                  @arg DAC_CHANNEL_2 : DAC channel 2
+ *
+ * @retval    None
+ */
+void DAC_ClearIntFlag(DAC_CHANNEL_T channel)
+{
+    if (channel == DAC_CHANNEL_1)
+    {
+        DAC->STS_B.DMAUDFLG1 = SET;
+    }
+    else
+    {
+        DAC->STS_B.DMAUDFLG2 = SET;
+    }
+}
+
+/**@} end of group DAC_Functions */
+/**@} end of group DAC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 197 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dbgmcu.c

@@ -0,0 +1,197 @@
+/*!
+ * @file        apm32f4xx_dbgmcu.c
+ *
+ * @brief       This file provides all the DEBUG firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_dbgmcu.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup DBGMCU_Driver
+  * @brief DBGMCU driver modules
+  @{
+*/
+
+/** @defgroup DBGMCU_Functions
+  @{
+*/
+
+/*!
+ * @brief     Returns the device identifier.
+ *
+ * @param     None
+ *
+ * @retval    Device identifier
+ */
+uint32_t DBGMCU_ReadDEVID(void)
+{
+    return (DBGMCU->IDCODE_B.EQR);
+}
+
+/*!
+ * @brief     Returns the device revision identifier.
+ *
+ * @param     None
+ *
+ * @retval    Device revision identifier
+ */
+uint32_t DBGMCU_ReadREVID(void)
+{
+    return (DBGMCU->IDCODE_B.WVR);
+}
+
+/*!
+ * @brief     Enable the specified peripheral and low power mode behavior
+ *            when the MCU under Debug mode
+ *
+ * @param     periph: Specifies the peripheral and low power mode
+ *                    This parameter can be any combination of the following values:
+ *                    @arg DBGMCU_SLEEP     : Keep debugger connection during SLEEP mode
+ *                    @arg DBGMCU_STOP      : Keep debugger connection during STOP mode
+ *                    @arg DBGMCU_STANDBY   : Keep debugger connection during STANDBY mode
+ *
+ * @retval    None
+ */
+void DBGMCU_Enable(uint32_t periph)
+{
+    DBGMCU->CFG |= periph;
+}
+
+/*!
+ * @brief     DBGMCU_Disable the specified peripheral and low power mode behavior
+ *            when the MCU under Debug mode
+ *
+ * @param     periph: Specifies the peripheral and low power mode
+ *                    This parameter can be any combination of the following values:
+ *                    @arg DBGMCU_SLEEP     : Keep debugger connection during SLEEP mode
+ *                    @arg DBGMCU_STOP      : Keep debugger connection during STOP mode
+ *                    @arg DBGMCU_STANDBY   : Keep debugger connection during STANDBY mode
+ *
+ * @retval    None
+ */
+void DBGMCU_Disable(uint32_t periph)
+{
+    DBGMCU->CFG &= ~periph;
+}
+
+/*!
+ * @brief     Enable APB1 peripheral behavior when the MCU is in Debug mode.
+ *
+ * @param     periph: specifies the APB1 peripheral.
+ *                    This parameter can be any combination of the following values:
+ *                    @arg DBGMCU_TMR2_STOP          : TMR2 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR3_STOP          : TMR3 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR4_STOP          : TMR4 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR5_STOP          : TMR5 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR6_STOP          : TMR6 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR7_STOP          : TMR7 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR12_STOP         : TMR12 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR13_STOP         : TMR13 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR14_STOP         : TMR14 counter stopped when Core is halted
+ *                    @arg DBGMCU_RTC_STOP           : RTC Calendar and Wakeup counter stopped when Core is halted.
+ *                    @arg DBGMCU_WWDT_STOP          : Debug WWDG stopped when Core is halted
+ *                    @arg DBGMCU_IWDT_STOP          : Debug IWDG stopped when Core is halted
+ *                    @arg DBGMCU_I2C1_SMBUS_TIMEOUT : I2C1 SMBUS timeout mode stopped when Core is halted
+ *                    @arg DBGMCU_I2C2_SMBUS_TIMEOUT : I2C2 SMBUS timeout mode stopped when Core is halted
+ *                    @arg DBGMCU_I2C3_SMBUS_TIMEOUT : I2C3 SMBUS timeout mode stopped when Core is halted
+ *                    @arg DBGMCU_CAN1_STOP          : Debug CAN1 stopped when Core is halted
+ *                    @arg DBGMCU_CAN2_STOP          : Debug CAN2 stopped when Core is halted
+ *
+ * @retval    None
+ */
+void DBGMCU_EnableAPB1Periph(uint32_t periph)
+{
+    DBGMCU->APB1F |= periph;
+}
+
+/*!
+ * @brief     Disable APB1 peripheral behavior when the MCU is in Debug mode.
+ *
+ * @param     periph: specifies the APB1 peripheral.
+ *                    This parameter can be any combination of the following values:
+ *                    @arg DBGMCU_TMR2_STOP          : TMR2 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR3_STOP          : TMR3 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR4_STOP          : TMR4 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR5_STOP          : TMR5 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR6_STOP          : TMR6 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR7_STOP          : TMR7 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR12_STOP         : TMR12 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR13_STOP         : TMR13 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR14_STOP         : TMR14 counter stopped when Core is halted
+ *                    @arg DBGMCU_RTC_STOP           : RTC Calendar and Wakeup counter stopped when Core is halted.
+ *                    @arg DBGMCU_WWDT_STOP          : Debug WWDG stopped when Core is halted
+ *                    @arg DBGMCU_IWDT_STOP          : Debug IWDG stopped when Core is halted
+ *                    @arg DBGMCU_I2C1_SMBUS_TIMEOUT : I2C1 SMBUS timeout mode stopped when Core is halted
+ *                    @arg DBGMCU_I2C2_SMBUS_TIMEOUT : I2C2 SMBUS timeout mode stopped when Core is halted
+ *                    @arg DBGMCU_I2C3_SMBUS_TIMEOUT : I2C3 SMBUS timeout mode stopped when Core is halted
+ *                    @arg DBGMCU_CAN1_STOP          : Debug CAN1 stopped when Core is halted
+ *                    @arg DBGMCU_CAN1_STOP          : Debug CAN2 stopped when Core is halted
+ *
+ * @retval    None
+ */
+void DBGMCU_DisableAPB1Periph(uint32_t periph)
+{
+    DBGMCU->APB1F &= ~periph;
+}
+
+/*!
+ * @brief     Enable APB2 peripheral behavior when the MCU is in Debug mode.
+ *
+ * @param     periph: specifies the APB2 peripheral.
+ *                    This parameter can be any combination of the following values:
+ *                    @arg DBGMCU_TMR1_STOP  : TMR1 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR8_STOP  : TMR8 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR9_STOP  : TMR9 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR10_STOP : TMR10 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR11_STOP : TMR11 counter stopped when Core is halted
+ *
+ * @retval    None
+ */
+void DBGMCU_EnableAPB2Periph(uint32_t periph)
+{
+    DBGMCU->APB2F |= periph;
+}
+
+/*!
+ * @brief     Disable APB2 peripheral behavior when the MCU is in Debug mode.
+ *
+ * @param     periph: specifies the APB2 peripheral.
+ *                    This parameter can be any combination of the following values:
+ *                    @arg DBGMCU_TMR1_STOP  : TMR1 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR8_STOP  : TMR8 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR9_STOP  : TMR9 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR10_STOP : TMR10 counter stopped when Core is halted
+ *                    @arg DBGMCU_TMR11_STOP : TMR11 counter stopped when Core is halted
+ *
+ * @retval    None
+ */
+void DBGMCU_DisableAPB2Periph(uint32_t periph)
+{
+    DBGMCU->APB2F &= ~periph;
+}
+
+/**@} end of group DBGMCU_Functions */
+/**@} end of group DBGMCU_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 369 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dci.c

@@ -0,0 +1,369 @@
+/*!
+ * @file        apm32f4xx_dci.c
+ *
+ * @brief       This file provides all the DCI firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_dci.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup DCI_Driver
+  * @brief DCI driver modules
+  @{
+*/
+
+/** @defgroup DCI_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reast the DCI registers to their default reset values.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DCI_Rest(void)
+{
+    DCI->CTRL      = 0x00;
+    DCI->INTEN     = 0x00;
+    DCI->INTCLR    = 0x1F;
+    DCI->ESYNCC    = 0x00;
+    DCI->ESYNCUM   = 0x00;
+    DCI->CROPWSTAT = 0x00;
+    DCI->CROPWSIZE = 0x00;
+}
+
+/*!
+ * @brief     Configure DCI by configuring the structure
+ *
+ * @param     dciConfig: pointer to a DCI_Config_T structure
+ *
+ * @retval    None
+ */
+void DCI_Config(DCI_Config_T *dciConfig)
+{
+    DCI->CTRL_B.CMODE    = dciConfig->captureMode;
+    DCI->CTRL_B.ESYNCSEL = dciConfig->synchroMode;
+    DCI->CTRL_B.PXCLKPOL = dciConfig->pckPolarity;
+    DCI->CTRL_B.VSYNCPOL = dciConfig->vsyncPolarity;
+    DCI->CTRL_B.HSYNCPOL = dciConfig->hsyncPolarity;
+    DCI->CTRL_B.FCRCFG   = dciConfig->capturerate;
+    DCI->CTRL_B.EXDMOD   = dciConfig->extendedDataMode;
+}
+
+/*!
+ * @brief     Fills each DCI InitStruct member with its default value.
+ *
+ * @param     dciConfig : pointer to a DCI_Config_T structure
+ *
+ * @retval    None
+ */
+void DCI_ConfigStructInit(DCI_Config_T *dciConfig)
+{
+    dciConfig->captureMode      = DCI_CAPTURE_MODE_CONTINUOUS;
+    dciConfig->synchroMode      = DCI_SYNCHRO_MODE_HARDWARE;
+    dciConfig->pckPolarity      = DCI_PCK_POL_FALLING;
+    dciConfig->vsyncPolarity    = DCI_VSYNC_POL_LOW;
+    dciConfig->hsyncPolarity    = DCI_HSYNC_POL_LOW;
+    dciConfig->capturerate      = DCI_CAPTURE_RATE_ALL_FRAME;
+    dciConfig->extendedDataMode = DCI_EXTENDED_DATA_MODE_8B;
+}
+
+/*!
+ * @brief       Configure DCI CROP mode by configuring the structure
+ *
+ * @param       cropConfig:  pointer to a DCI_CropConfig_T structure
+ *
+ * @retval      None
+ */
+void DCI_ConfigCROP(DCI_CropConfig_T *cropConfig)
+{
+    DCI->CROPWSTAT_B.HOFSCNT   = (uint16_t)cropConfig->horizontalOffsetCount;
+    DCI->CROPWSTAT_B.VSLINECNT = (uint16_t)cropConfig->verticalStartLine;
+
+    DCI->CROPWSIZE_B.CCNT     = (uint16_t)cropConfig->captureCount;
+    DCI->CROPWSIZE_B.VLINECNT = (uint16_t)cropConfig->verticalLineCount;
+}
+
+/*!
+ * @brief     Enable the DCI Crop.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DCI_EnableCROP(void)
+{
+    DCI->CTRL_B.CROPF = SET;
+}
+
+/*!
+ * @brief     Disable the DCI Crop.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DCI_DisableCROP(void)
+{
+    DCI->CTRL_B.CROPF = RESET;
+}
+
+/*!
+ * @brief     Sets the embedded synchronization codes
+ *
+ * @param     CodeConfig: pointer to a DCI_CodeConfig_T structure
+ *
+ * @retval    None
+ */
+void DCI_ConfigSynchroCode(DCI_CodeConfig_T *codeConfig)
+{
+    DCI->ESYNCC_B.FSDC = (uint8_t)codeConfig->frameStartCode;
+    DCI->ESYNCC_B.LSDC = (uint8_t)codeConfig->lineStartCode;
+    DCI->ESYNCC_B.LEDC = (uint8_t)codeConfig->lineEndCode;
+    DCI->ESYNCC_B.FEDC = (uint8_t)codeConfig->frameEndCode;
+}
+
+/*!
+ * @brief     Enable the DCI JPEG.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void  DCI_EnableJPEG(void)
+{
+    DCI->CTRL_B.JPGFM = SET;
+}
+
+/*!
+ * @brief     Disable the DCI JPEG.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void  DCI_DisableJPEG(void)
+{
+
+    DCI->CTRL_B.JPGFM = RESET;
+}
+
+/*!
+* @brief     Enable the DCI interface.
+*
+* @param     None
+*
+* @retval    None
+*/
+void  DCI_Enable(void)
+{
+    DCI->CTRL_B.DCIEN = SET;
+}
+
+/*!
+ * @brief     Disable the DCI interface.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void  DCI_Disable(void)
+{
+    DCI->CTRL_B.DCIEN = RESET;
+}
+
+/*!
+ * @brief     Enable the DCI Capture.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void  DCI_EnableCapture(void)
+{
+    DCI->CTRL_B.CEN = SET;
+}
+
+/*!
+ * @brief     Disable the DCI Capture.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void  DCI_DisableCapture(void)
+{
+    DCI->CTRL_B.CEN = RESET;
+}
+
+/*!
+ * @brief     Read the data stored in the DATA register.
+ *
+ * @param     None
+ *
+ * @retval    Data register value
+ */
+uint32_t DCI_ReadData(void)
+{
+    return DCI->DATA;
+}
+
+/*!
+ * @brief     Enable the DCI interface interrupts.
+ *
+ * @param     interrupt: specifies the DCI interrupt sources
+ *            This parameter can be any combination of the following values:
+ *              @arg DCI_INT_CC:    Frame capture complete interrupt mask
+ *              @arg DCI_INT_OVR:   Overflow interrupt mask
+ *              @arg DCI_INT_ERR:   Synchronization error interrupt mask
+ *              @arg DCI_INT_VSYNC: VSYNC interrupt mask
+ *              @arg DCI_INT_LINE:  Line interrupt mask
+ *
+ * @retval    None
+ */
+void DCI_EnableInterrupt(uint32_t interrupt)
+{
+    DCI->INTEN |= (uint32_t)interrupt;
+}
+
+/*!
+ * @brief     Disable the DCI interface interrupts.
+ *
+ * @param     interrupt: specifies the DCI interrupt sources
+ *            This parameter can be any combination of the following values:
+ *              @arg DCI_INT_CC:    Frame capture complete interrupt mask
+ *              @arg DCI_INT_OVR:   Overflow interrupt mask
+ *              @arg DCI_INT_ERR:   Synchronization error interrupt mask
+ *              @arg DCI_INT_VSYNC: VSYNC interrupt mask
+ *              @arg DCI_INT_LINE:  Line interrupt mask
+ *
+ * @retval    None
+ */
+void DCI_DisableInterrupt(uint32_t interrupt)
+{
+    DCI->INTEN &= ~(uint32_t)interrupt;
+}
+
+/*!
+ * @brief     Reads the DCI flag.
+ *
+ * @param     flag: specifies the flag to check.
+ *            This parameter can be one of the following values:
+ *              @arg DCI_FLAG_CCI:     Frame capture complete Raw flag mask
+ *              @arg DCI_FLAG_OVRI:    Overflow Raw flag mask
+ *              @arg DCI_FLAG_ERRI:    Synchronization error Raw flag mask
+ *              @arg DCI_FLAG_VSYNCI:  VSYNC Raw flag mask
+ *              @arg DCI_FLAG_LINEI:   Line Raw flag mask
+ *              @arg DCI_FLAG_CCMI:    Frame capture complete Masked flag mask
+ *              @arg DCI_FLAG_OVRMI:   Overflow Masked flag mask
+ *              @arg DCI_FLAG_ERRMI:   Synchronization error Masked flag mask
+ *              @arg DCI_FLAG_VSYNCMI: VSYNC Masked flag mask
+ *              @arg DCI_FLAG_LINEMI:  Line Masked flag mask
+ *              @arg DCI_FLAG_HSYNC:   HSYNC flag mask
+ *              @arg DCI_FLAG_VSYNC:   VSYNC flag mask
+ *              @arg DCI_FLAG_FNE:     Fifo not empty flag mask
+ *
+ * @retval    SET or RESET.
+ */
+uint16_t DCI_ReadStatusFlag(DCI_FLAG_T flag)
+{
+    uint32_t offset, temp = 0;
+    offset = (flag >> 12);
+
+    if (offset == 0x00)
+    {
+        temp = DCI->RINTSTS;
+    }
+    else if (offset == 0x01)
+    {
+        temp = DCI->MINTSTS;
+    }
+    else
+    {
+        temp = DCI->STS;
+    }
+    return (temp & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the DCI flag.
+ *
+ * @param     flag: specifies the flag to clear.
+ *            This parameter can be any combination of the following values:
+ *              @arg DCI_FLAG_CCI:     Frame capture complete Raw flag mask
+ *              @arg DCI_FLAG_OVRI:    Overflow Raw flag mask
+ *              @arg DCI_FLAG_ERRI:    Synchronization error Raw flag mask
+ *              @arg DCI_FLAG_VSYNCI:  VSYNC Raw flag mask
+ *              @arg DCI_FLAG_LINEI:   Line Raw flag mask
+
+ * @retval    None
+ */
+void DCI_ClearStatusFlag(uint16_t flag)
+{
+    DCI->INTCLR = (uint16_t)flag;
+}
+
+/*!
+ * @brief     Read the DCI interrupt flag.
+ *
+ * @param     flag: specifies the DCI interrupt source to check.
+ *            This parameter can be one of the following values:
+ *              @arg DCI_INT_CC:    Frame capture complete interrupt mask
+ *              @arg DCI_INT_OVR:   Overflow interrupt mask
+ *              @arg DCI_INT_ERR:   Synchronization error interrupt mask
+ *              @arg DCI_INT_VSYNC: VSYNC interrupt mask
+ *              @arg DCI_INT_LINE:  Line interrupt mask
+ *
+ * @retval    None
+ */
+uint16_t DCI_ReadIntFlag(DCI_INT_T flag)
+{
+    return (DCI->MINTSTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clear the DCI interrupt flag.
+ *
+ * @param     flag: specifies the DCI interrupt pending bit to clear.
+ *            This parameter can be any combination of the following values:
+ *              @arg DCI_INT_CC:    Frame capture complete interrupt mask
+ *              @arg DCI_INT_OVR:   Overflow interrupt mask
+ *              @arg DCI_INT_ERR:   Synchronization error interrupt mask
+ *              @arg DCI_INT_VSYNC: VSYNC interrupt mask
+ *              @arg DCI_INT_LINE:  Line interrupt mask
+ *
+ * @retval    None
+ */
+void DCI_ClearIntFlag(uint16_t flag)
+{
+    DCI->INTCLR = (uint16_t)flag;
+}
+
+/**@} end of group DCI_Functions */
+/**@} end of group DCI_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 652 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dma.c

@@ -0,0 +1,652 @@
+/*!
+ * @file        apm32f4xx_dma.c
+ *
+ * @brief       This file provides all the DMA firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_dma.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup DMA_Driver
+  * @brief DMA driver modules
+  @{
+*/
+
+/** @defgroup DMA_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset specified DMA Stream registers to their default reset
+ *
+ * @param     stream :DMAy_streamx(y can be 1 or 2 and x can be from 0 to 7)
+ *
+ * @retval    None
+ *
+ * @note      DMA2 channel only for APM32 High density devices.
+ */
+void DMA_Reset(DMA_Stream_T *stream)
+{
+    stream->SCFG_B.EN  =  BIT_RESET;
+    stream->SCFG       =  0;
+    stream->NDATA      =  0;
+    stream->PADDR      =  0;
+    stream->M0ADDR     =  0;
+    stream->M1ADDR     =  0;
+    stream->FCTRL      = (uint32_t)0x00000021;
+
+    if (stream == DMA1_Stream0)
+    {
+        DMA1->LIFCLR |=  0x0000003D;
+    }
+    else if (stream == DMA1_Stream1)
+    {
+        DMA1->LIFCLR |=  0X00000F40;
+    }
+    else if (stream == DMA1_Stream2)
+    {
+        DMA1->LIFCLR |=  0x003D0000;
+    }
+    else if (stream == DMA1_Stream3)
+    {
+        DMA1->LIFCLR |=  0X0F400000;
+    }
+    else if (stream == DMA1_Stream4)
+    {
+        DMA1->HIFCLR |=  0x0000003D;
+    }
+    else if (stream == DMA1_Stream5)
+    {
+        DMA1->HIFCLR |=  0X00000F40;
+    }
+    else if (stream == DMA1_Stream6)
+    {
+        DMA1->HIFCLR |=  0x003D0000;
+    }
+    else if (stream == DMA1_Stream7)
+    {
+        DMA1->HIFCLR |=  0X0F400000;
+    }
+    else if (stream == DMA2_Stream0)
+    {
+        DMA2->LIFCLR |=  0x0000003D;
+    }
+    else if (stream == DMA2_Stream1)
+    {
+        DMA2->LIFCLR |=  0X00000F40;
+    }
+    else if (stream == DMA2_Stream2)
+    {
+        DMA2->LIFCLR |=  0x003D0000;
+    }
+    else if (stream == DMA2_Stream3)
+    {
+        DMA2->LIFCLR |=  0X0F400000;
+    }
+    else if (stream == DMA2_Stream4)
+    {
+        DMA2->HIFCLR |=  0x0000003D;
+    }
+    else if (stream == DMA2_Stream5)
+    {
+        DMA2->HIFCLR |=  0X00000F40;
+    }
+    else if (stream == DMA2_Stream6)
+    {
+        DMA2->HIFCLR |=  0x003D0000;
+    }
+    else if (stream == DMA2_Stream7)
+    {
+        DMA2->HIFCLR |=  0X0F400000;
+    }
+}
+
+/*!
+ * @brief     Configs specified DMA channel through a structure.
+ *
+ * @param     stream:DMA1_channelx(y can be 1 or 2 and x can be from 0 to 7).
+ *
+ * @param     dmaConfig: Point to a DMA_Config_T structure
+ *
+ * @retval    None
+ *
+ * @note      DMA2 channel only for APM32 High density devices.
+ */
+void DMA_Config(DMA_Stream_T *stream, DMA_Config_T *dmaConfig)
+{
+    stream->SCFG_B.DIRCFG = dmaConfig->dir;
+    stream->SCFG_B.CIRCMEN = dmaConfig->loopMode;
+    stream->SCFG_B.PERIM = dmaConfig->peripheralInc;
+    stream->SCFG_B.MEMIM = dmaConfig->memoryInc;
+    stream->SCFG_B.PERSIZECFG = dmaConfig->peripheralDataSize;
+    stream->SCFG_B.MEMSIZECFG = dmaConfig->memoryDataSize;
+    stream->SCFG_B.PRILCFG = dmaConfig->priority;
+    stream->SCFG_B.PBCFG = dmaConfig->peripheralBurst;
+    stream->SCFG_B.MBCFG = dmaConfig->memoryBurst;
+    stream->SCFG_B.CHSEL = dmaConfig->channel;
+
+    stream->NDATA  = dmaConfig->bufferSize;
+    stream->PADDR  = dmaConfig->peripheralBaseAddr;
+    stream->M0ADDR = dmaConfig->memoryBaseAddr;
+
+    stream->FCTRL_B.DMDEN  = dmaConfig->fifoMode;
+    stream->FCTRL_B.FTHSEL = dmaConfig->fifoThreshold;
+}
+
+/*!
+ * @brief     Populate the structure with default values.
+ *
+ * @param     dmaConfig: Point to a DMA_Config_T structure.
+ *
+ * @retval    None
+ */
+void DMA_ConfigStructInit(DMA_Config_T *dmaConfig)
+{
+    dmaConfig->channel = DMA_CHANNEL_0;
+    dmaConfig->peripheralBaseAddr = 0;
+    dmaConfig->memoryBaseAddr = 0;
+    dmaConfig->dir = DMA_DIR_PERIPHERALTOMEMORY;
+    dmaConfig->bufferSize = 0;
+    dmaConfig->peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
+    dmaConfig->memoryInc = DMA_MEMORY_INC_DISABLE;
+    dmaConfig->peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_BYTE;
+    dmaConfig->memoryDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
+    dmaConfig->loopMode = DMA_MODE_NORMAL;
+    dmaConfig->priority = DMA_PRIORITY_LOW;
+    dmaConfig->fifoMode = DMA_FIFOMODE_DISABLE;
+    dmaConfig->fifoThreshold = DMA_FIFOTHRESHOLD_QUARTER;
+    dmaConfig->peripheralBurst = DMA_PERIPHERALBURST_SINGLE;
+    dmaConfig->memoryBurst = DMA_MEMORYBURST_SINGLE;
+}
+
+/*!
+ * @brief     Enable the specified DMA channel
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval    None
+ *
+ * @note      DMA2 channel only for APM32 High density devices.
+ */
+void DMA_Enable(DMA_Stream_T *stream)
+{
+    stream->SCFG_B.EN = ENABLE;
+}
+
+/*!
+ * @brief     Disable the specified DMA channel
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval    None
+ *
+ * @note      DMA2 channel only for APM32 High density devices.
+ */
+void DMA_Disable(DMA_Stream_T *stream)
+{
+    stream->SCFG_B.EN = DISABLE;
+}
+
+/*!
+ * @brief     Configures the specified DMA Peripheral increment offset size.
+ *
+ * @param     perioSize: specifies the Peripheral increment offset size.
+ *                       This parameter can be one of the following values:
+ *                        @arg DMA_PERIOSIZE_PSIZE: Peripheral address increment is done
+ *                                                  accordingly to PSIZE parameter.
+ *                        @arg DMA_PERIOSIZE_WORDALIGNED: Peripheral address increment offset is
+ *                                                  fixed to 4 (32-bit aligned addresses).
+ *
+ * @retval    None
+ *
+ * @note      DMA2 Stream only for APM32 High density devices.
+ */
+void DMA_ConfigPeriphIncOffsetSize(DMA_Stream_T *stream, DMA_PERIOSIZE_T perioSize)
+{
+    stream->SCFG_B.PERIOSIZE = perioSize;
+}
+
+/*!
+ * @brief     Configures the specified DMA flow controller.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flowController: specifies the DMA flow controller.
+ *                             This parameter can be one of the following values:
+ *                             @arg DMA_FLOWCTRL_MEMORY: DMAy_Channelx transactions flow controller is
+ *                                                       the DMA controller.
+ *                             @arg DMA_FLOWCTRL_PERIPHERAL: DMAy_Channelx transactions flow controller
+ *                                                       is the peripheral.
+ *
+ * @retval    None
+ *
+ * @note      DMA2 Stream only for APM32 High density devices.
+ */
+void DMA_ConfigFlowController(DMA_Stream_T *stream, DMA_FLOWCTRL_T flowController)
+{
+    stream->SCFG_B.PERFC = flowController;
+}
+
+/*!
+ * @brief     Configs the number of data units in the channel.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     dataNumber:The number of data units in the current DMA Stream transfer.
+ *
+ * @retval    The number of NDATA value
+ *
+ * @note      DMA2 Stream only for APM32 High density devices.
+ */
+void DMA_ConfigDataNumber(DMA_Stream_T *stream, uint16_t dataNumber)
+{
+    stream->NDATA = dataNumber;
+}
+
+/*!
+ * @brief     Read the number of data units in the channel
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval    The number of NDATA value
+ *
+ * @note      DMA2 Stream only for APM32 High density devices.
+ */
+uint16_t DMA_ReadDataNumber(DMA_Stream_T *stream)
+{
+    return (uint16_t)(stream->NDATA);
+}
+
+/*!
+ * @brief     Configures the double buffer mode and the current memory target.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     memory1BaseAddr: the base address of the second buffer (Memory 1)
+ *
+ * @param     currentMemory: specifies which memory will be first buffer for
+ *               the transactions when the Stream will be enabled.
+ *                  This parameter can be one of the following values:
+ *                    @arg DMA_MEMORY_0: Memory 0 is the current buffer.
+ *                    @arg DMA_MEMORY_1: Memory 1 is the current buffer.
+ *
+ * @retval    None
+ */
+void DMA_ConfigBufferMode(DMA_Stream_T *stream, uint32_t memory1BaseAddr, DMA_MEMORY_T currentMemory)
+{
+    stream->SCFG_B.CTARG = currentMemory;
+    stream->M1ADDR = memory1BaseAddr;
+}
+
+/*!
+ * @brief     Enable the double buffer mode for the selected DMA channel.
+ *
+ * @param     stream: DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval    None
+ */
+void DMA_EnableDoubleBufferMode(DMA_Stream_T *stream)
+{
+    stream->SCFG_B.DBM = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the double buffer mode for the selected DMA channel.
+ *
+ * @param     stream: DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval    None
+ */
+void DMA_DisableDoubleBufferMode(DMA_Stream_T *stream)
+{
+    stream->SCFG_B.DBM = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the Memory address for the next buffer transfer in double
+ *               buffer mode (for dynamic use).
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     memoryBaseAddr: The base address of the target memory buffer
+ *
+ * @param     memoryTarget: Next memory target to be used.
+ *               This parameter can be one of the following values:
+ *                  @arg DMA_MEMORY_0: To use the memory address 0
+ *                  @arg DMA_MEMORY_1: To use the memory address 1
+ *
+ * @retval       None
+ */
+void DMA_ConfigMemoryTarget(DMA_Stream_T *stream, uint32_t memoryBaseAddr, DMA_MEMORY_T memoryTarget)
+{
+    if (memoryTarget != DMA_MEMORY_0)
+    {
+        stream->M1ADDR = memoryBaseAddr;
+    }
+    else
+    {
+        stream->M0ADDR = memoryBaseAddr;
+    }
+}
+
+/*!
+ * @brief     Returns the current memory target used by double buffer transfer.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval    The memory target number: 0 for Memory0 or 1 for Memory1.
+ */
+uint32_t DMA_ReadCurrentMemoryTarget(DMA_Stream_T *stream)
+{
+    return (uint32_t)(stream->SCFG_B.CTARG);
+}
+
+/*!
+ * @brief      Returns the status of EN bit for the specified DMAy channelx.
+ *
+ * @param      stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval     Return state of the DMAy channelx (ENABLE or DISABLE).
+ */
+uint8_t DMA_ReadCmdStatus(DMA_Stream_T *stream)
+{
+    return (uint8_t)(stream->SCFG_B.EN);
+}
+
+/*!
+ * @brief      Returns the current DMAy channelx FIFO filled level.
+ *
+ * @param      stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @retval     The FIFO filling state.
+ *                  - DMA_FIFOSTATUS_LESS1QUARTER: when FIFO is less than 1 quarter-full and not empty.
+ *                  - DMA_FIFOSTATUS_1QUARTER: if more than 1 quarter-full.
+ *                  - DMA_FIFOSTATUS_HalfFull: if more than 1 half-full.
+ *                  - DMA_FIFOSTATUS_3QUARTERS: if more than 3 quarters-full.
+ *                  - DMA_FIFOSTATUS_EMPTY: when FIFO is empty
+ *                  - DMA_FIFOSTATUS_FULL: when FIFO is full
+ */
+uint32_t DMA_ReadFIFOFlag(DMA_Stream_T *stream)
+{
+    return (uint32_t)(stream->FCTRL_B.FSTS);
+}
+
+/*!
+ * @brief     Read the specified DMAy channelx flag.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flag: specifies the flag to check.
+ *                This parameter can be one of the following values:
+ *                  @arg DMA_FLAG_TCIFLGx:  channelx transfer complete flag
+ *                  @arg DMA_FLAG_HTIFLGx:  channelx half transfer complete flag
+ *                  @arg DMA_FLAG_TEIFLGx:  channelx transfer error flag
+ *                  @arg DMA_FLAG_DMEIFLGx: channelx direct mode error flag
+ *                  @arg DMA_FLAG_FEIFLGx:  channelx FIFO error flag
+ *               Where x can be 0 to 7 to select the DMA channel.
+ *
+ * @retval    None
+ */
+uint8_t DMA_ReadStatusFlag(DMA_Stream_T *stream, DMA_FLAG_T flag)
+{
+    DMA_T *dma;
+
+    if (stream < DMA2_Stream0)
+    {
+        dma = DMA1;
+    }
+    else
+    {
+        dma = DMA2;
+    }
+
+    if ((flag & 0x10000000) != RESET)
+    {
+        if ((dma->LINTSTS & flag) != RESET)
+        {
+            return  SET;
+        }
+        else
+        {
+            return RESET;
+        }
+    }
+    else
+    {
+        if ((dma->HINTSTS & flag) != RESET)
+        {
+            return  SET;
+        }
+        else
+        {
+            return RESET;
+        }
+    }
+}
+
+/*!
+ * @brief     Clears the DMAy channelx's pending flags.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flag: specifies the flag to clear.
+ *                This parameter can be any combination of the following values:
+ *                  @arg DMA_FLAG_TCIFLGx:  channelx transfer complete flag
+ *                  @arg DMA_FLAG_HTIFLGx:  channelx half transfer complete flag
+ *                  @arg DMA_FLAG_TEIFLGx:  channelx transfer error flag
+ *                  @arg DMA_FLAG_DMEIFLGx: channelx direct mode error flag
+ *                  @arg DMA_FLAG_FEIFLGx:  channelx FIFO error flag
+ *               Where x can be 0 to 7 to select the DMA channel.
+ *
+ * @retval    None
+ */
+void DMA_ClearStatusFlag(DMA_Stream_T *stream, uint32_t flag)
+{
+    DMA_T *dma;
+
+    if (stream < DMA2_Stream0)
+    {
+        dma = DMA1;
+    }
+    else
+    {
+        dma = DMA2;
+    }
+
+    if ((flag & 0x10000000) == RESET)
+    {
+        dma->LIFCLR = (flag & 0x0F7D0F7D);
+    }
+    else
+    {
+        dma->HIFCLR = (flag & 0x0F7D0F7D);
+    }
+}
+
+/*!
+ * @brief     Enable the specified DMAy channelx interrupts.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flag: specifies the DMA interrupt sources to be enabled or disabled.
+ *                This parameter can be any combination of the following values:
+ *                  @arg DMA_INT_TCIFLG:  Transfer complete interrupt mask
+ *                  @arg DMA_INT_HTIFLG:  Half transfer complete interrupt mask
+ *                  @arg DMA_INT_TEIFLG:  Transfer error interrupt mask
+ *                  @arg DMA_INT_FEIFLG:  FIFO error interrupt mask
+ *
+ * @retval    None
+ */
+void DMA_EnableInterrupt(DMA_Stream_T *stream, uint32_t interrupt)
+{
+    if ((interrupt & DMA_INT_FEIFLG) == DMA_INT_FEIFLG)
+    {
+        stream->FCTRL_B.FEIEN = BIT_SET;;
+    }
+
+    if (interrupt != DMA_INT_FEIFLG)
+    {
+        stream->SCFG |= (uint32_t)(interrupt & 0x0000001E);
+    }
+}
+
+/*!
+ * @brief     Disable the specified DMAy channelx interrupts.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flag: specifies the DMA interrupt sources to be enabled or disabled.
+ *                This parameter can be any combination of the following values:
+ *                  @arg DMA_INT_TCIFLG:  Transfer complete interrupt mask
+ *                  @arg DMA_INT_DMEIFLG:  Direct mode error interrupt mask
+ *                  @arg DMA_INT_HTIFLG:  Half transfer complete interrupt mask
+ *                  @arg DMA_INT_TEIFLG:  Transfer error interrupt mask
+ *                  @arg DMA_INT_FEIFLG:  FIFO error interrupt mask
+ *
+ * @retval    None
+ */
+void DMA_DisableInterrupt(DMA_Stream_T *stream, uint32_t interrupt)
+{
+    if ((interrupt & DMA_INT_FEIFLG) == DMA_INT_FEIFLG)
+    {
+        stream->FCTRL_B.FEIEN = BIT_RESET;;
+    }
+
+    if (interrupt != DMA_INT_FEIFLG)
+    {
+        stream->SCFG &= ~(uint32_t)(interrupt & 0x0000001E);
+    }
+}
+
+/*!
+ * @brief     Read the specified DMAy channelx interrupt.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flag: specifies the DMA interrupt source to check.
+ *                This parameter can be one of the following values:
+ *                  @arg DMA_INT_TCIFLGx:  streamx transfer complete flag
+ *                  @arg DMA_INT_HTIFLGx:  streamx half transfer complete flag
+ *                  @arg DMA_INT_TEIFLGx:  streamx transfer error flag
+ *                  @arg DMA_INT_DMEIFLGx: streamx direct mode error flag
+ *                  @arg DMA_INT_FEIFLGx:  streamx FIFO error flag
+ *                 Where x can be 0 to 7 to select the DMA channel.
+ *
+ * @retval    None.
+ */
+uint8_t DMA_ReadIntFlag(DMA_Stream_T *stream, DMA_INT_FLAG_T flag)
+{
+    uint32_t tmpreg = 0, enablestatus = 0;
+    DMA_T *dma;
+
+    if (stream < DMA2_Stream0)
+    {
+        dma = DMA1;
+    }
+    else
+    {
+        dma = DMA2;
+    }
+
+    /** Check if the interrupt enable bit is in the FCTRL or SCFG register */
+    if ((flag & 0x60000000) != RESET)
+    {
+        /** Check the enable bit in FEIEN register */
+        enablestatus = stream->FCTRL_B.FEIEN;
+    }
+    else
+    {
+        /** Get the interrupt enable position mask in SCFG register */
+        tmpreg = ((flag & 0xE000) >> 11) ;
+
+        /** Check the enable bit in SCFG register */
+        enablestatus = (stream->SCFG & tmpreg);
+    }
+
+    /* Check if the interrupt pending flag is in LINTSTS or HINTSTS */
+    if ((flag & 0x10000000) == RESET)
+    {
+        tmpreg = dma->LINTSTS;
+    }
+    else
+    {
+        tmpreg = dma->HINTSTS;
+    }
+
+    tmpreg &= 0x0F7D0F7D;
+
+    if (((tmpreg & flag) != RESET) && (enablestatus != RESET))
+    {
+        return SET ;
+    }
+    else
+    {
+        return RESET ;
+    }
+}
+
+/*!
+ * @brief     Read the DMAy channelx's interrupt pending bits.
+ *
+ * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
+ *
+ * @param     flag: specifies the DMA interrupt pending bit to clear.
+ *                This parameter can be any combination of the following values:
+ *                  @arg DMA_INT_TCIFLGx:  streamx transfer complete flag
+ *                  @arg DMA_INT_HTIFLGx:  streamx half transfer complete flag
+ *                  @arg DMA_INT_TEIFLGx:  streamx transfer error flag
+ *                  @arg DMA_INT_DMEIFLGx: streamx direct mode error flag
+ *                  @arg DMA_INT_FEIFLGx:  streamx FIFO error flag
+ *               Where x can be 0 to 7 to select the DMA channel.
+ *
+ * @retval    None
+ */
+void DMA_ClearIntFlag(DMA_Stream_T *stream, uint32_t flag)
+{
+    DMA_T *dma;
+
+    if (stream < DMA2_Stream0)
+    {
+        dma = DMA1;
+    }
+    else
+    {
+        dma = DMA2;
+    }
+
+    if ((flag & 0x10000000) == RESET)
+    {
+        dma->LIFCLR = (flag & 0x0F7D0F7D);
+    }
+    else
+    {
+        dma->HIFCLR = (flag & 0x0F7D0F7D);
+    }
+}
+
+/**@} end of group DMA_Functions */
+/**@} end of group DMA_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 435 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dmc.c

@@ -0,0 +1,435 @@
+/*!
+ * @file        apm32f4xx_dmc.c
+ *
+ * @brief       This file contains all the functions for the DMC controler peripheral
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_dmc.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup DMC_Driver
+  * @brief DMC driver modules
+  @{
+*/
+
+/** @defgroup DMC_Functions
+  @{
+*/
+
+/*!
+ * @brief     DMC controler configuration
+ *
+ * @param     dmcConfig: pointer to a DMC_Config_T structure
+ *
+ * @retval    None
+ */
+void DMC_Config(DMC_Config_T *dmcConfig)
+{
+    DMC->SW_B.MCSW = 1;
+    while (!DMC->CTRL1_B.INIT);
+
+    DMC->CFG_B.BAWCFG = dmcConfig->bankWidth;
+    DMC->CFG_B.RAWCFG = dmcConfig->rowWidth;
+    DMC->CFG_B.CAWCFG = dmcConfig->colWidth;
+
+    DMC->CTRL2_B.CPHACFG = dmcConfig->clkPhase;
+
+    DMC_ConfigTiming(&dmcConfig->timing);
+
+    DMC->CTRL1_B.MODESET = 1;
+    while (!DMC->CTRL1_B.MODESET);
+
+    DMC->CTRL2_B.RDDEN = 1;
+    DMC->CTRL2_B.RDDCFG = 7;
+}
+
+/*!
+ * @brief     Fills each dmcConfig member with its default value
+ *
+ * @param     dmcConfig: pointer to a DMC_Config_T structure
+ *
+ * @retval    None
+ */
+void DMC_ConfigStructInit(DMC_Config_T *dmcConfig)
+{
+    dmcConfig->bankWidth   = DMC_BANK_WIDTH_2;
+    dmcConfig->clkPhase    = DMC_CLK_PHASE_REVERSE;
+    dmcConfig->colWidth    = DMC_COL_WIDTH_10;
+    dmcConfig->rowWidth    = DMC_ROW_WIDTH_13;
+
+    DMC_ConfigTimingStructInit(&dmcConfig->timing);
+}
+
+/*!
+ * @brief     Timing configuration
+ *
+ * @param     timingConfig: pointer to a DMC_TimingConfig_T structure
+ *
+ * @retval    None
+ */
+void DMC_ConfigTiming(DMC_TimingConfig_T *timingConfig)
+{
+    DMC->TIM0_B.RASMINTSEL = timingConfig->tRAS;
+    DMC->TIM0_B.DTIMSEL    = timingConfig->tRCD;
+    DMC->TIM0_B.PCPSEL     = timingConfig->tRP;
+    DMC->TIM0_B.WRTIMSEL   = timingConfig->tWR;
+    DMC->TIM0_B.ARPSEL     = timingConfig->tARP;
+    DMC->TIM0_B.ATACP      = timingConfig->tCMD;
+
+    DMC->TIM0_B.CASLSEL0  =  timingConfig->latencyCAS & 0x03;
+    DMC->TIM0_B.ECASLSEL1 = (timingConfig->latencyCAS >> 2) & 0x01;
+
+    DMC->TIM0_B.XSR0  =  timingConfig->tXSR & 0X0F;
+    DMC->TIM0_B.EXSR1 = (timingConfig->tXSR >> 4) & 0X1F;
+
+    DMC->REF_B.RCYCCFG = timingConfig->tRFP;
+}
+
+/*!
+ * @brief     Fills each config member with its default value
+ *
+ * @param     timingConfig: pointer to a DMC_TimingConfig_T structure
+ *
+ * @retval    None
+ */
+void DMC_ConfigTimingStructInit(DMC_TimingConfig_T *timingConfig)
+{
+    timingConfig->latencyCAS = DMC_CAS_LATENCY_3;
+    timingConfig->tARP = DMC_AUTO_REFRESH_10;
+    timingConfig->tRAS = DMC_RAS_MINIMUM_5;
+    timingConfig->tCMD = DMC_ATA_CMD_7;
+    timingConfig->tRCD = DMC_DELAY_TIME_2;
+    timingConfig->tRP  = DMC_PRECHARGE_2;
+    timingConfig->tWR  = DMC_NEXT_PRECHARGE_2;
+    timingConfig->tXSR = 6;
+    timingConfig->tRFP = 0xC3;
+}
+
+/*!
+ * @brief     Set number of bank bits
+ *
+ * @param     bankWidth: Specifies the bank bits number
+ *                       This parameter can be one of the following values:
+ *                         @arg DMC_BANK_WIDTH_1 : Set bank address widen to 1-bit
+ *                         @arg DMC_BANK_WIDTH_2 : Set bank address widen to 2-bit
+ * @retval    None
+ */
+void DMC_ConfigBankWidth(DMC_BANK_WIDTH_T bankWidth)
+{
+    DMC->CFG_B.BAWCFG = bankWidth;
+}
+
+/*!
+ * @brief     Set address bus width
+ *
+ * @param     rowWidth: Specifies the row address bits number
+ *                        This parameter can be one of the following values:
+ *                        @arg DMC_ROW_WIDTH_11 : Set row address width to 11-bit
+ *                        @arg DMC_ROW_WIDTH_12 : Set row address width to 12-bit
+ *                        @arg DMC_ROW_WIDTH_13 : Set row address width to 13-bit
+ *                        @arg DMC_ROW_WIDTH_14 : Set row address width to 14-bit
+ *                        @arg DMC_ROW_WIDTH_15 : Set row address width to 15-bit
+ *                        @arg DMC_ROW_WIDTH_16 : Set row address width to 16-bit
+ * @param     colWidth: Specifies the column address bits number
+ *                        This parameter can be one of the following values:
+ *                        @arg DMC_COL_WIDTH_8 : Set column address width to 8-bit
+ *                        @arg DMC_COL_WIDTH_9 : Set column address width to 9-bit
+ *                        @arg DMC_COL_WIDTH_10 : Set column address width to 10-bit
+ *                        @arg DMC_COL_WIDTH_11 : Set column address width to 11-bit
+ *                        @arg DMC_COL_WIDTH_12 : Set column address width to 12-bit
+ *                        @arg DMC_COL_WIDTH_13 : Set column address width to 13-bit
+ *                        @arg DMC_COL_WIDTH_14 : Set column address width to 14-bit
+ *                        @arg DMC_COL_WIDTH_15 : Set column address width to 15-bit
+ * @retval    None
+ */
+void DMC_ConfigAddrWidth(DMC_ROW_WIDTH_T rowWidth, DMC_COL_WIDTH_T colWidth)
+{
+    DMC->CFG_B.RAWCFG = rowWidth;
+    DMC->CFG_B.CAWCFG = colWidth;
+}
+
+/*!
+ * @brief     Set stable time after power up
+ *
+ * @param     stableTime: Numper of the clock, can be 0x0000 to 0xFFFF
+ *
+ * @retval    None
+ */
+void DMC_ConfigStableTimePowerup(uint16_t stableTime)
+{
+    DMC->TIM1_B.STBTIM = stableTime;
+}
+
+/*!
+ * @brief     Number of auto-refreshes during initialization
+ *
+ * @param     num: Number of auto-refreshes can 1 to 16
+ *                 This parameter can be one of the following values:
+ *                      @arg DMC_AUTO_REFRESH_1 : Set auto-refresh period to 1 clock
+ *                      @arg DMC_AUTO_REFRESH_2 : Set auto-refresh period to 2 clock
+ *                           ......                          ......
+ *                      @arg DMC_AUTO_REFRESH_15 : Set auto-refresh period to 15 clock
+ *                      @arg DMC_AUTO_REFRESH_16 : Set auto-refresh period to 16 clock
+ *
+ * @retval    None
+ */
+void DMC_ConfigAutoRefreshNumDuringInit(DMC_AUTO_REFRESH_T num)
+{
+    DMC->TIM1_B.ARNUMCFG = num;
+}
+
+/*!
+ * @brief     Number of DMC internal banks to be open at any time;
+ *
+ * @param     num:  Number of banks can 1 to 16
+ *                  This parameter can be one of the following values:
+ *                       @arg DMC_BANK_NUMBER_1 : Set 1 bank be opened
+ *                       @arg DMC_BANK_NUMBER_2 : Set 2 bank be opened
+ *                            ......                   ......
+ *                       @arg DMC_BANK_NUMBER_15 : Set 15 bank be opened
+ *                       @arg DMC_BANK_NUMBER_16 : Set 16 bank be opened
+ * @retval    None
+ */
+void DMC_ConfigOpenBank(DMC_BANK_NUMBER_T num)
+{
+    DMC->CTRL1_B.BANKNUMCFG = num;
+}
+
+/*!
+ * @brief     Read self-refresh status
+ *
+ * @param     None
+ *
+ * @retval    The status of self-refresh (SET or RESET)
+ */
+uint8_t DMC_ReadSelfRefreshStatus(void)
+{
+    uint8_t ret;
+
+    ret = DMC->CTRL1_B.SRMFLG ? SET : RESET;
+
+    return ret;
+}
+
+/*!
+ * @brief     Set update mode bit
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_EnableUpdateMode(void)
+{
+    DMC->CTRL1_B.MODESET = 1;
+}
+
+/*!
+ * @brief     Enter power down mode
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_EnterPowerdownMode(void)
+{
+    DMC->CTRL1_B.PDMEN = 1;
+}
+
+/*!
+ * @brief     Exit self-refresh mode
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_EixtSlefRefreshMode(void)
+{
+    DMC->CTRL1_B.SRMEN = 0;
+}
+
+/*!
+ * @brief     Enter self-refresh mode
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_EnterSlefRefreshMode(void)
+{
+    DMC->CTRL1_B.SRMEN = 1;
+}
+
+/*!
+ * @brief     Init DMC
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_EnableInit(void)
+{
+    DMC->CTRL1_B.INIT = 1;
+}
+
+/*!
+ * @brief     Set refresh type before enter self-refresh
+ *
+ * @param     refresh: Specifies the refresh type
+ *                The parameter can be one of following values:
+ *                @arg DMC_REFRESH_ROW_ONE: Refresh one row
+ *                @arg DMC_REFRESH_ROW_ALL: Refresh all row
+ *
+ * @retval    None
+ */
+void DMC_ConfigFullRefreshBeforeSR(DMC_REFRESH_T refresh)
+{
+    DMC->CTRL1_B.FRBSREN = refresh;
+}
+
+/*!
+ * @brief     Set refresh type after exit self-refresh
+ *
+ * @param     refresh: Specifies the refresh type
+ *                The parameter can be one of following values:
+ *                @arg DMC_REFRESH_ROW_ONE: Refresh one row
+ *                @arg DMC_REFRESH_ROW_ALL: Refresh all row
+ *
+ * @retval    None
+ */
+void DMC_ConfigFullRefreshAfterSR(DMC_REFRESH_T refresh)
+{
+    DMC->CTRL1_B.FRASREN = refresh;
+}
+
+/*!
+ * @brief     Config precharge type
+ *
+ * @param     precharge: Specifies the precharge type
+ *                The parameter can be one of following values:
+ *                @arg DMC_PRECHARGE_IM:    Immediate precharge
+ *                @arg DMC_PRECHARGE_DELAY: Delayed precharge
+ *
+ * @retval    None
+ */
+void DMC_ConfigPrechargeType(DMC_PRECHARE_T precharge)
+{
+    DMC->CTRL1_B.PCACFG = precharge;
+}
+
+/*!
+ * @brief     Config refresh period
+ *
+ * @param     period:   Specifies the refresh period, can be 0x0000 to 0xFFFF
+ *
+ * @retval    None
+ */
+void DMC_ConfigRefreshPeriod(uint16_t period)
+{
+    DMC->REF_B.RCYCCFG = period;
+}
+
+/*!
+ * @brief     Enable DMC controler
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_Enable(void)
+{
+    DMC->SW_B.MCSW = 1;
+}
+
+/*!
+ * @brief     Disable DMC controler
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_Disable(void)
+{
+    DMC->SW_B.MCSW = 0;
+}
+
+/*!
+ * @brief     Set DMC clock phase
+ *
+ * @param     clkPhase: Specifies clock phase
+ *                The parameter can be one of following values:
+ *                @arg DMC_CLK_PHASE_NORMAL: Clock phase is normal
+ *                @arg DMC_CLK_PHASE_REVERSE: Clock phase is reverse
+ *
+ * @retval    None
+ *
+ */
+void DMC_ConfigClockPhase(DMC_CLK_PHASE_T clkPhase)
+{
+    DMC->CTRL2_B.CPHACFG = clkPhase;
+}
+
+/*!
+ * @brief     Enable Accelerate Module
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_EnableAccelerateModule(void)
+{
+    DMC->CTRL2_B.BUFFEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable Accelerate Module
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DMC_DisableAccelerateModule(void)
+{
+    DMC->CTRL2_B.BUFFEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Set DMC WRAP burst
+ *
+ * @param     burst: WRAP burst Type Selection
+ *                The parameter can be one of following values:
+ *                @arg DMC_WRAPB_4: wrap4 burst transfer
+ *                @arg DMC_WRAPB_8: wrap8 burst transfer
+ *
+ * @retval    None
+ *
+ */
+void DMC_ConfigWRAPB(DMC_WRPB_T burst)
+{
+    DMC->CTRL2_B.WRPBSEL = burst;
+}
+
+/**@} end of group DMC_Functions */
+/**@} end of group DMC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 324 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_eint.c

@@ -0,0 +1,324 @@
+/*!
+ * @file        apm32f4xx_eint.c
+ *
+ * @brief       This file provides all the EINT firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_eint.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup EINT_Driver
+  * @brief EINT driver modules
+  @{
+*/
+
+/** @defgroup EINT_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset the EINT peripheral registers to their default reset values.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void EINT_Reset(void)
+{
+    EINT->IMASK = 0x00000000;
+    EINT->EMASK = 0x00000000;
+    EINT->RTEN  = 0x00000000;
+    EINT->FTEN  = 0x00000000;
+    EINT->IPEND = 0x007FFFFF;
+}
+
+/*!
+ * @brief     Configure the EINT
+ *
+ * @param     eintConfig: pointer to a EINT_Config_T structure.
+ *
+ * @retval    None
+ */
+void EINT_Config(EINT_Config_T *eintConfig)
+{
+    uint32_t temp = 0;
+    temp = (uint32_t)EINT_BASE;
+
+    if (eintConfig->lineCmd != DISABLE)
+    {
+        EINT->IMASK &= ~eintConfig->line;
+        EINT->EMASK &= ~eintConfig->line;
+
+        temp += eintConfig->mode;
+        *(__IOM uint32_t *) temp |= eintConfig->line;
+
+        EINT->RTEN &= ~eintConfig->line;
+        EINT->FTEN &= ~eintConfig->line;
+
+        if (eintConfig->trigger == EINT_TRIGGER_RISING_FALLING)
+        {
+            EINT->RTEN |= eintConfig->line;
+            EINT->FTEN |= eintConfig->line;
+        }
+        else
+        {
+            temp = (uint32_t)EINT_BASE;
+            temp += eintConfig->trigger;
+            *(__IOM uint32_t *) temp |= eintConfig->line;
+        }
+    }
+    else
+    {
+        temp += eintConfig->mode;
+        *(__IOM uint32_t *) temp &= ~eintConfig->line;
+    }
+}
+
+/*!
+ * @brief     Fills each EINT_Config_T member with its reset value.
+ *
+ * @param     eintConfig: pointer to a EINT_Config_T structure
+ *
+ * @retval    None
+ */
+void EINT_ConfigStructInit(EINT_Config_T *eintConfig)
+{
+    eintConfig->line = EINT_LINENONE;
+    eintConfig->mode = EINT_MODE_INTERRUPT;
+    eintConfig->trigger = EINT_TRIGGER_FALLING;
+    eintConfig->lineCmd = DISABLE;
+}
+
+/*!
+ * @brief     Select Software interrupt on EINT line
+ *
+ * @param     line: specifies the EINT lines.
+ *            This parameter can be any combination of EINT_LINE_T(can be from 0 to 22)
+ *              @arg EINT_LINENONE  : No interrupt selected
+ *              @arg EINT_LINE_0    : External interrupt line 0
+ *              @arg EINT_LINE_1    : External interrupt line 1
+ *              @arg EINT_LINE_2    : External interrupt line 2
+ *              @arg EINT_LINE_3    : External interrupt line 3
+ *              @arg EINT_LINE_4    : External interrupt line 4
+ *              @arg EINT_LINE_5    : External interrupt line 5
+ *              @arg EINT_LINE_6    : External interrupt line 6
+ *              @arg EINT_LINE_7    : External interrupt line 7
+ *              @arg EINT_LINE_8    : External interrupt line 8
+ *              @arg EINT_LINE_9    : External interrupt line 9
+ *              @arg EINT_LINE_10   : External interrupt line 10
+ *              @arg EINT_LINE_11   : External interrupt line 11
+ *              @arg EINT_LINE_12   : External interrupt line 12
+ *              @arg EINT_LINE_13   : External interrupt line 13
+ *              @arg EINT_LINE_14   : External interrupt line 14
+ *              @arg EINT_LINE_15   : External interrupt line 15
+ *              @arg EINT_LINE_16   : External interrupt line 16
+ *              @arg EINT_LINE_17   : External interrupt line 17
+ *              @arg EINT_LINE_18   : External interrupt line 18
+ *              @arg EINT_LINE_19   : External interrupt line 19
+ *              @arg EINT_LINE_20   : External interrupt line 20
+ *              @arg EINT_LINE_21   : External interrupt line 21
+ *              @arg EINT_LINE_22   : External interrupt line 22
+ *
+ * @retval    None
+ */
+void EINT_SelectSWInterrupt(uint32_t line)
+{
+    EINT->SWINTE |= line;
+}
+
+/*!
+ * @brief     Read the specified EINT_Line flag
+ *
+ * @param     line: Select the EINT_Line.
+ *            This parameter can be one of EINT_LINE_T(can be from 0 to 22)
+ *              @arg EINT_LINENONE  : No interrupt selected
+ *              @arg EINT_LINE_0    : External interrupt line 0
+ *              @arg EINT_LINE_1    : External interrupt line 1
+ *              @arg EINT_LINE_2    : External interrupt line 2
+ *              @arg EINT_LINE_3    : External interrupt line 3
+ *              @arg EINT_LINE_4    : External interrupt line 4
+ *              @arg EINT_LINE_5    : External interrupt line 5
+ *              @arg EINT_LINE_6    : External interrupt line 6
+ *              @arg EINT_LINE_7    : External interrupt line 7
+ *              @arg EINT_LINE_8    : External interrupt line 8
+ *              @arg EINT_LINE_9    : External interrupt line 9
+ *              @arg EINT_LINE_10   : External interrupt line 10
+ *              @arg EINT_LINE_11   : External interrupt line 11
+ *              @arg EINT_LINE_12   : External interrupt line 12
+ *              @arg EINT_LINE_13   : External interrupt line 13
+ *              @arg EINT_LINE_14   : External interrupt line 14
+ *              @arg EINT_LINE_15   : External interrupt line 15
+ *              @arg EINT_LINE_16   : External interrupt line 16
+ *              @arg EINT_LINE_17   : External interrupt line 17
+ *              @arg EINT_LINE_18   : External interrupt line 18
+ *              @arg EINT_LINE_19   : External interrupt line 19
+ *              @arg EINT_LINE_20   : External interrupt line 20
+ *              @arg EINT_LINE_21   : External interrupt line 21
+ *              @arg EINT_LINE_22   : External interrupt line 22
+ *
+ * @retval    status: SET or RESET
+ */
+uint8_t EINT_ReadStatusFlag(EINT_LINE_T line)
+{
+    uint8_t status = RESET;
+
+    if ((EINT->IPEND & line) != (uint32_t)RESET)
+    {
+        status = SET;
+    }
+    else
+    {
+        status = RESET;
+    }
+    return status;
+}
+
+/*!
+ * @brief     Clears the EINT_Line pending bits
+ *
+ * @param     line: Select the EINT_Line.
+ *            This parameter can be any combination of EINT_LINE_T(can be from 0 to 22)
+ *              @arg EINT_LINENONE  : No interrupt selected
+ *              @arg EINT_LINE_0    : External interrupt line 0
+ *              @arg EINT_LINE_1    : External interrupt line 1
+ *              @arg EINT_LINE_2    : External interrupt line 2
+ *              @arg EINT_LINE_3    : External interrupt line 3
+ *              @arg EINT_LINE_4    : External interrupt line 4
+ *              @arg EINT_LINE_5    : External interrupt line 5
+ *              @arg EINT_LINE_6    : External interrupt line 6
+ *              @arg EINT_LINE_7    : External interrupt line 7
+ *              @arg EINT_LINE_8    : External interrupt line 8
+ *              @arg EINT_LINE_9    : External interrupt line 9
+ *              @arg EINT_LINE_10   : External interrupt line 10
+ *              @arg EINT_LINE_11   : External interrupt line 11
+ *              @arg EINT_LINE_12   : External interrupt line 12
+ *              @arg EINT_LINE_13   : External interrupt line 13
+ *              @arg EINT_LINE_14   : External interrupt line 14
+ *              @arg EINT_LINE_15   : External interrupt line 15
+ *              @arg EINT_LINE_16   : External interrupt line 16
+ *              @arg EINT_LINE_17   : External interrupt line 17
+ *              @arg EINT_LINE_18   : External interrupt line 18
+ *              @arg EINT_LINE_19   : External interrupt line 19
+ *              @arg EINT_LINE_20   : External interrupt line 20
+ *              @arg EINT_LINE_21   : External interrupt line 21
+ *              @arg EINT_LINE_22   : External interrupt line 22
+ *
+ * @retval    None
+ */
+void EINT_ClearStatusFlag(uint32_t line)
+{
+    EINT->IPEND = line;
+}
+
+/*!
+ * @brief     Read the specified EINT_Line Interrupt Flag.
+ *
+ * @param     line: Select the EINT_Line.
+ *            This parameter can be one of EINT_LINE_T(can be from 0 to 22)
+ *              @arg EINT_LINENONE  : No interrupt selected
+ *              @arg EINT_LINE_0    : External interrupt line 0
+ *              @arg EINT_LINE_1    : External interrupt line 1
+ *              @arg EINT_LINE_2    : External interrupt line 2
+ *              @arg EINT_LINE_3    : External interrupt line 3
+ *              @arg EINT_LINE_4    : External interrupt line 4
+ *              @arg EINT_LINE_5    : External interrupt line 5
+ *              @arg EINT_LINE_6    : External interrupt line 6
+ *              @arg EINT_LINE_7    : External interrupt line 7
+ *              @arg EINT_LINE_8    : External interrupt line 8
+ *              @arg EINT_LINE_9    : External interrupt line 9
+ *              @arg EINT_LINE_10   : External interrupt line 10
+ *              @arg EINT_LINE_11   : External interrupt line 11
+ *              @arg EINT_LINE_12   : External interrupt line 12
+ *              @arg EINT_LINE_13   : External interrupt line 13
+ *              @arg EINT_LINE_14   : External interrupt line 14
+ *              @arg EINT_LINE_15   : External interrupt line 15
+ *              @arg EINT_LINE_16   : External interrupt line 16
+ *              @arg EINT_LINE_17   : External interrupt line 17
+ *              @arg EINT_LINE_18   : External interrupt line 18
+ *              @arg EINT_LINE_19   : External interrupt line 19
+ *              @arg EINT_LINE_20   : External interrupt line 20
+ *              @arg EINT_LINE_21   : External interrupt line 21
+ *              @arg EINT_LINE_22   : External interrupt line 22
+ *
+ * @retval    status: SET or RESET
+ */
+uint8_t EINT_ReadIntFlag(EINT_LINE_T line)
+{
+    uint8_t status = RESET;
+    uint32_t enablestatus = 0;
+
+    enablestatus = EINT->IMASK & line;
+
+    if ((EINT->IPEND & line) != ((uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
+    {
+        status = SET;
+    }
+    else
+    {
+        status = RESET;
+    }
+    return status;
+}
+
+/*!
+ * @brief     Clears the EINT_Line pending bits
+ *
+ * @param     line: Select the EINT_Line
+ *            This parameter can be any combination of EINT_LINE_T(can be from 0 to 22)
+ *              @arg EINT_LINENONE  : No interrupt selected
+ *              @arg EINT_LINE_0    : External interrupt line 0
+ *              @arg EINT_LINE_1    : External interrupt line 1
+ *              @arg EINT_LINE_2    : External interrupt line 2
+ *              @arg EINT_LINE_3    : External interrupt line 3
+ *              @arg EINT_LINE_4    : External interrupt line 4
+ *              @arg EINT_LINE_5    : External interrupt line 5
+ *              @arg EINT_LINE_6    : External interrupt line 6
+ *              @arg EINT_LINE_7    : External interrupt line 7
+ *              @arg EINT_LINE_8    : External interrupt line 8
+ *              @arg EINT_LINE_9    : External interrupt line 9
+ *              @arg EINT_LINE_10   : External interrupt line 10
+ *              @arg EINT_LINE_11   : External interrupt line 11
+ *              @arg EINT_LINE_12   : External interrupt line 12
+ *              @arg EINT_LINE_13   : External interrupt line 13
+ *              @arg EINT_LINE_14   : External interrupt line 14
+ *              @arg EINT_LINE_15   : External interrupt line 15
+ *              @arg EINT_LINE_16   : External interrupt line 16
+ *              @arg EINT_LINE_17   : External interrupt line 17
+ *              @arg EINT_LINE_18   : External interrupt line 18
+ *              @arg EINT_LINE_19   : External interrupt line 19
+ *              @arg EINT_LINE_20   : External interrupt line 20
+ *              @arg EINT_LINE_21   : External interrupt line 21
+ *              @arg EINT_LINE_22   : External interrupt line 22
+ *
+ * @retval    None
+ */
+void EINT_ClearIntFlag(uint32_t line)
+{
+    EINT->IPEND = line;
+}
+
+/**@} end of group EINT_Functions */
+/**@} end of group EINT_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 791 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_fmc.c

@@ -0,0 +1,791 @@
+/*!
+ * @file        apm32f4xx_fmc.c
+ *
+ * @brief       This file provides all the FMC firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_fmc.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup FMC_Driver
+  * @brief FMC driver modules
+  @{
+*/
+
+/** @defgroup FMC_Functions
+  @{
+*/
+
+/*!
+ * @brief     Configs the code latency value.
+ *
+ * @param     latency: the FMC Latency value.
+ *            This parameter can be one of the following values:
+ *            @arg FMC_LTNCY_0: FMC 0 Latency cycle
+ *            @arg FMC_LTNCY_1: FMC 1 Latency cycle
+ *            @arg FMC_LTNCY_2: FMC 2 Latency cycles
+ *            @arg FMC_LTNCY_3: FMC 3 Latency cycles
+ *            @arg FMC_LTNCY_4: FMC 4 Latency cycles
+ *            @arg FMC_LTNCY_5: FMC 5 Latency cycles
+ *            @arg FMC_LTNCY_6: FMC 6 Latency cycles
+ *            @arg FMC_LTNCY_7: FMC 7 Latency cycles
+ *
+ * @retval    None
+ */
+void FMC_ConfigLatency(FMC_LATENCY_T latency)
+{
+    *(__IO uint8_t *)ACCTRL_BYTE0_ADDRESS = (uint8_t)latency;
+}
+
+/*!
+ * @brief     Enable the Prefetch Buffer.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_EnablePrefetchBuffer(void)
+{
+    FMC->ACCTRL |= FMC_ACCTRL_PREFEN;
+}
+
+/*!
+ * @brief     Disable the Prefetch Buffer.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_DisablePrefetchBuffer(void)
+{
+    FMC->ACCTRL &= (~FMC_ACCTRL_PREFEN);
+}
+
+/*!
+ * @brief     Enable the Instruction Cache feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_EnableInstructionCache(void)
+{
+    FMC->ACCTRL |= FMC_ACCTRL_ICACHEEN;
+}
+
+/*!
+ * @brief     Disable the Instruction Cache feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_DisableInstructionCache(void)
+{
+    FMC->ACCTRL &= (~FMC_ACCTRL_ICACHEEN);
+}
+
+/*!
+ * @brief     Enable the Data Cache feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_EnableDataCache(void)
+{
+    FMC->ACCTRL |= FMC_ACCTRL_DCACHEEN;
+}
+
+/*!
+ * @brief     Disable the Data Cache feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_DisableDataCache(void)
+{
+    FMC->ACCTRL &= (~FMC_ACCTRL_DCACHEEN);
+}
+
+/*!
+ * @brief     Reset the Instruction Cache feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_ResetInstructionCache(void)
+{
+    FMC->ACCTRL |= FMC_ACCTRL_ICACHERST;
+}
+
+/*!
+ * @brief     Reset the Data Cache feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_ResetDataCache(void)
+{
+    FMC->ACCTRL |= FMC_ACCTRL_DCACHERST;
+}
+
+/*!
+ * @brief     Unlocks the FMC control register access.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_Unlock(void)
+{
+    if ((FMC->CTRL & FMC_CTRL_LOCK) != RESET)
+    {
+        FMC->KEY = FMC_KEY1;
+        FMC->KEY = FMC_KEY2;
+    }
+}
+
+/*!
+ * @brief     Locks the FMC control register access.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_Lock(void)
+{
+    FMC->CTRL |= FMC_CTRL_LOCK;
+}
+
+/*!
+ * @brief     Erases a specified FMC Sector.
+ *
+ * @param     sector: The Sector number to be erased.
+ *            This parameter can be a value between FMC_SECTOR_0 and FMC_SECTOR_11.
+ *
+ * @param     voltageRange: The device voltage range which defines the erase parallelism.
+ *            This parameter can be one of the following values:
+ *              @arg FMC_VOLTAGE_1: when the device voltage range is 1.8V to 2.1V,
+ *                                  the operation will be done by byte (8-bit)
+ *              @arg FMC_VOLTAGE_2: when the device voltage range is 2.1V to 2.7V,
+ *                                  the operation will be done by half word (16-bit)
+ *              @arg FMC_VOLTAGE_3: when the device voltage range is 2.7V to 3.6V,
+ *                                  the operation will be done by word (32-bit)
+ *              @arg FMC_VOLTAGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
+ *                                  the operation will be done by double word (64-bit)
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_EraseSector(FMC_SECTOR_T sector, FMC_VOLTAGE_T voltageRange)
+{
+    uint32_t tmp_psize = 0x00;
+    FMC_STATUS_T status = FMC_COMPLETE;
+
+    if (voltageRange == FMC_VOLTAGE_1)
+    {
+        tmp_psize = FMC_PSIZE_BYTE;
+    }
+    else if (voltageRange == FMC_VOLTAGE_2)
+    {
+        tmp_psize = FMC_PSIZE_HALF_WORD;
+    }
+    else if (voltageRange == FMC_VOLTAGE_3)
+    {
+        tmp_psize = FMC_PSIZE_WORD;
+    }
+    else if (voltageRange == FMC_VOLTAGE_4)
+    {
+        tmp_psize = FMC_PSIZE_DOUBLE_WORD;
+    }
+
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        FMC->CTRL &= 0xFFFFFCFF;
+        FMC->CTRL |= tmp_psize;
+        FMC->CTRL &= 0xFFFFFF07;
+        FMC->CTRL |= FMC_CTRL_SERS | sector;
+        FMC->CTRL |= FMC_CTRL_START;
+        status = FMC_WaitForLastOperation();
+        FMC->CTRL &= (~FMC_CTRL_SERS);
+        FMC->CTRL &= 0xFFFFFF07;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Clears all FMC Sectors.
+ *
+ * @param     voltageRange: The device voltage range which defines the erase parallelism.
+ *            This parameter can be one of the following values:
+ *              @arg FMC_VOLTAGE_1: when the device voltage range is 1.8V to 2.1V,
+ *                                  the operation will be done by byte (8-bit)
+ *              @arg FMC_VOLTAGE_2: when the device voltage range is 2.1V to 2.7V,
+ *                                  the operation will be done by half word (16-bit)
+ *              @arg FMC_VOLTAGE_3: when the device voltage range is 2.7V to 3.6V,
+ *                                  the operation will be done by word (32-bit)
+ *              @arg FMC_VOLTAGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
+ *                                  the operation will be done by double word (64-bit)
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_EraseAllSectors(FMC_VOLTAGE_T voltageRange)
+{
+    uint32_t tmp_psize = 0x00;
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (voltageRange == FMC_VOLTAGE_1)
+    {
+        tmp_psize = FMC_PSIZE_BYTE;
+    }
+    else if (voltageRange == FMC_VOLTAGE_2)
+    {
+        tmp_psize = FMC_PSIZE_HALF_WORD;
+    }
+    else if (voltageRange == FMC_VOLTAGE_3)
+    {
+        tmp_psize = FMC_PSIZE_WORD;
+    }
+    else if (voltageRange == FMC_VOLTAGE_4)
+    {
+        tmp_psize = FMC_PSIZE_DOUBLE_WORD;
+    }
+
+    if (status == FMC_COMPLETE)
+    {
+        FMC->CTRL &= 0xFFFFFCFF;
+        FMC->CTRL |= tmp_psize;
+        FMC->CTRL |= FMC_CTRL_MERS;
+        FMC->CTRL |= FMC_CTRL_START;
+        status = FMC_WaitForLastOperation();
+        FMC->CTRL &= (~FMC_CTRL_MERS);
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Programs a double word (64-bit) at a specified address.
+ *
+ * @param     address:the address to be programmed.
+ *            ((address) >= 0x08000000) && ((address) <= 0x080FFFFF))
+ *            ((address) >= 0x1FFF7800) && ((address) <= 0x1FFF7A0F)))
+ *
+ * @param     data: the data to be programmed.
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_ProgramDoubleWord(uint32_t address, uint64_t data)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        FMC->CTRL &= 0xFFFFFCFF;
+        FMC->CTRL |= FMC_PSIZE_DOUBLE_WORD;
+        FMC->CTRL |= FMC_CTRL_PG;
+        *(__IO uint64_t *)address = data;
+        status = FMC_WaitForLastOperation();
+        FMC->CTRL &= (~FMC_CTRL_PG);
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Programs a word (32-bit) at a specified address.
+ *
+ * @param     address:the address to be programmed.
+ *            ((address) >= 0x08000000) && ((address) <= 0x080FFFFF))
+ *            ((address) >= 0x1FFF7800) && ((address) <= 0x1FFF7A0F)))
+ *
+ * @param     data: the data to be programmed.
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+
+FMC_STATUS_T FMC_ProgramWord(uint32_t address, uint32_t data)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        FMC->CTRL &= 0xFFFFFCFF;
+        FMC->CTRL |= FMC_PSIZE_WORD;
+        FMC->CTRL |= FMC_CTRL_PG;
+        *(__IO uint32_t *)address = data;
+        status = FMC_WaitForLastOperation();
+        FMC->CTRL &= (~FMC_CTRL_PG);
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Programs a half word (16-bit) at a specified address.
+ *
+ * @param     address:the address to be programmed.
+ *            ((address) >= 0x08000000) && ((address) <= 0x080FFFFF))
+ *            ((address) >= 0x1FFF7800) && ((address) <= 0x1FFF7A0F)))
+ *
+ * @param     data: the data to be programmed.
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_ProgramHalfWord(uint32_t address, uint16_t data)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        FMC->CTRL &= 0xFFFFFCFF;
+        FMC->CTRL |= FMC_PSIZE_HALF_WORD;
+        FMC->CTRL |= FMC_CTRL_PG;
+        *(__IO uint16_t *)address = data;
+        status = FMC_WaitForLastOperation();
+        FMC->CTRL &= (~FMC_CTRL_PG);
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Programs a byte (8-bit) at a specified address.
+ *
+ * @param     address:the address to be programmed.
+ *            ((address) >= 0x08000000) && ((address) <= 0x080FFFFF))
+ *            ((address) >= 0x1FFF7800) && ((address) <= 0x1FFF7A0F)))
+ *
+ * @param     data: the data to be programmed.
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_ProgramByte(uint32_t address, uint8_t data)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        FMC->CTRL &= 0xFFFFFCFF;
+        FMC->CTRL |= FMC_PSIZE_BYTE;
+        FMC->CTRL |= FMC_CTRL_PG;
+        *(__IO uint8_t *)address = data;
+        status = FMC_WaitForLastOperation();
+        FMC->CTRL &= (~FMC_CTRL_PG);
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Unlocks the option bytes block access
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_UnlockOptionByte(void)
+{
+    if ((FMC->OPTCTRL & FMC_OPTCTRL_OPTLOCK) != RESET)
+    {
+        FMC->OPTKEY = FMC_OPT_KEY1;
+        FMC->OPTKEY = FMC_OPT_KEY2;
+    }
+}
+
+/*!
+ * @brief     Locks the option bytes block access
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void FMC_LockOptionByte(void)
+{
+    FMC->OPTCTRL |= FMC_OPTCTRL_OPTLOCK;
+}
+
+/*!
+ * @brief     Enable the write protection of the desired sectors,
+ *            for the first 1 Mb of the FMC
+ *
+ * @param     wrp: specifies the sector(s) to be write protected or unprotected.
+ *            This parameter can be one of the following values:
+ *              @arg wrp: The value between FMC_OPT_WRP_SECTOR_0 and FMC_OPT_WRP_SECTOR_11
+ *              @arg FMC_OPT_WRP_SECTOR_All
+ *
+ * @retval    None
+ */
+void FMC_OPT_EnableWriteProtect(FMC_OPT_WRP_T wrp)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        *(__IO uint16_t *)(OPTCTRL_BYTE2_ADDRESS) &= (~(uint16_t)wrp);
+    }
+}
+
+/*!
+ * @brief     Disable the write protection of the desired sectors,
+ *            for the first 1 Mb of the FMC
+ *
+ * @param     wrp: Specifies the sector(s) to be write protected or unprotected.
+ *            This parameter can be one of the following values:
+ *              @arg wrp: The value between FMC_OPT_WRP_SECTOR_0 and FMC_OPT_WRP_SECTOR_11
+ *              @arg FMC_OPT_WRP_SECTOR_All
+ *
+ * @retval    None
+ */
+void FMC_OPT_DisableWriteProtect(FMC_OPT_WRP_T wrp)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        *(__IO uint16_t *)(OPTCTRL_BYTE2_ADDRESS) |= (uint16_t)wrp;
+    }
+}
+/*!
+ * @brief     Sets the read protection level.
+ *
+ * @param     rdp: Specifies the read protection level.
+ *            This parameter can be one of the following values:
+ *              @arg FMC_OPT_RDP_LV0: No protection
+ *              @arg FMC_OPT_RDP_LV1: Read protection of the memory
+ *
+ * @retval    None
+ */
+void FMC_OPT_ConfigReadProtect(FMC_OPT_RDP_T rdp)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        *(__IO uint8_t *)OPTCTRL_BYTE1_ADDRESS = rdp;
+    }
+}
+
+/*!
+ * @brief     Programs the FMC User Option Byte: WDTSEL / RSTSTOP / RSTSTDB.
+ *
+ * @param     iwdt: Selects the IWDT mode
+ *            This parameter can be one of the following values:
+ *              @arg FMC_OPT_IWDT_SOFT: Software IWDT selected
+ *              @arg FMC_OPT_IWDT_HARD: Hardware IWDT selected
+ * @param     stop: Reset event when entering STOP mode.
+ *            This parameter  can be one of the following values:
+ *              @arg FMC_OPT_STOP_NORST: No reset generated when entering in STOP
+ *              @arg FMC_OPT_STOP_RST: Reset generated when entering in STOP
+ * @param     stdby: Reset event when entering Standby mode.
+ *            This parameter  can be one of the following values:
+ *              @arg FMC_OPT_STDBY_NORST: No reset generated when entering in STANDBY
+ *              @arg FMC_OPT_STDBY_RST: Reset generated when entering in STANDBY
+ *
+ * @retval    None
+ */
+void FMC_OPT_ConfigUser(FMC_OPT_IWDT_T iwdt, FMC_OPT_STOP_T stop, FMC_OPT_STDBY_T stdby)
+{
+    uint8_t option = 0xFF;
+    FMC_STATUS_T status = FMC_COMPLETE;
+    status = FMC_WaitForLastOperation();
+
+    if (status == FMC_COMPLETE)
+    {
+        option = (uint8_t)((*(__IO uint8_t *)OPTCTRL_BYTE0_ADDRESS) & 0x0F);
+        *(__IO uint8_t *)OPTCTRL_BYTE0_ADDRESS = ((uint8_t)iwdt | stop | stdby | option);
+    }
+}
+
+/*!
+ * @brief     Sets the Brownout Reset Level.
+ *
+ * @param     bor: specifies the Option Bytes BOR Reset Level.
+ *            This parameter can be one of the following values:
+ *              @arg FMC_OPT_BOR_LV3: Supply voltage ranges from 2.7 to 3.6 V
+ *              @arg FMC_OPT_BOR_LV2: Supply voltage ranges from 2.4 to 2.7 V
+ *              @arg FMC_OPT_BOR_LV1: Supply voltage ranges from 2.1 to 2.4 V
+ *              @arg FMC_OPT_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V
+ *
+ * @retval    None
+ */
+void FMC_OPT_ConfigBrownoutReset(FMC_OPT_BOR_T bor)
+{
+    *(__IO uint8_t *)(OPTCTRL_BYTE0_ADDRESS) &= (~(FMC_OPTCTRL_BORLVL));
+    *(__IO uint8_t *)(OPTCTRL_BYTE0_ADDRESS) |= bor;
+}
+
+/*!
+ * @brief     Launch the option byte loading.
+ *
+ * @param     None
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_OPT_Launch(void)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+
+    *(__IO uint8_t *)(OPTCTRL_BYTE0_ADDRESS) |= (uint32_t)FMC_OPTCTRL_OPTSTART;
+    status = FMC_WaitForLastOperation();
+
+    return status;
+}
+
+/*!
+ * @brief     Returns the FMC User Option Bytes values.
+ *
+ * @param     None
+ *
+ * @retval    The FMC User Option Bytes values: WDTSEL(Bit0), RSTSTOP(Bit1)
+ *            and RSTSTDBY(Bit2).
+ */
+uint8_t FMC_OPT_ReadUser(void)
+{
+    return (uint8_t)(FMC->OPTCTRL >> 5);
+}
+
+/*!
+ * @brief     Returns the FMC Write Protection Option Bytes value.
+ *
+ * @param     None
+ *
+ * @retval    The FMC Write Protection Option Bytes value
+ */
+uint16_t FMC_OPT_ReadWriteProtect(void)
+{
+    return (*(__IO uint16_t *)(OPTCTRL_BYTE2_ADDRESS));
+}
+
+/*!
+ * @brief     Returns the FMC Read Protection level.
+ *
+ * @param     None
+ *
+ * @retval    tmp: ReadOut Protection Status:
+ *                 - SET, when FMC_OPT_RDP_LV1 is set
+ *                 - RESET, when FMC_OPT_RDP_LV0 is set
+ */
+uint8_t FMC_OPT_ReadProtectLevel(void)
+{
+    uint8_t tmp = RESET;
+
+    if ((*(__IO uint8_t *)((OPTCTRL_BYTE1_ADDRESS)) != (uint8_t)FMC_OPT_RDP_LV0))
+    {
+        tmp = SET;
+    }
+
+    return tmp;
+}
+
+/*!
+ * @brief     Returns the FMC BOR level.
+ *
+ * @param     None
+ *
+ * @retval    The FMC BOR level:
+ *              - FMC_OPT_BOR_LV1: Supply voltage ranges from 2.7 to 3.6 V
+ *              - FMC_OPT_BOR_LV1: Supply voltage ranges from 2.4 to 2.7 V
+ *              - FMC_OPT_BOR_LV1: Supply voltage ranges from 2.1 to 2.4 V
+ *              - FMC_OPT_BOR_OFF   : Supply voltage ranges from 1.62 to 2.1 V
+ */
+uint8_t FMC_OPT_ReadBrownoutReset(void)
+{
+    return (uint8_t)(*(__IO uint8_t *)((OPTCTRL_BYTE0_ADDRESS)) & FMC_OPT_BOR_OFF);
+}
+
+/*!
+ * @brief     Enables the specified FMC interrupts.
+ *
+ * @param     interrupt: Select the FMC interrupt sources
+ *                       This parameter can be any combination of the following values:
+ *                       @arg FMC_INT_ERR :  Error Interrupt
+ *                       @arg FMC_INT_OC  :  Operation Complete Interrupt
+ *
+ * @retval    None
+ */
+void FMC_EnableInterrupt(uint32_t interrupt)
+{
+    if (interrupt == FMC_INT_ERR)
+    {
+        FMC->CTRL |= FMC_INT_ERR;
+    }
+    else
+    {
+        FMC->CTRL |= FMC_INT_OC;
+    }
+}
+
+/*!
+ * @brief     Disable the specified FMC interrupts.
+ *
+ * @param     interrupt: Select the FMC interrupt sources
+ *                       This parameter can be any combination of the following values:
+ *                       @arg FMC_INT_ERR :  Error Interrupt
+ *                       @arg FMC_INT_OC  :  Operation Complete Interrupt
+ *
+ * @retval    None
+ */
+void FMC_DisableInterrupt(uint32_t interrupt)
+{
+    if (interrupt == FMC_INT_ERR)
+    {
+        FMC->CTRL &= ~(uint32_t)FMC_INT_ERR;
+    }
+    else
+    {
+        FMC->CTRL &= ~(uint32_t)FMC_INT_OC;
+    }
+}
+
+/*!
+ * @brief     Read the FMC flag
+ *
+ * @param     flag: specifies the FMC flag to check.
+ *            This parameter can be one of the following values:
+ *              @arg FMC_FLAG_ENDOP  : FMC End of Operation flag
+ *              @arg FMC_FLAG_ERROP  : FMC operation Error flag
+ *              @arg FMC_FLAG_ERRWRP : FMC Write protected error flag
+ *              @arg FMC_FLAG_ERRPGA : FMC Programming Alignment error flag
+ *              @arg FMC_FLAG_ERRPGP : FMC Programming Parallelism error flag
+ *              @arg FMC_FLAG_ERRPGS : FMC Programming Sequence error flag
+ *              @arg FMC_FLAG_BUSY   : FMC Busy flag
+ *
+ * @retval    SET or RESET.
+ */
+uint8_t FMC_ReadStatusFlag(FMC_FLAG_T flag)
+{
+    uint8_t temp = RESET;
+
+    if ((FMC->STS & flag) != (uint32_t)RESET)
+    {
+        temp = SET;
+    }
+
+    return temp;
+}
+
+/*!
+ * @brief     Clears the FMC flag.
+ *
+ * @param     flag: specifies the FMC flags to clear.
+ *            This parameter can be any combination of the following values:
+ *              @arg FMC_FLAG_ENDOP  : FMC End of Operation flag
+ *              @arg FMC_FLAG_ERROP  : FMC operation Error flag
+ *              @arg FMC_FLAG_ERRWRP : FMC Write protected error flag
+ *              @arg FMC_FLAG_ERRPGA : FMC Programming Alignment error flag
+ *              @arg FMC_FLAG_ERRPGP : FMC Programming Parallelism error flag
+ *              @arg FMC_FLAG_ERRPGS : FMC Programming Sequence error flag
+ *
+ * @retval    None
+ */
+void FMC_ClearStatusFlag(uint32_t flag)
+{
+    FMC->STS = flag;
+}
+
+/*!
+ * @brief     Returns the FMC Status.
+ *
+ * @param     None
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_ReadStatus(void)
+{
+    FMC_STATUS_T status = FMC_COMPLETE;
+
+    if ((FMC->STS & FMC_FLAG_BUSY) == FMC_FLAG_BUSY)
+    {
+        status = FMC_BUSY;
+    }
+    else if ((FMC->STS & FMC_FLAG_ERRWRP) != RESET)
+    {
+        status = FMC_ERROR_WRP;
+    }
+    else if ((FMC->STS & (uint32_t)0xE0) != RESET)
+    {
+        status = FMC_ERROR_PROGRAM;
+    }
+    else if ((FMC->STS & FMC_FLAG_ERROP) != RESET)
+    {
+        status = FMC_ERROR_OPERATION;
+    }
+    else
+    {
+        status = FMC_COMPLETE;
+    }
+
+    return status;
+}
+
+/*!
+ * @brief     Waits for a FMC operation to complete.
+ *
+ * @param     None
+ *
+ * @retval    FMC_STATUS_T: The returned value can be:
+ *            FMC_BUSY, FMC_ERROR_PROGRAM, FMC_ERROR_WRP, FMC_ERROR_OPERATION or FMC_COMPLETE.
+ */
+FMC_STATUS_T FMC_WaitForLastOperation(void)
+{
+    __IO FMC_STATUS_T status = FMC_COMPLETE;
+
+    status = FMC_ReadStatus();
+
+    while (status == FMC_BUSY)
+    {
+        status = FMC_ReadStatus();
+    }
+
+    return status;
+}
+
+/**@} end of group FMC_Functions */
+/**@} end of group FMC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 442 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_gpio.c

@@ -0,0 +1,442 @@
+/*!
+ * @file        apm32f4xx_gpio.c
+ *
+ * @brief       This file provides all the GPIO firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_gpio.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup GPIO_Driver
+  * @brief GPIO driver modules
+  @{
+*/
+
+/** @defgroup GPIO_Functions
+  @{
+*/
+
+/*!
+ * @brief  Reset the GPIOx peripheral registers to their default reset values.
+ *
+ * @param  port: Select the GPIO port.
+ *               This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *               for APM32F405xx/407xx and APM32F415xx/417xx devices
+ * @retval None
+ *
+ * @note   By reset, The GPIO pins are configured in input floating mode (except the JTAG pins).
+ */
+void GPIO_Reset(GPIO_T *port)
+{
+    RCM_AHB1_PERIPH_T AHB1Periph;
+
+    if (port == GPIOA)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOA;
+    }
+    else if (port == GPIOB)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOB;
+    }
+    else if (port == GPIOC)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOC;
+    }
+    else if (port == GPIOD)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOD;
+    }
+    else if (port == GPIOE)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOE;
+    }
+    else if (port == GPIOF)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOF;
+    }
+    else if (port == GPIOG)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOG;
+    }
+    else if (port == GPIOH)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOH;
+    }
+    else if (port == GPIOI)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOI;
+    }
+    else if (port == GPIOJ)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOJ;
+    }
+    else if (port == GPIOK)
+    {
+        AHB1Periph = RCM_AHB1_PERIPH_GPIOK;
+    }
+
+    RCM_EnableAHB1PeriphReset(AHB1Periph);
+    RCM_DisableAHB1PeriphReset(AHB1Periph);
+}
+
+/*!
+ * @brief        Config the GPIO peripheral according to the specified parameters in the gpioConfig
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param       gpioConfig: pointer to a GPIO_Config_T structure
+ *
+ * @retval      None
+ */
+void GPIO_Config(GPIO_T *port, GPIO_Config_T *gpioConfig)
+{
+    uint32_t i = 0x00;
+    uint32_t pos = 0x00;
+    uint32_t temp = 0x00;
+
+    for (i = 0; i < 16; i++)
+    {
+        pos = ((uint32_t)0x01) << i;
+        temp = (gpioConfig->pin) & pos;
+
+        if (temp == pos)
+        {
+            port->MODE  &= ~(0x03 << (i * 2));
+            port->MODE |= (((uint32_t)gpioConfig->mode) << (i * 2));
+
+            if ((gpioConfig->mode == GPIO_MODE_OUT) || (gpioConfig->mode == GPIO_MODE_AF))
+            {
+                port->OSSEL &= ~(0x03 << (i * 2));
+                port->OSSEL |= ((uint32_t)(gpioConfig->speed) << (i * 2));
+
+                port->OMODE  &= ~(0x01 << ((uint16_t)i)) ;
+                port->OMODE |= (uint16_t)(((uint16_t)gpioConfig->otype) << ((uint16_t)i));
+            }
+
+            port->PUPD &= ~(0x03 << ((uint16_t)i * 2));
+            port->PUPD |= (((uint32_t)gpioConfig->pupd) << (i * 2));
+        }
+    }
+}
+
+/*!
+ * @brief       Fills every gpioConfig member with its default value.
+ *
+ * @param       gpioConfig : pointer to a GPIO_Config_T structure which will be initialized.
+ *
+ * @retval      None
+ */
+void GPIO_ConfigStructInit(GPIO_Config_T *gpioConfig)
+{
+    gpioConfig->pin  = GPIO_PIN_ALL;
+    gpioConfig->mode = GPIO_MODE_IN;
+    gpioConfig->speed = GPIO_SPEED_2MHz;
+    gpioConfig->otype = GPIO_OTYPE_PP;
+    gpioConfig->pupd = GPIO_PUPD_NOPULL;
+}
+
+/*!
+ * @brief        Lock GPIO Pins config registers.
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param        pin: specifies the pin bit to be locked.
+ *                    This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+ *
+ * @retval       None
+ *
+ * @note         Locked registers are GPIOx_MODER, GPIOx_OMODER, GPIOx_OOSSELR,
+ *               GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH,until the next reset the
+ *               configuration of the locked GPIO pins can no longer be config.
+ *
+ */
+void GPIO_ConfigPinLock(GPIO_T *port, uint16_t pin)
+{
+    __IOM uint32_t temp = 0x00010000;
+
+    temp |= pin;
+
+    port->LOCK = temp;
+
+    port->LOCK = pin;
+
+    port->LOCK = temp;
+
+    temp = port->LOCK;
+}
+
+/*!
+ * @brief        Reads the specified input port pin.
+ *
+ * @param        port :Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param        pin: specifies the port bit to read.
+ *                    This parameter can be GPIO_Pin_x where x can be (0..15).
+ *
+ * @retval The input port pin value.
+ */
+uint8_t GPIO_ReadInputBit(GPIO_T *port, uint16_t pin)
+{
+    uint8_t readBit = 0x00;
+
+    readBit = (port->IDATA & pin) ?  BIT_SET : BIT_RESET;
+
+    return readBit;
+}
+
+/*!
+ * @brief        Reads the specified GPIO input data port.
+ *
+ * @param        port :Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @retval      GPIO input data port value.
+ */
+uint16_t GPIO_ReadInputPort(GPIO_T *port)
+{
+    return ((uint16_t)port->IDATA);
+}
+
+/*!
+ * @brief        Reads the specified output data port bit.
+ *
+ * @param        port :Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param        pin: specifies the port bit to read.
+ *                    This parameter can be one of GPIO_Pin_x where x can be (0..15).
+ *
+ * @retval       The output port pin value.
+ */
+uint8_t GPIO_ReadOutputBit(GPIO_T *port, uint16_t pin)
+{
+    uint8_t readBit = 0x00;
+
+    readBit = (port->ODATA & pin) ? BIT_SET : BIT_RESET;
+
+    return readBit;
+}
+
+/*!
+ * @brief        Reads the specified GPIO output data port
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @retval       output data port value
+ */
+uint16_t GPIO_ReadOutputPort(GPIO_T *port)
+{
+    return ((uint16_t)port->ODATA);
+}
+
+/*!
+ * @brief        Sets the selected data port bits
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param        pin : specifies pin to be written.
+ *                  This parameter can be any combination of GPIO_PIN_x( x can be from 0 to 15).
+ *
+ * @retval       None
+ */
+void GPIO_SetBit(GPIO_T *port, uint16_t pin)
+{
+    port->BSCL = pin;
+}
+
+/*!
+ * @brief     Clears the selected data port bits
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param     pin : specifies pin to be cleared.
+ *                  This parameter can be any combination of GPIO_PIN_x( x can be from 0 to 15).
+ *
+ * @retval    None
+ */
+void GPIO_ResetBit(GPIO_T *port, uint16_t pin)
+{
+    port->BSCH = pin;
+}
+
+/*!
+ * @brief        Writes data to the specified GPIO data port bit
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param        pin : Select specifies pin.
+ *                  This parameter can be one of GPIO_PIN_x( x can be from 0 to 15).
+ *
+ * @param       bitVal : specifies the value to be written to the port output data register
+ *                       This parameter can be one of the following values:
+ *                       @arg BIT_RESET : Reset the port pin
+ *                       @arg BIT_SET   : Set the port pin
+ *
+ * @retval       None
+ */
+void GPIO_WriteBitValue(GPIO_T *port, uint16_t pin, uint8_t bitVal)
+{
+    if (bitVal != BIT_RESET)
+    {
+        port->BSCL = pin;
+    }
+    else
+    {
+        port->BSCH = pin ;
+    }
+}
+
+/*!
+ * @brief        Writes data to the specified GPIO data port
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
+ *                     for APM32F405xx/407xx and APM32F415xx/417xx devices
+ *
+ * @param        portValue : specifies the value to be written to the port output data register.
+ *
+ * @retval       None
+ */
+void GPIO_WriteOutputPort(GPIO_T *port, uint16_t portValue)
+{
+    port->ODATA = (uint16_t)portValue;
+}
+
+/*!
+ * @brief       Toggles the specified GPIO pins.
+ *
+ * @param       port: Select the GPIO port.
+ *                    This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral.
+ *
+ * @param       pin: Specifies the pins to be toggled.
+ *
+ * @retval      None
+ */
+void GPIO_ToggleBit(GPIO_T *port, uint16_t pin)
+{
+    port->ODATA ^= pin;
+}
+
+/*!
+ * @brief        Changes the mapping of the specified pin.
+ *
+ * @param        port: Select the GPIO port.
+ *                     This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral.
+ *
+ * @param        gpioPinSource: specifies the pin for the Alternate function.
+ *                              This parameter can be GPIO_PinSourcex where x can be (0..15).
+ *
+ * @param        gpioAf: selects the pin to used as Alternate function.
+ *                       This parameter can be one of the following values:
+ *                       @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)
+ *                       @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)
+ *                       @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)
+ *                       @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)
+ *                       @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)
+ *                       @arg GPIO_AF_TMR1: Connect TMR1 pins to AF1
+ *                       @arg GPIO_AF_TMR2: Connect TMR2 pins to AF1
+ *                       @arg GPIO_AF_TMR3: Connect TMR3 pins to AF2
+ *                       @arg GPIO_AF_TMR4: Connect TMR4 pins to AF2
+ *                       @arg GPIO_AF_TMR5: Connect TMR5 pins to AF2
+ *                       @arg GPIO_AF_TMR8: Connect TMR8 pins to AF3
+ *                       @arg GPIO_AF_TMR9: Connect TMR9 pins to AF3
+ *                       @arg GPIO_AF_TMR10: Connect TMR10 pins to AF3
+ *                       @arg GPIO_AF_TMR11: Connect TMR11 pins to AF3
+ *                       @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4
+ *                       @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4
+ *                       @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4
+ *                       @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5
+ *                       @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
+ *                       @arg GPIO_AF_SPI4: Connect SPI4 pins to AF5
+ *                       @arg GPIO_AF_SPI5: Connect SPI5 pins to AF5
+ *                       @arg GPIO_AF_SPI6: Connect SPI6 pins to AF5
+ *                       @arg GPIO_AF_SAI1: Connect SAI1 pins to AF6
+ *                       @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
+ *                       @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7
+ *                       @arg GPIO_AF_USART1: Connect USART1 pins to AF7
+ *                       @arg GPIO_AF_USART2: Connect USART2 pins to AF7
+ *                       @arg GPIO_AF_USART3: Connect USART3 pins to AF7
+ *                       @arg GPIO_AF_UART4: Connect UART4 pins to AF8
+ *                       @arg GPIO_AF_UART5: Connect UART5 pins to AF8
+ *                       @arg GPIO_AF_USART6: Connect USART6 pins to AF8
+ *                       @arg GPIO_AF_UART7: Connect UART7 pins to AF8
+ *                       @arg GPIO_AF_UART8: Connect UART8 pins to AF8
+ *                       @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9
+ *                       @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9
+ *                       @arg GPIO_AF_TMR12: Connect TMR12 pins to AF9
+ *                       @arg GPIO_AF_TMR13: Connect TMR13 pins to AF9
+ *                       @arg GPIO_AF_TMR14: Connect TMR14 pins to AF9
+ *                       @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
+ *                       @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
+ *                       @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11
+ *                       @arg GPIO_AF_FSMC: Connect FSMC pins to AF12
+ *                       @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12
+ *                       @arg GPIO_AF_SDIO: Connect SDIO pins to AF12
+ *                       @arg GPIO_AF_DCMI: Connect DCMI pins to AF13
+ *                       @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15
+ *
+ * @retval    None
+ */
+void GPIO_ConfigPinAF(GPIO_T *port, GPIO_PIN_SOURCE_T gpioPinSource, GPIO_AF_T gpioAf)
+{
+    uint32_t val = 0x00;
+    uint32_t val_2 = 0x00;
+
+    if (gpioPinSource >> 0x03 == 0)
+    {
+        val = (uint32_t)(gpioAf) << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4);
+        port->ALFL &= ~((uint32_t)0xF << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4)) ;
+        val_2 = port->ALFL | val;
+        port->ALFL = val_2;
+    }
+    else
+    {
+        val = (uint32_t)(gpioAf) << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4);
+        port->ALFH &= ~((uint32_t)0xF << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4)) ;
+        val_2 = port->ALFH | val;
+        port->ALFH = val_2;
+    }
+}
+
+/**@} end of group GPIO_Functions */
+/**@} end of group GPIO_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 401 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash.c

@@ -0,0 +1,401 @@
+/*!
+ * @file        apm32f4xx_hash.c
+ *
+ * @brief       This file provides all the HASH firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_hash.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup HASH_Driver
+  * @brief HASH driver modules
+  @{
+*/
+
+/** @defgroup HASH_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset the HASH peripheral register.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void HASH_Reset(void)
+{
+    RCM_EnableAHB2PeriphReset(RCM_AHB2_PERIPH_HASH);
+    RCM_DisableAHB2PeriphReset(RCM_AHB2_PERIPH_HASH);
+}
+
+/*!
+ * @brief     Config the HASH peripheral according to the specified parameters in the hashConfig.
+ *
+ * @param     hashConfig: pointer to a HASH_Config_T structure.
+ *
+ * @retval    None
+ */
+void HASH_Config(HASH_Config_T *hashConfig)
+{
+    /* Configure the Algorithm used, algorithm mode and the datatype */
+    HASH->CTRL_B.ALGSEL = RESET;
+    HASH->CTRL_B.DTYPE = RESET;
+    HASH->CTRL_B.MODESEL = RESET;
+
+    HASH->CTRL_B.ALGSEL = hashConfig->algoSelect;
+    HASH->CTRL_B.DTYPE = hashConfig->dataType;
+    HASH->CTRL_B.MODESEL = hashConfig->algoMode;
+
+    /* if algorithm mode is HMAC, set the Key */
+    if (hashConfig->algoMode == HASH_ALGO_MODE_HMAC)
+    {
+        HASH->CTRL_B.LKEYSEL = RESET;
+        HASH->CTRL_B.LKEYSEL = hashConfig->hmacKeyType;
+    }
+
+    /* Reset the HASH processor core, so that the HASH will be ready to compute
+     the message digest of a new message */
+    HASH->CTRL_B.INITCAL = SET;
+}
+
+/*!
+ * @brief     Fills each HASH_Config_T member with its default value.
+ *
+ * @param     hashConfig: pointer to an HASH_Config_T structure.
+ *
+ * @retval    None
+ */
+void HASH_ConfigStructInit(HASH_Config_T *hashConfig)
+{
+    hashConfig->algoSelect = HASH_ALGO_SELECTION_SHA1;
+    hashConfig->algoMode = HASH_ALGO_MODE_HASH;
+    hashConfig->dataType = HASH_DATA_TYPE_32B;
+    hashConfig->hmacKeyType = HASH_HMAC_KEY_TYPE_SHORTKEY;
+}
+
+/*!
+ * @brief     Resets the HASH processor core.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void HASH_ResetProceCore(void)
+{
+    HASH->CTRL_B.INITCAL = SET;
+}
+
+/*!
+ * @brief     Configure the Number of valid bits in last word of the message.
+ *
+ * @param     ValidNumber: Number of valid bits in last word of the message.
+ *
+ * @retval    None
+ */
+void HASH_ConfigLastWordValidBitsNbr(uint16_t validNumber)
+{
+    HASH->START_B.LWNUM = RESET;
+    HASH->START_B.LWNUM = validNumber;
+}
+
+/*!
+ * @brief     Writes data in the Input Data FIFO.
+ *
+ * @param     data: new data of the message to be processed.
+ *
+ * @retval    None
+ */
+void HASH_WritesInputData(uint32_t data)
+{
+    HASH->INDATA_B.INDATA = data;
+}
+
+/*!
+ * @brief     Read the number of words already pushed into the IN FIFO.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+uint8_t HASH_ReadInFIFOWordsNbr(void)
+{
+    return (HASH->CTRL_B.WNUM);
+}
+
+/*!
+ * @brief     Read the provides message digest.
+ *
+ * @param     messageDigest: pointer to a HASH_Config_T structure.
+ *
+ * @retval    None
+ */
+void HASH_ReadDigest(HASH_MessageDigest_T *messageDigest)
+{
+    /* Read the data field */
+    messageDigest->Data[0] = HASH->DIG[0];
+    messageDigest->Data[1] = HASH->DIG[1];
+    messageDigest->Data[2] = HASH->DIG[2];
+    messageDigest->Data[3] = HASH->DIG[3];
+    messageDigest->Data[4] = HASH->DIG[4];
+}
+
+/*!
+ * @brief     Start the Digest calculation.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void HASH_StartDigest(void)
+{
+    HASH->START_B.DIGCAL = SET;
+}
+
+/*!
+ * @brief     Read the Hash peripheral Context.
+ *
+ * @param     contextRead: pointer to a HASH_Context_T structure that contains
+ *            the repository for current context.
+ *
+ * @retval    None
+ */
+void HASH_ReadContext(HASH_Context_T *contextRead)
+{
+    uint8_t i = 0;
+
+    contextRead->HASH_INT = HASH->INT;
+    contextRead->HASH_START = HASH->START;
+    contextRead->HASH_CTRL  = HASH->CTRL;
+
+    for (i = 0; i <= 50; i++)
+    {
+        contextRead->HASH_CTSWAP[i] = HASH->CTSWAP[i];
+    }
+}
+
+/*!
+ * @brief     Write the Hash peripheral Context.
+ *
+ * @param     contextWrite: pointer to a HASH_Context_T structure that contains
+ *            the repository for current context.
+ *
+ * @retval    None
+ */
+void HASH_WriteContext(HASH_Context_T *contextWrite)
+{
+    uint8_t i = 0;
+
+    HASH->INT = contextWrite->HASH_INT;
+    HASH->START = contextWrite->HASH_START;
+    HASH->CTRL = contextWrite->HASH_CTRL;
+
+    HASH->CTRL_B.INITCAL = SET;
+
+    for (i = 0; i <= 50; i++)
+    {
+        HASH->CTSWAP[i] = contextWrite->HASH_CTSWAP[i];
+    }
+}
+
+/*!
+ * @brief     Enables the HASH DMA interface.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void HASH_EnableDMA(void)
+{
+    HASH->CTRL_B.DMAEN = SET;
+}
+
+/*!
+ * @brief     Disabled the HASH DMA interface.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void HASH_DisableDMA(void)
+{
+    HASH->CTRL_B.DMAEN = RESET;
+}
+
+/*!
+ * @brief     Enables the specified HASH interrupts.
+ *
+ * @param     interrupt: Select the ADC interrupt sources
+ *                       This parameter can be any combination of the following values:
+ *                       @arg HASH_INT_INDATAINT: Input Data interrupt mask
+ *                       @arg HASH_INT_DCALCINT: Digest calculation completion Data interrupt mask
+ *
+ * @retval    None
+ */
+void HASH_EnableInterrupt(uint32_t interrupt)
+{
+    HASH->INT |= interrupt;
+}
+
+/*!
+ * @brief     Disables the specified HASH interrupts.
+ *
+ * @param     interrupt: Select the ADC interrupt sources
+ *                       This parameter can be any combination of the following values:
+ *                       @arg HASH_INT_INDATAINT: Input Data interrupt mask
+ *                       @arg HASH_INT_DCALCINT: Digest calculation completion Data interrupt mask
+ *
+ * @retval    None
+ */
+void HASH_DisableInterrupt(uint32_t interrupt)
+{
+    HASH->INT &= (uint32_t)~interrupt;
+}
+
+/*!
+ * @brief     Reads the pending HASH flag
+ *
+ * @param     flag: Select the flag to check
+ *                  This parameter can be one of the following values:
+ *             @arg HASH_FLAG_INDATAINT: Data input interrupt status flag
+ *             @arg HASH_FLAG_DCALCINT: Digest calculation completion interrupt status flag
+ *             @arg HASH_FLAG_DMA: DMAS Status flag
+ *             @arg HASH_FLAG_BUSY: Busy flag
+ *             @arg HASH_FLAG_DINNEMPT: Data Input register (DIN) not empty status flag
+ *
+ * @retval    SET or RESET
+ */
+uint8_t HASH_ReadFlagStatus(HASH_FLAG_T flag)
+{
+    uint32_t reg = 0;
+
+    if (flag == HASH_FLAG_DINNEMPT)
+    {
+        reg = HASH->CTRL;
+    }
+    else
+    {
+        reg = HASH->STS;
+    }
+
+    return (reg & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the pending HASH flag
+ *
+ * @param     flag: Select the flag to check
+ *                  This parameter can be one of the following values:
+ *             @arg HASH_FLAG_INDATAINT: Data input interrupt status flag
+ *             @arg HASH_FLAG_DCALCINT: Digest calculation completion interrupt status flag
+ *
+ * @retval    None
+ */
+void HASH_ClearStatusFlag(HASH_FLAG_T flag)
+{
+    if (flag == HASH_FLAG_INDATAINT)
+    {
+        HASH->STS_B.INDATAINT = BIT_RESET;
+    }
+    else if (flag == HASH_FLAG_DCALCINT)
+    {
+        HASH->STS_B.DCALCINT = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Reads the specified HASH Interrupt flag.
+ *
+ * @param     flag: Select the ADC interrupt source.
+ *                  This parameter can be one of the following values:
+ *             @arg HASH_INT_FLAG_INDATA: Input Data interrupt
+ *             @arg HASH_INT_FLAG_DCALC: Digest Calculation Completion Interrupt
+ *
+ * @retval    SET or RESET
+ */
+uint8_t HASH_ReadIntFlag(HASH_INT_FLAG_T flag)
+{
+    uint32_t intStatus = 0, reg = 0;
+
+    intStatus = HASH->INT;
+    reg = HASH->STS;
+
+    return (intStatus & (reg & flag)) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the pending HASH flag
+ *
+ * @param     flag: Select the flag to check
+ *                  This parameter can be one of the following values:
+ *             @arg HASH_INT_FLAG_INDATA: Input Data interrupt
+ *             @arg HASH_INT_FLAG_DCALC: Digest Calculation Completion Interrupt
+ *
+ * @retval    None
+ */
+void HASH_ClearIntFlag(HASH_INT_FLAG_T flag)
+{
+    if (flag == HASH_INT_FLAG_INDATA)
+    {
+        HASH->STS_B.INDATAINT = BIT_RESET;
+    }
+    else if (flag == HASH_INT_FLAG_DCALC)
+    {
+        HASH->STS_B.DCALCINT = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Waits for Compute data
+ *
+ * @param      timeOut: Waits for Compute time
+ *
+ * @retval    0: No block is currently being compute
+ *            1: The hash core is compute a block of data
+ *
+ */
+uint8_t HASH_WaitForCompute(uint32_t timeOut)
+{
+    __IO uint8_t flag = SET;
+    uint32_t time = timeOut;
+
+    while ((flag == SET) && (time > 0))
+    {
+        flag = HASH_ReadFlagStatus(HASH_FLAG_BUSY);
+        time --;
+    }
+
+    if ((flag == RESET) && (time > 0))
+    {
+        return 0;
+    }
+
+    return 1;
+}
+
+/**@} end of group HASH_Functions */
+/**@} end of group HASH_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 253 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash_md5.c

@@ -0,0 +1,253 @@
+/*!
+ * @file        apm32f4xx_hash_md5.c
+ *
+ * @brief       This file provides high level functions to compute the HASH MD5 and
+ *              HMAC MD5 Digest of an input message.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+
+#include "apm32f4xx_hash.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup HASH_MD5_Driver
+  * @brief HASH MD5 driver modules
+  @{
+*/
+
+/** @defgroup HASH_MD5_Functions
+  @{
+*/
+
+/** @defgroup HASH_MD5_Macros Macros
+  @{
+*/
+
+/* HASH MD5 timeout definition */
+#define MD5_BUSY_TIMEOUT    ((uint32_t) 0x00010000)
+
+/**@} end of group HASH_MD5_Macros*/
+
+/*!
+ * @brief     Compute the HASH MD5 digest
+ *
+ * @param     inBuffer: pointer to the input buffer to be treated
+ *
+ * @param     lenBuffer: length of the input buffer.
+ *
+ * @param     outBuffer: the returned digest.
+ *
+ * @retval    An ErrorStatus enumeration value:
+ *            SUCCESS: digest computation done
+ *            ERROR: digest computation failed
+ *
+ */
+uint8_t HASH_ComputeMD5(uint8_t *inBuffer, uint32_t lenBuffer,
+                        uint8_t outBuffer[16])
+{
+    HASH_Config_T hashMD5Config;
+    HASH_MessageDigest_T hashMD5MessageDigest;
+    uint16_t nuValidBits = 0;
+    uint32_t m = 0;
+    uint32_t inBufferaddr  = (uint32_t)inBuffer;
+    uint32_t outBufferaddr = (uint32_t)outBuffer;
+
+    nuValidBits = 8 * (lenBuffer % 4);
+
+    HASH_Reset();
+
+    /* HASH Configuration */
+    hashMD5Config.algoSelect = HASH_ALGO_SELECTION_MD5;
+    hashMD5Config.algoMode = HASH_ALGO_MODE_HASH;
+    hashMD5Config.dataType = HASH_DATA_TYPE_8B;
+    HASH_Config(&hashMD5Config);
+
+    /* Configure the number of valid bits in last word of the data */
+    HASH_ConfigLastWordValidBitsNbr(nuValidBits);
+
+    /* Write the input block in the IN FIFO */
+    for (m = 0; m < lenBuffer; m += 4)
+    {
+        HASH_WritesInputData(*(uint32_t *)inBufferaddr);
+        inBufferaddr += 4;
+    }
+
+    /* Start the HASH processor */
+    HASH_StartDigest();
+
+    /* wait until the Busy flag is RESET */
+    if (HASH_WaitForCompute(MD5_BUSY_TIMEOUT) != 0)
+    {
+        return ERROR;
+    }
+    else
+    {
+        /* Read the message digest */
+        HASH_ReadDigest(&hashMD5MessageDigest);
+
+        *(uint32_t *)(outBufferaddr)  = __REV(hashMD5MessageDigest.Data[0]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashMD5MessageDigest.Data[1]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashMD5MessageDigest.Data[2]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashMD5MessageDigest.Data[3]);
+    }
+
+    return SUCCESS;
+}
+
+/*!
+ * @brief     Compute the HMAC MD5 digest
+ *
+ * @param     key: pointer to the Key used for HMAC
+ *
+ * @param     lenkey: length of the Key used for HMAC
+ *
+ * @param     inBuffer: pointer to the Input buffer to be treated
+ *
+ * @param     lenBuffer: length of the Input buffer
+ *
+ * @param     outBuffer: the returned digest
+ *
+ * @retval    An ErrorStatus enumeration value:
+ *            SUCCESS: digest computation done
+ *            ERROR: digest computation failed
+ *
+ */
+uint8_t HMAC_ComputeMD5(uint8_t *key, uint32_t keylen, uint8_t *inBuffer,
+                        uint32_t lenBuffer, uint8_t outBuffer[16])
+{
+    HASH_Config_T hmacMD5Config;
+    HASH_MessageDigest_T hmacMD5MessageDigest;
+    uint16_t nuValidBits = 0;
+    uint16_t nuValidKey = 0;
+    uint32_t m = 0;
+    uint32_t keyaddr    = (uint32_t)key;
+    uint32_t inBufferaddr  = (uint32_t)inBuffer;
+    uint32_t outBufferaddr = (uint32_t)outBuffer;
+
+    nuValidBits = 8 * (lenBuffer % 4);
+    nuValidKey = 8 * (keylen % 4);
+
+    HASH_Reset();
+
+    /* HASH Configuration */
+    hmacMD5Config.algoSelect = HASH_ALGO_SELECTION_MD5;
+    hmacMD5Config.algoMode = HASH_ALGO_MODE_HMAC;
+    hmacMD5Config.dataType = HASH_DATA_TYPE_8B;
+
+    if (keylen > 64)
+    {
+        hmacMD5Config.hmacKeyType = HASH_HMAC_KEY_TYPE_LONGKEY;
+    }
+    else
+    {
+        hmacMD5Config.hmacKeyType = HASH_HMAC_KEY_TYPE_SHORTKEY;
+    }
+
+    HASH_Config(&hmacMD5Config);
+    HASH_ConfigLastWordValidBitsNbr(nuValidKey);
+
+    for (m = 0; m < keylen; m += 4)
+    {
+        HASH_WritesInputData(*(uint32_t *)keyaddr);
+        keyaddr += 4;
+    }
+
+    /* Start the HASH processor */
+    HASH_StartDigest();
+
+    /* wait until the Busy flag is RESET */
+    if (HASH_WaitForCompute(MD5_BUSY_TIMEOUT) != 0)
+    {
+        return ERROR;
+    }
+    else
+    {
+        /* Configure the number of valid bits in last word of the input data */
+        HASH_ConfigLastWordValidBitsNbr(nuValidBits);
+
+        /* Write the input block in the IN FIFO */
+        for (m = 0; m < lenBuffer; m += 4)
+        {
+            HASH_WritesInputData(*(uint32_t *)inBufferaddr);
+            inBufferaddr += 4;
+        }
+
+        /* Start the HASH processor */
+        HASH_StartDigest();
+
+        /* wait until the Busy flag is RESET */
+        if (HASH_WaitForCompute(MD5_BUSY_TIMEOUT) != 0)
+        {
+            return ERROR;
+        }
+        else
+        {
+            HASH_ConfigLastWordValidBitsNbr(nuValidKey);
+            keyaddr = (uint32_t)key;
+
+            for (m = 0; m < keylen; m += 4)
+            {
+                HASH_WritesInputData(*(uint32_t *)keyaddr);
+                keyaddr += 4;
+            }
+
+            /* Start the HASH processor */
+            HASH_StartDigest();
+
+            /* wait until the Busy flag is RESET */
+            if (HASH_WaitForCompute(MD5_BUSY_TIMEOUT) != 0)
+            {
+                return ERROR;
+            }
+            else
+            {
+                /* Read the message digest */
+                HASH_ReadDigest(&hmacMD5MessageDigest);
+
+                *(uint32_t *)(outBufferaddr)  = __REV(hmacMD5MessageDigest.Data[0]);
+
+                outBufferaddr += 4;
+                *(uint32_t *)(outBufferaddr)  = __REV(hmacMD5MessageDigest.Data[1]);
+
+                outBufferaddr += 4;
+                *(uint32_t *)(outBufferaddr)  = __REV(hmacMD5MessageDigest.Data[2]);
+
+                outBufferaddr += 4;
+                *(uint32_t *)(outBufferaddr)  = __REV(hmacMD5MessageDigest.Data[3]);
+            }
+        }
+    }
+
+    return SUCCESS;
+}
+
+/**@} end of group HASH_MD5_Functions */
+/**@} end of group HASH_MD5_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 253 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash_sha1.c

@@ -0,0 +1,253 @@
+/*!
+ * @file        apm32f4xx_hash_sha1.c
+ *
+ * @brief       This file provides high level functions to compute the HASH SHA1 and
+ *              HMAC SHA1 Digest of an input message.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_hash.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup HASH_SHA1_Driver
+  * @brief HASH SHA1 driver modules
+  @{
+*/
+
+/** @defgroup HASH_SHA1_Functions
+  @{
+*/
+
+/** @defgroup HASH_SHA1_Macros Macros
+  @{
+*/
+
+/* HASH SHA1 timeout definition */
+#define SHA1_BUSY_TIMEOUT    ((uint32_t) 0x00010000)
+
+/**@} end of group HASH_SHA1_Macros */
+
+/*!
+ * @brief     Compute the HASH SHA1 digest
+ *
+ * @param     inBuffer: pointer to the input buffer to be treated
+ *
+ * @param     lenBuffer: length of the input buffer.
+ *
+ * @param     outBuffer: the returned digest.
+ *
+ * @retval    An ErrorStatus enumeration value:
+ *            SUCCESS: digest computation done
+ *            ERROR: digest computation failed
+ *
+ */
+uint8_t HASH_ComputeSHA1(uint8_t *inBuffer, uint32_t lenBuffer,
+                         uint8_t outBuffer[20])
+{
+    HASH_Config_T hashSHA1Config;
+    HASH_MessageDigest_T hashSHA1MessageDigest;
+    uint16_t nBufferBits = 0;
+    uint32_t m = 0;
+    uint32_t inBufferaddr  = (uint32_t)inBuffer;
+    uint32_t outBufferaddr = (uint32_t)outBuffer;
+
+    nBufferBits = (lenBuffer % 4) * 8;
+
+    HASH_Reset();
+
+    /* Configure the number of valid bits in last word of the data */
+    hashSHA1Config.algoSelect = HASH_ALGO_SELECTION_SHA1;
+    hashSHA1Config.algoMode = HASH_ALGO_MODE_HASH;
+    hashSHA1Config.dataType = HASH_DATA_TYPE_8B;
+    HASH_Config(&hashSHA1Config);
+    HASH_ConfigLastWordValidBitsNbr(nBufferBits);
+
+    /* Write the input block in the IN FIFO */
+    for (m = 0; m < lenBuffer; m += 4)
+    {
+        HASH_WritesInputData(*(uint32_t *)inBufferaddr);
+        inBufferaddr += 4;
+    }
+
+    /* Start the HASH processor */
+    HASH_StartDigest();
+
+    /* wait until the Busy flag is RESET */
+    if (HASH_WaitForCompute(SHA1_BUSY_TIMEOUT) != 0)
+    {
+        return ERROR;
+    }
+    else
+    {
+        /* Read the message digest */
+        HASH_ReadDigest(&hashSHA1MessageDigest);
+
+        *(uint32_t *)(outBufferaddr)  = __REV(hashSHA1MessageDigest.Data[0]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashSHA1MessageDigest.Data[1]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashSHA1MessageDigest.Data[2]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashSHA1MessageDigest.Data[3]);
+
+        outBufferaddr += 4;
+        *(uint32_t *)(outBufferaddr)  = __REV(hashSHA1MessageDigest.Data[4]);
+    }
+
+    return SUCCESS;
+}
+
+/*!
+ * @brief     Compute the HMAC SHA1 digest
+ *
+ * @param     key: pointer to the Key used for HMAC
+ *
+ * @param     lenkey: length of the Key used for HMAC
+ *
+ * @param     inBuffer: pointer to the Input buffer to be treated
+ *
+ * @param     lenBuffer: length of the Input buffer
+ *
+ * @param     outBuffer: the returned digest
+ *
+ * @retval    An ErrorStatus enumeration value:
+ *            SUCCESS: digest computation done
+ *            ERROR: digest computation failed
+ *
+ */
+uint8_t HMAC_ComputeSHA1(uint8_t *key, uint32_t lenkey, uint8_t *inBuffer,
+                         uint32_t lenBuffer, uint8_t outBuffer[20])
+{
+    HASH_Config_T hmacSHA1Config;
+    HASH_MessageDigest_T hashSHA1MessageDigest;
+    uint16_t nBufferBits = 0;
+    uint16_t nuValidKey = 0;
+    uint32_t m = 0;
+    uint32_t keyaddr    = (uint32_t)key;
+    uint32_t inputaddr  = (uint32_t)inBuffer;
+    uint32_t outputaddr = (uint32_t)outBuffer;
+
+    nBufferBits = 8 * (lenBuffer % 4);
+    nuValidKey = 8 * (lenkey % 4);
+
+    HASH_Reset();
+
+    /* HASH Configuration */
+    hmacSHA1Config.algoSelect = HASH_ALGO_SELECTION_SHA1;
+    hmacSHA1Config.algoMode = HASH_ALGO_MODE_HMAC;
+    hmacSHA1Config.dataType = HASH_DATA_TYPE_8B;
+
+    if (lenkey > 64)
+    {
+        hmacSHA1Config.hmacKeyType = HASH_HMAC_KEY_TYPE_LONGKEY;
+    }
+    else
+    {
+        hmacSHA1Config.hmacKeyType = HASH_HMAC_KEY_TYPE_SHORTKEY;
+    }
+
+    HASH_Config(&hmacSHA1Config);
+    HASH_ConfigLastWordValidBitsNbr(nuValidKey);
+
+    /* Write the key */
+    for (m = 0; m < lenkey; m += 4)
+    {
+        HASH_WritesInputData(*(uint32_t *)keyaddr);
+        keyaddr += 4;
+    }
+
+    HASH_StartDigest();
+
+    /* wait until the Busy flag is RESET */
+    if (HASH_WaitForCompute(SHA1_BUSY_TIMEOUT) != 0)
+    {
+        return ERROR;
+    }
+    else
+    {
+        HASH_ConfigLastWordValidBitsNbr(nBufferBits);
+
+        for (m = 0; m < lenkey; m += 4)
+        {
+            HASH_WritesInputData(*(uint32_t *)inputaddr);
+            inputaddr += 4;
+        }
+
+        HASH_StartDigest();
+
+        /* wait until the Busy flag is RESET */
+        if (HASH_WaitForCompute(SHA1_BUSY_TIMEOUT) != 0)
+        {
+            return ERROR;
+        }
+        else
+        {
+            HASH_ConfigLastWordValidBitsNbr(nuValidKey);
+            /* Write the key */
+            keyaddr = (uint32_t)key;
+
+            for (m = 0; m < lenkey; m += 4)
+            {
+                HASH_WritesInputData(*(uint32_t *)keyaddr);
+                keyaddr += 4;
+            }
+
+            /* Start the HASH processor */
+            HASH_StartDigest();
+
+            /* wait until the Busy flag is RESET */
+            if (HASH_WaitForCompute(SHA1_BUSY_TIMEOUT) != 0)
+            {
+                return ERROR;
+            }
+            else
+            {
+                /* Read the message digest */
+                HASH_ReadDigest(&hashSHA1MessageDigest);
+                *(uint32_t *)(outputaddr)  = __REV(hashSHA1MessageDigest.Data[0]);
+
+                outputaddr += 4;
+                *(uint32_t *)(outputaddr)  = __REV(hashSHA1MessageDigest.Data[1]);
+
+                outputaddr += 4;
+                *(uint32_t *)(outputaddr)  = __REV(hashSHA1MessageDigest.Data[2]);
+
+                outputaddr += 4;
+                *(uint32_t *)(outputaddr)  = __REV(hashSHA1MessageDigest.Data[3]);
+
+                outputaddr += 4;
+                *(uint32_t *)(outputaddr)  = __REV(hashSHA1MessageDigest.Data[4]);
+            }
+        }
+    }
+
+    return SUCCESS;
+}
+
+/**@} end of group HASH_SHA1_Functions */
+/**@} end of group HASH_SHA1_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 1070 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_i2c.c

@@ -0,0 +1,1070 @@
+/*!
+ * @file        apm32f4xx_i2c.c
+ *
+ * @brief       This file provides all the I2C firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_i2c.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup I2C_Driver
+  * @brief I2C driver modules
+  @{
+*/
+
+/** @defgroup I2C_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset I2C
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_Reset(I2C_T *i2c)
+{
+    if (i2c == I2C1)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C1);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C1);
+    }
+    else if (i2c == I2C2)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C2);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C2);
+    }
+    else if (i2c == I2C3)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C3);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C3);
+    }
+}
+
+/*!
+ * @brief     Configure I2C by configuring the structure
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     i2cConfig: pointer to a I2C_Config_T structure
+ *
+ * @retval    None
+ */
+void I2C_Config(I2C_T *i2c, I2C_Config_T *i2cConfig)
+{
+    uint16_t temp = 0, freq = 0;
+    uint32_t PCLK1 = 8000000, PCLK2 = 0;
+    uint16_t result = 0x04;
+
+    /* I2C CTRL2 Configuration */
+    RCM_ReadPCLKFreq(&PCLK1, &PCLK2);
+    freq = PCLK1 / 1000000;
+    i2c->CTRL2_B.CLKFCFG = freq;
+
+    /* I2C CLKCTRL Configuration */
+    i2c->CTRL1_B.I2CEN = BIT_RESET;
+
+    if (i2cConfig->clockSpeed <= 100000)
+    {
+        result = (PCLK1 / (i2cConfig->clockSpeed << 1));
+        if (result < 0x04)
+        {
+            result = 0x04;
+        }
+        i2c->RISETMAX = freq + 1;
+        temp |= result;
+    }
+    /* Configure speed in fast mode */
+    else
+    {
+        if (i2cConfig->dutyCycle == I2C_DUTYCYCLE_2)
+        {
+            result = (PCLK1 / (i2cConfig->clockSpeed * 3));
+        }
+        else
+        {
+            result = (PCLK1 / (i2cConfig->clockSpeed * 25));
+            result |= I2C_DUTYCYCLE_16_9;
+        }
+
+        if ((result & 0x0FFF) == 0)
+        {
+            result |= 0x0001;
+        }
+
+        temp |= (uint16_t)(result | 0x8000);
+        i2c->RISETMAX = ((((freq) * 300) / 1000) + 1);
+    }
+    i2c->CLKCTRL = temp;
+    i2c->CTRL1_B.I2CEN = BIT_SET;
+
+    /* i2c CTRL1 Configuration  */
+    i2c->CTRL1_B.ACKEN = BIT_RESET;
+    i2c->CTRL1_B.SMBTCFG = BIT_RESET;
+    i2c->CTRL1_B.SMBEN = BIT_RESET;
+
+    i2c->CTRL1 |= i2cConfig->mode;
+    i2c->CTRL1_B.ACKEN = i2cConfig->ack;
+
+    i2c->SADDR1 = i2cConfig->ackAddress | i2cConfig->ownAddress1;
+}
+
+/*!
+ * @brief     Fills each I2C_InitStruct member with its default value.
+ *
+ * @param     i2cConfig: pointer to a I2C_Config_T structure
+ *
+ * @retval    None
+ */
+void I2C_ConfigStructInit(I2C_Config_T *i2cConfig)
+{
+    i2cConfig->clockSpeed = 5000;
+    i2cConfig->mode = I2C_MODE_I2C;
+    i2cConfig->dutyCycle = I2C_DUTYCYCLE_2;
+    i2cConfig->ownAddress1 = 0;
+    i2cConfig->ack = I2C_ACK_DISABLE;
+    i2cConfig->ackAddress = I2C_ACK_ADDRESS_7BIT;
+}
+
+/*!
+ * @brief     Enable I2C
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_Enable(I2C_T *i2c)
+{
+    i2c->CTRL1_B.I2CEN = SET;
+}
+
+/*!
+ * @brief     Disable I2C
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_Disable(I2C_T *i2c)
+{
+    i2c->CTRL1_B.I2CEN = RESET;
+}
+
+/*!
+ * @brief     Enable Generates i2c communication START condition.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableGenerateStart(I2C_T *i2c)
+{
+    i2c->CTRL1_B.START = SET;
+}
+
+/*!
+ * @brief     Disable Generates i2c communication START condition.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableGenerateStart(I2C_T *i2c)
+{
+    i2c->CTRL1_B.START = RESET;
+}
+
+/*!
+ * @brief     Enable Generates i2c communication STOP condition.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableGenerateStop(I2C_T *i2c)
+{
+    i2c->CTRL1_B.STOP = SET;
+}
+
+/*!
+ * @brief     Disable Generates i2c communication STOP condition.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableGenerateStop(I2C_T *i2c)
+{
+    i2c->CTRL1_B.STOP = RESET;
+}
+
+/*!
+ * @brief     Transmits the address byte to select the slave device.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     address: slave address which will be transmitted
+ *
+ * @param     direction: Direction mode
+ *              The parameter can be one of following values:
+ *              @arg I2C_DIRECTION_TX: Transmitter mode
+ *              @arg I2C_DIRECTION_RX: Receiver mode
+ *
+ * @retval    None
+ */
+void I2C_Tx7BitAddress(I2C_T *i2c, uint8_t address, I2C_DIRECTION_T direction)
+{
+    if (direction != I2C_DIRECTION_TX)
+    {
+        i2c->DATA_B.DATA = address | 0x0001;
+    }
+    else
+    {
+        i2c->DATA_B.DATA = address & 0xFFFE;
+    }
+}
+/*!
+ * @brief     Enables the specified I2C acknowledge feature.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableAcknowledge(I2C_T *i2c)
+{
+    i2c->CTRL1_B.ACKEN = SET;
+}
+
+/*!
+ * @brief     Disables the specified I2C acknowledge feature.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableAcknowledge(I2C_T *i2c)
+{
+    i2c->CTRL1_B.ACKEN = RESET;
+}
+
+/*!
+ * @brief     Config the specified I2C own address2.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     address:specifies the 7bit I2C own address2.
+ *
+ * @retval    None
+ */
+void I2C_ConfigOwnAddress2(I2C_T *i2c, uint8_t address)
+{
+    i2c->SADDR2_B.ADDR2 = address;
+}
+
+/*!
+ * @brief     Enables the specified I2C dual addressing mode.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableDualAddress(I2C_T *i2c)
+{
+    i2c->SADDR2_B.ADDRNUM = SET;
+}
+
+/*!
+ * @brief     Disables the specified I2C dual addressing mode.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableDualAddress(I2C_T *i2c)
+{
+    i2c->SADDR2_B.ADDRNUM = RESET;
+}
+
+/*!
+ * @brief     Enables the specified I2C general call feature.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableGeneralCall(I2C_T *i2c)
+{
+    i2c->CTRL1_B.SRBEN = SET;
+}
+
+/*!
+ * @brief     Disables the specified I2C general call feature.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableGeneralCall(I2C_T *i2c)
+{
+    i2c->CTRL1_B.SRBEN = RESET;
+}
+
+/*!
+ * @brief     Enables the I2C software reset.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableSoftwareReset(I2C_T *i2c)
+{
+    i2c->CTRL1_B.SWRST = SET;
+}
+
+/*!
+ * @brief     Disables the I2C software reset.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableSoftwareReset(I2C_T *i2c)
+{
+    i2c->CTRL1_B.SWRST = RESET;
+}
+
+/*!
+ * @brief     Enables the I2C Clock stretching.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableStretchClock(I2C_T *i2c)
+{
+    i2c->CTRL1_B.CLKSTRETCHD = RESET;
+}
+
+/*!
+ * @brief     Disables the I2C Clock stretching.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableStretchClock(I2C_T *i2c)
+{
+    i2c->CTRL1_B.CLKSTRETCHD = SET;
+}
+
+/*!
+ * @brief     Selects the specified I2C fast mode duty cycle.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     dutyCycle: the fast mode duty cycle.
+ *              The parameter can be one of following values:
+ *              @arg I2C_DUTYCYCLE_16_9: I2C fast mode Tlow/Thigh = 16/9
+ *              @arg I2C_DUTYCYCLE_2: I2C fast mode Tlow/Thigh = 2
+ * @retval    None
+ */
+void I2C_ConfigFastModeDutyCycle(I2C_T *i2c, I2C_DUTYCYCLE_T dutyCycle)
+{
+    if (dutyCycle == I2C_DUTYCYCLE_16_9)
+    {
+        i2c->CLKCTRL_B.FDUTYCFG = BIT_SET;
+    }
+    else
+    {
+        i2c->CLKCTRL_B.FDUTYCFG = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Selects the specified I2C NACK position in master receiver mode.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     NACKPosition: specifies the NACK position.
+ *
+ * @retval    None
+ */
+void I2C_ConfigNACKPosition(I2C_T *i2c, I2C_NACK_POSITION_T NACKPosition)
+{
+    if (NACKPosition == I2C_NACK_POSITION_NEXT)
+    {
+        i2c->CTRL1_B.ACKPOS = BIT_SET;
+    }
+    else
+    {
+        i2c->CTRL1_B.ACKPOS = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Control the height of pin of SMBusAlert
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     SMBusState: SMBAlert pin level.
+ *              The parameter can be one of following values:
+ *              @arg I2C_SMBUSALER_LOW: SMBus Alert pin low
+ *              @arg I2C_SMBUSALER_HIGH: SMBus Alert pin high
+ *
+ * @retval    None
+ */
+void I2C_ConfigSMBusAlert(I2C_T *i2c, I2C_SMBUSALER_T SMBusState)
+{
+    if (SMBusState == I2C_SMBUSALER_LOW)
+    {
+        i2c->CTRL1_B.ALERTEN = BIT_SET;
+    }
+    else
+    {
+        i2c->CTRL1_B.ALERTEN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the I2C ARP.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableARP(I2C_T *i2c)
+{
+    i2c->CTRL1_B.ARPEN = SET;
+}
+
+/*!
+* @brief      Disables the I2C ARP.
+*
+* @param      i2c: I2C selet 1 or 2
+*
+* @retval     None
+*/
+void I2C_DisableARP(I2C_T *i2c)
+{
+    i2c->CTRL1_B.ARPEN = RESET;
+}
+
+/*!
+ * @brief     Send one byte
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     data: data to send
+ *
+ * @retval    None
+ */
+void I2C_TxData(I2C_T *i2c, uint8_t data)
+{
+    i2c->DATA_B.DATA = data;
+}
+
+/*!
+ * @brief     Returns the recevie data
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    received data
+ */
+uint8_t I2C_RxData(I2C_T *i2c)
+{
+    return i2c->DATA_B.DATA;
+}
+
+/*!
+ * @brief     Enables the I2C PEC transfer.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnablePECTransmit(I2C_T *i2c)
+{
+    i2c->CTRL1_B.PEC = SET;
+}
+
+/*!
+ * @brief     Disables the I2C PEC transfer.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisablePECTransmit(I2C_T *i2c)
+{
+    i2c->CTRL1_B.PEC = RESET;
+}
+
+/*!
+ * @brief     Selects the I2C PEC position.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     PECPosition: PEC position
+ *              The parameter can be one of following values:
+ *              @arg I2C_PEC_POSITION_NEXT: indicates that the next byte is PEC
+ *              @arg I2C_PEC_POSITION_CURRENT: indicates that current byte is PEC
+ *
+ * @retval    None
+ */
+void I2C_ConfigPECPosition(I2C_T *i2c, I2C_PEC_POSITION_T PECPosition)
+{
+    if (PECPosition == I2C_PEC_POSITION_NEXT)
+    {
+        i2c->CTRL1_B.ACKPOS = SET;
+    }
+    else
+    {
+        i2c->CTRL1_B.ACKPOS = RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the PEC value calculation of the transferred bytes.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnablePEC(I2C_T *i2c)
+{
+    i2c->CTRL1_B.PECEN = SET;
+}
+
+/*!
+ * @brief     Disables the PEC value calculation of the transferred bytes.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisablePEC(I2C_T *i2c)
+{
+    i2c->CTRL1_B.PECEN = RESET;
+}
+
+/*!
+ * @brief     Read the PEC value for the I2C.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    value of PEC
+ */
+uint8_t I2C_ReadPEC(I2C_T *i2c)
+{
+    return i2c->STS2_B.PECVALUE;
+}
+
+/*!
+ * @brief     Enables the specified I2C DMA requests.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableDMA(I2C_T *i2c)
+{
+    i2c->CTRL2_B.DMAEN = SET;
+}
+
+/*!
+ * @brief     Disable the specified I2C DMA requests.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableDMA(I2C_T *i2c)
+{
+    i2c->CTRL2_B.DMAEN = RESET;
+}
+
+/*!
+ * @brief     Enable DMA to receive the last transfer
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_EnableDMALastTransfer(I2C_T *i2c)
+{
+    i2c->CTRL2_B.LTCFG = SET;
+}
+
+/*!
+ * @brief     Disable DMA to receive the last transfer
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    None
+ */
+void I2C_DisableDMALastTransfer(I2C_T *i2c)
+{
+    i2c->CTRL2_B.LTCFG = RESET;
+}
+
+/*!
+ * @brief     Reads the I2C register and returns its value.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     i2cRegister : register to read
+ *              The parameter can be one of following values:
+ *              @arg I2C_REGISTER_CTRL1: CTRL1 register
+ *              @arg I2C_REGISTER_CTRL2: CTRL2 register
+ *              @arg I2C_REGISTER_SADDR1: SADDR1 register
+ *              @arg I2C_REGISTER_SADDR2: SADDR2 register
+ *              @arg I2C_REGISTER_DATA: DATA register
+ *              @arg I2C_REGISTER_STS1: STS1 register
+ *              @arg I2C_REGISTER_STS2: STS2 register
+ *              @arg I2C_REGISTER_CLKCTRL: CLKCTRL register
+ *              @arg I2C_REGISTER_RISETMAX: RISETMAX register
+ *
+ * @retval    The value of the read register
+ */
+uint16_t I2C_ReadRegister(I2C_T *i2c, I2C_REGISTER_T i2cRegister)
+{
+    switch (i2cRegister)
+    {
+    case I2C_REGISTER_CTRL1:
+        return i2c->CTRL1;
+
+    case I2C_REGISTER_CTRL2:
+        return i2c->CTRL2;
+
+    case I2C_REGISTER_SADDR1:
+        return i2c->SADDR1;
+
+    case I2C_REGISTER_SADDR2:
+        return i2c->SADDR2;
+
+    case I2C_REGISTER_DATA:
+        return i2c->DATA;
+
+    case I2C_REGISTER_STS1:
+        return i2c->STS1;
+
+    case I2C_REGISTER_STS2:
+        return i2c->STS2;
+
+    case I2C_REGISTER_CLKCTRL:
+        return i2c->CLKCTRL;
+
+    case I2C_REGISTER_RISETMAX:
+        return i2c->RISETMAX;
+
+    default:
+        return 0;
+    }
+}
+
+/*!
+ * @brief     Enables the specified I2C interrupts.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     interrupt:I2C interrupts sources
+ *              The parameter can be any combination of following values:
+ *              @arg I2C_INT_BUF: Buffer interrupt
+ *              @arg I2C_INT_EVT: Event interrupt
+ *              @arg I2C_INT_ERR: Error interrupt
+ *
+ * @retval    None
+ */
+void I2C_EnableInterrupt(I2C_T *i2c, uint16_t interrupt)
+{
+    i2c->CTRL2 |= interrupt;
+}
+
+/*!
+ * @brief     Disable the specified I2C interrupts.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     interrupt:I2C interrupts sources
+ *              The parameter can be any combination of following values:
+ *              @arg I2C_INT_BUF: Buffer interrupt
+ *              @arg I2C_INT_EVT: Event interrupt
+ *              @arg I2C_INT_ERR: Error interrupt
+ *
+ * @retval    None
+ */
+void I2C_DisableInterrupt(I2C_T *i2c, uint16_t interrupt)
+{
+    i2c->CTRL2 &= ~interrupt;
+}
+
+/*!
+ * @brief     Check that the last event is equal to the last passed event
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     i2cEvent: the event to be checked.
+ *              The parameter can be one of the following values:
+ *            @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:           EV1
+ *            @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:              EV1
+ *            @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:     EV1
+ *            @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED:        EV1
+ *            @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:            EV1
+ *            @arg I2C_EVENT_SLAVE_BYTE_RECEIVED:                         EV2
+ *            @arg I2C_EVENT_SLAVE_BYTE_RECEIVED1:                        EV2
+ *            @arg I2C_EVENT_SLAVE_BYTE_RECEIVED2:                        EV2
+ *            @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED:                      EV3
+ *            @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED1:                     EV3
+ *            @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED2:                     EV3
+ *            @arg I2C_EVENT_SLAVE_ACK_FAILURE:                           EV3_2
+ *            @arg I2C_EVENT_SLAVE_STOP_DETECTED:                         EV4
+ *            @arg I2C_EVENT_MASTER_MODE_SELECT:                          EV5
+ *            @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:            EV6
+ *            @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:               EV6
+ *            @arg I2C_EVENT_MASTER_BYTE_RECEIVED:                        EV7
+ *            @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING:                    EV8
+ *            @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED:                     EV8_2
+ *            @arg I2C_EVENT_MASTER_MODE_ADDRESS10:                       EV9
+ *
+ * @retval    Status: SUCCESS or ERROR
+ */
+uint8_t  I2C_ReadEventStatus(I2C_T *i2c, I2C_EVENT_T i2cEvent)
+{
+    uint32_t lastevent = 0;
+    uint32_t flag1 = 0, flag2 = 0;
+
+    flag1 = i2c->STS1 & 0x0000FFFF;
+    flag2 = i2c->STS2 & 0x0000FFFF;
+    flag2 = flag2 << 16;
+
+    lastevent = (flag1 | flag2) & 0x00FFFFFF;
+
+    if ((lastevent & i2cEvent) == i2cEvent)
+    {
+        return SUCCESS;
+    }
+
+    return ERROR;
+}
+
+/*!
+ * @brief     Read the last i2c Event.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @retval    The last event
+ */
+uint32_t I2C_ReadLastEvent(I2C_T *i2c)
+{
+    uint32_t lastevent = 0;
+    uint32_t flag1 = 0, flag2 = 0;
+
+    flag1 = i2c->STS1 & 0x0000FFFF;
+    flag2 = i2c->STS2 & 0x0000FFFF;
+    flag2 = flag2 << 16;
+
+    lastevent = (flag1 | flag2) & 0x00FFFFFF;
+
+    return lastevent;
+}
+
+/*!
+ * @brief     Check whether the I2C flag is set
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     flag: specifies the I2C flag
+ *              The parameter can be one of the following values:
+ *              @arg I2C_FLAG_DUALADDR: Dual flag (Slave mode)
+ *              @arg I2C_FLAG_SMMHADDR: SMBus host header (Slave mode)
+ *              @arg I2C_FLAG_SMBDADDR: SMBus default header (Slave mode)
+ *              @arg I2C_FLAG_GENCALL:  General call header flag (Slave mode)
+ *              @arg I2C_FLAG_TR:       Transmitter/Receiver flag
+ *              @arg I2C_FLAG_BUSBSY:   Bus busy flag
+ *              @arg I2C_FLAG_MS:       Master/Slave flag
+ *              @arg I2C_FLAG_SMBALT:   SMBus Alert flag
+ *              @arg I2C_FLAG_TTE:      Timeout or Tlow error flag
+ *              @arg I2C_FLAG_PECE:     PEC error in reception flag
+ *              @arg I2C_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
+ *              @arg I2C_FLAG_AE:       Acknowledge error flag
+ *              @arg I2C_FLAG_AL:       Arbitration lost flag (Master mode)
+ *              @arg I2C_FLAG_BERR:     Bus error flag
+ *              @arg I2C_FLAG_TXBE:     Transmitter data register empty flag
+ *              @arg I2C_FLAG_RXBNE:    Receiver data register not empty flag
+ *              @arg I2C_FLAG_STOP:     Stop detection flag (Slave mode)
+ *              @arg I2C_FLAG_ADDR10:   10-bit header sent flag (Master mode)
+ *              @arg I2C_FLAG_BTC:      Byte transfer complete flag
+ *              @arg I2C_FLAG_ADDR:     Address sent flag (Master mode)
+ *              @arg I2C_FLAG_START:    Start bit flag (Master mode)
+ *
+ * @retval    Status: flag SET or RESET
+ */
+uint8_t I2C_ReadStatusFlag(I2C_T *i2c, I2C_FLAG_T flag)
+{
+
+    uint8_t status = 0;
+    switch (flag)
+    {
+    case I2C_FLAG_DUALADDR:
+        status = i2c->STS2_B.DUALADDRFLG;
+        break;
+
+    case I2C_FLAG_SMMHADDR:
+        status = i2c->STS2_B.SMMHADDR;
+        break;
+
+    case I2C_FLAG_SMBDADDR:
+        status = i2c->STS2_B.SMBDADDRFLG;
+        break;
+
+    case I2C_FLAG_GENCALL:
+        status = i2c->STS2_B.GENCALLFLG;
+        break;
+
+    case I2C_FLAG_TR:
+        status = i2c->STS2_B.TRFLG;
+        break;
+
+    case I2C_FLAG_BUSBSY:
+        status = i2c->STS2_B.BUSBSYFLG;
+        break;
+
+    case I2C_FLAG_MS:
+        status = i2c->STS2_B.MSFLG;
+        break;
+
+    case I2C_FLAG_SMBALT:
+        status = i2c->STS1_B.SMBALTFLG;
+        break;
+
+    case I2C_FLAG_TTE:
+        status = i2c->STS1_B.TTEFLG;
+        break;
+
+    case I2C_FLAG_PECE:
+        status = i2c->STS1_B.PECEFLG;
+        break;
+
+    case  I2C_FLAG_OVRUR:
+        status = i2c->STS1_B.OVRURFLG;
+        break;
+
+    case I2C_FLAG_AE:
+        status = i2c->STS1_B.AEFLG;
+        break;
+
+    case I2C_FLAG_AL:
+        status = i2c->STS1_B.ALFLG;
+        break;
+
+    case I2C_FLAG_BERR:
+        status = i2c->STS1_B.BERRFLG;
+        break;
+
+    case I2C_FLAG_TXBE:
+        status = i2c->STS1_B.TXBEFLG;
+        break;
+
+    case I2C_FLAG_RXBNE:
+        status = i2c->STS1_B.RXBNEFLG;
+        break;
+
+    case I2C_FLAG_STOP:
+        status = i2c->STS1_B.STOPFLG;
+        break;
+
+    case I2C_FLAG_ADDR10:
+        status = i2c->STS1_B.ADDR10FLG;
+        break;
+
+    case I2C_FLAG_BTC:
+        status = i2c->STS1_B.BTCFLG;
+        break;
+
+    case I2C_FLAG_ADDR:
+        status = i2c->STS1_B.ADDRFLG;
+        break;
+
+    case I2C_FLAG_START:
+        status = i2c->STS1_B.STARTFLG;
+        break;
+
+    default:
+        break;
+    }
+    return status;
+}
+
+/*!
+ * @brief     Clear the I2C flag
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     flag: specifies the I2C flag
+ *              The parameter can be one of the following values:
+ *              @arg I2C_FLAG_SMBALT:   SMBus Alert flag
+ *              @arg I2C_FLAG_TTE:      Timeout or Tlow error flag
+ *              @arg I2C_FLAG_PECE:     PEC error in reception flag
+ *              @arg I2C_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
+ *              @arg I2C_FLAG_AE:       Acknowledge error flag
+ *              @arg I2C_FLAG_AL:       Arbitration lost flag (Master mode)
+ *              @arg I2C_FLAG_BERR:     Bus error flag
+ *
+ * @retval    None
+ *
+ * @note      1)I2C_FLAG_STOP: Stop detection flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
+ *              followed by a write operation to I2C_CRTL1 register (I2C_Enable()).
+ *            2)I2C_FLAG_ADDR10: 10-bit header sent flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 (I2C_ReadStatusFlag())
+ *              followed by writing the second byte of the address in I2C_DATA register.
+ *            3)I2C_FLAG_BTC: Byte transfer complete flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
+ *              followed by a read/write to I2C_DATA register (I2C_TxData()).
+ *            4)I2C_FLAG_ADDR: Address sent flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
+ *              followed by a read operation to I2C_STS2 register ((void)(i2c->STS2)).
+ *            5)I2C_FLAG_START: Start bit flag is cleared software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
+ *              followed by a write operation to I2C_DATA register (I2C_TxData()).
+ */
+void I2C_ClearStatusFlag(I2C_T *i2c, I2C_FLAG_T flag)
+{
+    switch (flag)
+    {
+    case I2C_FLAG_SMBALT:
+        i2c->STS1_B.SMBALTFLG = BIT_RESET;
+        break;
+
+    case I2C_FLAG_TTE:
+        i2c->STS1_B.TTEFLG = BIT_RESET;
+        break;
+
+    case I2C_FLAG_PECE:
+        i2c->STS1_B.PECEFLG = BIT_RESET;
+        break;
+
+    case  I2C_FLAG_OVRUR:
+        i2c->STS1_B.OVRURFLG = BIT_RESET;
+        break;
+
+    case I2C_FLAG_AE:
+        i2c->STS1_B.AEFLG = BIT_RESET;
+        break;
+
+    case I2C_FLAG_AL:
+        i2c->STS1_B.ALFLG = BIT_RESET;
+        break;
+
+    case I2C_FLAG_BERR:
+        i2c->STS1_B.BERRFLG = BIT_RESET;
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*!
+ * @brief     Check whether the I2C interrupts is set
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     flag: specifies the I2C interrupts
+ *              The parameter can be one of the following values:
+ *              @arg I2C_INT_FLAG_SMBALT:   SMBus Alert flag
+ *              @arg I2C_INT_FLAG_TTE:      Timeout or Tlow error flag
+ *              @arg I2C_INT_FLAG_PECE:     PEC error in reception flag
+ *              @arg I2C_INT_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
+ *              @arg I2C_INT_FLAG_AE:       Acknowledge error flag
+ *              @arg I2C_INT_FLAG_AL:       Arbitration lost flag (Master mode)
+ *              @arg I2C_INT_FLAG_BERR:     Bus error flag
+ *              @arg I2C_INT_FLAG_TXBE:     Transmitter data register empty flag
+ *              @arg I2C_INT_FLAG_RXBNE:    Receiver data register not empty flag
+ *              @arg I2C_INT_FLAG_STOP:     Stop detection flag (Slave mode)
+ *              @arg I2C_INT_FLAG_ADDR10:   10-bit header sent flag (Master mode)
+ *              @arg I2C_INT_FLAG_BTC:      Byte transfer complete flag
+ *              @arg I2C_INT_FLAG_ADDR:     Address sent flag (Master mode)
+ *              @arg I2C_INT_FLAG_START:    Start bit flag (Master mode)
+ *
+ * @retval    Status: flag SET or RESET
+ */
+uint8_t I2C_ReadIntFlag(I2C_T *i2c, I2C_INT_FLAG_T flag)
+{
+    uint32_t enablestatus = 0;
+
+    enablestatus = ((flag & 0x07000000) >> 16) & (i2c->CTRL2);
+    flag &= 0x00FFFFFF;
+    if (((i2c->STS1 & flag) != RESET) && enablestatus)
+    {
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+ * @brief     Clears the I2C interrupt flag bits.
+ *
+ * @param     i2c: I2C selet 1 ,2 or 3
+ *
+ * @param     flag: specifies the I2C flag
+ *              The parameter can be any combination of the following values:
+ *              @arg I2C_INT_FLAG_SMBALT:   SMBus Alert flag
+ *              @arg I2C_INT_FLAG_TTE:      Timeout or Tlow error flag
+ *              @arg I2C_INT_FLAG_PECE:     PEC error in reception flag
+ *              @arg I2C_INT_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
+ *              @arg I2C_INT_FLAG_AE:       Acknowledge error flag
+ *              @arg I2C_INT_FLAG_AL:       Arbitration lost flag (Master mode)
+ *              @arg I2C_INT_FLAG_BERR:     Bus error flag
+ *
+ * @retval    None
+ *
+ * @note      1)I2C_INT_FLAG_STOP: Stop detection flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
+ *              followed by a write operation to I2C_CRTL1 register (I2C_Enable()).
+ *            2)I2C_INT_FLAG_ADDR10: 10-bit header sent flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 (I2C_ReadIntFlag())
+ *              followed by writing the second byte of the address in I2C_DATA register.
+ *            3)I2C_INT_FLAG_BTC: Byte transfer complete flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
+ *              followed by a read/write to I2C_DATA register (I2C_TxData()).
+ *            4)I2C_INT_FLAG_ADDR: Address sent flag is cleared by software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
+ *              followed by a read operation to I2C_STS2 register ((void)(i2c->STS2)).
+ *            5)I2C_INT_FLAG_START: Start bit flag is cleared software sequence:
+ *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
+ *              followed by a write operation to I2C_DATA register (I2C_TxData()).
+ */
+void I2C_ClearIntFlag(I2C_T *i2c, uint32_t flag)
+{
+    i2c->STS1 = (uint16_t)~(flag & 0x00FFFFFF);
+}
+
+/**@} end of group I2C_Functions */
+/**@} end of group I2C_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 150 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_iwdt.c

@@ -0,0 +1,150 @@
+/*!
+ * @file        apm32f4xx_iwdt.c
+ *
+ * @brief       This file provides all the IWDT firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_iwdt.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup IWDT_Driver
+  * @brief IWDT driver modules
+  @{
+*/
+
+/** @defgroup IWDT_Functions
+  @{
+*/
+
+/*!
+ * @brief     Enable IWDT
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void IWDT_Enable(void)
+{
+    IWDT->KEY = IWDT_KEYWORD_ENABLE;
+}
+
+/*!
+ * @brief     Reload the IWDT counter with value
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void IWDT_Refresh(void)
+{
+    IWDT->KEY = IWDT_KEYWORD_RELOAD;
+}
+
+/*!
+ * @brief     Set IWDT count reload values
+ *
+ * @param     reload: IWDT count reload values
+ *
+ * @retval    None
+ */
+void IWDT_ConfigReload(uint16_t reload)
+{
+    IWDT->CNTRLD = reload;
+}
+
+/*!
+ * @brief     Enable the IWDT write access
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void IWDT_EnableWriteAccess(void)
+{
+    IWDT->KEY_B.KEY = IWDT_WRITEACCESS_ENABLE;
+}
+
+/*!
+ * @brief     Disable the IWDT write access
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void IWDT_DisableWriteAccess(void)
+{
+    IWDT->KEY_B.KEY = IWDT_WRITEACCESS_DISABLE;
+}
+
+/*!
+ * @brief     Set IWDT frequency divider values
+ *
+ * @param     div: IWDT frequency divider values
+ *                 This parameter can be one of the following values:
+ *                    @arg IWDT_DIVIDER_4  : prescaler divider equal to 4
+ *                    @arg IWDT_DIVIDER_8  : prescaler divider equal to 8
+ *                    @arg IWDT_DIVIDER_16 : prescaler divider equal to 16
+ *                    @arg IWDT_DIVIDER_32 : prescaler divider equal to 32
+ *                    @arg IWDT_DIVIDER_64 : prescaler divider equal to 64
+ *                    @arg IWDT_DIVIDER_128: prescaler divider equal to 128
+ *                    @arg IWDT_DIVIDER_256: prescaler divider equal to 256
+ *
+ * @retval    None
+ */
+void IWDT_ConfigDivider(uint8_t div)
+{
+    IWDT->PSC = div;
+}
+
+/*!
+ * @brief     Read the specified IWDT flag
+ *
+ * @param     flag: specifies the flag to read
+ *                  This parameter can be one of the following values:
+ *                  @arg IWDT_FLAG_PSCU : Watchdog Prescaler Factor Update flag
+ *                  @arg IWDT_FLAG_CNTU : Watchdog Counter Reload Value Update flag
+ *
+ * @retval    status of IWDT_FLAG (SET or RESET)
+ *
+ * @note
+ */
+uint8_t IWDT_ReadStatusFlag(uint16_t flag)
+{
+    uint8_t bitStatus = RESET;
+
+    if ((IWDT->STS & flag) != (uint32_t)RESET)
+    {
+        bitStatus = SET;
+    }
+    else
+    {
+        bitStatus = RESET;
+    }
+    return bitStatus;
+}
+
+/**@} end of group IWDT_Functions */
+/**@} end of group IWDT_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 225 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_misc.c

@@ -0,0 +1,225 @@
+/*!
+ * @file        apm32f4xx_misc.c
+ *
+ * @brief       This file provides all the miscellaneous firmware functions.
+ *              Include NVIC,SystemTick and Power management.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_misc.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup MISC_Driver
+  * @brief MISC driver modules
+  @{
+*/
+
+/** @defgroup MISC_Functions
+  @{
+*/
+
+/** @defgroup MISC_Macros Macros
+  @{
+*/
+
+#define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)
+
+/**@} end of group MISC_Macros*/
+
+
+/** @addtogroup MISC_Functions
+  @{
+*/
+
+/*!
+ * @brief     Configures the priority grouping: pre-emption priority and subpriority.
+ *
+ * @param     priorityGroup : specifies the priority grouping bits length.
+ *                            This parameter can be one of the following values:
+ *                            @arg NVIC_PRIORITY_GROUP_0 : 0 bits for pre-emption priority,4 bits for subpriority
+ *                            @arg NVIC_PRIORITY_GROUP_1 : 1 bits for pre-emption priority,3 bits for subpriority
+ *                            @arg NVIC_PRIORITY_GROUP_2 : 2 bits for pre-emption priority,2 bits for subpriority
+ *                            @arg NVIC_PRIORITY_GROUP_3 : 3 bits for pre-emption priority,1 bits for subpriority
+ *                            @arg NVIC_PRIORITY_GROUP_4 : 4 bits for pre-emption priority,0 bits for subpriority
+ *
+ * @retval    None
+ */
+void NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_T priorityGroup)
+{
+    SCB->AIRCR = AIRCR_VECTKEY_MASK | priorityGroup;
+}
+
+/*!
+ * @brief     Enable NVIC request
+ *
+ * @param     irq: the NVIC interrupt request, detailed in IRQn_Type
+ *            For the complete APM32 Devices IRQ Channels list,please refer to apm32f4xx.h file
+ *
+ * @param     preemptionPriority: the pre-emption priority needed to set
+ *
+ * @param     subPriority: the subpriority needed to set
+ *
+ * @retval    None
+ */
+void NVIC_EnableIRQRequest(IRQn_Type irq, uint8_t preemptionPriority, uint8_t subPriority)
+{
+    uint32_t tempPriority, tempPrePri, tempSubPri;
+    uint32_t priorityGrp;
+
+    /** Get priority group */
+    priorityGrp = (SCB->AIRCR) & (uint32_t)0x700U;
+
+    /** get pre-emption priority and subpriority */
+    switch (priorityGrp)
+    {
+    case NVIC_PRIORITY_GROUP_0:
+        tempPrePri = 0;
+        tempSubPri = 4;
+        break;
+
+    case NVIC_PRIORITY_GROUP_1:
+        tempPrePri = 1;
+        tempSubPri = 3;
+        break;
+
+    case NVIC_PRIORITY_GROUP_2:
+        tempPrePri = 2;
+        tempSubPri = 2;
+        break;
+
+    case NVIC_PRIORITY_GROUP_3:
+        tempPrePri = 3;
+        tempSubPri = 1;
+        break;
+
+    case NVIC_PRIORITY_GROUP_4:
+        tempPrePri = 4;
+        tempSubPri = 0;
+        break;
+
+    default:
+        NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_0);
+        tempPrePri = 0;
+        tempSubPri = 4;
+        break;
+    }
+
+    tempPrePri = 4 - tempPrePri;
+    tempSubPri = 4 - tempSubPri;
+    tempPriority = preemptionPriority << tempPrePri;
+    tempPriority |= subPriority & (0x0f >> tempSubPri);
+    tempPriority <<= 4;
+    NVIC->IP[irq] = (uint8_t)tempPriority;
+
+    /** enable the selected IRQ */
+    NVIC->ISER[irq >> 0x05U] = (uint32_t)0x01U << (irq & (uint8_t)0x1FU);
+}
+
+/*!
+ * @brief     Disable NVIC request
+ *
+ * @param     irq: the NVIC interrupt request, detailed in IRQn_Type
+ *
+ * @retval    None
+ */
+void NVIC_DisableIRQRequest(IRQn_Type irq)
+{
+    /** disable the selected IRQ.*/
+    NVIC->ICER[irq >> 0x05U] = (uint32_t)0x01U << (irq & (uint8_t)0x1FU);
+}
+
+/*!
+ * @brief     Configs the vector table location and Offset.
+ *
+ * @param     vectTab: specifies if the vector table is in RAM or FLASH memory
+ *                     This parameter can be one of the following values:
+ *                     @arg NVIC_VECT_TAB_RAM   : NVIC vector table base address launch from RAM
+ *                     @arg NVIC_VECT_TAB_FLASH : NVIC vector table base address launch from flash
+ *
+ * @param     Offset   Vector Table base offset field. This value must be a multiple of 0x200
+ *
+ * @retval    None
+ */
+void NVIC_ConfigVectorTable(NVIC_VECT_TAB_T vectTab, uint32_t offset)
+{
+    SCB->VTOR = vectTab | (offset & (uint32_t)0x1FFFFF80);
+}
+
+/*!
+ * @brief     set the state of the low power mode
+ *
+ * @param     lowPowerMode: the low power mode state
+ *                          This parameter can be one of the following values:
+ *                          @arg NVIC_LOWPOWER_SEVONPEND    : Wake up according to pending request
+ *                          @arg NVIC_LOWPOWER_SLEEPDEEP    : Enable sleep deep
+ *                          @arg NVIC_LOWPOWER_SLEEPONEXIT  : Sleep after exit ISR
+ *
+ * @retval    None
+ */
+void NVIC_SetSystemLowPower(NVIC_LOWPOWER_T lowPowerMode)
+{
+    SCB->SCR |= lowPowerMode;
+}
+
+/*!
+ * @brief     reset the state of the low power mode
+ *
+ * @param     lowPowerMode: the low power mode state
+ *                          This parameter can be one of the following values:
+ *                          @arg NVIC_LOWPOWER_SEVONPEND    : Wake up according to pending request
+ *                          @arg NVIC_LOWPOWER_SLEEPDEEP    : Enable sleep deep
+ *                          @arg NVIC_LOWPOWER_SLEEPONEXIT  : Sleep after exit ISR
+ *
+ * @retval    None
+ */
+void NVIC_ResetystemLowPower(NVIC_LOWPOWER_T lowPowerMode)
+{
+    SCB->SCR &= (uint32_t)(~(uint32_t)lowPowerMode);
+}
+
+/*!
+ * @brief     Configures the SysTick clock source
+ *
+ * @param     clkSource: specifies the SysTick clock source
+ *                       This parameter can be one of the following values:
+ *                       @arg SYSTICK_CLK_SOURCE_HCLK_DIV8  : AHB clock divided by 8 selected as SysTick clock source.
+ *                       @arg SYSTICK_CLK_SOURCE_HCLK       : AHB clock selected as SysTick clock source.
+ *
+ * @retval    None
+ */
+void SysTick_ConfigCLKSource(SYSTICK_CLK_SOURCE_T clkSource)
+{
+    if (clkSource == SYSTICK_CLK_SOURCE_HCLK)
+    {
+        SysTick->CTRL |= (uint32_t)BIT2;
+    }
+    else
+    {
+        SysTick->CTRL &= (uint32_t)(~BIT2);
+    }
+}
+
+/**@} end of group MISC_Functions */
+/**@} end of group MISC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 339 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_pmu.c

@@ -0,0 +1,339 @@
+/*!
+ * @file        apm32f4xx_pmu.c
+ *
+ * @brief       This file provides all the PMU firmware functions.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_pmu.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup PMU_Driver
+  * @brief PMU driver modules
+  @{
+*/
+
+/** @defgroup PMU_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset the PMU peripheral register.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_Reset(void)
+{
+    RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_PMU);
+    RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_PMU);
+}
+
+/*!
+ * @brief     Enables access to the RTC and backup registers.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_EnableBackupAccess(void)
+{
+    PMU->CTRL_B.BPWEN = ENABLE;
+}
+
+/*!
+ * @brief     Disables access to the RTC and backup registers.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_DisableBackupAccess(void)
+{
+    PMU->CTRL_B.BPWEN = DISABLE;
+}
+
+/*!
+ * @brief     Enables the Power Voltage Detector(PVD).
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_EnablePVD(void)
+{
+    PMU->CTRL_B.PVDEN = ENABLE;
+}
+
+/*!
+ * @brief     Disables the Power Voltage Detector(PVD).
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_DisablePVD(void)
+{
+    PMU->CTRL_B.PVDEN = DISABLE;
+}
+
+/*!
+ * @brief    Configures the voltage threshold detected by the Power Voltage Detector(PVD).
+ *
+ * @param    level: specifies the PVD detection level
+ *           This parameter can be one of the following values:
+ *              @arg PMU_PVD_LEVEL_2V0 : Config PVD detection level to 2.0V
+ *              @arg PMU_PVD_LEVEL_2V1 : Config PVD detection level to 2.1V
+ *              @arg PMU_PVD_LEVEL_2V3 : Config PVD detection level to 2.3V
+ *              @arg PMU_PVD_LEVEL_2V5 : Config PVD detection level to 2.5V
+ *              @arg PMU_PVD_LEVEL_2V6 : Config PVD detection level to 2.6V
+ *              @arg PMU_PVD_LEVEL_2V7 : Config PVD detection level to 2.7V
+ *              @arg PMU_PVD_LEVEL_2V8 : Config PVD detection level to 2.8V
+ *              @arg PMU_PVD_LEVEL_2V9 : Config PVD detection level to 2.9V
+ *
+ * @retval   None
+ */
+void PMU_ConfigPVDLevel(PMU_PVD_LEVEL_T level)
+{
+    PMU->CTRL_B.PLSEL = 0;
+    PMU->CTRL_B.PLSEL = level;
+}
+
+/*!
+ * @brief     Enables the WakeUp Pin functionality.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_EnableWakeUpPin(void)
+{
+    PMU->CSTS_B.WKUPCFG = ENABLE;
+}
+
+/*!
+ * @brief     Diaables the WakeUp Pin functionality.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_DisableWakeUpPin(void)
+{
+    PMU->CSTS_B.WKUPCFG = DISABLE;
+}
+
+/*!
+ * @brief     Enables the Backup Regulator.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_EnableBackupRegulator(void)
+{
+    PMU->CSTS_B.BKPREN = ENABLE;
+}
+
+/*!
+ * @brief     Diaables the Backup Regulator.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_DisableBackupRegulator(void)
+{
+    PMU->CSTS_B.BKPREN = DISABLE;
+}
+
+/*!
+ * @brief     Configures the main internal regulator output voltage.
+ *
+ * @param     scale: This parameter can be one of the following values:
+ *               @arg PMU_REGULATOR_VOLTAGE_SCALE1 : Select regulator voltage scale 1
+ *               @arg PMU_REGULATOR_VOLTAGE_SCALE2 : Select regulator voltage scale 2
+ *
+ * @retval    None
+ */
+void PMU_ConfigMainRegulatorMode(PMU_REGULATOR_VOLTAGE_SCALE_T scale)
+{
+    PMU->CTRL_B.VOSSEL = 0;
+    PMU->CTRL_B.VOSSEL = scale;
+}
+
+/*!
+ * @brief     Enables the Flash Power Down in STOP mode.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_EnableFlashPowerDown(void)
+{
+    PMU->CTRL_B.FPDSM = ENABLE ;
+}
+
+/*!
+ * @brief     Diaables the Flash Power Down in STOP mode.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_DisableFlashPowerDown(void)
+{
+    PMU->CTRL_B.FPDSM = DISABLE ;
+}
+
+/*!
+ * @brief     Enters STOP mode.
+ *
+ * @param     regulator: specifies the regulator state in STOP mode.
+ *            This parameter can be one of the following values:
+ *              @arg PMU_REGULATOR_ON        : STOP mode with regulator ON
+ *              @arg PMU_REGULATOR_LOWPOWER  : STOP mode with regulator in low power mode
+ *
+ * @param     entry: specifies if STOP mode in entered with WFI or WFE instruction.
+ *            This parameter can be one of the following values:
+ *              @arg PMU_STOP_ENTRY_WFI: Enter STOP mode with WFI instruction
+ *              @arg PMU_STOP_ENTRY_WFE: Enter STOP mode with WFE instruction
+ *
+ * @retval    None
+ */
+void PMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOP_ENTRY_T entry)
+{
+    /* Clear PDDSCFG and LPDSCFG bits */
+    PMU->CTRL_B.PDDSCFG = 0x00;
+    PMU->CTRL_B.LPDSCFG = 0x00;
+    /* Set LPDSCFG bit according to regulator value */
+    PMU->CTRL_B.LPDSCFG = regulator;
+    /* Set Cortex System Control Register */
+    SCB->SCR |= (uint32_t)0x04;
+    /* Select STOP mode entry*/
+    if (entry == PMU_STOP_ENTRY_WFI)
+    {
+        /* Request Wait For Interrupt */
+        __WFI();
+    }
+    else
+    {
+        /* Request Wait For Event */
+        __WFE();
+    }
+
+    /* Reset SLEEPDEEP bit of Cortex System Control Register */
+    SCB->SCR &= (uint32_t)~((uint32_t)0x04);
+}
+
+/*!
+ * @brief     Enters STANDBY mode.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void PMU_EnterSTANDBYMode(void)
+{
+    /* Select STANDBY mode */
+    PMU->CTRL_B.PDDSCFG = BIT_SET;
+    /* Set SLEEPDEEP bit of Cortex System Control Register */
+    SCB->SCR |= (uint32_t)0x04;
+#if defined ( __CC_ARM   )
+    __force_stores();
+#endif
+    /* Request Wait For Interrupt */
+    __WFI();
+
+}
+
+/*!
+ * @brief     Read the specified PMU flag is set or not.
+ *
+ * @param     flag: Reads the status of specifies the flag.
+ *                  This parameter can be one of the following values:
+ *                    @arg PMU_FLAG_WUE : Wake Up flag.
+ *                    @arg PMU_FLAG_SB  : StandBy flag.
+ *                    @arg PMU_FLAG_PVDO: PVD Output.
+ *                    @arg PMU_FLAG_BKPR: Backup regulator ready flag.
+ *                    @arg PMU_FLAG_VOSR: This flag indicates that the Regulator voltage
+ *                         scaling output selection is ready.
+ *
+ * @retval    The new state of PMU_FLAG (SET or RESET).
+ */
+uint8_t PMU_ReadStatusFlag(PMU_FLAG_T flag)
+{
+    uint8_t BitStatus = BIT_RESET;
+
+    if (flag == PMU_FLAG_WUE)
+    {
+        BitStatus = PMU->CSTS_B.WUEFLG;
+    }
+    else if (flag == PMU_FLAG_SB)
+    {
+        BitStatus = PMU->CSTS_B.SBFLG;
+    }
+    else if (flag == PMU_FLAG_PVDO)
+    {
+        BitStatus = PMU->CSTS_B.PVDOFLG;
+    }
+    else if (flag == PMU_FLAG_BKPR)
+    {
+        BitStatus = PMU->CSTS_B.BKPRFLG;
+    }
+    else if (flag == PMU_FLAG_VOSR)
+    {
+        BitStatus = PMU->CSTS_B.VOSRFLG;
+    }
+
+    return BitStatus;
+}
+
+/*!
+ * @brief     Clears the PMU's pending flags.
+ *
+ * @param     flag: specifies the flag to clear.
+ *            This parameter can be one of the following values:
+ *              @arg PMU_FLAG_WUE : Wake Up flag.
+ *              @arg PMU_FLAG_SB  : StandBy flag.
+ *
+ * @retval    None
+ */
+void PMU_ClearStatusFlag(PMU_FLAG_T flag)
+{
+    if (flag == PMU_FLAG_WUE)
+    {
+        PMU->CTRL_B.WUFLGCLR = BIT_SET;
+    }
+    else if (flag == PMU_FLAG_SB)
+    {
+        PMU->CTRL_B.SBFLGCLR = BIT_SET;
+    }
+}
+
+/**@} end of group PMU_Functions */
+/**@} end of group PMU_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 1574 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rcm.c

@@ -0,0 +1,1574 @@
+/*!
+ * @file        apm32f4xx_rcm.c
+ *
+ * @brief       This file provides all the RCM firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup RCM_Driver
+  * @brief RCM driver modules
+  @{
+*/
+
+/** @defgroup RCM_Functions
+  @{
+*/
+
+/*!
+ * @brief     Resets the clock configuration to the default state
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_Reset(void)
+{
+    /* Open HSI clock */
+    RCM->CTRL_B.HSIEN = BIT_SET;
+    /* Clear CFG register */
+    RCM->CFG = (uint32_t)0x00000000;
+    /* Reset HSEON, CSSON, PLLON, PLLI2S bits */
+    RCM->CTRL &= (uint32_t)0xEAF6FFFF;
+
+    /* Reset PLL1CFG register */
+    RCM->PLL1CFG = 0x24003010;
+    /* Reset PLL2CFG register */
+    RCM->PLL2CFG = 0x20003000;
+
+    /* Reset HSEBCFG bit */
+    RCM->CTRL_B.HSEBCFG = BIT_RESET;
+
+    /* Disable all interrupts and clear pending bits */
+    RCM->INT = 0x00000000;
+}
+
+/*!
+ * @brief     Configs the HSE oscillator
+ *
+ * @param     state: state of the HSE
+ *                   This parameter can be one of the following values:
+ *                   @arg RCM_HSE_CLOSE  : Turn off the HSE oscillator
+ *                   @arg RCM_HSE_OPEN   : Turn on the HSE oscillator
+ *                   @arg RCM_HSE_BYPASS : HSE oscillator bypassed with external clock
+ *
+ * @retval    None
+ *
+ * @note      When HSE is not used directly or through the PLL as system clock, it can be stopped.
+ */
+void RCM_ConfigHSE(RCM_HSE_T state)
+{
+    /* Reset HSEEN bit */
+    RCM->CTRL_B.HSEEN = BIT_RESET;
+
+    /* Reset HSEBCFG bit */
+    RCM->CTRL_B.HSEBCFG = BIT_RESET;
+
+    if (state == RCM_HSE_OPEN)
+    {
+        RCM->CTRL_B.HSEEN = BIT_SET;
+    }
+    else if (state == RCM_HSE_BYPASS)
+    {
+        RCM->CTRL_B.HSEBCFG = BIT_SET;
+        RCM->CTRL_B.HSEEN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Waits for HSE to be ready
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS: HSE oscillator is ready
+ *            ERROR  : HSE oscillator is not ready
+ */
+
+uint8_t RCM_WaitHSEReady(void)
+{
+    __IO uint32_t cnt;
+
+    for (cnt = 0; cnt < HSE_STARTUP_TIMEOUT; cnt++)
+    {
+        if (RCM->CTRL_B.HSERDYFLG == BIT_SET)
+        {
+            return SUCCESS;
+        }
+    }
+
+    return ERROR;
+}
+
+/*!
+ * @brief     Config HSI trimming value
+ *
+ * @param     HSITrim: HSI trimming value
+ *                     This parameter must be a number between 0 and 0x1F.
+ *
+ * @retval    None
+ */
+void RCM_ConfigHSITrim(uint8_t HSITrim)
+{
+    RCM->CTRL_B.HSITRIM = HSITrim;
+}
+
+/*!
+ * @brief     Enable the HSI
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_EnableHSI(void)
+{
+    RCM->CTRL_B.HSIEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the HSI
+ *
+ * @param     None
+ *
+ * @retval    None
+ *
+ * @note      When HSI is not used directly or through the PLL as system clock, it can be stopped.
+ */
+
+void RCM_DisableHSI(void)
+{
+    RCM->CTRL_B.HSIEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the External Low Speed oscillator (LSE)
+ *
+ * @param     state : Specifies the new state of the LSE
+ *                    This parameter can be one of the following values:
+ *                    @arg RCM_LSE_CLOSE  : Close the LSE
+ *                    @arg RCM_LSE_OPEN   : Open the LSE
+ *                    @arg RCM_LSE_BYPASS : LSE bypass
+ *
+ * @retval    None
+ */
+void RCM_ConfigLSE(RCM_LSE_T state)
+{
+    RCM->BDCTRL_B.LSEEN = BIT_RESET;
+    RCM->BDCTRL_B.LSEBCFG = BIT_RESET;
+
+    if (state == RCM_LSE_OPEN)
+    {
+        RCM->BDCTRL_B.LSEEN = BIT_SET;
+    }
+    else if (state == RCM_LSE_BYPASS)
+    {
+        RCM->BDCTRL_B.LSEBCFG = BIT_SET;
+        RCM->BDCTRL_B.LSEEN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Enables the Internal Low Speed oscillator (LSI)
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_EnableLSI(void)
+{
+    RCM->CSTS_B.LSIEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the Internal Low Speed oscillator (LSI)
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_DisableLSI(void)
+{
+    RCM->CSTS_B.LSIEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the main PLL clock source, multiplication and division factors
+ *
+ * @param     pllSelect: PLL entry clock source select
+ *                       This parameter can be one of the following values:
+ *                       @arg RCM_PLLSEL_HSI: HSI oscillator clock selected as PLL clock entry
+ *                       @arg RCM_PLLSEL_HSE: HSE oscillator clock selected as PLL clock entry
+ *
+ * @param     inputDiv: specifies the Division factor for PLL VCO input clock
+ *                      This parameter must be a number between 0 and 63
+ *
+ * @param     vcoMul: specifies the Multiplication factor for PLL VCO output clock
+ *                    This parameter must be a number between 50 and 432
+ *
+ * @param     sysDiv: specifies the Division factor for main system clock (SYSCLK)
+ *                    This parameter can be one of the following values:
+ *                    @arg RCM_PLL_SYS_DIV_2 : system clock Division factor is 2
+ *                    @arg RCM_PLL_SYS_DIV_4 : system clock Division factor is 4
+ *                    @arg RCM_PLL_SYS_DIV_6 : system clock Division factor is 6
+ *                    @arg RCM_PLL_SYS_DIV_8 : system clock Division factor is 8
+ *
+ * @param     appDiv: specifies the Division factor for OTG FS, SDIO and RNG clocks
+ *                    This parameter must be a number between 4 and 15
+ *
+ * @retval    None
+ */
+void RCM_ConfigPLL1(uint32_t pllSelect, uint32_t inputDiv, uint32_t vcoMul,
+                    RCM_PLL_SYS_DIV_T sysDiv, uint32_t appDiv)
+{
+    RCM->PLL1CFG_B.PLL1CLKS = pllSelect;
+    RCM->PLL1CFG_B.PLLB = inputDiv;
+    RCM->PLL1CFG_B.PLL1A = vcoMul;
+    RCM->PLL1CFG_B.PLL1C = sysDiv;
+    RCM->PLL1CFG_B.PLLD = appDiv;
+}
+
+/*!
+ * @brief      Enables the PLL1
+ *
+ * @param      None
+ *
+ * @retval     None
+ */
+void RCM_EnablePLL1(void)
+{
+    RCM->CTRL_B.PLL1EN = BIT_SET;
+}
+
+/*!
+ * @brief      Disable the PLL
+ *
+ * @param      None
+ *
+ * @retval     None
+ *
+ * @note       When PLL1 is not used as system clock, it can be stopped.
+ */
+void RCM_DisablePLL1(void)
+{
+    RCM->CTRL_B.PLL1EN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the RCM_PLL2CFG register
+ *
+ * @param     i2sVcoMul: specifies the multiplication factor for PLLI2S VCO output clock
+ *                       This parameter must be a number between 50 and 432
+ *
+ * @param     i2sDiv: specifies the division factor for I2S clock
+ *                    This parameter must be a number between 2 and 7
+ *
+ * @retval    None
+ */
+void RCM_ConfigPLL2(uint32_t i2sVcoMul, uint32_t i2sDiv)
+{
+    RCM->PLL2CFG_B.PLL2A = i2sVcoMul;
+    RCM->PLL2CFG_B.PLL2C = i2sDiv;
+}
+
+/*!
+ * @brief      Enables the PLL2
+ *
+ * @param      None
+ *
+ * @retval     None
+ */
+void RCM_EnablePLL2(void)
+{
+    RCM->CTRL_B.PLL2EN = BIT_SET;
+}
+
+/*!
+ * @brief      Disable the PLL2
+ *
+ * @param      None
+ *
+ * @retval     None
+ */
+void RCM_DisablePLL2(void)
+{
+    RCM->CTRL_B.PLL2EN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enable the Clock Security System
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_EnableCSS(void)
+{
+    RCM->CTRL_B.CSSEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the Clock Security System
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_DisableCSS(void)
+{
+    RCM->CTRL_B.CSSEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Selects the clock source to output on MCO1 pin
+ *
+ * @param     mco1Div: specifies the clock source to output
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_MCO1_SEL_HSICLK : HSI clock selected as MCO1 source
+ *                     @arg RCM_MCO1_SEL_LSECLK : LSE clock selected as MCO1 source
+ *                     @arg RCM_MCO1_SEL_HSECLK : HSE clock selected as MCO1 source
+ *                     @arg RCM_MCO1_SEL_PLLCLK : main PLL clock selected as MCO1 source
+ *
+ * @param     mco1Div: specifies the MCO1 prescaler
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_MCO1_DIV_1 : no division applied to MCO1 clock
+ *                     @arg RCM_MCO1_DIV_2 : division by 2 applied to MCO1 clock
+ *                     @arg RCM_MCO1_DIV_3 : division by 3 applied to MCO1 clock
+ *                     @arg RCM_MCO1_DIV_4 : division by 4 applied to MCO1 clock
+ *                     @arg RCM_MCO1_DIV_5 : division by 5 applied to MCO1 clock
+ *
+ * @retval    None
+ */
+void RCM_ConfigMCO1(RCM_MCO1_SEL_T mco1Select, RCM_MCO1_DIV_T mco1Div)
+{
+    RCM->CFG_B.MCO1SEL = mco1Select;
+    RCM->CFG_B.MCO1PRE = mco1Div;
+}
+
+/*!
+ * @brief     Selects the clock source to output on MCO2 pin
+ *
+ * @param     mco2Select: specifies the clock source to output
+ *                        This parameter can be one of the following values:
+ *                        @arg RCM_MCO2_SEL_SYSCLK  : SYS clock selected as MCO2 source
+ *                        @arg RCM_MCO2_SEL_PLL2CLK : PLL2 clock selected as MCO2 source
+ *                        @arg RCM_MCO2_SEL_HSECLK  : HSE clock selected as MCO2 source
+ *                        @arg RCM_MCO2_SEL_PLLCLK  : PLL clock selected as MCO2 source
+ *
+ * @param     mco2Div: specifies the MCO2 prescaler
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_MCO2_DIV_1 : no division applied to MCO2 clock
+ *                     @arg RCM_MCO2_DIV_2 : division by 2 applied to MCO2 clock
+ *                     @arg RCM_MCO2_DIV_3 : division by 3 applied to MCO2 clock
+ *                     @arg RCM_MCO2_DIV_4 : division by 4 applied to MCO2 clock
+ *                     @arg RCM_MCO2_DIV_5 : division by 5 applied to MCO2 clock
+ *
+ * @retval    None
+ */
+void RCM_ConfigMCO2(RCM_MCO2_SEL_T mco2Select, RCM_MCO2_DIV_T mco2Div)
+{
+    RCM->CFG_B.MCO2SEL = mco2Select;
+    RCM->CFG_B.MCO2PRE = mco2Div;
+}
+
+/*!
+ * @brief    Configures the system clock source
+ *
+ * @param    sysClkSelect: specifies the clock source used as system clock
+ *                         This parameter can be one of the following values:
+ *                         @arg RCM_SYSCLK_SEL_HSI : HSI is selected as system clock source
+ *                         @arg RCM_SYSCLK_SEL_HSE : HSE is selected as system clock source
+ *                         @arg RCM_SYSCLK_SEL_PLL : PLL is selected as system clock source
+ *
+ * @retva    None
+ */
+void RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)
+{
+    RCM->CFG_B.SCLKSEL = sysClkSelect;
+}
+
+/*!
+ * @brief     Returns the clock source which is used as system clock
+ *
+ * @param     None
+ *
+ * @retval    The clock source used as system clock
+ */
+RCM_SYSCLK_SEL_T RCM_ReadSYSCLKSource(void)
+{
+    return (RCM_SYSCLK_SEL_T)RCM->CFG_B.SCLKSWSTS;
+}
+
+/*!
+ * @brief     Configs the AHB clock prescaler.
+ *
+ * @param     AHBDiv : Specifies the AHB clock prescaler from the system clock.
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_AHB_DIV_1   : HCLK = SYSCLK
+ *                     @arg RCM_AHB_DIV_2   : HCLK = SYSCLK / 2
+ *                     @arg RCM_AHB_DIV_4   : HCLK = SYSCLK / 4
+ *                     @arg RCM_AHB_DIV_8   : HCLK = SYSCLK / 8
+ *                     @arg RCM_AHB_DIV_16  : HCLK = SYSCLK / 16
+ *                     @arg RCM_AHB_DIV_64  : HCLK = SYSCLK / 64
+ *                     @arg RCM_AHB_DIV_128 : HCLK = SYSCLK / 128
+ *                     @arg RCM_AHB_DIV_256 : HCLK = SYSCLK / 256
+ *                     @arg RCM_AHB_DIV_512 : HCLK = SYSCLK / 512
+ *
+ * @retval    None
+ */
+void RCM_ConfigAHB(RCM_AHB_DIV_T AHBDiv)
+{
+    RCM->CFG_B.AHBPSC = AHBDiv;
+}
+
+/*!
+ * @brief     Configs the APB1 clock prescaler.
+ *
+ * @param     APB1Div: Specifies the APB1 clock prescaler from the AHB clock.
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_APB_DIV_1  : PCLK1 = HCLK
+ *                     @arg RCM_APB_DIV_2  : PCLK1 = HCLK / 2
+ *                     @arg RCM_APB_DIV_4  : PCLK1 = HCLK / 4
+ *                     @arg RCM_APB_DIV_8  : PCLK1 = HCLK / 8
+ *                     @arg RCM_APB_DIV_16 : PCLK1 = HCLK / 16
+ *
+ * @retval    None
+ */
+void RCM_ConfigAPB1(RCM_APB_DIV_T APB1Div)
+{
+    RCM->CFG_B.APB1PSC = APB1Div;
+}
+
+/*!
+ * @brief     Configs the APB2 clock prescaler
+ *
+ * @param     APB2Div: Specifies the APB2 clock prescaler from the AHB clock.
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_APB_DIV_1  : PCLK2 = HCLK
+ *                     @arg RCM_APB_DIV_2  : PCLK2 = HCLK / 2
+ *                     @arg RCM_APB_DIV_4  : PCLK2 = HCLK / 4
+ *                     @arg RCM_APB_DIV_8  : PCLK2 = HCLK / 8
+ *                     @arg RCM_APB_DIV_16 : PCLK2 = HCLK / 16
+ *
+ * @retval    None
+ */
+void RCM_ConfigAPB2(RCM_APB_DIV_T APB2Div)
+{
+    RCM->CFG_B.APB2PSC = APB2Div;
+}
+
+/*!
+ * @brief     Configs the SDRAM clock prescaler
+ *
+ * @param     SDRAMDiv: Specifies the SDRAM clock prescaler from the DMC clock.
+ *                     This parameter can be one of the following values:
+ *                     @arg RCM_SDRAM_DIV_1 : SDRAM clock = DMC clock
+ *                     @arg RCM_SDRAM_DIV_2 : SDRAM clock = DMC clock / 2
+ *                     @arg RCM_SDRAM_DIV_4 : SDRAM clock = DMC clock / 4
+ *
+ * @retval    None
+ */
+void RCM_ConfigSDRAM(RCM_SDRAM_DIV_T SDRAMDiv)
+{
+    RCM->CFG_B.SDRAMPSC = SDRAMDiv;
+}
+
+/*!
+ * @brief     Reads the frequency of SYSCLK
+ *
+ * @param     None
+ *
+ * @retval    Return the frequency of SYSCLK
+ */
+uint32_t RCM_ReadSYSCLKFreq(void)
+{
+    uint32_t sysClock, pllMull, pllSource, pllvco;
+
+    /* get sys clock */
+    sysClock = RCM->CFG_B.SCLKSWSTS;
+
+    switch (sysClock)
+    {
+    /* sys clock is HSI */
+    case RCM_SYSCLK_SEL_HSI:
+        sysClock = HSI_VALUE;
+        break;
+
+    /* sys clock is HSE */
+    case RCM_SYSCLK_SEL_HSE:
+        sysClock = HSE_VALUE;
+        break;
+
+    /* sys clock is PLL */
+    case RCM_SYSCLK_SEL_PLL:
+        pllMull = RCM->PLL1CFG_B.PLLB;
+        pllSource = RCM->PLL1CFG_B.PLL1CLKS;
+
+        /* PLL entry clock source is HSE */
+        if (pllSource == BIT_SET)
+        {
+            /* HSE used as PLL clock source */
+            pllvco = (HSE_VALUE / pllMull) * (RCM->PLL1CFG_B.PLL1A);
+        }
+        else
+        {
+            /* HSI used as PLL clock source */
+            pllvco = (HSI_VALUE / pllMull) * (RCM->PLL1CFG_B.PLL1A);
+        }
+
+        sysClock = pllvco / ((RCM->PLL1CFG_B.PLL1C + 1) * 2);
+        break;
+
+    default:
+        sysClock  = HSI_VALUE;
+        break;
+    }
+
+    return sysClock;
+}
+
+/*!
+ * @brief     Reads the frequency of HCLK(AHB)
+ *
+ * @param     None
+ *
+ * @retval    Return the frequency of HCLK
+ */
+uint32_t RCM_ReadHCLKFreq(void)
+{
+    uint32_t divider;
+    uint32_t sysClk, hclk;
+    uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+    sysClk = RCM_ReadSYSCLKFreq();
+    divider = AHBPrescTable[RCM->CFG_B.AHBPSC];
+    hclk = sysClk >> divider;
+
+    return hclk;
+}
+
+/*!
+ * @brief     Reads the frequency of PCLK1 And PCLK2
+ *
+ * @param     PCLK1 : Return the frequency of PCLK1
+ *
+ * @param     PCLK1 : Return the frequency of PCLK2
+ *
+ * @retval    None
+ */
+void RCM_ReadPCLKFreq(uint32_t *PCLK1, uint32_t *PCLK2)
+{
+    uint32_t hclk, divider;
+    uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+    hclk = RCM_ReadHCLKFreq();
+
+    if (PCLK1)
+    {
+        divider = APBPrescTable[RCM->CFG_B.APB1PSC];
+        *PCLK1 = hclk >> divider;
+    }
+
+    if (PCLK2)
+    {
+        divider = APBPrescTable[RCM->CFG_B.APB2PSC];
+        *PCLK2 = hclk >> divider;
+    }
+}
+
+/*!
+ * @brief     Configures the RTC clock source
+ *
+ * @param     rtcClkSelect : specifies the RTC clock source.
+ *                           This parameter can be one of the following values:
+ *                           @arg RCM_RTCCLK_LSE        : RTCCLK = LSE clock
+ *                           @arg RCM_RTCCLK_LSI        : RTCCLK = LSI clock
+ *                           @arg RCM_RTCCLK_HSE_DIVX   : X:[2:31]
+ *
+ * @retval    None
+ */
+void RCM_ConfigRTCCLK(RCM_RTCCLK_T rtcClkSelect)
+{
+    if (rtcClkSelect <= 1)
+    {
+        RCM->BDCTRL_B.RTCSRCSEL = (rtcClkSelect + 1);
+    }
+
+    else
+    {
+        RCM->BDCTRL_B.RTCSRCSEL = 3;
+        RCM->CFG_B.RTCPSC = rtcClkSelect;
+    }
+}
+
+/*!
+ * @brief     Enables the RTC clock
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_EnableRTCCLK(void)
+{
+    RCM->BDCTRL_B.RTCCLKEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the RTC clock
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_DisableRTCCLK(void)
+{
+    RCM->BDCTRL_B.RTCCLKEN = BIT_RESET;
+}
+/*!
+ * @brief     Enable the Backup domain reset
+ *
+ * @param     None
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void RCM_EnableBackupReset(void)
+{
+    RCM->BDCTRL_B.BDRST = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the Backup domain reset
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RCM_DisableBackupReset(void)
+{
+    RCM->BDCTRL_B.BDRST = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the I2S clock source (I2SCLK)
+ *
+ * @param     i2sClkSource: specifies the I2S clock source
+ *                          This parameter can be one of the following values:
+ *                          @arg RCM_I2S_CLK_PLLI2S : PLLI2S is selected as I2S clock source
+ *                          @arg RCM_I2S_CLK_EXT    : EXT is selected as I2S clock source
+ *
+ * @retval    None
+ */
+void RCM_ConfigI2SCLK(RCM_I2S_CLK_T i2sClkSource)
+{
+    RCM->CFG_B.I2SSEL = i2sClkSource;
+}
+
+/*!
+ * @brief    Enables AHB1 peripheral clock
+ *
+ * @param    AHB1Periph : Enable the specifies clock of AHB peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB1_PERIPH_GPIOA       : Enable GPIOA clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOB       : Enable GPIOB clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOC       : Enable GPIOC clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOD       : Enable GPIOD clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOE       : Enable GPIOE clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOF       : Enable GPIOF clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOG       : Enable GPIOG clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOI       : Enable GPIOI clock
+ *                       @arg RCM_AHB1_PERIPH_CRC         : Enable CRC clock
+ *                       @arg RCM_AHB1_PERIPH_BKPSRAM     : Enable BKPSRAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_CCMDATARAMEN: Enable CCM data RAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_DMA1        : Enable DMA1 clock
+ *                       @arg RCM_AHB1_PERIPH_DMA2        : Enable DMA2 clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC     : Enable Ethernet MAC clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Tx  : Enable Ethernet Transmission clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Rx  : Enable Ethernet Reception clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_PTP : Enable Ethernet PTP clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS      : Enable USB OTG HS clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS_ULPI : Enable USB OTG HS ULPI clock
+ *
+ * @retval    None
+ */
+void RCM_EnableAHB1PeriphClock(uint32_t AHB1Periph)
+{
+    RCM->AHB1CLKEN |= AHB1Periph;
+}
+
+/*!
+ * @brief    Disable AHB1 peripheral clock
+ *
+ * @param    AHB1Periph : Disable the specifies clock of AHB1 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB1_PERIPH_GPIOA       : Disable GPIOA clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOB       : Disable GPIOB clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOC       : Disable GPIOC clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOD       : Disable GPIOD clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOE       : Disable GPIOE clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOF       : Disable GPIOF clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOG       : Disable GPIOG clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOI       : Disable GPIOI clock
+ *                       @arg RCM_AHB1_PERIPH_CRC         : Disable CRC clock
+ *                       @arg RCM_AHB1_PERIPH_BKPSRAM     : Disable BKPSRAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_CCMDATARAMEN: Disable CCM data RAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_DMA1        : Disable DMA1 clock
+ *                       @arg RCM_AHB1_PERIPH_DMA2        : Disable DMA2 clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC     : Disable Ethernet MAC clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Tx  : Disable Ethernet Transmission clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Rx  : Disable Ethernet Reception clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_PTP : Disable Ethernet PTP clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS      : Disable USB OTG HS clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS_ULPI : Disable USB OTG HS ULPI clock
+ *
+ * @retval    None
+ */
+void RCM_DisableAHB1PeriphClock(uint32_t AHB1Periph)
+{
+    RCM->AHB1CLKEN &= (uint32_t)~AHB1Periph;
+}
+
+/*!
+ * @brief    Enables AHB2 peripheral clock
+ *
+ * @param    AHB2Periph : Enable the specifies clock of AHB2 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB2_PERIPH_DCI       : Enable DCI clock
+ *                       @arg RCM_AHB2_PERIPH_FPU       : Enable FPU clock
+ *                       @arg RCM_AHB2_PERIPH_BN        : Enable BN clock
+ *                       @arg RCM_AHB2_PERIPH_SM        : Enable SM clock
+ *                       @arg RCM_AHB2_PERIPH_CRYP      : Enable CRYP clock
+ *                       @arg RCM_AHB2_PERIPH_HASH      : Enable HASH clock
+ *                       @arg RCM_AHB2_PERIPH_RNG       : Enable RNG clock
+ *                       @arg RCM_AHB2_PERIPH_OTG_FS    : Enable OTG FS clock
+ *
+ * @retval    None
+ */
+void RCM_EnableAHB2PeriphClock(uint32_t AHB2Periph)
+{
+    RCM->AHB2CLKEN |= AHB2Periph;
+}
+
+/*!
+ * @brief    Disable AHB2 peripheral clock
+ *
+ * @param    AHB2Periph : Disable the specifies clock of AHB2 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB2_PERIPH_DCI       : Disable DCI clock
+ *                       @arg RCM_AHB2_PERIPH_FPU       : Disable FPU clock
+ *                       @arg RCM_AHB2_PERIPH_BN        : Disable BN clock
+ *                       @arg RCM_AHB2_PERIPH_SM        : Disable SM clock
+ *                       @arg RCM_AHB2_PERIPH_CRYP      : Disable CRYP clock
+ *                       @arg RCM_AHB2_PERIPH_HASH      : Disable HASH clock
+ *                       @arg RCM_AHB2_PERIPH_RNG       : Disable RNG clock
+ *                       @arg RCM_AHB2_PERIPH_OTG_FS    : Disable OTG FS clock
+ *
+ * @retval    None
+ */
+void RCM_DisableAHB2PeriphClock(uint32_t AHB2Periph)
+{
+    RCM->AHB2CLKEN &= (uint32_t)~AHB2Periph;
+}
+
+/*!
+ * @brief    Enable the Low Speed APB (APB1) peripheral clock
+ *
+ * @param    APB1Periph : Enable specifies clock of the APB1 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB1_PERIPH_TMR2   : Enable TMR2 clock
+ *                        @arg RCM_APB1_PERIPH_TMR3   : Enable TMR3 clock
+ *                        @arg RCM_APB1_PERIPH_TMR4   : Enable TMR4 clock
+ *                        @arg RCM_APB1_PERIPH_TMR5   : Enable TMR5 clock
+ *                        @arg RCM_APB1_PERIPH_TMR6   : Enable TMR6 clock
+ *                        @arg RCM_APB1_PERIPH_TMR7   : Enable TMR7 clock
+ *                        @arg RCM_APB1_PERIPH_TMR12  : Enable TMR12 clock
+ *                        @arg RCM_APB1_PERIPH_TMR13  : Enable TMR13 clock
+ *                        @arg RCM_APB1_PERIPH_TMR14  : Enable TMR14 clock
+ *                        @arg RCM_APB1_PERIPH_WWDT   : Enable WWDT clock
+ *                        @arg RCM_APB1_PERIPH_SPI2   : Enable SPI2 clock
+ *                        @arg RCM_APB1_PERIPH_SPI3   : Enable SPI3 clock
+ *                        @arg RCM_APB1_PERIPH_USART2 : Enable USART2 clock
+ *                        @arg RCM_APB1_PERIPH_USART3 : Enable USART3 clock
+ *                        @arg RCM_APB1_PERIPH_UART4  : Enable UART4 clock
+ *                        @arg RCM_APB1_PERIPH_UART5  : Enable UART5 clock
+ *                        @arg RCM_APB1_PERIPH_I2C1   : Enable I2C1 clock
+ *                        @arg RCM_APB1_PERIPH_I2C2   : Enable I2C2 clock
+ *                        @arg RCM_APB1_PERIPH_I2C3   : Enable I2C3 clock
+ *                        @arg RCM_APB1_PERIPH_FMPI2C1: Enable FMPI2C1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN1   : Enable CAN1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN2   : Enable CAN2 clock
+ *                        @arg RCM_APB1_PERIPH_PMU    : Enable PMU clock
+ *                        @arg RCM_APB1_PERIPH_DAC    : Enable DAC clock
+ *                        @arg RCM_APB1_PERIPH_UART7  : Enable UART7 clock
+ *                        @arg RCM_APB1_PERIPH_UART8  : Enable UART8 clock
+ *
+ * @retval   None
+ */
+void RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)
+{
+    RCM->APB1CLKEN |= APB1Periph;
+}
+
+/*!
+ * @brief    Disable the Low Speed APB (APB1) peripheral clock
+ *
+ * @param    APB1Periph : Disable specifies clock of the APB1 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB1_PERIPH_TMR2   : Disable TMR2 clock
+ *                        @arg RCM_APB1_PERIPH_TMR3   : Disable TMR3 clock
+ *                        @arg RCM_APB1_PERIPH_TMR4   : Disable TMR4 clock
+ *                        @arg RCM_APB1_PERIPH_TMR5   : Disable TMR5 clock
+ *                        @arg RCM_APB1_PERIPH_TMR6   : Disable TMR6 clock
+ *                        @arg RCM_APB1_PERIPH_TMR7   : Disable TMR7 clock
+ *                        @arg RCM_APB1_PERIPH_TMR12  : Disable TMR12 clock
+ *                        @arg RCM_APB1_PERIPH_TMR13  : Disable TMR13 clock
+ *                        @arg RCM_APB1_PERIPH_TMR14  : Disable TMR14 clock
+ *                        @arg RCM_APB1_PERIPH_WWDT   : Disable WWDT clock
+ *                        @arg RCM_APB1_PERIPH_SPI2   : Disable SPI2 clock
+ *                        @arg RCM_APB1_PERIPH_SPI3   : Disable SPI3 clock
+ *                        @arg RCM_APB1_PERIPH_USART2 : Disable USART2 clock
+ *                        @arg RCM_APB1_PERIPH_USART3 : Disable USART3 clock
+ *                        @arg RCM_APB1_PERIPH_UART4  : Disable UART4 clock
+ *                        @arg RCM_APB1_PERIPH_UART5  : Disable UART5 clock
+ *                        @arg RCM_APB1_PERIPH_I2C1   : Disable I2C1 clock
+ *                        @arg RCM_APB1_PERIPH_I2C2   : Disable I2C2 clock
+ *                        @arg RCM_APB1_PERIPH_I2C3   : Disable I2C3 clock
+ *                        @arg RCM_APB1_PERIPH_FMPI2C1: Disable FMPI2C1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN1   : Disable CAN1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN2   : Disable CAN2 clock
+ *                        @arg RCM_APB1_PERIPH_PMU    : Disable PMU clock
+ *                        @arg RCM_APB1_PERIPH_DAC    : Disable DAC clock
+ *                        @arg RCM_APB1_PERIPH_UART7  : Disable UART7 clock
+ *                        @arg RCM_APB1_PERIPH_UART8  : Disable UART8 clock
+ *
+ * @retval   None
+ */
+void RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)
+{
+    RCM->APB1CLKEN &= (uint32_t)~APB1Periph;
+}
+
+/*!
+ * @brief    Enable the High Speed APB (APB2) peripheral clock
+ *
+ * @param    APB2Periph : Enable specifies clock of the APB2 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB2_PERIPH_TMR1   : TMR1 clock
+ *                        @arg RCM_APB2_PERIPH_TMR8   : TMR8 clock
+ *                        @arg RCM_APB2_PERIPH_USART1 : USART1 clock
+ *                        @arg RCM_APB2_PERIPH_USART6 : USART6 clock
+ *                        @arg RCM_APB2_PERIPH_ADC1   : ADC1 clock
+ *                        @arg RCM_APB2_PERIPH_ADC2   : ADC2 clock
+ *                        @arg RCM_APB2_PERIPH_ADC3   : ADC3 clock
+ *                        @arg RCM_APB2_PERIPH_SDIO   : SDIO clock
+ *                        @arg RCM_APB2_PERIPH_SPI1   : SPI1 clock
+ *                        @arg RCM_APB2_PERIPH_SPI4   : SPI4 clock
+ *                        @arg RCM_APB2_PERIPH_SYSCFG : SYSCFG clock
+ *                        @arg RCM_APB2_PERIPH_TMR9   : TMR9 clock
+ *                        @arg RCM_APB2_PERIPH_TMR10  : TMR10 clock
+ *                        @arg RCM_APB2_PERIPH_TMR11  : TMR11 clock
+ *                        @arg RCM_APB2_PERIPH_SPI5   : SPI5 clock
+ *                        @arg RCM_APB2_PERIPH_SPI6   : SPI6 clock
+ *
+ * @retval   None
+ */
+void RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)
+{
+    RCM->APB2CLKEN |= APB2Periph;
+}
+
+/*!
+ * @brief    Disable the High Speed APB (APB2) peripheral clock
+ *
+ * @param    APB2Periph : Disable specifies clock of the APB2 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB2_PERIPH_TMR1   : TMR1 clock
+ *                        @arg RCM_APB2_PERIPH_TMR8   : TMR8 clock
+ *                        @arg RCM_APB2_PERIPH_USART1 : USART1 clock
+ *                        @arg RCM_APB2_PERIPH_USART6 : USART6 clock
+ *                        @arg RCM_APB2_PERIPH_ADC1   : ADC1 clock
+ *                        @arg RCM_APB2_PERIPH_ADC2   : ADC2 clock
+ *                        @arg RCM_APB2_PERIPH_ADC3   : ADC3 clock
+ *                        @arg RCM_APB2_PERIPH_SDIO   : SDIO clock
+ *                        @arg RCM_APB2_PERIPH_SPI1   : SPI1 clock
+ *                        @arg RCM_APB2_PERIPH_SPI4   : SPI4 clock
+ *                        @arg RCM_APB2_PERIPH_SYSCFG : SYSCFG clock
+ *                        @arg RCM_APB2_PERIPH_TMR9   : TMR9 clock
+ *                        @arg RCM_APB2_PERIPH_TMR10  : TMR10 clock
+ *                        @arg RCM_APB2_PERIPH_TMR11  : TMR11 clock
+ *                        @arg RCM_APB2_PERIPH_SPI5   : SPI5 clock
+ *                        @arg RCM_APB2_PERIPH_SPI6   : SPI6 clock
+ *
+ * @retval   None
+ */
+void RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)
+{
+    RCM->APB2CLKEN &= (uint32_t)~APB2Periph;
+}
+
+/*!
+ * @brief    Enables AHB1 peripheral reset
+ *
+ * @param    AHB1Periph : Enable the specifies reset of AHB peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB1_PERIPH_GPIOA       : Enable GPIOA reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOB       : Enable GPIOB reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOC       : Enable GPIOC reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOD       : Enable GPIOD reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOE       : Enable GPIOE reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOF       : Enable GPIOF reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOG       : Enable GPIOG reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOI       : Enable GPIOI reset
+ *                       @arg RCM_AHB1_PERIPH_CRC         : Enable CRC reset
+ *                       @arg RCM_AHB1_PERIPH_BKPSRAM     : Enable BKPSRAM interface reset
+ *                       @arg RCM_AHB1_PERIPH_CCMDATARAMEN: Enable CCM data RAM interface reset
+ *                       @arg RCM_AHB1_PERIPH_DMA1        : Enable DMA1 reset
+ *                       @arg RCM_AHB1_PERIPH_DMA2        : Enable DMA2 reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC     : Enable Ethernet MAC reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Tx  : Enable Ethernet Transmission reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Rx  : Enable Ethernet Reception reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_PTP : Enable Ethernet PTP reset
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS      : Enable USB OTG HS reset
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS_ULPI : Enable USB OTG HS ULPI clock
+ *
+ * @retval    None
+ */
+void RCM_EnableAHB1PeriphReset(uint32_t AHB1Periph)
+{
+    RCM->AHB1RST |= AHB1Periph;
+}
+
+/*!
+ * @brief    Disable AHB1 peripheral reset
+ *
+ * @param    AHB1Periph : Disable the specifies reset of AHB1 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB1_PERIPH_GPIOA       : Disable GPIOA reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOB       : Disable GPIOB reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOC       : Disable GPIOC reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOD       : Disable GPIOD reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOE       : Disable GPIOE reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOF       : Disable GPIOF reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOG       : Disable GPIOG reset
+ *                       @arg RCM_AHB1_PERIPH_GPIOI       : Disable GPIOI reset
+ *                       @arg RCM_AHB1_PERIPH_CRC         : Disable CRC reset
+ *                       @arg RCM_AHB1_PERIPH_BKPSRAM     : Disable BKPSRAM interface reset
+ *                       @arg RCM_AHB1_PERIPH_CCMDATARAMEN: Disable CCM data RAM interface reset
+ *                       @arg RCM_AHB1_PERIPH_DMA1        : Disable DMA1 reset
+ *                       @arg RCM_AHB1_PERIPH_DMA2        : Disable DMA2 reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC     : Disable Ethernet MAC reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Tx  : Disable Ethernet Transmission reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Rx  : Disable Ethernet Reception reset
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_PTP : Disable Ethernet PTP reset
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS      : Disable USB OTG HS reset
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS_ULPI : Disable USB OTG HS ULPI reset
+ *
+ * @retval    None
+ */
+void RCM_DisableAHB1PeriphReset(uint32_t AHB1Periph)
+{
+    RCM->AHB1RST &= (uint32_t)~AHB1Periph;
+}
+
+/*!
+ * @brief    Enables AHB2 peripheral reset
+ *
+ * @param    AHB2Periph : Enable the specifies reset of AHB2 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB2_PERIPH_DCI       : Enable DCI reset
+ *                       @arg RCM_AHB2_PERIPH_FPU       : Enable FPU reset
+ *                       @arg RCM_AHB2_PERIPH_BN        : Enable BN reset
+ *                       @arg RCM_AHB2_PERIPH_SM        : Enable SM reset
+ *                       @arg RCM_AHB2_PERIPH_CRYP      : Enable CRYP reset
+ *                       @arg RCM_AHB2_PERIPH_HASH      : Enable HASH reset
+ *                       @arg RCM_AHB2_PERIPH_RNG       : Enable RNG reset
+ *                       @arg RCM_AHB2_PERIPH_OTG_FS    : Enable OTG FS reset
+ *
+ * @retval    None
+ */
+void RCM_EnableAHB2PeriphReset(uint32_t AHB2Periph)
+{
+    RCM->AHB2RST |= AHB2Periph;
+}
+
+/*!
+ * @brief    Disable AHB2 peripheral reset
+ *
+ * @param    AHB2Periph : Disable the specifies reset of AHB2 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB2_PERIPH_DCI       : Disable DCI reset
+ *                       @arg RCM_AHB2_PERIPH_FPU       : Disable FPU reset
+ *                       @arg RCM_AHB2_PERIPH_BN        : Disable BN reset
+ *                       @arg RCM_AHB2_PERIPH_SM        : Disable SM reset
+ *                       @arg RCM_AHB2_PERIPH_CRYP      : Disable CRYP reset
+ *                       @arg RCM_AHB2_PERIPH_HASH      : Disable HASH reset
+ *                       @arg RCM_AHB2_PERIPH_RNG       : Disable RNG reset
+ *                       @arg RCM_AHB2_PERIPH_OTG_FS    : Disable OTG FS reset
+ *
+ * @retval    None
+ */
+void RCM_DisableAHB2PeriphReset(uint32_t AHB2Periph)
+{
+    RCM->AHB2RST &= (uint32_t)~AHB2Periph;
+}
+
+/*!
+ * @brief    Enable the Low Speed APB (APB1) peripheral reset
+ *
+ * @param    APB1Periph : Enable specifies reset of the APB1 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB1_PERIPH_TMR2   : Enable TMR2 reset
+ *                        @arg RCM_APB1_PERIPH_TMR3   : Enable TMR3 reset
+ *                        @arg RCM_APB1_PERIPH_TMR4   : Enable TMR4 reset
+ *                        @arg RCM_APB1_PERIPH_TMR5   : Enable TMR5 reset
+ *                        @arg RCM_APB1_PERIPH_TMR6   : Enable TMR6 reset
+ *                        @arg RCM_APB1_PERIPH_TMR7   : Enable TMR7 reset
+ *                        @arg RCM_APB1_PERIPH_TMR12  : Enable TMR12 reset
+ *                        @arg RCM_APB1_PERIPH_TMR13  : Enable TMR13 reset
+ *                        @arg RCM_APB1_PERIPH_TMR14  : Enable TMR14 reset
+ *                        @arg RCM_APB1_PERIPH_WWDT   : Enable WWDT reset
+ *                        @arg RCM_APB1_PERIPH_SPI2   : Enable SPI2 reset
+ *                        @arg RCM_APB1_PERIPH_SPI3   : Enable SPI3 reset
+ *                        @arg RCM_APB1_PERIPH_USART2 : Enable USART2 reset
+ *                        @arg RCM_APB1_PERIPH_USART3 : Enable USART3 reset
+ *                        @arg RCM_APB1_PERIPH_UART4  : Enable UART4 reset
+ *                        @arg RCM_APB1_PERIPH_UART5  : Enable UART5 reset
+ *                        @arg RCM_APB1_PERIPH_I2C1   : Enable I2C1 reset
+ *                        @arg RCM_APB1_PERIPH_I2C2   : Enable I2C2 reset
+ *                        @arg RCM_APB1_PERIPH_I2C3   : Enable I2C3 reset
+ *                        @arg RCM_APB1_PERIPH_FMPI2C1: Enable FMPI2C1 reset
+ *                        @arg RCM_APB1_PERIPH_CAN1   : Enable CAN1 reset
+ *                        @arg RCM_APB1_PERIPH_CAN2   : Enable CAN2 reset
+ *                        @arg RCM_APB1_PERIPH_PMU    : Enable PMU reset
+ *                        @arg RCM_APB1_PERIPH_DAC    : Enable DAC reset
+ *                        @arg RCM_APB1_PERIPH_UART7  : Enable UART7 reset
+ *                        @arg RCM_APB1_PERIPH_UART8  : Enable UART8 reset
+ *
+ * @retval   None
+ */
+void RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)
+{
+    RCM->APB1RST |= APB1Periph;
+}
+
+/*!
+ * @brief    Disable the Low Speed APB (APB1) peripheral reset
+ *
+ * @param    APB1Periph : Disable specifies reset of the APB1 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB1_PERIPH_TMR2   : Disable TMR2 reset
+ *                        @arg RCM_APB1_PERIPH_TMR3   : Disable TMR3 reset
+ *                        @arg RCM_APB1_PERIPH_TMR4   : Disable TMR4 reset
+ *                        @arg RCM_APB1_PERIPH_TMR5   : Disable TMR5 reset
+ *                        @arg RCM_APB1_PERIPH_TMR6   : Disable TMR6 reset
+ *                        @arg RCM_APB1_PERIPH_TMR7   : Disable TMR7 reset
+ *                        @arg RCM_APB1_PERIPH_TMR12  : Disable TMR12 reset
+ *                        @arg RCM_APB1_PERIPH_TMR13  : Disable TMR13 reset
+ *                        @arg RCM_APB1_PERIPH_TMR14  : Disable TMR14 reset
+ *                        @arg RCM_APB1_PERIPH_WWDT   : Disable WWDT reset
+ *                        @arg RCM_APB1_PERIPH_SPI2   : Disable SPI2 reset
+ *                        @arg RCM_APB1_PERIPH_SPI3   : Disable SPI3 reset
+ *                        @arg RCM_APB1_PERIPH_USART2 : Disable USART2 reset
+ *                        @arg RCM_APB1_PERIPH_USART3 : Disable USART3 reset
+ *                        @arg RCM_APB1_PERIPH_UART4  : Disable UART4 reset
+ *                        @arg RCM_APB1_PERIPH_UART5  : Disable UART5 reset
+ *                        @arg RCM_APB1_PERIPH_I2C1   : Disable I2C1 reset
+ *                        @arg RCM_APB1_PERIPH_I2C2   : Disable I2C2 reset
+ *                        @arg RCM_APB1_PERIPH_I2C3   : Disable I2C3 reset
+ *                        @arg RCM_APB1_PERIPH_FMPI2C1: Disable FMPI2C1 reset
+ *                        @arg RCM_APB1_PERIPH_CAN1   : Disable CAN1 reset
+ *                        @arg RCM_APB1_PERIPH_CAN2   : Disable CAN2 reset
+ *                        @arg RCM_APB1_PERIPH_PMU    : Disable PMU reset
+ *                        @arg RCM_APB1_PERIPH_DAC    : Disable DAC reset
+ *                        @arg RCM_APB1_PERIPH_UART7  : Disable UART7 reset
+ *                        @arg RCM_APB1_PERIPH_UART8  : Disable UART8 reset
+ *
+ * @retval   None
+ */
+void RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)
+{
+    RCM->APB1RST &= (uint32_t)~APB1Periph;
+}
+
+/*!
+ * @brief    Enable the High Speed APB (APB2) peripheral reset
+ *
+ * @param    APB2Periph : Enable specifies reset of the APB2 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB2_PERIPH_TMR1   : TMR1 reset
+ *                        @arg RCM_APB2_PERIPH_TMR8   : TMR8 reset
+ *                        @arg RCM_APB2_PERIPH_USART1 : USART1 reset
+ *                        @arg RCM_APB2_PERIPH_USART6 : USART6 reset
+ *                        @arg RCM_APB2_PERIPH_ADC    : All of ADC reset
+ *                        @arg RCM_APB2_PERIPH_SDIO   : SDIO reset
+ *                        @arg RCM_APB2_PERIPH_SPI1   : SPI1 reset
+ *                        @arg RCM_APB2_PERIPH_SPI4   : SPI4 reset
+ *                        @arg RCM_APB2_PERIPH_SYSCFG : SYSCFG reset
+ *                        @arg RCM_APB2_PERIPH_TMR9   : TMR9 reset
+ *                        @arg RCM_APB2_PERIPH_TMR10  : TMR10 reset
+ *                        @arg RCM_APB2_PERIPH_TMR11  : TMR11 reset
+ *                        @arg RCM_APB2_PERIPH_SPI5   : SPI5 reset
+ *                        @arg RCM_APB2_PERIPH_SPI6   : SPI6 reset
+ *
+ * @retval   None
+ */
+void RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)
+{
+    RCM->APB2RST |= APB2Periph;
+}
+
+/*!
+ * @brief    Disable the High Speed APB (APB2) peripheral reset
+ *
+ * @param    APB2Periph : Disable specifies reset of the APB2 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB2_PERIPH_TMR1   : TMR1 reset
+ *                        @arg RCM_APB2_PERIPH_TMR8   : TMR8 reset
+ *                        @arg RCM_APB2_PERIPH_USART1 : USART1 reset
+ *                        @arg RCM_APB2_PERIPH_USART6 : USART6 reset
+ *                        @arg RCM_APB2_PERIPH_ADC1   : ADC1 reset
+ *                        @arg RCM_APB2_PERIPH_ADC2   : ADC2 reset
+ *                        @arg RCM_APB2_PERIPH_ADC3   : ADC3 reset
+ *                        @arg RCM_APB2_PERIPH_SDIO   : SDIO reset
+ *                        @arg RCM_APB2_PERIPH_SPI1   : SPI1 reset
+ *                        @arg RCM_APB2_PERIPH_SPI4   : SPI4 reset
+ *                        @arg RCM_APB2_PERIPH_SYSCFG : SYSCFG reset
+ *                        @arg RCM_APB2_PERIPH_TMR9   : TMR9 reset
+ *                        @arg RCM_APB2_PERIPH_TMR10  : TMR10 reset
+ *                        @arg RCM_APB2_PERIPH_TMR11  : TMR11 reset
+ *                        @arg RCM_APB2_PERIPH_SPI5   : SPI5 reset
+ *                        @arg RCM_APB2_PERIPH_SPI6   : SPI6 reset
+ *
+ * @retval   None
+ */
+void RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)
+{
+    RCM->APB2RST &= (uint32_t)~APB2Periph;
+}
+
+/*!
+ * @brief    Enables AHB1 peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    AHB1Periph : Enable the specifies clock of AHB peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB1_PERIPH_GPIOA       : Enable GPIOA clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOB       : Enable GPIOB clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOC       : Enable GPIOC clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOD       : Enable GPIOD clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOE       : Enable GPIOE clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOF       : Enable GPIOF clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOG       : Enable GPIOG clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOI       : Enable GPIOI clock
+ *                       @arg RCM_AHB1_PERIPH_CRC         : Enable CRC clock
+ *                       @arg RCM_AHB1_PERIPH_BKPSRAM     : Enable BKPSRAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_CCMDATARAMEN: Enable CCM data RAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_DMA1        : Enable DMA1 clock
+ *                       @arg RCM_AHB1_PERIPH_DMA2        : Enable DMA2 clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC     : Enable Ethernet MAC clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Tx  : Enable Ethernet Transmission clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Rx  : Enable Ethernet Reception clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_PTP : Enable Ethernet PTP clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS      : Enable USB OTG HS clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS_ULPI : Enable USB OTG HS ULPI clock
+ *
+ * @retval    None
+ */
+void RCM_EnableAHB1PeriphClockLPMode(uint32_t AHB1Periph)
+{
+    RCM->LPAHB1CLKEN |= AHB1Periph;
+}
+
+/*!
+ * @brief    Disable AHB1 peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    AHB1Periph : Disable the specifies clock of AHB1 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB1_PERIPH_GPIOA       : Disable GPIOA clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOB       : Disable GPIOB clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOC       : Disable GPIOC clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOD       : Disable GPIOD clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOE       : Disable GPIOE clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOF       : Disable GPIOF clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOG       : Disable GPIOG clock
+ *                       @arg RCM_AHB1_PERIPH_GPIOI       : Disable GPIOI clock
+ *                       @arg RCM_AHB1_PERIPH_CRC         : Disable CRC clock
+ *                       @arg RCM_AHB1_PERIPH_BKPSRAM     : Disable BKPSRAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_CCMDATARAMEN: Disable CCM data RAM interface clock
+ *                       @arg RCM_AHB1_PERIPH_DMA1        : Disable DMA1 clock
+ *                       @arg RCM_AHB1_PERIPH_DMA2        : Disable DMA2 clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC     : Disable Ethernet MAC clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Tx  : Disable Ethernet Transmission clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_Rx  : Disable Ethernet Reception clock
+ *                       @arg RCM_AHB1_PERIPH_ETH_MAC_PTP : Disable Ethernet PTP clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS      : Disable USB OTG HS clock
+ *                       @arg RCM_AHB1_PERIPH_OTG_HS_ULPI : Disable USB OTG HS ULPI clock
+ *
+ * @retval    None
+ */
+void RCM_DisableAHB1PeriphClockLPMode(uint32_t AHB1Periph)
+{
+    RCM->LPAHB1CLKEN &= (uint32_t)~AHB1Periph;
+}
+
+/*!
+ * @brief    Enables AHB2 peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    AHB2Periph : Enable the specifies clock of AHB2 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB2_PERIPH_DCI       : Enable DCI clock
+ *                       @arg RCM_AHB2_PERIPH_FPU       : Enable FPU clock
+ *                       @arg RCM_AHB2_PERIPH_BN        : Enable BN clock
+ *                       @arg RCM_AHB2_PERIPH_SM        : Enable SM clock
+ *                       @arg RCM_AHB2_PERIPH_CRYP      : Enable CRYP clock
+ *                       @arg RCM_AHB2_PERIPH_HASH      : Enable HASH clock
+ *                       @arg RCM_AHB2_PERIPH_RNG       : Enable RNG clock
+ *                       @arg RCM_AHB2_PERIPH_OTG_FS    : Enable OTG FS clock
+ *
+ * @retval    None
+ */
+void RCM_EnableAHB2PeriphClockLPMode(uint32_t AHB2Periph)
+{
+    RCM->LPAHB2CLKEN |= AHB2Periph;
+}
+
+/*!
+ * @brief    Disable AHB2 peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    AHB2Periph : Disable the specifies clock of AHB2 peripheral
+ *                       This parameter can be any combination of the following values:
+ *                       @arg RCM_AHB2_PERIPH_DCI       : Disable DCI clock
+ *                       @arg RCM_AHB2_PERIPH_FPU       : Disable FPU clock
+ *                       @arg RCM_AHB2_PERIPH_BN        : Disable BN clock
+ *                       @arg RCM_AHB2_PERIPH_SM        : Disable SM clock
+ *                       @arg RCM_AHB2_PERIPH_CRYP      : Disable CRYP clock
+ *                       @arg RCM_AHB2_PERIPH_HASH      : Disable HASH clock
+ *                       @arg RCM_AHB2_PERIPH_RNG       : Disable RNG clock
+ *                       @arg RCM_AHB2_PERIPH_OTG_FS    : Disable OTG FS clock
+ *
+ * @retval    None
+ */
+void RCM_DisableAHB2PeriphClockLPMode(uint32_t AHB2Periph)
+{
+    RCM->LPAHB2CLKEN &= (uint32_t)~AHB2Periph;
+}
+
+/*!
+ * @brief    Enable the Low Speed APB (APB1) peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    APB1Periph : Enable specifies clock of the APB1 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB1_PERIPH_TMR2   : Enable TMR2 clock
+ *                        @arg RCM_APB1_PERIPH_TMR3   : Enable TMR3 clock
+ *                        @arg RCM_APB1_PERIPH_TMR4   : Enable TMR4 clock
+ *                        @arg RCM_APB1_PERIPH_TMR5   : Enable TMR5 clock
+ *                        @arg RCM_APB1_PERIPH_TMR6   : Enable TMR6 clock
+ *                        @arg RCM_APB1_PERIPH_TMR7   : Enable TMR7 clock
+ *                        @arg RCM_APB1_PERIPH_TMR12  : Enable TMR12 clock
+ *                        @arg RCM_APB1_PERIPH_TMR13  : Enable TMR13 clock
+ *                        @arg RCM_APB1_PERIPH_TMR14  : Enable TMR14 clock
+ *                        @arg RCM_APB1_PERIPH_WWDT   : Enable WWDT clock
+ *                        @arg RCM_APB1_PERIPH_SPI2   : Enable SPI2 clock
+ *                        @arg RCM_APB1_PERIPH_SPI3   : Enable SPI3 clock
+ *                        @arg RCM_APB1_PERIPH_USART2 : Enable USART2 clock
+ *                        @arg RCM_APB1_PERIPH_USART3 : Enable USART3 clock
+ *                        @arg RCM_APB1_PERIPH_UART4  : Enable UART4 clock
+ *                        @arg RCM_APB1_PERIPH_UART5  : Enable UART5 clock
+ *                        @arg RCM_APB1_PERIPH_I2C1   : Enable I2C1 clock
+ *                        @arg RCM_APB1_PERIPH_I2C2   : Enable I2C2 clock
+ *                        @arg RCM_APB1_PERIPH_I2C3   : Enable I2C3 clock
+ *                        @arg RCM_APB1_PERIPH_FMPI2C1: Enable FMPI2C1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN1   : Enable CAN1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN2   : Enable CAN2 clock
+ *                        @arg RCM_APB1_PERIPH_PMU    : Enable PMU clock
+ *                        @arg RCM_APB1_PERIPH_DAC    : Enable DAC clock
+ *                        @arg RCM_APB1_PERIPH_UART7  : Enable UART7 clock
+ *                        @arg RCM_APB1_PERIPH_UART8  : Enable UART8 clock
+ *
+ * @retval   None
+ */
+void RCM_EnableAPB1PeriphClockLPMode(uint32_t APB1Periph)
+{
+    RCM->LPAPB1CLKEN |= APB1Periph;
+}
+
+/*!
+ * @brief    Disable the Low Speed APB (APB1) peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    APB1Periph : Disable specifies clock of the APB1 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB1_PERIPH_TMR2   : Disable TMR2 clock
+ *                        @arg RCM_APB1_PERIPH_TMR3   : Disable TMR3 clock
+ *                        @arg RCM_APB1_PERIPH_TMR4   : Disable TMR4 clock
+ *                        @arg RCM_APB1_PERIPH_TMR5   : Disable TMR5 clock
+ *                        @arg RCM_APB1_PERIPH_TMR6   : Disable TMR6 clock
+ *                        @arg RCM_APB1_PERIPH_TMR7   : Disable TMR7 clock
+ *                        @arg RCM_APB1_PERIPH_TMR12  : Disable TMR12 clock
+ *                        @arg RCM_APB1_PERIPH_TMR13  : Disable TMR13 clock
+ *                        @arg RCM_APB1_PERIPH_TMR14  : Disable TMR14 clock
+ *                        @arg RCM_APB1_PERIPH_WWDT   : Disable WWDT clock
+ *                        @arg RCM_APB1_PERIPH_SPI2   : Disable SPI2 clock
+ *                        @arg RCM_APB1_PERIPH_SPI3   : Disable SPI3 clock
+ *                        @arg RCM_APB1_PERIPH_USART2 : Disable USART2 clock
+ *                        @arg RCM_APB1_PERIPH_USART3 : Disable USART3 clock
+ *                        @arg RCM_APB1_PERIPH_UART4  : Disable UART4 clock
+ *                        @arg RCM_APB1_PERIPH_UART5  : Disable UART5 clock
+ *                        @arg RCM_APB1_PERIPH_I2C1   : Disable I2C1 clock
+ *                        @arg RCM_APB1_PERIPH_I2C2   : Disable I2C2 clock
+ *                        @arg RCM_APB1_PERIPH_I2C3   : Disable I2C3 clock
+ *                        @arg RCM_APB1_PERIPH_FMPI2C1: Disable FMPI2C1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN1   : Disable CAN1 clock
+ *                        @arg RCM_APB1_PERIPH_CAN2   : Disable CAN2 clock
+ *                        @arg RCM_APB1_PERIPH_PMU    : Disable PMU clock
+ *                        @arg RCM_APB1_PERIPH_DAC    : Disable DAC clock
+ *                        @arg RCM_APB1_PERIPH_UART7  : Disable UART7 clock
+ *                        @arg RCM_APB1_PERIPH_UART8  : Disable UART8 clock
+ *
+ * @retval   None
+ */
+void RCM_DisableAPB1PeriphClockLPMode(uint32_t APB1Periph)
+{
+    RCM->LPAPB1CLKEN &= (uint32_t)~APB1Periph;
+}
+
+/*!
+ * @brief    Enable the High Speed APB (APB2) peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    APB2Periph : Enable specifies clock of the APB2 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB2_PERIPH_TMR1   : TMR1 clock
+ *                        @arg RCM_APB2_PERIPH_TMR8   : TMR8 clock
+ *                        @arg RCM_APB2_PERIPH_USART1 : USART1 clock
+ *                        @arg RCM_APB2_PERIPH_USART6 : USART6 clock
+ *                        @arg RCM_APB2_PERIPH_ADC1   : ADC1 clock
+ *                        @arg RCM_APB2_PERIPH_ADC2   : ADC2 clock
+ *                        @arg RCM_APB2_PERIPH_ADC3   : ADC3 clock
+ *                        @arg RCM_APB2_PERIPH_SDIO   : SDIO clock
+ *                        @arg RCM_APB2_PERIPH_SPI1   : SPI1 clock
+ *                        @arg RCM_APB2_PERIPH_SPI4   : SPI4 clock
+ *                        @arg RCM_APB2_PERIPH_SYSCFG : SYSCFG clock
+ *                        @arg RCM_APB2_PERIPH_TMR9   : TMR9 clock
+ *                        @arg RCM_APB2_PERIPH_TMR10  : TMR10 clock
+ *                        @arg RCM_APB2_PERIPH_TMR11  : TMR11 clock
+ *                        @arg RCM_APB2_PERIPH_SPI5   : SPI5 clock
+ *                        @arg RCM_APB2_PERIPH_SPI6   : SPI6 clock
+ *
+ * @retval   None
+ */
+void RCM_EnableAPB2PeriphClockLPMode(uint32_t APB2Periph)
+{
+    RCM->LPAPB2CLKEN |= APB2Periph;
+}
+
+/*!
+ * @brief    Disable the High Speed APB (APB2) peripheral clock during Low Power (Sleep) mode
+ *
+ * @param    APB2Periph : Disable specifies clock of the APB2 peripheral.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_APB2_PERIPH_TMR1   : TMR1 clock
+ *                        @arg RCM_APB2_PERIPH_TMR8   : TMR8 clock
+ *                        @arg RCM_APB2_PERIPH_USART1 : USART1 clock
+ *                        @arg RCM_APB2_PERIPH_USART6 : USART6 clock
+ *                        @arg RCM_APB2_PERIPH_ADC1   : ADC1 clock
+ *                        @arg RCM_APB2_PERIPH_ADC2   : ADC2 clock
+ *                        @arg RCM_APB2_PERIPH_ADC3   : ADC3 clock
+ *                        @arg RCM_APB2_PERIPH_SDIO   : SDIO clock
+ *                        @arg RCM_APB2_PERIPH_SPI1   : SPI1 clock
+ *                        @arg RCM_APB2_PERIPH_SPI4   : SPI4 clock
+ *                        @arg RCM_APB2_PERIPH_SYSCFG : SYSCFG clock
+ *                        @arg RCM_APB2_PERIPH_TMR9   : TMR9 clock
+ *                        @arg RCM_APB2_PERIPH_TMR10  : TMR10 clock
+ *                        @arg RCM_APB2_PERIPH_TMR11  : TMR11 clock
+ *                        @arg RCM_APB2_PERIPH_SPI5   : SPI5 clock
+ *                        @arg RCM_APB2_PERIPH_SPI6   : SPI6 clock
+ *
+ * @retval   None
+ */
+void RCM_DisableAPB2PeriphClockLPMode(uint32_t APB2Periph)
+{
+    RCM->LPAPB2CLKEN &= (uint32_t)~APB2Periph;
+}
+
+/*!
+ * @brief     Enable RCM interrupts
+ *
+ * @param     interrupt : Enable specifies RCM interrupt sources.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_INT_LSIRDY  : LSI ready interrupt
+ *                        @arg RCM_INT_LSERDY  : LSE ready interrupt
+ *                        @arg RCM_INT_HSIRDY  : HSI ready interrupt
+ *                        @arg RCM_INT_HSERDY  : HSE ready interrupt
+ *                        @arg RCM_INT_PLL1RDY : PLL1 ready interrupt
+ *                        @arg RCM_INT_PLL2RDY : PLL2 ready interrupt
+ *
+ * @retval    None
+ */
+void RCM_EnableInterrupt(uint32_t interrupt)
+{
+    uint32_t temp;
+
+    temp = interrupt << 8;
+
+    RCM->INT |= temp;
+}
+
+/*!
+ * @brief     Disable RCM interrupts
+ *
+ * @param     interrupt : Disable specifies RCM interrupt sources.
+ *                        This parameter can be any combination of the following values:
+ *                        @arg RCM_INT_LSIRDY  : LSI ready interrupt
+ *                        @arg RCM_INT_LSERDY  : LSE ready interrupt
+ *                        @arg RCM_INT_HSIRDY  : HSI ready interrupt
+ *                        @arg RCM_INT_HSERDY  : HSE ready interrupt
+ *                        @arg RCM_INT_PLL1RDY : PLL1 ready interrupt
+ *                        @arg RCM_INT_PLL2RDY : PLL2 ready interrupt
+ *
+ * @retval    None
+ */
+void RCM_DisableInterrupt(uint32_t interrupt)
+{
+    uint32_t temp;
+
+    temp = interrupt << 8;
+
+    RCM->INT &= (uint32_t)~temp;
+}
+
+/*!
+ * @brief     Read the specified RCM flag status
+ *
+ * @param     flag : Returns specifies the flag status.
+ *                   This parameter can be one of the following values:
+ *                   @arg RCM_FLAG_HSIRDY  : HSI ready flag
+ *                   @arg RCM_FLAG_HSERDY  : HSE ready flag
+ *                   @arg RCM_FLAG_PLL1RDY : PLL1 ready flag
+ *                   @arg RCM_FLAG_PLL2RDY : PLL2 ready flag
+ *                   @arg RCM_FLAG_LSERDY  : LSE ready flag
+ *                   @arg RCM_FLAG_LSIRDY  : LSI ready flag
+ *                   @arg RCM_FLAG_BORRST  : POR/PDR or BOR reset
+ *                   @arg RCM_FLAG_PINRST  : NRST PIN Reset Occur Flag
+ *                   @arg RCM_FLAG_PORRST  : POR/PDR Reset Occur Flag
+ *                   @arg RCM_FLAG_SWRST   : Software Reset Occur Flag
+ *                   @arg RCM_FLAG_IWDTRST : Independent Watchdog Reset Occur Flag
+ *                   @arg RCM_FLAG_WWDTRST : Window Watchdog Reset Occur Flag
+ *                   @arg RCM_FLAG_LPRRST  : Low Power Reset Occur Flag
+ *
+ * @retval    The new state of flag (SET or RESET)
+ */
+uint8_t RCM_ReadStatusFlag(RCM_FLAG_T flag)
+{
+    uint32_t reg, bit;
+
+    bit = (uint32_t)(1 << (flag & 0xff));
+
+    reg = (flag >> 8) & 0xff;
+
+    switch (reg)
+    {
+    case 0:
+        reg = RCM->CTRL;
+        break;
+
+    case 1:
+        reg = RCM->BDCTRL;
+        break;
+
+    case 2:
+        reg = RCM->CSTS;
+        break;
+
+    default:
+        break;
+    }
+
+    if (reg & bit)
+    {
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+ * @brief     Clears all the RCM reset flags
+ *
+ * @param     None
+ *
+ * @retval    None
+ *
+ * @note      The reset flags are:
+ *            RCM_FLAG_BORRST, RCM_FLAG_PINRST, RCM_FLAG_PWRST, RCM_FLAG_SWRST
+ *            RCM_FLAG_IWDTRST, RCM_FLAG_WWDTRST, RCM_FLAG_LPRRST
+ */
+void RCM_ClearStatusFlag(void)
+{
+    RCM->CSTS_B.RSTFLGCLR = BIT_SET;
+}
+
+/*!
+ * @brief     Reads the specified RCM interrupt Flag
+ *
+ * @param     flag : Reads specifies RCM interrupt flag.
+ *                   This parameter can be one of the following values:
+ *                   @arg RCM_INT_LSIRDY : LSI ready interrupt flag
+ *                   @arg RCM_INT_LSERDY : LSE ready interrupt flag
+ *                   @arg RCM_INT_HSIRDY : HSI ready interrupt flag
+ *                   @arg RCM_INT_HSERDY : HSE ready interrupt flag
+ *                   @arg RCM_INT_PLL1RDY: PLL1 ready interrupt flag
+ *                   @arg RCM_INT_PLL2RDY: PLL2 ready interrupt flag
+ *                   @arg RCM_INT_CSS    : Clock Security System interrupt flag
+ *
+ * @retval    The new state of intFlag (SET or RESET)
+ */
+uint8_t RCM_ReadIntFlag(RCM_INT_T flag)
+{
+    return (RCM->INT &flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the interrupt flag
+ *
+ * @param     flag : Clears specifies interrupt flag.
+ *                   @arg RCM_INT_LSIRDY : Clear LSI ready interrupt flag
+ *                   @arg RCM_INT_LSERDY : Clear LSE ready interrupt flag
+ *                   @arg RCM_INT_HSIRDY : Clear HSI ready interrupt flag
+ *                   @arg RCM_INT_HSERDY : Clear HSE ready interrupt flag
+ *                   @arg RCM_INT_PLL1RDY: Clear PLL1 ready interrupt flag
+ *                   @arg RCM_INT_PLL2RDY: Clear PLL2 ready interrupt flag
+ *                   @arg RCM_INT_CSS    : Clear Clock Security System interrupt flag
+ *
+ * @retval    None
+ */
+void RCM_ClearIntFlag(uint32_t flag)
+{
+    uint32_t temp;
+
+    temp = flag << 16;
+    RCM->INT |= temp;
+}
+
+/**@} end of group RCM_Functions */
+/**@} end of group RCM_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 195 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rng.c

@@ -0,0 +1,195 @@
+/*!
+ * @file        apm32f4xx_rng.c
+ *
+ * @brief       This file provides all the RNG firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_rng.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup RNG_Driver
+  * @brief RNG driver modules
+  @{
+*/
+
+/** @defgroup RNG_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset RNG peripheral registers to their default reset values.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RNG_Reset(void)
+{
+    RCM_EnableAHB2PeriphReset(RCM_AHB2_PERIPH_RNG);
+    RCM_DisableAHB2PeriphReset(RCM_AHB2_PERIPH_RNG);
+}
+
+/*!
+ * @brief     Enable the RNG peripheral.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RNG_Enable(void)
+{
+    RNG->CTRL_B.RNGEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the RNG peripheral.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RNG_Disable(void)
+{
+    RNG->CTRL_B.RNGEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Read the 32-bit random number.
+ *
+ * @param     None
+ *
+ * @retval    a 32-bit random number.
+ */
+uint32_t RNG_ReadRandomNumber(void)
+{
+    return RNG->DATA;
+}
+
+/*!
+ * @brief     Enable the RNG interrupt.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void EnableInterrupt(void)
+{
+    RNG->CTRL_B.INTEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the RNG interrupt.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void DisableInterrupt(void)
+{
+    RNG->CTRL_B.INTEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Read the specified RNG flag.
+ *
+ * @param     flag: specifies the RNG flag to check.
+ *                  This parameter can be one of the following values:
+ *                  @arg RNG_FLAG_DATARDY  : Data Ready flag.
+ *                  @arg RNG_FLAG_CLKERCSTS: RNG clock error flag.
+ *                  @arg RNG_FLAG_FSCSTS   : Faulty sequence flag.
+ *
+ * @retval    SET or RESET
+ */
+uint8_t RNG_ReadStatusFlag(RNG_FLAG_T flag)
+{
+    if ((RNG->STS & flag) != RESET)
+    {
+        return SET;
+    }
+    else
+    {
+        return RESET;
+    }
+}
+
+/*!
+ * @brief     Clears the RNG flags.
+ *
+ * @param     flag: specifies the flag to clear.
+ *                  This parameter can be any combination of the following values:
+ *                  @arg RNG_FLAG_CLKERCSTS: RNG clock error flag.
+ *                  @arg RNG_FLAG_FSCSTS   : Faulty sequence flag.
+ *
+ * @note      RNG_FLAG_DATARDY can not be cleared only by reading the Random data
+ *            (using RNG_ReadRandomNumber() function).
+ *
+ * @retval    None
+ */
+void RNG_ClearStatusFlag(uint8_t flag)
+{
+    RNG->STS = ~(uint32_t)(((uint32_t)flag) << 4);
+}
+
+/*!
+ * @brief     Read the specified RNG interrupt flag.
+ *
+ * @param     flag: check status of specifies the RNG interrupt source.
+ *                  This parameter can be one of the following values:
+ *                  @arg RNG_INT_FLAG_CLKERINT: RNGCLK Error Interrupt.
+ *                  @arg RNG_INT_FLAG_FSINT   : Faulty Sequence Interrupt.
+ *
+ * @retval    SET or RESET
+ */
+uint8_t RNG_ReadIntFlag(RNG_INT_FLAG_T flag)
+{
+    if ((RNG->STS & flag) != RESET)
+    {
+        return SET;
+    }
+    else
+    {
+        return RESET;
+    }
+}
+
+/*!
+ * @brief     Clears the RNG interrupt flags.
+ *
+ * @param     flag: clear flag specifies the RNG interrupt flag.
+ *                  This parameter can be any combination of the following values:
+ *                  @arg RNG_INT_FLAG_CLKERINT: RNGCLK Error Interrupt flag.
+ *                  @arg RNG_INT_FLAG_FSINT   : Faulty Sequence Interrupt flag.
+ *
+ * @retval    None
+ */
+void RNG_ClearIntFlag(uint8_t flag)
+{
+    RNG->STS = (uint8_t)~flag;
+}
+
+/**@} end of group RNG_Functions */
+/**@} end of group RNG_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 1899 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rtc.c

@@ -0,0 +1,1899 @@
+/*!
+ * @file        apm32f4xx_rtc.c
+ *
+ * @brief       This file provides all the RTC firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx.h"
+#include "apm32f4xx_rtc.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup RTC_Driver
+  * @brief RTC driver modules
+  @{
+*/
+
+/** @defgroup RTC_Macros Macros
+  @{
+*/
+
+/* RTC timeout definition */
+#define RTC_TIMEOUT_WAKE_UP        ((uint32_t)0x00010000)
+#define RTC_TIMEOUT_INIT           ((uint32_t)0x00010000)
+#define RTC_TIMEOUT_ALARM          ((uint32_t)0x00010000)
+#define RTC_TIMEOUT_CALIB          ((uint32_t)0x00020000)
+#define RTC_TIMEOUT_SYNCHRO        ((uint32_t)0x00020000)
+#define RTC_TIMEOUT_SHIFT          ((uint32_t)0x00001000)
+
+/**@} end of group RTC_Macros*/
+
+/** @defgroup RTC_Functions
+  @{
+*/
+
+static uint8_t RTC_ByteConBcd2(uint8_t val);
+static uint8_t RTC_Bcd2ConByte(uint8_t val);
+
+/*!
+ * @brief     Reset the RTC registers to their default values.
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_Reset(void)
+{
+    __IO uint32_t timeout = 0x00;
+
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+    else
+    {
+        /* Reset register */
+        RTC->TIME  = (uint32_t)0x00000000;
+        RTC->DATE  = (uint32_t)0x00002101;
+        RTC->CTRL &= (uint32_t)0x00000007;
+
+        /* Wait for wakeup timer write flag */
+        while ((RTC->STS_B.WUTWFLG != BIT_SET) && (timeout != RTC_TIMEOUT_WAKE_UP))
+        {
+            timeout++;
+        }
+
+        if (RTC->STS_B.WUTWFLG == BIT_RESET)
+        {
+            RTC_EnableWriteProtection();
+
+            return ERROR;
+        }
+        else
+        {
+            /* Reset register */
+            RTC->CTRL = (uint32_t)0x00000000;
+            RTC->AUTORLD = (uint32_t)0x0000FFFF;
+            RTC->PSC = (uint32_t)0x007F00FF;
+            RTC->DCAL = (uint32_t)0x00000000;
+            RTC->ALRMA = (uint32_t)0x00000000;
+            RTC->ALRMB = (uint32_t)0x00000000;
+            RTC->SHIFT = (uint32_t)0x00000000;
+            RTC->CAL = (uint32_t)0x00000000;
+            RTC->ALRMASS = (uint32_t)0x00000000;
+            RTC->ALRMBSS = (uint32_t)0x00000000;
+
+            RTC->STS = (uint32_t)0x00000000;
+
+            RTC->TACFG = (uint32_t)0x00000000;
+
+            if (RTC_WaitForSynchro() == ERROR)
+            {
+                RTC_EnableWriteProtection();
+
+                return ERROR;
+            }
+            else
+            {
+                RTC_EnableWriteProtection();
+
+                return SUCCESS;
+            }
+        }
+    }
+}
+
+/*!
+ * @brief     Deinitializes the RTC registers to their default reset values
+ *
+ * @param     rtcConfig : pointer to a RTC_Config_T structure which will be initialized
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_Config(RTC_Config_T *rtcConfig)
+{
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+    else
+    {
+        RTC->CTRL_B.TIMEFCFG  = (rtcConfig->format);
+        RTC->PSC_B.SPSC = (rtcConfig->synchPrediv);
+        RTC->PSC_B.APSC = (rtcConfig->asynchPrediv);
+
+        RTC_DisableInit();
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Fills each RTC_ConfigStruct member with its default value
+ *
+ * @param     rtcConfig : pointer to a RTC_Config_T structure which will be initialized
+ *
+ * @retval    None
+ */
+void RTC_ConfigStructInit(RTC_Config_T *rtcConfig)
+{
+    rtcConfig->format = RTC_HOURFORMAT_24;
+    rtcConfig->asynchPrediv = (uint32_t)0x7F;
+    rtcConfig->synchPrediv = (uint32_t)0xFF;
+}
+
+/*!
+ * @brief     Enable the write protection for RTC registers
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableWriteProtection(void)
+{
+    RTC->WRPROT = 0xFF;
+}
+
+/*!
+ * @brief     Disable the write protection for RTC registers
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisableWriteProtection(void)
+{
+    RTC->WRPROT = 0xCA;
+    RTC->WRPROT = 0x53;
+}
+
+/*!
+ * @brief     Enable the RTC Initialization mode.
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_EnableInit(void)
+{
+    __IO uint32_t timeout = 0x00;
+
+    if (RTC->STS_B.RINITFLG == BIT_RESET)
+    {
+        /* Enable initialization mode */
+        RTC->STS_B.INITEN = BIT_SET;
+
+        /* Wait for initialization flag */
+        while ((RTC->STS_B.RINITFLG != BIT_SET) && (timeout != RTC_TIMEOUT_INIT))
+        {
+            timeout++;
+        }
+
+        if (RTC->STS_B.RINITFLG != BIT_SET)
+        {
+            return ERROR;
+        }
+    }
+
+    return SUCCESS;
+}
+
+/*!
+ * @brief     Disable the RTC Initialization mode.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisableInit(void)
+{
+    RTC->STS_B.INITEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Waits until the RTC Time and Date registers are synchronized
+ *            with RTC APB clock
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_WaitForSynchro(void)
+{
+    __IO uint32_t timeout = 0;
+
+    RTC_DisableWriteProtection();
+
+    RTC->STS &= (uint32_t)0xFFFFFF5F;
+
+    /* Wait for synchrocnt flag */
+    while ((RTC->STS_B.RSFLG != BIT_SET) && (timeout != RTC_TIMEOUT_SYNCHRO))
+    {
+        timeout++;
+    }
+
+    if (RTC->STS_B.RSFLG != BIT_RESET)
+    {
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+    else
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+}
+
+/*!
+ * @brief     Enables the RTC reference clock detection.
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_EnableRefClock(void)
+{
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+    else
+    {
+        RTC->CTRL_B.RCLKDEN = BIT_SET;
+        RTC_DisableInit();
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Disable the RTC reference clock detection
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_DisableRefClock(void)
+{
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+    else
+    {
+        RTC->CTRL_B.RCLKDEN = BIT_RESET;
+        RTC_DisableInit();
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Enable the Bypass Shadow feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableBypassShadow(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.RCMCFG = BIT_SET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disable the Bypass Shadow feature.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisableBypassShadow(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.RCMCFG = BIT_RESET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Config the RTC current time
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_FORMAT_BIN : Format in Bin
+ *                    @arg RTC_FORMAT_BCD : Format in BCD
+ *
+ * @param     timeConfig: Pointer to a RTC_TimeConfig_T structure that
+ *                        contains the configuration information for the RTC peripheral
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_ConfigTime(RTC_FORMAT_T format, RTC_TimeConfig_T *timeConfig)
+{
+    uint8_t state = ERROR;
+    uint32_t temp = 0;
+
+    if (RTC->CTRL_B.TIMEFCFG == BIT_RESET)
+    {
+        timeConfig->h12 = RTC_H12_AM;
+    }
+
+    /* Combine parameters of time */
+    if (format != RTC_FORMAT_BIN)
+    {
+        temp = (((uint32_t)(timeConfig->hours) << 16) | \
+                ((uint32_t)(timeConfig->minutes) << 8) | \
+                ((uint32_t)(timeConfig->seconds)) | \
+                ((uint32_t)(timeConfig->h12) << 22));
+    }
+    else
+    {
+        temp = (uint32_t)(((uint32_t)RTC_ByteConBcd2(timeConfig->hours) << 16) | \
+                          ((uint32_t)RTC_ByteConBcd2(timeConfig->minutes) << 8) | \
+                          ((uint32_t)RTC_ByteConBcd2(timeConfig->seconds)) | \
+                          (((uint32_t)(timeConfig->h12) << 22)));
+    }
+
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        state = ERROR;
+    }
+    else
+    {
+        RTC->TIME = (uint32_t)(temp & 0x007F7F7F);
+
+        RTC_DisableInit();
+
+        if (RTC->CTRL_B.RCMCFG == RESET)
+        {
+            if (RTC_WaitForSynchro() == ERROR)
+            {
+                state = ERROR;
+            }
+            else
+            {
+                state = SUCCESS;
+            }
+        }
+        else
+        {
+            state = SUCCESS;
+        }
+    }
+
+    RTC_EnableWriteProtection();
+
+    return state;
+}
+
+/*!
+ * @brief     Fills each timeConfig member with its default value
+ *
+ * @param     timeConfig:  Pointer to a RTC_TimeConfig_T structure that
+ *                         contains the configuration information for the RTC peripheral
+ *
+ * @retval    None
+ */
+void RTC_ConfigTimeStructInit(RTC_TimeConfig_T *timeConfig)
+{
+    timeConfig->hours = 0;
+    timeConfig->minutes = 0;
+    timeConfig->seconds = 0;
+    timeConfig->h12 = RTC_H12_AM;
+}
+
+/*!
+ * @brief     Read the RTC current Time
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_FORMAT_BIN : format in Bin
+ *                    @arg RTC_FORMAT_BCD : format in BCD
+ *
+ * @param     time:  Pointer to a RTC_TimeConfig_T structure that
+ *                   contains the configuration information for the RTC peripheral
+ *
+ * @retval    None
+ */
+void RTC_ReadTime(RTC_FORMAT_T format, RTC_TimeConfig_T *time)
+{
+    uint32_t temp = 0;
+
+    temp = (uint32_t)((RTC->TIME) & 0x007F7F7F);
+
+    time->h12 = (RTC_H12_T)((temp & 0x00400000) >> 22);
+    time->hours   = (uint8_t)((temp & 0x003F0000) >> 16);
+    time->minutes = (uint8_t)((temp & 0x00007F00) >> 8);
+    time->seconds = (uint8_t)(temp & 0x0000007F);
+
+    if (format == RTC_FORMAT_BIN)
+    {
+        time->hours   = (uint8_t)RTC_Bcd2ConByte(time->hours);
+        time->minutes = (uint8_t)RTC_Bcd2ConByte(time->minutes);
+        time->seconds = (uint8_t)RTC_Bcd2ConByte(time->seconds);
+    }
+}
+
+/*!
+ * @brief     Read the RTC current Calendar Subseconds value
+ *
+ * @param     None
+ *
+ * @retval    RTC current Calendar Subseconds value
+ */
+uint32_t RTC_ReadSubSecond(void)
+{
+    uint32_t temp = 0;
+
+    temp = (uint32_t)(RTC->SUBSEC);
+    (void)(RTC->DATE);
+
+    return temp;
+}
+
+/*!
+ * @brief     Config the RTC current time
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_FORMAT_BIN : format in Bin
+ *                    @arg RTC_FORMAT_BCD : format in BCD
+ *
+ * @param     dateConfig:  Pointer to a RTC_DateConfig_T structure that
+ *                         contains the configuration DATE information for the RTC peripheral
+ *
+ * @retval    None
+ */
+uint8_t RTC_ConfigDate(RTC_FORMAT_T format, RTC_DateConfig_T *dateConfig)
+{
+    uint8_t state = ERROR;
+    uint32_t temp = 0;
+
+    if ((format == RTC_FORMAT_BIN) && ((dateConfig->month & 0x10) == 0x10))
+    {
+        dateConfig->month = (RTC_MONTH_T)((dateConfig->month & (uint32_t)~(0x10)) + 0x0A);
+    }
+
+    if (format != RTC_FORMAT_BIN)
+    {
+        temp = (((uint32_t)(dateConfig->year) << 16) | \
+                ((uint32_t)(dateConfig->month) << 8) | \
+                ((uint32_t)(dateConfig->date)) | \
+                ((uint32_t)(dateConfig->weekday) << 13));
+    }
+    else
+    {
+        temp = (((uint32_t)RTC_ByteConBcd2(dateConfig->year) << 16) | \
+                ((uint32_t)RTC_ByteConBcd2(dateConfig->month) << 8) | \
+                ((uint32_t)RTC_ByteConBcd2(dateConfig->date)) | \
+                ((uint32_t)(dateConfig->weekday) << 13));
+    }
+
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        state = ERROR;
+    }
+    else
+    {
+        RTC->DATE = (uint32_t)(temp & 0x00FFFF3F);
+        RTC_DisableInit();
+
+        if (RTC->CTRL_B.RCMCFG == RESET)
+        {
+            if (RTC_WaitForSynchro() == ERROR)
+            {
+                state = ERROR;
+            }
+            else
+            {
+                state = SUCCESS;
+            }
+        }
+        else
+        {
+            state = SUCCESS;
+        }
+    }
+
+    RTC_EnableWriteProtection();
+    return state;
+}
+
+/*!
+ * @brief     Fills each dateConfig member with its default value
+ *
+ * @param     dateConfig: Pointer to a RTC_DateConfig_T structure that contains
+ *                        the configuration DATE information for the RTC peripheral
+ *
+ * @retval    None
+ */
+void RTC_ConfigDateStructInit(RTC_DateConfig_T *dateConfig)
+{
+    dateConfig->weekday = RTC_WEEKDAY_MONDAY;
+    dateConfig->month = RTC_MONTH_JANUARY;
+    dateConfig->date = 0x01;
+    dateConfig->year = 0x00;
+}
+
+/*!
+ * @brief     Read the RTC current date
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_FORMAT_BIN : format in Bin
+ *                    @arg RTC_FORMAT_BCD : format in BCD
+ *
+ * @param     date: Pointer to a RTC_DateConfig_T structure that contains the
+ *                  configuration DATE information for the RTC peripheral.
+ *
+ * @retval    None
+ */
+void RTC_ReadDate(RTC_FORMAT_T format, RTC_DateConfig_T *date)
+{
+    uint32_t temp = 0;
+    temp = (uint32_t)((RTC->DATE) & 0x00FFFF3F);
+
+    date->year  = (uint8_t)((temp & 0x00FF0000) >> 16);
+    date->month = (RTC_MONTH_T)((temp & 0x00001F00) >> 8);
+    date->date  = (uint8_t)(temp &  0x0000003F);
+    date->weekday = (RTC_WEEKDAY_T)((temp & 0x0000E000) >> 13);
+
+    if (format == RTC_FORMAT_BIN)
+    {
+        date->year  = (uint8_t)RTC_Bcd2ConByte(date->year);
+        date->month = (RTC_MONTH_T)RTC_Bcd2ConByte(date->month);
+        date->date  = (uint8_t)RTC_Bcd2ConByte(date->date);
+        date->weekday = (RTC_WEEKDAY_T)(date->weekday);
+    }
+}
+
+/*!
+ * @brief    Config the specified RTC alarm
+ *
+ * @param    format: specifies the format to write
+ *                   This parameter can be one of the following values:
+ *                   @arg RTC_FORMAT_BIN : format in Bin
+ *                   @arg RTC_FORMAT_BCD : format in BCD
+ *
+ * @param    alarm: specifies the format to write
+ *                  This parameter can be one of the following values:
+ *                  @arg RTC_ALARM_A : to select Alarm A
+ *                  @arg RTC_ALARM_B : to select Alarm B
+ *
+ * @param    alarmConfig: Pointer to a RTC_AlarmConfig_T structure that
+ *                        contains the configuration ALRMA information for the RTC peripheral
+ *
+ * @retva    None
+ */
+void RTC_ConfigAlarm(RTC_FORMAT_T format, RTC_ALARM_T alarm, RTC_AlarmConfig_T *alarmConfig)
+{
+    uint32_t temp = 0;
+
+    if (RTC->CTRL_B.TIMEFCFG == BIT_RESET)
+    {
+        alarmConfig->time.h12 = RTC_H12_AM;
+    }
+
+    if (format == RTC_FORMAT_BCD)
+    {
+        temp = (((uint32_t)(alarmConfig->time.hours) << 16) | \
+                ((uint32_t)(alarmConfig->time.minutes) << 8) | \
+                ((uint32_t)alarmConfig->time.seconds) | \
+                ((uint32_t)(alarmConfig->time.h12) << 22) | \
+                ((uint32_t)(alarmConfig->alarmDateWeekDay) << 24) | \
+                ((uint32_t)alarmConfig->alarmDateWeekDaySel << 30) | \
+                ((uint32_t)alarmConfig->alarmMask));
+    }
+    else
+    {
+        temp = (((uint32_t)RTC_ByteConBcd2(alarmConfig->time.hours) << 16) | \
+                ((uint32_t)RTC_ByteConBcd2(alarmConfig->time.minutes) << 8) | \
+                ((uint32_t)RTC_ByteConBcd2(alarmConfig->time.seconds)) | \
+                ((uint32_t)(alarmConfig->time.h12) << 22) | \
+                ((uint32_t)RTC_ByteConBcd2(alarmConfig->alarmDateWeekDay) << 24) | \
+                ((uint32_t)alarmConfig->alarmDateWeekDaySel << 30) | \
+                ((uint32_t)alarmConfig->alarmMask));
+    }
+
+    RTC_DisableWriteProtection();
+
+    if (alarm == RTC_ALARM_A)
+    {
+        RTC->ALRMA = temp;
+    }
+    else
+    {
+        RTC->ALRMB = temp;
+    }
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Fills each alarmConfig member with its default value.
+ *
+ * @param     alarmConfig: Pointer to a RTC_AlarmConfig_T structure that
+ *                         contains the configuration ALRMA information for the RTC peripheral
+ *
+ * @retval    None
+ */
+void RTC_ConfigAlarmStructInit(RTC_AlarmConfig_T *alarmConfig)
+{
+    alarmConfig->time.hours = 0;
+    alarmConfig->time.minutes = 0;
+    alarmConfig->time.seconds = 0;
+    alarmConfig->time.h12 = RTC_H12_AM;
+    alarmConfig->alarmDateWeekDay = 1;
+    alarmConfig->alarmDateWeekDaySel = RTC_WEEKDAY_SEL_DATE;
+    alarmConfig->alarmMask = RTC_MASK_NONE;
+}
+
+/*!
+ * @brief     Read the RTC alarm value.
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_FORMAT_BIN : format in Bin
+ *                    @arg RTC_FORMAT_BCD : format in BCD
+ *
+ * @param     alarm: specifies the format to write
+ *                   This parameter can be one of the following values:
+ *                   @arg RTC_ALARM_A : to select Alarm A
+ *                   @arg RTC_ALARM_B : to select Alarm B
+ *
+ * @param     alarmConfig: Pointer to a RTC_AlarmConfig_T structure that contains
+ *                         the configuration ALRMA information for the RTC peripheral
+ *
+ * @retval    None
+ */
+void RTC_ReadAlarm(RTC_FORMAT_T format, RTC_ALARM_T alarm, RTC_AlarmConfig_T *alarmConfig)
+{
+    uint8_t day_d, day_u, hours_d, hours_u, minutes_d, minutes_u, seconds_d, seconds_u;
+    uint32_t day_mask, hours_mask, minutes_mask, seconds_mask;
+
+    if (alarm == RTC_ALARM_A)
+    {
+        day_d = RTC->ALRMA_B.DAYT << 0x04;
+        day_u = RTC->ALRMA_B.DAYU;
+        hours_d = RTC->ALRMA_B.HRT << 0x04;
+        hours_u = RTC->ALRMA_B.HRU;
+        minutes_d = RTC->ALRMA_B.MINT << 0x04;
+        minutes_u = RTC->ALRMA_B.MINU;
+        seconds_d = RTC->ALRMA_B.SECT << 0x04;
+        seconds_u = RTC->ALRMA_B.SECU;
+
+        day_mask = RTC->ALRMA_B.DATEMEN << 8;
+        hours_mask = RTC->ALRMA_B.HRMEN << 8;
+        minutes_mask = RTC->ALRMA_B.MINMEN << 8;
+        seconds_mask = RTC->ALRMA_B.SECMEN << 7;
+
+        alarmConfig->time.hours   = (uint8_t)(hours_d | hours_u);
+        alarmConfig->time.minutes = (uint8_t)(minutes_d | minutes_u);
+        alarmConfig->time.seconds = (uint8_t)(seconds_d | seconds_u);
+        alarmConfig->time.h12     = (RTC_H12_T)(RTC->ALRMA_B.TIMEFCFG);
+        alarmConfig->alarmDateWeekDay = (uint8_t)(day_d | day_u);
+        alarmConfig->alarmDateWeekDaySel = (RTC_WEEKDAY_SEL_T)(RTC->ALRMA_B.WEEKSEL);
+        alarmConfig->alarmMask = (uint32_t)(day_mask | hours_mask | minutes_mask | seconds_mask);
+    }
+    else
+    {
+        day_d = RTC->ALRMB_B.DAYT << 0x04;
+        day_u = RTC->ALRMB_B.DAYU;
+        hours_d = RTC->ALRMB_B.HRT << 0x04;
+        hours_u = RTC->ALRMB_B.HRU;
+        minutes_d = RTC->ALRMB_B.MINT << 0x04;
+        minutes_u = RTC->ALRMB_B.MINU;
+        seconds_d = RTC->ALRMB_B.SECT << 0x04;
+        seconds_u = RTC->ALRMB_B.SECU;
+
+        day_mask = RTC->ALRMB_B.DATEMEN << 8;
+        hours_mask = RTC->ALRMB_B.HRMEN << 8;
+        minutes_mask = RTC->ALRMB_B.MINMEN << 8;
+        seconds_mask = RTC->ALRMB_B.SECMEN << 7;
+
+        alarmConfig->time.hours   = (uint8_t)(hours_d | hours_u);
+        alarmConfig->time.minutes = (uint8_t)(minutes_d | minutes_u);
+        alarmConfig->time.seconds = (uint8_t)(seconds_d | seconds_u);
+        alarmConfig->time.h12     = (RTC_H12_T)(RTC->ALRMB_B.TIMEFCFG);
+        alarmConfig->alarmDateWeekDay = (uint8_t)(day_d | day_u);
+        alarmConfig->alarmDateWeekDaySel = (RTC_WEEKDAY_SEL_T)(RTC->ALRMB_B.WEEKSEL);
+        alarmConfig->alarmMask = (uint32_t)(day_mask | hours_mask | minutes_mask | seconds_mask);
+    }
+
+    if (format == RTC_FORMAT_BIN)
+    {
+        alarmConfig->time.hours = (uint8_t)RTC_Bcd2ConByte(alarmConfig->time.hours);
+        alarmConfig->time.minutes = (uint8_t)RTC_Bcd2ConByte(alarmConfig->time.minutes);
+        alarmConfig->time.seconds = (uint8_t)RTC_Bcd2ConByte(alarmConfig->time.seconds);
+        alarmConfig->alarmDateWeekDay = (uint8_t)RTC_Bcd2ConByte(alarmConfig->alarmDateWeekDay);
+    }
+}
+
+/*!
+ * @brief     Enable the RTC Alarm A.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableAlarmA(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.ALRAEN = BIT_SET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disable the the RTC Alarm A.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+uint8_t RTC_DisableAlarmA(void)
+{
+    __IO uint32_t timeout = 0x00;
+
+    RTC_DisableWriteProtection();
+    RTC->CTRL_B.ALRAEN = BIT_RESET;
+
+    /* wait for Alarm A write flag */
+    while (((RTC->STS_B.ALRAWFLG) != BIT_SET) && (timeout != RTC_TIMEOUT_ALARM))
+    {
+        timeout++;
+    }
+
+    if ((RTC->STS_B.ALRAWFLG) == BIT_RESET)
+    {
+        RTC_EnableWriteProtection();
+        return ERROR;
+    }
+    else
+    {
+        RTC_EnableWriteProtection();
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Enable the RTC Alarm B.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableAlarmB(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.ALRBEN = BIT_SET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disable the the RTC Alarm B.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+uint8_t RTC_DisableAlarmB(void)
+{
+    __IO uint32_t timeout = 0x00;
+
+    RTC_DisableWriteProtection();
+    RTC->CTRL_B.ALRBEN = BIT_RESET;
+
+    /* wait for Alarm B write flag */
+    while (((RTC->STS_B.ALRBWFLG) != BIT_SET) && (timeout != RTC_TIMEOUT_ALARM))
+    {
+        timeout++;
+    }
+
+    if ((RTC->STS_B.ALRBWFLG) == BIT_RESET)
+    {
+        RTC_EnableWriteProtection();
+        return ERROR;
+    }
+    else
+    {
+        RTC_EnableWriteProtection();
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Read the RTC ALRMA Subseconds value
+ *
+ * @param     val: specifies the value for ALRMA Sub Second
+ *                 this value must less than 0x00007FFF
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_ALARM_A : to select Alarm A
+ *                    @arg RTC_ALARM_B : to select Alarm B
+ *
+ * @param     mask: specifies the mask for ALRMA Sub Second.
+ *                  This parameter can be one of the following values:
+ *                  @arg RTC_ALARM_SUBSEC_MASK_ALL   : All Alarm SUBSEC fields are masked.
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_1  : Mask SUBSEC[14:1]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_2  : Mask SUBSEC[14:2]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_3  : Mask SUBSEC[14:3]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_4  : Mask SUBSEC[14:4]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_5  : Mask SUBSEC[14:5]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_6  : Mask SUBSEC[14:6]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_7  : Mask SUBSEC[14:7]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_8  : Mask SUBSEC[14:8]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_9  : Mask SUBSEC[14:9]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_10 : Mask SUBSEC[14:10]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_11 : Mask SUBSEC[14:11]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_12 : Mask SUBSEC[14:12]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14_13 : Mask SUBSEC[14:13]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_14    : Mask SUBSEC[14]
+ *                  @arg RTC_ALARM_SUBSEC_MASK_NONE  : Alarm comparison is all the SUBSEC bit.
+ *
+ *                  this value must less than 0x0f
+ *
+ * @retval    None
+ */
+void RTC_ConfigAlarmSubSecond(RTC_ALARM_T alarm, uint32_t val, RTC_ALARM_SUBSEC_MASK_T mask)
+{
+    RTC_DisableWriteProtection();
+
+    if (alarm == RTC_ALARM_A)
+    {
+        RTC->ALRMASS_B.SUBSEC  = val;
+        RTC->ALRMASS_B.MASKSEL = mask;
+    }
+    else
+    {
+        RTC->ALRMBSS_B.SUBSEC  = val;
+        RTC->ALRMBSS_B.MASKSEL = mask;
+    }
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Read the RTC Alarm Subseconds value
+ *
+ * @param     format: specifies the format to write
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_ALARM_A : select Alarm A
+ *                    @arg RTC_ALARM_B : select Alarm B
+ *
+ * @retval    RTC ALRM Subseconds value
+ */
+uint16_t RTC_ReadAlarmSubSecond(RTC_ALARM_T alarm)
+{
+    if (alarm == RTC_ALARM_A)
+    {
+        return (uint16_t)(RTC->ALRMASS_B.SUBSEC);
+    }
+    else
+    {
+        return (uint16_t)(RTC->ALRMBSS_B.SUBSEC);
+    }
+}
+
+/*!
+ * @brief     Configure the RTC Wakeup clock source.
+ *
+ * @param     wakeUpClock: specifies the Wakeup Clock source.
+ *                         This parameter can be one of the following values:
+ *                         @arg RTC_WAKEUP_CLOCK_RTC_DIV16   : Wakeup Clock Select to RTC/16
+ *                         @arg RTC_WAKEUP_CLOCK_RTC_DIV8    : Wakeup Clock Select to RTC/8
+ *                         @arg RTC_WAKEUP_CLOCK_RTC_DIV4    : Wakeup Clock Select to RTC/4
+ *                         @arg RTC_WAKEUP_CLOCK_RTC_DIV2    : Wakeup Clock Select to RTC/2
+ *                         @arg RTC_WAKEUP_CLOCK_CK_SPRE_16B : Wakeup Clock Select to clk_spre
+ *                         @arg RTC_WAKEUP_CLOCK_CK_SPRE_17B : Wakeup Clock Select to clk_spre
+ *
+ * @retval    None
+ */
+void RTC_ConfigWakeUpClock(RTC_WAKEUP_CLOCK_T wakeUpClock)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.WUCLKSEL = wakeUpClock;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Configure the RTC Wakeup counter value.
+ *
+ * @param     wakeUpValue: a 16-bit Wakeup auto-reload value.
+ *
+ * @retval    None
+ */
+void RTC_ConfigWakeUpValue(uint16_t wakeUpValue)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->AUTORLD = (uint32_t)wakeUpValue;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Read the RTC Wakeup auto-reload value.
+ *
+ * @param     None
+ *
+ * @retval    The RTC WakeUp auto-reload value.
+ */
+uint16_t RTC_ReadWakeUpValue(void)
+{
+    return (uint16_t)RTC->AUTORLD;
+}
+
+/*!
+ * @brief     Enable the RTC WakeUp timer.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableWakeUp(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.WUTEN = BIT_SET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disable the RTC WakeUp timer.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+uint8_t RTC_DisableWakeUp(void)
+{
+    __IO uint32_t timeout = 0x00;
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.WUTEN = BIT_RESET;
+
+    /* wait for wakeup timer write flag */
+    while (((RTC->STS_B.WUTWFLG) == BIT_RESET) && (timeout != RTC_TIMEOUT_WAKE_UP))
+    {
+        timeout++;
+    }
+
+    if ((RTC->STS_B.WUTWFLG) == BIT_RESET)
+    {
+        RTC_EnableWriteProtection();
+        return ERROR;
+    }
+    else
+    {
+        RTC_EnableWriteProtection();
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Adds or substract one hour from the current time
+ *
+ * @param     saving: specifies the DayLight Saving.
+ *                 This parameter can be one of the following values:
+ *                 @arg RTC_DLS_SUB_1H : Winter time change
+ *                 @arg RTC_DLS_ADD_1H : Summer time change
+ *
+ * @param     bit: set the Backup Value.
+ *                 This parameter can be one of the following values:
+ *                 @arg RTC_BACKUP_RESET : Reset backup value
+ *                 @arg RTC_BACKUP_SET   : Set backup value
+ *
+ * @retval    None
+ */
+void RTC_ConfigDayLightSaving(RTC_DLS_T saving, RTC_BACKUP_T bit)
+{
+    RTC_DisableWriteProtection();
+
+    if (saving == RTC_DLS_ADD_1H)
+    {
+        RTC->CTRL_B.STCCFG = BIT_SET;
+    }
+    else
+    {
+        RTC->CTRL_B.WTCCFG = BIT_SET;
+    }
+
+    /* Backup Value Setup */
+    RTC->CTRL_B.BAKP = bit;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Returns the RTC Day Light Saving stored operation
+ *
+ * @param     None
+ *
+ * @retval    RTC Day Light Saving backup stored operation
+ */
+uint8_t RTC_ReadStoreOperation(void)
+{
+    return (uint8_t)RTC->CTRL_B.BAKP;
+}
+
+/*!
+ * @brief     Config the RTC alarm Output Way and output polarity.
+ *
+ * @param     outputSel: specifies RTC alarm Output Way.
+ *                       This parameter can be one of the following values:
+ *                       @arg RTC_OUT_SEL_DISABLE : Disable RTC output
+ *                       @arg RTC_OUT_SEL_ALARM_A : Select alarm A as RTC output
+ *                       @arg RTC_OUT_SEL_ALARM_B : Select alarm B as RTC output
+ *                       @arg RTC_OUT_SEL_WAKEUP: : Select wake up as RTC output
+ *
+ * @param     polarity: specified the output polarity.
+ *                      This parameter can be one of the following values:
+ *                      @arg RTC_OUT_POLARITY_HIGH : The output polarity is high
+ *                      @arg RTC_OUT_POLARITY_LOW  : The output polarity is low
+ *
+ * @retval    None
+ */
+void RTC_ConfigOutput(RTC_OUT_SEL_T outputSel, RTC_OUT_POLARITY_T polarity)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.OUTSEL = outputSel;
+    RTC->CTRL_B.POLCFG = polarity;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Config RTC Coarse calibration.
+ *
+ * @param     calibSign: specifies the sign of the coarse calibration value.
+ *                       This parameter can be  one of the following values:
+ *                       @arg RTC_CALIB_SIGN_POSITIVE : The Calibration sign is positive
+ *                       @arg RTC_CALIB_SIGN_NEGATIVE : The Calibration sign is negative
+ *
+ * @param     value: a 5-bit value of coarse calibration expressed in ppm.
+ *
+ * @note      For positive sign, the Calibration value could be between 0 and 126
+ *            with a 4-ppm step.
+ *
+ * @note      For negative sign, the Calibration value could be between 0 and 63
+ *            with a 2-ppm step.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_ConfigCoarseCalib(RTC_CALIB_SIGN_T calibSign, uint32_t value)
+{
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+        return ERROR;
+    }
+    else
+    {
+        RTC->DCAL_B.DCALCFG = calibSign;
+        RTC->DCAL_B.DCAL    = value;
+
+        RTC_DisableInit();
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Enables the Coarse calibration.
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_EnableCoarseCalib(void)
+{
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+    else
+    {
+        RTC->CTRL_B.DCALEN = BIT_SET;
+
+        RTC_DisableInit();
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Disables the Coarse calibration.
+ *
+ * @param     None
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_DisableCoarseCalib(void)
+{
+    RTC_DisableWriteProtection();
+
+    if (RTC_EnableInit() == ERROR)
+    {
+        RTC_EnableWriteProtection();
+
+        return ERROR;
+    }
+    else
+    {
+        RTC->CTRL_B.DCALEN = BIT_RESET;
+
+        RTC_DisableInit();
+        RTC_EnableWriteProtection();
+
+        return SUCCESS;
+    }
+}
+
+/*!
+ * @brief     Enable the RTC clock Calibration Output.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableCalibOutput(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.CALOEN = BIT_SET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disable the RTC clock Calibration Output.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisableCalibOutput(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.CALOEN = BIT_RESET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Config the Calibration output.
+ *
+ * @param     calib: Select the Calibration output.
+ *                   This parameter can be one of the following values:
+ *                   @arg RTC_CALIB_OUTPUT_512HZ : Calibration output is 512 Hz
+ *                   @arg RTC_CALIB_OUTPUT_1HZ   : Calibration output is 1 Hz
+ *
+ * @retval    None
+ */
+void RTC_ConfigCalibOutput(RTC_CALIB_OUTPUT_T calib)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.CALOSEL = calib;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Config the Synchronization Shift Control Settings.
+ *
+ * @param     period: Select the Smooth Calibration period.
+ *                    This parameter can be can be one of the following values:
+ *                    @arg RTC_SCP_32SEC : The smooth calibration periode is 32s.
+ *                    @arg RTC_SCP_16SEC : The smooth calibration periode is 16s.
+ *                    @arg RTC_SCP_8SEC  : The smooth calibartion periode is 8s.
+ *
+ * @param     calibPulse: Select to Set or reset the CALP bit.
+ *                        This parameter can be one of the following values:
+ *                        @arg RTC_SCPP_RESET : Add one RTCCLK puls every 2**11 pulses.
+ *                        @arg RTC_SCPP_SET   : No RTCCLK pulses are added.
+ *
+ * @param     value: a 9-bits value to Config RECALF[8:0].
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_ConfigSmoothCalib(RTC_SCP_T period, RTC_SCPP_T calibPulse, uint16_t value)
+{
+    uint8_t state = ERROR;
+    uint32_t timeout = 0;
+
+    RTC_DisableWriteProtection();
+
+    /* wait for Recalibration flag to be cleared */
+    while ((RTC->STS_B.RCALPFLG != BIT_RESET) && (timeout != RTC_TIMEOUT_CALIB))
+    {
+        timeout++;
+    }
+
+    if (RTC->STS_B.RCALPFLG != BIT_SET)
+    {
+        RTC->CAL = ((uint32_t)calibPulse << 15) | ((uint32_t)period << 13) |
+                   (uint32_t)(value & 0x01FF);
+
+        state = SUCCESS;
+    }
+    else
+    {
+        state = ERROR;
+    }
+
+    RTC_EnableWriteProtection();
+
+    return state;
+}
+
+/*!
+ * @brief     Enables the RTC TimeStamp functionality and config the Timestamp event
+ *            active edge.
+ *
+ * @param     edge: Specifies the Timestamp event active edge.
+ *                  This paramete can be one of the following:
+ *                  @arg RTC_TIMESTAMP_EDGE_RISING  : Rising edge generates a timestamp event.
+ *                  @arg RTC_TIMESTAMP_EDGE_FALLING : Falling edge generates a timestamp event
+ *
+ * @retval    None
+ */
+void RTC_EnableTimeStamp(RTC_TIMESTAMP_EDGE_T edge)
+{
+    RTC_DisableWriteProtection();
+
+    /* Disable Timestamp when change the edge */
+    RTC->CTRL_B.TSEN = BIT_RESET;
+
+    RTC->CTRL_B.TSETECFG = edge;
+    RTC->CTRL_B.TSEN = BIT_SET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disables the RTC TimeStamp functionality.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisableTimeStamp(void)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL_B.TSEN = BIT_RESET;
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Read the RTC TimeStamp value and masks
+ *
+ * @param     format: specifies the format of the output parameters.
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_FORMAT_BIN : data in Binary format
+ *                    @arg RTC_FORMAT_BCD : data in BCD format
+ *
+ * @param     time: pointer to a RTC_TimeConfig_T structure that will
+ *                  contains the TimeStamp time values.
+ *
+ * @param     date: pointer to a RTC_DateConfig_T structure that will
+ *                  contains the TimeStamp date values.
+ *
+ * @retval    None
+ */
+void RTC_ReadTimeDate(RTC_FORMAT_T format, RTC_TimeConfig_T *time, RTC_DateConfig_T *date)
+{
+    uint32_t temptime = 0, tempdate = 0;
+    temptime = (uint32_t)((RTC->TSTIME) & 0x007F7F7F);
+    tempdate = (uint32_t)((RTC->TSDATE) & 0x00FFFF3F);
+
+    /* Read the time in BCD format */
+    time->hours   = (uint8_t)((temptime & 0x003F0000) >> 16);
+    time->minutes = (uint8_t)((temptime & 0x00007F00) >> 8);
+    time->seconds = (uint8_t)(temptime &  0x0000007F);
+    time->h12 = (RTC_H12_T)((temptime & 0x00400000) >> 22);
+
+    /* Read the date in BCD format */
+    date->year  =  0;
+    date->month = (RTC_MONTH_T)((tempdate & 0x00001F00) >> 8);
+    date->date  = (uint8_t)(tempdate &  0x0000003F);
+    date->weekday = (RTC_WEEKDAY_T)((tempdate & 0x0000E000) >> 13);
+
+    /* Binary format */
+    if (format == RTC_FORMAT_BIN)
+    {
+        time->hours   = (uint8_t)RTC_Bcd2ConByte(time->hours);
+        time->minutes = (uint8_t)RTC_Bcd2ConByte(time->minutes);
+        time->seconds = (uint8_t)RTC_Bcd2ConByte(time->seconds);
+
+        date->month = (RTC_MONTH_T)RTC_Bcd2ConByte(date->month);
+        date->date  = (uint8_t)RTC_Bcd2ConByte(date->date);
+        date->weekday = (RTC_WEEKDAY_T)(date->weekday);
+    }
+}
+
+/*!
+ * @brief     Get the RTC timestamp Subseconds value
+ *
+ * @param     None
+ *
+ * @retval    RTC current timestamp Subseconds value
+ */
+uint16_t RTC_ReadTimeStampSubSecond(void)
+{
+    return RTC->TSSUBSEC_B.SUBSEC;
+}
+
+/*!
+ * @brief     Config the select Tamper pin edge
+ *
+ * @param     tamper:  Selected tamper pin.
+ *                     This parameter can be one of the following values:
+ *                     @arg RTC_TAMPER_1 : Select Tamper 1.
+ *                     @arg RTC_TAMPER_2 : Select Tamper 2.
+ *
+ * @param     trigger: Specifies the trigger on the tamper pin that stimulates tamper event.
+ *                     This parameter can be one of the following values:
+ *                     @arg RTC_TAMPER_TRIGGER_EDGE_RISING  : Rising Edge of the tamper pin causes tamper event.
+ *                     @arg RTC_TAMPER_TRIGGER_EDGE_FALLING : Falling Edge of the tamper pin causes tamper event.
+ *                     @arg RTC_TAMPER_TRIGGER_LEVEL_LOW    : Low Level of the tamper pin causes tamper event.
+ *                     @arg RTC_TAMPER_TRIGGER_LEVEL_HIGH   : High Level of the tamper pin causes tamper event.
+ *
+ * @retval    None
+ */
+void RTC_ConfigTamperTrigger(RTC_TAMPER_T tamper, RTC_TAMPER_TRIGGER_T trigger)
+{
+    if (tamper == RTC_TAMPER_1)
+    {
+        RTC->TACFG_B.TP1ALCFG = trigger;
+    }
+    else
+    {
+        RTC->TACFG_B.TP2ALCFG = trigger;
+    }
+}
+
+/*!
+ * @brief     Enables the Tamper detection
+ *
+ * @param     tamper: Selected tamper pin.
+ *                    This parameter can be one of the following values:
+ *                    @arg RTC_TAMPER_1 : Select Tamper 1.
+ *                    @arg RTC_TAMPER_2 : Select Tamper 2.
+ *
+ * @retval    None
+ */
+void RTC_EnableTamper(RTC_TAMPER_T tamper)
+{
+    if (tamper == RTC_TAMPER_1)
+    {
+        RTC->TACFG_B.TP1EN = BIT_SET;
+    }
+    else
+    {
+        RTC->TACFG_B.TP2EN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disables the Tamper detection
+ *
+ * @param     tamper: Selected tamper pin.
+ *                    This parameter can be any combination of the following values:
+ *                    @arg RTC_TAMPER_1 : Select Tamper 1.
+ *                    @arg RTC_TAMPER_2 : Select Tamper 2.
+ *
+ * @retval    None
+ */
+void RTC_DisableTamper(RTC_TAMPER_T tamper)
+{
+    if (tamper == RTC_TAMPER_1)
+    {
+        RTC->TACFG_B.TP1EN = BIT_RESET;
+    }
+    else
+    {
+        RTC->TACFG_B.TP2EN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Config the Tampers Filter
+ *
+ * @param    filter: Specifies the tampers filter.
+ *                   This parameter can be one of the following values:
+ *                   @arg RTC_TAMPER_FILTER_DISABLE : Tamper filter is disabled.
+ *                   @arg RTC_TAMPER_FILTER_2SAMPLE : Tamper is activated after 2 consecutive samples at the active level
+ *                   @arg RTC_TAMPER_FILTER_4SAMPLE : Tamper is activated after 4 consecutive samples at the active level
+ *                   @arg RTC_TAMPER_FILTER_8SAMPLE : Tamper is activated after 8 consecutive samples at the active level
+ *
+ * @retval    None
+ */
+void RTC_ConfigFilter(RTC_TAMPER_FILTER_T filter)
+{
+    RTC->TACFG_B.TPFCSEL = filter;
+
+}
+
+/*!
+ * @brief     Config the Tampers Sampling Frequency
+ *
+ * @param     freq: Specifies the tampers Sampling Frequency.
+ *                  This parameter can be one of the following values:
+ *                  @arg RTC_TSF_DIV_32768 : Tampers Sampling Frequency = RTC_CLK/32768
+ *                  @arg RTC_TSF_DIV_16384 : Tampers Sampling Frequency = RTC_CLK/16384
+ *                  @arg RTC_TSF_DIV_8192  : Tampers Sampling Frequency = RTC_CLK/8192
+ *                  @arg RTC_TSF_DIV_4096  : Tampers Sampling Frequency = RTC_CLK/4096
+ *                  @arg RTC_TSF_DIV_2048  : Tampers Sampling Frequency = RTC_CLK/2048
+ *                  @arg RTC_TSF_DIV_1024  : Tampers Sampling Frequency = RTC_CLK/1024
+ *                  @arg RTC_TSF_DIV_512   : Tampers Sampling Frequency = RTC_CLK/512
+ *                  @arg RTC_TSF_DIV_256   : Tampers Sampling Frequency = RTC_CLK/256
+ *
+ * @retval    None
+ */
+void RTC_ConfigSamplingFreq(RTC_TSF_DIV_T freq)
+{
+    RTC->TACFG_B.TPSFSEL = freq;
+}
+
+/*!
+ * @brief     Config the Precharge Duration.
+ *
+ * @param     duration: Specifies the Tampers Pins input  Precharge Duration.
+ *                  This parameter can be one of the following values:
+ *                  @arg RTC_TPD_RTCCLK_1 : Tamper pins are pre-charged before sampling during 1 RTCCLK cycle.
+ *                  @arg RTC_TPD_RTCCLK_2 : Tamper pins are pre-charged before sampling during 2 RTCCLK cycle.
+ *                  @arg RTC_TPD_RTCCLK_4 : Tamper pins are pre-charged before sampling during 4 RTCCLK cycle.
+ *                  @arg RTC_TPD_RTCCLK_8 : Tamper pins are pre-charged before sampling during 8 RTCCLK cycle.
+ *
+ * @retval    None
+ */
+void RTC_PinsPrechargeDuration(RTC_TPD_RTCCLK_T duration)
+{
+    RTC->TACFG_B.TPPRDUSEL = duration;
+}
+
+/*!
+ * @brief     Enables the TimeStamp on Tamper Detection Event
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnableTDE(void)
+{
+    RTC->TACFG_B.TPTSEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the TimeStamp on Tamper Detection Event
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisableTDE(void)
+{
+    RTC->TACFG_B.TPTSEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enable pull-up resistors to precharge of the selected Tamper pin.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_EnablePullUp(void)
+{
+    /* Enable precharge */
+    RTC->TACFG_B.TPPUDIS = BIT_RESET;
+}
+
+/*!
+ * @brief     Disable pull-up resistors to precharge of the selected Tamper pin.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void RTC_DisablePullUp(void)
+{
+    /* Disable precharge */
+    RTC->TACFG_B.TPPUDIS = BIT_SET;
+}
+
+/*!
+ * @brief     Writes a data in RTC Backup data.
+ *
+ * @param     backup: RTC Backup data Register number.
+ *                    This parameter can be RTC_BAKP_REG_x where x can be from 0 to 19.
+ *
+ * @param     data: Data to be written in the specified RTC Backup data register.
+ *
+ * @retval    None
+ */
+void RTC_WriteBackup(RTC_BAKP_REG_T backupReg, uint32_t data)
+{
+    RTC->BAKP[backupReg] = (uint32_t)data;
+}
+
+/*!
+ * @brief     Reads a data in RTC Backup data.
+ *
+ * @param     backup: RTC Backup data Register number.
+ *                    This parameter can be RTC_BAKP_REG_x where x can be from 0 to 19.
+ *
+ * @retval    None
+ */
+uint32_t RTC_ReadBackup(RTC_BAKP_REG_T backupReg)
+{
+    return RTC->BAKP[backupReg];
+}
+
+/*!
+ * @brief     Config Tamper Pin.
+ *
+ * @param     tamperPin: specifies the RTC Tamper Pin.
+ *                       This parameter can be one of the following values:
+ *                       @arg RTC_TAMPER_PIN_AF1 : RTC_AF1(PC13) is used as RTC Tamper Pin.
+ *                       @arg RTC_TAMPER_PIN_AF2 : RTC_AF2(PI8) is used as RTC Tamper Pin.
+ *
+ * @retval    None
+ */
+void RTC_ConfigTamperPin(RTC_TAMPER_PIN_T tamperPin)
+{
+    RTC->TACFG_B.TP1MSEL = tamperPin;
+}
+
+/*!
+ * @brief     Config the RTC TimeStamp Pin.
+ *
+ * @param     timeStampPin: specifies the RTC TimeStamp Pin.
+ *                          This parameter can be one of the following values:
+ *                          @arg RTC_TIMESTAMP_PIN_AF1 : RTC_AF1(PC13) is used as RTC TimeStamp Pin.
+ *                          @arg RTC_TIMESTAMP_PIN_AF2 : RTC_AF2(PI8) is used as RTC TimeStamp Pin.
+ *
+ * @retval    None
+ */
+void RTC_ConfigTimeStampPin(RTC_TIMESTAMP_PIN_T timeStampPin)
+{
+    RTC->TACFG_B.TSMSEL = timeStampPin;
+}
+
+/*!
+ * @brief     Config the RTC Output Pin mode
+ *
+ * @param     outputType: specifies the RTC Output (PC13) pin mode.
+ *                        This parameter can be one of the following values:
+ *                        @arg RTC_OUTPUT_OD : RTC_ALARM(PC13) output Open-drain
+ *                        @arg RTC_OUTPUT_PP : RTC_ALARM(PC13) output Push-pull
+ *
+ * @retval    None
+ */
+void RTC_ConfigOutputType(RTC_OUTPUT_T outputType)
+{
+    RTC->TACFG_B.ALRMOT = outputType;
+}
+
+/*!
+ * @brief     Config the Synchronization Shift Control Settings.
+ *
+ * @param     add1S:  Select to add or not 1 second to the time Calendar.
+ *                    This parameter can be one of the following values :
+ *                    @arg RTC_SHIFT_ADD1S_RESET: No effect.
+ *                    @arg RTC_SHIFT_ADD1S_SET  : Add one second to the clock calendar.
+ *
+ * @param     subFS:  Select the number of Second Fractions to Substitute.
+ *                    This parameter can be one any value from 0 to 0x7FFF.
+ *
+ * @retval    SUCCESS or ERROR
+ */
+uint8_t RTC_ConfigSynchroShift(RTC_SHIFT_ADD1S_T add1S, uint16_t subFS)
+{
+    uint32_t timeout = 0;
+
+    RTC_DisableWriteProtection();
+
+    /* wait for Shift operation flag to be cleared */
+    while ((RTC->STS_B.SOPFLG != BIT_RESET) && (timeout != RTC_TIMEOUT_SHIFT))
+    {
+        timeout++;
+    }
+
+    /* check if Shift Operation flag is cleared and Reference Clock Detection is disabled */
+    if ((RTC->STS_B.SOPFLG != BIT_SET) && (RTC->CTRL_B.RCLKDEN != BIT_SET))
+    {
+        RTC->SHIFT = ((uint32_t)add1S << 31) | (uint32_t)subFS;
+
+        if (RTC_WaitForSynchro() != ERROR)
+        {
+            RTC_EnableWriteProtection();
+
+            return SUCCESS;
+        }
+    }
+
+    RTC_EnableWriteProtection();
+
+    return ERROR;
+}
+
+/*!
+ * @brief     Enable RTC interrupts.
+ *
+ * @param     interrupt: specifies the RTC interrupt sources to be enabled
+ *                     This parameter can be any combination of the following values:
+ *                      @arg RTC_INT_ALRA : Enable ALRMA A interrupt
+ *                      @arg RTC_INT_ALRB : Enable ALRMA B interrupt
+ *                      @arg RTC_INT_WT   : Enable WakeUp Timer interrupt
+ *                      @arg RTC_INT_TS   : Enable Time Stamp interrupt
+ *                      @arg RTC_INT_TAMP : Enable Tamper event interrupt
+ *
+ * @retval    None
+ */
+void RTC_EnableInterrupt(uint32_t interrupt)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL |= (uint32_t)(interrupt & ~RTC_INT_TAMP);
+    RTC->TACFG |= (uint32_t)(interrupt & RTC_INT_TAMP);
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Disable RTC interrupts.
+ *
+ * @param     interrupt: specifies the RTC interrupt sources to be disable
+ *                       This parameter can be any combination of the following values:
+ *                        @arg RTC_INT_ALRA : Disable ALRMA A interrupt
+ *                        @arg RTC_INT_ALRB : Disable ALRMA B interrupt
+ *                        @arg RTC_INT_WT   : Disable WakeUp Timer interrupt
+ *                        @arg RTC_INT_TS   : Disable Time Stamp interrupt
+ *                        @arg RTC_INT_TAMP : Disable Tamper event interrupt
+ *
+ * @retval    None
+ */
+void RTC_DisableInterrupt(uint32_t interrupt)
+{
+    RTC_DisableWriteProtection();
+
+    RTC->CTRL &= (uint32_t)~(interrupt & ~RTC_INT_TAMP);
+    RTC->TACFG &= (uint32_t)~(interrupt & RTC_INT_TAMP);
+
+    RTC_EnableWriteProtection();
+}
+
+/*!
+ * @brief     Read the specified RTC flag.
+ *
+ * @param     flag: specifies the flag to check.
+ *                  This parameter can be one of the following values:
+ *                  @arg RTC_FLAG_AAWF : Alarm A Write Flag
+ *                  @arg RTC_FLAG_ABWF : Alarm B Write Flag
+ *                  @arg RTC_FLAG_WTWF : Wakeup Timer Write Flag
+ *                  @arg RTC_FLAG_SOPF : Shift Operation Pending Flag
+ *                  @arg RTC_FLAG_ISF  : Initialization State Flag
+ *                  @arg RTC_FLAG_RSF  : Registers Synchronization Flag
+ *                  @arg RTC_FLAG_INTF : Register Initialization Flag
+ *                  @arg RTC_FLAG_ALRAF: Alarm A Match Flag
+ *                  @arg RTC_FLAG_ALRBF: Alarm B Match Flag
+ *                  @arg RTC_FLAG_WTF  : Wakeup Timer Flag
+ *                  @arg RTC_FLAG_TSF  : Time Stamp Flag
+ *                  @arg RTC_FLAG_TSOF : Time Stamp Overflow Flag
+ *                  @arg RTC_FLAG_TP1F : Tamper 1 event Detection Flag
+ *                  @arg RTC_FLAG_TP2F : Tamper 2 event Detection Flag
+ *                  @arg RTC_FLAG_RPF  : Recalibration Pending Flag
+ *
+ * @retval    SET or RESET.
+ */
+uint8_t RTC_ReadStatusFlag(RTC_FLAG_T flag)
+{
+    return (RTC->STS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the RTC's status flags.
+ * @param     flag: specifies the RTC flag to clear.
+ *                  This parameter can be any combination of the following values:
+ *                  @arg RTC_FLAG_RSF   : Registers Synchronization Flag
+ *                  @arg RTC_FLAG_ALRAF : Alarm A Match Flag
+ *                  @arg RTC_FLAG_ALRBF : Alarm B Match Flag
+ *                  @arg RTC_FLAG_WTF   : Wakeup Timer Flag
+ *                  @arg RTC_FLAG_TSF   : Time Stamp Flag
+ *                  @arg RTC_FLAG_TSOF  : Time Stamp Overflow Flag
+ *                  @arg RTC_FLAG_TP1F  : Tamper 1 event Detection Flag
+ *                  @arg RTC_FLAG_TP2F  : Tamper 2 event Detection Flag
+ */
+void RTC_ClearStatusFlag(uint32_t flag)
+{
+    RTC->STS &= (uint32_t)~flag;
+}
+
+/*!
+ * @brief     Read interrupt flag bit is set
+ *
+ * @param     flag: specifies the flag to read.
+ *                  This parameter can be one of the following values:
+ *                  @arg RTC_INT_FLAG_ALRA  : Alarm A interrupt
+ *                  @arg RTC_INT_FLAG_ALRB  : Alarm B interrupt
+ *                  @arg RTC_INT_FLAG_WT    : WakeUp Timer interrupt
+ *                  @arg RTC_INT_FLAG_TS    : Time Stamp interrupt
+ *                  @arg RTC_INT_FLAG_TAMP1 : Tamper1 event interrupt
+ *                  @arg RTC_INT_FLAG_TAMP2 : Tamper2 event interrupt
+ *
+ * @retval    The new state of flag (SET or RESET).
+ */
+uint8_t RTC_ReadIntFlag(RTC_INT_FLAG_T flag)
+{
+    uint8_t intEnable;
+    uint32_t intStatus;
+
+    if (flag & 0x01)
+    {
+        intEnable = RTC->TACFG_B.TPIEN;
+        intStatus = (uint32_t)(RTC->STS & (flag >> 4));
+    }
+    else
+    {
+        intEnable = (RTC->CTRL & flag) ? SET : RESET;
+        intStatus = (uint32_t)(RTC->STS & (flag >> 4));
+    }
+
+    if (intEnable && intStatus)
+    {
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+ * @brief     Clear RTC interrupt flag bit
+ *
+ * @param     flag: specifies the flag to clear.
+ *                  This parameter can be any combination the following values:
+ *                  @arg RTC_INT_FLAG_ALRA  : ALRMA interrupt
+ *                  @arg RTC_INT_FLAG_ALRB  : ALRMB interrupt
+ *                  @arg RTC_INT_FLAG_TS    : Time Stamp interrupt
+ *                  @arg RTC_INT_FLAG_WT    : WakeUp Timer interrupt
+ *                  @arg RTC_INT_FLAG_TAMP1 : Tamper1 event interrupt
+ *                  @arg RTC_INT_FLAG_TAMP2 : Tamper2 event interrupt
+ *
+ * @retval    SET or RESET
+ */
+void RTC_ClearIntFlag(uint32_t flag)
+{
+    RTC->STS &= (uint32_t) ~(flag >> 4);
+}
+
+/*!
+ * @brief     Converts a 2 digit decimal to BCD format
+ *
+ * @param     val: Byte to be converted
+ *
+ * @retval    Converted byte
+ */
+static uint8_t RTC_ByteConBcd2(uint8_t val)
+{
+    uint8_t bcdhigh = 0;
+
+    while (val >= 10)
+    {
+        bcdhigh++;
+        val -= 10;
+    }
+
+    return ((uint8_t)(bcdhigh << 4) | val);
+}
+
+/*!
+ * @brief     Convert from 2 digit BCD to Binary
+ *
+ * @param     val: BCD value to be converted
+ *
+ * @retval    Converted word
+ */
+static uint8_t RTC_Bcd2ConByte(uint8_t val)
+{
+    uint8_t tmp = 0;
+    tmp = ((uint8_t)(val & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
+    return (tmp + (val & (uint8_t)0x0F));
+}
+
+/**@} end of group RTC_Functions */
+/**@} end of group RTC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 720 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_sdio.c

@@ -0,0 +1,720 @@
+/*!
+ * @file        apm32f4Xx_sdio.c
+ *
+ * @brief       This file provides all the SDIO firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4Xx_sdio.h"
+#include "apm32f4Xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup SDIO_Driver
+  * @brief SDIO driver modules
+  @{
+*/
+
+/** @defgroup SDIO_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset sdio peripheral registers to their default reset values
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_Reset(void)
+{
+    RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SDIO);
+    RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SDIO);
+}
+
+/*!
+ * @brief     Config the SDIO peripheral according to the specified parameters in the sdioConfig
+ *
+ * @param     sdioConfig: pointer to a SDIO_Config_T structure
+ *
+ * @retval    None
+ */
+void SDIO_Config(SDIO_Config_T *sdioConfig)
+{
+    SDIO->CLKCTRL_B.CLKDIV   = sdioConfig->clockDiv;
+    SDIO->CLKCTRL_B.PWRSAV   = sdioConfig->clockPowerSave;
+    SDIO->CLKCTRL_B.BYPASSEN = sdioConfig->clockBypass;
+    SDIO->CLKCTRL_B.WBSEL    = sdioConfig->busWide;
+    SDIO->CLKCTRL_B.DEPSEL   = sdioConfig->clockEdge;
+    SDIO->CLKCTRL_B.HFCEN    = sdioConfig->hardwareFlowControl;
+}
+
+/*!
+ * @brief     Fills each SDIO_Config_T member with its default value
+ *
+ * @param     sdioConfig: pointer to a SDIO_Config_T structure
+ *
+ * @retval    None
+ */
+void SDIO_ConfigStructInit(SDIO_Config_T *sdioConfig)
+{
+    sdioConfig->clockDiv = 0x00;
+    sdioConfig->clockEdge = SDIO_CLOCK_EDGE_RISING;
+    sdioConfig->clockBypass = SDIO_CLOCK_BYPASS_DISABLE;
+    sdioConfig->clockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
+    sdioConfig->busWide = SDIO_BUS_WIDE_1B;
+    sdioConfig->hardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
+}
+
+/*!
+ * @brief     Enables the SDIO clock
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableClock(void)
+{
+    SDIO->CLKCTRL_B.CLKEN = SET;
+}
+
+/*!
+ * @brief     Disables the SDIO clock
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableClock(void)
+{
+    SDIO->CLKCTRL_B.CLKEN = RESET;
+}
+
+/*!
+ * @brief    Sets the power status of the controller
+ *
+ * @param    powerState: new state of the Power state
+ *                       The parameter can be one of following values:
+ *                       @arg SDIO_POWER_STATE_OFF : Power off
+ *                       @arg SDIO_POWER_STATE_ON  : Power on
+ *
+ * @retval    None
+ */
+void SDIO_ConfigPowerState(SDIO_POWER_STATE_T powerState)
+{
+    SDIO->PWRCTRL_B.PWRCTRL = powerState;
+}
+
+/*!
+ * @brief     Reads the SDIO power state
+ *
+ * @param     None
+ *
+ * @retval    The new state SDIO power
+ *
+ * @note      0x00:Power OFF, 0x02:Power UP, 0x03:Power ON
+ */
+uint32_t SDIO_ReadPowerState(void)
+{
+    return (uint8_t)SDIO->PWRCTRL_B.PWRCTRL;
+}
+
+/*!
+ * @brief     Enables the SDIO DMA request
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableDMA(void)
+{
+    SDIO->DCTRL_B.DMAEN = SET;
+}
+
+/*!
+ * @brief     Disables the SDIO DMA request
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableDMA(void)
+{
+    SDIO->DCTRL_B.DMAEN = RESET;
+}
+
+/*!
+ * @brief     Configs the SDIO Command and send the command
+ *
+ * @param     cmdConfig: pointer to a SDIO_CmdConfig_T structure
+ *
+ * @retval    None
+ */
+void SDIO_TxCommand(SDIO_CmdConfig_T *cmdConfig)
+{
+    uint32_t tempReg = 0;
+
+    SDIO->ARG = cmdConfig->argument;
+    tempReg = SDIO->CMD;
+    /* Clear CMDINDEX, WAITRES, WAITINT, WENDDATA, CPSMEN bits */
+    tempReg &= ((uint32_t)0xFFFFF800);
+    tempReg |= (uint32_t)(cmdConfig->cmdIndex) | (cmdConfig->response) << 6
+               | (cmdConfig->wait) << 8 | (cmdConfig->CPSM) << 10;
+    SDIO->CMD = tempReg;
+}
+
+/*!
+ * @brief     Fills each cmdConfig member with its default value
+ *
+ * @param     cmdConfig: pointer to a SDIO_CmdConfig_T structure
+ *
+ * @retval    None
+ */
+void SDIO_TxCommandStructInit(SDIO_CmdConfig_T *cmdConfig)
+{
+    cmdConfig->argument = 0x00;
+    cmdConfig->cmdIndex = 0x00;
+    cmdConfig->response = SDIO_RESPONSE_NO;
+    cmdConfig->wait = SDIO_WAIT_NO;
+    cmdConfig->CPSM = SDIO_CPSM_DISABLE;
+}
+
+/*!
+ * @brief     Reads the SDIO command response
+ *
+ * @param     None
+ *
+ * @retval    The command index of the last command response received
+ */
+uint8_t SDIO_ReadCommandResponse(void)
+{
+    return (uint8_t)(SDIO->CMDRES);
+}
+
+/*!
+ * @brief     Reads the SDIO response
+ *
+ * @param     res:  Specifies the SDIO response register
+ *                  The parameter can be one of following values:
+ *                  @arg SDIO_RES1 : Response Register 1
+ *                  @arg SDIO_RES2 : Response Register 2
+ *                  @arg SDIO_RES3 : Response Register 3
+ *                  @arg SDIO_RES4 : Response Register 4
+ *
+ * @retval    The Corresponding response register value
+ */
+uint32_t SDIO_ReadResponse(SDIO_RES_T res)
+{
+    __IO uint32_t tmp = 0;
+
+    tmp = ((uint32_t)(SDIO_BASE + 0x14)) + res;
+
+    return (*(__IO uint32_t *) tmp);
+}
+
+/*!
+ * @brief     Configs the SDIO Dataaccording to the specified parameters in the dataConfig
+ *
+ * @param     dataConfig: pointer to a SDIO_DataConfig_T structure
+ *
+ * @retval    None
+ */
+void SDIO_ConfigData(SDIO_DataConfig_T *dataConfig)
+{
+    uint32_t tempReg = 0;
+
+    SDIO->DATATIME = dataConfig->dataTimeOut;
+
+    SDIO->DATALEN = dataConfig->dataLength;
+
+    tempReg = SDIO->DCTRL;
+    /* Clear DTEN, DTSEL, DTDRCFG and DBSIZE bits */
+    tempReg &= ((uint32_t)0xFFFFFF08);
+    tempReg |= (uint32_t)(dataConfig->dataBlockSize) << 4 | (dataConfig->transferDir) << 1
+               | (dataConfig->transferMode) << 2 | (dataConfig->DPSM);
+    SDIO->DCTRL = tempReg;
+}
+
+/*!
+ * @brief     Fills each SDIO_DataConfig_T member with its default value
+ *
+ * @param     dataConfig: pointer to a SDIO_DataConfig_T structure
+ *
+ * @retval    None
+ */
+void SDIO_ConfigDataStructInit(SDIO_DataConfig_T *dataConfig)
+{
+    dataConfig->dataTimeOut = 0xFFFFFFFF;
+    dataConfig->dataLength = 0x00;
+    dataConfig->dataBlockSize = SDIO_DATA_BLOCKSIZE_1B;
+    dataConfig->transferDir = SDIO_TRANSFER_DIR_TO_CARD;
+    dataConfig->transferMode = SDIO_TRANSFER_MODE_BLOCK;
+    dataConfig->DPSM = SDIO_DPSM_DISABLE;
+}
+
+/*!
+ * @brief     Reads the SDIO Data counter
+ *
+ * @param     None
+ *
+ * @retval    The SDIO Data counter value
+ */
+uint32_t SDIO_ReadDataCounter(void)
+{
+    return SDIO->DCNT;
+}
+
+/*!
+ * @brief     Write the SDIO Data
+ *
+ * @param     data : a 32-bit data to write
+ *
+ * @retval    None
+ */
+void SDIO_WriteData(uint32_t data)
+{
+    SDIO->FIFODATA = data;
+}
+
+/*!
+ * @brief     Reads the SDIO Data
+ *
+ * @param     None
+ *
+ * @retval    The SDIO FIFO Data value
+ */
+uint32_t SDIO_ReadData(void)
+{
+    return SDIO->FIFODATA;
+}
+
+/*!
+ * @brief     Reads the SDIO FIFO count value
+ *
+ * @param     None
+ *
+ * @retval    The SDIO FIFO count value
+ */
+uint32_t SDIO_ReadFIFOCount(void)
+{
+    return SDIO->FIFOCNT;
+}
+
+/*!
+ * @brief     Enables SDIO start read wait
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableStartReadWait(void)
+{
+    SDIO->DCTRL_B.RWSTR = SET;
+}
+
+/*!
+ * @brief     Disables SDIO stop read wait
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableStartReadWait(void)
+{
+    SDIO->DCTRL_B.RWSTR = RESET;
+}
+
+/*!
+ * @brief     Disables SDIO start read wait
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableStopReadWait(void)
+{
+    SDIO->DCTRL_B.RWSTOP = RESET;
+}
+
+/*!
+ * @brief     Enables SDIO stop read wait
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableStopReadWait(void)
+{
+    SDIO->DCTRL_B.RWSTOP = SET;
+}
+
+/*!
+ * @brief     Config the read wait interval
+ *
+ * @param     readWaitMode: SDIO read Wait Mode
+ *                  The parameter can be one of following values:
+ *                  @arg SDIO_READ_WAIT_MODE_DATA2  : Read Wait control using SDIO_DATA2
+ *                  @arg SDIO_READ_WAIT_MODE_CLK    : Read Wait control by stopping SDIOCLK
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void SDIO_ConfigSDIOReadWaitMode(SDIO_READ_WAIT_MODE_T readWaitMode)
+{
+    SDIO->DCTRL_B.RDWAIT = readWaitMode;
+}
+/*!
+ * @brief     Enables SDIO SD I/O Mode Operation
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableSDIO(void)
+{
+    SDIO->DCTRL_B.SDIOF = SET;
+}
+
+/*!
+ * @brief     Disables SDIO SD I/O Mode Operation
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableSDIO(void)
+{
+    SDIO->DCTRL_B.SDIOF = RESET;
+}
+
+/*!
+ * @brief     Ensables SDIO SD I/O Mode suspend command sending
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableTxSDIOSuspend(void)
+{
+    SDIO->CMD_B.SDIOSC = SET;
+}
+
+/*!
+ * @brief     Disables SDIO SD I/O Mode suspend command sending
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableTxSDIOSuspend(void)
+{
+    SDIO->CMD_B.SDIOSC = RESET;
+}
+
+/*!
+ * @brief     Enables the command completion signal
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableCommandCompletion(void)
+{
+    SDIO->CMD_B.CMDCPEN = SET;
+}
+
+/*!
+ * @brief     Disables the command completion signal
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableCommandCompletion(void)
+{
+    SDIO->CMD_B.CMDCPEN = RESET;
+}
+
+/*!
+ * @brief     Enables the CE-ATA interrupt
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableCEATAInterrupt(void)
+{
+    SDIO->CMD_B.INTEN = RESET;
+}
+
+/*!
+ * @brief     Disables the CE-ATA interrupt
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableCEATAInterrupt(void)
+{
+    SDIO->CMD_B.INTEN =  SET;
+}
+
+/*!
+ * @brief     Ensables Sends CE-ATA command
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_EnableTxCEATA(void)
+{
+    SDIO->CMD_B.ATACMD = SET;
+}
+
+/*!
+ * @brief     Disables Sends CE-ATA command
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SDIO_DisableTxCEATA(void)
+{
+    SDIO->CMD_B.ATACMD = RESET;
+}
+
+/*!
+ * @brief     Enables the specified SDIO interrupt
+ *
+ * @param     interrupt: Select the SDIO interrupt source
+ *                       The parameter can be any combination of following values:
+ *                       @arg SDIO_INT_COMRESP  : Command response received (CRC check failed) interrupt
+ *                       @arg SDIO_INT_DBDR     : Data block sent/received (CRC check failed) interrupt
+ *                       @arg SDIO_INT_CMDRESTO : Command response timeout interrupt
+ *                       @arg SDIO_INT_DATATO   : Data timeout interrupt
+ *                       @arg SDIO_INT_TXUDRER  : Transmit FIFO underrun error interrupt
+ *                       @arg SDIO_INT_RXOVRER  : Received FIFO overrun error interrupt
+ *                       @arg SDIO_INT_CMDRES   : Command response received (CRC check passed) interrupt
+ *                       @arg SDIO_INT_CMDSENT  : Command sent (no response required) interrupt
+ *                       @arg SDIO_INT_DATAEND  : Data end (data counter, SDIDCOUNT, is zero) interrupt
+ *                       @arg SDIO_INT_SBE      : Start bit not detected on all data signals in wide bus mode interrupt
+ *                       @arg SDIO_INT_DBCP     : Data block sent/received (CRC check passed) interrupt
+ *                       @arg SDIO_INT_CMDACT   : Command transfer in progress interrupt
+ *                       @arg SDIO_INT_TXACT    : Data transmit in progress interrupt
+ *                       @arg SDIO_INT_RXACT    : Data receive in progress interrupt
+ *                       @arg SDIO_INT_TXFHF    : Transmit FIFO Half Empty interrupt
+ *                       @arg SDIO_INT_RXFHF    : Receive FIFO Half Full interrupt
+ *                       @arg SDIO_INT_TXFF     : Transmit FIFO full interrupt
+ *                       @arg SDIO_INT_RXFF     : Receive FIFO full interrupt
+ *                       @arg SDIO_INT_TXFE     : Transmit FIFO empty interrupt
+ *                       @arg SDIO_INT_RXFE     : Receive FIFO empty interrupt
+ *                       @arg SDIO_INT_TXDA     : Data available in transmit FIFO interrupt
+ *                       @arg SDIO_INT_RXDA     : Data available in receive FIFO interrupt
+ *                       @arg SDIO_INT_SDIOINT  : SD I/O interrupt received interrupt
+ *                       @arg SDIO_INT_ATAEND   : CE-ATA command completion signal received for CMD61 interrupt
+ *
+ * @retval    None
+ */
+void SDIO_EnableInterrupt(uint32_t interrupt)
+{
+    SDIO->MASK |= interrupt;
+}
+
+/*!
+ * @brief     Disables the specified SDIO interrupt
+ *
+ * @param     interrupt: Select the SDIO interrupt source
+ *                       The parameter can be any combination of following values:
+ *                       @arg SDIO_INT_COMRESP  : Command response received (CRC check failed) interrupt
+ *                       @arg SDIO_INT_DBDR     : Data block sent/received (CRC check failed) interrupt
+ *                       @arg SDIO_INT_CMDRESTO : Command response timeout interrupt
+ *                       @arg SDIO_INT_DATATO   : Data timeout interrupt
+ *                       @arg SDIO_INT_TXUDRER  : Transmit FIFO underrun error interrupt
+ *                       @arg SDIO_INT_RXOVRER  : Received FIFO overrun error interrupt
+ *                       @arg SDIO_INT_CMDRES   : Command response received (CRC check passed) interrupt
+ *                       @arg SDIO_INT_CMDSENT  : Command sent (no response required) interrupt
+ *                       @arg SDIO_INT_DATAEND  : Data end (data counter, SDIDCOUNT, is zero) interrupt
+ *                       @arg SDIO_INT_SBE      : Start bit not detected on all data signals in wide bus mode interrupt
+ *                       @arg SDIO_INT_DBCP     : Data block sent/received (CRC check passed) interrupt
+ *                       @arg SDIO_INT_CMDACT   : Command transfer in progress interrupt
+ *                       @arg SDIO_INT_TXACT    : Data transmit in progress interrupt
+ *                       @arg SDIO_INT_RXACT    : Data receive in progress interrupt
+ *                       @arg SDIO_INT_TXFHF    : Transmit FIFO Half Empty interrupt
+ *                       @arg SDIO_INT_RXFHF    : Receive FIFO Half Full interrupt
+ *                       @arg SDIO_INT_TXFF     : Transmit FIFO full interrupt
+ *                       @arg SDIO_INT_RXFF     : Receive FIFO full interrupt
+ *                       @arg SDIO_INT_TXFE     : Transmit FIFO empty interrupt
+ *                       @arg SDIO_INT_RXFE     : Receive FIFO empty interrupt
+ *                       @arg SDIO_INT_TXDA     : Data available in transmit FIFO interrupt
+ *                       @arg SDIO_INT_RXDA     : Data available in receive FIFO interrupt
+ *                       @arg SDIO_INT_SDIOINT  : SD I/O interrupt received interrupt
+ *                       @arg SDIO_INT_ATAEND   : CE-ATA command completion signal received for CMD61 interrupt
+ *
+ * @retval    None
+ */
+void SDIO_DisableInterrupt(uint32_t interrupt)
+{
+    SDIO->MASK &= ~interrupt;
+}
+
+/*!
+ * @brief     Reads the specified SDIO flag
+ *
+ * @param     flag: Select the flag to read
+ *              The parameter can be one of following values:
+ *              @arg SDIO_FLAG_COMRESP  : Command response received (CRC check failed) flag
+ *              @arg SDIO_FLAG_DBDR     : Data block sent/received (CRC check failed) flag
+ *              @arg SDIO_FLAG_CMDRESTO : Command response timeout flag
+ *              @arg SDIO_FLAG_DATATO   : Data timeout flag
+ *              @arg SDIO_FLAG_TXUDRER  : Transmit FIFO underrun error flag
+ *              @arg SDIO_FLAG_RXOVRER  : Received FIFO overrun error flag
+ *              @arg SDIO_FLAG_CMDRES   : Command response received (CRC check passed) flag
+ *              @arg SDIO_FLAG_CMDSENT  : Command sent (no response required) flag
+ *              @arg SDIO_FLAG_DATAEND  : Data end (data counter is zero) flag
+ *              @arg SDIO_FLAG_SBE      : Start bit not detected on all data signals in wide bus mode flag
+ *              @arg SDIO_FLAG_DBCP     : Data block sent/received (CRC check passed) flag
+ *              @arg SDIO_FLAG_CMDACT   : Command transfer in progress flag
+ *              @arg SDIO_FLAG_TXACT    : Data transmit in progress flag
+ *              @arg SDIO_FLAG_RXACT    : Data receive in progress flag
+ *              @arg SDIO_FLAG_TXFHF    : Transmit FIFO Half Empty flag
+ *              @arg SDIO_FLAG_RXFHF    : Receive FIFO Half Full flag
+ *              @arg SDIO_FLAG_TXFF     : Transmit FIFO full flag
+ *              @arg SDIO_FLAG_RXFF     : Receive FIFO full flag
+ *              @arg SDIO_FLAG_TXFE     : Transmit FIFO empty flag
+ *              @arg SDIO_FLAG_RXFE     : Receive FIFO empty flag
+ *              @arg SDIO_FLAG_TXDA     : Data available in transmit FIFO flag
+ *              @arg SDIO_FLAG_RXDA     : Data available in receive FIFO flag
+ *              @arg SDIO_FLAG_SDIOINT  : SD I/O interrupt received flag
+ *              @arg SDIO_FLAG_ATAEND   : CE-ATA command completion signal received for CMD61 flag
+ *
+ * @retval    SET or RESET
+ */
+uint8_t SDIO_ReadStatusFlag(SDIO_FLAG_T flag)
+{
+    return (SDIO->STS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the specified SDIO flag
+ *
+ * @param     flag: Select the flag to clear
+ *              The parameter can be any combination of following values:
+ *              @arg SDIO_FLAG_COMRESP  : Command response received (CRC check failed) flag
+ *              @arg SDIO_FLAG_DBDR     : Data block sent/received (CRC check failed) flag
+ *              @arg SDIO_FLAG_CMDRESTO : Command response timeout flag
+ *              @arg SDIO_FLAG_DATATO   : Data timeout flag
+ *              @arg SDIO_FLAG_TXUDRER  : Transmit FIFO underrun error flag
+ *              @arg SDIO_FLAG_RXOVRER  : Received FIFO overrun error flag
+ *              @arg SDIO_FLAG_CMDRES   : Command response received (CRC check passed) flag
+ *              @arg SDIO_FLAG_CMDSENT  : Command sent (no response required) flag
+ *              @arg SDIO_FLAG_DATAEND  : Data end (data counter is zero) flag
+ *              @arg SDIO_FLAG_SBE      : Start bit not detected on all data signals in wide bus mode flag
+ *              @arg SDIO_FLAG_DBCP     : Data block sent/received (CRC check passed) flag
+ *              @arg SDIO_FLAG_SDIOINT  : SD I/O interrupt received flag
+ *              @arg SDIO_FLAG_ATAEND   : CE-ATA command completion signal received for CMD61 flag
+ *
+ * @retval    None
+ */
+void SDIO_ClearStatusFlag(uint32_t flag)
+{
+    SDIO->ICF = flag;
+}
+
+/*!
+ * @brief     Reads the specified SDIO Interrupt flag
+ *
+ * @param     flag: Select the SDIO interrupt source
+ *              The parameter can be one of following values:
+ *              @arg SDIO_INT_COMRESP   : Command response received (CRC check failed) interrupt
+ *              @arg SDIO_INT_DBDR      : Data block sent/received (CRC check failed) interrupt
+ *              @arg SDIO_INT_CMDRESTO  : Command response timeout interrupt
+ *              @arg SDIO_INT_DATATO    : Data timeout interrupt
+ *              @arg SDIO_INT_TXUDRER   : Transmit FIFO underrun error interrupt
+ *              @arg SDIO_INT_RXOVRER   : Received FIFO overrun error interrupt
+ *              @arg SDIO_INT_CMDRES    : Command response received (CRC check passed) interrupt
+ *              @arg SDIO_INT_CMDSENT   : Command sent (no response required) interrupt
+ *              @arg SDIO_INT_DATAEND   : Data end (data counter is zero) interrupt
+ *              @arg SDIO_INT_SBE       : Start bit not detected on all data signals in wide bus mode interrupt
+ *              @arg SDIO_INT_DBCP      : Data block sent/received (CRC check passed) interrupt
+ *              @arg SDIO_INT_CMDACT    : Command transfer in progress interrupt
+ *              @arg SDIO_INT_TXACT     : Data transmit in progress interrupt
+ *              @arg SDIO_INT_RXACT     : Data receive in progress interrupt
+ *              @arg SDIO_INT_TXFHF     : Transmit FIFO Half Empty interrupt
+ *              @arg SDIO_INT_RXFHF     : Receive FIFO Half Full interrupt
+ *              @arg SDIO_INT_TXFF      : Transmit FIFO full interrupt
+ *              @arg SDIO_INT_RXFF      : Receive FIFO full interrupt
+ *              @arg SDIO_INT_TXFE      : Transmit FIFO empty interrupt
+ *              @arg SDIO_INT_RXFE      : Receive FIFO empty interrupt
+ *              @arg SDIO_INT_TXDA      : Data available in transmit FIFO interrupt
+ *              @arg SDIO_INT_RXDA      : Data available in receive FIFO interrupt
+ *              @arg SDIO_INT_SDIOINT   : SD I/O interrupt received interrupt
+ *              @arg SDIO_INT_ATAEND    : CE-ATA command completion signal received for CMD61 interrupt
+ *
+ * @retval    SET or RESET
+ */
+uint8_t SDIO_ReadIntFlag(SDIO_INT_T flag)
+{
+    uint32_t intEnable;
+    uint32_t intStatus;
+
+    intEnable = (uint32_t)(SDIO->MASK & flag);
+    intStatus = (uint32_t)(SDIO->STS & flag);
+
+    if (intEnable && intStatus)
+    {
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+ * @brief     Clears the specified SDIO Interrupt pending bits
+ *
+ * @param     flag: Select the SDIO interrupt source
+ *              The parameter can be any combination of following values:
+ *              @arg SDIO_INT_COMRESP   : Command response received (CRC check failed) interrupt
+ *              @arg SDIO_INT_DBDR      : Data block sent/received (CRC check failed) interrupt
+ *              @arg SDIO_INT_CMDRESTO  : Command response timeout interrupt
+ *              @arg SDIO_INT_DATATO    : Data timeout interrupt
+ *              @arg SDIO_INT_TXUDRER   : Transmit FIFO underrun error interrupt
+ *              @arg SDIO_INT_RXOVRER   : Received FIFO overrun error interrupt
+ *              @arg SDIO_INT_CMDRES    : Command response received (CRC check passed) interrupt
+ *              @arg SDIO_INT_CMDSENT   : Command sent (no response required) interrupt
+ *              @arg SDIO_INT_DATAEND   : Data end (data counter is zero) interrupt
+ *              @arg SDIO_INT_SBE       : Start bit not detected on all data signals in wide bus mode interrupt
+ *              @arg SDIO_INT_DBCP      : Data block sent/received (CRC check passed) interrupt
+ *              @arg SDIO_INT_SDIOINT   : SD I/O interrupt received interrupt
+ *              @arg SDIO_INT_ATAEND    : CE-ATA command completion signal received for CMD61 interrupt
+ *
+ * @retval    None
+ */
+void SDIO_ClearIntFlag(uint32_t flag)
+{
+    SDIO->ICF = flag;
+}
+
+/**@} end of group SDIO_Functions */
+/**@} end of group SDIO_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 969 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_smc.c

@@ -0,0 +1,969 @@
+/*!
+ * @file        apm32f4xx_smc.c
+ *
+ * @brief       This file provides all the SMC firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_smc.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup SMC_Driver
+  * @brief SMC driver modules
+  @{
+*/
+
+/** @defgroup SMC_Functions
+  @{
+*/
+
+/*!
+ * @brief     Rest the SMC NOR/SRAM Banks registers
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK1_NORSRAM_1 : SMC Bank1 NOR/SRAM1
+ *                  @arg SMC_BANK1_NORSRAM_2 : SMC Bank1 NOR/SRAM2
+ *                  @arg SMC_BANK1_NORSRAM_3 : SMC Bank1 NOR/SRAM3
+ *                  @arg SMC_BANK1_NORSRAM_4 : SMC Bank1 NOR/SRAM4
+ *
+ * @retval    None
+ */
+void SMC_ResetNORSRAM(SMC_BANK1_NORSRAM_T bank)
+{
+    if (bank == SMC_BANK1_NORSRAM_1)
+    {
+        SMC_Bank1->CSCTRL1 = 0x000030DB;
+        SMC_Bank1->CSTIM1 = 0x0FFFFFFF;
+        SMC_Bank1E->WRTTIM1 = 0x0FFFFFFF;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_2)
+    {
+        SMC_Bank1->CSCTRL2 =  0x000030D2;
+        SMC_Bank1->CSTIM2 =   0x0FFFFFFF;
+        SMC_Bank1E->WRTTIM2 = 0x0FFFFFFF;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_3)
+    {
+        SMC_Bank1->CSCTRL3 =  0x000030D2;
+        SMC_Bank1->CSTIM3 =   0x0FFFFFFF;
+        SMC_Bank1E->WRTTIM3 = 0x0FFFFFFF;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_4)
+    {
+        SMC_Bank1->CSCTRL4 =  0x000030D2;
+        SMC_Bank1->CSTIM4 =   0x0FFFFFFF;
+        SMC_Bank1E->WRTTIM4 = 0x0FFFFFFF;
+    }
+}
+
+/*!
+ * @brief     Rest the SMC NAND Banks registers
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK2_NAND : SMC Bank2 NAND
+ *                  @arg SMC_BANK3_NAND : SMC Bank3 NAND
+ *
+ * @retval    None
+ */
+void SMC_ResetNAND(SMC_BANK_NAND_T bank)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->CTRL2 = 0x00000018;
+        SMC_Bank2->STSINT2 = 0x00000040;
+        SMC_Bank2->CMSTIM2 = 0xFCFCFCFC;
+        SMC_Bank2->AMSTIM2 = 0xFCFCFCFC;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->CTRL3 = 0x00000018;
+        SMC_Bank3->STSINT3 = 0x00000040;
+        SMC_Bank3->CMSTIM3 = 0xFCFCFCFC;
+        SMC_Bank3->AMSTIM3 = 0xFCFCFCFC;
+    }
+}
+
+/*!
+ * @brief     Reset the SMC PCCARD Banks registers
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SMC_ResetPCCard(void)
+{
+    SMC_Bank4->CTRL4 = 0x00000018;
+    SMC_Bank4->STSINT4 = 0x00000000;
+    SMC_Bank4->CMSTIM4 = 0xFCFCFCFC;
+    SMC_Bank4->AMSTIM4 = 0xFCFCFCFC;
+    SMC_Bank4->IOSTIM4 = 0xFCFCFCFC;
+}
+
+/*!
+ * @brief     Config the SMC NOR/SRAM Banks according to the specified parameters in the smcNORSRAMConfig.
+ *
+ * @param     smcNORSRAMConfig: Point to a SMC_NORSRAMConfig_T structure
+ *
+ * @retval    None
+ */
+void SMC_ConfigNORSRAM(SMC_NORSRAMConfig_T *smcNORSRAMConfig)
+{
+    if (smcNORSRAMConfig->bank == SMC_BANK1_NORSRAM_1)
+    {
+        SMC_Bank1->CSCTRL1_B.ADMUXEN   = smcNORSRAMConfig->dataAddressMux;
+        SMC_Bank1->CSCTRL1_B.MTYPECFG  = smcNORSRAMConfig->memoryType;
+        SMC_Bank1->CSCTRL1_B.MDBWIDCFG = smcNORSRAMConfig->memoryDataWidth;
+        SMC_Bank1->CSCTRL1_B.BURSTEN = smcNORSRAMConfig->burstAcceesMode;
+        SMC_Bank1->CSCTRL1_B.WSASYNCEN = smcNORSRAMConfig->asynchronousWait;
+        SMC_Bank1->CSCTRL1_B.WSPOLCFG = smcNORSRAMConfig->waitSignalPolarity;
+        SMC_Bank1->CSCTRL1_B.WRAPBEN = smcNORSRAMConfig->wrapMode;
+        SMC_Bank1->CSCTRL1_B.WTIMCFG = smcNORSRAMConfig->waitSignalActive;
+        SMC_Bank1->CSCTRL1_B.WREN = smcNORSRAMConfig->writeOperation;
+        SMC_Bank1->CSCTRL1_B.WAITEN = smcNORSRAMConfig->waiteSignal;
+        SMC_Bank1->CSCTRL1_B.EXTMODEEN = smcNORSRAMConfig->extendedMode;
+        SMC_Bank1->CSCTRL1_B.WRBURSTEN = smcNORSRAMConfig->writeBurst;
+
+        if (smcNORSRAMConfig->memoryType == SMC_MEMORY_TYPE_NOR)
+        {
+            SMC_Bank1->CSCTRL1_B.NORFMACCEN = BIT_SET;
+        }
+
+        SMC_Bank1->CSTIM1_B.ADDRSETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressSetupTime;
+        SMC_Bank1->CSTIM1_B.ADDRHLDCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressHodeTime;
+        SMC_Bank1->CSTIM1_B.DATASETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataSetupTime;
+        SMC_Bank1->CSTIM1_B.BUSTURNCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->busTurnaroundTime;
+        SMC_Bank1->CSTIM1_B.CLKDIVCFG = \
+                                        smcNORSRAMConfig->readWriteTimingStruct->clockDivision;
+        SMC_Bank1->CSTIM1_B.DATALATCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataLatency;
+        SMC_Bank1->CSTIM1_B.ASYNCACCCFG = \
+                                          smcNORSRAMConfig->readWriteTimingStruct->accessMode;
+
+        if (smcNORSRAMConfig->extendedMode == SMC_EXTENDEN_MODE_ENABLE)
+        {
+            SMC_Bank1E->WRTTIM1_B.ADDRSETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressSetupTime;
+            SMC_Bank1E->WRTTIM1_B.ADDRHLDCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressHodeTime;
+            SMC_Bank1E->WRTTIM1_B.DATASETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->dataSetupTime;
+            SMC_Bank1E->WRTTIM1_B.BUSTURNCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->busTurnaroundTime;
+            SMC_Bank1E->WRTTIM1_B.ASYNCACCCFG = \
+                                                smcNORSRAMConfig->writeTimingStruct->accessMode;
+        }
+        else
+        {
+            SMC_Bank1E->WRTTIM1 = 0x0FFFFFFF;
+        }
+    }
+    else if (smcNORSRAMConfig->bank == SMC_BANK1_NORSRAM_2)
+    {
+        SMC_Bank1->CSCTRL2_B.ADMUXEN   = smcNORSRAMConfig->dataAddressMux;
+        SMC_Bank1->CSCTRL2_B.MTYPECFG  = smcNORSRAMConfig->memoryType;
+        SMC_Bank1->CSCTRL2_B.MDBWIDCFG = smcNORSRAMConfig->memoryDataWidth;
+        SMC_Bank1->CSCTRL2_B.BURSTEN = smcNORSRAMConfig->burstAcceesMode;
+        SMC_Bank1->CSCTRL2_B.WSASYNCEN = smcNORSRAMConfig->asynchronousWait;
+        SMC_Bank1->CSCTRL2_B.WSPOLCFG = smcNORSRAMConfig->waitSignalPolarity;
+        SMC_Bank1->CSCTRL2_B.WRAPBEN = smcNORSRAMConfig->wrapMode;
+        SMC_Bank1->CSCTRL2_B.WTIMCFG = smcNORSRAMConfig->waitSignalActive;
+        SMC_Bank1->CSCTRL2_B.WREN = smcNORSRAMConfig->writeOperation;
+        SMC_Bank1->CSCTRL2_B.WAITEN = smcNORSRAMConfig->waiteSignal;
+        SMC_Bank1->CSCTRL2_B.EXTMODEEN = smcNORSRAMConfig->extendedMode;
+        SMC_Bank1->CSCTRL2_B.WRBURSTEN = smcNORSRAMConfig->writeBurst;
+
+        if (smcNORSRAMConfig->memoryType == SMC_MEMORY_TYPE_NOR)
+        {
+            SMC_Bank1->CSCTRL2_B.NORFMACCEN = BIT_SET;
+        }
+
+        SMC_Bank1->CSTIM2_B.ADDRSETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressSetupTime;
+        SMC_Bank1->CSTIM2_B.ADDRHLDCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressHodeTime;
+        SMC_Bank1->CSTIM2_B.DATASETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataSetupTime;
+        SMC_Bank1->CSTIM2_B.BUSTURNCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->busTurnaroundTime;
+        SMC_Bank1->CSTIM2_B.CLKDIVCFG = \
+                                        smcNORSRAMConfig->readWriteTimingStruct->clockDivision;
+        SMC_Bank1->CSTIM2_B.DATALATCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataLatency;
+        SMC_Bank1->CSTIM2_B.ASYNCACCCFG = \
+                                          smcNORSRAMConfig->readWriteTimingStruct->accessMode;
+
+        if (smcNORSRAMConfig->extendedMode == SMC_EXTENDEN_MODE_ENABLE)
+        {
+            SMC_Bank1E->WRTTIM2_B.ADDRSETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressSetupTime;
+            SMC_Bank1E->WRTTIM2_B.ADDRHLDCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressHodeTime;
+            SMC_Bank1E->WRTTIM2_B.DATASETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->dataSetupTime;
+            SMC_Bank1E->WRTTIM2_B.BUSTURNCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->busTurnaroundTime;
+            SMC_Bank1E->WRTTIM2_B.ASYNCACCCFG = \
+                                                smcNORSRAMConfig->writeTimingStruct->accessMode;
+        }
+        else
+        {
+            SMC_Bank1E->WRTTIM2 = 0x0FFFFFFF;
+        }
+    }
+    else if (smcNORSRAMConfig->bank == SMC_BANK1_NORSRAM_3)
+    {
+        SMC_Bank1->CSCTRL3_B.ADMUXEN   = smcNORSRAMConfig->dataAddressMux;
+        SMC_Bank1->CSCTRL3_B.MTYPECFG  = smcNORSRAMConfig->memoryType;
+        SMC_Bank1->CSCTRL3_B.MDBWIDCFG = smcNORSRAMConfig->memoryDataWidth;
+        SMC_Bank1->CSCTRL3_B.BURSTEN = smcNORSRAMConfig->burstAcceesMode;
+        SMC_Bank1->CSCTRL3_B.WSASYNCEN = smcNORSRAMConfig->asynchronousWait;
+        SMC_Bank1->CSCTRL3_B.WSPOLCFG = smcNORSRAMConfig->waitSignalPolarity;
+        SMC_Bank1->CSCTRL3_B.WRAPBEN = smcNORSRAMConfig->wrapMode;
+        SMC_Bank1->CSCTRL3_B.WTIMCFG = smcNORSRAMConfig->waitSignalActive;
+        SMC_Bank1->CSCTRL3_B.WREN = smcNORSRAMConfig->writeOperation;
+        SMC_Bank1->CSCTRL3_B.WAITEN = smcNORSRAMConfig->waiteSignal;
+        SMC_Bank1->CSCTRL3_B.EXTMODEEN = smcNORSRAMConfig->extendedMode;
+        SMC_Bank1->CSCTRL3_B.WRBURSTEN = smcNORSRAMConfig->writeBurst;
+
+        if (smcNORSRAMConfig->memoryType == SMC_MEMORY_TYPE_NOR)
+        {
+            SMC_Bank1->CSCTRL3_B.NORFMACCEN = BIT_SET;
+        }
+
+        SMC_Bank1->CSTIM3_B.ADDRSETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressSetupTime;
+        SMC_Bank1->CSTIM3_B.ADDRHLDCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressHodeTime;
+        SMC_Bank1->CSTIM3_B.DATASETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataSetupTime;
+        SMC_Bank1->CSTIM3_B.BUSTURNCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->busTurnaroundTime;
+        SMC_Bank1->CSTIM3_B.CLKDIVCFG = \
+                                        smcNORSRAMConfig->readWriteTimingStruct->clockDivision;
+        SMC_Bank1->CSTIM3_B.DATALATCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataLatency;
+        SMC_Bank1->CSTIM3_B.ASYNCACCCFG = \
+                                          smcNORSRAMConfig->readWriteTimingStruct->accessMode;
+
+        if (smcNORSRAMConfig->extendedMode == SMC_EXTENDEN_MODE_ENABLE)
+        {
+            SMC_Bank1E->WRTTIM3_B.ADDRSETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressSetupTime;
+            SMC_Bank1E->WRTTIM3_B.ADDRHLDCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressHodeTime;
+            SMC_Bank1E->WRTTIM3_B.DATASETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->dataSetupTime;
+            SMC_Bank1E->WRTTIM3_B.BUSTURNCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->busTurnaroundTime;
+            SMC_Bank1E->WRTTIM3_B.ASYNCACCCFG = \
+                                                smcNORSRAMConfig->writeTimingStruct->accessMode;
+        }
+        else
+        {
+            SMC_Bank1E->WRTTIM3 = 0x0FFFFFFF;
+        }
+    }
+    else if (smcNORSRAMConfig->bank == SMC_BANK1_NORSRAM_4)
+    {
+        SMC_Bank1->CSCTRL4_B.ADMUXEN   = smcNORSRAMConfig->dataAddressMux;
+        SMC_Bank1->CSCTRL4_B.MTYPECFG  = smcNORSRAMConfig->memoryType;
+        SMC_Bank1->CSCTRL4_B.MDBWIDCFG = smcNORSRAMConfig->memoryDataWidth;
+        SMC_Bank1->CSCTRL4_B.BURSTEN = smcNORSRAMConfig->burstAcceesMode;
+        SMC_Bank1->CSCTRL4_B.WSASYNCEN = smcNORSRAMConfig->asynchronousWait;
+        SMC_Bank1->CSCTRL4_B.WSPOLCFG = smcNORSRAMConfig->waitSignalPolarity;
+        SMC_Bank1->CSCTRL4_B.WRAPBEN = smcNORSRAMConfig->wrapMode;
+        SMC_Bank1->CSCTRL4_B.WTIMCFG = smcNORSRAMConfig->waitSignalActive;
+        SMC_Bank1->CSCTRL4_B.WREN = smcNORSRAMConfig->writeOperation;
+        SMC_Bank1->CSCTRL4_B.WAITEN = smcNORSRAMConfig->waiteSignal;
+        SMC_Bank1->CSCTRL4_B.EXTMODEEN = smcNORSRAMConfig->extendedMode;
+        SMC_Bank1->CSCTRL4_B.WRBURSTEN = smcNORSRAMConfig->writeBurst;
+
+        if (smcNORSRAMConfig->memoryType == SMC_MEMORY_TYPE_NOR)
+        {
+            SMC_Bank1->CSCTRL4_B.NORFMACCEN = BIT_SET;
+        }
+
+        SMC_Bank1->CSTIM4_B.ADDRSETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressSetupTime;
+        SMC_Bank1->CSTIM4_B.ADDRHLDCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->addressHodeTime;
+        SMC_Bank1->CSTIM4_B.DATASETCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataSetupTime;
+        SMC_Bank1->CSTIM4_B.BUSTURNCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->busTurnaroundTime;
+        SMC_Bank1->CSTIM4_B.CLKDIVCFG = \
+                                        smcNORSRAMConfig->readWriteTimingStruct->clockDivision;
+        SMC_Bank1->CSTIM4_B.DATALATCFG = \
+                                         smcNORSRAMConfig->readWriteTimingStruct->dataLatency;
+        SMC_Bank1->CSTIM4_B.ASYNCACCCFG = \
+                                          smcNORSRAMConfig->readWriteTimingStruct->accessMode;
+
+        if (smcNORSRAMConfig->extendedMode == SMC_EXTENDEN_MODE_ENABLE)
+        {
+            SMC_Bank1E->WRTTIM4_B.ADDRSETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressSetupTime;
+            SMC_Bank1E->WRTTIM4_B.ADDRHLDCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->addressHodeTime;
+            SMC_Bank1E->WRTTIM4_B.DATASETCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->dataSetupTime;
+            SMC_Bank1E->WRTTIM4_B.BUSTURNCFG = \
+                                               smcNORSRAMConfig->writeTimingStruct->busTurnaroundTime;
+            SMC_Bank1E->WRTTIM4_B.ASYNCACCCFG = \
+                                                smcNORSRAMConfig->writeTimingStruct->accessMode;
+        }
+        else
+        {
+            SMC_Bank1E->WRTTIM4 = 0x0FFFFFFF;
+        }
+    }
+}
+
+/*!
+ * @brief     Config the SMC NAND Banks according to the specified parameters in the smcNANDConfig.
+ *
+ * @param     smcNANDConfig : Point to a SMC_NANDConfig_T structure.
+ *
+ * @retval    None
+ */
+void SMC_ConfigNAND(SMC_NANDConfig_T *smcNANDConfig)
+{
+    if (smcNANDConfig->bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->CTRL2_B.WAITFEN = smcNANDConfig->waitFeature;
+        SMC_Bank2->CTRL2_B.DBWIDCFG = smcNANDConfig->memoryDataWidth;
+        SMC_Bank2->CTRL2_B.ECCEN = smcNANDConfig->ECC;
+        SMC_Bank2->CTRL2_B.ECCPSCFG = smcNANDConfig->ECCPageSize;
+        SMC_Bank2->CTRL2_B.C2RDCFG = smcNANDConfig->TCLRSetupTime;
+        SMC_Bank2->CTRL2_B.A2RDCFG = smcNANDConfig->TARSetupTime;
+        SMC_Bank2->CTRL2_B.MTYPECFG = BIT_SET;
+
+        SMC_Bank2->CMSTIM2_B.SET2 = \
+                                    smcNANDConfig->commonSpaceTimingStruct->setupTime;
+        SMC_Bank2->CMSTIM2_B.WAIT2 = \
+                                     smcNANDConfig->commonSpaceTimingStruct->waitSetupTime;
+        SMC_Bank2->CMSTIM2_B.HLD2 = \
+                                    smcNANDConfig->commonSpaceTimingStruct->holdSetupTime;
+        SMC_Bank2->CMSTIM2_B.HIZ2 = \
+                                    smcNANDConfig->commonSpaceTimingStruct->HiZSetupTime;
+
+        SMC_Bank2->AMSTIM2_B.SET2 = \
+                                    smcNANDConfig->attributeSpaceTimingStruct->setupTime;
+        SMC_Bank2->AMSTIM2_B.WAIT2 = \
+                                     smcNANDConfig->attributeSpaceTimingStruct->waitSetupTime;
+        SMC_Bank2->AMSTIM2_B.HLD2 = \
+                                    smcNANDConfig->attributeSpaceTimingStruct->holdSetupTime;
+        SMC_Bank2->AMSTIM2_B.HIZ2 = \
+                                    smcNANDConfig->attributeSpaceTimingStruct->HiZSetupTime;
+    }
+    else if (smcNANDConfig->bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->CTRL3_B.WAITFEN = smcNANDConfig->waitFeature;
+        SMC_Bank3->CTRL3_B.DBWIDCFG = smcNANDConfig->memoryDataWidth;
+        SMC_Bank3->CTRL3_B.ECCEN = smcNANDConfig->ECC;
+        SMC_Bank3->CTRL3_B.ECCPSCFG = smcNANDConfig->ECCPageSize;
+        SMC_Bank3->CTRL3_B.C2RDCFG = smcNANDConfig->TCLRSetupTime;
+        SMC_Bank3->CTRL3_B.A2RDCFG = smcNANDConfig->TARSetupTime;
+        SMC_Bank3->CTRL3_B.MTYPECFG = BIT_SET;
+
+        SMC_Bank3->CMSTIM3_B.SET3 = \
+                                    smcNANDConfig->commonSpaceTimingStruct->setupTime;
+        SMC_Bank3->CMSTIM3_B.WAIT3 = \
+                                     smcNANDConfig->commonSpaceTimingStruct->waitSetupTime;
+        SMC_Bank3->CMSTIM3_B.HLD3 = \
+                                    smcNANDConfig->commonSpaceTimingStruct->holdSetupTime;
+        SMC_Bank3->CMSTIM3_B.HIZ3 = \
+                                    smcNANDConfig->commonSpaceTimingStruct->HiZSetupTime;
+
+        SMC_Bank3->AMSTIM3_B.SET3 = \
+                                    smcNANDConfig->attributeSpaceTimingStruct->setupTime;
+        SMC_Bank3->AMSTIM3_B.WAIT3 = \
+                                     smcNANDConfig->attributeSpaceTimingStruct->waitSetupTime;
+        SMC_Bank3->AMSTIM3_B.HLD3 = \
+                                    smcNANDConfig->attributeSpaceTimingStruct->holdSetupTime;
+        SMC_Bank3->AMSTIM3_B.HIZ3 = \
+                                    smcNANDConfig->attributeSpaceTimingStruct->HiZSetupTime;
+    }
+}
+
+/*!
+ * @brief     Config the SMC PCCARD according to the specified parameters in the smcPCCardConfig.
+ *
+ * @param     smcPCCardConfig: Point to a SMC_PCCARDConfig_T structure.
+ *
+ * @retval    None
+ */
+void SMC_ConfigPCCard(SMC_PCCARDConfig_T *smcPCCardConfig)
+{
+    SMC_Bank4->CTRL4_B.WAITFEN = smcPCCardConfig->waitFeature;
+    SMC_Bank4->CTRL4_B.C2RDCFG = smcPCCardConfig->TCLRSetupTime;
+    SMC_Bank4->CTRL4_B.A2RDCFG = smcPCCardConfig->TARSetupTime;
+    SMC_Bank4->CTRL4_B.DBWIDCFG = BIT_SET;
+
+    SMC_Bank4->CMSTIM4_B.SET4 = \
+                                smcPCCardConfig->commonSpaceTimingStruct->setupTime;
+    SMC_Bank4->CMSTIM4_B.WAIT4 = \
+                                 smcPCCardConfig->commonSpaceTimingStruct->waitSetupTime;
+    SMC_Bank4->CMSTIM4_B.HLD4 = \
+                                smcPCCardConfig->commonSpaceTimingStruct->holdSetupTime;
+    SMC_Bank4->CMSTIM4_B.HIZ4 = \
+                                smcPCCardConfig->commonSpaceTimingStruct->HiZSetupTime;
+
+    SMC_Bank4->AMSTIM4_B.SET4 = \
+                                smcPCCardConfig->attributeSpaceTimingStruct->setupTime;
+    SMC_Bank4->AMSTIM4_B.WAIT4 = \
+                                 smcPCCardConfig->attributeSpaceTimingStruct->waitSetupTime;
+    SMC_Bank4->AMSTIM4_B.HLD4 = \
+                                smcPCCardConfig->attributeSpaceTimingStruct->holdSetupTime;
+    SMC_Bank4->AMSTIM4_B.HIZ4 = \
+                                smcPCCardConfig->attributeSpaceTimingStruct->HiZSetupTime;
+
+    SMC_Bank4->IOSTIM4_B.SET = \
+                               smcPCCardConfig->IOSpaceTimingStruct->setupTime;
+    SMC_Bank4->IOSTIM4_B.WAIT = \
+                                smcPCCardConfig->IOSpaceTimingStruct->waitSetupTime;
+    SMC_Bank4->IOSTIM4_B.HLD = \
+                               smcPCCardConfig->IOSpaceTimingStruct->holdSetupTime;
+    SMC_Bank4->IOSTIM4_B.HIZ = \
+                               smcPCCardConfig->IOSpaceTimingStruct->HiZSetupTime;
+}
+
+/*!
+ * @brief     Fills each smcNORSRAMConfig member with its default value.
+ *
+ * @param     smcNORSRAMConfig : Point to a SMC_NORSRAMConfig_T structure.
+ *
+ * @retval    None
+ */
+void SMC_ConfigNORSRAMStructInit(SMC_NORSRAMConfig_T *smcNORSRAMConfig)
+{
+    smcNORSRAMConfig->bank = SMC_BANK1_NORSRAM_1;
+    smcNORSRAMConfig->dataAddressMux = SMC_DATA_ADDRESS_MUX_ENABLE;
+    smcNORSRAMConfig->memoryType = SMC_MEMORY_TYPE_SRAM;
+    smcNORSRAMConfig->memoryDataWidth = SMC_MEMORY_DATA_WIDTH_8BIT;
+    smcNORSRAMConfig->burstAcceesMode = SMC_BURST_ACCESS_MODE_DISABLE;
+    smcNORSRAMConfig->asynchronousWait = SMC_ASYNCHRONOUS_WAIT_DISABLE;
+    smcNORSRAMConfig->waitSignalPolarity = SMC_WAIT_SIGNAL_POLARITY_LOW;
+    smcNORSRAMConfig->wrapMode = SMC_WRAP_MODE_DISABLE;
+    smcNORSRAMConfig->waitSignalActive = SMC_WAIT_SIGNAL_ACTIVE_BEFORE_WAIT_STATE;
+    smcNORSRAMConfig->writeOperation = SMC_WRITE_OPERATION_ENABLE;
+    smcNORSRAMConfig->waiteSignal = SMC_WAITE_SIGNAL_ENABLE;
+    smcNORSRAMConfig->extendedMode = SMC_EXTENDEN_MODE_DISABLE;
+    smcNORSRAMConfig->writeBurst = SMC_WRITE_BURST_DISABLE;
+    smcNORSRAMConfig->readWriteTimingStruct->addressSetupTime = 0xF;
+    smcNORSRAMConfig->readWriteTimingStruct->addressHodeTime = 0xF;
+    smcNORSRAMConfig->readWriteTimingStruct->dataSetupTime = 0xFF;
+    smcNORSRAMConfig->readWriteTimingStruct->busTurnaroundTime = 0xF;
+    smcNORSRAMConfig->readWriteTimingStruct->clockDivision = 0xF;
+    smcNORSRAMConfig->readWriteTimingStruct->dataLatency = 0xF;
+    smcNORSRAMConfig->readWriteTimingStruct->accessMode = SMC_ACCESS_MODE_A;
+    smcNORSRAMConfig->writeTimingStruct->addressSetupTime = 0xF;
+    smcNORSRAMConfig->writeTimingStruct->addressHodeTime = 0xF;
+    smcNORSRAMConfig->writeTimingStruct->dataSetupTime = 0xFF;
+    smcNORSRAMConfig->writeTimingStruct->busTurnaroundTime = 0xF;
+    smcNORSRAMConfig->writeTimingStruct->clockDivision = 0xF;
+    smcNORSRAMConfig->writeTimingStruct->dataLatency = 0xF;
+    smcNORSRAMConfig->writeTimingStruct->accessMode = SMC_ACCESS_MODE_A;
+}
+
+/*!
+ * @brief     Fills each smcNANDConfig member with its default value.
+ *
+ * @param     smcNANDConfig : Point to a SMC_NANDConfig_T structure.
+ *
+ * @retval    None
+ */
+void SMC_ConfigNANDStructInit(SMC_NANDConfig_T *smcNANDConfig)
+{
+    smcNANDConfig->bank = SMC_BANK2_NAND;
+    smcNANDConfig->waitFeature = SMC_WAIT_FEATURE_DISABLE;
+    smcNANDConfig->memoryDataWidth = SMC_MEMORY_DATA_WIDTH_8BIT;
+    smcNANDConfig->ECC = SMC_ECC_DISABLE;
+    smcNANDConfig->ECCPageSize = SMC_ECC_PAGE_SIZE_BYTE_256;
+    smcNANDConfig->TCLRSetupTime = 0x0;
+    smcNANDConfig->TARSetupTime = 0x0;
+    smcNANDConfig->commonSpaceTimingStruct->setupTime = 0xFC;
+    smcNANDConfig->commonSpaceTimingStruct->waitSetupTime = 0xFC;
+    smcNANDConfig->commonSpaceTimingStruct->holdSetupTime = 0xFC;
+    smcNANDConfig->commonSpaceTimingStruct->HiZSetupTime = 0xFC;
+    smcNANDConfig->attributeSpaceTimingStruct->setupTime = 0xFC;
+    smcNANDConfig->attributeSpaceTimingStruct->waitSetupTime = 0xFC;
+    smcNANDConfig->attributeSpaceTimingStruct->holdSetupTime = 0xFC;
+    smcNANDConfig->attributeSpaceTimingStruct->HiZSetupTime = 0xFC;
+}
+
+/*!
+ * @brief     Fills each smcPCCardConfig member with its default value.
+ *
+ * @param     smcPCCardConfig : Point to a SMC_PCCARDConfig_T structure.
+ *
+ * @retval    None
+ */
+void SMC_ConfigPCCardStructInit(SMC_PCCARDConfig_T *smcPCCardConfig)
+{
+    smcPCCardConfig->waitFeature = SMC_WAIT_FEATURE_DISABLE;
+    smcPCCardConfig->TCLRSetupTime = 0x0;
+    smcPCCardConfig->TARSetupTime = 0x0;
+    smcPCCardConfig->commonSpaceTimingStruct->setupTime = 0xFC;
+    smcPCCardConfig->commonSpaceTimingStruct->waitSetupTime = 0xFC;
+    smcPCCardConfig->commonSpaceTimingStruct->holdSetupTime = 0xFC;
+    smcPCCardConfig->commonSpaceTimingStruct->HiZSetupTime = 0xFC;
+    smcPCCardConfig->attributeSpaceTimingStruct->setupTime = 0xFC;
+    smcPCCardConfig->attributeSpaceTimingStruct->waitSetupTime = 0xFC;
+    smcPCCardConfig->attributeSpaceTimingStruct->holdSetupTime = 0xFC;
+    smcPCCardConfig->attributeSpaceTimingStruct->HiZSetupTime = 0xFC;
+    smcPCCardConfig->IOSpaceTimingStruct->setupTime = 0xFC;
+    smcPCCardConfig->IOSpaceTimingStruct->waitSetupTime = 0xFC;
+    smcPCCardConfig->IOSpaceTimingStruct->holdSetupTime = 0xFC;
+    smcPCCardConfig->IOSpaceTimingStruct->HiZSetupTime = 0xFC;
+}
+
+/*!
+ * @brief     Enables the specified NOR/SRAM Memory Bank.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK1_NORSRAM_1 : SMC Bank1 NOR/SRAM1
+ *                  @arg SMC_BANK1_NORSRAM_2 : SMC Bank1 NOR/SRAM2
+ *                  @arg SMC_BANK1_NORSRAM_3 : SMC Bank1 NOR/SRAM3
+ *                  @arg SMC_BANK1_NORSRAM_4 : SMC Bank1 NOR/SRAM4
+ *
+ * @retval    None
+ */
+void SMC_EnableNORSRAM(SMC_BANK1_NORSRAM_T bank)
+{
+    if (bank == SMC_BANK1_NORSRAM_1)
+    {
+        SMC_Bank1->CSCTRL1_B.MBKEN = BIT_SET;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_2)
+    {
+        SMC_Bank1->CSCTRL2_B.MBKEN = BIT_SET;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_3)
+    {
+        SMC_Bank1->CSCTRL3_B.MBKEN = BIT_SET;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_4)
+    {
+        SMC_Bank1->CSCTRL4_B.MBKEN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disbles the specified NOR/SRAM Memory Bank.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK1_NORSRAM_1 : SMC Bank1 NOR/SRAM1
+ *                  @arg SMC_BANK1_NORSRAM_2 : SMC Bank1 NOR/SRAM2
+ *                  @arg SMC_BANK1_NORSRAM_3 : SMC Bank1 NOR/SRAM3
+ *                  @arg SMC_BANK1_NORSRAM_4 : SMC Bank1 NOR/SRAM4
+ *
+ * @retval    None
+ */
+void SMC_DisableNORSRAM(SMC_BANK1_NORSRAM_T bank)
+{
+    if (bank == SMC_BANK1_NORSRAM_1)
+    {
+        SMC_Bank1->CSCTRL1_B.MBKEN = BIT_RESET;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_2)
+    {
+        SMC_Bank1->CSCTRL2_B.MBKEN = BIT_RESET;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_3)
+    {
+        SMC_Bank1->CSCTRL3_B.MBKEN = BIT_RESET;
+    }
+    else if (bank == SMC_BANK1_NORSRAM_4)
+    {
+        SMC_Bank1->CSCTRL4_B.MBKEN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the specified NAND Memory Bank.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK2_NAND : SMC Bank2 NAND
+ *                  @arg SMC_BANK3_NAND : SMC Bank3 NAND
+ *
+ * @retval    None
+ */
+void SMC_EnableNAND(SMC_BANK_NAND_T bank)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->CTRL2_B.MBKEN = BIT_SET;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->CTRL3_B.MBKEN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disbles the specified NAND Memory Bank.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK2_NAND : SMC Bank2 NAND
+ *                  @arg SMC_BANK3_NAND : SMC Bank3 NAND
+ *
+ * @retval    None
+ */
+void SMC_DisableNAND(SMC_BANK_NAND_T bank)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->CTRL2_B.MBKEN = BIT_RESET;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->CTRL3_B.MBKEN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the specified PC Card Memory Bank.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SMC_EnablePCCARD(void)
+{
+    SMC_Bank4->CTRL4_B.MBKEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the specified PC Card Memory Bank.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SMC_DisablePCCARD(void)
+{
+    SMC_Bank4->CTRL4_B.MBKEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enbles the SMC NAND ECC feature.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK2_NAND : SMC Bank2 NAND
+ *                  @arg SMC_BANK3_NAND : SMC Bank3 NAND
+ *
+ * @retval    None
+ */
+void SMC_EnableNANDECC(SMC_BANK_NAND_T bank)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->CTRL2_B.ECCEN = BIT_SET;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->CTRL3_B.ECCEN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disbles or disables the SMC NAND ECC feature.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK2_NAND : SMC Bank2 NAND
+ *                  @arg SMC_BANK3_NAND : SMC Bank3 NAND
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void SMC_DisableNANDECC(SMC_BANK_NAND_T bank)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->CTRL2_B.ECCEN = BIT_RESET;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->CTRL3_B.ECCEN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Read the error correction code register value.
+ *
+ * @param     bank: Selects the SMC Bank.
+ *                  The parameter can be one of following values:
+ *                  @arg SMC_BANK2_NAND : SMC Bank2 NAND
+ *                  @arg SMC_BANK3_NAND : SMC Bank3 NAND
+ *
+ * @retval    The value of Error Correction Code (ECC).
+ */
+uint32_t  SMC_ReadECC(SMC_BANK_NAND_T bank)
+{
+    uint32_t eccval = 0x00000000;
+
+    if (bank == SMC_BANK2_NAND)
+    {
+        eccval = SMC_Bank2->ECCRS2;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        eccval = SMC_Bank3->ECCRS3;
+    }
+
+    return eccval;
+}
+
+/*!
+ * @brief    Enables the specified SMC interrupts.
+ *
+ * @param    bank: Selects the SMC Bank.
+ *                 The parameter can be one of following values:
+ *                 @arg SMC_BANK2_NAND   : SMC Bank2 NAND
+ *                 @arg SMC_BANK3_NAND   : SMC Bank3 NAND
+ *                 @arg SMC_BANK4_PCCARD : SMC Bank4 PCCARD
+ *
+ * @param    interrupt: Select the SMC interrupt sources.
+ *                      This parameter can be any combination of the following values:
+ *                      @arg SMC_INT_EDGE_RISING  : Rising edge detection interrupt.
+ *                      @arg SMC_INT_LEVEL_HIGH   : High level detection interrupt.
+ *                      @arg SMC_INT_EDGE_FALLING : Falling edge detection interrupt.
+ *
+ * @retval   None
+ */
+void SMC_EnableInterrupt(SMC_BANK_NAND_T bank, uint32_t interrupt)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->STSINT2 |= interrupt;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->STSINT3 |= interrupt;
+    }
+    else
+    {
+        SMC_Bank4->STSINT4 |= interrupt;
+    }
+}
+
+/*!
+ * @brief    Enables the specified SMC interrupts.
+ *
+ * @param    bank: Selects the SMC Bank.
+ *                 The parameter can be one of following values:
+ *                 @arg SMC_BANK2_NAND   : SMC Bank2 NAND
+ *                 @arg SMC_BANK3_NAND   : SMC Bank3 NAND
+ *                 @arg SMC_BANK4_PCCARD : SMC Bank4 PCCARD
+ *
+ * @param    interrupt: Select the SMC interrupt sources.
+ *                      This parameter can be any combination of the following values:
+ *                      @arg SMC_INT_EDGE_RISING  : Rising edge detection interrupt.
+ *                      @arg SMC_INT_LEVEL_HIGH   : High level edge detection interrupt.
+ *                      @arg SMC_INT_EDGE_FALLING : Falling edge detection interrupt.
+ *
+ * @retval   None
+ */
+void SMC_DisableInterrupt(SMC_BANK_NAND_T bank, uint32_t interrupt)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->STSINT2 &= ~interrupt;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->STSINT3 &= ~interrupt;
+    }
+    else
+    {
+        SMC_Bank4->STSINT4 &= ~interrupt;
+    }
+}
+
+/*!
+ * @brief     Read the status of specified SMC flag.
+ *
+ * @param    bank: Selects the SMC Bank.
+ *                 The parameter can be one of following values:
+ *                 @arg SMC_BANK2_NAND   : SMC Bank2 NAND
+ *                 @arg SMC_BANK3_NAND   : SMC Bank3 NAND
+ *                 @arg SMC_BANK4_PCCARD : SMC Bank4 PCCARD
+ *
+ * @param    flag: Select the SMC interrupt sources.
+ *                 This parameter can be one of the following values:
+ *                 @arg SMC_FLAG_EDGE_RISING  : Rising egde detection Flag.
+ *                 @arg SMC_FLAG_LEVEL_HIGH   : High level detection Flag.
+ *                 @arg SMC_FLAG_EDGE_FALLING : Falling egde detection Flag.
+ *                 @arg SMC_FLAG_FIFO_EMPTY   : FIFO empty Flag.
+ *
+ * @retval    SET or RESET
+ *
+ * @note
+ */
+uint16_t SMC_ReadStatusFlag(SMC_BANK_NAND_T bank, SMC_FLAG_T flag)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        return (SMC_Bank2->STSINT2 & flag) ? SET : RESET;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        return (SMC_Bank3->STSINT3 & flag) ? SET : RESET;
+    }
+    else
+    {
+        return (SMC_Bank4->STSINT4 & flag) ? SET : RESET;
+    }
+}
+
+/*!
+ * @brief     Clears the SMC's pending flags.
+ *
+ * @param    bank: Selects the SMC Bank.
+ *                 The parameter can be one of following values:
+ *                 @arg SMC_BANK2_NAND   : SMC Bank2 NAND
+ *                 @arg SMC_BANK3_NAND   : SMC Bank3 NAND
+ *                 @arg SMC_BANK4_PCCARD : SMC Bank4 PCCARD
+ *
+ * @param    flag: Select the SMC interrupt sources.
+ *                 This parameter can be any combination of the following values:
+ *                 @arg SMC_FLAG_EDGE_RISING  : Rising egde detection Flag.
+ *                 @arg SMC_FLAG_LEVEL_HIGH   : High level detection Flag.
+ *                 @arg SMC_FLAG_EDGE_FALLING : Falling egde detection Flag.
+ *
+ * @retval    None
+ */
+void SMC_ClearStatusFlag(SMC_BANK_NAND_T bank, uint32_t flag)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->STSINT2 &= ~flag;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->STSINT3 &= ~flag;
+    }
+    else
+    {
+        SMC_Bank4->STSINT4 &= ~flag;
+    }
+}
+
+/*!
+ * @brief    Read the specified SMC interrupt has occurred or not.
+ *
+ * @param    bank: Selects the SMC Bank.
+ *                 The parameter can be one of following values:
+ *                 @arg SMC_BANK2_NAND   : SMC Bank2 NAND
+ *                 @arg SMC_BANK3_NAND   : SMC Bank3 NAND
+ *                 @arg SMC_BANK4_PCCARD : SMC Bank4 PCCARD
+ *
+ * @param    flag: Select the SMC interrupt source.
+ *                 This parameter can be one of the following values:
+ *                 @arg SMC_INT_EDGE_RISING  : Rising edge detection interrupt.
+ *                 @arg SMC_INT_LEVEL_HIGH   : High level edge detection interrupt.
+ *                 @arg SMC_INT_EDGE_FALLING : Falling edge detection interrupt.
+ *
+ * @retval   The status of specified SMC interrupt source.
+ */
+uint16_t  SMC_ReadIntFlag(SMC_BANK_NAND_T bank, SMC_INT_T flag)
+{
+    uint32_t tmpStatus = 0x0, itstatus = 0x0, itenable = 0x0;
+
+    if (bank == SMC_BANK2_NAND)
+    {
+        tmpStatus = SMC_Bank2->STSINT2;
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        tmpStatus = SMC_Bank3->STSINT3;
+    }
+    else
+    {
+        tmpStatus = SMC_Bank4->STSINT4;
+    }
+
+    itstatus = tmpStatus & flag;
+    itenable = tmpStatus & (flag >> 3);
+
+    if ((itstatus != RESET) && (itenable != RESET))
+    {
+        return SET;
+    }
+    else
+    {
+        return RESET;
+    }
+}
+
+/*!
+ * @brief    Clears the SMC's interrupt Flag.
+ *
+ * @param    bank: Selects the SMC Bank.
+ *                 The parameter can be one of following values:
+ *                 @arg SMC_BANK2_NAND   : SMC Bank2 NAND
+ *                 @arg SMC_BANK3_NAND   : SMC Bank3 NAND
+ *                 @arg SMC_BANK4_PCCARD : SMC Bank4 PCCARD
+ *
+ * @param    interrupt: Select the SMC interrupt sources.
+ *                      This parameter can be any combination of the following values:
+ *                      @arg SMC_INT_EDGE_RISING  : Rising edge detection interrupt.
+ *                      @arg SMC_INT_LEVEL_HIGH   : High level edge detection interrupt.
+ *                      @arg SMC_INT_EDGE_FALLING : Falling edge detection interrupt.
+ *
+ * @retval   None
+ */
+void SMC_ClearIntFlag(SMC_BANK_NAND_T bank, uint32_t flag)
+{
+    if (bank == SMC_BANK2_NAND)
+    {
+        SMC_Bank2->STSINT2 &= ~(flag >> 3);
+    }
+    else if (bank == SMC_BANK3_NAND)
+    {
+        SMC_Bank3->STSINT3 &= ~(flag >> 3);
+    }
+    else
+    {
+        SMC_Bank4->STSINT4 &= ~(flag >> 3);
+    }
+}
+
+/**@} end of group SMC_Functions */
+/**@} end of group SMC_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 714 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_spi.c

@@ -0,0 +1,714 @@
+/*!
+ * @file        apm32f4xx_spi.c
+ *
+ * @brief       This file provides all the SPI firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_spi.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup SPI_Driver
+  * @brief SPI driver modules
+  @{
+*/
+
+/** @defgroup SPI_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset the specified SPIx peripheral
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6
+ *
+ * @retval    None
+ */
+void SPI_I2S_Reset(SPI_T *spi)
+{
+    if (spi == SPI1)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SPI1);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SPI1);
+    }
+    else if (spi == SPI2)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_SPI2);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_SPI2);
+    }
+    else if (spi == SPI3)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_SPI3);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_SPI3);
+    }
+    else if (spi == SPI4)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SPI4);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SPI4);
+    }
+    else if (spi == SPI5)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SPI5);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SPI5);
+    }
+    else if (spi == SPI6)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SPI6);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SPI6);
+    }
+}
+
+/*!
+ * @brief     Config the SPI peripheral according to the specified parameters in the spiConfig
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @param     spiConfig: pointer to a SPI_Config_T structure
+ *
+ * @retval    None
+ */
+void SPI_Config(SPI_T *spi, SPI_Config_T *spiConfig)
+{
+    spi->CTRL1_B.MSMCFG = spiConfig->mode;
+    spi->CTRL1_B.ISSEL = spiConfig->mode;
+    spi->CTRL1_B.DFLSEL = spiConfig->length;
+    spi->CTRL1_B.CPHA = spiConfig->phase;
+    spi->CTRL1_B.CPOL = spiConfig->polarity;
+    spi->CTRL1_B.SSEN = spiConfig->nss;
+    spi->CTRL1_B.LSBSEL = spiConfig->firstBit;
+    /** 1 line or 2 lines */
+    spi->CTRL1_B.BMEN = spiConfig->direction & 0x0001;
+    /** Tx or Rx in 1 line */
+    spi->CTRL1_B.BMOEN = (spiConfig->direction & 0x0010) >> 4;
+    /** receive only or full-duplex in 2 lines */
+    spi->CTRL1_B.RXOMEN = (spiConfig->direction & 0x0100) >> 8;
+    spi->CTRL1_B.BRSEL = spiConfig->baudrateDiv;
+
+    spi->CRCPOLY_B.CRCPOLY = spiConfig->crcPolynomial;
+}
+
+/*!
+ * @brief     Config the I2S peripheral according to the specified parameters in the spiConfig
+ *
+ * @param     spi: The SPIx can be 2,3
+ *
+ * @param     i2sConfig: pointer to a I2S_Config_T structure
+ *
+ * @retval    None
+ */
+void I2S_Config(SPI_T *spi, I2S_Config_T *i2sConfig)
+{
+    uint16_t i2sDiv = 2, i2sOdd = 0, packetSize = 1;
+    uint32_t tmp = 0;
+    uint32_t sysClock = 0;
+
+    /* Clear MODESEL, I2SEN, I2SMOD, PFSSEL, I2SSSEL, CPOL, DATALEN and CHLEN bits */
+    spi->I2SCFG &= 0xF040;
+    spi->I2SPSC  = 0x0002;
+
+    if (i2sConfig->audioDiv == I2S_AUDIO_DIV_DEFAULT)
+    {
+        i2sDiv = 2;
+        i2sOdd = 0;
+    }
+    else
+    {
+        if (i2sConfig->length == I2S_DATA_LENGHT_16B)
+        {
+            packetSize = 1;
+        }
+        else
+        {
+            packetSize = 2;
+        }
+
+        sysClock = RCM_ReadSYSCLKFreq();
+
+        if (i2sConfig->MCLKOutput == I2S_MCLK_OUTPUT_ENABLE)
+        {
+            tmp = (uint16_t)(((((sysClock / 256) * 10) / i2sConfig->audioDiv)) + 5);
+        }
+        else
+        {
+            tmp = (uint16_t)(((((sysClock / (32 * packetSize)) * 10) / i2sConfig->audioDiv)) + 5);
+        }
+
+        tmp = tmp / 10;
+
+        i2sOdd = (uint16_t)(tmp & (uint16_t)0x0001);
+        i2sDiv = (uint16_t)((tmp - i2sOdd) / 2);
+
+        if ((i2sDiv < 2) || (i2sDiv > 0xFF))
+        {
+            i2sDiv = 2;
+            i2sOdd = 0;
+        }
+    }
+
+    spi->I2SPSC_B.I2SPSC = i2sDiv;
+    spi->I2SPSC_B.ODDPSC = i2sOdd;
+    spi->I2SPSC_B.MCOEN  = i2sConfig->MCLKOutput;
+
+    spi->I2SCFG_B.I2SMOD  = i2sConfig->mode;
+    spi->I2SCFG_B.I2SSSEL = i2sConfig->standard & 0x03;
+    spi->I2SCFG_B.PFSSEL  = (i2sConfig->standard & 0x10) >> 4;
+    spi->I2SCFG_B.CHLEN   = i2sConfig->length & 0x01;
+    spi->I2SCFG_B.DATLEN  = i2sConfig->length >> 1;
+    spi->I2SCFG_B.CPOL    = i2sConfig->polarity;
+
+    /** select I2S mode */
+    spi->I2SCFG_B.MODESEL = BIT_SET;
+}
+
+/*!
+ * @brief     Fills each SPI_Config_T member with its default value
+ *
+ * @param     spiConfig: pointer to a SPI_Config_T structure
+ *
+ * @retval    None
+ */
+void SPI_ConfigStructInit(SPI_Config_T *spiConfig)
+{
+    spiConfig->direction     = SPI_DIRECTION_2LINES_FULLDUPLEX;
+    spiConfig->mode          = SPI_MODE_SLAVE;
+    spiConfig->length        = SPI_DATA_LENGTH_8B;
+    spiConfig->polarity      = SPI_CLKPOL_LOW;
+    spiConfig->phase         = SPI_CLKPHA_1EDGE;
+    spiConfig->nss           = SPI_NSS_HARD;
+    spiConfig->baudrateDiv   = SPI_BAUDRATE_DIV_2;
+    spiConfig->firstBit      = SPI_FIRSTBIT_MSB;
+    spiConfig->crcPolynomial = 7;
+}
+
+/*!
+ * @brief     Fills each I2S_Config_T member with its default value
+ *
+ * @param     i2sConfig: pointer to a I2S_Config_T structure
+ *
+ * @retval    None
+ */
+void I2S_ConfigStructInit(I2S_Config_T *i2sConfig)
+{
+    i2sConfig->mode       = I2S_MODE_SLAVE_TX;
+    i2sConfig->standard   = I2S_STANDARD_PHILLIPS;
+    i2sConfig->length     = I2S_DATA_LENGHT_16B;
+    i2sConfig->MCLKOutput = I2S_MCLK_OUTPUT_DISABLE;
+    i2sConfig->audioDiv   = I2S_AUDIO_DIV_DEFAULT;
+    i2sConfig->polarity   = I2S_CLKPOL_LOW;
+}
+
+/*!
+ * @brief     Enables the specified SPI peripheral
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_Enable(SPI_T *spi)
+{
+    spi->CTRL1_B.SPIEN = BIT_SET;
+}
+
+/*!
+* @brief     Disable the specified SPI peripheral
+*
+* @param     spi: The SPIx can be 1,2,3,4,5,6.
+*
+* @retval    None
+*/
+void SPI_Disable(SPI_T *spi)
+{
+    spi->CTRL1_B.SPIEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the specified I2S peripheral
+ *
+ * @param     spi: The I2S can be SPI2,SPI3
+ *
+ * @retval    None
+ */
+void I2S_Enable(SPI_T *spi)
+{
+    spi->I2SCFG_B.I2SEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the specified I2S peripheral
+ *
+ * @param     spi: The I2S can be SPI2,SPI3
+ *
+ * @retval    None
+ */
+void I2S_Disable(SPI_T *spi)
+{
+    spi->I2SCFG_B.I2SEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the data size for the selected SPI.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @param     length: specifies the SPI data size.
+ *                    This parameter can be one of the following values:
+ *                    @arg SPI_DATA_LENGTH_16B : Set data frame format to 16bit
+ *                    @arg SPI_DATA_LENGTH_8B  : Set data frame format to 8bit
+ *
+ * @retval    None
+ */
+void SPI_ConfigDataSize(SPI_T *spi, SPI_DATA_LENGTH_T length)
+{
+    spi->CTRL1_B.DFLSEL = length;
+}
+
+/*!
+ * @brief     Configures the specified SPI data transfer direction
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @param     direction: Select the SPI data transfer direction
+ *                      The parameter can be one of following values:
+ *                      @arg SPI_DIRECTION_RX : Selects Rx receive direction
+ *                      @arg SPI_DIRECTION_TX : Selects Tx transmission direction
+ * @retval    None
+ */
+void SPI_ConfigBiDirectionalLine(SPI_T *spi, SPI_DIRECTION_SELECT_T direction)
+{
+    spi->CTRL1_B.BMOEN = direction;
+}
+/*!
+ * @brief     Set the SPI NSS internal by Software
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_SetSoftwareNSS(SPI_T *spi)
+{
+    spi->CTRL1_B.ISSEL = BIT_SET;
+}
+
+/*!
+ * @brief     Reset the SPI NSS internal by Software
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_ResetSoftwareNSS(SPI_T *spi)
+{
+    spi->CTRL1_B.ISSEL = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the specified SPI SS output
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_EnableSSOutput(SPI_T *spi)
+{
+    spi->CTRL2_B.SSOEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the specified SPI SS output
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_DisableSSOutput(SPI_T *spi)
+{
+    spi->CTRL2_B.SSOEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the specified SPI TI mode
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_EnableTIMode(SPI_T *spi)
+{
+    spi->CTRL2_B.FRFCFG = BIT_SET;
+}
+
+/*!
+* @brief     Disable the specified SPI TI mode
+*
+* @param     spi: The SPIx can be 1,2,3,4,5,6.
+*
+* @retval    None
+*/
+void SPI_DisableTIMode(SPI_T *spi)
+{
+    spi->CTRL2_B.FRFCFG = BIT_RESET;
+}
+
+/*!
+ * @brief  Configures the full-duplex mode for the I2S peripheral using its extension
+ *         I2S peripheral according to the specified parameters in the i2sConfig.
+ *
+ * @param  i2sExt: Specified the I2S peripheral extension block.
+ *                 The parameter can be one of following values:
+ *                 @arg I2S2ext : Extended I2S2
+ *                 @arg I2S3ext : Extended I2S3
+ *
+ * @param  i2sConfig: Pointer to the I2S_Config_T structure.
+ *
+ * @retval None
+ *
+ * @note   The structure pointed by i2sConfig parameter should be the same used for
+ *         the master I2S peripheral.
+ *
+ * @note   The I2S full-duplex extension only can be configured in slave mode.
+ */
+void I2S_ConfigFullDuplex(SPI_T *i2sExt, I2S_Config_T *i2sConfig)
+{
+    /** Reset I2SCFG and I2SPSC register */
+    i2sExt->I2SCFG = 0;
+    i2sExt->I2SPSC = 0x0002;
+
+    /** Config the extended I2S */
+    if ((i2sConfig->mode == I2S_MODE_MASTER_TX) || (i2sConfig->mode == I2S_MODE_SLAVE_TX))
+    {
+        i2sExt->I2SCFG_B.I2SMOD  = I2S_MODE_SLAVE_RX;
+        i2sExt->I2SCFG_B.I2SSSEL = i2sConfig->standard & 0x03;
+        i2sExt->I2SCFG_B.PFSSEL  = (i2sConfig->standard & 0x10) >> 4;
+        i2sExt->I2SCFG_B.CHLEN   = i2sConfig->length & 0x01;
+        i2sExt->I2SCFG_B.DATLEN  = i2sConfig->length >> 1;
+        i2sExt->I2SCFG_B.CPOL    = i2sConfig->polarity;
+    }
+    else
+    {
+        i2sExt->I2SCFG_B.I2SMOD  = I2S_MODE_SLAVE_TX;
+        i2sExt->I2SCFG_B.I2SSSEL = i2sConfig->standard & 0x03;
+        i2sExt->I2SCFG_B.PFSSEL  = (i2sConfig->standard & 0x10) >> 4;
+        i2sExt->I2SCFG_B.CHLEN   = i2sConfig->length & 0x01;
+        i2sExt->I2SCFG_B.DATLEN  = i2sConfig->length >> 1;
+        i2sExt->I2SCFG_B.CPOL    = i2sConfig->polarity;
+    }
+
+    i2sExt->I2SCFG_B.MODESEL = BIT_SET;
+}
+
+/*!
+ * @brief     Transmits a Data through the SPIx/I2Sx peripheral.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @param     data: Data to be transmitted
+ *
+ * @retval    None
+ */
+void SPI_I2S_TxData(SPI_T *spi, uint16_t data)
+{
+    spi->DATA = data;
+}
+
+/*!
+* @brief     Returns the most recent received data by the SPIx/I2Sx peripheral.
+*
+* @param     spi: The SPIx can be 1,2,3,4,5,6.
+*
+* @retval    data :The value of the received data
+*
+* @retval    None
+*/
+uint16_t SPI_I2S_RxData(SPI_T *spi)
+{
+    return spi->DATA;
+}
+
+/*!
+ * @brief     Enables the specified SPI CRC value calculation of the transferred bytes
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_EnableCRC(SPI_T *spi)
+{
+    spi->CTRL1_B.CRCEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the specified SPI CRC value calculation of the transferred bytes
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ */
+void SPI_DisableCRC(SPI_T *spi)
+{
+    spi->CTRL1_B.CRCEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Transmit CRC value
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    None
+ */
+void SPI_TxCRC(SPI_T *spi)
+{
+    spi->CTRL1_B.CRCNXT = BIT_SET;
+}
+
+/*!
+ * @brief     Reads the specified SPI transmit CRC register value
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    The SPI transmit CRC register value
+ */
+uint16_t SPI_ReadTxCRC(SPI_T *spi)
+{
+    return spi->TXCRC_B.TXCRC;
+}
+
+/*!
+ * @brief     Reads the specified SPI receive CRC register value
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    The SPI receive CRC register value
+ */
+uint16_t SPI_ReadRxCRC(SPI_T *spi)
+{
+    return spi->RXCRC_B.RXCRC;
+}
+
+/*!
+ * @brief     Reads the specified SPI CRC Polynomial register value
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @retval    The SPI CRC Polynomial register value
+ */
+uint16_t SPI_ReadCRCPolynomial(SPI_T *spi)
+{
+    return spi->CRCPOLY_B.CRCPOLY;
+}
+
+/*!
+ * @brief     Enables the SPIx/I2Sx DMA interface.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6, When the I2S can be 2,3
+ *
+ * @param     dmaReq: specifies the SPI/I2S DMA transfer request
+ *                     The parameter can be one of following values:
+ *                     @arg SPI_I2S_DMA_REQ_TX : Tx buffer DMA transfer request
+ *                     @arg SPI_I2S_DMA_REQ_RX : Rx buffer DMA transfer request
+ *
+ * @retval    None
+ */
+void SPI_I2S_EnableDMA(SPI_T *spi, SPI_I2S_DMA_REQ_T dmaReq)
+{
+    if (dmaReq == SPI_I2S_DMA_REQ_TX)
+    {
+        spi->CTRL2_B.TXDEN = ENABLE;
+    }
+    else
+    {
+        spi->CTRL2_B.RXDEN = ENABLE;
+    }
+}
+
+/*!
+ * @brief     Disables the SPIx/I2Sx DMA interface.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6., When the I2S can be 2,3
+ *
+ * @param     dmaReq: specifies the SPI/I2S DMA transfer request
+ *                     The parameter can be one of following values:
+ *                     @arg SPI_I2S_DMA_REQ_TX : Tx buffer DMA transfer request
+ *                     @arg SPI_I2S_DMA_REQ_RX : Rx buffer DMA transfer request
+ *
+ * @retval    None
+ */
+void SPI_I2S_DisableDMA(SPI_T *spi, SPI_I2S_DMA_REQ_T dmaReq)
+{
+    if (dmaReq == SPI_I2S_DMA_REQ_TX)
+    {
+        spi->CTRL2_B.TXDEN = DISABLE;
+    }
+    else
+    {
+        spi->CTRL2_B.RXDEN = DISABLE;
+    }
+}
+
+/*!
+ * @brief     Enables the specified SPI/I2S interrupts.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6., When the I2S can be 2,3
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                       The parameter can be any combination of following values:
+ *                       @arg SPI_I2S_INT_TXBE  : Tx buffer empty interrupt
+ *                       @arg SPI_I2S_INT_RXBNE : Rx buffer not empty interrupt
+ *                       @arg SPI_I2S_INT_ERR   : Error interrupt
+ *
+ * @retval       None
+ */
+void SPI_I2S_EnableInterrupt(SPI_T *spi, uint32_t interrupt)
+{
+    spi->CTRL2 |= (uint32_t)(interrupt >> 8);
+}
+
+/*!
+ * @brief     Disables the specified SPI/I2S interrupts.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6., When the I2S can be 2,3
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                     The parameter can be any combination of following values:
+ *                     @arg SPI_I2S_INT_TXBE  : Tx buffer empty interrupt
+ *                     @arg SPI_I2S_INT_RXBNE : Rx buffer not empty interrupt
+ *                     @arg SPI_I2S_INT_ERR   : Error interrupt
+ *
+ * @retval    None
+ */
+void SPI_I2S_DisableInterrupt(SPI_T *spi, uint32_t interrupt)
+{
+    spi->CTRL2 &= ~((uint32_t)(interrupt >> 8));
+}
+
+/*!
+ * @brief     Checks whether the specified SPI/I2S flag is set or not.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6., When the I2S can be 2,3
+ *
+ * @param     flag: specifies the SPI/I2S flag to check
+ *                  The parameter can be one of following values:
+ *                  @arg SPI_FLAG_RXBNE  : Receive buffer not empty flag
+ *                  @arg SPI_FLAG_TXBE   : Transmit buffer empty flag
+ *                  @arg I2S_FLAG_SCHDIR : Side Channel flag
+ *                  @arg I2S_FLAG_UDR    : Underrun Error flag
+ *                  @arg SPI_FLAG_CRCE   : CRC Error flag
+ *                  @arg SPI_FLAG_ME     : Mode Error flag
+ *                  @arg SPI_FLAG_OVR    : Overrun flag
+ *                  @arg SPI_FLAG_BSY    : Busy flag
+ *
+ * @retval     SET or RESET
+ */
+uint8_t SPI_I2S_ReadStatusFlag(SPI_T *spi, SPI_FLAG_T flag)
+{
+    return (spi->STS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the SPIx CRC Error flag
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @param     flag: only clears SPI_FLAG_CRCE(CRC Error flag)
+ *
+ * @retval    None
+ *
+ * @note      1)SPI_FLAG_OVR: (OverRun error) flag is cleared by software sequence:
+ *              a read operation to SPI_DATA register (SPI_I2S_RxData())
+ *              followed by a read operation to SPI_STS register (SPI_I2S_ReadStatusFlag()).
+ *            2)I2S_FLAG_UDR: (UnderRun error) flag is cleared:
+ *              a read operation to SPI_STS register (SPI_I2S_ReadStatusFlag()).
+ *            3)SPI_FLAG_ME: (Mode Fault) flag is cleared by software sequence:
+ *              a read/write operation to SPI_STS register (SPI_I2S_ReadStatusFlag())
+ *              followed by a write operation to SPI_CTRL1 register (SPI_Enable()).
+ */
+void SPI_I2S_ClearStatusFlag(SPI_T *spi, SPI_FLAG_T flag)
+{
+    if (flag == SPI_FLAG_CRCE)
+    {
+        spi->STS_B.CRCEFLG = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Checks whether the specified SPI/I2S interrupt has occurred or not.
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6., When the I2S can be 2,3
+ *
+ * @param     flag: specifies the SPI/I2S interrupt flag to check.
+ *                     The parameter can be one of following values:
+ *                     @arg SPI_I2S_INT_RXBNE : Receive buffer not empty interrupt flag
+ *                     @arg SPI_I2S_INT_TXBE  : Transmit buffer empty interrupt flag
+ *                     @arg SPI_I2S_INT_OVR   : Overrun interrupt flag
+ *                     @arg SPI_INT_CRCE      : CRC Error interrupt flag
+ *                     @arg SPI_INT_ME        :  Mode Error interrupt flag
+ *                     @arg I2S_INT_UDR       : Underrun Error interrupt flag
+ *
+ * @retval       SET or RESET
+ */
+uint8_t SPI_I2S_ReadIntFlag(SPI_T *spi, SPI_I2S_INT_T flag)
+{
+    uint32_t intEnable;
+    uint32_t intStatus;
+
+    intEnable = (uint32_t)(spi->CTRL2 & (flag >> 8));
+    intStatus = (uint32_t)(spi->STS & flag);
+
+    if (intEnable && intStatus)
+    {
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+ * @brief     Clears the SPIx CRC Error interrupt flag
+ *
+ * @param     spi: The SPIx can be 1,2,3,4,5,6.
+ *
+ * @param     flag: only clears SPI_INT_CRCE(CRC Error interrupt flag)
+ *
+ * @retval    None
+ *
+ * @note      1)SPI_I2S_INT_OVR: (OverRun interrupt error) flag is cleared by software sequence:
+ *              a read operation to SPI_DATA register (SPI_I2S_RxData())
+ *              followed by a read operation to SPI_STS register (SPI_I2S_ReadIntFlag()).
+ *            2)I2S_INT_UDR: (UnderRun interrupt error) flag is cleared:
+ *              a read operation to SPI_STS register (SPI_I2S_ReadIntFlag()).
+ *            3)SPI_INT_ME: (Mode interrupt Fault) flag is cleared by software sequence:
+ *              a read/write operation to SPI_STS register (SPI_I2S_ReadIntFlag())
+ *              followed by a write operation to SPI_CTRL1 register (SPI_Enable()).
+ */
+void SPI_I2S_ClearIntFlag(SPI_T *spi, SPI_I2S_INT_T flag)
+{
+    if (flag == SPI_INT_CRCE)
+    {
+        spi->STS_B.CRCEFLG = BIT_RESET;
+    }
+
+}
+
+/**@} end of group SPI_Functions */
+/**@} end of group SPI_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 194 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_syscfg.c

@@ -0,0 +1,194 @@
+/*!
+ * @file        apm32f4xx_syscfg.c
+ *
+ * @brief       This file provides all the SYSCFG firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_syscfg.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup SYSCFG_Driver
+  * @brief SYSCFG driver modules
+  @{
+*/
+
+/** @defgroup SYSCFG_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset the remap and EINT configuration registers to their default values.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void SYSCFG_Reset(void)
+{
+    RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_SYSCFG);
+    RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_SYSCFG);
+}
+
+/*!
+ * @brief     Changes the mapping of the specified pin.
+ *
+ * @param     memory: selects the memory remapping.
+ *                   The parameter can be one of the following values:
+ *                   @arg SYSCFG_REMAP_FLASH        : Memory mapping to Flash
+ *                   @arg SYSCFG_REMAP_SYSTEM_FLASH : Memory mapping to SystemFlash
+ *                   @arg SYSCFG_REMAP_SMC_BANK1    : Memory mapping to bank1 of SMC (NOR-flash/PSRAM)
+ *                   @arg SYSCFG_REMAP_SRAM         : Memory mapping to SRAM
+ *
+ * @retval    None
+ */
+void SYSCFG_ConfigMemoryRemap(SYSCFG_REMAP_T memory)
+{
+    SYSCFG->MMSEL_B.MMSEL = memory;
+}
+
+/*!
+ * @brief     Config the GPIO pin used as EINT Line.
+ *
+ * @param     port: select the port
+ *                  The parameter can be one of the following values
+ *                  @arg SYSCFG_PORT_GPIOA : Port Source GPIOA
+ *                  @arg SYSCFG_PORT_GPIOB : Port Source GPIOB
+ *                  @arg SYSCFG_PORT_GPIOC : Port Source GPIOC
+ *                  @arg SYSCFG_PORT_GPIOD : Port Source GPIOD
+ *                  @arg SYSCFG_PORT_GPIOE : Port Source GPIOE
+ *                  @arg SYSCFG_PORT_GPIOF : Port Source GPIOF
+ *                  @arg SYSCFG_PORT_GPIOG : Port Source GPIOG
+ *                  @arg SYSCFG_PORT_GPIOH : Port Source GPIOH
+ *                  @arg SYSCFG_PORT_GPIOI : Port Source GPIOI
+ *
+ * @param     pin:  select the pin
+ *                  The parameter can be one of the following values
+ *                  @arg SYSCFG_PIN_0 : Pin Source 0
+ *                  @arg SYSCFG_PIN_1 : Pin Source 1
+ *                  @arg SYSCFG_PIN_2 : Pin Source 2
+ *                  @arg SYSCFG_PIN_3 : Pin Source 3
+ *                  @arg SYSCFG_PIN_4 : Pin Source 4
+ *                  @arg SYSCFG_PIN_5 : Pin Source 5
+ *                  @arg SYSCFG_PIN_6 : Pin Source 6
+ *                  @arg SYSCFG_PIN_7 : Pin Source 7
+ *                  @arg SYSCFG_PIN_8 : Pin Source 8
+ *                  @arg SYSCFG_PIN_9 : Pin Source 9
+ *                  @arg SYSCFG_PIN_10: Pin Source 10
+ *                  @arg SYSCFG_PIN_11: Pin Source 11
+ *                  @arg SYSCFG_PIN_12: Pin Source 12
+ *                  @arg SYSCFG_PIN_13: Pin Source 13
+ *                  @arg SYSCFG_PIN_14: Pin Source 14
+ *                  @arg SYSCFG_PIN_15: Pin Source 15
+ *
+ * @retval    None
+ *
+ * @note      pin from SYSCFG_PIN_12 to SYSCFG_PIN_15 is not fit for
+ *            SYSCFG_PORT_GPIOI of the port.
+ */
+void SYSCFG_ConfigEINTLine(SYSCFG_PORT_T port, SYSCFG_PIN_T pin)
+{
+    uint32_t status;
+
+    status = ((uint32_t)(port & 0x0F)) << (0x04 * (pin & 0x03));
+
+    if ((pin >> 2) == 0)
+    {
+        SYSCFG->EINTCFG1 |= status;
+    }
+    else if ((pin >> 2) == 1)
+    {
+        SYSCFG->EINTCFG2 |= status;
+    }
+    else if ((pin >> 2) == 2)
+    {
+        SYSCFG->EINTCFG3 |= status;
+    }
+    else if ((pin >> 2) == 3)
+    {
+        SYSCFG->EINTCFG4 |= status;
+    }
+}
+
+/*!
+ * @brief     Selects the ETHERNET media interface
+ *
+ * @param     media: select the media
+ *                   The parameter can be combination of folling values
+ *                   @arg SYSCFG_INTERFACE_MII  : MII mode selected
+ *                   @arg SYSCFG_INTERFACE_RMII : RMII mode selected
+ *
+ * @retval    None
+ */
+void SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_T media)
+{
+    SYSCFG->PMC_B.ENETSEL = media;
+}
+
+/*!
+ * @brief     Enables the I/O Compensation Cell.
+ *
+ * @param     None
+ *
+ * @retval    None
+ *
+ * @note      The I/O compensation cell can be used only when the device supply
+ *            voltage ranges from 2.4 to 3.6 V.
+ */
+void SYSCFG_EnableCompensationCell(void)
+{
+    SYSCFG->CCCTRL_B.CCPD = BIT_SET;
+}
+
+/*!
+ * @brief     Disables the I/O Compensation Cell.
+ *
+ * @param     None
+ *
+ * @retval    None
+ *
+ * @note      The I/O compensation cell can be used only when the device supply
+ *            voltage ranges from 2.4 to 3.6 V.
+ */
+void SYSCFG_DisableCompensationCell(void)
+{
+    SYSCFG->CCCTRL_B.CCPD = BIT_RESET;
+}
+
+/*!
+ * @brief     Read the I/O Compensation Cell ready flag.
+ *
+ * @param     None
+ *
+ * @retval    SET or RESET
+ */
+uint8_t SYSCFG_ReadCompensationCellStatus(void)
+{
+    return (SYSCFG->CCCTRL & BIT8) ? SET : RESET;
+}
+
+/**@} end of group SYSCFG_Functions */
+/**@} end of group SYSCFG_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 2300 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_tmr.c

@@ -0,0 +1,2300 @@
+/*!
+ * @file        apm32f4xx_tmr.c
+ *
+ * @brief       This file provides all the TMR firmware functions.
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_tmr.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup TMR_Driver
+  * @brief TMR driver modules
+  @{
+*/
+
+/** @defgroup TMR_Functions
+  @{
+*/
+
+static void TI1Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter);
+static void TI2Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter);
+static void TI3Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter);
+static void TI4Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter);
+
+/*!
+ * @brief     Deinitializes the TMRx peripheral registers to their default reset values.
+ *
+ * @param     tmr: Select TMRx peripheral, The x can be from 1 to 14.
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void TMR_Reset(TMR_T *tmr)
+{
+    if (tmr == TMR1)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_TMR1);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_TMR1);
+    }
+    else if (tmr == TMR2)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR2);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR2);
+    }
+    else if (tmr == TMR3)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR3);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR3);
+    }
+    else if (tmr == TMR4)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR4);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR4);
+    }
+    else if (tmr == TMR5)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR5);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR5);
+    }
+    else if (tmr == TMR6)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR6);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR6);
+    }
+    else if (tmr == TMR7)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR7);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR7);
+    }
+    else if (tmr == TMR8)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_TMR8);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_TMR8);
+    }
+    else if (tmr == TMR9)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_TMR9);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_TMR9);
+    }
+    else if (tmr == TMR10)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_TMR10);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_TMR10);
+    }
+    else if (tmr == TMR11)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_TMR11);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_TMR11);
+    }
+    else if (tmr == TMR12)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR12);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR12);
+    }
+    else if (tmr == TMR13)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR13);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR13);
+    }
+    else if (tmr == TMR14)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_TMR14);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_TMR14);
+    }
+}
+
+/*!
+ * @brief     Config the base timer through the structure
+ *
+ * @param     tmr: Select TMRx peripheral, The x can be 1 to 14
+ *
+ * @param     baseConfig: Pointer to a TMR_BaseConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigTimeBase(TMR_T *tmr, TMR_BaseConfig_T *baseConfig)
+{
+    if ((tmr == TMR1) || (tmr == TMR2) || \
+            (tmr == TMR3) || (tmr == TMR4) || \
+            (tmr == TMR5) || (tmr == TMR8))
+    {
+        /** Count Direction */
+        tmr->CTRL1_B.CNTDIR = baseConfig->countMode & 0x01;
+        /** Aligned mode */
+        tmr->CTRL1_B.CAMSEL = baseConfig->countMode >> 4;
+    }
+
+    if ((tmr != TMR6) && (tmr != TMR7))
+    {
+        tmr->CTRL1_B.CLKDIV = baseConfig->clockDivision;
+    }
+
+    tmr->AUTORLD = baseConfig->period ;
+
+    tmr->PSC = baseConfig->division;
+
+    if ((tmr == TMR1) || (tmr == TMR8))
+    {
+        tmr->REPCNT = baseConfig->repetitionCounter;
+    }
+
+    tmr->CEG_B.UEG = TMR_PSC_RELOAD_IMMEDIATE;
+}
+
+/*!
+ * @brief     Config the Base timer with its default value.
+ *
+ * @param     baseConfig: pointer to a TMR_BaseConfig_T
+ *
+ * @retval    None
+ */
+void TMR_ConfigTimeBaseStructInit(TMR_BaseConfig_T *baseConfig)
+{
+    baseConfig->countMode = TMR_COUNTER_MODE_UP;
+    baseConfig->clockDivision = TMR_CLOCK_DIV_1;
+    baseConfig->period = 0xFFFF;
+    baseConfig->division = 0x0000;
+    baseConfig->repetitionCounter = 0x0000;
+}
+
+/*!
+ * @brief     Configures the TMRx Prescaler.
+ *
+ * @param     tmr: Select TMRx peripheral, The x can be 1 to 14
+ *
+ * @param     psc: specifies the Prescaler Register value
+ *
+ * @param     reload: specifies the TMR Prescaler Reload mode
+ *                    The parameter can be one of following values:
+ *                    @arg TMR_PSC_RELOAD_UPDATE: The Prescaler reload at the update event
+ *                    @arg TMR_PSC_RELOAD_IMMEDIATE: The Prescaler reload immediately
+ *
+ * @retval    None
+ */
+void TMR_ConfigPrescaler(TMR_T *tmr, uint16_t psc, TMR_PSC_RELOAD_T reload)
+{
+    tmr->PSC_B.PSC = psc;
+    tmr->CEG_B.UEG = reload;
+}
+
+/*!
+ * @brief     Config counter mode.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     countMode: specifies the Counter Mode to be used
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_COUNTER_MODE_UP:   Timer Up Counting Mode
+ *                       @arg TMR_COUNTER_MODE_DOWN: Timer Down Counting Mode
+ *                       @arg TMR_COUNTER_MODE_CENTER_ALIGNED1: Timer Center Aligned Mode1
+ *                       @arg TMR_COUNTER_MODE_CENTER_ALIGNED2: Timer Center Aligned Mode2
+ *                       @arg TMR_COUNTER_MODE_CENTER_ALIGNED3: Timer Center Aligned Mode3
+ *
+ * @retval    None
+ */
+void TMR_ConfigCounterMode(TMR_T *tmr, TMR_COUNTER_MODE_T countMode)
+{
+    tmr->CTRL1_B.CNTDIR = countMode & 0x01;
+    tmr->CTRL1_B.CAMSEL = countMode >> 4;
+}
+
+/*!
+ * @brief     Configs the Counter Register value
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     counter: Counter register new value
+ *
+ * @retval    None
+ */
+void TMR_ConfigCounter(TMR_T *tmr, uint16_t counter)
+{
+    tmr->CNT = counter;
+}
+
+/*!
+ * @brief     Configs the value of AutoReload Register.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     autoReload: autoReload register new value
+ *
+ * @retval    None
+ */
+void TMR_ConfigAutoreload(TMR_T *tmr, uint16_t autoReload)
+{
+    tmr->AUTORLD_B.AUTORLD = autoReload;
+}
+
+/*!
+ * @brief     Read the TMRx Counter value.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    Counter Register value.
+ */
+uint16_t TMR_ReadCounter(TMR_T *tmr)
+{
+    return tmr->CNT;
+}
+
+/*!
+ * @brief     Read the TMRx  Prescaler value.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    Prescaler Register value.
+ */
+uint16_t TMR_ReadPrescaler(TMR_T *tmr)
+{
+    return tmr->PSC;
+}
+
+/*!
+ * @brief     Enable the TMRx update event
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    None
+ */
+void TMR_EnableUpdate(TMR_T *tmr)
+{
+    /** Clear Update Disable bit */
+    tmr->CTRL1_B.UD = DISABLE;
+}
+
+/*!
+ * @brief     Disable the TMRx update event
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    None
+ */
+void TMR_DisableUpdate(TMR_T *tmr)
+{
+    /** Set Update Disable bit */
+    tmr->CTRL1_B.UD = ENABLE;
+}
+
+/*!
+ * @brief     Configures the Update Request Interrupt source
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     updateSource: Config the Update source
+ *                          The parameter can be one of following values:
+ *                          @arg TMR_UPDATE_SOURCE_GLOBAL : Source of update is
+ *                                  - Counter overflow/underflow.
+ *                                  - UEG bit of Control event generation register(CEG) is set.
+ *                                  - Update generation through the slave mode controller.
+ *                          @arg TMR_UPDATE_SOURCE_REGULAR: Source of update is
+ *                                  - Counter overflow/underflow
+ *
+ * @retval    None
+ */
+void TMR_ConfigUpdateRequest(TMR_T *tmr, TMR_UPDATE_SOURCE_T updateSource)
+{
+    tmr->CTRL1_B.URSSEL = updateSource;
+}
+
+/*!
+ * @brief     Enables peripheral Preload register on AUTORLD.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    None
+ */
+void TMR_EnableAutoReload(TMR_T *tmr)
+{
+    tmr->CTRL1_B.ARPEN = ENABLE;
+}
+
+/*!
+ * @brief     Disable peripheral Preload register on AUTORLD.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    None
+ */
+void TMR_DisableAutoReload(TMR_T *tmr)
+{
+    tmr->CTRL1_B.ARPEN = DISABLE;
+}
+
+/*!
+ * @brief     Config the Single pulse Mode.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     singlePulseMode: specifies the Single Pulse Mode
+ *                             The parameter can be one of following values:
+ *                             @arg TMR_SPM_REPETITIVE
+ *                             @arg TMR_SPM_SINGLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigSinglePulseMode(TMR_T *tmr, TMR_SPM_T singlePulseMode)
+{
+    tmr->CTRL1_B.SPMEN = singlePulseMode;
+}
+
+/*!
+ * @brief     Configs the Clock Division value
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     clockDivision: specifies the clock division value.
+ *                           The parameter can be one of following values:
+ *                           @arg TMR_CLOCK_DIV_1: TDTS = Tck_tim
+ *                           @arg TMR_CLOCK_DIV_2: TDTS = 2*Tck_tim
+ *                           @arg TMR_CLOCK_DIV_4: TDTS = 4*Tck_tim
+ *
+ * @retval    None
+ */
+void TMR_ConfigClockDivision(TMR_T *tmr, TMR_CLOCK_DIV_T clockDivision)
+{
+    tmr->CTRL1_B.CLKDIV = clockDivision;
+}
+
+/*!
+ * @brief     Enable the specified TMR peripheral
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    None
+ */
+void TMR_Enable(TMR_T *tmr)
+{
+    tmr->CTRL1_B.CNTEN = ENABLE;
+}
+
+/*!
+ * @brief     Disable the specified TMR peripheral
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @retval    None
+ */
+void TMR_Disable(TMR_T *tmr)
+{
+    tmr->CTRL1_B.CNTEN = DISABLE;
+}
+
+/*!
+ * @brief     Configure channel 1 according to parameters
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     OCConfig: Pointer to a TMR_OCConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC1(TMR_T *tmr, TMR_OCConfig_T *OCConfig)
+{
+    tmr->CCEN_B.CC1EN = BIT_RESET;
+
+    tmr->CCM1_COMPARE_B.CC1SEL = BIT_RESET;
+    tmr->CCM1_COMPARE_B.OC1MOD = OCConfig->mode;
+
+    tmr->CCEN_B.CC1POL = OCConfig->polarity;
+    tmr->CCEN_B.CC1EN = OCConfig->outputState;
+
+    if ((tmr == TMR1) || (tmr == TMR8))
+    {
+        tmr->CCEN_B.CC1NPOL = OCConfig->nPolarity;
+        tmr->CCEN_B.CC1NEN = OCConfig->outputNState;
+
+        tmr->CTRL2_B.OC1OIS = OCConfig->idleState;
+        tmr->CTRL2_B.OC1NOIS = OCConfig->nIdleState;
+    }
+
+    tmr->CC1 = OCConfig->pulse;
+}
+
+/*!
+ * @brief     Configure channel 2 according to parameters
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     OCConfig: Pointer to a TMR_OCConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC2(TMR_T *tmr, TMR_OCConfig_T *OCConfig)
+{
+    tmr->CCEN_B.CC2EN = BIT_RESET;
+
+    tmr->CCM1_COMPARE_B.OC2MOD = BIT_RESET;
+    tmr->CCM1_COMPARE_B.CC2SEL = BIT_RESET;
+    tmr->CCM1_COMPARE_B.OC2MOD = OCConfig->mode;
+
+    tmr->CCEN_B.CC2POL = BIT_RESET;
+    tmr->CCEN_B.CC2POL = OCConfig->polarity;
+    tmr->CCEN_B.CC2EN = OCConfig->outputState;
+
+    if ((tmr == TMR1) || (tmr == TMR8))
+    {
+        tmr->CCEN_B.CC2NPOL = OCConfig->nPolarity;
+        tmr->CCEN_B.CC2NEN = OCConfig->outputNState;
+
+        tmr->CTRL2_B.OC2OIS = OCConfig->idleState;
+        tmr->CTRL2_B.OC2NOIS = OCConfig->nIdleState;
+    }
+
+    tmr->CC2 = OCConfig->pulse;
+}
+
+/*!
+ * @brief     Configure channel 3 according to parameters
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCConfig: Pointer to a TMR_OCConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC3(TMR_T *tmr, TMR_OCConfig_T *OCConfig)
+{
+    tmr->CCEN_B.CC3EN = BIT_RESET;
+
+    tmr->CCM2_COMPARE_B.OC3MOD = BIT_RESET;
+    tmr->CCM2_COMPARE_B.CC3SEL = BIT_RESET;
+    tmr->CCM2_COMPARE_B.OC3MOD = OCConfig->mode;
+
+    tmr->CCEN_B.CC3POL = BIT_RESET;
+    tmr->CCEN_B.CC3POL = OCConfig->polarity;
+    tmr->CCEN_B.CC3EN = OCConfig->outputState;
+
+    if ((tmr == TMR1) || (tmr == TMR8))
+    {
+        tmr->CCEN_B.CC3NPOL = OCConfig->nPolarity;
+        tmr->CCEN_B.CC3NEN = OCConfig->outputNState;
+
+        tmr->CTRL2_B.OC3OIS = OCConfig->idleState;
+        tmr->CTRL2_B.OC3NOIS = OCConfig->nIdleState;
+    }
+
+    tmr->CC3 = OCConfig->pulse;
+}
+
+/*!
+ * @brief     Configure channel 4 according to parameters
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCConfig: Pointer to a TMR_OCConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC4(TMR_T *tmr, TMR_OCConfig_T *OCConfig)
+{
+    tmr->CCEN_B.CC4EN = BIT_RESET;
+
+    tmr->CCM2_COMPARE_B.OC4MOD = BIT_RESET;
+    tmr->CCM2_COMPARE_B.CC4SEL = BIT_RESET;
+    tmr->CCM2_COMPARE_B.OC4MOD = OCConfig->mode;
+
+    tmr->CCEN_B.CC4POL = OCConfig->polarity;
+    tmr->CCEN_B.CC4EN = OCConfig->outputState;
+
+    if ((tmr == TMR1) || (tmr == TMR8))
+    {
+        tmr->CTRL2_B.OC4OIS = OCConfig->idleState;
+    }
+
+    tmr->CC4 = OCConfig->pulse;
+}
+
+/*!
+ * @brief     Initialize the OC timer with its default value.
+ *
+ * @param     OCConfig: pointer to a TMR_OCConfig_T
+ *
+ * @retval    None
+ */
+void TMR_ConfigOCStructInit(TMR_OCConfig_T *OCConfig)
+{
+    OCConfig->mode = TMR_OC_MODE_TMRING;
+    OCConfig->outputState = TMR_OC_STATE_DISABLE;
+    OCConfig->outputNState = TMR_OC_NSTATE_DISABLE;
+    OCConfig->pulse = 0x0000;
+    OCConfig->polarity = TMR_OC_POLARITY_HIGH;
+    OCConfig->nPolarity = TMR_OC_NPOLARITY_HIGH;
+    OCConfig->idleState = TMR_OC_IDLE_STATE_RESET;
+    OCConfig->nIdleState = TMR_OC_NIDLE_STATE_RESET;
+}
+
+/*!
+ * @brief     Selects the Output Compare Mode.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     channel: specifies the Channel
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_CHANNEL_1: Timer Channel 1
+ *                     @arg TMR_CHANNEL_2: Timer Channel 2
+ *                     @arg TMR_CHANNEL_3: Timer Channel 3
+ *                     @arg TMR_CHANNEL_4: Timer Channel 4
+ *
+ * @param     mode: specifies the Output Compare Mode
+ *                  The parameter can be one of following values:
+ *                  @arg TMR_OC_MODE_TMRING
+ *                  @arg TMR_OC_MODE_ACTIVE
+ *                  @arg TMR_OC_MODE_INACTIVE
+ *                  @arg TMR_OC_MODE_TOGGLE
+ *                  @arg TMR_OC_MODE_LOWLEVEL
+ *                  @arg TMR_OC_MODE_HIGHLEVEL
+ *                  @arg TMR_OC_MODE_PWM1
+ *                  @arg TMR_OC_MODE_PWM2
+ *
+ * @retval    None
+ */
+void TMR_SelectOCxMode(TMR_T *tmr, TMR_CHANNEL_T channel, TMR_OC_MODE_T mode)
+{
+    if (channel == TMR_CHANNEL_1)
+    {
+        tmr->CCM1_COMPARE_B.OC1MOD = mode;
+    }
+    else if (channel == TMR_CHANNEL_2)
+    {
+        tmr->CCM1_COMPARE_B.OC2MOD = mode;
+    }
+    else if (channel == TMR_CHANNEL_3)
+    {
+        tmr->CCM2_COMPARE_B.OC3MOD = mode;
+    }
+    else if (channel == TMR_CHANNEL_4)
+    {
+        tmr->CCM2_COMPARE_B.OC4MOD = mode;
+    }
+}
+
+/*!
+ * @brief     Configs the Capture Compare1 Register value
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     compare1: specifies the Capture Compare1 value.
+ *
+ * @retval    None
+ */
+void TMR_ConfigCompare1(TMR_T *tmr, uint32_t compare1)
+{
+    tmr->CC1 = compare1;
+}
+
+/*!
+ * @brief     Configs the Capture Compare2 Register value
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     compare2: specifies the Capture Compare1 value.
+ *
+ * @retval    None
+ */
+void TMR_ConfigCompare2(TMR_T *tmr, uint32_t compare2)
+{
+    tmr->CC2 = compare2;
+}
+
+/*!
+ * @brief     Configs the Capture Compare3 Register value
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     compare3: specifies the Capture Compare1 value.
+ *
+ * @retval    None
+ */
+void TMR_ConfigCompare3(TMR_T *tmr, uint32_t compare3)
+{
+    tmr->CC3 = compare3;
+}
+
+/*!
+ * @brief     Configs the Capture Compare4 Register value
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     compare4: specifies the Capture Compare1 value.
+ *
+ * @retval    None
+ */
+void TMR_ConfigCompare4(TMR_T *tmr, uint32_t compare4)
+{
+    tmr->CC4 = compare4;
+}
+
+/*!
+ * @brief     Forces the output 1 waveform to active or inactive level.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     forcesAction: specifies the forced Action to be set to the output waveform
+ *                          The parameter can be one of following values:
+ *                          @arg TMR_FORCED_ACTION_ACTIVE:  Force active level on OC1REF
+ *                          @arg TMR_FORCED_ACTION_INACTIVE: Force inactive level on OC1REF
+ *
+ * @retval    None
+ */
+void TMR_ConfigForcedOC1(TMR_T *tmr, TMR_FORCED_ACTION_T forcesAction)
+{
+    tmr->CCM1_COMPARE_B.OC1MOD = forcesAction;
+}
+
+/*!
+ * @brief     Forces the output 2 waveform to active or inactive level.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     forcesAction: specifies the forced Action to be set to the output waveform
+ *                          The parameter can be one of following values:
+ *                          @arg TMR_FORCED_ACTION_ACTIVE:  Force active level on OC1REF
+ *                          @arg TMR_FORCED_ACTION_INACTIVE: Force inactive level on OC1REF
+ *
+ * @retval    None
+ */
+void TMR_ConfigForcedOC2(TMR_T *tmr, TMR_FORCED_ACTION_T forcesAction)
+{
+    tmr->CCM1_COMPARE_B.OC2MOD = forcesAction;
+}
+
+/*!
+ * @brief     Forces the output 3 waveform to active or inactive level.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     forcesAction: specifies the forced Action to be set to the output waveform
+ *                          The parameter can be one of following values:
+ *                          @arg TMR_FORCED_ACTION_ACTIVE:  Force active level on OC1REF
+ *                          @arg TMR_FORCED_ACTION_INACTIVE: Force inactive level on OC1REF
+ *
+ * @retval    None
+ */
+void TMR_ConfigForcedOC3(TMR_T *tmr, TMR_FORCED_ACTION_T forcesAction)
+{
+    tmr->CCM2_COMPARE_B.OC3MOD = forcesAction;
+}
+
+/*!
+ * @brief     Forces the output 4 waveform to active or inactive level.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     forcesAction: specifies the forced Action to be set to the output waveform
+ *                          The parameter can be one of following values:
+ *                          @arg TMR_FORCED_ACTION_ACTIVE:  Force active level on OC1REF
+ *                          @arg TMR_FORCED_ACTION_INACTIVE: Force inactive level on OC1REF
+ *
+ * @retval    None
+ */
+void TMR_ConfigForcedOC4(TMR_T *tmr, TMR_FORCED_ACTION_T forcesAction)
+{
+    tmr->CCM2_COMPARE_B.OC4MOD = forcesAction;
+}
+
+/*!
+ * @brief     Enables or disables the peripheral Preload register on CCM1.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     OCPreload: specifies the Output Compare Channel Preload
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_PRELOAD_DISABLE
+ *                       @arg TMR_OC_PRELOAD_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC1Preload(TMR_T *tmr, TMR_OC_PRELOAD_T OCPreload)
+{
+    tmr->CCM1_COMPARE_B.OC1PEN = OCPreload;
+}
+
+/*!
+ * @brief     Enables or disables the peripheral Preload register on CCM2.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     OCPreload: specifies the Output Compare Channel Preload
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_PRELOAD_DISABLE
+ *                       @arg TMR_OC_PRELOAD_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC2Preload(TMR_T *tmr, TMR_OC_PRELOAD_T OCPreload)
+{
+    tmr->CCM1_COMPARE_B.OC2PEN = OCPreload;
+}
+
+/*!
+ * @brief     Enables or disables the peripheral Preload register on CCM3.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCPreload: specifies the Output Compare Channel Preload
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_PRELOAD_DISABLE
+ *                       @arg TMR_OC_PRELOAD_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC3Preload(TMR_T *tmr, TMR_OC_PRELOAD_T OCPreload)
+{
+    tmr->CCM2_COMPARE_B.OC3PEN = OCPreload;
+}
+
+/*!
+ * @brief     Enables or disables the peripheral Preload register on CCM4.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCPreload: specifies the Output Compare Channel Preload
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_PRELOAD_DISABLE
+ *                       @arg TMR_OC_PRELOAD_ENABLE
+ *
+ * @retval    Nonee
+ */
+void TMR_ConfigOC4Preload(TMR_T *tmr, TMR_OC_PRELOAD_T OCPreload)
+{
+    tmr->CCM2_COMPARE_B.OC4PEN = OCPreload;
+}
+
+/*!
+ * @brief     Configures the Output Compare 1 Fast feature.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     OCFast: specifies the Output Compare Channel Fast
+ *                    The parameter can be one of following values:
+ *                    @arg TMR_OC_FAST_DISABLE
+ *                    @arg TMR_OC_FAST_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC1Fast(TMR_T *tmr, TMR_OC_FAST_T OCFast)
+{
+    tmr->CCM1_COMPARE_B.OC1FEN = OCFast;
+}
+
+/*!
+ * @brief     Configures the Output Compare 2 Fast feature.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     OCFast: specifies the Output Compare Channel Fast
+ *                    The parameter can be one of following values:
+ *                    @arg TMR_OC_FAST_DISABLE
+ *                    @arg TMR_OC_FAST_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC2Fast(TMR_T *tmr, TMR_OC_FAST_T OCFast)
+{
+    tmr->CCM1_COMPARE_B.OC2FEN = OCFast;
+}
+
+/*!
+ * @brief     Configures the Output Compare 2 Fast feature.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCFast: specifies the Output Compare Channel Fast
+ *                    The parameter can be one of following values:
+ *                    @arg TMR_OC_FAST_DISABLE
+ *                    @arg TMR_OC_FAST_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC3Fast(TMR_T *tmr, TMR_OC_FAST_T OCFast)
+{
+    tmr->CCM2_COMPARE_B.OC3FEN = OCFast;
+}
+
+/*!
+ * @brief     Configures the Output Compare 4 Fast feature.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCFast: specifies the Output Compare Channel Fast
+ *                    The parameter can be one of following values:
+ *                    @arg TMR_OC_FAST_DISABLE
+ *                    @arg TMR_OC_FAST_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC4Fast(TMR_T *tmr, TMR_OC_FAST_T OCFast)
+{
+    tmr->CCM2_COMPARE_B.OC4FEN = OCFast;
+}
+
+/*!
+ * @brief     Clears or safeguards the OCREF1 signal on an external event
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     OCClear: specifies the Output Compare Channel1 Clear
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_OC_CLEAR_DISABLE
+ *                     @arg TMR_OC_CLEAR_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ClearOC1Ref(TMR_T *tmr, TMR_OC_CLEAR_T OCClear)
+{
+    tmr->CCM1_COMPARE_B.OC1CEN = OCClear;
+}
+
+/*!
+ * @brief     Clears or safeguards the OCREF2 signal on an external event
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     OCClear: specifies the Output Compare Channel1 Clear
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_OC_CLEAR_DISABLE
+ *                     @arg TMR_OC_CLEAR_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ClearOC2Ref(TMR_T *tmr, TMR_OC_CLEAR_T OCClear)
+{
+    tmr->CCM1_COMPARE_B.OC2CEN = OCClear;
+}
+
+/*!
+ * @brief     Clears or safeguards the OCREF3 signal on an external event
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCClear: specifies the Output Compare Channel1 Clear
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_OC_CLEAR_DISABLE
+ *                     @arg TMR_OC_CLEAR_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ClearOC3Ref(TMR_T *tmr, TMR_OC_CLEAR_T OCClear)
+{
+    tmr->CCM2_COMPARE_B.OC3CEN = OCClear;
+}
+
+/*!
+ * @brief     Clears or safeguards the OCREF4 signal on an external event
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     OCClear: specifies the Output Compare Channel1 Clear
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_OC_CLEAR_DISABLE
+ *                     @arg TMR_OC_CLEAR_ENABLE
+ *
+ * @retval    None
+ */
+void TMR_ClearOC4Ref(TMR_T *tmr, TMR_OC_CLEAR_T OCClear)
+{
+    tmr->CCM2_COMPARE_B.OC4CEN = OCClear;
+}
+
+/*!
+ * @brief     Configures the channel 1 polarity.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     polarity: specifies the OC1 Polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_OC_POLARITY_HIGH: Output Compare active high
+ *                      @arg TMR_OC_POLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC1Polarity(TMR_T *tmr, TMR_OC_POLARITY_T polarity)
+{
+    tmr->CCEN_B.CC1POL = polarity;
+}
+
+/*!
+ * @brief     Configures the  channel 1 nPolarity.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @param     nPolarity: specifies the OC1 nPolarity
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_NPOLARITY_HIGH: Output Compare active high
+ *                       @arg TMR_OC_NPOLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC1NPolarity(TMR_T *tmr, TMR_OC_NPOLARITY_T nPolarity)
+{
+    tmr->CCEN_B.CC1NPOL = nPolarity;
+}
+
+/*!
+ * @brief     Configures the channel 2 polarity.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     polarity: specifies the OC2 Polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_OC_POLARITY_HIGH: Output Compare active high
+ *                      @arg TMR_OC_POLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC2Polarity(TMR_T *tmr, TMR_OC_POLARITY_T polarity)
+{
+    tmr->CCEN_B.CC2POL = polarity;
+}
+
+/*!
+ * @brief     Configures the  channel 2 nPolarity.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @param     nPolarity: specifies the OC2 nPolarity
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_NPOLARITY_HIGH: Output Compare active high
+ *                       @arg TMR_OC_NPOLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC2NPolarity(TMR_T *tmr, TMR_OC_NPOLARITY_T nPolarity)
+{
+    tmr->CCEN_B.CC2NPOL = nPolarity;
+}
+
+/*!
+ * @brief     Configures the channel 3 polarity.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     polarity: specifies the OC3 Polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_OC_POLARITY_HIGH: Output Compare active high
+ *                      @arg TMR_OC_POLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC3Polarity(TMR_T *tmr, TMR_OC_POLARITY_T polarity)
+{
+    tmr->CCEN_B.CC3POL = polarity;
+}
+
+/*!
+ * @brief     Configures the  channel 3 nPolarity.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @param     nPolarity: specifies the OC3 nPolarity
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_OC_NPOLARITY_HIGH: Output Compare active high
+ *                       @arg TMR_OC_NPOLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC3NPolarity(TMR_T *tmr, TMR_OC_NPOLARITY_T nPolarity)
+{
+    tmr->CCEN_B.CC3NPOL = nPolarity;
+}
+
+/*!
+ * @brief     Configures the channel 4 polarity.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     polarity: specifies the OC4 Polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_OC_POLARITY_HIGH: Output Compare active high
+ *                      @arg TMR_OC_POLARITY_LOW: Output Compare active low
+ *
+ * @retval    None
+ */
+void TMR_ConfigOC4Polarity(TMR_T *tmr, TMR_OC_POLARITY_T polarity)
+{
+    tmr->CCEN_B.CC4POL = polarity;
+}
+
+/*!
+ * @brief     Enables the Capture Compare Channel x.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     channel: specifies the Channel
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_CHANNEL_1: Timer Channel 1
+ *                     @arg TMR_CHANNEL_2: Timer Channel 2
+ *                     @arg TMR_CHANNEL_3: Timer Channel 3
+ *                     @arg TMR_CHANNEL_4: Timer Channel 4
+ *
+ * @retval    None
+ */
+void TMR_EnableCCxChannel(TMR_T *tmr, TMR_CHANNEL_T channel)
+{
+    if (channel == TMR_CHANNEL_1)
+    {
+        tmr->CCEN_B.CC1EN = BIT_SET;
+    }
+    else if (channel == TMR_CHANNEL_2)
+    {
+        tmr->CCEN_B.CC2EN = BIT_SET;
+    }
+    else if (channel == TMR_CHANNEL_3)
+    {
+        tmr->CCEN_B.CC3EN = BIT_SET;
+    }
+    else if (channel == TMR_CHANNEL_4)
+    {
+        tmr->CCEN_B.CC4EN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disables the Capture Compare Channel x.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     channel: specifies the Channel
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_CHANNEL_1: Timer Channel 1
+ *                     @arg TMR_CHANNEL_2: Timer Channel 2
+ *                     @arg TMR_CHANNEL_3: Timer Channel 3
+ *                     @arg TMR_CHANNEL_4: Timer Channel 4
+ *
+ * @retval    None
+ */
+void TMR_DisableCCxChannel(TMR_T *tmr, TMR_CHANNEL_T channel)
+{
+    if (channel == TMR_CHANNEL_1)
+    {
+        tmr->CCEN_B.CC1EN = BIT_RESET;
+    }
+    else if (channel == TMR_CHANNEL_2)
+    {
+        tmr->CCEN_B.CC2EN = BIT_RESET;
+    }
+    else if (channel == TMR_CHANNEL_3)
+    {
+        tmr->CCEN_B.CC3EN = BIT_RESET;
+    }
+    else if (channel == TMR_CHANNEL_4)
+    {
+        tmr->CCEN_B.CC4EN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Enables the Capture Compare Channelx N.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @param     channel: specifies the Channel
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_CHANNEL_1: Timer Channel 1
+ *                     @arg TMR_CHANNEL_2: Timer Channel 2
+ *                     @arg TMR_CHANNEL_3: Timer Channel 3
+ *
+ * @retval    None
+ */
+void TMR_EnableCCxNChannel(TMR_T *tmr, TMR_CHANNEL_T channel)
+{
+    if (channel == TMR_CHANNEL_1)
+    {
+        tmr->CCEN_B.CC1NEN = BIT_SET;
+    }
+    else if (channel == TMR_CHANNEL_2)
+    {
+        tmr->CCEN_B.CC2NEN = BIT_SET;
+    }
+    else if (channel == TMR_CHANNEL_3)
+    {
+        tmr->CCEN_B.CC3NEN = BIT_SET;
+    }
+}
+
+/*!
+ * @brief     Disables the Capture Compare Channelx N.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @param     channel: specifies the Channel
+ *                     The parameter can be one of following values:
+ *                     @arg TMR_CHANNEL_1: Timer Channel 1
+ *                     @arg TMR_CHANNEL_2: Timer Channel 2
+ *                     @arg TMR_CHANNEL_3: Timer Channel 3
+ *
+ * @retval    None
+ */
+void TMR_DisableCCxNChannel(TMR_T *tmr, TMR_CHANNEL_T channel)
+{
+    if (channel == TMR_CHANNEL_1)
+    {
+        tmr->CCEN_B.CC1NEN = BIT_RESET;
+    }
+    else if (channel == TMR_CHANNEL_2)
+    {
+        tmr->CCEN_B.CC2NEN = BIT_RESET;
+    }
+    else if (channel == TMR_CHANNEL_3)
+    {
+        tmr->CCEN_B.CC3NEN = BIT_RESET;
+    }
+}
+
+/*!
+ * @brief     Configure Peripheral equipment
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     ICConfig: Pointer to a TMR_ICConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigIC(TMR_T *tmr, TMR_ICConfig_T *ICConfig)
+{
+    if (ICConfig->channel == TMR_CHANNEL_1)
+    {
+        TI1Config(tmr, ICConfig->polarity, ICConfig->selection, ICConfig->filter);
+        TMR_ConfigIC1Prescaler(tmr, ICConfig->prescaler);
+    }
+    else if (ICConfig->channel == TMR_CHANNEL_2)
+    {
+        TI2Config(tmr, ICConfig->polarity, ICConfig->selection, ICConfig->filter);
+        TMR_ConfigIC2Prescaler(tmr, ICConfig->prescaler);
+    }
+    else if (ICConfig->channel == TMR_CHANNEL_3)
+    {
+        TI3Config(tmr, ICConfig->polarity, ICConfig->selection, ICConfig->filter);
+        TMR_ConfigIC3Prescaler(tmr, ICConfig->prescaler);
+    }
+    else if (ICConfig->channel == TMR_CHANNEL_4)
+    {
+        TI4Config(tmr, ICConfig->polarity, ICConfig->selection, ICConfig->filter);
+        TMR_ConfigIC4Prescaler(tmr, ICConfig->prescaler);
+    }
+}
+
+/*!
+ * @brief     Initialize the IC timer with its default value.
+ *
+ * @param     ICConfig: pointer to a TMR_ICConfig_T structure.
+ *
+ * @retval    None
+ */
+void TMR_ConfigICStructInit(TMR_ICConfig_T *ICConfig)
+{
+    ICConfig->channel = TMR_CHANNEL_1;
+    ICConfig->polarity = TMR_IC_POLARITY_RISING;
+    ICConfig->selection = TMR_IC_SELECTION_DIRECT_TI;
+    ICConfig->prescaler = TMR_IC_PSC_1;
+    ICConfig->filter = 0x00;
+}
+
+/*!
+ * @brief     Config of TMR to PWM
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     PWMConfig: pointer to a TMR_ICConfig_T structure.
+ *
+ * @retval    None
+ */
+void TMR_ConfigPWM(TMR_T *tmr, TMR_ICConfig_T *PWMConfig)
+{
+    uint16_t icpolarity = TMR_IC_POLARITY_RISING;
+    uint16_t icselection = TMR_IC_SELECTION_DIRECT_TI;
+
+    if (PWMConfig->polarity == TMR_IC_POLARITY_RISING)
+    {
+        icpolarity = TMR_IC_POLARITY_FALLING;
+    }
+    else
+    {
+        icpolarity = TMR_IC_POLARITY_RISING;
+    }
+
+    if (PWMConfig->selection == TMR_IC_SELECTION_DIRECT_TI)
+    {
+        icselection = TMR_IC_SELECTION_INDIRECT_TI;
+    }
+    else
+    {
+        icselection = TMR_IC_SELECTION_DIRECT_TI;
+    }
+
+    if (PWMConfig->channel == TMR_CHANNEL_1)
+    {
+        TI1Config(tmr, PWMConfig->polarity, PWMConfig->selection, PWMConfig->filter);
+        TMR_ConfigIC1Prescaler(tmr, PWMConfig->prescaler);
+        TI2Config(tmr, icpolarity, icselection, PWMConfig->filter);
+        TMR_ConfigIC2Prescaler(tmr, PWMConfig->prescaler);
+    }
+    else
+    {
+        TI2Config(tmr, PWMConfig->polarity, PWMConfig->selection, PWMConfig->filter);
+        TMR_ConfigIC2Prescaler(tmr, PWMConfig->prescaler);
+        TI1Config(tmr, icpolarity, icselection, PWMConfig->filter);
+        TMR_ConfigIC1Prescaler(tmr, PWMConfig->prescaler);
+    }
+}
+
+/*!
+ * @brief     Read Input Capture 1 value.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @retval    Capture Compare 1 Register value.
+ */
+uint32_t TMR_ReadCaputer1(TMR_T *tmr)
+{
+    return tmr->CC1;
+}
+
+/*!
+ * @brief     Read Input Capture 2 value.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @retval    Capture Compare 2 Register value.
+ */
+uint32_t TMR_ReadCaputer2(TMR_T *tmr)
+{
+    return tmr->CC2;
+}
+
+/*!
+ * @brief     Read Input Capture 3 value.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @retval    Capture Compare 3 Register value.
+ */
+uint32_t TMR_ReadCaputer3(TMR_T *tmr)
+{
+    return tmr->CC3;
+}
+
+/*!
+ * @brief     Read Input Capture 4 value.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @retval    Capture Compare 4 Register value.
+ */
+uint32_t TMR_ReadCaputer4(TMR_T *tmr)
+{
+    return tmr->CC4;
+}
+
+/*!
+ * @brief     Configs the TMRx Input Capture 1 prescaler.
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     prescaler: specifies the Input Capture Channel 1 Perscaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_IC_PSC_1: no prescaler
+ *                       @arg TMR_IC_PSC_2: capture is done once every 2 events
+ *                       @arg TMR_IC_PSC_4: capture is done once every 4 events
+ *                       @arg TMR_IC_PSC_8: capture is done once every 8 events
+ *
+ * @retval    None
+ */
+void TMR_ConfigIC1Prescaler(TMR_T *tmr, TMR_IC_PSC_T prescaler)
+{
+    tmr->CCM1_CAPTURE_B.IC1PSC = prescaler;
+}
+/*!
+ * @brief     Sets the TMRx Input Capture 2 prescaler.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     prescaler: specifies the Input Capture Channel 2 Perscaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_IC_PSC_1: no prescaler
+ *                       @arg TMR_IC_PSC_2: capture is done once every 2 events
+ *                       @arg TMR_IC_PSC_4: capture is done once every 4 events
+ *                       @arg TMR_IC_PSC_8: capture is done once every 8 events
+ *
+ * @retval    None
+ */
+void TMR_ConfigIC2Prescaler(TMR_T *tmr, TMR_IC_PSC_T prescaler)
+{
+    tmr->CCM1_CAPTURE_B.IC2PSC = prescaler;
+}
+
+/*!
+ * @brief     Configs the TMRx Input Capture 3 prescaler.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     prescaler: specifies the Input Capture Channel 3 Perscaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_IC_PSC_1: no prescaler
+ *                       @arg TMR_IC_PSC_2: capture is done once every 2 events
+ *                       @arg TMR_IC_PSC_4: capture is done once every 4 events
+ *                       @arg TMR_IC_PSC_8: capture is done once every 8 events
+ *
+ * @retval    None
+ */
+void TMR_ConfigIC3Prescaler(TMR_T *tmr, TMR_IC_PSC_T prescaler)
+{
+    tmr->CCM2_CAPTURE_B.IC3PSC = prescaler;
+}
+
+/*!
+ * @brief     Configs the TMRx Input Capture 4 prescaler.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     prescaler: specifies the Input Capture Channel4 Perscaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_IC_PSC_1: no prescaler
+ *                       @arg TMR_IC_PSC_2: capture is done once every 2 events
+ *                       @arg TMR_IC_PSC_4: capture is done once every 4 events
+ *                       @arg TMR_IC_PSC_8: capture is done once every 8 events
+ *
+ * @retval    None
+ */
+void TMR_ConfigIC4Prescaler(TMR_T *tmr, TMR_IC_PSC_T prescaler)
+{
+    tmr->CCM2_CAPTURE_B.IC4PSC = prescaler;
+}
+
+/*!
+ * @brief     Configures the: Break feature, dead time, Lock level, the IMOS
+ *
+ * @param     tmr: The TMRx can be 1 or 8
+ *
+ * @param     BDTConfig: Pointer to a TMR_BDTConfig_T structure
+ *
+ * @retval    None
+ */
+void TMR_ConfigBDT(TMR_T *tmr, TMR_BDTConfig_T *BDTConfig)
+{
+    tmr->BDT = (BDTConfig->IMOS) << 10 | \
+               (BDTConfig->RMOS) << 11 | \
+               (BDTConfig->lockLevel) << 8 | \
+               (BDTConfig->deadTime) | \
+               (BDTConfig->BRKState) << 12 | \
+               (BDTConfig->BRKPolarity) << 13 | \
+               (BDTConfig->automaticOutput) << 14;
+}
+
+/*!
+ * @brief     Initialize the BDT timer with its default value.
+ *
+ * @param     BDTConfig: pointer to a TMR_BDTConfig_T
+ *
+ * @retval    None
+ */
+void TMR_ConfigBDTStructInit(TMR_BDTConfig_T *BDTConfig)
+{
+    BDTConfig->RMOS = TMR_RMOS_STATE_DISABLE;
+    BDTConfig->IMOS = TMR_IMOS_STATE_DISABLE;
+    BDTConfig->lockLevel = TMR_LOCK_LEVEL_OFF;
+    BDTConfig->deadTime = 0x00;
+    BDTConfig->BRKState = TMR_BRK_STATE_DISABLE;
+    BDTConfig->BRKPolarity = TMR_BRK_POLARITY_LOW;
+    BDTConfig->automaticOutput = TMR_AUTOMATIC_OUTPUT_DISABLE;
+}
+
+/*!
+ * @brief     Enable TMRx PWM output
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @retval    None
+ */
+void TMR_EnablePWMOutputs(TMR_T *tmr)
+{
+    tmr->BDT_B.MOEN = ENABLE;
+}
+
+/*!
+ * @brief     Disable TMRx PWM output.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @retval    None
+ */
+void TMR_DisablePWMOutputs(TMR_T *tmr)
+{
+    tmr->BDT_B.MOEN = DISABLE;
+}
+
+/*!
+ * @brief     Enable to Select the TMR peripheral Commutation event.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @retval    None
+ */
+void TMR_EnableSelectCOM(TMR_T *tmr)
+{
+    tmr->CTRL2_B.CCUSEL = ENABLE;
+}
+/*!
+ * @brief     Disable to Select the TMR peripheral Commutation event.
+ *
+ * @param     tmr: The TMRx it can be TMR1 and TMR8
+ *
+ * @retval    None
+ */
+void TMR_DisableSelectCOM(TMR_T *tmr)
+{
+    tmr->CTRL2_B.CCUSEL = DISABLE;
+}
+
+/*!
+ * @brief     Enable Capture Compare Preload Control bit.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @retval    None
+ */
+void TMR_EnableCCPreload(TMR_T *tmr)
+{
+    tmr->CTRL2_B.CCPEN = ENABLE;
+}
+
+/*!
+ * @brief     Disable Capture Compare Preload Control bit.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @retval    None
+ */
+void TMR_DisableCCPreload(TMR_T *tmr)
+{
+    tmr->CTRL2_B.CCPEN = DISABLE;
+}
+
+/*!
+ * @brief     Configures the TMRx's DMA interface.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     baseAddress: DMA Base address.
+ *                         This parameter can be one of the following values:
+ *                         @arg TMR_DMA_BASE_CTRL1
+ *                         @arg TMR_DMA_BASE_CTRL2
+ *                         @arg TMR_DMA_BASE_SMCTRL
+ *                         @arg TMR_DMA_BASE_DIEN
+ *                         @arg TMR_DMA_BASE_STS
+ *                         @arg TMR_DMA_BASE_CEG
+ *                         @arg TMR_DMA_BASE_CCM1
+ *                         @arg TMR_DMA_BASE_CCM2
+ *                         @arg TMR_DMA_BASE_CCEN
+ *                         @arg TMR_DMA_BASE_CNT
+ *                         @arg TMR_DMA_BASE_PSC
+ *                         @arg TMR_DMA_BASE_AUTORLD
+ *                         @arg TMR_DMA_BASE_REPCNT
+ *                         @arg TMR_DMA_BASE_CC1
+ *                         @arg TMR_DMA_BASE_CC2
+ *                         @arg TMR_DMA_BASE_CC3
+ *                         @arg TMR_DMA_BASE_CC4
+ *                         @arg TMR_DMA_BASE_BDT
+ *                         @arg TMR_DMA_BASE_DCTRL
+ *
+ * @param     burstLength: DMA Burst length. This parameter can be one value
+ *            between: TMR_DMA_BURSTLENGTH_1TRANSFER and TMR_DMA_BURSTLENGTH_18TRANSFERS.
+ *
+ * @retval    None
+ */
+void TMR_ConfigDMA(TMR_T *tmr, TMR_DMA_BASE_T baseAddress, TMR_DMA_BURSTLENGTH_T burstLength)
+{
+    tmr->DCTRL = (uint32_t)baseAddress | (uint32_t)burstLength;
+}
+
+/*!
+ * @brief     Enable TMRx Requests.
+ *
+ * @param     tmr: The TMRx can be 1 to 8
+ *
+ * @param     dmaSource: specifies the TMR DMA souces
+ *                      The parameter can be any combination of following values:
+ *                      @arg TMR_DMA_SOURCE_UPDATE: TMR update DMA souces
+ *                      @arg TMR_DMA_SOURCE_CH1:    TMR Capture Compare 1 DMA souces
+ *                      @arg TMR_DMA_SOURCE_CH2:    TMR Capture Compare 2 DMA souces
+ *                      @arg TMR_DMA_SOURCE_CH3:    TMR Capture Compare 3 DMA souces
+ *                      @arg TMR_DMA_SOURCE_CH4:    TMR Capture Compare 4 DMA souces
+ *                      @arg TMR_DMA_SOURCE_COM:    TMR Commutation DMA souces
+ *                      @arg TMR_DMA_SOURCE_TRG:    TMR Trigger DMA souces
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void TMR_EnableDMASoure(TMR_T *tmr, uint16_t dmaSource)
+{
+    tmr->DIEN |= dmaSource;
+}
+
+/*!
+ * @brief     Disable TMRx Requests.
+ *
+ * @param     tmr: The TMRx can be 1 to 8
+ *
+ * @param     dmaSource: specifies the TMR DMA souces
+ *                       The parameter can be any combination of following values:
+ *                       @arg TMR_DMA_SOURCE_UPDATE: TMR update DMA souces
+ *                       @arg TMR_DMA_SOURCE_CH1:    TMR Capture Compare 1 DMA souces
+ *                       @arg TMR_DMA_SOURCE_CH2:    TMR Capture Compare 2 DMA souces
+ *                       @arg TMR_DMA_SOURCE_CH3:    TMR Capture Compare 3 DMA souces
+ *                       @arg TMR_DMA_SOURCE_CH4:    TMR Capture Compare 4 DMA souces
+ *                       @arg TMR_DMA_SOURCE_COM:    TMR Commutation DMA souces
+ *                       @arg TMR_DMA_SOURCE_TRG:    TMR Trigger DMA souces
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void TMR_DisableDMASoure(TMR_T *tmr, uint16_t dmaSource)
+{
+    tmr->DIEN &= ~dmaSource;
+}
+
+/*!
+ * @brief     Enable Capture Compare DMA source.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @retval    None
+ */
+void TMR_EnableCCDMA(TMR_T *tmr)
+{
+    tmr->CTRL2_B.CCDSEL = ENABLE;
+}
+
+/*!
+ * @brief     Disable Capture Compare DMA source.
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @retval    None
+ */
+void TMR_DisableCCDMA(TMR_T *tmr)
+{
+    tmr->CTRL2_B.CCDSEL = DISABLE;
+}
+
+/*!
+ * @brief     Configures the TMRx internal Clock
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @retval    None
+ */
+void TMR_ConfigInternalClock(TMR_T *tmr)
+{
+    tmr->SMCTRL_B.SMFSEL = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the TMRx Internal Trigger as External Clock
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     triggerSource: specifies the TMR trigger souces
+ *                           The parameter can be one of following values:
+ *                           @arg TMR_TRIGGER_SOURCE_ITR0: TMR Internal Trigger 0
+ *                           @arg TMR_TRIGGER_SOURCE_ITR1: TMR Internal Trigger 1
+ *                           @arg TMR_TRIGGER_SOURCE_ITR2: TMR Internal Trigger 2
+ *                           @arg TMR_TRIGGER_SOURCE_ITR3: TMR Internal Trigger 3
+ *
+ * @retval    None
+ */
+void TMR_ConfigIntTrigExternalClock(TMR_T *tmr, TMR_TRIGGER_SOURCE_T triggerSource)
+{
+    TMR_SelectInputTrigger(tmr, triggerSource);
+    tmr->SMCTRL_B.SMFSEL = TMR_SLAVE_MODE_EXTERNAL1;
+}
+
+/*!
+ * @brief     Configures the TMRx  Trigger as External Clock
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     triggerSource: specifies the TMR trigger souces
+ *                           The parameter can be one of following values:
+ *                           @arg TMR_TRIGGER_SOURCE_TI1F_ED:  TI1 Edge Detector
+ *                           @arg TMR_TRIGGER_SOURCE_TI1FP1:   Filtered Timer Input 1
+ *                           @arg TMR_TRIGGER_SOURCE_TI2FP2:   Filtered Timer Input 2
+ *
+ * @param     ICpolarity: specifies the TMR IC polarity
+ *                        The parameter can be one of following values:
+ *                        @arg TMR_IC_POLARITY_RISING:  TMR IC polarity rising
+ *                        @arg TMR_IC_POLARITY_FALLING: TMR IC polarity falling
+ *
+ * @param     ICfilter: This parameter must be a value between 0x00 and 0x0F.
+ *
+ * @retval    None
+ */
+void TMR_ConfigTrigExternalClock(TMR_T *tmr, TMR_TRIGGER_SOURCE_T triggerSource,
+                                 TMR_IC_POLARITY_T ICpolarity, uint16_t ICfilter)
+{
+    if (triggerSource == TMR_TRIGGER_SOURCE_TI2FP2)
+    {
+        TI2Config(tmr, ICpolarity, TMR_IC_SELECTION_DIRECT_TI, ICfilter);
+    }
+    else
+    {
+        TI1Config(tmr, ICpolarity, TMR_IC_SELECTION_DIRECT_TI, ICfilter);
+    }
+
+    TMR_SelectInputTrigger(tmr, triggerSource);
+    tmr->SMCTRL_B.SMFSEL = 0x07;
+}
+
+/*!
+ * @brief     Configures the External clock Mode1
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     prescaler: specifies the external Trigger Prescaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_EXTTRG_PSC_OFF:  ETRP Prescaler OFF
+ *                       @arg TMR_EXTTRG_PSC_DIV2: ETRP frequency divided by 2
+ *                       @arg TMR_EXTTRG_PSC_DIV4: ETRP frequency divided by 4
+ *                       @arg TMR_EXTTRG_PSC_DIV8: ETRP frequency divided by 8
+ *
+ * @param     polarity: specifies the TMR IC polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_EXTTRG_POL_INVERTED:  Active low or falling edge active
+ *                      @arg TMR_EXTTGR_POL_NONINVERTED: Active high or rising edge active
+ *
+ * @param     filter: This parameter must be a value between 0x00 and 0x0F.
+ *
+ * @retval    None
+ */
+void TMR_ConfigETRClockMode1(TMR_T *tmr, TMR_EXTTRG_PSC_T prescaler,
+                             TMR_EXTTRG_POL_T polarity, uint16_t filter)
+{
+    TMR_ConfigETR(tmr, prescaler, polarity, filter);
+
+    tmr->SMCTRL_B.SMFSEL = TMR_SLAVE_MODE_EXTERNAL1;
+    tmr->SMCTRL_B.TRGSEL = TMR_TRIGGER_SOURCE_ETRF;
+}
+
+/*!
+ * @brief     Configures the External clock Mode2
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     prescaler: specifies the external Trigger Prescaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_EXTTRG_PSC_OFF:  ETRP Prescaler OFF
+ *                       @arg TMR_EXTTRG_PSC_DIV2: ETRP frequency divided by 2
+ *                       @arg TMR_EXTTRG_PSC_DIV4: ETRP frequency divided by 4
+ *                       @arg TMR_EXTTRG_PSC_DIV8: ETRP frequency divided by 8
+ *
+ * @param     polarity: specifies the TMR IC polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_EXTTRG_POL_INVERTED:  Active low or falling edge active
+ *                      @arg TMR_EXTTGR_POL_NONINVERTED: Active high or rising edge active
+ *
+ * @param     filter: This parameter must be a value between 0x00 and 0x0F.
+ *
+ * @retval    None
+ */
+void TMR_ConfigETRClockMode2(TMR_T *tmr, TMR_EXTTRG_PSC_T prescaler,
+                             TMR_EXTTRG_POL_T polarity, uint16_t filter)
+{
+    TMR_ConfigETR(tmr, prescaler, polarity, filter);
+
+    tmr->SMCTRL_B.ECEN = ENABLE;
+}
+
+/*!
+ * @brief     Selects the Input Trigger source
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     triggerSource: specifies the Input Trigger source
+ *                           The parameter can be one of following values:
+ *                           @arg TMR_TRIGGER_SOURCE_ITR0: Internal Trigger 0
+ *                           @arg TMR_TRIGGER_SOURCE_ITR1: Internal Trigger 1
+ *                           @arg TMR_TRIGGER_SOURCE_ITR2: Internal Trigger 2
+ *                           @arg TMR_TRIGGER_SOURCE_ITR3: Internal Trigger 3
+ *                           @arg TMR_TRIGGER_SOURCE_TI1F_ED: TI1 Edge Detector
+ *                           @arg TMR_TRIGGER_SOURCE_TI1FP1: Filtered Timer Input 1
+ *                           @arg TMR_TRIGGER_SOURCE_TI2FP2: Filtered Timer Input 2
+ *                           @arg TMR_TRIGGER_SOURCE_ETRF: External Trigger input
+ *
+ * @retval    None
+ */
+void TMR_SelectInputTrigger(TMR_T *tmr, TMR_TRIGGER_SOURCE_T triggerSource)
+{
+    tmr->SMCTRL_B.TRGSEL = triggerSource;
+}
+
+/*!
+ * @brief     Selects the Trigger Output Mode.
+ *
+ * @param     tmr: The TMRx can be 1 to 8
+ *
+ * @param     TRGOSource: specifies the Trigger Output source
+ *                       The parameter can be one of following values:
+ *                        @arg TMR_TRGO_SOURCE_RESET
+ *                        @arg TMR_TRGO_SOURCE_ENABLE
+ *                        @arg TMR_TRGO_SOURCE_UPDATE
+ *                       The under parameters are not for TMR6 and TMR7:
+ *                        @arg TMR_TRGO_SOURCE_OC1
+ *                        @arg TMR_TRGO_SOURCE_OC1REF
+ *                        @arg TMR_TRGO_SOURCE_OC2REF
+ *                        @arg TMR_TRGO_SOURCE_OC3REF
+ *                        @arg TMR_TRGO_SOURCE_OC4REF
+ *
+ * @retval    None
+ */
+void TMR_SelectOutputTrigger(TMR_T *tmr, TMR_TRGO_SOURCE_T TRGOSource)
+{
+    tmr->CTRL2_B.MMSEL = TRGOSource;
+}
+
+/*!
+ * @brief     Selects the Slave Mode.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     slaveMode: specifies the Timer Slave Mode.
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_SLAVE_MODE_RESET
+ *                       @arg TMR_SLAVE_MODE_GATED
+ *                       @arg TMR_SLAVE_MODE_TRIGGER
+ *                       @arg TMR_SLAVE_MODE_EXTERNAL1
+ *
+ * @retval    None
+ */
+void TMR_SelectSlaveMode(TMR_T *tmr, TMR_SLAVE_MODE_T slaveMode)
+{
+    tmr->SMCTRL_B.SMFSEL = slaveMode;
+}
+
+/*!
+ * @brief     Enable the Master Slave Mode
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @retval    None
+ */
+void TMR_EnableMasterSlaveMode(TMR_T *tmr)
+{
+    tmr->SMCTRL_B.MSMEN = ENABLE;
+}
+
+/*!
+ * @brief     Disable the Master Slave Mode
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @retval    None
+ */
+void TMR_DisableMasterSlaveMode(TMR_T *tmr)
+{
+    tmr->SMCTRL_B.MSMEN = DISABLE;
+}
+
+/*!
+ * @brief     Configures the TMRx External Trigger (ETR).
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     prescaler: specifies the external Trigger Prescaler
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_EXTTRG_PSC_OFF:  ETRP Prescaler OFF
+ *                       @arg TMR_EXTTRG_PSC_DIV2: ETRP frequency divided by 2
+ *                       @arg TMR_EXTTRG_PSC_DIV4: ETRP frequency divided by 4
+ *                       @arg TMR_EXTTRG_PSC_DIV8: ETRP frequency divided by 8
+ *
+ * @param     polarity: specifies the TMR IC polarity
+ *                      The parameter can be one of following values:
+ *                      @arg TMR_EXTTRG_POL_INVERTED:  Active low or falling edge active
+ *                      @arg TMR_EXTTGR_POL_NONINVERTED: Active high or rising edge active
+ *
+ * @param     filter: This parameter must be a value between 0x00 and 0x0F.
+ *
+ * @retval    None
+ */
+void TMR_ConfigETR(TMR_T *tmr, TMR_EXTTRG_PSC_T prescaler,
+                   TMR_EXTTRG_POL_T polarity, uint16_t filter)
+{
+    tmr->SMCTRL &= 0x00FF;
+    tmr->SMCTRL_B.ETPCFG = prescaler;
+    tmr->SMCTRL_B.ETPOL = polarity;
+    tmr->SMCTRL_B.ETFCFG = filter;
+}
+
+/*!
+ * @brief     Configures the Encoder Interface.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     encodeMode: specifies the Encoder Mode
+ *                        The parameter can be one of following values:
+ *                        @arg TMR_ENCODER_MODE_TI1
+ *                        @arg TMR_ENCODER_MODE_TI2
+ *                        @arg TMR_ENCODER_MODE_TI12
+ *
+ * @param     IC1Polarity: specifies the TMR IC1 polarity
+ *                         The parameter can be one of following values:
+ *                         @arg TMR_IC_POLARITY_RISING:  TMR IC polarity rising
+ *                         @arg TMR_IC_POLARITY_FALLING: TMR IC polarity falling
+ *
+ * @param     IC2Polarity: specifies the TMR IC2 polarity
+ *                         The parameter can be one of following values:
+ *                         @arg TMR_IC_POLARITY_RISING:  TMR IC polarity rising
+ *                         @arg TMR_IC_POLARITY_FALLING: TMR IC polarity falling
+ *
+ * @retval    None
+ */
+void TMR_ConfigEncodeInterface(TMR_T *tmr, TMR_ENCODER_MODE_T encodeMode, TMR_IC_POLARITY_T IC1Polarity,
+                               TMR_IC_POLARITY_T IC2Polarity)
+{
+    tmr->SMCTRL_B.SMFSEL = BIT_RESET;
+    tmr->SMCTRL_B.SMFSEL = encodeMode;
+
+    tmr->CCM1_CAPTURE_B.CC1SEL = BIT_RESET ;
+    tmr->CCM1_CAPTURE_B.CC2SEL = BIT_RESET ;
+    tmr->CCM1_CAPTURE_B.CC1SEL = 0x01 ;
+    tmr->CCM1_CAPTURE_B.CC2SEL = 0x01 ;
+
+    tmr->CCEN_B.CC1POL = BIT_RESET;
+    tmr->CCEN_B.CC2POL = BIT_RESET;
+    tmr->CCEN_B.CC1POL = IC1Polarity;
+    tmr->CCEN_B.CC2POL = IC2Polarity;
+}
+
+/*!
+ * @brief     Enables Hall sensor interface.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @retval    None
+ */
+void TMR_EnableHallSensor(TMR_T *tmr)
+{
+    tmr->CTRL2_B.TI1SEL = ENABLE;
+}
+
+/*!
+ * @brief     Disable Hall sensor interface.
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @retval    None
+ */
+void TMR_DisableHallSensor(TMR_T *tmr)
+{
+    tmr->CTRL2_B.TI1SEL = DISABLE;
+}
+
+/*!
+ * @brief     Configures the TMR2, TMR5 and TMR11 Remapping input capabilities.
+ *
+ * @param     tmr: The TMRx can be 2, 5 or 11
+ *
+ * @param     remap: specifies the MR input remapping source.
+ *                   The parameter can be one of the following values:
+ *                   @arg TMR2_TMR8_TRGO     : TMR2 ITR1 input is connected to TMR8 Trigger output(default)
+ *                   @arg TMR2_PTP_TRG       : TMR2 ITR1 input is connected to ETH PTP trigger output.
+ *                   @arg TMR2_OTG_FSUSB_SOF : TMR2 ITR1 input is connected to OTG FS SOF.
+ *                   @arg TMR2_OTG_HSUSB_SOF : TMR2 ITR1 input is connected to OTG HS SOF.
+ *                   @arg TMR5_GPIO          : TMR5 CH4 input is connected to GPIO
+ *                   @arg TMR5_LSI           : TMR5 CH4 input is connected to LSI clock.
+ *                   @arg TMR5_LSE           : TMR5 CH4 input is connected to LSE clock.
+ *                   @arg TMR5_RTC           : TMR5 CH4 input is connected to RTC Output event.
+ *                   @arg TMRx_GPIO          : TMR10/11/13/14 CH1 input is connected to GPIO
+ *                   @arg TMRx_RTCCLK        : TMR10/11/13/14 CH1 input is connected to RTC clock
+ *                   @arg TMRx_HSECLK        : TMR10/11/13/14 CH1 input is connected to HSE clock/32
+ *                   @arg TMRx_MCO           : TMR10/11/13/14 CH1 input is connected to MCO
+ *
+ * @retval    None
+ */
+void TMR_ConfigRemap(TMR_T *tmr, uint32_t remap)
+{
+    tmr->OPT = remap;
+}
+
+/*!
+ * @brief     Enable intterupts
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                       The parameter can be any combination of following values:
+ *                       @arg TMR_INT_UPDATE: Timer update Interrupt source
+ *                       @arg TMR_INT_CC1: Timer Capture Compare 1 Interrupt source
+ *                       @arg TMR_INT_CC2: Timer Capture Compare 2 Interrupt source
+ *                       @arg TMR_INT_CC3: Timer Capture Compare 3 Interrupt source
+ *                       @arg TMR_INT_CC4: Timer Capture Compare 4 Interrupt source
+ *                       @arg TMR_INT_COM: Timer Commutation Interrupt source (Only for TMR1 and TMR8)
+ *                       @arg TMR_INT_TRG: Timer Trigger Interrupt source
+ *                       @arg TMR_INT_BRK: Timer Break Interrupt source (Only for TMR1 and TMR8)
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_INT_UPDATE.
+ */
+void TMR_EnableInterrupt(TMR_T *tmr, uint16_t interrupt)
+{
+    tmr->DIEN |= interrupt;
+}
+
+/*!
+ * @brief     Disable intterupts
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                       The parameter can be any combination of following values:
+ *                       @arg TMR_INT_UPDATE: Timer update Interrupt source
+ *                       @arg TMR_INT_CC1: Timer Capture Compare 1 Interrupt source
+ *                       @arg TMR_INT_CC2: Timer Capture Compare 1 Interrupt source
+ *                       @arg TMR_INT_CC3: Timer Capture Compare 3 Interrupt source
+ *                       @arg TMR_INT_CC4: Timer Capture Compare 4 Interrupt source
+ *                       @arg TMR_INT_COM: Timer Commutation Interrupt source (Only for TMR1 and TMR8)
+ *                       @arg TMR_INT_TRG: Timer Trigger Interrupt source
+ *                       @arg TMR_INT_BRK: Timer Break Interrupt source (Only for TMR1 and TMR8)
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_INT_UPDATE.
+ */
+void TMR_DisableInterrupt(TMR_T *tmr, uint16_t interrupt)
+{
+    tmr->DIEN &= ~interrupt;
+}
+
+/*!
+ * @brief     Configures the TMRx event to be generate by software.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     eventSources: specifies the TMR event sources
+ *                         The parameter can be any combination of following values:
+ *                         @arg TMR_EVENT_UPDATE: Timer update Interrupt source
+ *                         @arg TMR_EVENT_CH1: Timer Capture Compare 1 Event source
+ *                         @arg TMR_EVENT_CH2: Timer Capture Compare 1 Event source
+ *                         @arg TMR_EVENT_CH3: Timer Capture Compare 3 Event source
+ *                         @arg TMR_EVENT_CH4: Timer Capture Compare 4 Event source
+ *                         @arg TMR_EVENT_COM: Timer Commutation Event source (Only for TMR1 and TMR8)
+ *                         @arg TMR_EVENT_TRG: Timer Trigger Event source
+ *                         @arg TMR_EVENT_BRK: Timer Break Event source (Only for TMR1 and TMR8)
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_EVENT_UPDATE.
+ */
+void TMR_GenerateEvent(TMR_T *tmr, uint16_t eventSources)
+{
+    tmr->CEG = eventSources;
+}
+
+/*!
+ * @brief     Check whether the flag is set or reset
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                     The parameter can be any combination of following values:
+ *                     @arg TMR_FLAG_UPDATE: Timer update Flag
+ *                     @arg TMR_FLAG_CH1: Timer Capture Compare 1 Flag
+ *                     @arg TMR_FLAG_CH2: Timer Capture Compare 2 Flag
+ *                     @arg TMR_FLAG_CH3: Timer Capture Compare 3 Flag
+ *                     @arg TMR_FLAG_CH4: Timer Capture Compare 4 Flag
+ *                     @arg TMR_FLAG_COM: Timer Commutation Flag (Only for TMR1 and TMR8)
+ *                     @arg TMR_FLAG_TRG: Timer Trigger Flag
+ *                     @arg TMR_FLAG_BRK: Timer Break Flag (Only for TMR1 and TMR8)
+ *                     @arg TMR_FLAG_CC1RC: Timer Capture Compare 1 Repetition Flag
+ *                     @arg TMR_FLAG_CC2RC: Timer Capture Compare 2 Repetition Flag
+ *                     @arg TMR_FLAG_CC3RC: Timer Capture Compare 3 Repetition Flag
+ *            @arg TMR_FLAG_CC4RC: Timer Capture Compare 4 Repetition Flag
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_FLAG_UPDATE.
+ */
+uint16_t TMR_ReadStatusFlag(TMR_T *tmr, TMR_FLAG_T flag)
+{
+    return (tmr->STS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the TMR's pending flags.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                      The parameter can be any combination of following values:
+ *                      @arg TMR_FLAG_UPDATE: Timer update Flag
+ *                      @arg TMR_FLAG_CH1: Timer Capture Compare 1 Flag
+ *                      @arg TMR_FLAG_CH2: Timer Capture Compare 2 Flag
+ *                      @arg TMR_FLAG_CH3: Timer Capture Compare 3 Flag
+ *                      @arg TMR_FLAG_CH4: Timer Capture Compare 4 Flag
+ *                      @arg TMR_FLAG_COM: Timer Commutation Flag (Only for TMR1 and TMR8)
+ *                      @arg TMR_FLAG_TRG: Timer Trigger Flag
+ *                      @arg TMR_FLAG_BRK: Timer Break Flag (Only for TMR1 and TMR8)
+ *                      @arg TMR_FLAG_CC1RC: Timer Capture Compare 1 Repetition Flag
+ *                      @arg TMR_FLAG_CC2RC: Timer Capture Compare 2 Repetition Flag
+ *                      @arg TMR_FLAG_CC3RC: Timer Capture Compare 3 Repetition Flag
+ *                      @arg TMR_FLAG_CC4RC: Timer Capture Compare 4 Repetition Flag
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_FLAG_UPDATE.
+ */
+void TMR_ClearStatusFlag(TMR_T *tmr, uint16_t flag)
+{
+    tmr->STS = ~flag;
+}
+
+/*!
+ * @brief     Check whether the ITflag is set or reset
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                       The parameter can be one of following values:
+ *                       @arg TMR_INT_UPDATE: Timer update Interrupt source
+ *                       @arg TMR_INT_CC1: Timer Capture Compare 1 Interrupt source
+ *                       @arg TMR_INT_CC2: Timer Capture Compare 1 Interrupt source
+ *                       @arg TMR_INT_CC3: Timer Capture Compare 3 Interrupt source
+ *                       @arg TMR_INT_CC4: Timer Capture Compare 4 Interrupt source
+ *                       @arg TMR_INT_COM: Timer Commutation Interrupt source (Only for TMR1 and TMR8)
+ *                       @arg TMR_INT_TRG: Timer Trigger Interrupt source
+ *                       @arg TMR_INT_BRK: Timer Break Interrupt source (Only for TMR1 and TMR8)
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_INT_UPDATE.
+ */
+uint16_t TMR_ReadIntFlag(TMR_T *tmr, TMR_INT_T flag)
+{
+    if (((tmr->STS & flag) != RESET) && ((tmr->DIEN & flag) != RESET))
+    {
+        return SET;
+    }
+    else
+    {
+        return RESET;
+    }
+}
+
+/*!
+ * @brief     Clears the TMR's interrupt pending bits.
+ *
+ * @param     tmr: The TMRx can be 1 to 14
+ *
+ * @param     interrupt: specifies the TMR interrupts sources
+ *                      The parameter can be any combination following values:
+ *                      @arg TMR_INT_UPDATE: Timer update Interrupt source
+ *                      @arg TMR_INT_CC1: Timer Capture Compare 1 Interrupt source
+ *                      @arg TMR_INT_CC2: Timer Capture Compare 1 Interrupt source
+ *                      @arg TMR_INT_CC3: Timer Capture Compare 3 Interrupt source
+ *                      @arg TMR_INT_CC4: Timer Capture Compare 4 Interrupt source
+ *                      @arg TMR_INT_COM: Timer Commutation Interrupt source (Only for TMR1 and TMR8)
+ *                      @arg TMR_INT_TRG: Timer Trigger Interrupt source
+ *                      @arg TMR_INT_BRK: Timer Break Interrupt source (Only for TMR1 and TMR8)
+ *
+ * @retval    None
+ *
+ * @note      TMR6 and TMR7 can only generate an TMR_INT_UPDATE.
+ */
+void TMR_ClearIntFlag(TMR_T *tmr,  uint16_t flag)
+{
+    tmr->STS = ~flag;
+}
+
+/*!
+ * @brief     Configure the TI1 as Input
+ *
+ * @param     tmr: The TMRx can be 1 to 14 except 6 and 7
+ *
+ * @param     ICpolarity: pointer to a TMR_IC_POLARITY_T structure
+ *
+ * @param     ICselection: pointer to a TMR_IC_SELECTION_T structure
+ *
+ * @param     ICfilter: This parameter must be a value between 0x00 and 0x0F
+ *
+ * @retval    None
+ */
+static void TI1Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter)
+{
+    uint16_t tmpchctrl = 0;
+
+    tmr->CCEN_B.CC1EN = BIT_RESET;
+
+    tmr->CCM1_CAPTURE_B.CC1SEL = BIT_RESET;
+    tmr->CCM1_CAPTURE_B.IC1F = BIT_RESET;
+    tmr->CCM1_CAPTURE_B.CC1SEL = ICselection;
+    tmr->CCM1_CAPTURE_B.IC1F = ICfilter;
+
+    if ((tmr == TMR1) || (tmr == TMR8) || (tmr == TMR2) || (tmr == TMR3) ||
+            (tmr == TMR4) || (tmr == TMR5))
+    {
+        tmr->CCEN_B.CC1POL = BIT_RESET;
+        tmr->CCEN_B.CC1EN = BIT_SET;
+        tmpchctrl = tmr->CCEN;
+        tmpchctrl |= ICpolarity;
+        tmr->CCEN = tmpchctrl;
+    }
+    else
+    {
+        tmr->CCEN_B.CC1POL = BIT_RESET;
+        tmr->CCEN_B.CC1NPOL = BIT_RESET;
+        tmr->CCEN_B.CC1EN = BIT_SET;
+        tmpchctrl = tmr->CCEN;
+        tmpchctrl |= ICpolarity;
+        tmr->CCEN = tmpchctrl;
+    }
+}
+
+/*!
+ * @brief     Configure the TI2 as Input
+ *
+ * @param     tmr: The TMRx can be 1 to 12 except 6 7 10 and 11
+ *
+ * @param     ICpolarity: pointer to a TMR_IC_POLARITY_T structure
+ *
+ * @param     ICselection: pointer to a TMR_IC_SELECTION_T structure
+ *
+ * @param     ICfilter: This parameter must be a value between 0x00 and 0x0F
+ *
+ * @retval    None
+ */
+static void TI2Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter)
+{
+    uint16_t tmpchctrl = 0;
+
+    tmr->CCEN_B.CC2EN = BIT_RESET;
+
+    tmr->CCM1_CAPTURE_B.CC2SEL = BIT_RESET;
+    tmr->CCM1_CAPTURE_B.IC2F = BIT_RESET;
+    tmr->CCM1_CAPTURE_B.CC2SEL = ICselection;
+    tmr->CCM1_CAPTURE_B.IC2F = ICfilter;
+
+    if ((tmr == TMR1) || (tmr == TMR8) || (tmr == TMR2) || (tmr == TMR3) ||
+            (tmr == TMR4) || (tmr == TMR5))
+    {
+        tmr->CCEN_B.CC2POL = BIT_RESET;
+        tmr->CCEN_B.CC2EN = BIT_SET;
+        tmpchctrl = tmr->CCEN;
+        tmpchctrl |= (ICpolarity << 4);
+        tmr->CCEN = tmpchctrl;
+    }
+    else
+    {
+        tmr->CCEN_B.CC2POL = BIT_RESET;
+        tmr->CCEN_B.CC2NPOL = BIT_RESET;
+        tmr->CCEN_B.CC2EN = BIT_SET;
+        tmpchctrl = tmr->CCEN;
+        tmpchctrl |= (ICpolarity << 4);
+        tmr->CCEN = tmpchctrl;
+    }
+}
+
+/*!
+ * @brief     Configure the TI3 as Input
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     ICpolarity: pointer to a TMR_IC_POLARITY_T structure
+ *
+ * @param     ICselection: pointer to a TMR_IC_SELECTION_T structure
+ *
+ * @param     ICfilter: This parameter must be a value between 0x00 and 0x0F
+ *
+ * @retval    None
+ */
+static void TI3Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter)
+{
+    uint16_t tmpchctrl = 0;
+
+    tmr->CCEN_B.CC3EN = BIT_RESET;
+
+    tmr->CCM2_CAPTURE_B.CC3SEL = BIT_RESET;
+    tmr->CCM2_CAPTURE_B.IC3F = BIT_RESET;
+    tmr->CCM2_CAPTURE_B.CC3SEL = ICselection;
+    tmr->CCM2_CAPTURE_B.IC3F = ICfilter;
+
+    if ((tmr == TMR1) || (tmr == TMR8) || (tmr == TMR2) || (tmr == TMR3) ||
+            (tmr == TMR4) || (tmr == TMR5))
+    {
+        tmr->CCEN_B.CC3POL = BIT_RESET;
+        tmr->CCEN_B.CC3EN = BIT_SET;
+        tmpchctrl = tmr->CCEN;
+        tmpchctrl |= (ICpolarity << 8);
+        tmr->CCEN = tmpchctrl;
+    }
+    else
+    {
+        tmr->CCEN_B.CC3POL = BIT_RESET;
+        tmr->CCEN_B.CC3NPOL = BIT_RESET;
+        tmr->CCEN_B.CC3EN = BIT_SET;
+        tmpchctrl = tmr->CCEN;
+        tmpchctrl |= (ICpolarity << 8);
+        tmr->CCEN = tmpchctrl;
+    }
+}
+
+/*!
+ * @brief     Configure the TI4 as Input
+ *
+ * @param     tmr: The TMRx can be 1 to 8 except 6 and 7
+ *
+ * @param     ICpolarity: pointer to a TMR_IC_POLARITY_T structure
+ *
+ * @param     ICselection: pointer to a TMR_IC_SELECTION_T structure
+ *
+ * @param     ICfilter: This parameter must be a value between 0x00 and 0x0F
+ *
+ * @retval    None
+ */
+static void TI4Config(TMR_T *tmr, uint16_t ICpolarity, uint16_t ICselection, uint16_t ICfilter)
+{
+    uint16_t tmpchctrl = 0;
+
+    tmr->CCEN_B.CC4EN = BIT_RESET;
+
+    tmr->CCM2_CAPTURE_B.CC4SEL = BIT_RESET;
+    tmr->CCM2_CAPTURE_B.IC4F = BIT_RESET;
+    tmr->CCM2_CAPTURE_B.CC4SEL = ICselection;
+    tmr->CCM2_CAPTURE_B.IC4F = ICfilter;
+
+    tmr->CCEN_B.CC4POL = BIT_RESET;
+    tmr->CCEN_B.CC4EN = BIT_SET;
+    tmpchctrl = tmr->CCEN;
+    tmpchctrl |= (ICpolarity << 12);
+    tmr->CCEN = tmpchctrl;
+}
+
+/**@} end of group TMR_Functions */
+/**@} end of group TMR_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 862 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_usart.c

@@ -0,0 +1,862 @@
+/*!
+ * @file        apm32f4xx_usart.c
+ *
+ * @brief       This file provides all the USART firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_usart.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup USART_Driver
+  * @brief USART driver modules
+  @{
+*/
+
+/** @defgroup USART_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset usart peripheral registers to their default reset values
+ *
+ * @param     USARTx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or
+ *                    UART peripheral.
+ *
+ * @retval    None
+ */
+void USART_Reset(USART_T *usart)
+{
+    if (USART1 == usart)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_USART1);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_USART1);
+    }
+    else if (USART2 == usart)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_USART2);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_USART2);
+    }
+    else if (USART3 == usart)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_USART3);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_USART3);
+    }
+    else if (UART4 == usart)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_UART4);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_UART4);
+    }
+    else if (UART5 == usart)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_UART5);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_UART5);
+    }
+    else if (USART6 == usart)
+    {
+        RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_USART6);
+        RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_USART6);
+    }
+    else if (UART7 == usart)
+    {
+        RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_UART7);
+        RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_UART7);
+    }
+    else if (UART8 == usart)
+    {
+        RCM_EnableAPB1PeriphReset((uint32_t)RCM_APB1_PERIPH_UART8);
+        RCM_DisableAPB1PeriphReset((uint32_t)RCM_APB1_PERIPH_UART8);
+    }
+}
+
+/*!
+ * @brief     Config the USART peripheral according to the specified parameters in the usartConfig
+ *
+ * @param     usart:         Select the USART or the UART peripheral
+ *
+ * @param     usartConfig:  pointer to a USART_Config_T structure
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_Config(USART_T *usart, USART_Config_T *usartConfig)
+{
+    uint32_t temp, fCLK, intDiv, fractionalDiv;
+
+    usart->CTRL1_B.RXEN = usartConfig->mode & 0x01;
+    usart->CTRL1_B.TXEN = usartConfig->mode >> 1;
+    usart->CTRL1_B.PCFG = usartConfig->parity >> 1;
+    usart->CTRL1_B.PCEN = usartConfig->parity & 0x01;
+    usart->CTRL1_B.DBLCFG = usartConfig->wordLength;
+
+    usart->CTRL2_B.STOPCFG = usartConfig->stopBits;
+
+    usart->CTRL3_B.RTSEN = usartConfig->hardwareFlow & 0x01;
+    usart->CTRL3_B.CTSEN = usartConfig->hardwareFlow >> 1;
+
+    if ((usart == USART1) || (usart == USART6))
+    {
+        RCM_ReadPCLKFreq(NULL, &fCLK);
+    }
+    else
+    {
+        RCM_ReadPCLKFreq(&fCLK, NULL);
+    }
+
+    /* Compute the integer part */
+    if (usart->CTRL1_B.OSMCFG != RESET) /*!< Oversampling by 8 */
+    {
+        intDiv = ((25 * fCLK) / (2 * (usartConfig->baudRate)));
+    }
+    else /*!< Oversampling by 16 */
+    {
+        intDiv = ((25 * fCLK) / (4 * (usartConfig->baudRate)));
+    }
+
+    temp = (intDiv / 100) << 4;
+    fractionalDiv = intDiv - (100 * (temp >> 4));
+
+    /* Implement the fractional part in the register */
+    if (usart->CTRL1_B.OSMCFG != RESET) /*!< Oversampling by 8 */
+    {
+        temp |= ((((fractionalDiv * 8) + 50) / 100)) & ((uint8_t)0x07);
+    }
+    else /*!< Oversampling by 16 */
+    {
+        temp |= ((((fractionalDiv * 16) + 50) / 100)) & ((uint8_t)0x0F);
+    }
+
+    usart->BR = temp;
+}
+
+/*!
+ * @brief     Fills each USART_InitStruct member with its default value
+ *
+ * @param     usartConfig:   pointer to a USART_Config_T structure which will be initialized
+ *
+ * @retval    None
+ */
+void USART_ConfigStructInit(USART_Config_T *usartConfig)
+{
+    usartConfig->baudRate = 9600;
+    usartConfig->wordLength = USART_WORD_LEN_8B;
+    usartConfig->stopBits = USART_STOP_BIT_1;
+    usartConfig->parity = USART_PARITY_NONE ;
+    usartConfig->mode = USART_MODE_TX_RX;
+    usartConfig->hardwareFlow = USART_HARDWARE_FLOW_NONE;
+}
+
+/*!
+ * @brief     Configuration communication clock
+ *
+ * @param     usart:  Select the USART or the UART peripheral
+ *
+ * @param     clockConfig:   Pointer to a USART_clockConfig_T structure
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3 and USART6
+ */
+void USART_ConfigClock(USART_T *usart, USART_ClockConfig_T *clockConfig)
+{
+    usart->CTRL2_B.CLKEN   = clockConfig->clock;
+    usart->CTRL2_B.CPHA    = clockConfig->phase;
+    usart->CTRL2_B.CPOL    = clockConfig->polarity;
+    usart->CTRL2_B.LBCPOEN = clockConfig->lastBit;
+}
+
+/*!
+ * @brief     Fills each clockConfig member with its default value
+ *
+ * @param     clockConfig:   Pointer to a USART_clockConfig_T structure
+ *
+ * @retval    None
+ *
+ * @note
+ */
+void USART_ConfigClockStructInit(USART_ClockConfig_T *clockConfig)
+{
+    clockConfig->clock     = USART_CLKEN_DISABLE;
+    clockConfig->phase     = USART_CLKPHA_1EDGE;
+    clockConfig->polarity  = USART_CLKPOL_LOW;
+    clockConfig->lastBit   = USART_LBCP_DISABLE;
+}
+
+/*!
+ * @brief     Enables the specified USART peripheral
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_Enable(USART_T *usart)
+{
+    usart->CTRL1_B.UEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the specified USART peripheral
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_Disable(USART_T *usart)
+{
+    usart->CTRL1_B.UEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Sets the system clock divider number
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     div:   specifies the divider number
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_ConfigPrescaler(USART_T *usart, uint8_t div)
+{
+    usart->GTPSC_B.PSC = div;
+}
+
+/*!
+ * @brief     Enables the USART's 8x oversampling mode
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableOverSampling8(USART_T *usart)
+{
+    usart->CTRL1_B.OSMCFG = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the USART's 8x oversampling mode
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableOverSampling8(USART_T *usart)
+{
+    usart->CTRL1_B.OSMCFG = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the USART's sample method
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableOverSampling(USART_T *usart)
+{
+    usart->CTRL3_B.SAMCFG = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the USART's sample method
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableOverSampling(USART_T *usart)
+{
+    usart->CTRL3_B.SAMCFG = BIT_RESET;
+}
+
+/*!
+ * @brief     Transmits single data
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     data:  the data to transmit
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_TxData(USART_T *usart, uint16_t data)
+{
+    usart->DATA_B.DATA = data;
+}
+
+/*!
+ * @brief     Returns the most recent received data
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+uint16_t USART_RxData(USART_T *usart)
+{
+    return (uint16_t)(usart->DATA_B.DATA);
+}
+
+/*!
+ * @brief     Configures the address of the USART node
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @param     address: Indicates the address of the USART node
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_Address(USART_T *usart, uint8_t address)
+{
+    usart->CTRL2_B.ADDR = address;
+}
+
+/*!
+ * @brief     Enable USART Receiver in mute mode
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableMuteMode(USART_T *usart)
+{
+    usart->CTRL1_B.RXMUTEEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable USART Receiver in active mode
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableMuteMode(USART_T *usart)
+{
+    usart->CTRL1_B.RXMUTEEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Selects the USART WakeUp method.
+ *
+ * @param     usart:  Select the USART or the UART peripheral
+ *
+ * @param     wakeup: Specifies the selected USART auto baud rate method
+ *                    This parameter can be one of the following values:
+ *                    @arg USART_WAKEUP_IDLE_LINE    : WakeUp by an idle line detection
+ *                    @arg USART_WAKEUP_ADDRESS_MARK : WakeUp by an address mark
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_ConfigWakeUp(USART_T *usart, USART_WAKEUP_T wakeup)
+{
+    usart->CTRL1_B.WUPMCFG = wakeup;
+}
+
+/*!
+ * @brief     Sets the USART LIN Break detection length
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @param     length:  Specifies the LIN break detection length
+ *                     This parameter can be one of the following values:
+ *                     @arg USART_LBDL_10B : 10-bit break detection
+ *                     @arg USART_LBDL_11B : 11-bit break detection
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_ConfigLINBreakDetectLength(USART_T *usart, USART_LBDL_T length)
+{
+    usart->CTRL2_B.LBDLCFG = length;
+}
+
+/*!
+ * @brief     Enables the USART LIN MODE
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableLIN(USART_T *usart)
+{
+    usart->CTRL2_B.LINMEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the USART LIN MODE
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableLIN(USART_T *usart)
+{
+    usart->CTRL2_B.LINMEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Transmits break characters
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_TxBreak(USART_T *usart)
+{
+    usart->CTRL1_B.TXBF = BIT_SET;
+}
+
+/*!
+ * @brief     Enables USART Half Duplex communication
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableHalfDuplex(USART_T *usart)
+{
+    usart->CTRL3_B.HDEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable USART Half Duplex communication
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableHalfDuplex(USART_T *usart)
+{
+    usart->CTRL3_B.HDEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Sets the specified USART guard time
+ *
+ * @param     usart:     Select the USART or the UART peripheral
+ *
+ * @param     guardTime: Specifies the guard time
+ *
+ * @retval    None
+ *
+ * @note      The specified USART guard time is not available for UART4 and UART5
+ */
+void USART_ConfigGuardTime(USART_T *usart, uint8_t guardTime)
+{
+    usart->GTPSC_B.GRDT = guardTime;
+}
+
+/*!
+ * @brief     Enables the USART Smart Card mode
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The Smart Card mode is not available for UART4 and UART5
+ */
+void USART_EnableSmartCard(USART_T *usart)
+{
+    usart->CTRL3_B.SCEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the USART Smart Card mode
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The Smart Card mode is not available for UART4 and UART5
+ */
+void USART_DisableSmartCard(USART_T *usart)
+{
+    usart->CTRL3_B.SCEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables NACK transmission
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The Smart Card mode is not available for UART4 and UART5
+ */
+void USART_EnableSmartCardNACK(USART_T *usart)
+{
+    usart->CTRL3_B.SCNACKEN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable NACK transmission
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The Smart Card mode is not available for UART4 and UART5
+ */
+void USART_DisableSmartCardNACK(USART_T *usart)
+{
+    usart->CTRL3_B.SCNACKEN = BIT_RESET;
+}
+
+/*!
+ * @brief     Configures the USART's IrDA interface
+ *
+ * @param     usart:    Select the USART or the UART peripheral
+ *
+ * @param     IrDAMode: Specifies the IrDA mode
+ *                      This parameter can be one of the following values:
+ *                      @arg USART_IRDALP_NORMAL    : Normal
+ *                      @arg USART_IRDALP_LOWPOWER  : Low-Power
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_ConfigIrDA(USART_T *usart, USART_IRDALP_T IrDAMode)
+{
+    usart->CTRL3_B.IRLPEN = IrDAMode;
+}
+
+/*!
+ * @brief     Enables the USART's IrDA interface
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableIrDA(USART_T *usart)
+{
+    usart->CTRL3_B.IREN = BIT_SET;
+}
+
+/*!
+ * @brief     Disable the USART's IrDA interface
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableIrDA(USART_T *usart)
+{
+    usart->CTRL3_B.IREN = BIT_RESET;
+}
+
+/*!
+ * @brief     Enables the USART DMA interface
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @param     dmaReq:  Specifies the DMA request
+ *                     This parameter can be one of the following values:
+ *                     @arg USART_DMA_TX    : USART DMA receive request
+ *                     @arg USART_DMA_RX    : USART DMA transmit request
+ *                     @arg USART_DMA_TX_RX : USART DMA transmit/receive request
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableDMA(USART_T *usart, USART_DMA_T dmaReq)
+{
+    usart->CTRL3_B.DMARXEN = dmaReq & 0x01;
+    usart->CTRL3_B.DMATXEN = dmaReq >> 1;
+}
+
+/*!
+ * @brief     Disable the USART DMA interface
+ *
+ * @param     usart:   Select the USART or the UART peripheral
+ *
+ * @param     dmaReq:  Specifies the DMA request
+ *                     This parameter can be one of the following values:
+ *                     @arg USART_DMA_TX    : USART DMA receive request
+ *                     @arg USART_DMA_RX    : USART DMA transmit request
+ *                     @arg USART_DMA_TX_RX : USART DMA transmit/receive request
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableDMA(USART_T *usart, USART_DMA_T dmaReq)
+{
+    usart->CTRL3_B.DMARXEN = !(dmaReq & 0x01);
+    usart->CTRL3_B.DMATXEN = !(dmaReq >> 1);
+}
+
+/*!
+ * @brief     Enable the specified USART interrupts
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     interrupt: Specifies the USART interrupts sources
+ *                       The parameter can be one of following values:
+ *                       @arg USART_INT_PE      : Parity error interrupt
+ *                       @arg USART_INT_TXBE    : Tansmit data buffer empty interrupt
+ *                       @arg USART_INT_TXC     : Transmission complete interrupt
+ *                       @arg USART_INT_RXBNE   : Receive data buffer not empty interrupt
+ *                       @arg USART_INT_IDLE    : Idle line detection interrupt
+ *                       @arg USART_INT_LBD     : LIN break detection interrupt
+ *                       @arg USART_INT_CTS     : CTS change interrupt
+ *                       @arg USART_INT_ERR     : Error interrupt(Frame error, noise error, overrun error)
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_EnableInterrupt(USART_T *usart, USART_INT_T interrupt)
+{
+    uint32_t temp;
+
+    temp = (uint32_t)(interrupt & 0xffff);
+
+    if (interrupt & 0x10000)
+    {
+        usart->CTRL1 |= temp;
+    }
+
+    if (interrupt & 0x20000)
+    {
+        usart->CTRL2 |= temp;
+    }
+
+    if (interrupt & 0x40000)
+    {
+        usart->CTRL3 |= temp;
+    }
+}
+
+/*!
+ * @brief     Disables the specified USART interrupts
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     interrupt: Specifies the USART interrupts sources
+ *                       The parameter can be one of following values:
+ *                       @arg USART_INT_PE      : Parity error interrupt
+ *                       @arg USART_INT_TXBE    : Tansmit data buffer empty interrupt
+ *                       @arg USART_INT_TXC     : Transmission complete interrupt
+ *                       @arg USART_INT_RXBNE   : Receive data buffer not empty interrupt
+ *                       @arg USART_INT_IDLE    : Idle line detection interrupt
+ *                       @arg USART_INT_LBD     : LIN break detection interrupt
+ *                       @arg USART_INT_CTS     : CTS change interrupt
+ *                       @arg USART_INT_ERR     : Error interrupt(Frame error, noise error, overrun error)
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_DisableInterrupt(USART_T *usart, USART_INT_T interrupt)
+{
+    uint32_t temp;
+
+    temp = (uint32_t)~(interrupt & 0xffff);
+
+    if (interrupt & 0x10000)
+    {
+        usart->CTRL1 &= temp;
+    }
+
+    if (interrupt & 0x20000)
+    {
+        usart->CTRL2 &= temp;
+    }
+
+    if (interrupt & 0x40000)
+    {
+        usart->CTRL3 &= temp;
+    }
+}
+
+/*!
+ * @brief     Read the specified USART flag
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     flag: Specifies the flag to check
+ *                  The parameter can be one of following values:
+ *                  @arg USART_FLAG_CTS     : CTS Change flag (not available for UART4 and UART5)
+ *                  @arg USART_FLAG_LBD     : LIN Break detection flag
+ *                  @arg USART_FLAG_TXBE    : Transmit data buffer empty flag
+ *                  @arg USART_FLAG_TXC     : Transmission Complete flag
+ *                  @arg USART_FLAG_RXBNE   : Receive data buffer not empty flag
+ *                  @arg USART_FLAG_IDLE    : Idle Line detection flag
+ *                  @arg USART_FLAG_OVRE    : OverRun Error flag
+ *                  @arg USART_FLAG_NE      : Noise Error flag
+ *                  @arg USART_FLAG_FE      : Framing Error flag
+ *                  @arg USART_FLAG_PE      : Parity Error flag
+ *
+ * @retval    The new state of flag (SET or RESET)
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+uint8_t USART_ReadStatusFlag(USART_T *usart, USART_FLAG_T flag)
+{
+    return (usart->STS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief     Clears the USARTx's pending flags
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     flag: Specifies the flag to clear
+ *                  The parameter can be one of following values:
+ *                  @arg USART_FLAG_CTS     : CTS Change flag (not available for UART4 and UART5)
+ *                  @arg USART_FLAG_LBD     : LIN Break detection flag
+ *                  @arg USART_FLAG_TXC     : Transmission Complete flag
+ *                  @arg USART_FLAG_RXBNE   : Receive data buffer not empty flag
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_ClearStatusFlag(USART_T *usart, USART_FLAG_T flag)
+{
+    usart->STS &= (uint32_t)~flag;
+}
+
+/*!
+ * @brief     Read the specified USART interrupt flag
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     flag:  Specifies the USART interrupt source to check
+ *                        The parameter can be one of following values:
+ *                        @arg USART_INT_TXBE    : Tansmit data buffer empty interrupt
+ *                        @arg USART_INT_TXC     : Transmission complete interrupt
+ *                        @arg USART_INT_RXBNE   : Receive data buffer not empty interrupt
+ *                        @arg USART_INT_IDLE    : Idle line detection interrupt
+ *                        @arg USART_INT_LBD     : LIN break detection interrupt
+ *                        @arg USART_INT_CTS     : CTS change interrupt
+ *                        @arg USART_INT_OVRE_RX : OverRun Error interruptpt if the RXBNFLG bit is set
+ *                        @arg USART_INT_OVRE_ER : OverRun Error interruptpt if the EIE bit is set
+ *                        @arg USART_INT_NE      : Noise Error interrupt
+ *                        @arg USART_INT_FE      : Framing Error interrupt
+ *                        @arg USART_INT_PE      : Parity error interrupt
+ *
+ * @retval    The new state of flag (SET or RESET)
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+uint8_t USART_ReadIntFlag(USART_T *usart, USART_INT_T flag)
+{
+    uint32_t itFlag, srFlag;
+
+    if (flag & 0x10000)
+    {
+        itFlag = usart->CTRL1 & flag & 0xffff;
+    }
+    else if (flag & 0x20000)
+    {
+        itFlag = usart->CTRL2 & flag & 0xffff;
+    }
+    else
+    {
+        itFlag = usart->CTRL3 & flag & 0xffff;
+    }
+
+    srFlag = flag >> 24;
+    srFlag = (uint32_t)(1 << srFlag);
+    srFlag = usart->STS & srFlag;
+
+    if (srFlag && itFlag)
+    {
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+ * @brief     Clears the USART interrupt pending bits
+ *
+ * @param     usart: Select the USART or the UART peripheral
+ *
+ * @param     flag: Specifies the interrupt pending bit to clear
+ *                  The parameter can be one of following values:
+ *                  @arg USART_INT_RXBNE : Receive data buffer not empty interrupt
+ *                  @arg USART_INT_TXC   : Transmission complete interrupt
+ *                  @arg USART_INT_LBD   : LIN break detection interrupt
+ *                  @arg USART_INT_CTS   : CTS change interrupt
+ *
+ * @retval    None
+ *
+ * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
+ */
+void USART_ClearIntFlag(USART_T *usart, USART_INT_T flag)
+{
+    uint32_t srFlag;
+
+    srFlag = flag >> 24;
+    srFlag = (uint32_t)(1 << srFlag);
+
+    usart->STS &= (uint32_t)~srFlag;
+}
+
+/**@} end of group USART_Functions */
+/**@} end of group USART_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 153 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_wwdt.c

@@ -0,0 +1,153 @@
+/*!
+ * @file        apm32f4xx_wwdt.c
+ *
+ * @brief       This file contains all the functions for the WWDT peripheral
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_wwdt.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_StdPeriphDriver
+  @{
+*/
+
+/** @defgroup WWDT_Driver
+  * @brief WWDT driver modules
+  @{
+*/
+
+/** @defgroup WWDT_Functions
+  @{
+*/
+
+/*!
+ * @brief     Reset the WWDT peripheral registers to the default value.
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void WWDT_Reset(void)
+{
+    RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_WWDT);
+    RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_WWDT);
+}
+
+/*!
+ * @brief     Config the WWDT Timer Base Prescaler Factor.
+ *
+ * @param     timebase: Specifies WWDT Prescaler
+ *                      The parameter can be one of following values:
+ *                      @arg WWDT_TIME_BASE_1 : WWDT counter clock = (PCLK1/4096)/1
+ *                      @arg WWDT_TIME_BASE_2 : WWDT counter clock = (PCLK1/4096)/2
+ *                      @arg WWDT_TIME_BASE_4 : WWDT counter clock = (PCLK1/4096)/4
+ *                      @arg WWDT_TIME_BASE_8 : WWDT counter clock = (PCLK1/4096)/8
+ *
+ * @retval    None
+ */
+void WWDT_ConfigTimebase(WWDT_TIME_BASE_T timeBase)
+{
+    WWDT->CFG_B.TBPSC = timeBase;
+}
+
+/*!
+ * @brief     Config the WWDT Window data
+ *
+ * @param     windowdata: window data which compare with the downcounter
+ *
+ * @retval    None
+ *
+ * @note      The windowdata must be lower than 0x80
+ */
+void WWDT_ConfigWindowData(uint8_t windowData)
+{
+    WWDT->CFG_B.WIN = windowData;
+}
+
+/*!
+ * @brief     Config the WWDT counter value
+ *
+ * @param     counter: Specifies the watchdog counter value.
+ *
+ * @retval    None
+ *
+ * @note      The counter must be from 0x40 to 0x7F.
+ */
+void WWDT_ConfigCounter(uint8_t counter)
+{
+    WWDT->CTRL_B.CNT = counter;
+}
+
+/*!
+ * @brief     Enable the WWDT Early Wakeup interrupt
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void WWDT_EnableEWI(void)
+{
+    WWDT->CFG_B.EWIEN = SET;
+}
+
+/*!
+ * @brief     Enable WWDT and set the counter value
+ *
+ * @param     counter: the window watchdog counter value
+ *
+ * @retval    None
+ *
+ * @note      The counter between 0x40 and 0x7F
+ */
+void WWDT_Enable(uint8_t counter)
+{
+    WWDT->CTRL = counter | 0x00000080;
+}
+
+/*!
+ * @brief     Checks whether the Early Wakeup interrupt flag is set or not.
+ *
+ * @param     None
+ *
+ * @retval    SET or RESET
+ */
+uint8_t WWDT_ReadFlag(void)
+{
+    return (WWDT->STS_B.EWIFLG);
+}
+
+/*!
+ * @brief     Clear the Early Wakeup interrupt flag
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void WWDT_ClearFlag(void)
+{
+    WWDT->STS_B.EWIFLG = RESET;
+
+}
+
+/**@} end of group WWDT_Functions */
+/**@} end of group WWDT_Driver */
+/**@} end of group APM32F4xx_StdPeriphDriver */

+ 176 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/LICENSE.txt

@@ -0,0 +1,176 @@
+ Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS

+ 888 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/cmsis_armcc.h

@@ -0,0 +1,888 @@
+/**************************************************************************//**
+ * @file     cmsis_armcc.h
+ * @brief    CMSIS compiler ARMCC (Arm Compiler 5) header file
+ * @version  V5.3.2
+ * @date     27. May 2021
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+  #error "Please use Arm Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* CMSIS compiler control architecture macros */
+#if ((defined (__TARGET_ARCH_6_M  ) && (__TARGET_ARCH_6_M   == 1)) || \
+     (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M  == 1))   )
+  #define __ARM_ARCH_6M__           1
+#endif
+
+#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M  == 1))
+  #define __ARM_ARCH_7M__           1
+#endif
+
+#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
+  #define __ARM_ARCH_7EM__          1
+#endif
+
+  /* __ARM_ARCH_8M_BASE__  not applicable */
+  /* __ARM_ARCH_8M_MAIN__  not applicable */
+  /* __ARM_ARCH_8_1M_MAIN__  not applicable */
+
+/* CMSIS compiler control DSP macros */
+#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     )
+  #define __ARM_FEATURE_DSP         1
+#endif
+
+/* CMSIS compiler specific defines */
+#ifndef   __ASM
+  #define __ASM                                  __asm
+#endif
+#ifndef   __INLINE
+  #define __INLINE                               __inline
+#endif
+#ifndef   __STATIC_INLINE
+  #define __STATIC_INLINE                        static __inline
+#endif
+#ifndef   __STATIC_FORCEINLINE
+  #define __STATIC_FORCEINLINE                   static __forceinline
+#endif
+#ifndef   __NO_RETURN
+  #define __NO_RETURN                            __declspec(noreturn)
+#endif
+#ifndef   __USED
+  #define __USED                                 __attribute__((used))
+#endif
+#ifndef   __WEAK
+  #define __WEAK                                 __attribute__((weak))
+#endif
+#ifndef   __PACKED
+  #define __PACKED                               __attribute__((packed))
+#endif
+#ifndef   __PACKED_STRUCT
+  #define __PACKED_STRUCT                        __packed struct
+#endif
+#ifndef   __PACKED_UNION
+  #define __PACKED_UNION                         __packed union
+#endif
+#ifndef   __UNALIGNED_UINT32        /* deprecated */
+  #define __UNALIGNED_UINT32(x)                  (*((__packed uint32_t *)(x)))
+#endif
+#ifndef   __UNALIGNED_UINT16_WRITE
+  #define __UNALIGNED_UINT16_WRITE(addr, val)    ((*((__packed uint16_t *)(addr))) = (val))
+#endif
+#ifndef   __UNALIGNED_UINT16_READ
+  #define __UNALIGNED_UINT16_READ(addr)          (*((const __packed uint16_t *)(addr)))
+#endif
+#ifndef   __UNALIGNED_UINT32_WRITE
+  #define __UNALIGNED_UINT32_WRITE(addr, val)    ((*((__packed uint32_t *)(addr))) = (val))
+#endif
+#ifndef   __UNALIGNED_UINT32_READ
+  #define __UNALIGNED_UINT32_READ(addr)          (*((const __packed uint32_t *)(addr)))
+#endif
+#ifndef   __ALIGNED
+  #define __ALIGNED(x)                           __attribute__((aligned(x)))
+#endif
+#ifndef   __RESTRICT
+  #define __RESTRICT                             __restrict
+#endif
+#ifndef   __COMPILER_BARRIER
+  #define __COMPILER_BARRIER()                   __memory_changed()
+#endif
+
+/* #########################  Startup and Lowlevel Init  ######################## */
+
+#ifndef __PROGRAM_START
+#define __PROGRAM_START           __main
+#endif
+
+#ifndef __INITIAL_SP
+#define __INITIAL_SP              Image$$ARM_LIB_STACK$$ZI$$Limit
+#endif
+
+#ifndef __STACK_LIMIT
+#define __STACK_LIMIT             Image$$ARM_LIB_STACK$$ZI$$Base
+#endif
+
+#ifndef __VECTOR_TABLE
+#define __VECTOR_TABLE            __Vectors
+#endif
+
+#ifndef __VECTOR_TABLE_ATTRIBUTE
+#define __VECTOR_TABLE_ATTRIBUTE  __attribute__((used, section("RESET")))
+#endif
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/**
+  \brief   Wait For Interrupt
+  \details 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
+  \details 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
+  \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details 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
+  \details 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
+  \details 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)
+  \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
+  \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 (16 bit)
+  \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+#endif
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    op1  Value to rotate
+  \param [in]    op2  Number of Bits to rotate
+  \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+/**
+  \brief   Breakpoint
+  \details 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)
+
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \
+     (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     )
+  #define __RBIT                          __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+  uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
+
+  result = value;                      /* r will be reversed bits of v; first get LSB of v */
+  for (value >>= 1U; value != 0U; value >>= 1U)
+  {
+    result <<= 1U;
+    result |= value & 1U;
+    s--;
+  }
+  result <<= s;                        /* shift when v's highest bits are zero */
+  return result;
+}
+#endif
+
+
+/**
+  \brief   Count leading zeros
+  \details 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
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \
+     (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     )
+
+/**
+  \brief   LDR Exclusive (8 bit)
+  \details Executes a exclusive LDR instruction for 8 bit value.
+  \param [in]    ptr  Pointer to data
+  \return             value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXB(ptr)                                                        ((uint8_t ) __ldrex(ptr))
+#else
+  #define __LDREXB(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   LDR Exclusive (16 bit)
+  \details Executes a exclusive LDR instruction for 16 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXH(ptr)                                                        ((uint16_t) __ldrex(ptr))
+#else
+  #define __LDREXH(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   LDR Exclusive (32 bit)
+  \details Executes a exclusive LDR instruction for 32 bit values.
+  \param [in]    ptr  Pointer to data
+  \return        value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __LDREXW(ptr)                                                        ((uint32_t ) __ldrex(ptr))
+#else
+  #define __LDREXW(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr))  _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (8 bit)
+  \details 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
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXB(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXB(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (16 bit)
+  \details 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
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXH(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXH(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   STR Exclusive (32 bit)
+  \details 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
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+  #define __STREXW(value, ptr)                                                 __strex(value, ptr)
+#else
+  #define __STREXW(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
+#endif
+
+
+/**
+  \brief   Remove the exclusive lock
+  \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX                           __clrex
+
+
+/**
+  \brief   Signed Saturate
+  \details 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
+  \details 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   Rotate Right with Extend (32 bit)
+  \details 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)
+  \details 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)
+  \details 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)
+  \details 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)
+  \details 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)
+  \details 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)
+  \details 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)
+
+#else  /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \
+           (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */
+
+/**
+  \brief   Signed Saturate
+  \details Saturates a signed value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (1..32)
+  \return             Saturated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
+{
+  if ((sat >= 1U) && (sat <= 32U))
+  {
+    const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
+    const int32_t min = -1 - max ;
+    if (val > max)
+    {
+      return max;
+    }
+    else if (val < min)
+    {
+      return min;
+    }
+  }
+  return val;
+}
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
+{
+  if (sat <= 31U)
+  {
+    const uint32_t max = ((1U << sat) - 1U);
+    if (val > (int32_t)max)
+    {
+      return max;
+    }
+    else if (val < 0)
+    {
+      return 0U;
+    }
+  }
+  return (uint32_t)val;
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \
+           (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+/**
+  \brief   Enable IRQ Interrupts
+  \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
+           Can only be executed in Privileged modes.
+ */
+/* intrinsic void __enable_irq();     */
+
+
+/**
+  \brief   Disable IRQ Interrupts
+  \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
+           Can only be executed in Privileged modes.
+ */
+/* intrinsic void __disable_irq();    */
+
+/**
+  \brief   Get Control Register
+  \details 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
+  \details 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;
+  __ISB();
+}
+
+
+/**
+  \brief   Get IPSR Register
+  \details 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
+  \details 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
+  \details 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
+  \details 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
+  \details 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
+  \details 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
+  \details 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
+  \details 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
+  \details 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 ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \
+     (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     )
+
+/**
+  \brief   Enable FIQ
+  \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK.
+           Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/**
+  \brief   Disable FIQ
+  \details Disables FIQ interrupts by setting special-purpose register FAULTMASK.
+           Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/**
+  \brief   Get Base Priority
+  \details 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
+  \details 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 & 0xFFU);
+}
+
+
+/**
+  \brief   Set Base Priority with condition
+  \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+           or the new value increases the BASEPRI priority level.
+  \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+  register uint32_t __regBasePriMax      __ASM("basepri_max");
+  __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+  \brief   Get Fault Mask
+  \details 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
+  \details 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)1U);
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__  == 1)) || \
+           (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */
+
+
+/**
+  \brief   Get FPSCR
+  \details 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 ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+     (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0U);
+#endif
+}
+
+
+/**
+  \brief   Set FPSCR
+  \details 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 ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+     (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#else
+  (void)fpscr;
+#endif
+}
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     )
+
+#define __SADD8                           __sadd8
+#define __QADD8                           __qadd8
+#define __SHADD8                          __shadd8
+#define __UADD8                           __uadd8
+#define __UQADD8                          __uqadd8
+#define __UHADD8                          __uhadd8
+#define __SSUB8                           __ssub8
+#define __QSUB8                           __qsub8
+#define __SHSUB8                          __shsub8
+#define __USUB8                           __usub8
+#define __UQSUB8                          __uqsub8
+#define __UHSUB8                          __uhsub8
+#define __SADD16                          __sadd16
+#define __QADD16                          __qadd16
+#define __SHADD16                         __shadd16
+#define __UADD16                          __uadd16
+#define __UQADD16                         __uqadd16
+#define __UHADD16                         __uhadd16
+#define __SSUB16                          __ssub16
+#define __QSUB16                          __qsub16
+#define __SHSUB16                         __shsub16
+#define __USUB16                          __usub16
+#define __UQSUB16                         __uqsub16
+#define __UHSUB16                         __uhsub16
+#define __SASX                            __sasx
+#define __QASX                            __qasx
+#define __SHASX                           __shasx
+#define __UASX                            __uasx
+#define __UQASX                           __uqasx
+#define __UHASX                           __uhasx
+#define __SSAX                            __ssax
+#define __QSAX                            __qsax
+#define __SHSAX                           __shsax
+#define __USAX                            __usax
+#define __UQSAX                           __uqsax
+#define __UHSAX                           __uhsax
+#define __USAD8                           __usad8
+#define __USADA8                          __usada8
+#define __SSAT16                          __ssat16
+#define __USAT16                          __usat16
+#define __UXTB16                          __uxtb16
+#define __UXTAB16                         __uxtab16
+#define __SXTB16                          __sxtb16
+#define __SXTAB16                         __sxtab16
+#define __SMUAD                           __smuad
+#define __SMUADX                          __smuadx
+#define __SMLAD                           __smlad
+#define __SMLADX                          __smladx
+#define __SMLALD                          __smlald
+#define __SMLALDX                         __smlaldx
+#define __SMUSD                           __smusd
+#define __SMUSDX                          __smusdx
+#define __SMLSD                           __smlsd
+#define __SMLSDX                          __smlsdx
+#define __SMLSLD                          __smlsld
+#define __SMLSLDX                         __smlsldx
+#define __SEL                             __sel
+#define __QADD                            __qadd
+#define __QSUB                            __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
+                                           ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
+
+#define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
+                                           ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
+
+#define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+                                                      ((int64_t)(ARG3) << 32U)     ) >> 32U))
+
+#define __SXTB16_RORn(ARG1, ARG2)        __SXTB16(__ROR(ARG1, ARG2))
+
+#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3))
+
+#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1))     ) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_H */

+ 283 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/cmsis_compiler.h

@@ -0,0 +1,283 @@
+/**************************************************************************//**
+ * @file     cmsis_compiler.h
+ * @brief    CMSIS compiler generic header file
+ * @version  V5.1.0
+ * @date     09. October 2018
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMSIS_COMPILER_H
+#define __CMSIS_COMPILER_H
+
+#include <stdint.h>
+
+/*
+ * Arm Compiler 4/5
+ */
+#if   defined ( __CC_ARM )
+  #include "cmsis_armcc.h"
+
+
+/*
+ * Arm Compiler 6.6 LTM (armclang)
+ */
+#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
+  #include "cmsis_armclang_ltm.h"
+
+  /*
+ * Arm Compiler above 6.10.1 (armclang)
+ */
+#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
+  #include "cmsis_armclang.h"
+
+
+/*
+ * GNU Compiler
+ */
+#elif defined ( __GNUC__ )
+  #include "cmsis_gcc.h"
+
+
+/*
+ * IAR Compiler
+ */
+#elif defined ( __ICCARM__ )
+  #include <cmsis_iccarm.h>
+
+
+/*
+ * TI Arm Compiler
+ */
+#elif defined ( __TI_ARM__ )
+  #include <cmsis_ccs.h>
+
+  #ifndef   __ASM
+    #define __ASM                                  __asm
+  #endif
+  #ifndef   __INLINE
+    #define __INLINE                               inline
+  #endif
+  #ifndef   __STATIC_INLINE
+    #define __STATIC_INLINE                        static inline
+  #endif
+  #ifndef   __STATIC_FORCEINLINE
+    #define __STATIC_FORCEINLINE                   __STATIC_INLINE
+  #endif
+  #ifndef   __NO_RETURN
+    #define __NO_RETURN                            __attribute__((noreturn))
+  #endif
+  #ifndef   __USED
+    #define __USED                                 __attribute__((used))
+  #endif
+  #ifndef   __WEAK
+    #define __WEAK                                 __attribute__((weak))
+  #endif
+  #ifndef   __PACKED
+    #define __PACKED                               __attribute__((packed))
+  #endif
+  #ifndef   __PACKED_STRUCT
+    #define __PACKED_STRUCT                        struct __attribute__((packed))
+  #endif
+  #ifndef   __PACKED_UNION
+    #define __PACKED_UNION                         union __attribute__((packed))
+  #endif
+  #ifndef   __UNALIGNED_UINT32        /* deprecated */
+    struct __attribute__((packed)) T_UINT32 { uint32_t v; };
+    #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
+  #endif
+  #ifndef   __UNALIGNED_UINT16_WRITE
+    __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+    #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
+  #endif
+  #ifndef   __UNALIGNED_UINT16_READ
+    __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+    #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+  #endif
+  #ifndef   __UNALIGNED_UINT32_WRITE
+    __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+    #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+  #endif
+  #ifndef   __UNALIGNED_UINT32_READ
+    __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+    #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+  #endif
+  #ifndef   __ALIGNED
+    #define __ALIGNED(x)                           __attribute__((aligned(x)))
+  #endif
+  #ifndef   __RESTRICT
+    #define __RESTRICT                             __restrict
+  #endif
+  #ifndef   __COMPILER_BARRIER
+    #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
+    #define __COMPILER_BARRIER()                   (void)0
+  #endif
+
+
+/*
+ * TASKING Compiler
+ */
+#elif defined ( __TASKING__ )
+  /*
+   * 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.
+   */
+
+  #ifndef   __ASM
+    #define __ASM                                  __asm
+  #endif
+  #ifndef   __INLINE
+    #define __INLINE                               inline
+  #endif
+  #ifndef   __STATIC_INLINE
+    #define __STATIC_INLINE                        static inline
+  #endif
+  #ifndef   __STATIC_FORCEINLINE
+    #define __STATIC_FORCEINLINE                   __STATIC_INLINE
+  #endif
+  #ifndef   __NO_RETURN
+    #define __NO_RETURN                            __attribute__((noreturn))
+  #endif
+  #ifndef   __USED
+    #define __USED                                 __attribute__((used))
+  #endif
+  #ifndef   __WEAK
+    #define __WEAK                                 __attribute__((weak))
+  #endif
+  #ifndef   __PACKED
+    #define __PACKED                               __packed__
+  #endif
+  #ifndef   __PACKED_STRUCT
+    #define __PACKED_STRUCT                        struct __packed__
+  #endif
+  #ifndef   __PACKED_UNION
+    #define __PACKED_UNION                         union __packed__
+  #endif
+  #ifndef   __UNALIGNED_UINT32        /* deprecated */
+    struct __packed__ T_UINT32 { uint32_t v; };
+    #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
+  #endif
+  #ifndef   __UNALIGNED_UINT16_WRITE
+    __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+    #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+  #endif
+  #ifndef   __UNALIGNED_UINT16_READ
+    __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+    #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+  #endif
+  #ifndef   __UNALIGNED_UINT32_WRITE
+    __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+    #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+  #endif
+  #ifndef   __UNALIGNED_UINT32_READ
+    __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+    #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+  #endif
+  #ifndef   __ALIGNED
+    #define __ALIGNED(x)              __align(x)
+  #endif
+  #ifndef   __RESTRICT
+    #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
+    #define __RESTRICT
+  #endif
+  #ifndef   __COMPILER_BARRIER
+    #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
+    #define __COMPILER_BARRIER()                   (void)0
+  #endif
+
+
+/*
+ * COSMIC Compiler
+ */
+#elif defined ( __CSMC__ )
+   #include <cmsis_csm.h>
+
+ #ifndef   __ASM
+    #define __ASM                                  _asm
+  #endif
+  #ifndef   __INLINE
+    #define __INLINE                               inline
+  #endif
+  #ifndef   __STATIC_INLINE
+    #define __STATIC_INLINE                        static inline
+  #endif
+  #ifndef   __STATIC_FORCEINLINE
+    #define __STATIC_FORCEINLINE                   __STATIC_INLINE
+  #endif
+  #ifndef   __NO_RETURN
+    // NO RETURN is automatically detected hence no warning here
+    #define __NO_RETURN
+  #endif
+  #ifndef   __USED
+    #warning No compiler specific solution for __USED. __USED is ignored.
+    #define __USED
+  #endif
+  #ifndef   __WEAK
+    #define __WEAK                                 __weak
+  #endif
+  #ifndef   __PACKED
+    #define __PACKED                               @packed
+  #endif
+  #ifndef   __PACKED_STRUCT
+    #define __PACKED_STRUCT                        @packed struct
+  #endif
+  #ifndef   __PACKED_UNION
+    #define __PACKED_UNION                         @packed union
+  #endif
+  #ifndef   __UNALIGNED_UINT32        /* deprecated */
+    @packed struct T_UINT32 { uint32_t v; };
+    #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
+  #endif
+  #ifndef   __UNALIGNED_UINT16_WRITE
+    __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+    #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+  #endif
+  #ifndef   __UNALIGNED_UINT16_READ
+    __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+    #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+  #endif
+  #ifndef   __UNALIGNED_UINT32_WRITE
+    __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+    #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+  #endif
+  #ifndef   __UNALIGNED_UINT32_READ
+    __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+    #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+  #endif
+  #ifndef   __ALIGNED
+    #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
+    #define __ALIGNED(x)
+  #endif
+  #ifndef   __RESTRICT
+    #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
+    #define __RESTRICT
+  #endif
+  #ifndef   __COMPILER_BARRIER
+    #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
+    #define __COMPILER_BARRIER()                   (void)0
+  #endif
+
+
+#else
+  #error Unknown compiler.
+#endif
+
+
+#endif /* __CMSIS_COMPILER_H */
+

+ 1858 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cm4.h

@@ -0,0 +1,1858 @@
+/**************************************************************************//**
+ * @file     core_cm4.h
+ * @brief    CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version  V4.10
+ * @date     18. March 2015
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 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_CM4_H_GENERIC
+#define __CORE_CM4_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_M4
+  @{
+ */
+
+/*  CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN  (0x04)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM4_CMSIS_VERSION_SUB   (0x00)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM4_CMSIS_VERSION       ((__CM4_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM4_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x04)                                   /*!< 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.
+    For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __CSMC__ )      /* Cosmic */
+  #if ( __CSMC__ & 0x400)       // FPU present for parser
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+#include <core_cmSimd.h>                 /* Compiler specific SIMD Intrinsics               */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM4_REV
+    #define __CM4_REV               0x0000
+    #warning "__CM4_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4
+    #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_M4 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU 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
+  {
+    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                           */
+    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;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31                                             /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30                                             /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29                                             /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28                                             /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27                                             /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos                        16                                             /*!< APSR: GE Position */
+#define APSR_GE_Msk                        (0xFUL << APSR_GE_Pos)                         /*!< APSR: GE Mask */
+
+
+/** \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;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0                                             /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    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                           */
+    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;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31                                             /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30                                             /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29                                             /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28                                             /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27                                             /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25                                             /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24                                             /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos                        16                                             /*!< xPSR: GE Position */
+#define xPSR_GE_Msk                        (0xFUL << xPSR_GE_Pos)                         /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos                        0                                             /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/** \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;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos                    2                                             /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk                   (1UL << CONTROL_FPCA_Pos)                      /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos                   1                                             /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0                                             /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} 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[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0                                          /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} 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                  */
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+  __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                        */
+  __IO uint8_t  SHP[12];                 /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+  __IO uint32_t CFSR;                    /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register                    */
+  __IO uint32_t HFSR;                    /*!< Offset: 0x02C (R/W)  HardFault Status Register                             */
+  __IO uint32_t DFSR;                    /*!< Offset: 0x030 (R/W)  Debug Fault Status Register                           */
+  __IO uint32_t MMFAR;                   /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register                      */
+  __IO uint32_t BFAR;                    /*!< Offset: 0x038 (R/W)  BusFault Address Register                             */
+  __IO uint32_t AFSR;                    /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register                       */
+  __I  uint32_t PFR[2];                  /*!< Offset: 0x040 (R/ )  Processor Feature Register                            */
+  __I  uint32_t DFR;                     /*!< Offset: 0x048 (R/ )  Debug Feature Register                                */
+  __I  uint32_t ADR;                     /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register                            */
+  __I  uint32_t MMFR[4];                 /*!< Offset: 0x050 (R/ )  Memory Model Feature Register                         */
+  __I  uint32_t ISAR[5];                 /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register                   */
+       uint32_t RESERVED0[5];
+  __IO uint32_t CPACR;                   /*!< Offset: 0x088 (R/W)  Coprocessor Access Control 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_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE 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 Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF 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_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP 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 */
+
+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET 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_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP 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 */
+
+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+    \brief      Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/** \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __I  uint32_t ICTR;                    /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register      */
+  __IO uint32_t ACTLR;                   /*!< Offset: 0x008 (R/W)  Auxiliary Control Register              */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0                                          /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos            9                                          /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk           (1UL << SCnSCB_ACTLR_DISOOFP_Pos)           /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos            8                                          /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk           (1UL << SCnSCB_ACTLR_DISFPCA_Pos)           /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2                                          /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1                                          /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0                                          /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \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_ITM     Instrumentation Trace Macrocell (ITM)
+    \brief      Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/** \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __O  union
+  {
+    __O  uint8_t    u8;                  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
+    __O  uint16_t   u16;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
+    __O  uint32_t   u32;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
+  }  PORT [32];                          /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                     /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                     /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                     /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
+       uint32_t RESERVED3[29];
+  __O  uint32_t IWR;                     /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
+  __I  uint32_t IRR;                     /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
+  __IO uint32_t IMCR;                    /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
+       uint32_t RESERVED4[43];
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
+       uint32_t RESERVED5[6];
+  __I  uint32_t PID4;                    /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __I  uint32_t PID5;                    /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __I  uint32_t PID6;                    /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __I  uint32_t PID7;                    /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __I  uint32_t PID0;                    /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __I  uint32_t PID1;                    /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __I  uint32_t PID2;                    /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __I  uint32_t PID3;                    /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __I  uint32_t CID0;                    /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __I  uint32_t CID1;                    /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __I  uint32_t CID2;                    /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __I  uint32_t CID3;                    /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16                                             /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10                                             /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+    \brief      Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/** \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  Control Register                          */
+  __IO uint32_t CYCCNT;                  /*!< Offset: 0x004 (R/W)  Cycle Count Register                      */
+  __IO uint32_t CPICNT;                  /*!< Offset: 0x008 (R/W)  CPI Count Register                        */
+  __IO uint32_t EXCCNT;                  /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register         */
+  __IO uint32_t SLEEPCNT;                /*!< Offset: 0x010 (R/W)  Sleep Count Register                      */
+  __IO uint32_t LSUCNT;                  /*!< Offset: 0x014 (R/W)  LSU Count Register                        */
+  __IO uint32_t FOLDCNT;                 /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register         */
+  __I  uint32_t PCSR;                    /*!< Offset: 0x01C (R/ )  Program Counter Sample Register           */
+  __IO uint32_t COMP0;                   /*!< Offset: 0x020 (R/W)  Comparator Register 0                     */
+  __IO uint32_t MASK0;                   /*!< Offset: 0x024 (R/W)  Mask Register 0                           */
+  __IO uint32_t FUNCTION0;               /*!< Offset: 0x028 (R/W)  Function Register 0                       */
+       uint32_t RESERVED0[1];
+  __IO uint32_t COMP1;                   /*!< Offset: 0x030 (R/W)  Comparator Register 1                     */
+  __IO uint32_t MASK1;                   /*!< Offset: 0x034 (R/W)  Mask Register 1                           */
+  __IO uint32_t FUNCTION1;               /*!< Offset: 0x038 (R/W)  Function Register 1                       */
+       uint32_t RESERVED1[1];
+  __IO uint32_t COMP2;                   /*!< Offset: 0x040 (R/W)  Comparator Register 2                     */
+  __IO uint32_t MASK2;                   /*!< Offset: 0x044 (R/W)  Mask Register 2                           */
+  __IO uint32_t FUNCTION2;               /*!< Offset: 0x048 (R/W)  Function Register 2                       */
+       uint32_t RESERVED2[1];
+  __IO uint32_t COMP3;                   /*!< Offset: 0x050 (R/W)  Comparator Register 3                     */
+  __IO uint32_t MASK3;                   /*!< Offset: 0x054 (R/W)  Mask Register 3                           */
+  __IO uint32_t FUNCTION3;               /*!< Offset: 0x058 (R/W)  Function Register 3                       */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28                                          /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27                                          /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26                                          /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25                                          /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24                                          /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22                                          /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21                                          /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20                                          /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19                                          /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18                                          /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17                                          /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16                                          /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12                                          /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10                                          /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9                                          /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5                                          /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1                                          /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0                                          /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0                                          /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0                                          /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0                                          /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0                                          /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0                                          /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0                                          /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24                                          /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16                                          /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12                                          /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10                                          /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9                                          /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8                                          /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7                                          /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5                                          /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0                                          /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+    \brief      Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/** \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IO uint32_t SSPSR;                   /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register     */
+  __IO uint32_t CSPSR;                   /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+       uint32_t RESERVED0[2];
+  __IO uint32_t ACPR;                    /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+       uint32_t RESERVED1[55];
+  __IO uint32_t SPPR;                    /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+       uint32_t RESERVED2[131];
+  __I  uint32_t FFSR;                    /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IO uint32_t FFCR;                    /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __I  uint32_t FSCR;                    /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+       uint32_t RESERVED3[759];
+  __I  uint32_t TRIGGER;                 /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __I  uint32_t FIFO0;                   /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __I  uint32_t ITATBCTR2;               /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+       uint32_t RESERVED4[1];
+  __I  uint32_t ITATBCTR0;               /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __I  uint32_t FIFO1;                   /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IO uint32_t ITCTRL;                  /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+       uint32_t RESERVED5[39];
+  __IO uint32_t CLAIMSET;                /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IO uint32_t CLAIMCLR;                /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+       uint32_t RESERVED7[8];
+  __I  uint32_t DEVID;                   /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __I  uint32_t DEVTYPE;                 /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0                                          /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0                                          /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3                                          /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2                                          /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1                                          /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0                                          /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8                                          /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1                                          /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0                                          /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27                                          /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24                                          /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16                                          /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8                                          /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0                                          /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0                                          /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27                                          /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24                                          /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16                                          /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8                                          /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0                                          /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0                                          /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0                                          /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11                                          /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10                                          /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9                                          /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6                                          /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5                                          /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0                                          /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+  __IO uint32_t RBAR_A1;                 /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register       */
+  __IO uint32_t RASR_A1;                 /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A2;                 /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register       */
+  __IO uint32_t RASR_A2;                 /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A3;                 /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register       */
+  __IO uint32_t RASR_A3;                 /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+    \brief      Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __IO uint32_t FPCCR;                   /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register               */
+  __IO uint32_t FPCAR;                   /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register               */
+  __IO uint32_t FPDSCR;                  /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register        */
+  __I  uint32_t MVFR0;                   /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0                       */
+  __I  uint32_t MVFR1;                   /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1                       */
+} FPU_Type;
+
+/* Floating-Point Context Control Register */
+#define FPU_FPCCR_ASPEN_Pos                31                                             /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30                                             /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8                                             /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6                                             /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5                                             /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4                                             /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3                                             /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1                                             /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0                                             /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL /*<< FPU_FPCCR_LSPACT_Pos*/)              /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register */
+#define FPU_FPCAR_ADDRESS_Pos               3                                             /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register */
+#define FPU_FPDSCR_AHP_Pos                 26                                             /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25                                             /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24                                             /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22                                             /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28                                             /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24                                             /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20                                             /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16                                             /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12                                             /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8                                             /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4                                             /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0                                             /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/)  /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28                                             /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24                                             /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4                                             /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0                                             /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/)          /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Type definitions for the Core Debug Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IO uint32_t DHCSR;                   /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register    */
+  __O  uint32_t DCRSR;                   /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register        */
+  __IO uint32_t DCRDR;                   /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register            */
+  __IO uint32_t DEMCR;                   /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} 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-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address                   */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address                   */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug 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 SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#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          */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct           */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct           */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct           */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct    */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+#if (__FPU_PRESENT == 1)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit                */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit                */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug 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.
+    @{
+ */
+
+/** \brief  Set Priority Grouping
+
+  The function sets the priority grouping field using the required unlock sequence.
+  The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+  Only values from 0..7 are used.
+  In case of a conflict between priority grouping and available
+  priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk));             /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8)                       );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/** \brief  Get Priority Grouping
+
+  The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+    \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/** \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[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \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[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \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[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/** \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[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \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[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \brief  Get Active Interrupt
+
+    The function reads the active register in NVIC and returns the active bit.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not active.
+    \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/** \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((int32_t)IRQn < 0) {
+    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/** \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((int32_t)IRQn < 0) {
+    return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8 - __NVIC_PRIO_BITS)));
+  }
+  else {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8 - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/** \brief  Encode Priority
+
+    The function encodes the priority for an interrupt with the given priority group,
+    preemptive priority value, and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]     PriorityGroup  Used priority group.
+    \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+    \param [in]       SubPriority  Subpriority value (starting from 0).
+    \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/** \brief  Decode Priority
+
+    The function decodes an interrupt priority value with a given priority group to
+    preemptive priority value and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+
+    \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+    \param [in]     PriorityGroup  Used priority group.
+    \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+    \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/** \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  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+  while(1) { __NOP(); }                                             /* 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 - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); }    /* Reload value impossible */
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* 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 (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_core_DebugFunctions ITM Functions
+    \brief   Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters.                         */
+#define                 ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief  ITM Send Character
+
+    The function transmits a character via the ITM channel 0, and
+    \li Just returns when no debugger is connected that has booked the output.
+    \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+    \param [in]     ch  Character to transmit.
+
+    \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0UL) { __NOP(); }
+    ITM->PORT[0].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/** \brief  ITM Receive Character
+
+    The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+    \return             Received character.
+    \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/** \brief  ITM Check Character
+
+    The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+    \return          0  No character available.
+    \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */

+ 664 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmFunc.h

@@ -0,0 +1,664 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V4.10
+ * @date     18. March 2015
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 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  Set Base Priority with condition
+
+    This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+    or the new value increases the BASEPRI priority level.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+  register uint32_t __regBasePriMax      __ASM("basepri_max");
+  __regBasePriMax = (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" : "=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  Set Base Priority with condition
+
+    This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+    or the new value increases the BASEPRI priority level.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+  __ASM volatile ("MSR basepri_max, %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 */

+ 916 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmInstr.h

@@ -0,0 +1,916 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V4.10
+ * @date     18. March 2015
+ *
+ * @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() do {\
+                   __schedule_barrier();\
+                   __isb(0xF);\
+                   __schedule_barrier();\
+                } while (0)
+
+/** \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() do {\
+                   __schedule_barrier();\
+                   __dsb(0xF);\
+                   __schedule_barrier();\
+                } while (0)
+
+/** \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() do {\
+                   __schedule_barrier();\
+                   __dmb(0xF);\
+                   __schedule_barrier();\
+                } while (0)
+
+/** \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)
+
+
+/** \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
+ */
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+  #define __RBIT                          __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
+
+  result = value;                      // r will be reversed bits of v; first get LSB of v
+  for (value >>= 1; value; value >>= 1)
+  {
+    result <<= 1;
+    result |= value & 1;
+    s--;
+  }
+  result <<= s;                       // shift when v's highest bits are zero
+  return(result);
+}
+#endif
+
+
+/** \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
+
+
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+
+/** \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  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 0xF":::"memory");
+}
+
+
+/** \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 0xF":::"memory");
+}
+
+
+/** \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 0xF":::"memory");
+}
+
+
+/** \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)
+
+
+/** \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;
+
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+  int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
+
+  result = value;                      // r will be reversed bits of v; first get LSB of v
+  for (value >>= 1; value; value >>= 1)
+  {
+    result <<= 1;
+    result |= value & 1;
+    s--;
+  }
+  result <<= s;                       // shift when v's highest bits are zero
+#endif
+  return(result);
+}
+
+
+/** \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             __builtin_clz
+
+
+#if       (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
+
+/** \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  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 */

+ 697 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmSimd.h

@@ -0,0 +1,697 @@
+/**************************************************************************//**
+ * @file     core_cmSimd.h
+ * @brief    CMSIS Cortex-M SIMD Header File
+ * @version  V4.10
+ * @date     18. March 2015
+ *
+ * @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_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+#define __SADD8                           __sadd8
+#define __QADD8                           __qadd8
+#define __SHADD8                          __shadd8
+#define __UADD8                           __uadd8
+#define __UQADD8                          __uqadd8
+#define __UHADD8                          __uhadd8
+#define __SSUB8                           __ssub8
+#define __QSUB8                           __qsub8
+#define __SHSUB8                          __shsub8
+#define __USUB8                           __usub8
+#define __UQSUB8                          __uqsub8
+#define __UHSUB8                          __uhsub8
+#define __SADD16                          __sadd16
+#define __QADD16                          __qadd16
+#define __SHADD16                         __shadd16
+#define __UADD16                          __uadd16
+#define __UQADD16                         __uqadd16
+#define __UHADD16                         __uhadd16
+#define __SSUB16                          __ssub16
+#define __QSUB16                          __qsub16
+#define __SHSUB16                         __shsub16
+#define __USUB16                          __usub16
+#define __UQSUB16                         __uqsub16
+#define __UHSUB16                         __uhsub16
+#define __SASX                            __sasx
+#define __QASX                            __qasx
+#define __SHASX                           __shasx
+#define __UASX                            __uasx
+#define __UQASX                           __uqasx
+#define __UHASX                           __uhasx
+#define __SSAX                            __ssax
+#define __QSAX                            __qsax
+#define __SHSAX                           __shsax
+#define __USAX                            __usax
+#define __UQSAX                           __uqsax
+#define __UHSAX                           __uhsax
+#define __USAD8                           __usad8
+#define __USADA8                          __usada8
+#define __SSAT16                          __ssat16
+#define __USAT16                          __usat16
+#define __UXTB16                          __uxtb16
+#define __UXTAB16                         __uxtab16
+#define __SXTB16                          __sxtb16
+#define __SXTAB16                         __sxtab16
+#define __SMUAD                           __smuad
+#define __SMUADX                          __smuadx
+#define __SMLAD                           __smlad
+#define __SMLADX                          __smladx
+#define __SMLALD                          __smlald
+#define __SMLALDX                         __smlaldx
+#define __SMUSD                           __smusd
+#define __SMUSDX                          __smusdx
+#define __SMLSD                           __smlsd
+#define __SMLSDX                          __smlsdx
+#define __SMLSLD                          __smlsld
+#define __SMLSLDX                         __smlsldx
+#define __SEL                             __sel
+#define __QADD                            __qadd
+#define __QSUB                            __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
+                                           ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
+
+#define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
+                                           ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
+
+#define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+                                                      ((int64_t)(ARG3) << 32)      ) >> 32))
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+
+#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 */
+/* not yet supported */
+
+
+#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
+/* Cosmic specific functions */
+#include <cmsis_csm.h>
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */

+ 176 - 0
project_0/libraries/APM32F4xx_Library/CMSIS/LICENSE.txt

@@ -0,0 +1,176 @@
+ Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS

+ 7492 - 0
project_0/libraries/APM32F4xx_Library/Device/Geehy/APM32F4xx/Include/apm32f4xx.h

@@ -0,0 +1,7492 @@
+/*!
+ * @file        apm32f4xx.h
+ *
+ * @brief       CMSIS Cortex-M4 Device Peripheral Access Layer Header File.
+ *
+ * @details     This file contains all the peripheral register's definitions, bits definitions and memory mapping
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#ifndef __APM32F4XX_H
+#define __APM32F4XX_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif /* __cplusplus */
+
+/** @addtogroup CMSIS
+  @{
+*/
+
+/** @defgroup APM32F4xx
+  * @brief Peripheral Access Layer
+  @{
+*/
+
+/** @defgroup HSE_Macros
+  @{
+*/
+
+/**
+ * @brief Define Value of the External oscillator in Hz
+ */
+#ifndef  HSE_VALUE
+#define HSE_VALUE                   ((uint32_t)8000000)
+#endif
+
+/** Time out for HSE start up */
+#define HSE_STARTUP_TIMEOUT         ((uint16_t)0x05000)
+
+/** Value of the Internal oscillator in Hz */
+#define HSI_VALUE                   ((uint32_t)16000000)
+
+/**
+  * @}
+  */
+
+/** @defgroup APM32F4xx_StdPeripheral_Library_Version
+  @{
+*/
+
+/**
+ * @brief Library_Version_Number_Macros
+ */
+#define __APM32F4XX_STDPERIPH_VERSION_MAIN   (0x01) /*!< [31:24] main version */
+#define __APM32F4XX_STDPERIPH_VERSION_SUB1   (0x00) /*!< [23:16] sub1 version */
+#define __APM32F4XX_STDPERIPH_VERSION_SUB2   (0x02) /*!< [15:8]  sub2 version */
+#define __APM32F4XX_STDPERIPH_VERSION_RC     (0x00) /*!< [7:0]  release candidate */
+#define __APM32F4XX_STDPERIPH_VERSION        ((__APM32F4XX_STDPERIPH_VERSION_MAIN << 24)\
+                                             |(__APM32F4XX_STDPERIPH_VERSION_SUB1 << 16)\
+                                             |(__APM32F4XX_STDPERIPH_VERSION_SUB2 << 8)\
+                                             |(__APM32F4XX_STDPERIPH_VERSION_RC))
+
+/**
+  * @}
+  */
+
+/** @defgroup Configuraion_for_CMSIS
+  @{
+*/
+
+/** Core revision r0p1 */
+#define __CM4_REV                      0x0001
+/** APM32 devices provides an MPU */
+#define __MPU_PRESENT                  1
+/** APM32 uses 4 Bits for the Priority Levels  */
+#define __NVIC_PRIO_BITS               4
+/** Set to 1 if different SysTick Config is used */
+#define __Vendor_SysTickConfig         0
+/** APM32 devices provides an FPU */
+#define __FPU_PRESENT                  1
+
+/**
+ * @brief APM32F4xx Interrupt Number Definition, according to the selected device
+ *        in @ref Library_configuration_section
+ */
+typedef enum IRQn
+{
+    /******  Cortex-M4 Processor Exceptions Numbers ****************************************************************/
+    NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                                          */
+    MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M3 Memory Management Interrupt                           */
+    BusFault_IRQn               = -11,    /*!< 5 Cortex-M3 Bus Fault Interrupt                                   */
+    UsageFault_IRQn             = -10,    /*!< 6 Cortex-M3 Usage Fault Interrupt                                 */
+    SVCall_IRQn                 = -5,     /*!< 11 Cortex-M3 SV Call Interrupt                                    */
+    DebugMonitor_IRQn           = -4,     /*!< 12 Cortex-M3 Debug Monitor Interrupt                              */
+    PendSV_IRQn                 = -2,     /*!< 14 Cortex-M3 Pend SV Interrupt                                    */
+    SysTick_IRQn                = -1,     /*!< 15 Cortex-M3 System Tick Interrupt                                */
+
+    /******  APM32 specific Interrupt Numbers **********************************************************************/
+    WWDT_IRQn                   = 0,      /*!< Window WatchDog Interrupt                                         */
+    PVD_IRQn                    = 1,      /*!< PVD through EINT Line detection Interrupt                         */
+    TAMP_STAMP_IRQn             = 2,      /*!< Tamper Interrupt                                                  */
+    RTC_WKUP_IRQn               = 3,      /*!< RTC global Interrupt                                              */
+    FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                                            */
+    RCM_IRQn                    = 5,      /*!< RCM global Interrupt                                              */
+    EINT0_IRQn                  = 6,      /*!< EINT Line0 Interrupt                                              */
+    EINT1_IRQn                  = 7,      /*!< EINT Line1 Interrupt                                              */
+    EINT2_IRQn                  = 8,      /*!< EINT Line2 Interrupt                                              */
+    EINT3_IRQn                  = 9,      /*!< EINT Line3 Interrupt                                              */
+    EINT4_IRQn                  = 10,     /*!< EINT Line4 Interrupt                                              */
+    DMA1_STR0_IRQn              = 11,     /*!< DMA1 Stream 1 global Interrupt                                    */
+    DMA1_STR1_IRQn              = 12,     /*!< DMA1 Stream 1 global Interrupt                                    */
+    DMA1_STR2_IRQn              = 13,     /*!< DMA1 Stream 2 global Interrupt                                    */
+    DMA1_STR3_IRQn              = 14,     /*!< DMA1 Stream 3 global Interrupt                                    */
+    DMA1_STR4_IRQn              = 15,     /*!< DMA1 Stream 4 global Interrupt                                    */
+    DMA1_STR5_IRQn              = 16,     /*!< DMA1 Stream 5 global Interrupt                                    */
+    DMA1_STR6_IRQn              = 17,     /*!< DMA1 Stream 6 global Interrupt                                    */
+
+#if defined(APM32F40X)
+    ADC_IRQn                    = 18,     /*!< ADC Interrupt                                                     */
+    CAN1_TX_IRQn                = 19,     /*!< CAN1 TX Interrupt                                                 */
+    CAN1_RX0_IRQn               = 20,     /*!< CAN1 RX0 Interrupt                                                */
+    CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                                */
+    CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                                */
+    EINT9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                                     */
+    TMR1_BRK_TMR9_IRQn          = 24,     /*!< TMR1 Break interrupt and TMR9 global interrupt                    */
+    TMR1_UP_TMR10_IRQn          = 25,     /*!< TMR1 Update Interrupt and TMR10 global interrupt                  */
+    TMR1_TRG_COM_TMR11_IRQn     = 26,     /*!< TMR1 Trigger and Commutation Interrupt and TMR11 global interrupt */
+    TMR1_CC_IRQn                = 27,     /*!< TMR1 Capture Compare Interrupt                                    */
+    TMR2_IRQn                   = 28,     /*!< TMR2 global Interrupt                                             */
+    TMR3_IRQn                   = 29,     /*!< TMR3 global Interrupt                                             */
+    TMR4_IRQn                   = 30,     /*!< TMR4 global Interrupt                                             */
+    I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                              */
+    I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                              */
+    I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                              */
+    I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                              */
+    SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                             */
+    SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                             */
+    USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                                           */
+    USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                                           */
+    USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                                           */
+    EINT15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                                   */
+    RTC_Alarm_IRQn              = 41,     /*!< RTC Alarm (A and B) through EINT Line Interrupt                   */
+    OTG_FS_WKUP_IRQn            = 42,     /*!< OTG_FS Wakeup through EINT line interrupt                         */
+    TMR8_BRK_TMR12_IRQn         = 43,     /*!< TMR8 Break Interrupt and TMR12 global interrupt                   */
+    TMR8_UP_TMR13_IRQn          = 44,     /*!< TMR8 Update Interrupt and TMR13 global interrupt                  */
+    TMR8_TRG_COM_TMR14_IRQn     = 45,     /*!< TMR8 Trigger and Commutation Interrupt and TMR14 global interrupt */
+    TMR8_CC_IRQn                = 46,     /*!< TMR8 Capture Compare Interrupt                                    */
+    DMA1_STR7_IRQn              = 47,     /*!< DMA1 Stream 7 Interrupt                                           */
+    EMMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                             */
+    SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                             */
+    TMR5_IRQn                   = 50,     /*!< TMR5 global Interrupt                                             */
+    SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                             */
+    UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                                            */
+    UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                                            */
+    TMR6_DAC_IRQn               = 54,     /*!< TMR6 global and DAC1&2 underrun error  interrupts                 */
+    TMR7_IRQn                   = 55,     /*!< TMR7 global interrupt                                             */
+    DMA2_STR0_IRQn              = 56,     /*!< DMA2 Stream 0 global Interrupt                                    */
+    DMA2_STR1_IRQn              = 57,     /*!< DMA2 Stream 1 global Interrupt                                    */
+    DMA2_STR2_IRQn              = 58,     /*!< DMA2 Stream 2 global Interrupt                                    */
+    DMA2_STR3_IRQn              = 59,     /*!< DMA2 Stream 3 global Interrupt                                    */
+    DMA2_STR4_IRQn              = 60,     /*!< DMA2 Stream 4 global Interrupt                                    */
+    ETH_IRQn                    = 61,     /*!< Ethernet global Interrupt                                         */
+    ETH_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EINT line Interrupt                       */
+    CAN2_TX_IRQn                = 63,     /*!< CAN2 TX Interrupt                                                 */
+    CAN2_RX0_IRQn               = 64,     /*!< CAN2 RX0 Interrupt                                                */
+    CAN2_RX1_IRQn               = 65,     /*!< CAN2 RX1 Interrupt                                                */
+    CAN2_SCE_IRQn               = 66,     /*!< CAN2 SCE Interrupt                                                */
+    OTG_FS_IRQn                 = 67,     /*!< OTG_FS global Interrupt                                           */
+    DMA2_STR5_IRQn              = 68,     /*!< DMA2 Stream 5 global interrupt                                    */
+    DMA2_STR6_IRQn              = 69,     /*!< DMA2 Stream 6 global interrupt                                    */
+    DMA2_STR7_IRQn              = 70,     /*!< DMA2 Stream 7 global interrupt                                    */
+    USART6_IRQn                 = 71,     /*!< USART6 global interrupt                                           */
+    I2C3_EV_IRQn                = 72,     /*!< I2C3 event interrupt                                              */
+    I2C3_ER_IRQn                = 73,     /*!< I2C3 error interrupt                                              */
+    OTG_HS1_EP1_OUT_IRQn        = 74,     /*!< OTG_HS1 End Point 1 Out global interrupt                          */
+    OTG_HS1_EP1_IN_IRQn         = 75,     /*!< OTG_HS1 End Point 1 In global interrupt                           */
+    OTG_HS1_WKUP_IRQn           = 76,     /*!< OTG_HS1 Wakeup through EINT interrupt                             */
+    OTG_HS1_IRQn                = 77,     /*!< OTG_HS1 global interrupt                                          */
+    DCI_IRQn                    = 78,     /*!< DCMI global interrupt                                             */
+    FPU_IRQn                    = 81,     /*!< FPU global interrupt                                              */
+    SM3_IRQn                    = 82,     /*!< SM3 global interrupt                                              */
+    SM4_IRQn                    = 83,     /*!< SM4 global interrupt                                              */
+    BN_IRQn                     = 84      /*!< BN global interrupt                                               */
+#endif /* APM32F40x */
+
+#if defined(APM32F41X)
+    ADC_IRQn                    = 18,     /*!< ADC Interrupt                                                     */
+    CAN1_TX_IRQn                = 19,     /*!< CAN1 TX Interrupt                                                 */
+    CAN1_RX0_IRQn               = 20,     /*!< CAN1 RX0 Interrupt                                                */
+    CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                                */
+    CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                                */
+    EINT9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                                     */
+    TMR1_BRK_TMR9_IRQn          = 24,     /*!< TMR1 Break interrupt and TMR9 global interrupt                    */
+    TMR1_UP_TMR10_IRQn          = 25,     /*!< TMR1 Update Interrupt and TMR10 global interrupt                  */
+    TMR1_TRG_COM_TMR11_IRQn     = 26,     /*!< TMR1 Trigger and Commutation Interrupt and TMR11 global interrupt */
+    TMR1_CC_IRQn                = 27,     /*!< TMR1 Capture Compare Interrupt                                    */
+    TMR2_IRQn                   = 28,     /*!< TMR2 global Interrupt                                             */
+    TMR3_IRQn                   = 29,     /*!< TMR3 global Interrupt                                             */
+    TMR4_IRQn                   = 30,     /*!< TMR4 global Interrupt                                             */
+    I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                              */
+    I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                              */
+    I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                              */
+    I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                              */
+    SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                             */
+    SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                             */
+    USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                                           */
+    USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                                           */
+    USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                                           */
+    EINT15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                                   */
+    RTC_Alarm_IRQn              = 41,     /*!< RTC Alarm (A and B) through EINT Line Interrupt                   */
+    OTG_FS_WKUP_IRQn            = 42,     /*!< OTG_FS Wakeup through EINT line interrupt                          */
+    TMR8_BRK_TMR12_IRQn         = 43,     /*!< TMR8 Break Interrupt and TMR12 global interrupt                   */
+    TMR8_UP_TMR13_IRQn          = 44,     /*!< TMR8 Update Interrupt and TMR13 global interrupt                  */
+    TMR8_TRG_COM_TMR14_IRQn     = 45,     /*!< TMR8 Trigger and Commutation Interrupt and TMR14 global interrupt */
+    TMR8_CC_IRQn                = 46,     /*!< TMR8 Capture Compare Interrupt                                    */
+    DMA1_STR7_IRQn              = 47,     /*!< DMA1 Stream 7 Interrupt                                           */
+    EMMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                             */
+    SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                             */
+    TMR5_IRQn                   = 50,     /*!< TMR5 global Interrupt                                             */
+    SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                             */
+    UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                                            */
+    UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                                            */
+    TMR6_DAC_IRQn               = 54,     /*!< TMR6 global and DAC1&2 underrun error  interrupts                 */
+    TMR7_IRQn                   = 55,     /*!< TMR7 global interrupt                                             */
+    DMA2_STR0_IRQn              = 56,     /*!< DMA2 Stream 0 global Interrupt                                    */
+    DMA2_STR1_IRQn              = 57,     /*!< DMA2 Stream 1 global Interrupt                                    */
+    DMA2_STR2_IRQn              = 58,     /*!< DMA2 Stream 2 global Interrupt                                    */
+    DMA2_STR3_IRQn              = 59,     /*!< DMA2 Stream 3 global Interrupt                                    */
+    DMA2_STR4_IRQn              = 60,     /*!< DMA2 Stream 4 global Interrupt                                    */
+    ETH_IRQn                    = 61,     /*!< Ethernet global Interrupt                                         */
+    ETH_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EINT line Interrupt                       */
+    CAN2_TX_IRQn                = 63,     /*!< CAN2 TX Interrupt                                                 */
+    CAN2_RX0_IRQn               = 64,     /*!< CAN2 RX0 Interrupt                                                */
+    CAN2_RX1_IRQn               = 65,     /*!< CAN2 RX1 Interrupt                                                */
+    CAN2_SCE_IRQn               = 66,     /*!< CAN2 SCE Interrupt                                                */
+    OTG_FS_IRQn                 = 67,     /*!< OTG_FS global Interrupt                                           */
+    DMA2_STR5_IRQn              = 68,     /*!< DMA2 Stream 5 global interrupt                                    */
+    DMA2_STR6_IRQn              = 69,     /*!< DMA2 Stream 6 global interrupt                                    */
+    DMA2_STR7_IRQn              = 70,     /*!< DMA2 Stream 7 global interrupt                                    */
+    USART6_IRQn                 = 71,     /*!< USART6 global interrupt                                           */
+    I2C3_EV_IRQn                = 72,     /*!< I2C3 event interrupt                                              */
+    I2C3_ER_IRQn                = 73,     /*!< I2C3 error interrupt                                              */
+    OTG_HS1_EP1_OUT_IRQn        = 74,     /*!< OTG_HS1 End Point 1 Out global interrupt                          */
+    OTG_HS1_EP1_IN_IRQn         = 75,     /*!< OTG_HS1 End Point 1 In global interrupt                           */
+    OTG_HS1_WKUP_IRQn           = 76,     /*!< OTG_HS1 Wakeup through EINT interrupt                             */
+    OTG_HS1_IRQn                = 77,     /*!< OTG_HS1 global interrupt                                          */
+    DCI_IRQn                    = 78,     /*!< DCMI global interrupt                                             */
+    CRYP_IRQn                   = 79,     /*!< CRYP crypto global interrupt                                      */
+    HASH_RNG_IRQn               = 80,     /*!< Hash and Rng global interrupt                                     */
+    FPU_IRQn                    = 81,     /*!< FPU global interrupt                                              */
+    SM3_IRQn                    = 82,     /*!< SM3 global interrupt                                              */
+    SM4_IRQn                    = 83,     /*!< SM4 global interrupt                                              */
+    BN_IRQn                     = 84      /*!< BN global interrupt                                               */
+#endif /* APM32F41x */
+
+} IRQn_Type;
+
+/**
+  * @}
+  */
+
+#include "core_cm4.h"
+#include "system_apm32f4xx.h"
+#include <stdint.h>
+
+/** @defgroup Exported_Types
+  @{
+*/
+
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t  s8;
+
+typedef const int32_t sc32;
+typedef const int16_t sc16;
+typedef const int8_t sc8;
+
+typedef __IO int32_t  vs32;
+typedef __IO int16_t  vs16;
+typedef __IO int8_t   vs8;
+
+typedef __I int32_t vsc32;
+typedef __I int16_t vsc16;
+typedef __I int8_t vsc8;
+
+typedef uint32_t  u32;
+typedef uint16_t u16;
+typedef uint8_t  u8;
+
+typedef const uint32_t uc32;
+typedef const uint16_t uc16;
+typedef const uint8_t uc8;
+
+typedef __IO uint32_t  vu32;
+typedef __IO uint16_t vu16;
+typedef __IO uint8_t  vu8;
+
+typedef __I uint32_t vuc32;
+typedef __I uint16_t vuc16;
+typedef __I uint8_t vuc8;
+
+#ifndef __IM
+#define __IM   __I
+#endif
+#ifndef __OM
+#define __OM   __O
+#endif
+#ifndef __IOM
+#define __IOM  __IO
+#endif
+
+enum {BIT_RESET, BIT_SET};
+enum {RESET, SET};
+enum {DISABLE, ENABLE};
+enum {ERROR, SUCCESS};
+
+#ifndef NULL
+#define NULL   ((void *)0)
+#endif
+
+#if defined (__CC_ARM )
+#pragma anon_unions
+#endif
+
+/**
+  * @}
+  */
+
+/** @defgroup Peripheral_registers_structures
+  @{
+*/
+
+/**
+* @brief General purpose I/O (GPIO)
+*/
+typedef struct
+{
+    /** Port Mode configure register  */
+    union
+    {
+        __IOM uint32_t MODE;
+
+        struct
+        {
+            __IOM uint32_t MODE0           : 2;
+            __IOM uint32_t MODE1           : 2;
+            __IOM uint32_t MODE2           : 2;
+            __IOM uint32_t MODE3           : 2;
+            __IOM uint32_t MODE4           : 2;
+            __IOM uint32_t MODE5           : 2;
+            __IOM uint32_t MODE6           : 2;
+            __IOM uint32_t MODE7           : 2;
+            __IOM uint32_t MODE8           : 2;
+            __IOM uint32_t MODE9           : 2;
+            __IOM uint32_t MODE10          : 2;
+            __IOM uint32_t MODE11          : 2;
+            __IOM uint32_t MODE12          : 2;
+            __IOM uint32_t MODE13          : 2;
+            __IOM uint32_t MODE14          : 2;
+            __IOM uint32_t MODE15          : 2;
+        } MODE_B;
+    } ;
+
+    /** Port Output Type configure register  */
+    union
+    {
+        __IOM uint32_t OMODE;
+
+        struct
+        {
+            __IOM uint32_t OMODE0           : 1;
+            __IOM uint32_t OMODE1           : 1;
+            __IOM uint32_t OMODE2           : 1;
+            __IOM uint32_t OMODE3           : 1;
+            __IOM uint32_t OMODE4           : 1;
+            __IOM uint32_t OMODE5           : 1;
+            __IOM uint32_t OMODE6           : 1;
+            __IOM uint32_t OMODE7           : 1;
+            __IOM uint32_t OMODE8           : 1;
+            __IOM uint32_t OMODE9           : 1;
+            __IOM uint32_t OMODE10          : 1;
+            __IOM uint32_t OMODE11          : 1;
+            __IOM uint32_t OMODE12          : 1;
+            __IOM uint32_t OMODE13          : 1;
+            __IOM uint32_t OMODE14          : 1;
+            __IOM uint32_t OMODE15          : 1;
+            __IOM uint32_t RESERVED         : 16;
+        } OMODE_B;
+    } ;
+
+    /** Port Output Speed configure register  */
+    union
+    {
+        __IOM uint32_t OSSEL;
+
+        struct
+        {
+            __IOM uint32_t OSSEL0           : 2;
+            __IOM uint32_t OSSEL1           : 2;
+            __IOM uint32_t OSSEL2           : 2;
+            __IOM uint32_t OSSEL3           : 2;
+            __IOM uint32_t OSSEL4           : 2;
+            __IOM uint32_t OSSEL5           : 2;
+            __IOM uint32_t OSSEL6           : 2;
+            __IOM uint32_t OSSEL7           : 2;
+            __IOM uint32_t OSSEL8           : 2;
+            __IOM uint32_t OSSEL9           : 2;
+            __IOM uint32_t OSSEL10          : 2;
+            __IOM uint32_t OSSEL11          : 2;
+            __IOM uint32_t OSSEL12          : 2;
+            __IOM uint32_t OSSEL13          : 2;
+            __IOM uint32_t OSSEL14          : 2;
+            __IOM uint32_t OSSEL15          : 2;
+        } OSSEL_B;
+    } ;
+
+    /**  port pull-up/pull-down register  */
+    union
+    {
+        __IOM uint32_t PUPD;
+
+        struct
+        {
+            __IOM uint32_t PUPD0            : 2;
+            __IOM uint32_t PUPD1            : 2;
+            __IOM uint32_t PUPD2            : 2;
+            __IOM uint32_t PUPD3            : 2;
+            __IOM uint32_t PUPD4            : 2;
+            __IOM uint32_t PUPD5            : 2;
+            __IOM uint32_t PUPD6            : 2;
+            __IOM uint32_t PUPD7            : 2;
+            __IOM uint32_t PUPD8            : 2;
+            __IOM uint32_t PUPD9            : 2;
+            __IOM uint32_t PUPD10           : 2;
+            __IOM uint32_t PUPD11           : 2;
+            __IOM uint32_t PUPD12           : 2;
+            __IOM uint32_t PUPD13           : 2;
+            __IOM uint32_t PUPD14           : 2;
+            __IOM uint32_t PUPD15           : 2;
+        } PUPD_B;
+    } ;
+
+    /** Port data in register */
+    union
+    {
+        __IM  uint32_t IDATA;
+
+        struct
+        {
+            __IM  uint32_t IDATA0          : 1;
+            __IM  uint32_t IDATA1          : 1;
+            __IM  uint32_t IDATA2          : 1;
+            __IM  uint32_t IDATA3          : 1;
+            __IM  uint32_t IDATA4          : 1;
+            __IM  uint32_t IDATA5          : 1;
+            __IM  uint32_t IDATA6          : 1;
+            __IM  uint32_t IDATA7          : 1;
+            __IM  uint32_t IDATA8          : 1;
+            __IM  uint32_t IDATA9          : 1;
+            __IM  uint32_t IDATA10         : 1;
+            __IM  uint32_t IDATA11         : 1;
+            __IM  uint32_t IDATA12         : 1;
+            __IM  uint32_t IDATA13         : 1;
+            __IM  uint32_t IDATA14         : 1;
+            __IM  uint32_t IDATA15         : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } IDATA_B;
+    } ;
+
+    /** Port data output register */
+    union
+    {
+        __IOM uint32_t ODATA;
+
+        struct
+        {
+            __IOM uint32_t ODATA0          : 1;
+            __IOM uint32_t ODATA1          : 1;
+            __IOM uint32_t ODATA2          : 1;
+            __IOM uint32_t ODATA3          : 1;
+            __IOM uint32_t ODATA4          : 1;
+            __IOM uint32_t ODATA5          : 1;
+            __IOM uint32_t ODATA6          : 1;
+            __IOM uint32_t ODATA7          : 1;
+            __IOM uint32_t ODATA8          : 1;
+            __IOM uint32_t ODATA9          : 1;
+            __IOM uint32_t ODATA10         : 1;
+            __IOM uint32_t ODATA11         : 1;
+            __IOM uint32_t ODATA12         : 1;
+            __IOM uint32_t ODATA13         : 1;
+            __IOM uint32_t ODATA14         : 1;
+            __IOM uint32_t ODATA15         : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } ODATA_B;
+    } ;
+
+    /**GPIO port bit set/clear register*/
+    union
+    {
+        __OM  uint16_t BSCL;
+
+        struct
+        {
+            __OM  uint16_t BS0        : 1;
+            __OM  uint16_t BS1        : 1;
+            __OM  uint16_t BS2        : 1;
+            __OM  uint16_t BS3        : 1;
+            __OM  uint16_t BS4        : 1;
+            __OM  uint16_t BS5        : 1;
+            __OM  uint16_t BS6        : 1;
+            __OM  uint16_t BS7        : 1;
+            __OM  uint16_t BS8        : 1;
+            __OM  uint16_t BS9        : 1;
+            __OM  uint16_t BS10       : 1;
+            __OM  uint16_t BS11       : 1;
+            __OM  uint16_t BS12       : 1;
+            __OM  uint16_t BS13       : 1;
+            __OM  uint16_t BS14       : 1;
+            __OM  uint16_t BS15       : 1;
+        } BSCL_B;
+    } ;
+
+    union
+    {
+        __OM  uint16_t BSCH;
+
+        struct
+        {
+            __OM  uint16_t BC0        : 1;
+            __OM  uint16_t BC1        : 1;
+            __OM  uint16_t BC2        : 1;
+            __OM  uint16_t BC3        : 1;
+            __OM  uint16_t BC4        : 1;
+            __OM  uint16_t BC5        : 1;
+            __OM  uint16_t BC6        : 1;
+            __OM  uint16_t BC7        : 1;
+            __OM  uint16_t BC8        : 1;
+            __OM  uint16_t BC9        : 1;
+            __OM  uint16_t BC10       : 1;
+            __OM  uint16_t BC11       : 1;
+            __OM  uint16_t BC12       : 1;
+            __OM  uint16_t BC13       : 1;
+            __OM  uint16_t BC14       : 1;
+            __OM  uint16_t BC15       : 1;
+        } BSCH_B;
+    };
+
+    /** Port configuration lock register */
+    union
+    {
+        __IOM uint32_t LOCK;
+
+        struct
+        {
+            __IOM uint32_t LOCK0           : 1;
+            __IOM uint32_t LOCK1           : 1;
+            __IOM uint32_t LOCK2           : 1;
+            __IOM uint32_t LOCK3           : 1;
+            __IOM uint32_t LOCK4           : 1;
+            __IOM uint32_t LOCK5           : 1;
+            __IOM uint32_t LOCK6           : 1;
+            __IOM uint32_t LOCK7           : 1;
+            __IOM uint32_t LOCK8           : 1;
+            __IOM uint32_t LOCK9           : 1;
+            __IOM uint32_t LOCK10          : 1;
+            __IOM uint32_t LOCK11          : 1;
+            __IOM uint32_t LOCK12          : 1;
+            __IOM uint32_t LOCK13          : 1;
+            __IOM uint32_t LOCK14          : 1;
+            __IOM uint32_t LOCK15          : 1;
+            __IOM uint32_t LOCKKEY         : 1;
+            __IM  uint32_t RESERVED        : 15;
+        } LOCK_B;
+    };
+
+    /**  Port Alternate Function Low register  */
+    union
+    {
+        __IOM uint32_t ALFL;
+
+        struct
+        {
+            __IOM uint32_t ALFSEL0         : 4;
+            __IOM uint32_t ALFSEL1         : 4;
+            __IOM uint32_t ALFSEL2         : 4;
+            __IOM uint32_t ALFSEL3         : 4;
+            __IOM uint32_t ALFSEL4         : 4;
+            __IOM uint32_t ALFSEL5         : 4;
+            __IOM uint32_t ALFSEL6         : 4;
+            __IOM uint32_t ALFSEL7         : 4;
+        } ALFL_B;
+    };
+
+    /**  Port alternate function High register  */
+    union
+    {
+        __IOM uint32_t ALFH;
+
+        struct
+        {
+            __IOM uint32_t ALFSEL8         : 4;
+            __IOM uint32_t ALFSEL9         : 4;
+            __IOM uint32_t ALFSEL10        : 4;
+            __IOM uint32_t ALFSEL11        : 4;
+            __IOM uint32_t ALFSEL12        : 4;
+            __IOM uint32_t ALFSEL13        : 4;
+            __IOM uint32_t ALFSEL14        : 4;
+            __IOM uint32_t ALFSEL15        : 4;
+        } ALFH_B;
+    };
+} GPIO_T;
+
+/**
+ * @brief Reset and clock management unit (RCM)
+ */
+typedef struct
+{
+    /** Clock control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t HSIEN           : 1;
+            __IM  uint32_t HSIRDYFLG       : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t HSITRIM         : 5;
+            __IM  uint32_t HSICAL          : 8;
+            __IOM uint32_t HSEEN           : 1;
+            __IM  uint32_t HSERDYFLG       : 1;
+            __IOM uint32_t HSEBCFG         : 1;
+            __IOM uint32_t CSSEN           : 1;
+            __IM  uint32_t RESERVED2       : 4;
+            __IOM uint32_t PLL1EN          : 1;
+            __IM  uint32_t PLL1RDYFLG      : 1;
+            __IOM uint32_t PLL2EN          : 1;
+            __IM  uint32_t PLL2RDYFLG      : 1;
+            __IM  uint32_t RESERVED3       : 4;
+        } CTRL_B;
+    };
+
+    /** PLL1 configuration register */
+    union
+    {
+        __IOM uint32_t PLL1CFG;
+
+        struct
+        {
+            __IOM uint32_t PLLB            : 6;
+            __IOM uint32_t PLL1A           : 9;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t PLL1C           : 2;
+            __IM  uint32_t RESERVED2       : 4;
+            __IOM uint32_t PLL1CLKS        : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t PLLD            : 4;
+            __IM  uint32_t RESERVED4       : 4;
+        } PLL1CFG_B;
+    } ;
+
+    /** Clock configuration register */
+    union
+    {
+        __IOM uint32_t CFG;
+
+        struct
+        {
+            __IOM uint32_t SCLKSEL         : 2;
+            __IM  uint32_t SCLKSWSTS       : 2;
+            __IOM uint32_t AHBPSC          : 4;
+            __IOM uint32_t SDRAMPSC        : 2;
+            __IOM uint32_t APB1PSC         : 3;
+            __IOM uint32_t APB2PSC         : 3;
+            __IOM uint32_t RTCPSC          : 5;
+            __IOM uint32_t MCO1SEL         : 2;
+            __IOM uint32_t I2SSEL          : 1;
+            __IOM uint32_t MCO1PRE         : 3;
+            __IOM uint32_t MCO2PRE         : 3;
+            __IOM uint32_t MCO2SEL         : 2;
+        } CFG_B;
+    } ;
+
+    /** Clock interrupt control register */
+    union
+    {
+        __IOM uint32_t INT;
+
+        struct
+        {
+            __IM  uint32_t LSIRDYFLG       : 1;
+            __IM  uint32_t LSERDYFLG       : 1;
+            __IM  uint32_t HSIRDYFLG       : 1;
+            __IM  uint32_t HSERDYFLG       : 1;
+            __IM  uint32_t PLL1RDYFLG      : 1;
+            __IM  uint32_t PLL2RDYFLG      : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IM  uint32_t CSSFLG          : 1;
+            __IOM uint32_t LSIRDYEN        : 1;
+            __IOM uint32_t LSERDYEN        : 1;
+            __IOM uint32_t HSIRDYEN        : 1;
+            __IOM uint32_t HSERDYEN        : 1;
+            __IOM uint32_t PLL1RDYEN       : 1;
+            __IOM uint32_t PLL2RDYEN       : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __OM  uint32_t LSIRDYCLR       : 1;
+            __OM  uint32_t LSERDYCLR       : 1;
+            __OM  uint32_t HSIRDYCLR       : 1;
+            __OM  uint32_t HSERDYCLR       : 1;
+            __OM  uint32_t PLL1RDYCLR      : 1;
+            __OM  uint32_t PLL2RDYCLR      : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __OM  uint32_t CSSCLR          : 1;
+            __IM  uint32_t RESERVED4       : 8;
+        } INT_B;
+    } ;
+
+    /** AHB1 peripheral reset register */
+    union
+    {
+        __IOM uint32_t AHB1RST;
+
+        struct
+        {
+            __IOM uint32_t PARST           : 1;
+            __IOM uint32_t PBRST           : 1;
+            __IOM uint32_t PCRST           : 1;
+            __IOM uint32_t PDRST           : 1;
+            __IOM uint32_t PERST           : 1;
+            __IOM uint32_t PFRST           : 1;
+            __IOM uint32_t PGRST           : 1;
+            __IOM uint32_t PHRST           : 1;
+            __IOM uint32_t PIRST           : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t CRCRST          : 1;
+            __IM  uint32_t RESERVED2       : 8;
+            __IOM uint32_t DMA1RST         : 1;
+            __IOM uint32_t DMA2RST         : 1;
+            __IM  uint32_t RESERVED3       : 2;
+            __IOM uint32_t ETHRST          : 1;
+            __IM  uint32_t RESERVED4       : 3;
+            __IOM uint32_t OTG_HS1RST        : 1;
+            __IM  uint32_t RESERVED5       : 2;
+        } AHB1RST_B;
+    } ;
+
+    /** AHB2 peripheral reset register */
+    union
+    {
+        __IOM uint32_t AHB2RST;
+
+        struct
+        {
+            __IOM uint32_t DCIRST          : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t CRYPRST         : 1;
+            __IOM uint32_t HASHP           : 1;
+            __IOM uint32_t RNGRST          : 1;
+            __IOM uint32_t OTG_FSRST        : 1;
+            __IM  uint32_t RESERVED2       : 24;
+        } AHB2RST_B;
+    } ;
+
+    /** AHB3 peripheral reset register */
+    union
+    {
+        __IOM uint32_t AHB3RST;
+
+        struct
+        {
+            __IOM uint32_t EMMCRST         : 1;
+            __IM  uint32_t RESERVED        : 31;
+        } AHB3RST_B;
+    } ;
+
+    __IM  uint32_t  RESERVED;
+
+    /** APB1 peripheral reset register */
+    union
+    {
+        __IOM uint32_t APB1RST;
+
+        struct
+        {
+            __IOM uint32_t TMR2RST         : 1;
+            __IOM uint32_t TMR3RST         : 1;
+            __IOM uint32_t TMR4RST         : 1;
+            __IOM uint32_t TMR5RST         : 1;
+            __IOM uint32_t TMR6RST         : 1;
+            __IOM uint32_t TMR7RST         : 1;
+            __IOM uint32_t TMR12RST        : 1;
+            __IOM uint32_t TMR13RST        : 1;
+            __IOM uint32_t TMR14RST        : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t WWDTRST         : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t SPI2RST         : 1;
+            __IOM uint32_t SPI3RST         : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t USART2RST       : 1;
+            __IOM uint32_t USART3RST       : 1;
+            __IOM uint32_t UART4RST        : 1;
+            __IOM uint32_t UART5RST        : 1;
+            __IOM uint32_t I2C1RST         : 1;
+            __IOM uint32_t I2C2RST         : 1;
+            __IOM uint32_t I2C3RST         : 1;
+            __IM  uint32_t RESERVED4       : 1;
+            __IOM uint32_t CAN1RST         : 1;
+            __IM  uint32_t CAN2RST         : 1;
+            __IM  uint32_t RESERVED5       : 1;
+            __IOM uint32_t PMURST          : 1;
+            __IOM uint32_t DACRST          : 1;
+            __IM  uint32_t RESERVED6       : 2;
+        } APB1RST_B;
+    } ;
+
+    /** APB2 peripheral reset register */
+    union
+    {
+        __IOM uint32_t APB2RST;
+
+        struct
+        {
+            __IOM uint32_t TMR1RST         : 1;
+            __IOM uint32_t TMR8RST         : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t USART1RST       : 1;
+            __IOM uint32_t USART6RST       : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t ADCRST          : 1;
+            __IM  uint32_t RESERVED3       : 2;
+            __IOM uint32_t SDIORST         : 1;
+            __IOM uint32_t SPI1RST         : 1;
+            __IM  uint32_t RESERVED4       : 1;
+            __IOM uint32_t SYSCFGRST       : 1;
+            __IM  uint32_t RESERVED5       : 1;
+            __IOM uint32_t TMR9RST         : 1;
+            __IOM uint32_t TMR10RST        : 1;
+            __IOM uint32_t TMR11RST        : 1;
+            __IM  uint32_t RESERVED6       : 13;
+        } APB2RST_B;
+    } ;
+
+    __IM  uint32_t  RESERVED1[2];
+
+    /** AHB1 clock enable register */
+    union
+    {
+        __IOM uint32_t AHB1CLKEN;
+
+        struct
+        {
+            __IOM uint32_t PAEN            : 1;
+            __IOM uint32_t PBEN            : 1;
+            __IOM uint32_t PCEN            : 1;
+            __IOM uint32_t PDEN            : 1;
+            __IOM uint32_t PEEN            : 1;
+            __IOM uint32_t PFEN            : 1;
+            __IOM uint32_t PGEN            : 1;
+            __IOM uint32_t PHEN            : 1;
+            __IOM uint32_t PIEN            : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t CRCEN           : 1;
+            __IM  uint32_t RESERVED2       : 5;
+            __IOM uint32_t BAKPSRAMEN      : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t DRAMEN          : 1;
+            __IOM uint32_t DMA1EN          : 1;
+            __IOM uint32_t DMA2EN          : 1;
+            __IM  uint32_t RESERVED4       : 2;
+            __IOM uint32_t ETHEN           : 1;
+            __IOM uint32_t ETHTXEN         : 1;
+            __IOM uint32_t ETHRXEN         : 1;
+            __IOM uint32_t ETHPTPEN        : 1;
+            __IOM uint32_t OTG_HS1EN         : 1;
+            __IOM uint32_t HSULPIEN        : 1;
+            __IM  uint32_t RESERVED5       : 1;
+        } AHB1CLKEN_B;
+    } ;
+
+    /** AHB2 clock enable register */
+    union
+    {
+        __IOM uint32_t AHB2CLKEN;
+
+        struct
+        {
+            __IOM uint32_t DCIEN           : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t CRYPEN          : 1;
+            __IOM uint32_t HASHP           : 1;
+            __IOM uint32_t RNGEN           : 1;
+            __IOM uint32_t OTG_FSEN         : 1;
+            __IM  uint32_t RESERVED2       : 24;
+        } AHB2CLKEN_B;
+    };
+
+    /** AHB3 peripheral enable register */
+    union
+    {
+        __IOM uint32_t AHB3CLKEN;
+
+        struct
+        {
+            __IOM uint32_t EMMCEN          : 1;
+            __IM  uint32_t RESERVED        : 31;
+        } AHB3CLKEN_B;
+    } ;
+
+    __IM  uint32_t  RESERVED2;
+
+    /** APB1 peripheral enable register */
+    union
+    {
+        __IOM uint32_t APB1CLKEN;
+
+        struct
+        {
+            __IOM uint32_t TMR2EN          : 1;
+            __IOM uint32_t TMR3EN          : 1;
+            __IOM uint32_t TMR4EN          : 1;
+            __IOM uint32_t TMR5EN          : 1;
+            __IOM uint32_t TMR6EN          : 1;
+            __IOM uint32_t TMR7EN          : 1;
+            __IOM uint32_t TMR12EN         : 1;
+            __IOM uint32_t TMR13EN         : 1;
+            __IOM uint32_t TMR14EN         : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t WWDTEN          : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t SPI2EN          : 1;
+            __IOM uint32_t SPI3EN          : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t USART2EN        : 1;
+            __IOM uint32_t USART3EN        : 1;
+            __IOM uint32_t UART4EN         : 1;
+            __IOM uint32_t UART5EN         : 1;
+            __IOM uint32_t I2C1EN          : 1;
+            __IOM uint32_t I2C2EN          : 1;
+            __IOM uint32_t I2C3EN          : 1;
+            __IM  uint32_t RESERVED4       : 1;
+            __IOM uint32_t CAN1EN          : 1;
+            __IM  uint32_t CAN2EN          : 1;
+            __IM  uint32_t RESERVED5       : 1;
+            __IOM uint32_t PMUEN           : 1;
+            __IOM uint32_t DACEN           : 1;
+            __IM  uint32_t RESERVED6       : 2;
+        } APB1CLKEN_B;
+    } ;
+
+    /** APB2 peripheral enable register */
+    union
+    {
+        __IOM uint32_t APB2CLKEN;
+
+        struct
+        {
+            __IOM uint32_t TMR1EN          : 1;
+            __IOM uint32_t TMR8EN          : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t USART1EN        : 1;
+            __IOM uint32_t USART6EN        : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t ADC1EN          : 1;
+            __IOM uint32_t ADC2EN          : 1;
+            __IOM uint32_t ADC3EN          : 1;
+            __IOM uint32_t SDIOEN          : 1;
+            __IOM uint32_t SPI1EN          : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t SYSCFGEN        : 1;
+            __IM  uint32_t RESERVED4       : 1;
+            __IOM uint32_t TMR9EN          : 1;
+            __IOM uint32_t TMR10EN         : 1;
+            __IOM uint32_t TMR11EN         : 1;
+            __IM  uint32_t RESERVED5       : 13;
+        } APB2CLKEN_B;
+    } ;
+
+    __IM  uint32_t  RESERVED3[2];
+
+    /** AHB1 clock enable register during lowpower mode */
+    union
+    {
+        __IOM uint32_t LPAHB1CLKEN;
+
+        struct
+        {
+            __IOM uint32_t PAEN            : 1;
+            __IOM uint32_t PBEN            : 1;
+            __IOM uint32_t PCEN            : 1;
+            __IOM uint32_t PDEN            : 1;
+            __IOM uint32_t PEEN            : 1;
+            __IOM uint32_t PFEN            : 1;
+            __IOM uint32_t PGEN            : 1;
+            __IOM uint32_t PHEN            : 1;
+            __IOM uint32_t PIEN            : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t CRCEN           : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t FMCEN           : 1;
+            __IOM uint32_t SRAM1EN         : 1;
+            __IOM uint32_t SRAM2EN         : 1;
+            __IOM uint32_t BAKPSRAMEN      : 1;
+            __IM  uint32_t RESERVED3       : 2;
+            __IOM uint32_t DMA1EN          : 1;
+            __IOM uint32_t DMA2EN          : 1;
+            __IM  uint32_t RESERVED4       : 2;
+            __IOM uint32_t ETHEN           : 1;
+            __IOM uint32_t ETHTXEN         : 1;
+            __IOM uint32_t ETHRXEN         : 1;
+            __IOM uint32_t ETHPTPEN        : 1;
+            __IOM uint32_t OTG_HS1EN         : 1;
+            __IOM uint32_t HSULPIEN        : 1;
+            __IM  uint32_t RESERVED5       : 1;
+        } LPAHB1CLKEN_B;
+    } ;
+
+    /** AHB2 clock enable register during lowpower mode */
+    union
+    {
+        __IOM uint32_t LPAHB2CLKEN;
+
+        struct
+        {
+            __IOM uint32_t DCIEN           : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t CRYPEN          : 1;
+            __IOM uint32_t HASHPEN         : 1;
+            __IOM uint32_t RNGEN           : 1;
+            __IOM uint32_t OTG_FSEN         : 1;
+            __IM  uint32_t RESERVED2       : 24;
+        } LPAHB2CLKEN_B;
+    };
+
+    /** AHB3 peripheral enable register during lowpower mode */
+    union
+    {
+        __IOM uint32_t LPAHB3CLKEN;
+
+        struct
+        {
+            __IOM uint32_t EMMCEN          : 1;
+            __IM  uint32_t RESERVED        : 31;
+        } LPAHB3CLKEN_B;
+    } ;
+
+    __IM  uint32_t  RESERVED4;
+
+    /** APB1 peripheral enable register during lowpower mode */
+    union
+    {
+        __IOM uint32_t LPAPB1CLKEN;
+
+        struct
+        {
+            __IOM uint32_t TMR2EN          : 1;
+            __IOM uint32_t TMR3EN          : 1;
+            __IOM uint32_t TMR4EN          : 1;
+            __IOM uint32_t TMR5EN          : 1;
+            __IOM uint32_t TMR6EN          : 1;
+            __IOM uint32_t TMR7EN          : 1;
+            __IOM uint32_t TMR12EN         : 1;
+            __IOM uint32_t TMR13EN         : 1;
+            __IOM uint32_t TMR14EN         : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t WWDTEN          : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t SPI2EN          : 1;
+            __IOM uint32_t SPI3EN          : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t USART2EN        : 1;
+            __IOM uint32_t USART3EN        : 1;
+            __IOM uint32_t UART4EN         : 1;
+            __IOM uint32_t UART5EN         : 1;
+            __IOM uint32_t I2C1EN          : 1;
+            __IOM uint32_t I2C2EN          : 1;
+            __IOM uint32_t I2C3EN          : 1;
+            __IM  uint32_t RESERVED4       : 1;
+            __IOM uint32_t CAN1EN          : 1;
+            __IM  uint32_t CAN2EN          : 1;
+            __IM  uint32_t RESERVED5       : 1;
+            __IOM uint32_t PMUEN           : 1;
+            __IOM uint32_t DACEN           : 1;
+            __IM  uint32_t RESERVED6       : 2;
+        } LPAPB1CLKEN_B;
+    } ;
+
+    /** APB2 peripheral enable register during lowpower mode */
+    union
+    {
+        __IOM uint32_t LPAPB2CLKEN;
+
+        struct
+        {
+            __IOM uint32_t TMR1EN          : 1;
+            __IOM uint32_t TMR8EN          : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t USART1EN        : 1;
+            __IOM uint32_t USART6EN        : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t ADC1EN          : 1;
+            __IOM uint32_t ADC2EN          : 1;
+            __IOM uint32_t ADC3EN          : 1;
+            __IOM uint32_t SDIOEN          : 1;
+            __IOM uint32_t SPI1EN          : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t SYSCFGEN        : 1;
+            __IM  uint32_t RESERVED4       : 1;
+            __IOM uint32_t TMR9EN          : 1;
+            __IOM uint32_t TMR10EN         : 1;
+            __IOM uint32_t TMR11EN         : 1;
+            __IM  uint32_t RESERVED5       : 13;
+        } LPAPB2CLKEN_B;
+    } ;
+
+    __IM  uint32_t  RESERVED5[2];
+
+    /** Backup domain control register */
+    union
+    {
+        __IOM uint32_t BDCTRL;
+
+        struct
+        {
+            __IOM uint32_t LSEEN           : 1;
+            __IM  uint32_t LSERDYFLG       : 1;
+            __IOM uint32_t LSEBCFG         : 1;
+            __IM  uint32_t RESERVED1       : 5;
+            __IOM uint32_t RTCSRCSEL       : 2;
+            __IM  uint32_t RESERVED2       : 5;
+            __IOM uint32_t RTCCLKEN        : 1;
+            __IOM uint32_t BDRST           : 1;
+            __IM  uint32_t RESERVED3       : 15;
+        } BDCTRL_B;
+    } ;
+
+    /** Control/status register */
+    union
+    {
+        __IOM uint32_t CSTS;
+
+        struct
+        {
+            __IOM uint32_t LSIEN           : 1;
+            __IM  uint32_t LSIRDYFLG       : 1;
+            __IM  uint32_t RESERVED        : 22;
+            __IOM uint32_t RSTFLGCLR       : 1;
+            __IM  uint32_t BORRSTFLG       : 1;
+            __IM  uint32_t PINRSTFLG       : 1;
+            __IM  uint32_t PODRSTFLG       : 1;
+            __IM  uint32_t SWRSTFLG        : 1;
+            __IM  uint32_t IWDTRSTFLG      : 1;
+            __IM  uint32_t WWDTRSTFLG      : 1;
+            __IM  uint32_t LPWRRSTFLG      : 1;
+        } CSTS_B;
+    } ;
+
+    __IM  uint32_t  RESERVED6[2];
+
+    /** spread spectrum clock generation register */
+    union
+    {
+        __IOM uint32_t SSCCFG;
+
+        struct
+        {
+            __IOM uint32_t MODPCFG         : 13;
+            __IOM uint32_t STEP            : 15;
+            __IM  uint32_t RESERVED        : 2;
+            __IOM uint32_t SSSEL           : 1;
+            __IM  uint32_t SSEN            : 1;
+        } SSCCFG_B;
+    } ;
+
+    /** PLL2 configuration register */
+    union
+    {
+        __IOM uint32_t PLL2CFG;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 6;
+            __IOM uint32_t PLL2A           : 9;
+            __IM  uint32_t RESERVED2       : 13;
+            __IOM uint32_t PLL2C           : 3;
+            __IM  uint32_t RESERVED3       : 1;
+        } PLL2CFG_B;
+    } ;
+} RCM_T;
+
+/**
+ * @brief Universal synchronous asynchronous receiver transmitter (USART)
+ */
+typedef struct
+{
+    /** Status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IM  uint32_t PEFLG           : 1;
+            __IM  uint32_t FEFLG           : 1;
+            __IM  uint32_t NEFLG           : 1;
+            __IM  uint32_t OVREFLG         : 1;
+            __IM  uint32_t IDLEFLG         : 1;
+            __IOM uint32_t RXBNEFLG        : 1;
+            __IOM uint32_t TXCFLG          : 1;
+            __IM  uint32_t TXBEFLG         : 1;
+            __IOM uint32_t LBDFLG          : 1;
+            __IOM uint32_t CTSFLG          : 1;
+            __IM  uint32_t RESERVED        : 22;
+        } STS_B;
+    } ;
+
+    /** TX Buffer Data Register */
+    union
+    {
+        __IOM uint32_t DATA;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 9;
+            __IM  uint32_t RESERVED        : 23;
+        } DATA_B;
+    } ;
+
+    /** Baud rate register */
+    union
+    {
+        __IOM uint32_t BR;
+
+        struct
+        {
+            __IOM uint32_t FBR             : 4;
+            __IOM uint32_t IBR             : 12;
+            __IM  uint32_t RESERVED        : 16;
+        } BR_B;
+    } ;
+
+    /** Control register 1 */
+    union
+    {
+        __IOM uint32_t CTRL1;
+
+        struct
+        {
+            __IOM uint32_t TXBF            : 1;
+            __IOM uint32_t RXMUTEEN        : 1;
+            __IOM uint32_t RXEN            : 1;
+            __IOM uint32_t TXEN            : 1;
+            __IOM uint32_t IDLEIEN         : 1;
+            __IOM uint32_t RXBNEIEN        : 1;
+            __IOM uint32_t TXCIEN          : 1;
+            __IOM uint32_t TXBEIEN         : 1;
+            __IOM uint32_t PEIEN           : 1;
+            __IOM uint32_t PCFG            : 1;
+            __IOM uint32_t PCEN            : 1;
+            __IOM uint32_t WUPMCFG         : 1;
+            __IOM uint32_t DBLCFG          : 1;
+            __IOM uint32_t UEN             : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t OSMCFG          : 1;
+            __IM  uint32_t RESERVED2       : 16;
+        } CTRL1_B;
+    } ;
+
+    /** Control register 2 */
+    union
+    {
+        __IOM uint32_t CTRL2;
+
+        struct
+        {
+            __IOM uint32_t ADDR            : 4;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t LBDLCFG         : 1;
+            __IOM uint32_t LBDIEN          : 1;
+            __IM  uint32_t RESERVED2       : 1;
+            __IOM uint32_t LBCPOEN         : 1;
+            __IOM uint32_t CPHA            : 1;
+            __IOM uint32_t CPOL            : 1;
+            __IOM uint32_t CLKEN           : 1;
+            __IOM uint32_t STOPCFG         : 2;
+            __IOM uint32_t LINMEN          : 1;
+            __IM  uint32_t RESERVED3       : 17;
+        } CTRL2_B;
+    } ;
+
+    /** Control register 3 */
+    union
+    {
+        __IOM uint32_t CTRL3;
+
+        struct
+        {
+            __IOM uint32_t ERRIEN          : 1;
+            __IOM uint32_t IREN            : 1;
+            __IOM uint32_t IRLPEN          : 1;
+            __IOM uint32_t HDEN            : 1;
+            __IOM uint32_t SCNACKEN        : 1;
+            __IOM uint32_t SCEN            : 1;
+            __IOM uint32_t DMARXEN         : 1;
+            __IOM uint32_t DMATXEN         : 1;
+            __IOM uint32_t RTSEN           : 1;
+            __IOM uint32_t CTSEN           : 1;
+            __IOM uint32_t CTSIEN          : 1;
+            __IOM uint32_t SAMCFG          : 1;
+            __IM  uint32_t RESERVED        : 20;
+        } CTRL3_B;
+    } ;
+
+    /** Guard TMRe and divider number register */
+    union
+    {
+        __IOM uint32_t GTPSC;
+
+        struct
+        {
+            __IOM uint32_t PSC             : 8;
+            __IOM uint32_t GRDT            : 8;
+            __IM  uint32_t RESERVED        : 16;
+        } GTPSC_B;
+    } ;
+} USART_T;
+
+/**
+  * @brief FLASH Registers (FMC)
+  */
+
+typedef struct
+{
+
+    /** Flash access control register  */
+    union
+    {
+        __IOM uint32_t ACCTRL;
+
+        struct
+        {
+            __IOM uint32_t WAITP      : 3;
+            __IM  uint32_t RESERVED1  : 5;
+            __IOM uint32_t PREFEN     : 1;
+            __IOM uint32_t ICACHEEN   : 1;
+            __IOM uint32_t DCACHEEN   : 1;
+            __OM  uint32_t ICACHERST  : 1;
+            __IOM uint32_t DCACHERST  : 1;
+            __IM  uint32_t RESERVED2  : 19;
+        } ACCTRL_B;
+    } ;
+
+    /** Flash key register  */
+    union
+    {
+        __OM  uint32_t KEY;
+
+        struct
+        {
+            __OM  uint32_t KEY        : 32;
+        } KEY_B;
+    } ;
+
+    /** Flash option key register   */
+    union
+    {
+        __OM   uint32_t OPTKEY;
+
+        struct
+        {
+            __OM  uint32_t OPTKEY      : 32;
+        } OPTKEY_B;
+    } ;
+
+    /** Flash status register  */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IOM uint32_t OPRCMP     : 1;
+            __IOM uint32_t OPRERR     : 1;
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t WPROTERR   : 1;
+            __IOM uint32_t PGALGERR   : 1;
+            __IOM uint32_t PGPRLERR   : 1;
+            __IOM uint32_t PGSEQERR   : 1;
+            __IM  uint32_t RESERVED2  : 8;
+            __IM  uint32_t BUSY       : 1;
+            __IM  uint32_t RESERVED3  : 15;
+        } STS_B;
+    } ;
+
+    /** Flash control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t PG         : 1;
+            __IOM uint32_t SERS       : 1;
+            __IOM uint32_t MERS       : 1;
+            __IOM uint32_t SNUM       : 4;
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t PGSIZE     : 2;
+            __IM  uint32_t RESERVED2  : 6;
+            __IOM uint32_t START      : 1;
+            __IM  uint32_t RESERVED3  : 7;
+            __IOM uint32_t OPCINTEN   : 1;
+            __IOM uint32_t ERRINTEN   : 1;
+            __IM  uint32_t RESERVED4  : 5;
+            __IOM uint32_t LOCK       : 1;
+        } CTRL_B;
+    } ;
+
+    /** Option byte register */
+    union
+    {
+        __IOM  uint32_t OPTCTRL;
+
+        struct
+        {
+            __IOM uint32_t OPTLOCK    : 1;
+            __IOM uint32_t OPTSTART   : 1;
+            __IOM uint32_t BORLVL     : 2;
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t WDTSEL     : 1;
+            __IOM uint32_t RSTSTOP    : 1;
+            __IOM uint32_t RSTSTDB    : 1;
+            __IOM uint32_t RPROT      : 8;
+            __IOM uint32_t NWPROT     : 12;
+            __IM  uint32_t RESERVED2  : 4;
+        } OPTCTRL_B;
+    } ;
+} FMC_T;
+
+/**
+ * @brief  CRC calculation unit (CRC)
+ */
+typedef struct
+{
+    /** @brief  DATA register */
+    union
+    {
+        __IOM uint32_t DATA;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 32;
+        } DATA_B;
+    } ;
+
+    /** @brief independent DATA register */
+    union
+    {
+        __IOM  uint32_t INDATA;
+
+        struct
+        {
+            __IOM uint32_t INDATA          : 8;
+            __IM  uint32_t RESERVED        : 24;
+        } INDATA_B;
+    };
+
+    /** @brief Countrol register */
+    union
+    {
+        __OM uint32_t CTRL;
+
+        struct
+        {
+            __OM  uint32_t RST             : 1;
+            __IM  uint32_t RESERVED        : 31;
+        } CTRL_B;
+    };
+} CRC_T;
+
+/**
+  * @brief Real-time clock (RTC)
+  */
+typedef struct
+{
+
+    /** time register */
+    union
+    {
+        __IOM uint32_t TIME;
+
+        struct
+        {
+            __IOM uint32_t SECU       : 4;
+            __IOM uint32_t SECT       : 3;
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t MINU       : 4;
+            __IOM uint32_t MINT       : 3;
+            __IM  uint32_t RESERVED2  : 1;
+            __IOM uint32_t HRU        : 4;
+            __IOM uint32_t HRT        : 2;
+            __IOM uint32_t TIMEFCFG   : 1;
+            __IM  uint32_t RESERVED3  : 9;
+        } TIME_B;
+    } ;
+
+    /** date register */
+    union
+    {
+        __IOM uint32_t DATE;
+
+        struct
+        {
+            __IOM uint32_t DAYU       : 4;
+            __IOM uint32_t DAYT       : 2;
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t MONU       : 4;
+            __IOM uint32_t MONT       : 1;
+            __IOM uint32_t WEEKSEL    : 3;
+            __IOM uint32_t YRU        : 4;
+            __IOM uint32_t YRT        : 4;
+            __IM  uint32_t RESERVED2  : 8;
+        } DATE_B;
+    } ;
+
+    /** control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t WUCLKSEL   : 3;
+            __IOM uint32_t TSETECFG   : 1;
+            __IOM uint32_t RCLKDEN    : 1;
+            __IOM uint32_t RCMCFG     : 1;
+            __IOM uint32_t TIMEFCFG   : 1;
+            __IOM uint32_t DCALEN     : 1;
+            __IOM uint32_t ALRAEN     : 1;
+            __IOM uint32_t ALRBEN     : 1;
+            __IOM uint32_t WUTEN      : 1;
+            __IOM uint32_t TSEN       : 1;
+            __IOM uint32_t ALRAIEN    : 1;
+            __IOM uint32_t ALRBIEN    : 1;
+            __IOM uint32_t WUTIEN     : 1;
+            __IOM uint32_t TSIEN      : 1;
+            __IOM uint32_t STCCFG     : 1;
+            __IOM uint32_t WTCCFG     : 1;
+            __IOM uint32_t BAKP       : 1;
+            __IOM uint32_t CALOSEL    : 1;
+            __IOM uint32_t POLCFG     : 1;
+            __IOM uint32_t OUTSEL     : 2;
+            __IOM uint32_t CALOEN     : 1;
+            __IM  uint32_t RESERVED1  : 8;
+        } CTRL_B;
+    } ;
+
+    /** initialization and status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IM  uint32_t ALRAWFLG   : 1;
+            __IM  uint32_t ALRBWFLG   : 1;
+            __IOM uint32_t WUTWFLG    : 1;
+            __IOM uint32_t SOPFLG     : 1;
+            __IM  uint32_t INITSFLG   : 1;
+            __IOM uint32_t RSFLG      : 1;
+            __IM  uint32_t RINITFLG   : 1;
+            __IOM uint32_t INITEN     : 1;
+            __IOM uint32_t ALRAFLG    : 1;
+            __IOM uint32_t ALRBFLG    : 1;
+            __IOM uint32_t WUTFLG     : 1;
+            __IOM uint32_t TSFLG      : 1;
+            __IOM uint32_t TSOVRFLG   : 1;
+            __IOM uint32_t TP1FLG     : 1;
+            __IOM uint32_t TP2FLG     : 1;
+            __IM  uint32_t RESERVED1  : 1;
+            __IM  uint32_t RCALPFLG   : 1;
+            __IM  uint32_t RESERVED2  : 15;
+        } STS_B;
+    } ;
+
+    /** prescaler register */
+    union
+    {
+        __IOM uint32_t PSC;
+
+        struct
+        {
+            __IOM uint32_t SPSC       : 15;
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t APSC       : 7;
+            __IM  uint32_t RESERVED2  : 9;
+        } PSC_B;
+    } ;
+
+    /** auto-reload register */
+    union
+    {
+        __IOM uint32_t AUTORLD;
+
+        struct
+        {
+            __IOM uint32_t WUAUTORE   : 16;
+            __IM  uint32_t RESERVED   : 16;
+        } AUTORLD_B;
+    } ;
+
+    /** calibration register */
+    union
+    {
+        __IOM uint32_t DCAL;
+
+        struct
+        {
+            __IOM uint32_t DCAL       : 5;
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t DCALCFG    : 1;
+            __IM  uint32_t RESERVED2  : 24;
+        } DCAL_B;
+    } ;
+
+    /** alarm A register */
+    union
+    {
+        __IOM uint32_t ALRMA;
+
+        struct
+        {
+            __IOM uint32_t SECU       : 4;
+            __IOM uint32_t SECT       : 3;
+            __IOM uint32_t SECMEN     : 1;
+            __IOM uint32_t MINU       : 4;
+            __IOM uint32_t MINT       : 3;
+            __IOM uint32_t MINMEN     : 1;
+            __IOM uint32_t HRU        : 4;
+            __IOM uint32_t HRT        : 2;
+            __IOM uint32_t TIMEFCFG   : 1;
+            __IOM uint32_t HRMEN      : 1;
+            __IOM uint32_t DAYU       : 4;
+            __IOM uint32_t DAYT       : 2;
+            __IOM uint32_t WEEKSEL    : 1;
+            __IOM uint32_t DATEMEN    : 1;
+        } ALRMA_B;
+    } ;
+
+    /** alarm B register */
+    union
+    {
+        __IOM uint32_t ALRMB;
+
+        struct
+        {
+            __IOM uint32_t SECU       : 4;
+            __IOM uint32_t SECT       : 3;
+            __IOM uint32_t SECMEN     : 1;
+            __IOM uint32_t MINU       : 4;
+            __IOM uint32_t MINT       : 3;
+            __IOM uint32_t MINMEN     : 1;
+            __IOM uint32_t HRU        : 4;
+            __IOM uint32_t HRT        : 2;
+            __IOM uint32_t TIMEFCFG   : 1;
+            __IOM uint32_t HRMEN      : 1;
+            __IOM uint32_t DAYU       : 4;
+            __IOM uint32_t DAYT       : 2;
+            __IOM uint32_t WEEKSEL    : 1;
+            __IOM uint32_t DATEMEN    : 1;
+        } ALRMB_B;
+    } ;
+
+    /** write protection register */
+    union
+    {
+        __OM  uint32_t WRPROT;
+
+        struct
+        {
+            __OM  uint32_t KEY        : 16;
+            __IM  uint32_t RESERVED   : 16;
+        } WRPROT_B;
+    } ;
+
+    /** sub second register */
+    union
+    {
+        __IM  uint32_t SUBSEC;
+
+        struct
+        {
+            __IM  uint32_t SUBSEC     : 16;
+            __IM  uint32_t RESERVED   : 16;
+        } SUBSEC_B;
+    } ;
+
+    /** shift control register */
+    union
+    {
+        __OM  uint32_t SHIFT;
+
+        struct
+        {
+            __OM  uint32_t SFSEC      : 15;
+            __IM  uint32_t RESERVED   : 16;
+            __OM  uint32_t ADD1SECEN  : 1;
+        } SHIFT_B;
+    } ;
+
+    /** timestamp time register */
+    union
+    {
+        __IM  uint32_t TSTIME;
+
+        struct
+        {
+            __IM  uint32_t SECU       : 4;
+            __IM  uint32_t SECT       : 3;
+            __IM  uint32_t RESERVED1  : 1;
+            __IM  uint32_t MINU       : 4;
+            __IM  uint32_t MINT       : 3;
+            __IM  uint32_t RESERVED2  : 1;
+            __IM  uint32_t HRU        : 4;
+            __IM  uint32_t HRT        : 2;
+            __IM  uint32_t TIMEFCFG   : 1;
+            __IM  uint32_t RESERVED3  : 9;
+        } TSTIME_B;
+    } ;
+
+    /** timestamp date register */
+    union
+    {
+        __IM  uint32_t TSDATE;
+
+        struct
+        {
+            __IM  uint32_t DAYU       : 4;
+            __IM  uint32_t DAYT       : 2;
+            __IM  uint32_t RESERVED1  : 2;
+            __IM  uint32_t MONU       : 4;
+            __IM  uint32_t MONT       : 1;
+            __IM  uint32_t WEEKSEL    : 3;
+            __IM  uint32_t RESERVED2  : 16;
+        } TSDATE_B;
+    } ;
+
+    /** time-stamp sub second register */
+    union
+    {
+        __IM  uint32_t TSSUBSEC;
+
+        struct
+        {
+            __IM  uint32_t SUBSEC     : 16;
+            __IM  uint32_t RESERVED1  : 16;
+        } TSSUBSEC_B;
+    } ;
+
+    /** calibration register */
+    union
+    {
+        __IOM uint32_t CAL;
+
+        struct
+        {
+            __IOM uint32_t RECALF     : 9;
+            __IM  uint32_t RESERVED1  : 4;
+            __IOM uint32_t CAL16CFG   : 1;
+            __IOM uint32_t CAL8CFG    : 1;
+            __IOM uint32_t ICALFEN    : 1;
+            __IM  uint32_t RESERVED2  : 16;
+        } CAL_B;
+    } ;
+
+    /** tamper and alternate function configuration register */
+    union
+    {
+        __IOM uint32_t TACFG;
+
+        struct
+        {
+            __IOM uint32_t TP1EN      : 1;
+            __IOM uint32_t TP1ALCFG   : 1;
+            __IOM uint32_t TPIEN      : 1;
+            __IOM uint32_t TP2EN      : 1;
+            __IOM uint32_t TP2ALCFG   : 1;
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t TPTSEN     : 1;
+            __IOM uint32_t TPSFSEL    : 3;
+            __IOM uint32_t TPFCSEL    : 2;
+            __IOM uint32_t TPPRDUSEL  : 2;
+            __IOM uint32_t TPPUDIS    : 1;
+            __IOM uint32_t TP1MSEL    : 1;
+            __IOM uint32_t TSMSEL     : 1;
+            __IOM uint32_t ALRMOT     : 1;
+            __IM  uint32_t RESERVED2  : 13;
+        } TACFG_B;
+    } ;
+
+    /** alarm A sub second register */
+    union
+    {
+        __IOM uint32_t ALRMASS;
+
+        struct
+        {
+            __IOM uint32_t SUBSEC     : 15;
+            __IM  uint32_t RESERVED1  : 9;
+            __IOM uint32_t MASKSEL    : 4;
+            __IM  uint32_t RESERVED2  : 4;
+        } ALRMASS_B;
+    } ;
+
+    /** alarm B sub second register */
+    union
+    {
+        __IOM uint32_t ALRMBSS;
+
+        struct
+        {
+            __IOM uint32_t SUBSEC     : 15;
+            __IM  uint32_t RESERVED1  : 9;
+            __IOM uint32_t MASKSEL    : 4;
+            __IM  uint32_t RESERVED2  : 4;
+        } ALRMBSS_B;
+    } ;
+
+    __IM  uint32_t  RESERVED;
+
+    /** backup register */
+    __IOM uint32_t BAKP[20];
+
+} RTC_T;
+
+/**
+ * @brief Power Management Unit(PMU)
+ */
+typedef struct
+{
+    /** @brief Control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t LPDSCFG         : 1;
+            __IOM uint32_t PDDSCFG         : 1;
+            __IOM uint32_t WUFLGCLR        : 1;
+            __IOM uint32_t SBFLGCLR        : 1;
+            __IOM uint32_t PVDEN           : 1;
+            __IOM uint32_t PLSEL           : 3;
+            __IOM uint32_t BPWEN           : 1;
+            __IOM uint32_t FPDSM           : 1;
+            __IM  uint32_t RESERVED1       : 4;
+            __IOM uint32_t VOSSEL          : 1;
+            __IM  uint32_t RESERVED2       : 17;
+        } CTRL_B;
+    };
+
+    /** @brief PMU Status register */
+    union
+    {
+        __IOM uint32_t CSTS;
+
+        struct
+        {
+            __IM  uint32_t WUEFLG          : 1;
+            __IM  uint32_t SBFLG           : 1;
+            __IM  uint32_t PVDOFLG         : 1;
+            __IM  uint32_t BKPRFLG         : 1;
+            __IM  uint32_t RESERVED1       : 4;
+            __IOM uint32_t WKUPCFG         : 1;
+            __IOM uint32_t BKPREN          : 1;
+            __IM  uint32_t RESERVED2       : 4;
+            __IOM uint32_t VOSRFLG         : 1;
+            __IM  uint32_t RESERVED3       : 17;
+        } CSTS_B;
+    };
+} PMU_T;
+
+/**
+ * @brief Timer register(TMR)
+ */
+typedef struct
+{
+    /** control register 1 */
+    union
+    {
+        __IOM uint32_t CTRL1;
+
+        struct
+        {
+            __IOM uint32_t CNTEN      : 1;
+            __IOM uint32_t UD         : 1;
+            __IOM uint32_t URSSEL     : 1;
+            __IOM uint32_t SPMEN      : 1;
+            __IOM uint32_t CNTDIR     : 1;
+            __IOM uint32_t CAMSEL     : 2;
+            __IOM uint32_t ARPEN      : 1;
+            __IOM uint32_t CLKDIV     : 2;
+            __IM  uint32_t RESERVED   : 22;
+        } CTRL1_B;
+    } ;
+
+    /** control register 2 */
+    union
+    {
+        __IOM uint32_t CTRL2;
+
+        struct
+        {
+            __IOM uint32_t CCPEN      : 1;
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t CCUSEL     : 1;
+            __IOM uint32_t CCDSEL     : 1;
+            __IOM uint32_t MMSEL      : 3;
+            __IOM uint32_t TI1SEL     : 1;
+            __IOM uint32_t OC1OIS     : 1;
+            __IOM uint32_t OC1NOIS    : 1;
+            __IOM uint32_t OC2OIS     : 1;
+            __IOM uint32_t OC2NOIS    : 1;
+            __IOM uint32_t OC3OIS     : 1;
+            __IOM uint32_t OC3NOIS    : 1;
+            __IOM uint32_t OC4OIS     : 1;
+            __IM  uint32_t RESERVED2  : 17;
+        } CTRL2_B;
+    } ;
+
+    /** slave mode control register */
+    union
+    {
+        __IOM uint32_t SMCTRL;
+
+        struct
+        {
+            __IOM uint32_t SMFSEL     : 3;
+            __IOM uint32_t OCCSEL     : 1;
+            __IOM uint32_t TRGSEL     : 3;
+            __IOM uint32_t MSMEN      : 1;
+            __IOM uint32_t ETFCFG     : 4;
+            __IOM uint32_t ETPCFG     : 2;
+            __IOM uint32_t ECEN       : 1;
+            __IOM uint32_t ETPOL      : 1;
+            __IM  uint32_t RESERVED   : 16;
+        } SMCTRL_B;
+    } ;
+
+    /** DMA/Interrupt enable register */
+    union
+    {
+        __IOM uint32_t DIEN;
+
+        struct
+        {
+            __IOM uint32_t UIEN       : 1;
+            __IOM uint32_t CC1IEN     : 1;
+            __IOM uint32_t CC2IEN     : 1;
+            __IOM uint32_t CC3IEN     : 1;
+            __IOM uint32_t CC4IEN     : 1;
+            __IOM uint32_t COMIEN     : 1;
+            __IOM uint32_t TRGIEN     : 1;
+            __IOM uint32_t BRKIEN     : 1;
+            __IOM uint32_t UDIEN      : 1;
+            __IOM uint32_t CC1DEN     : 1;
+            __IOM uint32_t CC2DEN     : 1;
+            __IOM uint32_t CC3DEN     : 1;
+            __IOM uint32_t CC4DEN     : 1;
+            __IOM uint32_t COMDEN     : 1;
+            __IOM uint32_t TRGDEN     : 1;
+            __IM  uint32_t RESERVED   : 17;
+        } DIEN_B;
+    } ;
+
+    /** status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IOM uint32_t UIFLG      : 1;
+            __IOM uint32_t CC1IFLG    : 1;
+            __IOM uint32_t CC2IFLG    : 1;
+            __IOM uint32_t CC3IFLG    : 1;
+            __IOM uint32_t CC4IFLG    : 1;
+            __IOM uint32_t COMIFLG    : 1;
+            __IOM uint32_t TRGIFLG    : 1;
+            __IOM uint32_t BRKIFLG    : 1;
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t CC1RCFLG   : 1;
+            __IOM uint32_t CC2RCFLG   : 1;
+            __IOM uint32_t CC3RCFLG   : 1;
+            __IOM uint32_t CC4RCFLG   : 1;
+            __IM  uint32_t RESERVED2  : 19;
+        } STS_B;
+    } ;
+
+    /** event generation register */
+    union
+    {
+        __OM  uint32_t CEG;
+
+        struct
+        {
+            __OM  uint32_t UEG        : 1;
+            __OM  uint32_t CC1EG      : 1;
+            __OM  uint32_t CC2EG      : 1;
+            __OM  uint32_t CC3EG      : 1;
+            __OM  uint32_t CC4EG      : 1;
+            __OM  uint32_t COMG       : 1;
+            __OM  uint32_t TEG        : 1;
+            __OM  uint32_t BEG        : 1;
+            __IM  uint32_t RESERVED   : 24;
+        } CEG_B;
+    } ;
+
+    /** @brief Capture the compare mode register 1 */
+    union
+    {
+        __IOM uint32_t CCM1;
+
+        /** @brief Compare mode */
+        struct
+        {
+            __IOM uint32_t CC1SEL          : 2;
+            __IOM uint32_t OC1FEN          : 1;
+            __IOM uint32_t OC1PEN          : 1;
+            __IOM uint32_t OC1MOD          : 3;
+            __IOM uint32_t OC1CEN          : 1;
+            __IOM uint32_t CC2SEL          : 2;
+            __IOM uint32_t OC2FEN          : 1;
+            __IOM uint32_t OC2PEN          : 1;
+            __IOM uint32_t OC2MOD          : 3;
+            __IOM uint32_t OC2CEN          : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } CCM1_COMPARE_B;
+
+        /** @brief Capture mode */
+        struct
+        {
+            __IOM uint32_t CC1SEL          : 2;
+            __IOM uint32_t IC1PSC          : 2;
+            __IOM uint32_t IC1F            : 4;
+            __IOM uint32_t CC2SEL          : 2;
+            __IOM uint32_t IC2PSC          : 2;
+            __IOM uint32_t IC2F            : 4;
+            __IM  uint32_t RESERVED        : 16;
+        } CCM1_CAPTURE_B;
+    };
+
+    /** @brief Capture the compare mode register 2 */
+    union
+    {
+        __IOM uint32_t CCM2;
+
+        /** @brief Compare mode */
+        struct
+        {
+            __IOM uint32_t CC3SEL          : 2;
+            __IOM uint32_t OC3FEN          : 1;
+            __IOM uint32_t OC3PEN          : 1;
+            __IOM uint32_t OC3MOD          : 3;
+            __IOM uint32_t OC3CEN          : 1;
+            __IOM uint32_t CC4SEL          : 2;
+            __IOM uint32_t OC4FEN          : 1;
+            __IOM uint32_t OC4PEN          : 1;
+            __IOM uint32_t OC4MOD          : 3;
+            __IOM uint32_t OC4CEN          : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } CCM2_COMPARE_B;
+
+        /** @brief Capture mode */
+        struct
+        {
+            __IOM uint32_t CC3SEL          : 2;
+            __IOM uint32_t IC3PSC          : 2;
+            __IOM uint32_t IC3F            : 4;
+            __IOM uint32_t CC4SEL          : 2;
+            __IOM uint32_t IC4PSC          : 2;
+            __IOM uint32_t IC4F            : 4;
+            __IM  uint32_t RESERVED        : 16;
+        } CCM2_CAPTURE_B;
+    };
+
+    /** capture/compare enable register */
+    union
+    {
+        __IOM uint32_t CCEN;
+
+        struct
+        {
+            __IOM uint32_t CC1EN      : 1;
+            __IOM uint32_t CC1POL     : 1;
+            __IOM uint32_t CC1NEN     : 1;
+            __IOM uint32_t CC1NPOL    : 1;
+            __IOM uint32_t CC2EN      : 1;
+            __IOM uint32_t CC2POL     : 1;
+            __IOM uint32_t CC2NEN     : 1;
+            __IOM uint32_t CC2NPOL    : 1;
+            __IOM uint32_t CC3EN      : 1;
+            __IOM uint32_t CC3POL     : 1;
+            __IOM uint32_t CC3NEN     : 1;
+            __IOM uint32_t CC3NPOL    : 1;
+            __IOM uint32_t CC4EN      : 1;
+            __IOM uint32_t CC4POL     : 1;
+            __IM  uint32_t RESERVED   : 18;
+        } CCEN_B;
+    } ;
+
+    /** counter */
+    union
+    {
+        __IOM uint32_t CNT;
+
+        struct
+        {
+            __IOM uint32_t CNT        : 32;
+        } CNT_B;
+    } ;
+
+    /** prescaler */
+    union
+    {
+        __IOM uint32_t PSC;
+
+        struct
+        {
+            __IOM uint32_t PSC        : 16;
+            __IM  uint32_t RESERVED   : 16;
+        } PSC_B;
+    } ;
+
+    /** auto-reload register */
+    union
+    {
+        __IOM uint32_t AUTORLD;
+
+        struct
+        {
+            __IOM uint32_t AUTORLD    : 32;
+        } AUTORLD_B;
+    } ;
+
+    /** repetition counter register */
+    union
+    {
+        __IOM uint32_t REPCNT;
+
+        struct
+        {
+            __IOM uint32_t REPCNT     : 8;
+            __IM  uint32_t RESERVED   : 24;
+        } REPCNT_B;
+    } ;
+
+    /** capture/compare register 1 */
+    union
+    {
+        __IOM uint32_t CC1;
+
+        struct
+        {
+            __IOM uint32_t CC1        : 32;
+        } CC1_B;
+    } ;
+
+    /** capture/compare register 2 */
+    union
+    {
+        __IOM uint32_t CC2;
+
+        struct
+        {
+            __IOM uint32_t CC2        : 32;
+        } CC2_B;
+    } ;
+
+    /** capture/compare register 3 */
+    union
+    {
+        __IOM uint32_t CC3;
+
+        struct
+        {
+            __IOM uint32_t CC3        : 32;
+        } CC3_B;
+    } ;
+
+    /** capture/compare register 4 */
+    union
+    {
+        __IOM uint32_t CC4;
+
+        struct
+        {
+            __IOM uint32_t CC4        : 32;
+        } CC4_B;
+    } ;
+
+    /** break and dead-time register */
+    union
+    {
+        __IOM uint32_t BDT;
+
+        struct
+        {
+            __IOM uint32_t DTS        : 8;
+            __IOM uint32_t LOCKCFG    : 2;
+            __IOM uint32_t IMOS       : 1;
+            __IOM uint32_t RMOS       : 1;
+            __IOM uint32_t BRKEN      : 1;
+            __IOM uint32_t BRKPOL     : 1;
+            __IOM uint32_t AOEN       : 1;
+            __IOM uint32_t MOEN       : 1;
+            __IM  uint32_t RESERVED   : 16;
+        } BDT_B;
+    } ;
+
+    /** DMA control register */
+    union
+    {
+        __IOM uint32_t DCTRL;
+
+        struct
+        {
+            __IOM uint32_t DBADDR     : 5;
+            __IM  uint32_t RESERVED1  : 3;
+            __IOM uint32_t DBLEN      : 5;
+            __IM  uint32_t RESERVED2  : 19;
+        } DCTRL_B;
+    } ;
+
+    /** DMA address for full transfer */
+    union
+    {
+        __IOM uint32_t DMADDR;
+
+        struct
+        {
+            __IOM uint32_t DMADDR     : 32;
+        } DMADDR_B;
+    } ;
+
+    /** Remap */
+    union
+    {
+        __IOM uint32_t OPT;
+
+        struct
+        {
+            __IOM uint32_t RMPSEL     : 32;
+        } OPT_B;
+    } ;
+} TMR_T;
+
+/**
+ * @brief    Direct Memory Access register(DMA)
+ */
+typedef struct
+{
+    union
+    {
+        __IM uint32_t LINTSTS;
+
+        struct
+        {
+            __IM  uint32_t FEIFLG0        : 1;
+            __IM  uint32_t RESERVED1      : 1;
+            __IM  uint32_t DMEIFLG0       : 1;
+            __IM  uint32_t TXEIFLG0       : 1;
+            __IM  uint32_t HTXIFLG0       : 1;
+            __IM  uint32_t TXCIFLG0       : 1;
+            __IM  uint32_t FEIFLG1        : 1;
+            __IM  uint32_t RESERVED2      : 1;
+            __IM  uint32_t DMEIFLG1       : 1;
+            __IM  uint32_t TXEIFLG1       : 1;
+            __IM  uint32_t HTXIFLG1       : 1;
+            __IM  uint32_t TXCIFLG1       : 1;
+            __IM  uint32_t RESERVED3      : 4;
+            __IM  uint32_t FEIFLG2        : 1;
+            __IM  uint32_t RESERVED4      : 1;
+            __IM  uint32_t DMEIFLG2       : 1;
+            __IM  uint32_t TXEIFLG2       : 1;
+            __IM  uint32_t HTXIFLG2       : 1;
+            __IM  uint32_t TXCIFLG2       : 1;
+            __IM  uint32_t FEIFLG3        : 1;
+            __IM  uint32_t RESERVED5      : 1;
+            __IM  uint32_t DMEIFLG3       : 1;
+            __IM  uint32_t TXEIFLG3       : 1;
+            __IM  uint32_t HTXIFLG3       : 1;
+            __IM  uint32_t TXCIFLG3       : 1;
+            __IM  uint32_t RESERVED6      : 4;
+        } LINTSTS_B;
+    };
+
+    union
+    {
+        __IM uint32_t HINTSTS;
+
+        struct
+        {
+            __IM  uint32_t FEIFLG4        : 1;
+            __IM  uint32_t RESERVED1      : 1;
+            __IM  uint32_t DMEIFLG4       : 1;
+            __IM  uint32_t TXEIFLG4       : 1;
+            __IM  uint32_t HTXIFLG4       : 1;
+            __IM  uint32_t TXCIFLG4       : 1;
+            __IM  uint32_t FEIFLG5        : 1;
+            __IM  uint32_t RESERVED2      : 1;
+            __IM  uint32_t DMEIFLG5       : 1;
+            __IM  uint32_t TXEIFLG5       : 1;
+            __IM  uint32_t HTXIFLG5       : 1;
+            __IM  uint32_t TXCIFLG5       : 1;
+            __IM  uint32_t RESERVED3      : 4;
+            __IM  uint32_t FEIFLG6        : 1;
+            __IM  uint32_t RESERVED4      : 1;
+            __IM  uint32_t DMEIFLG6       : 1;
+            __IM  uint32_t TXEIFLG6       : 1;
+            __IM  uint32_t HTXIFLG6       : 1;
+            __IM  uint32_t TXCIFLG6       : 1;
+            __IM  uint32_t FEIFLG7        : 1;
+            __IM  uint32_t RESERVED5      : 1;
+            __IM  uint32_t DMEIFLG7       : 1;
+            __IM  uint32_t TXEIFLG7       : 1;
+            __IM  uint32_t HTXIFLG7       : 1;
+            __IM  uint32_t TXCIFLG7       : 1;
+            __IM  uint32_t RESERVED6      : 4;
+        } HINTSTS_B;
+    };
+
+    union
+    {
+        __OM uint32_t LIFCLR;
+
+        struct
+        {
+            __OM  uint32_t CFEIFLG0       : 1;
+            __IM  uint32_t RESERVED1      : 1;
+            __OM  uint32_t CDMEIFLG0      : 1;
+            __OM  uint32_t CTXEIFLG0      : 1;
+            __OM  uint32_t CHTXIFLG0      : 1;
+            __OM  uint32_t CTXCIFLG0      : 1;
+            __OM  uint32_t CFEIFLG1       : 1;
+            __IM  uint32_t RESERVED2      : 1;
+            __OM  uint32_t CDMEIFLG1      : 1;
+            __OM  uint32_t CTXEIFLG1      : 1;
+            __OM  uint32_t CHTXIFLG1      : 1;
+            __OM  uint32_t CTXCIFLG1      : 1;
+            __IM  uint32_t RESERVED3      : 4;
+            __OM  uint32_t CFEIFLG2       : 1;
+            __IM  uint32_t RESERVED4      : 1;
+            __OM  uint32_t CDMEIFLG2      : 1;
+            __OM  uint32_t CTXEIFLG2      : 1;
+            __OM  uint32_t CHTXIFLG2      : 1;
+            __OM  uint32_t CTXCIFLG2      : 1;
+            __OM  uint32_t CFEIFLG3       : 1;
+            __IM  uint32_t RESERVED5      : 1;
+            __OM  uint32_t CDMEIFLG3      : 1;
+            __OM  uint32_t CTXEIFLG3      : 1;
+            __OM  uint32_t CHTXIFLG3      : 1;
+            __OM  uint32_t CTXCIFLG3      : 1;
+            __IM  uint32_t RESERVED6      : 4;
+        } LIFCLR_B;
+    };
+
+    union
+    {
+        __OM uint32_t HIFCLR;
+
+        struct
+        {
+            __OM  uint32_t CFEIFLG4       : 1;
+            __IM  uint32_t RESERVED1      : 1;
+            __OM  uint32_t CDMEIFLG4      : 1;
+            __OM  uint32_t CTXEIFLG4      : 1;
+            __OM  uint32_t CHTXIFLG4      : 1;
+            __OM  uint32_t CTXCIFLG4      : 1;
+            __OM  uint32_t CFEIFLG5       : 1;
+            __IM  uint32_t RESERVED2      : 1;
+            __OM  uint32_t CDMEIFLG5      : 1;
+            __OM  uint32_t CTXEIFLG5      : 1;
+            __OM  uint32_t CHTXIFLG5      : 1;
+            __OM  uint32_t CTXCIFLG5      : 1;
+            __IM  uint32_t RESERVED3      : 4;
+            __OM  uint32_t CFEIFLG6       : 1;
+            __IM  uint32_t RESERVED4      : 1;
+            __OM  uint32_t CDMEIFLG6      : 1;
+            __OM  uint32_t CTXEIFLG6      : 1;
+            __OM  uint32_t CHTXIFLG6      : 1;
+            __OM  uint32_t CTXCIFLG6      : 1;
+            __OM  uint32_t CFEIFLG7       : 1;
+            __IM  uint32_t RESERVED5      : 1;
+            __OM  uint32_t CDMEIFLG7      : 1;
+            __OM  uint32_t CTXEIFLG7      : 1;
+            __OM  uint32_t CHTXIFLG7      : 1;
+            __OM  uint32_t CTXCIFLG7      : 1;
+            __IM  uint32_t RESERVED6      : 4;
+        } HIFCLR_B;
+    };
+} DMA_T;
+
+/**
+ * @brief DMA Stream register
+ */
+typedef struct
+{
+    union
+    {
+        __IOM uint32_t SCFG;
+
+        struct
+        {
+            __IOM uint32_t EN            : 1;
+            __IOM uint32_t DMEIEN        : 1;
+            __IOM uint32_t TXEIEN        : 1;
+            __IOM uint32_t HTXIEN        : 1;
+            __IOM uint32_t TXCIEN        : 1;
+            __IOM uint32_t PERFC         : 1;
+            __IOM uint32_t DIRCFG        : 2;
+            __IOM uint32_t CIRCMEN       : 1;
+            __IOM uint32_t PERIM         : 1;
+            __IOM uint32_t MEMIM         : 1;
+            __IOM uint32_t PERSIZECFG    : 2;
+            __IOM uint32_t MEMSIZECFG    : 2;
+            __IOM uint32_t PERIOSIZE     : 1;
+            __IOM uint32_t PRILCFG       : 2;
+            __IOM uint32_t DBM           : 1;
+            __IOM uint32_t CTARG         : 1;
+            __IM  uint32_t RESERVED1     : 1;
+            __IOM uint32_t PBCFG         : 2;
+            __IOM uint32_t MBCFG         : 2;
+            __IOM uint32_t CHSEL         : 3;
+            __IM  uint32_t RESERVED2     : 4;
+        } SCFG_B;
+    };
+
+    union
+    {
+        __IOM uint32_t NDATA;
+
+        struct
+        {
+            __IOM  uint32_t NDATA        : 16;
+            __IM   uint32_t RESERVED     : 16;
+        } NDATA_B;
+    };
+
+    union
+    {
+        __IOM uint32_t PADDR;
+
+        struct
+        {
+            __IOM  uint32_t PADDR         : 32;
+        } PADDR_B;
+
+    };
+
+    union
+    {
+        __IOM uint32_t M0ADDR;
+
+        struct
+        {
+            __IOM  uint32_t M0ADDR         : 32;
+        } M0ADDR_B;
+
+    };
+
+    union
+    {
+        __IOM uint32_t M1ADDR;
+
+        struct
+        {
+            __IOM  uint32_t M1ADDR         : 32;
+        } M1ADDR_B;
+
+    };
+
+    union
+    {
+        __IOM uint32_t FCTRL;
+
+        struct
+        {
+            __IOM  uint32_t FTHSEL         : 2;
+            __IOM  uint32_t DMDEN          : 1;
+            __IM   uint32_t FSTS           : 3;
+            __IM   uint32_t RESERVED1      : 1;
+            __IOM  uint32_t FEIEN          : 1;
+            __IM   uint32_t RESERVED2      : 24;
+        } FCTRL_B;
+    };
+} DMA_Stream_T;
+
+/**
+ * @brief CAN sending mailbox (CAN)
+ */
+typedef struct
+{
+    /** @brief CAN Each mailbox contains the sending mailbox identifier register */
+    union
+    {
+        __IOM uint32_t TXMID;
+
+        struct
+        {
+            __IOM uint32_t TXMREQ          : 1;
+            __IOM uint32_t TXRFREQ         : 1;
+            __IOM uint32_t IDTYPESEL       : 1;
+            __IOM uint32_t EXTID           : 18;
+            __IOM uint32_t STDID           : 11;
+        } TXMID_B;
+    };
+
+    /** @brief CAN Send the mailbox data length and timestamp register */
+    union
+    {
+        __IOM uint32_t TXDLEN;
+
+        struct
+        {
+            __IOM uint32_t DLCODE          : 4;
+            __IM  uint32_t RESERVED        : 28;
+        } TXDLEN_B;
+    };
+
+    /** @brief CAN Send mailbox low byte data register */
+    union
+    {
+        __IOM uint32_t TXMDL;
+
+        struct
+        {
+            __IOM uint32_t DATABYTE0       : 8;
+            __IOM uint32_t DATABYTE1       : 8;
+            __IOM uint32_t DATABYTE2       : 8;
+            __IOM uint32_t DATABYTE3       : 8;
+        } TXMDL_B;
+    };
+
+    /** @brief CAN Send mailbox High byte data register */
+    union
+    {
+        __IOM uint32_t TXMDH;
+
+        struct
+        {
+            __IOM uint32_t DATABYTE4       : 8;
+            __IOM uint32_t DATABYTE5       : 8;
+            __IOM uint32_t DATABYTE6       : 8;
+            __IOM uint32_t DATABYTE7       : 8;
+        } TXMDH_B;
+    };
+} CAN_TxMailBox_T;
+
+/**
+ * @brief CAN receive mailbox
+ */
+typedef struct
+{
+    /** @brief CAN Each mailbox contains the receive mailbox identifier register */
+    union
+    {
+        __IM uint32_t RXMID;
+
+        struct
+        {
+            __IM  uint32_t RESERVED        : 1;
+            __IM  uint32_t RFTXREQ         : 1;
+            __IM  uint32_t IDTYPESEL       : 1;
+            __IM  uint32_t EXTID           : 18;
+            __IM  uint32_t STDID           : 11;
+        } RXMID_B;
+    };
+
+    /** @brief CAN receive the mailbox data length and timestamp register */
+    union
+    {
+        __IM uint32_t RXDLEN;
+
+        struct
+        {
+            __IM  uint32_t DLCODE          : 4;
+            __IM  uint32_t RESERVED1       : 4;
+            __IM  uint32_t FMIDX           : 8;
+            __IM  uint32_t RESERVED2       : 16;
+        } RXDLEN_B;
+    };
+
+    /** @brief CAN receive mailbox low byte data register */
+    union
+    {
+        __IM uint32_t RXMDL;
+
+        struct
+        {
+            __IM  uint32_t DATABYTE0       : 8;
+            __IM  uint32_t DATABYTE1       : 8;
+            __IM  uint32_t DATABYTE2       : 8;
+            __IM  uint32_t DATABYTE3       : 8;
+        } RXMDL_B;
+    };
+
+    /** @briefCAN receive mailbox High byte data register */
+    union
+    {
+        __IOM uint32_t RXMDH;
+
+        struct
+        {
+            __IM  uint32_t DATABYTE4       : 8;
+            __IM  uint32_t DATABYTE5       : 8;
+            __IM  uint32_t DATABYTE6       : 8;
+            __IM  uint32_t DATABYTE7       : 8;
+        } RXMDH_B;
+    };
+} CAN_RxMailBox_T;
+
+/**
+ * @brief CAN Filter bank register
+ */
+typedef struct
+{
+    /** @brief CAN Filter bank register 1 */
+    union
+    {
+        __IOM uint32_t  FBANK1;
+
+        struct
+        {
+            __IOM uint32_t FBIT0           : 1;
+            __IOM uint32_t FBIT1           : 1;
+            __IOM uint32_t FBIT2           : 1;
+            __IOM uint32_t FBIT3           : 1;
+            __IOM uint32_t FBIT4           : 1;
+            __IOM uint32_t FBIT5           : 1;
+            __IOM uint32_t FBIT6           : 1;
+            __IOM uint32_t FBIT7           : 1;
+            __IOM uint32_t FBIT8           : 1;
+            __IOM uint32_t FBIT9           : 1;
+            __IOM uint32_t FBIT10          : 1;
+            __IOM uint32_t FBIT11          : 1;
+            __IOM uint32_t FBIT12          : 1;
+            __IOM uint32_t FBIT13          : 1;
+            __IOM uint32_t FBIT14          : 1;
+            __IOM uint32_t FBIT15          : 1;
+            __IOM uint32_t FBIT16          : 1;
+            __IOM uint32_t FBIT17          : 1;
+            __IOM uint32_t FBIT18          : 1;
+            __IOM uint32_t FBIT19          : 1;
+            __IOM uint32_t FBIT20          : 1;
+            __IOM uint32_t FBIT21          : 1;
+            __IOM uint32_t FBIT22          : 1;
+            __IOM uint32_t FBIT23          : 1;
+            __IOM uint32_t FBIT24          : 1;
+            __IOM uint32_t FBIT25          : 1;
+            __IOM uint32_t FBIT26          : 1;
+            __IOM uint32_t FBIT27          : 1;
+            __IOM uint32_t FBIT28          : 1;
+            __IOM uint32_t FBIT29          : 1;
+            __IOM uint32_t FBIT30          : 1;
+            __IOM uint32_t FBIT31          : 1;
+        } FBANK1_B;
+    };
+
+    /** @brief CAN Filter bank register 2 */
+    union
+    {
+        __IOM uint32_t  FBANK2;
+
+        struct
+        {
+            __IOM uint32_t FBIT0           : 1;
+            __IOM uint32_t FBIT1           : 1;
+            __IOM uint32_t FBIT2           : 1;
+            __IOM uint32_t FBIT3           : 1;
+            __IOM uint32_t FBIT4           : 1;
+            __IOM uint32_t FBIT5           : 1;
+            __IOM uint32_t FBIT6           : 1;
+            __IOM uint32_t FBIT7           : 1;
+            __IOM uint32_t FBIT8           : 1;
+            __IOM uint32_t FBIT9           : 1;
+            __IOM uint32_t FBIT10          : 1;
+            __IOM uint32_t FBIT11          : 1;
+            __IOM uint32_t FBIT12          : 1;
+            __IOM uint32_t FBIT13          : 1;
+            __IOM uint32_t FBIT14          : 1;
+            __IOM uint32_t FBIT15          : 1;
+            __IOM uint32_t FBIT16          : 1;
+            __IOM uint32_t FBIT17          : 1;
+            __IOM uint32_t FBIT18          : 1;
+            __IOM uint32_t FBIT19          : 1;
+            __IOM uint32_t FBIT20          : 1;
+            __IOM uint32_t FBIT21          : 1;
+            __IOM uint32_t FBIT22          : 1;
+            __IOM uint32_t FBIT23          : 1;
+            __IOM uint32_t FBIT24          : 1;
+            __IOM uint32_t FBIT25          : 1;
+            __IOM uint32_t FBIT26          : 1;
+            __IOM uint32_t FBIT27          : 1;
+            __IOM uint32_t FBIT28          : 1;
+            __IOM uint32_t FBIT29          : 1;
+            __IOM uint32_t FBIT30          : 1;
+            __IOM uint32_t FBIT31          : 1;
+        } FBANK2_B;
+    };
+} CAN_FilterRegister_T;
+
+/**
+ * @brief     Controller Area Network(CAN)
+ */
+typedef struct
+{
+    /** @brief CAN Master control register */
+    union
+    {
+        __IOM uint32_t MCTRL;
+
+        struct
+        {
+            __IOM uint32_t INITREQ         : 1;
+            __IOM uint32_t SLEEPREQ        : 1;
+            __IOM uint32_t TXFPCFG         : 1;
+            __IOM uint32_t RXFLOCK         : 1;
+            __IOM uint32_t ARTXMD          : 1;
+            __IOM uint32_t AWUPCFG         : 1;
+            __IOM uint32_t ALBOFFM         : 1;
+            __IM  uint32_t RESERVED1       : 8;
+            __IOM uint32_t SWRST           : 1;
+            __IOM uint32_t DBGFRZE         : 1;
+            __IM  uint32_t RESERVED2       : 15;
+        } MCTRL_B;
+    };
+
+    /** @brief CAN Master States register */
+    union
+    {
+        __IOM uint32_t MSTS;
+
+        struct
+        {
+            __IM  uint32_t INITFLG         : 1;
+            __IM  uint32_t SLEEPFLG        : 1;
+            __IOM uint32_t ERRIFLG         : 1;
+            __IOM uint32_t WUPIFLG         : 1;
+            __IOM uint32_t SLEEPIFLG       : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IM  uint32_t TXMFLG          : 1;
+            __IM  uint32_t RXMFLG          : 1;
+            __IM  uint32_t LSAMVALUE       : 1;
+            __IM  uint32_t RXSIGL          : 1;
+            __IM  uint32_t RESERVED2       : 20;
+        } MSTS_B;
+    };
+
+    /** @brief CAN Send States register */
+    union
+    {
+        __IOM uint32_t TXSTS;
+
+        struct
+        {
+            __IOM uint32_t REQCFLG0        : 1;
+            __IOM uint32_t TXSUSFLG0       : 1;
+            __IOM uint32_t ARBLSTFLG0      : 1;
+            __IOM uint32_t TXERRFLG0       : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t ABREQFLG0       : 1;
+            __IOM uint32_t REQCFLG1        : 1;
+            __IOM uint32_t TXSUSFLG1       : 1;
+            __IOM uint32_t ARBLSTFLG1      : 1;
+            __IOM uint32_t TXERRFLG1       : 1;
+            __IM  uint32_t RESERVED2       : 3;
+            __IOM uint32_t ABREQFLG1       : 1;
+            __IOM uint32_t REQCFLG2        : 1;
+            __IOM uint32_t TXSUSFLG2       : 1;
+            __IOM uint32_t ARBLSTFLG2      : 1;
+            __IOM uint32_t TXERRFLG2       : 1;
+            __IM  uint32_t RESERVED3       : 3;
+            __IOM uint32_t ABREQFLG2       : 1;
+            __IM  uint32_t EMNUM           : 2;
+            __IM  uint32_t TXMEFLG0        : 1;
+            __IM  uint32_t TXMEFLG1        : 1;
+            __IM  uint32_t TXMEFLG2        : 1;
+            __IM  uint32_t LOWESTP0        : 1;
+            __IM  uint32_t LOWESTP1        : 1;
+            __IM  uint32_t LOWESTP2        : 1;
+        } TXSTS_B;
+    };
+
+    /** @brief CAN Receive FIFO 0 register */
+    union
+    {
+        __IOM uint32_t RXF0;
+
+        struct
+        {
+            __IM  uint32_t FMNUM0          : 2;
+            __IM  uint32_t RESERVED        : 1;
+            __IOM uint32_t FFULLFLG0       : 1;
+            __IOM uint32_t FOVRFLG0        : 1;
+            __IOM uint32_t RFOM0           : 1;
+            __IM  uint32_t RESERVED1       : 26;
+        } RXF0_B;
+    };
+
+    /** @brief CAN Receive FIFO 1 register */
+    union
+    {
+        __IOM uint32_t RXF1;
+
+        struct
+        {
+            __IM  uint32_t FMNUM1          : 2;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t FFULLFLG1       : 1;
+            __IOM uint32_t FOVRFLG1        : 1;
+            __IOM uint32_t RFOM1           : 1;
+            __IM  uint32_t RESERVED2       : 26;
+        } RXF1_B;
+    };
+
+    /** @brief CAN Interrupts register */
+    union
+    {
+        __IOM uint32_t INTEN;
+
+        struct
+        {
+            __IOM uint32_t TXMEIEN         : 1;
+            __IOM uint32_t FMIEN0          : 1;
+            __IOM uint32_t FFULLIEN0       : 1;
+            __IOM uint32_t FOVRIEN0        : 1;
+            __IOM uint32_t FMIEN1          : 1;
+            __IOM uint32_t FFULLIEN1       : 1;
+            __IOM uint32_t FOVRIEN1        : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t ERRWIEN         : 1;
+            __IOM uint32_t ERRPIEN         : 1;
+            __IOM uint32_t BOFFIEN         : 1;
+            __IOM uint32_t LECIEN          : 1;
+            __IM  uint32_t RESERVED2       : 3;
+            __IOM uint32_t ERRIEN          : 1;
+            __IOM uint32_t WUPIEN          : 1;
+            __IOM uint32_t SLEEPIEN        : 1;
+            __IM  uint32_t RESERVED3       : 14;
+        } INTEN_B;
+    };
+
+    /** @brief CAN Error States register */
+    union
+    {
+        __IOM uint32_t ERRSTS;
+
+        struct
+        {
+            __IM  uint32_t ERRWFLG         : 1;
+            __IM  uint32_t ERRPFLG         : 1;
+            __IM  uint32_t BOFLG           : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t LERRC           : 3;
+            __IM  uint32_t RESERVED2       : 9;
+            __IM  uint32_t TXERRCNT        : 8;
+            __IM  uint32_t RXERRCNT        : 8;
+        } ERRSTS_B;
+    };
+
+    /** @brief CAN Bit Time register */
+    union
+    {
+        __IOM uint32_t BITTIM;
+
+        struct
+        {
+            __IOM uint32_t BRPSC           : 10;
+            __IM  uint32_t RESERVED1       : 6;
+            __IOM uint32_t TIMSEG1         : 4;
+            __IOM uint32_t TIMSEG2         : 3;
+            __IM  uint32_t RESERVED2       : 1;
+            __IOM uint32_t RSYNJW          : 2;
+            __IM  uint32_t RESERVED3       : 4;
+            __IOM uint32_t LBKMEN          : 1;
+            __IOM uint32_t SILMEN          : 1;
+        } BITTIM_B;
+    };
+
+    __IM uint32_t RESERVED0[88];
+
+    CAN_TxMailBox_T  sTxMailBox[3];
+    CAN_RxMailBox_T  sRxMailBox[2];
+
+    __IM  uint32_t  RESERVED1[12];
+
+    /** @brief CAN Filter the master control register */
+    union
+    {
+        __IOM uint32_t FCTRL;
+
+        struct
+        {
+            __IOM uint32_t FINITEN         : 1;
+            __IM  uint32_t RESERVED        : 7;
+            __IOM uint32_t CAN2BN          : 6;
+            __IM  uint32_t RESERVED1       : 18;
+        } FCTRL_B;
+    };
+
+    /** @brief CAN Filter register */
+    union
+    {
+        __IOM uint32_t FMCFG;
+
+        struct
+        {
+            __IOM uint32_t FMCFG0          : 1;
+            __IOM uint32_t FMCFG1          : 1;
+            __IOM uint32_t FMCFG2          : 1;
+            __IOM uint32_t FMCFG3          : 1;
+            __IOM uint32_t FMCFG4          : 1;
+            __IOM uint32_t FMCFG5          : 1;
+            __IOM uint32_t FMCFG6          : 1;
+            __IOM uint32_t FMCFG7          : 1;
+            __IOM uint32_t FMCFG8          : 1;
+            __IOM uint32_t FMCFG9          : 1;
+            __IOM uint32_t FMCFG10         : 1;
+            __IOM uint32_t FMCFG11         : 1;
+            __IOM uint32_t FMCFG12         : 1;
+            __IOM uint32_t FMCFG13         : 1;
+            __IOM uint32_t FMCFG14         : 1;
+            __IOM uint32_t FMCFG15         : 1;
+            __IOM uint32_t FMCFG16         : 1;
+            __IOM uint32_t FMCFG17         : 1;
+            __IOM uint32_t FMCFG18         : 1;
+            __IOM uint32_t FMCFG19         : 1;
+            __IOM uint32_t FMCFG20         : 1;
+            __IOM uint32_t FMCFG21         : 1;
+            __IOM uint32_t FMCFG22         : 1;
+            __IOM uint32_t FMCFG23         : 1;
+            __IOM uint32_t FMCFG24         : 1;
+            __IOM uint32_t FMCFG25         : 1;
+            __IOM uint32_t FMCFG26         : 1;
+            __IOM uint32_t FMCFG27         : 1;
+            __IM  uint32_t RESERVED        : 4;
+        } FMCFG_B;
+    };
+
+    __IM  uint32_t  RESERVED2;
+
+    /** @brief CAN Filter bit scale register */
+    union
+    {
+        __IOM uint32_t FSCFG;
+
+        struct
+        {
+            __IOM uint32_t FSCFG0          : 1;
+            __IOM uint32_t FSCFG1          : 1;
+            __IOM uint32_t FSCFG2          : 1;
+            __IOM uint32_t FSCFG3          : 1;
+            __IOM uint32_t FSCFG4          : 1;
+            __IOM uint32_t FSCFG5          : 1;
+            __IOM uint32_t FSCFG6          : 1;
+            __IOM uint32_t FSCFG7          : 1;
+            __IOM uint32_t FSCFG8          : 1;
+            __IOM uint32_t FSCFG9          : 1;
+            __IOM uint32_t FSCFG10         : 1;
+            __IOM uint32_t FSCFG11         : 1;
+            __IOM uint32_t FSCFG12         : 1;
+            __IOM uint32_t FSCFG13         : 1;
+            __IOM uint32_t FSCFG14         : 1;
+            __IOM uint32_t FSCFG15         : 1;
+            __IOM uint32_t FSCFG16         : 1;
+            __IOM uint32_t FSCFG17         : 1;
+            __IOM uint32_t FSCFG18         : 1;
+            __IOM uint32_t FSCFG19         : 1;
+            __IOM uint32_t FSCFG20         : 1;
+            __IOM uint32_t FSCFG21         : 1;
+            __IOM uint32_t FSCFG22         : 1;
+            __IOM uint32_t FSCFG23         : 1;
+            __IOM uint32_t FSCFG24         : 1;
+            __IOM uint32_t FSCFG25         : 1;
+            __IOM uint32_t FSCFG26         : 1;
+            __IOM uint32_t FSCFG27         : 1;
+            __IM  uint32_t RESERVED        : 4;
+        } FSCFG_B;
+    };
+
+    __IM  uint32_t  RESERVED3;
+
+    /** @brief CAN Filter FIFO associated registers */
+    union
+    {
+        __IOM uint32_t FFASS;
+
+        struct
+        {
+            __IOM uint32_t FFASS0          : 1;
+            __IOM uint32_t FFASS1          : 1;
+            __IOM uint32_t FFASS2          : 1;
+            __IOM uint32_t FFASS3          : 1;
+            __IOM uint32_t FFASS4          : 1;
+            __IOM uint32_t FFASS5          : 1;
+            __IOM uint32_t FFASS6          : 1;
+            __IOM uint32_t FFASS7          : 1;
+            __IOM uint32_t FFASS8          : 1;
+            __IOM uint32_t FFASS9          : 1;
+            __IOM uint32_t FFASS10         : 1;
+            __IOM uint32_t FFASS11         : 1;
+            __IOM uint32_t FFASS12         : 1;
+            __IOM uint32_t FFASS13         : 1;
+            __IOM uint32_t FFASS14         : 1;
+            __IOM uint32_t FFASS15         : 1;
+            __IOM uint32_t FFASS16         : 1;
+            __IOM uint32_t FFASS17         : 1;
+            __IOM uint32_t FFASS18         : 1;
+            __IOM uint32_t FFASS19         : 1;
+            __IOM uint32_t FFASS20         : 1;
+            __IOM uint32_t FFASS21         : 1;
+            __IOM uint32_t FFASS22         : 1;
+            __IOM uint32_t FFASS23         : 1;
+            __IOM uint32_t FFASS24         : 1;
+            __IOM uint32_t FFASS25         : 1;
+            __IOM uint32_t FFASS26         : 1;
+            __IOM uint32_t FFASS27         : 1;
+            __IM  uint32_t RESERVED        : 4;
+        } FFASS_B;
+    };
+
+    __IM  uint32_t  RESERVED4;
+
+    /** @brief CAN Filter activation register */
+    union
+    {
+        __IOM uint32_t FACT;
+
+        struct
+        {
+            __IOM uint32_t FACT0           : 1;
+            __IOM uint32_t FACT1           : 1;
+            __IOM uint32_t FACT2           : 1;
+            __IOM uint32_t FACT3           : 1;
+            __IOM uint32_t FACT4           : 1;
+            __IOM uint32_t FACT5           : 1;
+            __IOM uint32_t FACT6           : 1;
+            __IOM uint32_t FACT7           : 1;
+            __IOM uint32_t FACT8           : 1;
+            __IOM uint32_t FACT9           : 1;
+            __IOM uint32_t FACT10          : 1;
+            __IOM uint32_t FACT11          : 1;
+            __IOM uint32_t FACT12          : 1;
+            __IOM uint32_t FACT13          : 1;
+            __IOM uint32_t FACT14          : 1;
+            __IOM uint32_t FACT15          : 1;
+            __IOM uint32_t FACT16          : 1;
+            __IOM uint32_t FACT17          : 1;
+            __IOM uint32_t FACT18          : 1;
+            __IOM uint32_t FACT19          : 1;
+            __IOM uint32_t FACT20          : 1;
+            __IOM uint32_t FACT21          : 1;
+            __IOM uint32_t FACT22          : 1;
+            __IOM uint32_t FACT23          : 1;
+            __IOM uint32_t FACT24          : 1;
+            __IOM uint32_t FACT25          : 1;
+            __IOM uint32_t FACT26          : 1;
+            __IOM uint32_t FACT27          : 1;
+            __IM  uint32_t RESERVED        : 4;
+        } FACT_B;
+    };
+
+    __IM  uint32_t  RESERVED5[8];
+
+    CAN_FilterRegister_T sFilterRegister[28];
+} CAN_T;
+
+/**
+ * @brief    I2C register (I2C)
+ */
+typedef struct
+{
+    /** @brief Control register 1 */
+    union
+    {
+        __IOM uint32_t CTRL1;
+
+        struct
+        {
+            __IOM uint32_t I2CEN           : 1;
+            __IOM uint32_t SMBEN           : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t SMBTCFG         : 1;
+            __IOM uint32_t ARPEN           : 1;
+            __IOM uint32_t PECEN           : 1;
+            __IOM uint32_t SRBEN           : 1;
+            __IOM uint32_t CLKSTRETCHD     : 1;
+            __IOM uint32_t START           : 1;
+            __IOM uint32_t STOP            : 1;
+            __IOM uint32_t ACKEN           : 1;
+            __IOM uint32_t ACKPOS          : 1;
+            __IOM uint32_t PEC             : 1;
+            __IOM uint32_t ALERTEN         : 1;
+            __IM  uint32_t RESERVED2       : 1;
+            __IOM uint32_t SWRST           : 1;
+            __IM  uint32_t RESERVED3       : 16;
+        } CTRL1_B;
+    } ;
+
+    /** @brief Control register 2 */
+    union
+    {
+        __IOM uint32_t CTRL2;
+
+        struct
+        {
+            __IOM uint32_t CLKFCFG         : 6;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t ERRIEN          : 1;
+            __IOM uint32_t EVIEN           : 1;
+            __IOM uint32_t BUFIEN          : 1;
+            __IOM uint32_t DMAEN           : 1;
+            __IOM uint32_t LTCFG           : 1;
+            __IM  uint32_t RESERVED2       : 19;
+        } CTRL2_B;
+    } ;
+
+    /** @brief Slave machine address register 1 */
+    union
+    {
+        __IOM uint32_t SADDR1;
+
+        struct
+        {
+            __IOM uint32_t ADDR0           : 1;
+            __IOM uint32_t ADDR1_7         : 7;
+            __IOM uint32_t ADDR8_9         : 2;
+            __IM  uint32_t RESERVED1       : 5;
+            __IOM uint32_t ADDRLEN         : 1;
+            __IM  uint32_t RESERVED2       : 16;
+        } SADDR1_B;
+    };
+
+    /** @brief Slave machine address register 2 */
+    union
+    {
+        __IOM uint32_t SADDR2;
+
+        struct
+        {
+            __IOM uint32_t ADDRNUM         : 1;
+            __IOM uint32_t ADDR2           : 7;
+            __IM  uint32_t RESERVED        : 24;
+        } SADDR2_B;
+    };
+
+    /** @brief Cache data register */
+    union
+    {
+        __IOM uint32_t DATA;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 8;
+            __IM  uint32_t RESERVED        : 24;
+        } DATA_B;
+    };
+
+    /** @brief Status register 1 */
+    union
+    {
+        __IOM uint32_t STS1;
+
+        struct
+        {
+            __IM  uint32_t STARTFLG        : 1;
+            __IM  uint32_t ADDRFLG         : 1;
+            __IM  uint32_t BTCFLG          : 1;
+            __IM  uint32_t ADDR10FLG       : 1;
+            __IM  uint32_t STOPFLG         : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IM  uint32_t RXBNEFLG        : 1;
+            __IM  uint32_t TXBEFLG         : 1;
+            __IOM uint32_t BERRFLG         : 1;
+            __IOM uint32_t ALFLG           : 1;
+            __IOM uint32_t AEFLG           : 1;
+            __IOM uint32_t OVRURFLG        : 1;
+            __IOM uint32_t PECEFLG         : 1;
+            __IM  uint32_t RESERVED2       : 1;
+            __IOM uint32_t TTEFLG          : 1;
+            __IOM uint32_t SMBALTFLG       : 1;
+            __IM  uint32_t RESERVED3       : 16;
+        } STS1_B;
+    };
+
+    /** @brief Status register 2 */
+    union
+    {
+        __IM uint32_t STS2;
+
+        struct
+        {
+            __IM  uint32_t MSFLG           : 1;
+            __IM  uint32_t BUSBSYFLG       : 1;
+            __IM  uint32_t TRFLG           : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IM  uint32_t GENCALLFLG      : 1;
+            __IM  uint32_t SMBDADDRFLG     : 1;
+            __IM  uint32_t SMMHADDR        : 1;
+            __IM  uint32_t DUALADDRFLG     : 1;
+            __IM  uint32_t PECVALUE        : 8;
+            __IM  uint32_t RESERVED2       : 16;
+        } STS2_B;
+    };
+
+    /** @brief Clock control register */
+    union
+    {
+        __IOM uint32_t CLKCTRL;
+
+        struct
+        {
+            __IOM uint32_t CLKS            : 12;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t FDUTYCFG        : 1;
+            __IOM uint32_t SPEEDCFG        : 1;
+            __IM  uint32_t RESERVED2       : 16;
+        } CLKCTRL_B;
+    };
+
+    /** @brief  Maximum rise time */
+    union
+    {
+        __IOM uint32_t RISETMAX;
+
+        struct
+        {
+            __IOM uint32_t RISETMAX        : 6;
+            __IM  uint32_t RESERVED        : 26;
+        } RISETMAX_B;
+    };
+} I2C_T;
+
+/**
+ * @brief Analog to Digital Converter(ADC)
+ */
+typedef struct
+{
+    /** interrupt and status register */
+    union
+    {
+        __IOM  uint32_t STS;
+
+        struct
+        {
+            __IOM uint32_t AWDFLG     : 1;
+            __IOM uint32_t EOCFLG     : 1;
+            __IOM uint32_t INJEOCFLG  : 1;
+            __IOM uint32_t INJCSFLG   : 1;
+            __IOM uint32_t REGCSFLG   : 1;
+            __IOM uint32_t OVREFLG    : 1;
+            __IM  uint32_t RESERVED1  : 26;
+        } STS_B;
+    } ;
+
+    /** Control register1*/
+
+    union
+    {
+        __IOM uint32_t CTRL1;
+
+        struct
+        {
+            __IOM uint32_t AWDCHSEL      : 5;
+            __IOM uint32_t EOCIEN        : 1;
+            __IOM uint32_t AWDIEN        : 1;
+            __IOM uint32_t INJEOCIEN     : 1;
+            __IOM uint32_t SCANEN        : 1;
+            __IOM uint32_t AWDSGLEN      : 1;
+            __IOM uint32_t INJGACEN      : 1;
+            __IOM uint32_t REGDISCEN     : 1;
+            __IOM uint32_t INJDISCEN     : 1;
+            __IOM uint32_t DISCNUMCFG    : 3;
+            __IM  uint32_t RESERVED1     : 6;
+            __IOM uint32_t INJAWDEN      : 1;
+            __IOM uint32_t REGAWDEN      : 1;
+            __IOM uint32_t RESSEL        : 2;
+            __IOM uint32_t OVRIEN        : 1;
+            __IM  uint32_t RESERVED2     : 5;
+        } CTRL1_B;
+    } ;
+    /** Control register2*/
+    union
+    {
+        __IOM uint32_t CTRL2;
+
+        struct
+        {
+            __IOM uint32_t ADCEN           : 1;
+            __IOM uint32_t CONTCEN         : 1;
+            __IM  uint32_t RESERVED1       : 6;
+            __IOM uint32_t DMAEN           : 1;
+            __IOM uint32_t DMADISSEL       : 1;
+            __IOM uint32_t EOCSEL          : 1;
+            __IOM uint32_t DALIGNCFG       : 1;
+            __IM  uint32_t RESERVED2       : 4;
+            __IOM uint32_t INJGEXTTRGSEL   : 4;
+            __IOM uint32_t INJEXTTRGEN     : 2;
+            __IOM uint32_t INJCHSC         : 1;
+            __IM  uint32_t RESERVED3       : 1;
+            __IOM uint32_t REGEXTTRGSEL    : 4;
+            __IOM uint32_t REGEXTTRGEN     : 2;
+            __IOM uint32_t REGCHSC         : 1;
+            __IM  uint32_t RESERVED4       : 1;
+        } CTRL2_B;
+    } ;
+
+    /** Sample time register1*/
+    union
+    {
+        __IOM uint32_t SMPTIM1;
+
+        struct
+        {
+            __IOM uint32_t SMPCYCCFG10     : 3;
+            __IOM uint32_t SMPCYCCFG11     : 3;
+            __IOM uint32_t SMPCYCCFG12     : 3;
+            __IOM uint32_t SMPCYCCFG13     : 3;
+            __IOM uint32_t SMPCYCCFG14     : 3;
+            __IOM uint32_t SMPCYCCFG15     : 3;
+            __IOM uint32_t SMPCYCCFG16     : 3;
+            __IOM uint32_t SMPCYCCFG17     : 3;
+            __IOM uint32_t SMPCYCCFG18     : 3;
+            __IM  uint32_t RESERVED        : 5;
+        } SMPTIM1_B;
+    };
+
+    /** Sample time register2*/
+    union
+    {
+        __IOM uint32_t SMPTIM2;
+
+        struct
+        {
+            __IOM uint32_t SMPCYCCFG0      : 3;
+            __IOM uint32_t SMPCYCCFG1      : 3;
+            __IOM uint32_t SMPCYCCFG2      : 3;
+            __IOM uint32_t SMPCYCCFG3      : 3;
+            __IOM uint32_t SMPCYCCFG4      : 3;
+            __IOM uint32_t SMPCYCCFG5      : 3;
+            __IOM uint32_t SMPCYCCFG6      : 3;
+            __IOM uint32_t SMPCYCCFG7      : 3;
+            __IOM uint32_t SMPCYCCFG8      : 3;
+            __IOM uint32_t SMPCYCCFG9      : 3;
+            __IM  uint32_t RESERVED        : 2;
+        } SMPTIM2_B;
+    };
+
+    /** Injected channel Data offset register1*/
+    union
+    {
+        __IOM uint32_t INJDOF1;
+
+        struct
+        {
+            __IOM  uint32_t INJDOF1        : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } INJDOF1_B;
+    };
+
+    /** Injected channel Data offset register2*/
+    union
+    {
+        __IOM uint32_t INJDOF2;
+
+        struct
+        {
+            __IOM  uint32_t INJDOF2        : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } INJDOF2_B;
+    };
+
+    /** Injected channel Data offset register3*/
+    union
+    {
+        __IOM uint32_t INJDOF3;
+
+        struct
+        {
+            __IOM  uint32_t INJDOF3        : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } INJDOF3_B;
+    };
+
+    /** Injected channel Data offset register4*/
+    union
+    {
+        __IOM uint32_t INJDOF4;
+
+        struct
+        {
+            __IOM  uint32_t INJDOF4        : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } INJDOF4_B;
+    };
+
+    /** Analog watchdog high threshold register*/
+    union
+    {
+        __IOM uint32_t AWDHT;
+
+        struct
+        {
+            __IOM  uint32_t AWDHT          : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } AWDHT_B;
+    };
+
+    /** Analog watchdog low threshold register*/
+    union
+    {
+        __IOM uint32_t AWDLT;
+
+        struct
+        {
+            __IOM  uint32_t AWDLT          : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } AWDLT_B;
+    };
+
+    /** Regular channel sequence register1*/
+    union
+    {
+        __IOM uint32_t REGSEQ1;
+
+        struct
+        {
+            __IOM uint32_t REGSEQC13       : 5;
+            __IOM uint32_t REGSEQC14       : 5;
+            __IOM uint32_t REGSEQC15       : 5;
+            __IOM uint32_t REGSEQC16       : 5;
+            __IOM uint32_t REGSEQLEN       : 4;
+            __IM  uint32_t RESERVED        : 8;
+        } REGSEQ1_B;
+    };
+
+    /** Regular channel sequence register2*/
+    union
+    {
+        __IOM uint32_t REGSEQ2;
+
+        struct
+        {
+            __IOM uint32_t REGSEQC7        : 5;
+            __IOM uint32_t REGSEQC8        : 5;
+            __IOM uint32_t REGSEQC9        : 5;
+            __IOM uint32_t REGSEQC10       : 5;
+            __IOM uint32_t REGSEQC11       : 5;
+            __IOM uint32_t REGSEQC12       : 5;
+            __IM  uint32_t RESERVED        : 2;
+        } REGSEQ2_B;
+    };
+
+    /** Regular channel sequence register3*/
+    union
+    {
+        __IOM uint32_t REGSEQ3;
+
+        struct
+        {
+            __IOM uint32_t REGSEQC1        : 5;
+            __IOM uint32_t REGSEQC2        : 5;
+            __IOM uint32_t REGSEQC3        : 5;
+            __IOM uint32_t REGSEQC4        : 5;
+            __IOM uint32_t REGSEQC5        : 5;
+            __IOM uint32_t REGSEQC6        : 5;
+            __IM  uint32_t RESERVED        : 2;
+        } REGSEQ3_B;
+    };
+
+    /** Injected sequence register*/
+    union
+    {
+        __IOM uint32_t INJSEQ;
+
+        struct
+        {
+            __IOM uint32_t INJSEQC1        : 5;
+            __IOM uint32_t INJSEQC2        : 5;
+            __IOM uint32_t INJSEQC3        : 5;
+            __IOM uint32_t INJSEQC4        : 5;
+            __IOM uint32_t INJSEQLEN       : 2;
+            __IM  uint32_t RESERVED        : 10;
+        } INJSEQ_B;
+    };
+
+    /** Injected Data register1*/
+    union
+    {
+        __IM uint32_t INJDATA1;
+
+        struct
+        {
+            __IM   uint32_t INJDATA        : 16;
+            __IM   uint32_t RESERVED       : 16;
+        } INJDATA1_B;
+    };
+
+    /** Injected Data register2*/
+    union
+    {
+        __IM uint32_t INJDATA2;
+
+        struct
+        {
+            __IM   uint32_t INJDATA        : 16;
+            __IM   uint32_t RESERVED       : 16;
+        } INJDATA2_B;
+    };
+
+    /** Injected Data register3*/
+    union
+    {
+        __IM uint32_t INJDATA3;
+
+        struct
+        {
+            __IM   uint32_t INJDATA        : 16;
+            __IM   uint32_t RESERVED       : 16;
+        } INJDATA3_B;
+    };
+
+    /** Injected Data register4*/
+    union
+    {
+        __IM uint32_t INJDATA4;
+
+        struct
+        {
+            __IM   uint32_t INJDATA        : 16;
+            __IM   uint32_t RESERVED       : 16;
+        } INJDATA4_B;
+    };
+
+    /** Regular Data register*/
+    union
+    {
+        __IOM uint32_t REGDATA;
+
+        struct
+        {
+            __IM  uint32_t REGDATA         : 16;
+            __IM  uint32_t RESERVED        : 16;
+        } REGDATA_B;
+    };
+} ADC_T;
+
+typedef struct
+{
+    /**Common status register*/
+    union
+    {
+        __IOM uint32_t CSTS;
+
+        struct
+        {
+            __IM uint32_t AWDFLG1        : 1;
+            __IM uint32_t EOCFLG1        : 1;
+            __IM uint32_t INJEOCFLG1     : 1;
+            __IM uint32_t INJCSFLG1      : 1;
+            __IM uint32_t REGCSFLG1      : 1;
+            __IM uint32_t OVRFLG1        : 1;
+            __IM uint32_t RESERVED1      : 2;
+            __IM uint32_t AWDFLG2        : 1;
+            __IM uint32_t EOCFLG2        : 1;
+            __IM uint32_t INJEOCFLG2     : 1;
+            __IM uint32_t INJCSFLG2      : 1;
+            __IM uint32_t REGCSFLG2      : 1;
+            __IM uint32_t OVRFLG2        : 1;
+            __IM uint32_t RESERVED2      : 2;
+            __IM uint32_t AWDFLG3        : 1;
+            __IM uint32_t EOCFLG3        : 1;
+            __IM uint32_t INJEOCFLG3     : 1;
+            __IM uint32_t INJCSFLG3      : 1;
+            __IM uint32_t REGCSFLG3      : 1;
+            __IM uint32_t OVRFLG3        : 1;
+            __IM uint32_t RESERVED3      : 2;
+        } CSTS_B;
+    } ;
+
+    /** Common control register*/
+    union
+    {
+        __IOM uint32_t CCTRL;
+
+        struct
+        {
+            __IOM uint32_t ADCMSEL      : 5;
+            __IM  uint32_t RESERVED1    : 3;
+            __IOM uint32_t SMPDEL2      : 4;
+            __IM  uint32_t RESERVED2    : 1;
+            __IOM uint32_t DMADISSEL    : 1;
+            __IOM uint32_t DMAMODE      : 2;
+            __IOM uint32_t ADCPRE       : 2;
+            __IM  uint32_t RESERVED3    : 4;
+            __IOM uint32_t VBATEN       : 1;
+            __IOM uint32_t TSVREFEN     : 1;
+            __IM  uint32_t RESERVED4    : 8;
+        } CCTRL_B;
+    } ;
+
+    /** Common regular data register for dual and triple modes */
+    union
+    {
+        __IOM uint32_t CDATA;
+
+        struct
+        {
+            __IM uint32_t DATA1     : 16;
+            __IM uint32_t DATA2     : 16;
+        } CDATA_B;
+    } ;
+} ADC_Common_T;
+
+/**
+ * @brief    External Interrupt/Event Controller (EINT)
+ */
+typedef struct
+{
+    union
+    {
+        __IOM uint32_t IMASK;
+
+        struct
+        {
+            __IOM uint32_t IMASK0          : 1;
+            __IOM uint32_t IMASK1          : 1;
+            __IOM uint32_t IMASK2          : 1;
+            __IOM uint32_t IMASK3          : 1;
+            __IOM uint32_t IMASK4          : 1;
+            __IOM uint32_t IMASK5          : 1;
+            __IOM uint32_t IMASK6          : 1;
+            __IOM uint32_t IMASK7          : 1;
+            __IOM uint32_t IMASK8          : 1;
+            __IOM uint32_t IMASK9          : 1;
+            __IOM uint32_t IMASK10         : 1;
+            __IOM uint32_t IMASK11         : 1;
+            __IOM uint32_t IMASK12         : 1;
+            __IOM uint32_t IMASK13         : 1;
+            __IOM uint32_t IMASK14         : 1;
+            __IOM uint32_t IMASK15         : 1;
+            __IOM uint32_t IMASK16         : 1;
+            __IOM uint32_t IMASK17         : 1;
+            __IOM uint32_t IMASK18         : 1;
+            __IOM uint32_t IMASK19         : 1;
+            __IOM uint32_t IMASK20         : 1;
+            __IOM uint32_t IMASK21         : 1;
+            __IOM uint32_t IMASK22         : 1;
+            __IM   uint32_t RESERVED       : 9;
+        } IMASK_B;
+    };
+
+    union
+    {
+        __IOM uint32_t EMASK;
+
+        struct
+        {
+            __IOM uint32_t EMASK0          : 1;
+            __IOM uint32_t EMASK1          : 1;
+            __IOM uint32_t EMASK2          : 1;
+            __IOM uint32_t EMASK3          : 1;
+            __IOM uint32_t EMASK4          : 1;
+            __IOM uint32_t EMASK5          : 1;
+            __IOM uint32_t EMASK6          : 1;
+            __IOM uint32_t EMASK7          : 1;
+            __IOM uint32_t EMASK8          : 1;
+            __IOM uint32_t EMASK9          : 1;
+            __IOM uint32_t EMASK10         : 1;
+            __IOM uint32_t EMASK11         : 1;
+            __IOM uint32_t EMASK12         : 1;
+            __IOM uint32_t EMASK13         : 1;
+            __IOM uint32_t EMASK14         : 1;
+            __IOM uint32_t EMASK15         : 1;
+            __IOM uint32_t EMASK16         : 1;
+            __IOM uint32_t EMASK17         : 1;
+            __IOM uint32_t EMASK18         : 1;
+            __IOM uint32_t EMASK19         : 1;
+            __IOM uint32_t EMASK20         : 1;
+            __IOM uint32_t EMASK21         : 1;
+            __IOM uint32_t EMASK22         : 1;
+            __IM   uint32_t RESERVED       : 9;
+        } EMASK_B;
+    };
+
+    union
+    {
+        __IOM uint32_t RTEN;
+
+        struct
+        {
+            __IOM uint32_t RTEN0           : 1;
+            __IOM uint32_t RTEN1           : 1;
+            __IOM uint32_t RTEN2           : 1;
+            __IOM uint32_t RTEN3           : 1;
+            __IOM uint32_t RTEN4           : 1;
+            __IOM uint32_t RTEN5           : 1;
+            __IOM uint32_t RTEN6           : 1;
+            __IOM uint32_t RTEN7           : 1;
+            __IOM uint32_t RTEN8           : 1;
+            __IOM uint32_t RTEN9           : 1;
+            __IOM uint32_t RTEN10          : 1;
+            __IOM uint32_t RTEN11          : 1;
+            __IOM uint32_t RTEN12          : 1;
+            __IOM uint32_t RTEN13          : 1;
+            __IOM uint32_t RTEN14          : 1;
+            __IOM uint32_t RTEN15          : 1;
+            __IOM uint32_t RTEN16          : 1;
+            __IOM uint32_t RTEN17          : 1;
+            __IOM uint32_t RTEN18          : 1;
+            __IOM uint32_t RTEN19          : 1;
+            __IOM uint32_t RTEN20          : 1;
+            __IOM uint32_t RTEN21          : 1;
+            __IOM uint32_t RTEN22          : 1;
+            __IM   uint32_t RESERVED       : 9;
+        } RTEN_B;
+    };
+
+    union
+    {
+        __IOM uint32_t FTEN;
+
+        struct
+        {
+            __IOM uint32_t FTEN0           : 1;
+            __IOM uint32_t FTEN1           : 1;
+            __IOM uint32_t FTEN2           : 1;
+            __IOM uint32_t FTEN3           : 1;
+            __IOM uint32_t FTEN4           : 1;
+            __IOM uint32_t FTEN5           : 1;
+            __IOM uint32_t FTEN6           : 1;
+            __IOM uint32_t FTEN7           : 1;
+            __IOM uint32_t FTEN8           : 1;
+            __IOM uint32_t FTEN9           : 1;
+            __IOM uint32_t FTEN10          : 1;
+            __IOM uint32_t FTEN11          : 1;
+            __IOM uint32_t FTEN12          : 1;
+            __IOM uint32_t FTEN13          : 1;
+            __IOM uint32_t FTEN14          : 1;
+            __IOM uint32_t FTEN15          : 1;
+            __IOM uint32_t FTEN16          : 1;
+            __IOM uint32_t FTEN17          : 1;
+            __IOM uint32_t FTEN18          : 1;
+            __IOM uint32_t FTEN19          : 1;
+            __IOM uint32_t FTEN20          : 1;
+            __IOM uint32_t FTEN21          : 1;
+            __IOM uint32_t FTEN22          : 1;
+            __IM   uint32_t RESERVED       : 9;
+        } FTEN_B;
+    };
+
+    union
+    {
+        __IOM uint32_t SWINTE;
+
+        struct
+        {
+            __IOM uint32_t SWINTE0         : 1;
+            __IOM uint32_t SWINTE1         : 1;
+            __IOM uint32_t SWINTE2         : 1;
+            __IOM uint32_t SWINTE3         : 1;
+            __IOM uint32_t SWINTE4         : 1;
+            __IOM uint32_t SWINTE5         : 1;
+            __IOM uint32_t SWINTE6         : 1;
+            __IOM uint32_t SWINTE7         : 1;
+            __IOM uint32_t SWINTE8         : 1;
+            __IOM uint32_t SWINTE9         : 1;
+            __IOM uint32_t SWINTE10        : 1;
+            __IOM uint32_t SWINTE11        : 1;
+            __IOM uint32_t SWINTE12        : 1;
+            __IOM uint32_t SWINTE13        : 1;
+            __IOM uint32_t SWINTE14        : 1;
+            __IOM uint32_t SWINTE15        : 1;
+            __IOM uint32_t SWINTE16        : 1;
+            __IOM uint32_t SWINTE17        : 1;
+            __IOM uint32_t SWINTE18        : 1;
+            __IOM uint32_t SWINTE19        : 1;
+            __IOM uint32_t SWINTE20        : 1;
+            __IOM uint32_t SWINTE21        : 1;
+            __IOM uint32_t SWINTE22        : 1;
+            __IM   uint32_t RESERVED       : 9;
+        } SWINTE_B;
+    };
+
+    union
+    {
+        __IOM uint32_t IPEND;
+
+        struct
+        {
+            __IOM uint32_t IPEND0          : 1;
+            __IOM uint32_t IPEND1          : 1;
+            __IOM uint32_t IPEND2          : 1;
+            __IOM uint32_t IPEND3          : 1;
+            __IOM uint32_t IPEND4          : 1;
+            __IOM uint32_t IPEND5          : 1;
+            __IOM uint32_t IPEND6          : 1;
+            __IOM uint32_t IPEND7          : 1;
+            __IOM uint32_t IPEND8          : 1;
+            __IOM uint32_t IPEND9          : 1;
+            __IOM uint32_t IPEND10         : 1;
+            __IOM uint32_t IPEND11         : 1;
+            __IOM uint32_t IPEND12         : 1;
+            __IOM uint32_t IPEND13         : 1;
+            __IOM uint32_t IPEND14         : 1;
+            __IOM uint32_t IPEND15         : 1;
+            __IOM uint32_t IPEND16         : 1;
+            __IOM uint32_t IPEND17         : 1;
+            __IOM uint32_t IPEND18         : 1;
+            __IOM uint32_t IPEND19         : 1;
+            __IOM uint32_t IPEND20         : 1;
+            __IOM uint32_t IPEND21         : 1;
+            __IOM uint32_t IPEND22         : 1;
+            __IM   uint32_t RESERVED       : 9;
+        } IPEND_B;
+    };
+} EINT_T;
+
+/**
+ * @brief    Independent WATCHDOG (IWDT)
+ */
+typedef struct
+{
+    union
+    {
+        __IOM uint32_t KEY;
+
+        struct
+        {
+            __OM   uint32_t KEY            : 16;
+            __IM   uint32_t RESERVED       : 16;
+        } KEY_B;
+    };
+
+    union
+    {
+        __IOM uint32_t PSC;
+
+        struct
+        {
+            __IOM  uint32_t PSC            : 3;
+            __IM   uint32_t RESERVED       : 29;
+        } PSC_B;
+    };
+
+    union
+    {
+        __IOM uint32_t CNTRLD;
+
+        struct
+        {
+            __IOM  uint32_t CNTRLD         : 12;
+            __IM   uint32_t RESERVED       : 20;
+        } CNTRLD_B;
+    };
+
+    union
+    {
+        __IM uint32_t STS;
+
+        struct
+        {
+            __IM   uint32_t PSCUFLG        : 1;
+            __IM   uint32_t CNTUFLG        : 1;
+            __IM   uint32_t RESERVED       : 30;
+        } STS_B;
+    };
+} IWDT_T;
+
+/**
+ * @brief    Window WATCHDOG (WWDT)
+ */
+typedef struct
+{
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM  uint32_t CNT            : 7;
+            __IOM  uint32_t WWDTEN         : 1;
+            __IM   uint32_t RESERVED       : 24;
+        } CTRL_B;
+    };
+
+    union
+    {
+        __IOM uint32_t CFG;
+
+        struct
+        {
+            __IOM  uint32_t WIN            : 7;
+            __IOM  uint32_t TBPSC          : 2;
+            __IOM  uint32_t EWIEN          : 1;
+            __IM   uint32_t RESERVED       : 22;
+        } CFG_B;
+    };
+
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IOM  uint32_t EWIFLG          : 1;
+            __IM   uint32_t RESERVED       : 31;
+        } STS_B;
+    };
+} WWDT_T;
+
+/**
+ * @brief Serial peripheral interface(SPI)
+ */
+typedef struct
+{
+    /** Control register 1 */
+    union
+    {
+        __IOM uint32_t CTRL1;
+
+        struct
+        {
+            __IOM uint32_t CPHA            : 1;
+            __IOM uint32_t CPOL            : 1;
+            __IOM uint32_t MSMCFG          : 1;
+            __IOM uint32_t BRSEL           : 3;
+            __IOM uint32_t SPIEN           : 1;
+            __IOM uint32_t LSBSEL          : 1;
+            __IOM uint32_t ISSEL           : 1;
+            __IOM uint32_t SSEN            : 1;
+            __IOM uint32_t RXOMEN          : 1;
+            __IOM uint32_t DFLSEL          : 1;
+            __IOM uint32_t CRCNXT          : 1;
+            __IOM uint32_t CRCEN           : 1;
+            __IOM uint32_t BMOEN           : 1;
+            __IOM uint32_t BMEN            : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } CTRL1_B;
+    };
+
+    /** Control register 2 */
+    union
+    {
+        __IOM uint32_t CTRL2;
+
+        struct
+        {
+            __IOM uint32_t RXDEN           : 1;
+            __IOM uint32_t TXDEN           : 1;
+            __IOM uint32_t SSOEN           : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t FRFCFG          : 1;
+            __IOM uint32_t ERRIEN          : 1;
+            __IOM uint32_t RXBNEIEN        : 1;
+            __IOM uint32_t TXBEIEN         : 1;
+            __IM  uint32_t RESERVED2       : 24;
+        } CTRL2_B;
+    };
+
+    /** Status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IM  uint32_t RXBNEFLG        : 1;
+            __IM  uint32_t TXBEFLG         : 1;
+            __IM  uint32_t SCHDIR          : 1;
+            __IM  uint32_t UDRFLG          : 1;
+            __IOM uint32_t CRCEFLG         : 1;
+            __IM  uint32_t MEFLG           : 1;
+            __IM  uint32_t OVRFLG          : 1;
+            __IM  uint32_t BSYFLG          : 1;
+            __IM  uint32_t FFERR           : 1;
+            __IM  uint32_t RESERVED        : 23;
+        } STS_B;
+    };
+
+    /** Data register */
+    union
+    {
+        __IOM uint32_t DATA;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 16;
+            __IM  uint32_t RESERVED        : 16;
+        } DATA_B;
+    };
+
+    /** CRC polynomial register */
+    union
+    {
+        __IOM uint32_t CRCPOLY;
+
+        struct
+        {
+            __IOM uint32_t CRCPOLY         : 16;
+            __IM  uint32_t RESERVED        : 16;
+        } CRCPOLY_B;
+    };
+
+    /** Receive CRC register */
+    union
+    {
+        __IM uint32_t RXCRC;
+
+        struct
+        {
+            __IM  uint32_t RXCRC           : 16;
+            __IM  uint32_t RESERVED        : 16;
+        } RXCRC_B;
+    };
+
+    /** Transmit CRC register */
+    union
+    {
+        __IM uint32_t TXCRC;
+
+        struct
+        {
+            __IM  uint32_t TXCRC           : 16;
+            __IM  uint32_t RESERVED        : 16;
+        } TXCRC_B;
+    };
+
+    /** Transmit I2S CTRL register */
+    union
+    {
+        __IOM uint32_t I2SCFG;
+
+        struct
+        {
+            __IOM uint32_t CHLEN           : 1;
+            __IOM uint32_t DATLEN          : 2;
+            __IOM uint32_t CPOL            : 1;
+            __IOM uint32_t I2SSSEL         : 2;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t PFSSEL          : 1;
+            __IOM uint32_t I2SMOD          : 2;
+            __IOM uint32_t I2SEN           : 1;
+            __IOM uint32_t MODESEL         : 1;
+            __IM  uint32_t RESERVED2       : 20;
+        } I2SCFG_B;
+    };
+
+    /** Transmit I2S DIV register */
+    union
+    {
+        __IOM uint32_t I2SPSC;
+
+        struct
+        {
+            __IOM uint32_t I2SPSC          : 8;
+            __IOM uint32_t ODDPSC          : 1;
+            __IOM uint32_t MCOEN           : 1;
+            __IM  uint32_t RESERVED        : 22;
+        } I2SPSC_B;
+    };
+} SPI_T;
+
+/**
+ * @brief Secure digital input/output interface (SDIO)
+ */
+typedef struct
+{
+    /** Power control register */
+    union
+    {
+        __IOM uint32_t PWRCTRL;
+
+        struct
+        {
+            __IOM  uint32_t PWRCTRL        : 2;
+            __IM   uint32_t RESERVED       : 30;
+        } PWRCTRL_B;
+    };
+
+    /** Clock control register */
+    union
+    {
+        __IOM uint32_t CLKCTRL;
+
+        struct
+        {
+            __IOM uint32_t CLKDIV          : 8;
+            __IOM uint32_t CLKEN           : 1;
+            __IOM uint32_t PWRSAV          : 1;
+            __IOM uint32_t BYPASSEN        : 1;
+            __IOM uint32_t WBSEL           : 2;
+            __IOM uint32_t DEPSEL          : 1;
+            __IOM uint32_t HFCEN           : 1;
+            __IM  uint32_t RESERVED        : 17;
+        } CLKCTRL_B;
+    };
+
+    /** Argument register */
+    union
+    {
+        __IOM uint32_t ARG;
+
+        struct
+        {
+            __IOM  uint32_t CMDARG         : 32;
+        } ARG_B;
+    };
+
+    /** Command register */
+    union
+    {
+        __IOM uint32_t CMD;
+
+        struct
+        {
+            __IOM uint32_t CMDINDEX        : 6;
+            __IOM uint32_t WAITRES         : 2;
+            __IOM uint32_t WAITINT         : 1;
+            __IOM uint32_t WENDDATA        : 1;
+            __IOM uint32_t CPSMEN          : 1;
+            __IOM uint32_t SDIOSC          : 1;
+            __IOM uint32_t CMDCPEN         : 1;
+            __IOM uint32_t INTEN           : 1;
+            __IOM uint32_t ATACMD          : 1;
+            __IM  uint32_t RESERVED        : 17;
+        } CMD_B;
+    };
+
+    /** Command response register */
+    union
+    {
+        __IM uint32_t CMDRES;
+
+        struct
+        {
+            __IM  uint32_t CMDRES          : 6;
+            __IM  uint32_t RESERVED        : 26;
+        } CMDRES_B;
+    };
+
+    /** SDIO response register1 */
+    union
+    {
+        __IM uint32_t RES1;
+
+        struct
+        {
+            __IM  uint32_t CARDSTS1        : 32;
+        } RES1_B;
+    };
+
+    /** SDIO response register2 */
+    union
+    {
+        __IM uint32_t RES2;
+
+        struct
+        {
+            __IM  uint32_t CARDSTS2        : 32;
+        } RES2_B;
+    };
+
+    /** SDIO response register3 */
+    union
+    {
+        __IM uint32_t RES3;
+
+        struct
+        {
+            __IM  uint32_t CARDSTS3        : 32;
+        } RES3_B;
+    };
+
+    /** SDIO response register4 */
+    union
+    {
+        __IM uint32_t RES4;
+
+        struct
+        {
+            __IM  uint32_t CARDSTS4        : 32;
+        } RES4_B;
+    };
+
+    /** Data timer register */
+    union
+    {
+        __IOM uint32_t DATATIME;
+
+        struct
+        {
+            __IOM  uint32_t DATATIME       : 32;
+        } DTMR_B;
+    };
+
+    /** Data length register */
+    union
+    {
+        __IOM uint32_t DATALEN;
+
+        struct
+        {
+            __IOM uint32_t DATALEN         : 25;
+            __IM  uint32_t RESERVED        : 7;
+        } DLEN_B;
+    };
+
+    /** Data control register */
+    union
+    {
+        __IOM uint32_t DCTRL;
+
+        struct
+        {
+            __IOM uint32_t DTEN            : 1;
+            __IOM uint32_t DTDRCFG         : 1;
+            __IOM uint32_t DTSEL           : 1;
+            __IOM uint32_t DMAEN           : 1;
+            __IOM uint32_t DBSIZE          : 4;
+            __IOM uint32_t RWSTR           : 1;
+            __IOM uint32_t RWSTOP          : 1;
+            __IOM uint32_t RDWAIT          : 1;
+            __IOM uint32_t SDIOF           : 1;
+            __IM  uint32_t RESERVED        : 20;
+        } DCTRL_B;
+    };
+
+    /** Data count register */
+    union
+    {
+        __IM uint32_t DCNT;
+
+        struct
+        {
+            __IM  uint32_t DATACNT         : 25;
+            __IM  uint32_t RESERVED        : 7;
+        } DCNT_B;
+    };
+
+    /** SDIO status register */
+    union
+    {
+        __IM uint32_t STS;
+
+        struct
+        {
+            __IM  uint32_t COMRESP         : 1;
+            __IM  uint32_t DBDR            : 1;
+            __IM  uint32_t CMDRESTO        : 1;
+            __IM  uint32_t DATATO          : 1;
+            __IM  uint32_t TXUDRER         : 1;
+            __IM  uint32_t RXOVRER         : 1;
+            __IM  uint32_t CMDRES          : 1;
+            __IM  uint32_t CMDSENT         : 1;
+            __IM  uint32_t DATAEND         : 1;
+            __IM  uint32_t SBE             : 1;
+            __IM  uint32_t DBCP            : 1;
+            __IM  uint32_t CMDACT          : 1;
+            __IM  uint32_t TXACT           : 1;
+            __IM  uint32_t RXACT           : 1;
+            __IM  uint32_t TXFHF           : 1;
+            __IM  uint32_t RXFHF           : 1;
+            __IM  uint32_t TXFF            : 1;
+            __IM  uint32_t RXFF            : 1;
+            __IM  uint32_t TXFE            : 1;
+            __IM  uint32_t RXFE            : 1;
+            __IM  uint32_t TXDA            : 1;
+            __IM  uint32_t RXDA            : 1;
+            __IM  uint32_t SDIOINT         : 1;
+            __IM  uint32_t ATAEND          : 1;
+            __IM  uint32_t RESERVED        : 8;
+        } STS_B;
+    };
+
+    /** SDIO interrupt clear register */
+    union
+    {
+        __IOM uint32_t ICF;
+
+        struct
+        {
+            __IOM uint32_t DBCE            : 1;
+            __IOM uint32_t CRCE            : 1;
+            __IOM uint32_t CRTO            : 1;
+            __IOM uint32_t DTO             : 1;
+            __IOM uint32_t TXFUE           : 1;
+            __IOM uint32_t RXFOE           : 1;
+            __IOM uint32_t CMDRES          : 1;
+            __IOM uint32_t CMDSENT         : 1;
+            __IOM uint32_t DATAEND         : 1;
+            __IOM uint32_t SBE             : 1;
+            __IOM uint32_t DBCP            : 1;
+            __IM  uint32_t RESERVED1       : 11;
+            __IOM uint32_t SDIOIT          : 1;
+            __IOM uint32_t ATAEND          : 1;
+            __IM  uint32_t RESERVED2       : 8;
+        } ICF_B;
+    };
+
+    /** SDIO interrupt mask register */
+    union
+    {
+        __IOM uint32_t MASK;
+
+        struct
+        {
+            __IOM uint32_t CCRCFAIL        : 1;
+            __IOM uint32_t DCRCFAIL        : 1;
+            __IOM uint32_t CMDTO           : 1;
+            __IOM uint32_t DATATO          : 1;
+            __IOM uint32_t TXURER          : 1;
+            __IOM uint32_t RXORER          : 1;
+            __IOM uint32_t CMDRESRC        : 1;
+            __IOM uint32_t CMDSENT         : 1;
+            __IOM uint32_t DATAEND         : 1;
+            __IOM uint32_t STRTER          : 1;
+            __IOM uint32_t DBEND           : 1;
+            __IOM uint32_t CMDACT          : 1;
+            __IOM uint32_t TXACT           : 1;
+            __IOM uint32_t RXACT           : 1;
+            __IOM uint32_t TXHFERT         : 1;
+            __IOM uint32_t RXHFFUL         : 1;
+            __IOM uint32_t TXFUL           : 1;
+            __IOM uint32_t RXFUL           : 1;
+            __IOM uint32_t TXEPT           : 1;
+            __IOM uint32_t RXFEIE          : 1;
+            __IOM uint32_t TXDAVB          : 1;
+            __IOM uint32_t RXDAVB          : 1;
+            __IOM uint32_t SDIOINTREC      : 1;
+            __IOM uint32_t ATACLPREC       : 1;
+            __IM  uint32_t RESERVED        : 8;
+        } MASK_B;
+    };
+
+    __IM  uint32_t  RESERVED[2];
+
+    /** SDIO FIFO count register */
+    union
+    {
+        __IM uint32_t FIFOCNT;
+
+        struct
+        {
+            __IM  uint32_t FIFOCNT         : 24;
+            __IM  uint32_t RESERVED        : 8;
+        } FIFOCNT_B;
+    };
+
+    __IM  uint32_t  RESERVED1[13];
+
+    /** SDIO data FIFO register */
+    union
+    {
+        __IOM uint32_t FIFODATA;
+
+        struct
+        {
+            __IOM  uint32_t FIFODATA       : 32;
+        } FIFODATA_B;
+    };
+} SDIO_T;
+
+/**
+ * @brief Digital to Analog Converter(DAC)
+ */
+typedef struct
+{
+    /** Control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t ENCH1           : 1;
+            __IOM uint32_t BUFFDCH1        : 1;
+            __IOM uint32_t TRGENCH1        : 1;
+            __IOM uint32_t TRGSELCH1       : 3;
+            __IOM uint32_t WAVENCH1        : 2;
+            __IOM uint32_t MAMPSELCH1      : 4;
+            __IOM uint32_t DMAENCH1        : 1;
+            __IOM uint32_t DMAUDIEN1       : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t ENCH2           : 1;
+            __IOM uint32_t BUFFDCH2        : 1;
+            __IOM uint32_t TRGENCH2        : 1;
+            __IOM uint32_t TRGSELCH2       : 3;
+            __IOM uint32_t WAVENCH2        : 2;
+            __IOM uint32_t MAMPSELCH2      : 4;
+            __IOM uint32_t DMAENCH2        : 1;
+            __IOM uint32_t DMAUDIEN2       : 1;
+            __IM  uint32_t RESERVED2       : 2;
+        } CTRL_B;
+    };
+
+    /** Software trigger register */
+    union
+    {
+        __OM uint32_t SWTRG;
+
+        struct
+        {
+            __OM   uint32_t SWTRG1         : 1;
+            __OM   uint32_t SWTRG2         : 1;
+            __IM   uint32_t RESERVED       : 30;
+        } SWTRG_B;
+    };
+
+    /** Channel1 12-bit right-aligned register */
+    union
+    {
+        __IOM uint32_t DH12R1;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 12;
+            __IM  uint32_t RESERVED        : 20;
+        } DH12R1_B;
+    };
+
+    /** Channel1 12-bit left-aligned register */
+    union
+    {
+        __IOM uint32_t DH12L1;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 4;
+            __IOM uint32_t DATA            : 12;
+            __IM  uint32_t RESERVED2       : 16;
+        } DH12L1_B;
+    };
+
+    /** Channel1 8-bit right-aligned register */
+    union
+    {
+        __IOM uint32_t DH8R1;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 8;
+            __IM  uint32_t RESERVED        : 24;
+        } DH8R1_B;
+    };
+
+    /** Channel2 12-bit right-aligned register */
+    union
+    {
+        __IOM uint32_t DH12R2;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 12;
+            __IM  uint32_t RESERVED        : 20;
+        } DH12R2_B;
+    };
+
+    /** Channel2 12-bit left-aligned register */
+    union
+    {
+        __IOM uint32_t DH12L2;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 4;
+            __IOM uint32_t DATA            : 12;
+            __IM  uint32_t RESERVED2       : 16;
+        } DH12L2_B;
+    };
+
+    /** Channel2 8-bit right-aligned register */
+    union
+    {
+        __IOM uint32_t DH8R2;
+
+        struct
+        {
+            __IOM uint32_t DATA            : 8;
+            __IM  uint32_t RESERVED        : 24;
+        } DH8R2_B;
+    };
+
+    /** Channel1,Channel2 12-bit right-aligned register */
+    union
+    {
+        __IOM uint32_t DH12RDUAL;
+
+        struct
+        {
+            __IOM uint32_t DATACH1         : 12;
+            __IM  uint32_t RESERVED1       : 4;
+            __IOM uint32_t DATACH2         : 12;
+            __IM  uint32_t RESERVED2       : 4;
+        } DH12RDUAL_B;
+    };
+
+    /** Channel1,Channel2 12-bit left-aligned register */
+    union
+    {
+        __IOM uint32_t DH12LDUAL;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 4;
+            __IOM uint32_t DATACH1         : 12;
+            __IM  uint32_t RESERVED2       : 4;
+            __IOM uint32_t DATACH2         : 12;
+        } DH12LDUAL_B;
+    };
+
+    /** Channel1,Channel2 8-bit right-aligned register */
+    union
+    {
+        __IOM uint32_t DH8RDUAL;
+
+        struct
+        {
+            __IOM uint32_t DATACH1         : 8;
+            __IOM uint32_t DATACH2         : 8;
+            __IM  uint32_t RESERVED        : 16;
+        } DH8RDUAL_B;
+    };
+
+    /** Channel1 data output register */
+    union
+    {
+        __IM uint32_t DATAOCH1;
+
+        struct
+        {
+            __IM  uint32_t DATA            : 12;
+            __IM  uint32_t RESERVED        : 20;
+        } DATAOCH1_B;
+    };
+
+    /** Channel2 data output register */
+    union
+    {
+        __IM uint32_t DATAOCH2;
+
+        struct
+        {
+            __IM  uint32_t DATA            : 12;
+            __IM  uint32_t RESERVED        : 20;
+        } DATAOCH2_B;
+    };
+
+    /** DAC status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 13;
+            __IOM uint32_t DMAUDFLG1       : 1;
+            __IM  uint32_t RESERVED2       : 15;
+            __IOM uint32_t DMAUDFLG2       : 1;
+            __IM  uint32_t RESERVED3       : 2;
+        } STS_B;
+    };
+} DAC_T;
+
+/**
+ * @brief Static Memory Controller (SMC) Bank1
+ */
+typedef struct
+{
+    /** SRAM/NOR-Flash chip-select control register 1 */
+    union
+    {
+        __IOM uint32_t CSCTRL1;
+
+        struct
+        {
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t ADMUXEN         : 1;
+            __IOM uint32_t MTYPECFG        : 2;
+            __IOM uint32_t MDBWIDCFG       : 2;
+            __IOM uint32_t NORFMACCEN      : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t BURSTEN         : 1;
+            __IOM uint32_t WSPOLCFG        : 1;
+            __IOM uint32_t WRAPBEN         : 1;
+            __IOM uint32_t WTIMCFG         : 1;
+            __IOM uint32_t WREN            : 1;
+            __IOM uint32_t WAITEN          : 1;
+            __IOM uint32_t EXTMODEEN       : 1;
+            __IOM uint32_t WSASYNCEN       : 1;
+            __IOM uint32_t CRAMPSIZECFG    : 3;
+            __IOM uint32_t WRBURSTEN       : 1;
+            __IM  uint32_t RESERVED2       : 12;
+        } CSCTRL1_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select timing register 1 */
+    union
+    {
+        __IOM uint32_t CSTIM1;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } CSTIM1_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select control register 2 */
+    union
+    {
+        __IOM uint32_t CSCTRL2;
+
+        struct
+        {
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t ADMUXEN         : 1;
+            __IOM uint32_t MTYPECFG        : 2;
+            __IOM uint32_t MDBWIDCFG       : 2;
+            __IOM uint32_t NORFMACCEN      : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t BURSTEN         : 1;
+            __IOM uint32_t WSPOLCFG        : 1;
+            __IOM uint32_t WRAPBEN         : 1;
+            __IOM uint32_t WTIMCFG         : 1;
+            __IOM uint32_t WREN            : 1;
+            __IOM uint32_t WAITEN          : 1;
+            __IOM uint32_t EXTMODEEN       : 1;
+            __IOM uint32_t WSASYNCEN       : 1;
+            __IOM uint32_t CRAMPSIZECFG    : 3;
+            __IOM uint32_t WRBURSTEN       : 1;
+            __IM  uint32_t RESERVED2       : 12;
+        } CSCTRL2_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select timing register 2 */
+    union
+    {
+        __IOM uint32_t CSTIM2;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } CSTIM2_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select control register 3 */
+    union
+    {
+        __IOM uint32_t CSCTRL3;
+
+        struct
+        {
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t ADMUXEN         : 1;
+            __IOM uint32_t MTYPECFG        : 2;
+            __IOM uint32_t MDBWIDCFG       : 2;
+            __IOM uint32_t NORFMACCEN      : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t BURSTEN         : 1;
+            __IOM uint32_t WSPOLCFG        : 1;
+            __IOM uint32_t WRAPBEN         : 1;
+            __IOM uint32_t WTIMCFG         : 1;
+            __IOM uint32_t WREN            : 1;
+            __IOM uint32_t WAITEN          : 1;
+            __IOM uint32_t EXTMODEEN       : 1;
+            __IOM uint32_t WSASYNCEN       : 1;
+            __IOM uint32_t CRAMPSIZECFG    : 3;
+            __IOM uint32_t WRBURSTEN       : 1;
+            __IM  uint32_t RESERVED2       : 12;
+        } CSCTRL3_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select timing register 3 */
+    union
+    {
+        __IOM uint32_t CSTIM3;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } CSTIM3_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select control register 4 */
+    union
+    {
+        __IOM uint32_t CSCTRL4;
+
+        struct
+        {
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t ADMUXEN         : 1;
+            __IOM uint32_t MTYPECFG        : 2;
+            __IOM uint32_t MDBWIDCFG       : 2;
+            __IOM uint32_t NORFMACCEN      : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t BURSTEN         : 1;
+            __IOM uint32_t WSPOLCFG        : 1;
+            __IOM uint32_t WRAPBEN         : 1;
+            __IOM uint32_t WTIMCFG         : 1;
+            __IOM uint32_t WREN            : 1;
+            __IOM uint32_t WAITEN          : 1;
+            __IOM uint32_t EXTMODEEN       : 1;
+            __IOM uint32_t WSASYNCEN       : 1;
+            __IOM uint32_t CRAMPSIZECFG    : 3;
+            __IOM uint32_t WRBURSTEN       : 1;
+            __IM  uint32_t RESERVED2       : 12;
+        } CSCTRL4_B;
+    };
+
+    /** SRAM/NOR-Flash chip-select timing register 4 */
+    union
+    {
+        __IOM uint32_t CSTIM4;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } CSTIM4_B;
+    };
+} SMC_Bank1_T;
+
+/**
+ * @brief Static Memory Controller (SMC) Bank1E
+ */
+typedef struct
+{
+    /** SRAM/NOR-Flash write timing registers 1 */
+    union
+    {
+        __IOM uint32_t WRTTIM1;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } WRTTIM1_B;
+    };
+
+    __IM  uint32_t  RESERVED;
+
+    /** SRAM/NOR-Flash write timing registers 2 */
+    union
+    {
+        __IOM uint32_t WRTTIM2;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } WRTTIM2_B;
+    };
+
+    __IM  uint32_t  RESERVED1;
+
+    /** SRAM/NOR-Flash write timing registers 3 */
+    union
+    {
+        __IOM uint32_t WRTTIM3;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } WRTTIM3_B;
+    };
+
+    __IOM  uint32_t  RESERVED2;
+
+    /** SRAM/NOR-Flash write timing registers 4 */
+    union
+    {
+        __IOM uint32_t WRTTIM4;
+
+        struct
+        {
+            __IOM uint32_t ADDRSETCFG      : 4;
+            __IOM uint32_t ADDRHLDCFG      : 4;
+            __IOM uint32_t DATASETCFG      : 8;
+            __IOM uint32_t BUSTURNCFG      : 4;
+            __IOM uint32_t CLKDIVCFG       : 4;
+            __IOM uint32_t DATALATCFG      : 4;
+            __IOM uint32_t ASYNCACCCFG     : 2;
+            __IM  uint32_t RESERVED        : 2;
+        } WRTTIM4_B;
+    };
+} SMC_Bank1E_T;
+
+/**
+ * @brief  Static Memory Controller (SMC) Bank 2
+ */
+typedef struct
+{
+    /** PC Card/NAND Flash control register 2 */
+    union
+    {
+        __IOM uint32_t CTRL2;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t WAITFEN         : 1;
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t MTYPECFG        : 1;
+            __IOM uint32_t DBWIDCFG        : 2;
+            __IOM uint32_t ECCEN           : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t C2RDCFG         : 4;
+            __IOM uint32_t A2RDCFG         : 4;
+            __IOM uint32_t ECCPSCFG        : 3;
+            __IM  uint32_t RESERVED3       : 12;
+        } CTRL2_B;
+    };
+
+    /** FIFO status and interrupt register 2 */
+    union
+    {
+        __IOM uint32_t STSINT2;
+
+        struct
+        {
+            __IOM uint32_t IREFLG          : 1;
+            __IOM uint32_t IHLFLG          : 1;
+            __IOM uint32_t IFEFLG          : 1;
+            __IOM uint32_t IREDEN          : 1;
+            __IOM uint32_t IHLDEN          : 1;
+            __IOM uint32_t IFEDEN          : 1;
+            __IM  uint32_t FEFLG           : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } STSINT2_B;
+    };
+    /** Common memory space timing register 2 */
+    union
+    {
+        __IOM uint32_t CMSTIM2;
+
+        struct
+        {
+            __IOM uint32_t SET2            : 8;
+            __IOM uint32_t WAIT2           : 8;
+            __IOM uint32_t HLD2            : 8;
+            __IOM uint32_t HIZ2            : 8;
+        } CMSTIM2_B;
+    };
+
+    /** Attribute memory space timing register 2 */
+    union
+    {
+        __IOM uint32_t AMSTIM2;
+
+        struct
+        {
+            __IOM uint32_t SET2            : 8;
+            __IOM uint32_t WAIT2           : 8;
+            __IOM uint32_t HLD2            : 8;
+            __IOM uint32_t HIZ2            : 8;
+        } AMSTIM2_B;
+    };
+
+    __IM uint32_t RESERVED;
+
+    /** ECC result register 2 */
+    union
+    {
+        __IM  uint32_t ECCRS2;
+
+        struct
+        {
+            __IM  uint32_t ECCRS2          : 32;
+        } ECCRS2_B;
+    };
+} SMC_Bank2_T;
+
+/**
+ * @brief Flexible Static Memory Controller (SMC) Bank 3
+ */
+typedef struct
+{
+    /** PC Card/NAND Flash control register 3 */
+    union
+    {
+        __IOM uint32_t CTRL3;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t WAITFEN         : 1;
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t MTYPECFG        : 1;
+            __IOM uint32_t DBWIDCFG        : 2;
+            __IOM uint32_t ECCEN           : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t C2RDCFG         : 4;
+            __IOM uint32_t A2RDCFG         : 4;
+            __IOM uint32_t ECCPSCFG        : 3;
+            __IM  uint32_t RESERVED3       : 12;
+        } CTRL3_B;
+    };
+
+    /** FIFO status and interrupt register 3 */
+    union
+    {
+        __IOM uint32_t STSINT3;
+
+        struct
+        {
+            __IOM uint32_t IREFLG          : 1;
+            __IOM uint32_t IHLFLG          : 1;
+            __IOM uint32_t IFEFLG          : 1;
+            __IOM uint32_t IREDEN          : 1;
+            __IOM uint32_t IHLDEN          : 1;
+            __IOM uint32_t IFEDEN          : 1;
+            __IM  uint32_t FEFLG           : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } STSINT3_B;
+    };
+
+    /** Common memory space timing register 3 */
+    union
+    {
+        __IOM uint32_t CMSTIM3;
+
+        struct
+        {
+            __IOM uint32_t SET3            : 8;
+            __IOM uint32_t WAIT3           : 8;
+            __IOM uint32_t HLD3            : 8;
+            __IOM uint32_t HIZ3            : 8;
+        } CMSTIM3_B;
+    };
+
+    /** Attribute memory space timing register 3 */
+    union
+    {
+        __IOM uint32_t AMSTIM3;
+
+        struct
+        {
+            __IOM uint32_t SET3            : 8;
+            __IOM uint32_t WAIT3           : 8;
+            __IOM uint32_t HLD3            : 8;
+            __IOM uint32_t HIZ3            : 8;
+        } AMSTIM3_B;
+    };
+
+    __IM uint32_t RESERVED;
+
+    /** ECC result register 3 */
+    union
+    {
+        __IM  uint32_t ECCRS3;
+
+        struct
+        {
+            __IM  uint32_t ECCRS3       : 32;
+        } ECCRS3_B;
+    };
+} SMC_Bank3_T;
+
+/**
+ * @brief Flexible Static Memory Controller (SMC) Bank 4
+ */
+typedef struct
+{
+    /** PC Card/NAND Flash control register 4 */
+    union
+    {
+        __IOM uint32_t CTRL4;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 1;
+            __IOM uint32_t WAITFEN         : 1;
+            __IOM uint32_t MBKEN           : 1;
+            __IOM uint32_t MTYPECFG        : 1;
+            __IOM uint32_t DBWIDCFG        : 2;
+            __IOM uint32_t ECCEN           : 1;
+            __IM  uint32_t RESERVED2       : 2;
+            __IOM uint32_t C2RDCFG         : 4;
+            __IOM uint32_t A2RDCFG         : 4;
+            __IOM uint32_t ECCPSCFG        : 3;
+            __IM  uint32_t RESERVED3       : 12;
+        } CTRL4_B;
+    };
+
+    /** FIFO status and interrupt register 4 */
+    union
+    {
+        __IOM uint32_t STSINT4;
+
+        struct
+        {
+            __IOM uint32_t IREFLG          : 1;
+            __IOM uint32_t IHLFLG          : 1;
+            __IOM uint32_t IFEFLG          : 1;
+            __IOM uint32_t IREDEN          : 1;
+            __IOM uint32_t IHLDEN          : 1;
+            __IOM uint32_t IFEDEN          : 1;
+            __IM  uint32_t FEFLG           : 1;
+            __IM  uint32_t RESERVED        : 16;
+        } STSINT4_B;
+    };
+
+    /** Common memory space timing register 4 */
+    union
+    {
+        __IOM uint32_t CMSTIM4;
+
+        struct
+        {
+            __IOM uint32_t SET4            : 8;
+            __IOM uint32_t WAIT4           : 8;
+            __IOM uint32_t HLD4            : 8;
+            __IOM uint32_t HIZ4            : 8;
+        } CMSTIM4_B;
+    };
+
+    /** Attribute memory space timing register 4 */
+    union
+    {
+        __IOM uint32_t AMSTIM4;
+
+        struct
+        {
+            __IOM uint32_t SET4            : 8;
+            __IOM uint32_t WAIT4           : 8;
+            __IOM uint32_t HLD4            : 8;
+            __IOM uint32_t HIZ4            : 8;
+        } AMSTIM4_B;
+    };
+
+    /** I/O space timing register 4 */
+    union
+    {
+        __IOM uint32_t IOSTIM4;
+
+        struct
+        {
+            __IOM uint32_t SET             : 8;
+            __IOM uint32_t WAIT            : 8;
+            __IOM uint32_t HLD             : 8;
+            __IOM uint32_t HIZ             : 8;
+        } IOSTIM4_B;
+    };
+} SMC_Bank4_T;
+
+/**
+ * @brief Dynamic memory controler (DMC)
+ */
+typedef struct
+{
+    /** @brief Configuraion register */
+    union
+    {
+        __IOM uint32_t CFG;
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t BAWCFG          : 2;
+            __IOM uint32_t RAWCFG          : 4;
+            __IOM uint32_t CAWCFG          : 4;
+            __IOM uint32_t DWCFG           : 2;
+            __IM  uint32_t RESERVED2       : 17;
+        } CFG_B;
+    };
+
+    /** @brief Timing register 0 */
+    union
+    {
+        __IOM uint32_t TIM0;
+        struct
+        {
+            __IOM uint32_t CASLSEL0        : 2;
+            __IOM uint32_t RASMINTSEL      : 4;
+            __IOM uint32_t DTIMSEL         : 3;
+            __IOM uint32_t PCPSEL          : 3;
+            __IOM uint32_t WRTIMSEL        : 2;
+            __IOM uint32_t ARPSEL          : 4;
+            __IOM uint32_t XSR0            : 4;
+            __IOM uint32_t ATACP           : 4;
+            __IOM uint32_t ECASLSEL1       : 1;
+            __IOM uint32_t EXSR1           : 5;
+        } TIM0_B;
+    };
+
+    /** @brief Timing register 1 */
+    union
+    {
+        __IOM uint32_t TIM1;
+        struct
+        {
+            __IOM uint32_t STBTIM          : 16;
+            __IOM uint32_t ARNUMCFG        : 4;
+            __IM  uint32_t RESERVED        : 12;
+        } TIM1_B;
+    };
+
+    /** @brief Control register 1 */
+    union
+    {
+        __IOM uint32_t CTRL1;
+        struct
+        {
+            __IOM uint32_t INIT            : 1;
+            __IOM uint32_t SRMEN           : 1;
+            __IOM uint32_t PDMEN           : 1;
+            __IOM uint32_t PCACFG          : 1;
+            __IOM uint32_t FRBSREN         : 1;
+            __IOM uint32_t FRASREN         : 1;
+            __IOM uint32_t RDNUMMCFG       : 3;
+            __IOM uint32_t MODESET         : 1;
+            __IM  uint32_t RESERVED1       : 1;
+            __IM  uint32_t SRMFLG          : 1;
+            __IOM uint32_t BANKNUMCFG      : 4;
+            __IM  uint32_t RESERVED2       : 16;
+        } CTRL1_B;
+    };
+
+    /** @brief Refresh register */
+    union
+    {
+        __IOM uint32_t REF;
+        struct
+        {
+            __IOM uint32_t RCYCCFG         : 16;
+            __IM  uint32_t RESERVED        : 16;
+        } REF_B;
+    };
+
+    __IM uint32_t RESERVED[251];
+
+    /** @brief Switch register */
+    union
+    {
+        __IOM uint32_t SW;
+        struct
+        {
+            __IOM uint32_t MCSW            : 1;
+            __IM  uint32_t RESERVED        : 31;
+        } SW_B;
+    };
+
+    /** @brief Control register 2 */
+    union
+    {
+        __IOM uint32_t CTRL2;
+        struct
+        {
+            __IOM uint32_t CPHACFG         : 1;
+            __IOM uint32_t RDDEN           : 1;
+            __IOM uint32_t RDDCFG          : 3;
+            __IOM uint32_t WPEN            : 1;
+            __IOM uint32_t BUFFEN          : 1;
+            __IOM uint32_t WRPBSEL         : 1;
+            __IM  uint32_t RESERVED        : 24;
+        } CTRL2_B;
+    };
+} DMC_T;
+
+/**
+ * @brief Debug MCU(DBGMCU)
+ */
+typedef struct
+{
+    /** @brief ID register */
+    union
+    {
+        __IM  uint32_t IDCODE;
+        struct
+        {
+            __IM  uint32_t EQR             : 12;
+            __IM  uint32_t RESERVED        : 4;
+            __IM  uint32_t WVR             : 16;
+        } IDCODE_B;
+    };
+
+    /** @brief Control register */
+    union
+    {
+        __IOM uint32_t CFG;
+        struct
+        {
+            __IOM uint32_t SLEEP_CLK_STS   : 1;
+            __IOM uint32_t STOP_CLK_STS    : 1;
+            __IOM uint32_t STANDBY_CLK_STS : 1;
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t TRACE_IOEN      : 1;
+            __IOM uint32_t TRACE_MODE      : 2;
+            __IM  uint32_t RESERVED2       : 24;
+        } CFG_B;
+    };
+
+    /** @brief APB1F register */
+    union
+    {
+        __IOM uint32_t APB1F;
+        struct
+        {
+            __IOM uint32_t TMR2_STS                  : 1;
+            __IOM uint32_t TMR3_STS                  : 1;
+            __IOM uint32_t TMR4_STS                  : 1;
+            __IOM uint32_t TMR5_STS                  : 1;
+            __IOM uint32_t TMR6_STS                  : 1;
+            __IOM uint32_t TMR7_STS                  : 1;
+            __IOM uint32_t TMR12_STS                 : 1;
+            __IOM uint32_t TMR13_STS                 : 1;
+            __IOM uint32_t TMR14_STS                 : 1;
+            __IM  uint32_t RESERVED1                 : 1;
+            __IOM uint32_t RTC_STS                   : 1;
+            __IOM uint32_t WWDT_STS                  : 1;
+            __IOM uint32_t IWDT_STS                  : 1;
+            __IM  uint32_t RESERVED2                 : 8;
+            __IOM uint32_t I2C1_SMBUS_TIMEOUT_STS    : 1;
+            __IOM uint32_t I2C2_SMBUS_TIMEOUT_STS    : 1;
+            __IOM uint32_t I2C3_SMBUS_TIMEOUT_STS    : 1;
+            __IM  uint32_t RESERVED3                 : 1;
+            __IOM uint32_t CAN1_STS                  : 1;
+            __IOM uint32_t CAN2_STS                  : 1;
+            __IM  uint32_t RESERVED4                 : 5;
+        } APB1F_B;
+    };
+
+    /** @brief APB2F register */
+    union
+    {
+        __IOM uint32_t APB2F;
+        struct
+        {
+            __IOM uint32_t TMR1_STS                  : 1;
+            __IOM uint32_t TMR8_STS                  : 1;
+            __IM  uint32_t RESERVED1                 : 14;
+            __IOM uint32_t TMR9_STS                  : 1;
+            __IOM uint32_t TMR10_STS                 : 1;
+            __IOM uint32_t TMR11_STS                 : 1;
+            __IM  uint32_t RESERVED2                 : 23;
+        } APB2F_B;
+    };
+} DBGMCU_T;
+
+/**
+ * @brief Digital camera interface (DCI)
+ */
+typedef struct
+{
+    /** @brief DCI control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t CEN           : 1;
+            __IOM uint32_t CMODE         : 1;
+            __IOM uint32_t CROPF         : 1;
+            __IOM uint32_t JPGFM         : 1;
+            __IOM uint32_t ESYNCSEL      : 1;
+            __IOM uint32_t PXCLKPOL      : 1;
+            __IOM uint32_t HSYNCPOL      : 1;
+            __IOM uint32_t VSYNCPOL      : 1;
+            __IOM uint32_t FCRCFG        : 2;
+            __IOM uint32_t EXDMOD        : 2;
+            __IM  uint32_t RESERVED1     : 2;
+            __IOM uint32_t DCIEN         : 1;
+            __IM  uint32_t RESERVED2     : 17;
+        } CTRL_B;
+    } ;
+
+    /** @brief DCI status register*/
+    union
+    {
+        __IM uint32_t STS;
+
+        struct
+        {
+            __IM uint32_t HSYNCSTS       : 1;
+            __IM uint32_t VSYNCSTS       : 1;
+            __IM uint32_t FIFONEMP       : 1;
+            __IM uint32_t RESERVED       : 29;
+        } STS_B;
+    };
+
+    /** @brief DCI raw interrupt status register */
+    union
+    {
+        __IM uint32_t RINTSTS;
+
+        struct
+        {
+            __IM uint32_t CC_RINT           : 1;
+            __IM uint32_t OVR_RINT          : 1;
+            __IM uint32_t SYNCERR_RINT      : 1;
+            __IM uint32_t VSYNC_RINT        : 1;
+            __IM uint32_t LINE_RINT         : 1;
+            __IM uint32_t RESERVED          : 27;
+        } RINTSTS_B;
+    };
+
+    /** @brief DCI interrupt enable register */
+    union
+    {
+        __IOM uint32_t INTEN;
+
+        struct
+        {
+            __IOM uint32_t CCINTEN           : 1;
+            __IOM uint32_t OVRINTEN          : 1;
+            __IOM uint32_t SYNCERRINTEN      : 1;
+            __IOM uint32_t VSYNCINTEN        : 1;
+            __IOM uint32_t LINEINTEN         : 1;
+            __IM  uint32_t RESERVED          : 22;
+        } INTEN_B;
+    };
+
+    /** @brief DCI masked interrupt status register */
+    union
+    {
+        __IM uint32_t MINTSTS;
+
+        struct
+        {
+            __IM uint32_t CC_MINT           : 1;
+            __IM uint32_t OVR_MINT          : 1;
+            __IM uint32_t SYNCERR_MINT      : 1;
+            __IM uint32_t VSYNC_MINT        : 1;
+            __IM uint32_t LINE_MINT         : 1;
+            __IM uint32_t RESERVED          : 27;
+        } MINTSTS_B;
+    };
+
+    /** @brief DCI interrupt clear registe */
+    union
+    {
+        __IOM uint32_t INTCLR;
+
+        struct
+        {
+            __OM uint32_t CC_INTCLR           : 1;
+            __OM uint32_t OVR_INTCLR          : 1;
+            __OM uint32_t SYNCERR_INTCLR      : 1;
+            __OM uint32_t VSYNC_INTCLR        : 1;
+            __OM uint32_t LINE_INTCLR         : 1;
+            __IM uint32_t RESERVED            : 22;
+        } INTCLR_B;
+    };
+
+    /** @brief DCI embedded synchronization code register */
+    union
+    {
+        __IOM uint32_t ESYNCC;
+
+        struct
+        {
+            __IOM uint32_t FSDC           : 8;
+            __IOM uint32_t LSDC           : 8;
+            __IOM uint32_t LEDC           : 8;
+            __IOM uint32_t FEDC           : 8;
+        } ESYNCC_B;
+    };
+
+    /** @brief DCI embedded synchronization unmask register */
+    union
+    {
+        __IOM uint32_t ESYNCUM;
+
+        struct
+        {
+            __IOM uint32_t FSDUM           : 8;
+            __IOM uint32_t LSDUM           : 8;
+            __IOM uint32_t LEDUM           : 8;
+            __IOM uint32_t FEDUM           : 8;
+        } ESYNCUM_B;
+    };
+
+    /** @brief DCI crop window start register */
+    union
+    {
+        __IOM uint32_t CROPWSTAT;
+
+        struct
+        {
+            __IOM uint32_t HOFSCNT           : 14;
+            __IM  uint32_t RESERVED1         : 2;
+            __IOM uint32_t VSLINECNT         : 13;
+            __IM  uint32_t RESERVED2         : 3;
+        } CROPWSTAT_B;
+    };
+
+    /** @brief DCI crop window size register */
+    union
+    {
+        __IOM uint32_t CROPWSIZE;
+
+        struct
+        {
+            __IOM uint32_t CCNT           : 14;
+            __IM  uint32_t RESERVED1      : 2;
+            __IOM uint32_t VLINECNT       : 14;
+            __IM  uint32_t RESERVED2      : 2;
+        } CROPWSIZE_B;
+    };
+
+    /** @brief DCI data register */
+    union
+    {
+        __IOM uint32_t DATA;
+
+        struct
+        {
+            __IM uint32_t DATA0          : 8;
+            __IM uint32_t DATA1          : 8;
+            __IM uint32_t DATA2          : 8;
+            __IM uint32_t DATA3          : 8;
+        } DATA_B;
+    };
+} DCI_T;
+
+/**
+ * @brief System configuration controller (SYSCFG)
+ */
+typedef struct
+{
+    union
+    {
+        __IOM uint32_t MMSEL;
+
+        struct
+        {
+            __IOM uint32_t MMSEL         : 2;
+            __IM  uint32_t RESERVED      : 30;
+        } MMSEL_B;
+    };
+    /** @brief Peripheral Mode Configuration register */
+    union
+    {
+        __IOM uint32_t PMC;
+
+        struct
+        {
+            __IM uint32_t RESERVED1        : 23;
+            __IOM uint32_t ENETSEL         : 1;
+            __IM uint32_t RESERVED2        : 8;
+        } PMC_B;
+    };
+
+    /** @brief External Interrupt Configuration register1 */
+    union
+    {
+        __IOM uint32_t EINTCFG1;
+
+        struct
+        {
+            __IOM uint32_t EINT0           : 4;
+            __IOM uint32_t EINT1           : 4;
+            __IOM uint32_t EINT2           : 4;
+            __IOM uint32_t EINT3           : 4;
+            __IM  uint32_t RESERVED        : 16;
+        } EINTCFG1_B;
+    };
+
+    /** @brief External Interrupt Configuration register2 */
+    union
+    {
+        __IOM uint32_t EINTCFG2;
+
+        struct
+        {
+            __IOM uint32_t EINT4           : 4;
+            __IOM uint32_t EINT5           : 4;
+            __IOM uint32_t EINT6           : 4;
+            __IOM uint32_t EINT7           : 4;
+            __IM  uint32_t RESERVED        : 16;
+        } EINTCFG2_B;
+    };
+
+    /** @brief External Interrupt Configuration register3 */
+    union
+    {
+        __IOM uint32_t EINTCFG3;
+
+        struct
+        {
+            __IOM uint32_t EINT8           : 4;
+            __IOM uint32_t EINT9           : 4;
+            __IOM uint32_t EINT10          : 4;
+            __IOM uint32_t EINT11          : 4;
+            __IM  uint32_t RESERVED        : 16;
+        } EINTCFG3_B;
+    };
+
+    /** @brief External Interrupt Configuration register4 */
+    union
+    {
+        __IOM uint32_t EINTCFG4;
+
+        struct
+        {
+            __IOM uint32_t EINT12          : 4;
+            __IOM uint32_t EINT13          : 4;
+            __IOM uint32_t EINT14          : 4;
+            __IOM uint32_t EINT15          : 4;
+            __IM  uint32_t RESERVED        : 16;
+        } EINTCFG4_B;
+    };
+
+    __IM  uint32_t  RESERVED[2];
+
+    /** @brief Compensation cell control register */
+    union
+    {
+        __IOM uint32_t CCCTRL;
+
+        struct
+        {
+            __IOM uint32_t CCPD            : 1;
+            __IM uint32_t RESERVED1        : 6;
+            __IOM uint32_t RDYFLG          : 1;
+            __IM  uint32_t RESERVED        : 24;
+        } CCCTRL_B;
+    };
+} SYSCFG_T;
+
+/**
+ * @brief Ethernet (ETH)
+ */
+typedef struct
+{
+    /**
+     * @brief ETH_MAC
+     */
+
+    /** @brief CFG register */
+    union
+    {
+        __IOM uint32_t CFG;
+        struct
+        {
+            __IM  uint32_t RESERVED1                 : 2;
+            __IOM uint32_t RXEN                      : 1;
+            __IOM uint32_t TXEN                      : 1;
+            __IOM uint32_t DC                        : 1;
+            __IOM uint32_t BL                        : 2;
+            __IOM uint32_t ACS                       : 1;
+            __IM  uint32_t RESERVED2                 : 1;
+            __IOM uint32_t DISR                      : 1;
+            __IOM uint32_t IPC                       : 1;
+            __IOM uint32_t DM                        : 1;
+            __IOM uint32_t LBM                       : 1;
+            __IOM uint32_t DISRXO                    : 1;
+            __IOM uint32_t SSEL                      : 1;
+            __IM  uint32_t RESERVED3                 : 1;
+            __IOM uint32_t DISCRS                    : 1;
+            __IOM uint32_t IFG                       : 3;
+            __IM  uint32_t RESERVED4                 : 2;
+            __IOM uint32_t JDIS                      : 1;
+            __IOM uint32_t WDTDIS                    : 1;
+            __IM  uint32_t RESERVED5                 : 1;
+            __IOM uint32_t CST                       : 1;
+            __IM  uint32_t RESERVED6                 : 6;
+        } CFG_B;
+    };
+
+    /** @brief FRAF register */
+    union
+    {
+        __IOM uint32_t FRAF;
+        struct
+        {
+            __IOM uint32_t PR                        : 1;
+            __IOM uint32_t HUC                       : 1;
+            __IOM uint32_t HMC                       : 1;
+            __IOM uint32_t DAIF                      : 1;
+            __IOM uint32_t PM                        : 1;
+            __IOM uint32_t DISBF                     : 1;
+            __IOM uint32_t PCTRLF                    : 2;
+            __IOM uint32_t SAIF                      : 1;
+            __IOM uint32_t SAFEN                     : 1;
+            __IOM uint32_t HPF                       : 1;
+            __IM  uint32_t RESERVED1                 : 20;
+            __IOM uint32_t RXA                       : 1;
+        } FRAF_B;
+    };
+
+    /** @brief HTH register */
+    union
+    {
+        __IOM uint32_t HTH;
+        struct
+        {
+            __IOM uint32_t HTH                         : 32;
+        } HTH_B;
+    };
+
+    /** @brief HTL register */
+    union
+    {
+        __IOM uint32_t HTL;
+        struct
+        {
+            __IOM uint32_t HTL                         : 32;
+        } HTL_B;
+    };
+
+    /** @brief ADDR register */
+    union
+    {
+        __IOM uint32_t ADDR;
+        struct
+        {
+            __IOM uint32_t MB                          : 1;
+            __IOM uint32_t MW                          : 1;
+            __IOM uint32_t CR                          : 3;
+            __IM  uint32_t RESERVED1                   : 1;
+            __IOM uint32_t MR                          : 5;
+            __IOM uint32_t PA                          : 5;
+            __IM  uint32_t RESERVED2                   : 16;
+        } ADDR_B;
+    };
+
+    /** @brief DATA register */
+    union
+    {
+        __IOM uint32_t DATA;
+        struct
+        {
+            __IOM uint32_t MD                          : 16;
+            __IM  uint32_t RESERVED1                   : 16;
+        } DATA_B;
+    };
+
+    /** @brief FCTRL register */
+    union
+    {
+        __IOM uint32_t FCTRL;
+        struct
+        {
+            __IOM uint32_t FCTRLB                      : 1;
+            __IOM uint32_t TXFCTRLEN                   : 1;
+            __IOM uint32_t RXFCTRLEN                   : 1;
+            __IOM uint32_t UNPFDETE                    : 1;
+            __IOM uint32_t PTSEL                       : 2;
+            __IM  uint32_t RESERVED1                   : 1;
+            __IOM uint32_t ZQPDIS                      : 1;
+            __IM  uint32_t RESERVED2                   : 8;
+            __IOM uint32_t PT                          : 16;
+        } FCTRL_B;
+    };
+
+    /** @brief VLANT register */
+    union
+    {
+        __IOM uint32_t VLANT;
+        struct
+        {
+            __IOM uint32_t VLANTID                     : 16;
+            __IOM uint32_t VLANTCOMP                   : 1;
+            __IM  uint32_t RESERVED                    : 15;
+        } VLANT_B;
+    };
+
+    __IM  uint32_t  RESERVED0[2];
+
+    /** @brief WKUPFFL register */
+    union
+    {
+        __IOM uint32_t WKUPFFL;
+        struct
+        {
+            __IOM uint32_t FLXBMASK                    : 32;
+        } WKUPFFL_B;
+    };
+
+    union
+    {
+        __IOM uint32_t PMTCTRLSTS;
+        struct
+        {
+            __IOM uint32_t PD                          : 1;
+            __IOM uint32_t MPEN                        : 1;
+            __IOM uint32_t WKUPFEN                     : 1;
+            __IM  uint32_t RESERVED1                   : 2;
+            __IOM uint32_t MPRX                        : 1;
+            __IOM uint32_t WKUPFRX                     : 1;
+            __IM  uint32_t RESERVED2                   : 2;
+            __IOM uint32_t GUN                         : 1;
+            __IM  uint32_t RESERVED3                   : 21;
+            __IOM uint32_t WKUPFRST                    : 1;
+        } PMTCTRLSTS_B;
+    } ;
+
+    __IM  uint32_t  RESERVED1;
+
+    /** @brief DBG register */
+    union
+    {
+        __IM  uint32_t DBG;
+        struct
+        {
+            __IM  uint32_t RPESTS                      : 1;
+            __IM  uint32_t RFCFCSTS                    : 2;
+            __IM  uint32_t RESERVED1                   : 1;
+            __IM  uint32_t RWCSTS                      : 1;
+            __IM  uint32_t RRCSTS                      : 2;
+            __IM  uint32_t RESERVED2                   : 1;
+            __IM  uint32_t RXFSTS                      : 2;
+            __IM  uint32_t RESERVED3                   : 6;
+            __IM  uint32_t TPESTS                      : 1;
+            __IM  uint32_t TFCSTS                      : 2;
+            __IM  uint32_t TXPAUSED                    : 1;
+            __IM  uint32_t TRCSTS                      : 2;
+            __IM  uint32_t TWCSTS                      : 1;
+            __IM  uint32_t RESERVED4                   : 1;
+            __IM  uint32_t TXFSTS                      : 1;
+            __IM  uint32_t TXSTSFSTS                   : 1;
+            __IM  uint32_t RESERVED5                   : 6;
+        } DBG_B;
+    };
+
+    /** @brief ISTS register */
+    union
+    {
+        __IM  uint32_t ISTS;
+        struct
+        {
+            __IM  uint32_t RESERVED1                   : 3;
+            __IM  uint32_t PMTIS                       : 1;
+            __IM  uint32_t MMCIS                       : 1;
+            __IM  uint32_t MMCRXIS                     : 1;
+            __IM  uint32_t MMCTXIS                     : 1;
+            __IM  uint32_t RESERVED2                   : 2;
+            __IM  uint32_t TSIS                        : 1;
+            __IM  uint32_t RESERVED3                   : 22;
+        } ISTS_B;
+    };
+
+    /** @brief IMASK register */
+    union
+    {
+        __IOM uint32_t IMASK;
+        struct
+        {
+            __IM  uint32_t RESERVED1                   : 3;
+            __IOM uint32_t PMTIM                       : 1;
+            __IM  uint32_t RESERVED2                   : 5;
+            __IOM uint32_t TSTIM                       : 1;
+            __IM  uint32_t RESERVED3                   : 6;
+        } IMASK_B;
+    };
+
+    /** @brief ADDR0H register */
+    union
+    {
+        __IOM uint32_t ADDR0H;
+        struct
+        {
+            __IOM uint32_t ADDR0H                      : 16;
+            __IM  uint32_t RESERVED                    : 15;
+            __IM  uint32_t AL1                         : 1;
+        } ADDR0H_B;
+    };
+
+    /** @brief ADDR0L register */
+    union
+    {
+        __IOM uint32_t ADDR0L;
+        struct
+        {
+            __IOM uint32_t ADDR0L                      : 32;
+        } ADDR0L_B;
+    };
+
+    /** @brief ADDR1H register */
+    union
+    {
+        __IOM uint32_t ADDR1H;
+        struct
+        {
+            __IOM uint32_t ADDR1H                      : 16;
+            __IM  uint32_t RESERVED                    : 8;
+            __IOM uint32_t MASKBCTRL                   : 6;
+            __IOM uint32_t ADDRSEL                     : 1;
+            __IOM uint32_t ADDREN                      : 1;
+        } ADDR1H_B;
+    };
+
+    /** @brief ADDR1L register */
+    union
+    {
+        __IOM uint32_t ADDR1L;
+        struct
+        {
+            __IOM uint32_t ADDR1L                      : 32;
+        } ADDR1L_B;
+    };
+
+    /** @brief ADDR2H register */
+    union
+    {
+        __IOM uint32_t ADDR2H;
+        struct
+        {
+            __IOM uint32_t ADDR2H                      : 16;
+            __IM  uint32_t RESERVED                    : 8;
+            __IOM uint32_t MASKBCTRL                   : 6;
+            __IOM uint32_t ADDRSEL                     : 1;
+            __IOM uint32_t ADDREN                      : 1;
+        } ADDR2H_B;
+    };
+
+    /** @brief ADDR2L register */
+    union
+    {
+        __IOM uint32_t ADDR2L;
+        struct
+        {
+            __IOM uint32_t ADDR2L                      : 32;
+        } ADDR2L_B;
+    };
+
+    /** @brief ADDR3H register */
+    union
+    {
+        __IOM uint32_t ADDR3H;
+        struct
+        {
+            __IOM uint32_t ADDR3H                      : 16;
+            __IM  uint32_t RESERVED                    : 8;
+            __IOM uint32_t MASKBCTRL                   : 6;
+            __IOM uint32_t ADDRSEL                     : 1;
+            __IOM uint32_t ADDREN                      : 1;
+        } ADDR3H_B;
+    };
+
+    /** @brief ADDR3L register */
+    union
+    {
+        __IOM uint32_t ADDR3L;
+        struct
+        {
+            __IOM uint32_t ADDR3L                      : 32;
+        } ADDR3L_B;
+    };
+
+    __IM uint32_t RESERVED2[40];
+    /**
+     * @brief MAC management counters (MMC)
+     */
+    /** Control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM uint32_t CNTRST          : 1;
+            __IOM uint32_t CNTSTOPRO       : 1;
+            __IOM uint32_t RSTOR           : 1;
+            __IOM uint32_t MCNTF           : 1;
+            __IOM uint32_t MCNTP           : 1;
+            __IOM uint32_t MCNTVALP        : 1;
+            __IM  uint32_t RESERVED        : 26;
+        } CTRL_B;
+    } ;
+
+    /** RX Interrupt Register */
+    union
+    {
+        __IOM uint32_t RXINT;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 5;
+            __IM  uint32_t RXFCE           : 1;
+            __IM  uint32_t RXFAE           : 1;
+            __IM  uint32_t RESERVED2       : 10;
+            __IM  uint32_t RXGUNF          : 1;
+            __IM  uint32_t RESERVED3       : 14;
+        } RXINT_B;
+    } ;
+
+    /** TX Interrupt Register */
+    union
+    {
+        __IOM uint32_t TXINT;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 14;
+            __IM  uint32_t TXGFSCOL        : 1;
+            __IM  uint32_t TXGFMCOL        : 1;
+            __IM  uint32_t RESERVED2       : 5;
+            __IM  uint32_t TXGF            : 1;
+            __IM  uint32_t RESERVED3       : 10;
+        } TXINT_B;
+    } ;
+
+    /** RX Interrupt Mask Register */
+    union
+    {
+        __IOM uint32_t RXINTMASK;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 5;
+            __IOM uint32_t RXFCEM          : 1;
+            __IOM uint32_t RXFAEM          : 1;
+            __IM  uint32_t RESERVED2       : 10;
+            __IOM uint32_t RXGUNFM         : 1;
+            __IM  uint32_t RESERVED3       : 14;
+        } RXINTMASK_B;
+    } ;
+
+    /** TX Interrupt Mask Register */
+    union
+    {
+        __IOM uint32_t TXINTMASK;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 14;
+            __IOM uint32_t TXGFSCOLM       : 1;
+            __IOM uint32_t TXGFMCOLM       : 1;
+            __IM  uint32_t RESERVED2       : 5;
+            __IOM uint32_t TXGFM           : 1;
+            __IM  uint32_t RESERVED3       : 10;
+        } TXINTMASK_B;
+    } ;
+
+    __IM  uint32_t  RESERVED3[14];
+
+    /** TX Good Frames After a Single Collision Counter Register */
+    union
+    {
+        __IM uint32_t TXGFSCCNT;
+
+        struct
+        {
+            __IM  uint32_t TXGFSCCNT       : 32;
+        } TXGFSCCNT_B;
+    } ;
+
+    /** TX Good Frames After More Than a Single Collision Counter Register */
+    union
+    {
+        __IM uint32_t TXGFMCCNT;
+
+        struct
+        {
+            __IM  uint32_t TXGFMCCNT       : 32;
+        } TXGFMCCNT_B;
+    } ;
+
+    __IM  uint32_t  RESERVED4[5];
+
+    /** TX Good Frames Counter Register */
+    union
+    {
+        __IM uint32_t TXGFCNT;
+
+        struct
+        {
+            __IM  uint32_t TXGFCNT       : 32;
+        } TXGFCNT_B;
+    } ;
+
+    __IM  uint32_t  RESERVED5[10];
+
+    /** RX Frames With CRC Error Counter Register */
+    union
+    {
+        __IM uint32_t RXFCECNT;
+
+        struct
+        {
+            __IM  uint32_t RXFCECNT       : 32;
+        } RXFCECNT_B;
+    } ;
+
+    /** RX Frames With Alignment Error Counter Register */
+    union
+    {
+        __IM uint32_t RXFAECNT;
+
+        struct
+        {
+            __IM  uint32_t RXFAECNT       : 32;
+        } RXFAECNT_B;
+    } ;
+
+    __IM  uint32_t  RESERVED6[10];
+
+    /** RX Good Unicast Frames Counter Register */
+    union
+    {
+        __IM uint32_t RXGUNCNT;
+
+        struct
+        {
+            __IM  uint32_t RXGUNCNT       : 32;
+        } RXGUNCNT_B;
+    } ;
+
+    __IM  uint32_t  RESERVED7[334];
+
+    /**
+      * @brief Ethernet: Precision time protocol (Ethernet_PTP)
+      */
+    union
+    {
+        __IOM uint32_t TSCTRL;                      /*!< (@ 0x00000000) Ethernet PTP time stamp control register                   */
+
+        struct
+        {
+            __IOM uint32_t TSEN       : 1;            /*!< [0..0] Time Stamp Enable                                                  */
+            __IOM uint32_t TSUDSEL    : 1;            /*!< [1..1] Time Stamp Update Mode Select                                      */
+            __IOM uint32_t TSSTINIT   : 1;            /*!< [2..2] Time Stamp System Time Initialize                                  */
+            __IOM uint32_t TSSTUD     : 1;            /*!< [3..3] Time Stamp System Time Update                                      */
+            __IOM uint32_t TSTRGIEN   : 1;            /*!< [4..4] Time Stamp Trigger Interrupt Enable                                */
+            __IOM uint32_t TSADDUD    : 1;            /*!< [5..5] Time Stamp Addend Register Update                                  */
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t TSSNEN     : 1;            /*!< [8..8] Time Stamp Snapshot for Received Frames Enable                     */
+            __IOM uint32_t TSSUBRO    : 1;            /*!< [9..9] Time Stamp Subsecond Rollover                                      */
+            __IOM uint32_t LISTVSEL   : 1;            /*!< [10..10] Listening Version Select                                         */
+            __IOM uint32_t TSSPTPEN   : 1;            /*!< [11..11] Time Stamp Snapshot for PTP Ethernet Frames Enable               */
+            __IOM uint32_t TSS6EN     : 1;            /*!< [12..12] Time stamp snapshot for IPv6 frames Enable                       */
+            __IOM uint32_t TSS4EN     : 1;            /*!< [13..13] Time Stamp Snapshot for IPv4 Frames Enable                       */
+            __IOM uint32_t TSSMESEL   : 1;            /*!< [14..14] Time Stamp Snapshot for Message Select                           */
+            __IOM uint32_t TSSMNSEL   : 1;            /*!< [15..15] Time Stamp Snapshot for Master Node Select                       */
+            __IOM uint32_t TSCLKNSEL  : 2;            /*!< [17..16] Time stamp Clock Node Select                                     */
+            __IOM uint32_t TSSPTPFMACEN : 1;          /*!< [18..18] Time Stamp PTP Frame Filtering MAC Address Enable                */
+            __IM  uint32_t RESERVED12  : 13;
+        } TSCTRL_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t SUBSECI;                     /*!< (@ 0x00000004) Ethernet PTP subsecond increment register                  */
+
+        struct
+        {
+            __IOM uint32_t STSUBSECI  : 8;            /*!< [7..0] System Time Subseconds Incremen                                    */
+            __IM  uint32_t RESERVED   : 24;
+        } SUBSECI_B;
+    } ;
+
+    union
+    {
+        __IM  uint32_t TSH;                         /*!< (@ 0x00000008) Ethernet PTP time stamp high register                      */
+
+        struct
+        {
+            __IM  uint32_t STSEC      : 32;           /*!< [31..0] System Time Second Value                                          */
+        } TSH_B;
+    } ;
+
+    union
+    {
+        __IM  uint32_t TSL;                         /*!< (@ 0x0000000C) Ethernet PTP time stamp low register                       */
+
+        struct
+        {
+            __IM  uint32_t STSUBSEC   : 31;           /*!< [30..0] System Time Subseconds Value                                      */
+            __IM  uint32_t STSEL      : 1;            /*!< [31..31] System Time Select                                               */
+        } TSL_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t TSHUD;                       /*!< (@ 0x00000010) Ethernet PTP time stamp high update register               */
+
+        struct
+        {
+            __IOM uint32_t TSUDSEC    : 32;           /*!< [31..0] Time Stamp Update Second Value                                    */
+        } TSHUD_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t TSLUD;                       /*!< (@ 0x00000014) Ethernet PTP time stamp low update register                */
+
+        struct
+        {
+            __IOM uint32_t TSUDSUBSEC : 31;           /*!< [30..0] Time Stamp Update Subseconds Value                                */
+            __IOM uint32_t TSUDSEL    : 1;            /*!< [31..31] Time Stamp Update Select                                         */
+        } TSLUD_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t TSA;                         /*!< (@ 0x00000018) Ethernet PTP time stamp addend register                    */
+
+        struct
+        {
+            __IOM uint32_t TSA        : 32;           /*!< [31..0] Time Stamp Addend Value                                           */
+        } TSA_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t TTSH;                        /*!< (@ 0x0000001C) Ethernet PTP target time high register                     */
+
+        struct
+        {
+            __IOM uint32_t TTSH       : 32;           /*!< [31..0] Target Time Stamp High Value                                      */
+        } TTSH_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t TTSL;                        /*!< (@ 0x00000020) Ethernet PTP target time low register                      */
+
+        struct
+        {
+            __IOM uint32_t TTSL       : 32;           /*!< [31..0] Target Time Stamp Low Value                                       */
+        } TTSL_B;
+    } ;
+    __IM  uint32_t  RESERVED8;
+
+    union
+    {
+        __IM  uint32_t TSSTS;                       /*!< (@ 0x00000028) Ethernet PTP time stamp status register                    */
+
+        struct
+        {
+            __IM  uint32_t TSSECOVR   : 1;            /*!< [0..0] Time Stamp Second Value Overflow                                   */
+            __IM  uint32_t TTSRD      : 1;            /*!< [1..1] Target Time Stamp Value Reached                                    */
+            __IM  uint32_t RESERVED   : 30;
+        } TSSTS_B;
+    } ;
+
+    union
+    {
+        __IM  uint32_t PPSCTRL;                     /*!< (@ 0x0000002C) Ethernet PTP PPS control register                          */
+
+        struct
+        {
+            __IM  uint32_t PPSFSEL    : 4;            /*!< [3..0] PPS Frequency Selection                                            */
+            __IM  uint32_t RESERVED   : 28;
+        } PPSCTRL_B;
+    } ;
+
+    __IM  uint32_t  RESERVED9[564];
+
+    /**
+      * @brief Ethernet: DMA controller operation (Ethernet_DMA)
+      */
+    union
+    {
+        __IOM uint32_t DMABMOD;                     /*!< (@ 0x00000000) Ethernet DMA bus mode register                             */
+
+        struct
+        {
+            __IOM uint32_t SWR        : 1;            /*!< [0..0] Software Reset                                                     */
+            __IOM uint32_t DAS        : 1;            /*!< [1..1] DMA Arbitration Scheme                                             */
+            __IOM uint32_t DSL        : 5;            /*!< [6..2] Descriptor Skip Length                                             */
+            __IOM uint32_t EDFEN      : 1;            /*!< [7..7] Enhanced Descriptor Format Enable                                  */
+            __IOM uint32_t PBL        : 6;            /*!< [13..8] Programmable Burst Length                                         */
+            __IOM uint32_t PR         : 2;            /*!< [15..14] Priority Ratio                                                   */
+            __IOM uint32_t FB         : 1;            /*!< [16..16] Fixed Burst                                                      */
+            __IOM uint32_t RPBL       : 6;            /*!< [22..17] Rx DMA PBL                                                       */
+            __IOM uint32_t USP        : 1;            /*!< [23..23] Use Separate PBL                                                 */
+            __IOM uint32_t PBLx4      : 1;            /*!< [24..24] PBLx4 Mode                                                       */
+            __IOM uint32_t AAL        : 1;            /*!< [25..25] Address-Aligned Beats                                            */
+            __IOM uint32_t MB         : 1;            /*!< [26..26] Mixed Burst                                                      */
+            __IM  uint32_t RESERVED   : 5;
+        } DMABMOD_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMATXPD;                     /*!< (@ 0x00000004) Ethernet DMA transmit poll demand register                 */
+
+        struct
+        {
+            __IOM uint32_t TXPD       : 32;           /*!< [31..0] Transmit Poll Demand                                              */
+        } DMATXPD_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMARXPD;                     /*!< (@ 0x00000008) EHERNET DMA receive poll demand register                   */
+
+        struct
+        {
+            __IOM uint32_t RXPD       : 32;           /*!< [31..0] Receive Poll Demand                                               */
+        } DMARXPD_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMARXDLADDR;                 /*!< (@ 0x0000000C) Ethernet DMA receive descriptor list address
+                                                                    register                                                   */
+
+        struct
+        {
+            __IOM uint32_t RXSTA      : 32;           /*!< [31..0] Start of Receive List                                             */
+        } DMARXDLADDR_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMATXDLADDR;                 /*!< (@ 0x00000010) Ethernet DMA transmit descriptor list address
+                                                                    register                                                   */
+
+        struct
+        {
+            __IOM uint32_t TXSTA      : 32;           /*!< [31..0] Start of Transmit List                                            */
+        } DMATXDLADDR_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMASTS;                      /*!< (@ 0x00000014) Ethernet DMA status register                               */
+
+        struct
+        {
+            __IOM uint32_t TXFLG      : 1;            /*!< [0..0] Transmit Flag                                                      */
+            __IOM uint32_t TXSFLG     : 1;            /*!< [1..1] Transmit Stopped Flag                                              */
+            __IOM uint32_t TXBU       : 1;            /*!< [2..2] Transmit Buffer Unavailable                                        */
+            __IOM uint32_t TXJTO      : 1;            /*!< [3..3] Transmit Jabber Timeout                                            */
+            __IOM uint32_t RXOVF      : 1;            /*!< [4..4] Receive Overflow                                                   */
+            __IOM uint32_t TXUNF      : 1;            /*!< [5..5] Transmit Underflow                                                 */
+            __IOM uint32_t RXFLG      : 1;            /*!< [6..6] Receive Flag                                                       */
+            __IOM uint32_t RXBU       : 1;            /*!< [7..7] Receive Buffer Unavailable                                         */
+            __IOM uint32_t RXSFLG     : 1;            /*!< [8..8] Receive Stopped Flag                                               */
+            __IOM uint32_t RXWTOFLG   : 1;            /*!< [9..9] Receive Watchdog Timeout Flag                                      */
+            __IOM uint32_t ETXFLG     : 1;            /*!< [10..10] Early Transmit Flag                                              */
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t FBERRFLG   : 1;            /*!< [13..13] Fatal Bus Error Flag                                             */
+            __IOM uint32_t ERXFLG     : 1;            /*!< [14..14] Early Receive Flag                                               */
+            __IOM uint32_t AINTS      : 1;            /*!< [15..15] Abnormal Interrupt Summary                                       */
+            __IOM uint32_t NINTS      : 1;            /*!< [16..16] Normal Interrupt Summary                                         */
+            __IM  uint32_t RXSTS      : 3;            /*!< [19..17] Receive Process State                                            */
+            __IM  uint32_t TXSTS      : 3;            /*!< [22..20] Transmit Process State                                           */
+            __IM  uint32_t ERRB       : 3;            /*!< [25..23] Error Bits                                                       */
+            __IM  uint32_t RESERVED2  : 1;
+            __IM  uint32_t MMCFLG     : 1;            /*!< [27..27] MMC Flag                                                         */
+            __IM  uint32_t PMTFLG     : 1;            /*!< [28..28] PMT Flag                                                         */
+            __IM  uint32_t TSTFLG     : 1;            /*!< [29..29] Timestamp Trigger Flag                                           */
+            __IM  uint32_t RESERVED3  : 2;
+        } DMASTS_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMAOPMOD;                    /*!< (@ 0x00000018) Ethernet DMA operation mode register                       */
+
+        struct
+        {
+            __IM  uint32_t            : 1;
+            __IOM uint32_t STRX       : 1;            /*!< [1..1] Start or Stop Receive                                              */
+            __IOM uint32_t OSECF      : 1;            /*!< [2..2] Operate on Second Frame                                            */
+            __IOM uint32_t RXTHCTRL   : 2;            /*!< [4..3] Receive Threshold Control                                          */
+            __IM  uint32_t RESERVED1  : 1;
+            __IOM uint32_t FUF        : 1;            /*!< [6..6] Forward Undersized Good Frames                                     */
+            __IOM uint32_t FERRF      : 1;            /*!< [7..7] Forward Error Frames                                               */
+            __IM  uint32_t RESERVED2  : 5;
+            __IOM uint32_t STTX       : 1;            /*!< [13..13] Start or Stop Transmission Command                               */
+            __IOM uint32_t TXTHCTRL   : 3;            /*!< [16..14] Transmit Threshold Control                                       */
+            __IM  uint32_t RESERVED3  : 3;
+            __IOM uint32_t FTXF       : 1;            /*!< [20..20] Flush Transmit FIFO                                              */
+            __IOM uint32_t TXSF       : 1;            /*!< [21..21] Transmit Store and Forward                                       */
+            __IM  uint32_t RESERVED4  : 2;
+            __IOM uint32_t DISFRXF    : 1;            /*!< [24..24] Disable Flushing of Received Frames                              */
+            __IOM uint32_t RXSF       : 1;            /*!< [25..25] Receive Store and Forward                                        */
+            __IOM uint32_t DISDT      : 1;            /*!< [26..26] Disable Dropping of TCP/IP Checksum Error Frames                 */
+            __IM  uint32_t RESERVED5  : 5;
+        } DMAOPMOD_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMAINTEN;                    /*!< (@ 0x0000001C) Ethernet DMA interrupt enable register                     */
+
+        struct
+        {
+            __IOM uint32_t TXIEN      : 1;            /*!< [0..0] Transmit Interrupt Enable                                          */
+            __IOM uint32_t TXSEN      : 1;            /*!< [1..1] Transmit Stopped Enable                                            */
+            __IOM uint32_t TXBUEN     : 1;            /*!< [2..2] Transmit Buffer Unavailable Enable                                 */
+            __IOM uint32_t TXJTOEN    : 1;            /*!< [3..3] Transmit Jabber Timeout Enable                                     */
+            __IOM uint32_t RXOVFEN    : 1;            /*!< [4..4] Receive Overflow Interrupt Enable                                  */
+            __IOM uint32_t TXUNFEN    : 1;            /*!< [5..5] Transmit Underflow Interrupt Enable                                */
+            __IOM uint32_t RXIEN      : 1;            /*!< [6..6] Receive Interrupt Enable                                           */
+            __IOM uint32_t RXBUEN     : 1;            /*!< [7..7] Receive Buffer Unavailable Enable                                  */
+            __IOM uint32_t RXSEN      : 1;            /*!< [8..8] Receive Stopped Enable                                             */
+            __IOM uint32_t RXWTOEN    : 1;            /*!< [9..9] Receive Watchdog Timeout Enable                                    */
+            __IOM uint32_t ETXIEN     : 1;            /*!< [10..10] Early Transmit Interrupt Enable                                  */
+            __IM  uint32_t RESERVED1  : 2;
+            __IOM uint32_t FBERREN    : 1;            /*!< [13..13] Fatal Bus Error Enable                                           */
+            __IOM uint32_t ERXIEN     : 1;            /*!< [14..14] Early Receive Interrupt Enable                                   */
+            __IOM uint32_t AINTSEN    : 1;            /*!< [15..15] Abnormal Interrupt Summary Enable                                */
+            __IOM uint32_t NINTSEN    : 1;            /*!< [16..16] Normal Interrupt Summary Enable                                  */
+            __IM  uint32_t RESERVED2  : 15;
+        } DMAINTEN_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMAMFABOCNT;                 /*!< (@ 0x00000020) Ethernet DMA missed frame and buffer overflow
+                                                                    counter register                                           */
+
+        struct
+        {
+            __IOM uint32_t MISFCNT    : 16;           /*!< [15..0] Missed Frame Counter                                              */
+            __IOM uint32_t MISFCNTOVF : 1;            /*!< [16..16] Overflow Bit for Missed Frame Counter                            */
+            __IOM uint32_t AMISFCNT   : 11;           /*!< [27..17] Missed Frame Counter                                             */
+            __IOM uint32_t OVFCNTOVF  : 1;            /*!< [28..28] Overflow Bit for FIFO Overflow Counter                           */
+            __IM  uint32_t RESERVED   : 3;
+        } DMAMFABOCNT_B;
+    } ;
+
+    union
+    {
+        __IOM uint32_t DMARXFLGWDT;                 /*!< (@ 0x00000024) Ethernet DMA receive status watchdog timer register        */
+
+        struct
+        {
+            __IOM uint32_t RXWDTCNT   : 8;            /*!< [7..0] RXFLG Watchdog Timer Count                                         */
+            __IM  uint32_t RESERVED   : 24;
+        } DMARXFLGWDT_B;
+    } ;
+    __IM  uint32_t  RESERVED10[8];
+
+    union
+    {
+        __IM  uint32_t DMAHTXD;                     /*!< (@ 0x00000048) Ethernet DMA current host transmit descriptor
+                                                                    register                                                   */
+        struct
+        {
+            __IM  uint32_t HTXDADDRP  : 32;           /*!< [31..0] Host Transmit Descriptor Address Pointer                          */
+        } DMAHTXD_B;
+    } ;
+
+    union
+    {
+        __IM  uint32_t DMAHRXD;                     /*!< (@ 0x0000004C) Ethernet DMA current host receive descriptor
+                                                                    register                                                   */
+        struct
+        {
+            __IM  uint32_t HRXDADDRP  : 32;           /*!< [31..0] Host Receive Descriptor Address Pointer                           */
+        } DMAHRXD_B;
+    } ;
+
+    union
+    {
+        __IM  uint32_t DMAHTXBADDR;                 /*!< (@ 0x00000050) Ethernet DMA current host transmit buffer address
+                                                                    register                                                   */
+
+        struct
+        {
+            __IM  uint32_t HTXBADDRP  : 32;           /*!< [31..0] Host Transmit Buffer Address Pointer                              */
+        } DMAHTXBADDR_B;
+    } ;
+
+    union
+    {
+        __IM  uint32_t DMAHRXBADDR;                 /*!< (@ 0x00000054) Ethernet DMA current host receive buffer address
+                                                                    register                                                   */
+
+        struct
+        {
+            __IM  uint32_t HRXBADDRP  : 32;           /*!< [31..0] Host Receive Buffer Address Pointer                               */
+        } DMAHRXBADDR_B;
+    } ;
+} ETH_T;
+
+/**
+ * @brief    CRYP register (CRYP)
+ */
+typedef struct
+{
+    /** @brief Control register  */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IM  uint32_t RESERVED1       : 2;
+            __IOM uint32_t ALGODIRSEL      : 1;
+            __IOM uint32_t ALGOMSEL        : 3;
+            __IOM uint32_t DTSEL           : 2;
+            __IOM uint32_t KSIZESEL        : 2;
+            __IM  uint32_t RESERVED2       : 4;
+            __IOM uint32_t FFLUSH          : 1;
+            __IOM uint32_t CRYPEN          : 1;
+            __IM  uint32_t RESERVED3       : 16;
+        } CTRL_B;
+    } ;
+
+    /** @brief Status register */
+    union
+    {
+        __IM uint32_t STS;
+
+        struct
+        {
+            __IM  uint32_t IFEMPT         : 1;
+            __IM  uint32_t IFFULL         : 1;
+            __IM  uint32_t OFEMPT         : 1;
+            __IM  uint32_t OFFULL         : 1;
+            __IM  uint32_t BUSY           : 1;
+            __IM  uint32_t RESERVED       : 27;
+        } STS_B;
+    };
+
+    /** @brief Input data register */
+    union
+    {
+        __IOM uint32_t DATAIN;
+
+        struct
+        {
+            __IOM uint32_t DATAIN          : 32;
+        } DATAIN_B;
+    };
+
+    /** @brief Output data register */
+    union
+    {
+        __IM uint32_t DATAOUT;
+
+        struct
+        {
+            __IM uint32_t DATAOUT          : 32;
+        } DATAOUT_B;
+    };
+
+    /** @brief Control DMA register */
+    union
+    {
+        __IOM uint32_t DMACTRL;
+
+        struct
+        {
+            __IOM uint32_t INEN             : 1;
+            __IOM uint32_t OUTEN            : 1;
+            __IM  uint32_t RESERVED         : 30;
+        } DMACTRL_B;
+    };
+
+    /** @brief Service Interrupt Mask register */
+    union
+    {
+        __IOM uint32_t INTMASK;
+
+        struct
+        {
+            __IOM uint32_t INIMASK          : 1;
+            __IOM uint32_t OUTIMASK         : 1;
+            __IM  uint32_t RESERVED         : 30;
+        } INTMASK_B;
+    };
+
+    /** @brief Service Raw Interrupt Status register */
+    union
+    {
+        __IM uint32_t INTSTS;
+
+        struct
+        {
+            __IM uint32_t INISTS            : 1;
+            __IM uint32_t OUTISTS           : 1;
+            __IM  uint32_t RESERVED         : 30;
+        } INTSTS_B;
+    };
+
+    /** @brief Service Masked Interrupt Status register */
+    union
+    {
+        __IOM uint32_t MINTSTS;
+
+        struct
+        {
+            __IOM uint32_t INMISTS           : 1;
+            __IOM uint32_t OUTMISTS          : 1;
+            __IM  uint32_t RESERVED          : 30;
+        } MINTSTS_B;
+    };
+
+    /** @brief Key0L register */
+    union
+    {
+        __OM uint32_t K0L;
+
+        struct
+        {
+            __OM  uint32_t Bx         : 32;
+        } K0L_B;
+    };
+
+    /** @brief Key0R register */
+    union
+    {
+        __OM uint32_t K0R;
+
+        struct
+        {
+            __OM  uint32_t Bx         : 32;
+        } K0R_B;
+    };
+
+    /** @brief Key1L register */
+    union
+    {
+        __OM uint32_t K1L;
+
+        struct
+        {
+            __OM  uint32_t KyBx         : 32;
+        } K1L_B;
+    };
+
+    /** @brief Key1R register */
+    union
+    {
+        __OM uint32_t K1R;
+
+        struct
+        {
+            __OM  uint32_t KyBx         : 32;
+        } K1R_B;
+    };
+
+    /** @brief Key2L register */
+    union
+    {
+        __OM uint32_t K2L;
+
+        struct
+        {
+            __OM  uint32_t KyBx         : 32;
+        } K2L_B;
+    };
+
+    /** @brief Key2R register */
+    union
+    {
+        __OM uint32_t K2R;
+
+        struct
+        {
+            __OM  uint32_t KyBx         : 32;
+        } K2R_B;
+    };
+
+    /** @brief Key3L register */
+    union
+    {
+        __OM uint32_t K3L;
+
+        struct
+        {
+            __OM  uint32_t KyBx         : 32;
+        } K3L_B;
+    };
+
+    /** @brief Key3R register */
+    union
+    {
+        __OM uint32_t K3R;
+
+        struct
+        {
+            __OM  uint32_t KyBx         : 32;
+        } K3R_B;
+    };
+
+    /** @brief Initialize the vector register register */
+    union
+    {
+        __IOM uint32_t IV0L;
+
+        struct
+        {
+            __IOM  uint32_t IVx         : 32;
+        } IV0L_B;
+    };
+
+    /** @brief Initialize the vector register register */
+    union
+    {
+        __IOM uint32_t IV0R;
+
+        struct
+        {
+            __IOM  uint32_t IVx         : 32;
+        } IV0R_B;
+    };
+
+    /** @brief Initialize the vector register register */
+    union
+    {
+        __IOM uint32_t IV1L;
+
+        struct
+        {
+            __IOM  uint32_t IVx         : 32;
+        } IV1L_B;
+    };
+
+    /** @brief Initialize the vector register register */
+    union
+    {
+        __IOM uint32_t IV1R;
+
+        struct
+        {
+            __IOM  uint32_t IVx         : 32;
+        } IV1R_B;
+    };
+
+} CRYP_T;
+
+/**
+* @brief The registers of HASH
+*/
+typedef struct
+{
+    /** @brief HASH Control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+        struct
+        {
+            __IM  uint32_t RESERVED        : 2;
+            __IOM uint32_t INITCAL         : 1;
+            __IOM uint32_t DMAEN           : 1;
+            __IOM uint32_t DTYPE           : 2;
+            __IOM uint32_t MODESEL         : 1;
+            __IOM uint32_t ALGSEL          : 1;
+            __IOM uint32_t WNUM            : 4;
+            __IOM uint32_t DINNEMPT        : 1;
+            __IM  uint32_t RESERVED1       : 3;
+            __IOM uint32_t LKEYSEL         : 1;
+            __IM  uint32_t RESERVED2       : 15;
+        } CTRL_B;
+    };
+
+    /** @brief HASH Input Data register */
+    union
+    {
+        __IOM uint32_t INDATA;
+        struct
+        {
+            __IOM uint32_t INDATA         : 32;
+        } INDATA_B;
+    };
+
+    /** @brief HASH Start register */
+    union
+    {
+        __IOM uint32_t START;
+        struct
+        {
+            __IOM uint32_t LWNUM          : 5;
+            __IM  uint32_t RESERVED1      : 3;
+            __OM  uint32_t DIGCAL         : 1;
+            __IM  uint32_t RESERVED2      : 23;
+        } START_B;
+    };
+
+    __IO uint32_t DIG[5];
+
+    /** @brief HASH interrupt enable register */
+    union
+    {
+        __IOM uint32_t INT;
+        struct
+        {
+            __IOM uint32_t INDATA         : 1;
+            __IOM uint32_t DCALC          : 1;
+            __IM  uint32_t RESERVED1      : 30;
+        } INT_B;
+    };
+
+    /** @brief HASH status register */
+    union
+    {
+        __IOM uint32_t STS;
+        struct
+        {
+            __IOM uint32_t INDATAINT      : 1;
+            __IOM uint32_t DCALCINT       : 1;
+            __IM  uint32_t DMA            : 1;
+            __IM  uint32_t BUSY           : 1;
+            __IM  uint32_t RESERVED       : 28;
+        } STS_B;
+    };
+
+    __IM uint32_t RESERVED[52];
+
+    /** @brief HASH context swap register */
+    __IOM uint32_t CTSWAP[51];
+
+} HASH_T;
+
+/**
+ * @brief    Random Number Generator (RNG)
+ */
+typedef struct
+{
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IM   uint32_t RESERVED       : 2;
+            __IOM  uint32_t RNGEN          : 1;
+            __IOM  uint32_t INTEN          : 1;
+            __IM   uint32_t RESERVED1      : 28;
+        } CTRL_B;
+    };
+
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IM   uint32_t DATARDY        : 1;
+            __IM   uint32_t CLKERCSTS      : 1;
+            __IM   uint32_t FSCSTS         : 1;
+            __IM   uint32_t RESERVED1      : 2;
+            __IOM  uint32_t CLKERINT       : 1;
+            __IOM  uint32_t FSINT          : 1;
+            __IM   uint32_t RESERVED2      : 25;
+        } STS_B;
+    };
+
+    union
+    {
+        __IM uint32_t DATA;
+
+        struct
+        {
+            __IM   uint32_t DATA           : 32;
+        } DATA_B;
+    };
+} RNG_T;
+
+/**
+ * @brief    Big number module (BN)
+ */
+typedef struct
+{
+    /** Revision register */
+    union
+    {
+        __IM uint32_t REV;
+
+        struct
+        {
+            __IM   uint32_t MIN            : 8;
+            __IM   uint32_t MID            : 8;
+            __IM   uint32_t MAJ            : 8;
+            __IM   uint32_t RESERVED       : 8;
+        } REV_B;
+
+    };
+
+    /** Control register */
+    union
+    {
+        __IOM uint32_t CTRL;
+
+        struct
+        {
+            __IOM   uint32_t START          : 1;
+            __IOM   uint32_t SP             : 3;
+            __IOM   uint32_t SELECT         : 4;
+            __IOM   uint32_t IE             : 1;
+            __IM    uint32_t RESERVED       : 23;
+        } CTRL_B;
+
+    };
+
+    /** Status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IOM   uint32_t DONE           : 1;
+            __IOM   uint32_t BUSY           : 1;
+            __IOM   uint32_t CB             : 1;
+            __IOM   uint32_t TR             : 1;
+            __IOM   uint32_t INF            : 1;
+            __IOM   uint32_t EVEN           : 1;
+            __IOM   uint32_t ZERO           : 1;
+            __IOM   uint32_t ATTACKED       : 1;
+            __IOM   uint32_t BLEN           : 16;
+            __IM    uint32_t RESERVED       : 8;
+        } STS_B;
+    };
+
+    /**  Operand Width register */
+    union
+    {
+        __IOM uint32_t WID;
+
+        struct
+        {
+            __IOM   uint32_t PWID           : 7;
+            __IM    uint32_t RESERVED       : 7;
+            __IOM   uint32_t KWID           : 4;
+            __IM    uint32_t RESERVED1      : 14;
+        } WID_B;
+    };
+
+    __IM uint32_t        RESERVED[12];
+
+    /** P/M register */
+    union
+    {
+        __IOM uint32_t P;
+
+        struct
+        {
+            __IOM   uint32_t P_REG           : 32;
+        } P_B;
+    };
+
+    /** BN Operand/EC Parameter A register */
+    union
+    {
+        __IOM uint32_t A;
+
+        struct
+        {
+            __IOM   uint32_t A_REG           : 32;
+        } A_B;
+    };
+
+    /** BN Operand/EC Parameter B register */
+    union
+    {
+        __IOM uint32_t B;
+
+        struct
+        {
+            __IOM   uint32_t B_REG           : 32;
+        } B_B;
+    };
+
+    /** ECC Key register */
+    union
+    {
+        __IOM uint32_t K;
+
+        struct
+        {
+            __IOM   uint32_t K_REG           : 32;
+        } K_B;
+    };
+
+    /** ECC PX register */
+    union
+    {
+        __IOM uint32_t PX;
+
+        struct
+        {
+            __IOM   uint32_t PX_REG           : 32;
+        } PX_B;
+    };
+
+    /** ECC PY register */
+    union
+    {
+        __IOM uint32_t PY;
+
+        struct
+        {
+            __IOM   uint32_t PY_REG           : 32;
+        } PY_B;
+    };
+
+    /** ECC SX register */
+    union
+    {
+        __IOM uint32_t SX;
+
+        struct
+        {
+            __IOM   uint32_t SX_REG           : 32;
+        } SX_B;
+    };
+
+    /** ECC SY register */
+    union
+    {
+        __IOM uint32_t SY;
+
+        struct
+        {
+            __IOM   uint32_t SY_REG           : 32;
+        } SY_B;
+    };
+
+    /** ECC Result RX register */
+    union
+    {
+        __IM uint32_t RX;
+
+        struct
+        {
+            __IM   uint32_t RX_REG           : 32;
+        } RX_B;
+    };
+
+    /** ECC Result RY register */
+    union
+    {
+        __IM uint32_t RY;
+
+        struct
+        {
+            __IM   uint32_t RY_REG           : 32;
+        } RY_B;
+    };
+
+    /** Random Number register */
+    union
+    {
+        __OM uint32_t RND;
+
+        struct
+        {
+            __OM   uint32_t RND_REG          : 32;
+        } RND_B;
+    };
+} BN_T;
+
+/**
+ * @brief    SM3
+ */
+typedef struct
+{
+    /** Revision Register */
+    union
+    {
+        __IM uint32_t REV;
+
+        struct
+        {
+            __IM   uint32_t MIN            : 8;
+            __IM   uint32_t MID            : 8;
+            __IM   uint32_t MAJ            : 8;
+            __IM   uint32_t RESERVED       : 8;
+        } REV_B;
+    };
+
+    /** Control Register */
+    union
+    {
+        __IOM uint32_t CTRL;
+        struct
+        {
+            __IOM   uint32_t START          : 1;
+            __IOM   uint32_t IE             : 1;
+            __IOM   uint32_t INIMODE        : 1;
+            __IOM   uint32_t PADMODE        : 1;
+            __IOM   uint32_t ENDIAN         : 1;
+            __IM    uint32_t RESERVED       : 27;
+        } CTRL_B;
+    };
+
+    /** Status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IOM   uint32_t DONE           : 1;
+            __IOM   uint32_t BUSY           : 1;
+            __IM    uint32_t RESERVED       : 30;
+        } STS_B;
+    };
+
+    /** Data input length higher register */
+    union
+    {
+        __OM uint32_t DILH;
+
+        struct
+        {
+            __OM   uint32_t DATA           : 32;
+        } DILH_B;
+    };
+
+    /** Data input length lower register */
+    union
+    {
+        __OM uint32_t DILL;
+
+        struct
+        {
+            __OM   uint32_t DATA           : 32;
+        } DILL_B;
+    };
+
+    /** Input Message Register[16](0x14-0x50) */
+    __IOM uint32_t DIN[16];
+    /** Input Initial Value[8](0x54-0x70) */
+    __IOM uint32_t IV[8];
+    /** Output Message Digest Register[8](0x74-0x90) */
+    __IM  uint32_t DOUT[8];
+
+} SM3_T;
+
+/**
+ * @brief    SM4
+ */
+typedef struct
+{
+    /** Revision Register */
+    union
+    {
+        __IM uint32_t REV;
+
+        struct
+        {
+            __IM   uint32_t REC0           : 1;
+            __IM   uint32_t REC1           : 1;
+            __IM   uint32_t RESERVED       : 30;
+        } REV_B;
+    };
+
+    /** Control Register */
+    union
+    {
+        __IOM uint32_t CTRL;
+        struct
+        {
+            __IOM   uint32_t START          : 1;
+            __IOM   uint32_t IE             : 1;
+            __IOM   uint32_t ENC            : 1;
+            __IOM   uint32_t MODE           : 1;
+            __IM    uint32_t RESERVED       : 28;
+        } CTRL_B;
+    };
+
+    /** Status register */
+    union
+    {
+        __IOM uint32_t STS;
+
+        struct
+        {
+            __IOM   uint32_t DONE           : 1;
+            __IOM   uint32_t BUSY           : 1;
+            __IM    uint32_t RESERVED       : 30;
+        } STS_B;
+    };
+
+    /** SM4 key register[4](0x0C..0x18) */
+    __IOM uint32_t KEY[4];
+    /** SM4 data input register[4](0x20..0x28) */
+    __IOM uint32_t DIN[4];
+    /** SM4 data output register[4](0x2C..0x38) */
+    __IM  uint32_t DOUT[4];
+    /** SM4 initial vector register[4](0x3C..0x48) */
+    __IOM uint32_t IV[4];
+} SM4_T;
+
+/**
+  * @}
+  */
+
+/** @defgroup Peripheral_memory_map
+  @{
+*/
+
+/** FMC base address in the alias region */
+#define FMC_BASE                ((uint32_t)0x08000000)
+/** CCM(core coupled memory) data RAM(64 KB) base address in the alias region */
+#define CCMDATARAM_BASE         ((uint32_t)0x10000000)
+/** SRAM1 base address in the alias region */
+#define SRAM1_BASE              ((uint32_t)0x20000000)
+/** SRAM2 base address in the alias region */
+#define SRAM2_BASE              ((uint32_t)0x2001C000)
+/** SRAM3 base address in the alias region */
+#define SRAM3_BASE              ((uint32_t)0x20020000)
+/** Peripheral base address in the alias region */
+#define PERIPH_BASE             ((uint32_t)0x40000000)
+/** Backup SRAM(4 KB) base address in the alias region */
+#define BKPSRAM_BASE            ((uint32_t)0x40024000)
+
+/** CCM(core coupled memory) data RAM(64 KB) base address in the bit-band region */
+#define CCMDATARAM_BB_BASE      ((uint32_t)0x12000000)
+/** SRAM1 base address in the bit-band region */
+#define SRAM1_BB_BASE           ((uint32_t)0x22000000)
+/** SRAM2 base address in the bit-band region */
+#define SRAM2_BB_BASE           ((uint32_t)0x22380000)
+/** SRAM3 base address in the bit-band region */
+#define SRAM3_BB_BASE           ((uint32_t)0x22400000)
+/** Peripheral base address in the bit-band region */
+#define PERIPH_BB_BASE          ((uint32_t)0x42000000)
+/** Backup SRAM(4 KB) base address in the bit-band region */
+#define BKPSRAM_BB_BASE         ((uint32_t)0x42480000)
+
+/** Legacy defines */
+#define SRAM_BASE               SRAM1_BASE
+#define SRAM_BB_BASE            SRAM1_BB_BASE
+
+/** EMMC registers base address */
+#define SMC_R_BASE              ((uint32_t)0xA0000000)
+/** QSPI registers base address */
+#define QSPI_BASE               ((uint32_t)0xA0000000)
+/** DMC registers base address */
+#define DMC_BASE                ((uint32_t)0xA0000000)
+
+/** Peripheral memory map */
+#define APB1PERIPH_BASE         PERIPH_BASE
+#define APB2PERIPH_BASE         (PERIPH_BASE + 0x00010000)
+#define AHB1PERIPH_BASE         (PERIPH_BASE + 0x00020000)
+#define AHB2PERIPH_BASE         (PERIPH_BASE + 0x10000000)
+
+/** APB1 peripherals */
+#define TMR2_BASE               (APB1PERIPH_BASE + 0x0000)
+#define TMR3_BASE               (APB1PERIPH_BASE + 0x0400)
+#define TMR4_BASE               (APB1PERIPH_BASE + 0x0800)
+#define TMR5_BASE               (APB1PERIPH_BASE + 0x0C00)
+#define TMR6_BASE               (APB1PERIPH_BASE + 0x1000)
+#define TMR7_BASE               (APB1PERIPH_BASE + 0x1400)
+#define TMR12_BASE              (APB1PERIPH_BASE + 0x1800)
+#define TMR13_BASE              (APB1PERIPH_BASE + 0x1C00)
+#define TMR14_BASE              (APB1PERIPH_BASE + 0x2000)
+#define RTC_BASE                (APB1PERIPH_BASE + 0x2800)
+#define WWDT_BASE               (APB1PERIPH_BASE + 0x2C00)
+#define IWDT_BASE               (APB1PERIPH_BASE + 0x3000)
+#define I2S2ext_BASE            (APB1PERIPH_BASE + 0x3400)
+#define SPI2_BASE               (APB1PERIPH_BASE + 0x3800)
+#define SPI3_BASE               (APB1PERIPH_BASE + 0x3C00)
+#define I2S3ext_BASE            (APB1PERIPH_BASE + 0x4000)
+#define USART2_BASE             (APB1PERIPH_BASE + 0x4400)
+#define USART3_BASE             (APB1PERIPH_BASE + 0x4800)
+#define UART4_BASE              (APB1PERIPH_BASE + 0x4C00)
+#define UART5_BASE              (APB1PERIPH_BASE + 0x5000)
+#define I2C1_BASE               (APB1PERIPH_BASE + 0x5400)
+#define I2C2_BASE               (APB1PERIPH_BASE + 0x5800)
+#define I2C3_BASE               (APB1PERIPH_BASE + 0x5C00)
+#define CAN1_BASE               (APB1PERIPH_BASE + 0x6400)
+#define CAN2_BASE               (APB1PERIPH_BASE + 0x6800)
+#define PMU_BASE                (APB1PERIPH_BASE + 0x7000)
+#define DAC_BASE                (APB1PERIPH_BASE + 0x7400)
+#define UART7_BASE              (APB1PERIPH_BASE + 0x7800)
+#define UART8_BASE              (APB1PERIPH_BASE + 0x7C00)
+
+/** APB2 peripherals */
+#define TMR1_BASE               (APB2PERIPH_BASE + 0x0000)
+#define TMR8_BASE               (APB2PERIPH_BASE + 0x0400)
+#define USART1_BASE             (APB2PERIPH_BASE + 0x1000)
+#define USART6_BASE             (APB2PERIPH_BASE + 0x1400)
+#define UART9_BASE              (APB2PERIPH_BASE + 0x1800U)
+#define UART10_BASE             (APB2PERIPH_BASE + 0x1C00U)
+#define ADC1_BASE               (APB2PERIPH_BASE + 0x2000)
+#define ADC2_BASE               (APB2PERIPH_BASE + 0x2100)
+#define ADC3_BASE               (APB2PERIPH_BASE + 0x2200)
+#define ADC_BASE                (APB2PERIPH_BASE + 0x2300)
+#define SDIO_BASE               (APB2PERIPH_BASE + 0x2C00)
+#define SPI1_BASE               (APB2PERIPH_BASE + 0x3000)
+#define SPI4_BASE               (APB2PERIPH_BASE + 0x3400)
+#define SYSCFG_BASE             (APB2PERIPH_BASE + 0x3800)
+#define EINT_BASE               (APB2PERIPH_BASE + 0x3C00)
+#define TMR9_BASE               (APB2PERIPH_BASE + 0x4000)
+#define TMR10_BASE              (APB2PERIPH_BASE + 0x4400)
+#define TMR11_BASE              (APB2PERIPH_BASE + 0x4800)
+#define SPI5_BASE               (APB2PERIPH_BASE + 0x5000)
+#define SPI6_BASE               (APB2PERIPH_BASE + 0x5400)
+#define SAI1_BASE               (APB2PERIPH_BASE + 0x5800)
+#define SAI1_Block_A_BASE       (SAI1_BASE + 0x004)
+#define SAI1_Block_B_BASE       (SAI1_BASE + 0x024)
+
+/** AHB1 peripherals */
+#define GPIOA_BASE              (AHB1PERIPH_BASE + 0x0000)
+#define GPIOB_BASE              (AHB1PERIPH_BASE + 0x0400)
+#define GPIOC_BASE              (AHB1PERIPH_BASE + 0x0800)
+#define GPIOD_BASE              (AHB1PERIPH_BASE + 0x0C00)
+#define GPIOE_BASE              (AHB1PERIPH_BASE + 0x1000)
+#define GPIOF_BASE              (AHB1PERIPH_BASE + 0x1400)
+#define GPIOG_BASE              (AHB1PERIPH_BASE + 0x1800)
+#define GPIOH_BASE              (AHB1PERIPH_BASE + 0x1C00)
+#define GPIOI_BASE              (AHB1PERIPH_BASE + 0x2000)
+#define GPIOJ_BASE              (AHB1PERIPH_BASE + 0x2400)
+#define GPIOK_BASE              (AHB1PERIPH_BASE + 0x2800)
+#define CRC_BASE                (AHB1PERIPH_BASE + 0x3000)
+#define RCM_BASE                (AHB1PERIPH_BASE + 0x3800)
+#define FMC_R_BASE              (AHB1PERIPH_BASE + 0x3C00)
+#define DMA1_BASE               (AHB1PERIPH_BASE + 0x6000)
+#define DMA1_Stream0_BASE       (DMA1_BASE + 0x010)
+#define DMA1_Stream1_BASE       (DMA1_BASE + 0x028)
+#define DMA1_Stream2_BASE       (DMA1_BASE + 0x040)
+#define DMA1_Stream3_BASE       (DMA1_BASE + 0x058)
+#define DMA1_Stream4_BASE       (DMA1_BASE + 0x070)
+#define DMA1_Stream5_BASE       (DMA1_BASE + 0x088)
+#define DMA1_Stream6_BASE       (DMA1_BASE + 0x0A0)
+#define DMA1_Stream7_BASE       (DMA1_BASE + 0x0B8)
+#define DMA2_BASE                (AHB1PERIPH_BASE + 0x6400)
+#define DMA2_Stream0_BASE       (DMA2_BASE + 0x010)
+#define DMA2_Stream1_BASE       (DMA2_BASE + 0x028)
+#define DMA2_Stream2_BASE       (DMA2_BASE + 0x040)
+#define DMA2_Stream3_BASE       (DMA2_BASE + 0x058)
+#define DMA2_Stream4_BASE       (DMA2_BASE + 0x070)
+#define DMA2_Stream5_BASE       (DMA2_BASE + 0x088)
+#define DMA2_Stream6_BASE       (DMA2_BASE + 0x0A0)
+#define DMA2_Stream7_BASE       (DMA2_BASE + 0x0B8)
+#define ETH_BASE                (AHB1PERIPH_BASE + 0x8000)
+#define ETH_MAC_BASE            (ETH_BASE)
+#define ETH_MMC_BASE            (ETH_BASE + 0x0100)
+#define ETH_PTP_BASE            (ETH_BASE + 0x0700)
+#define ETH_DMA_BASE            (ETH_BASE + 0x1000)
+#define DMA2D_BASE              (AHB1PERIPH_BASE + 0xB000)
+
+/** AHB2 peripherals */
+#define DCI_BASE                (AHB2PERIPH_BASE + 0x50000)
+#define CRYP_BASE               (AHB2PERIPH_BASE + 0x60000)
+#define HASH_BASE               (AHB2PERIPH_BASE + 0x60400)
+#define HASH_DIGEST_BASE        (AHB2PERIPH_BASE + 0x60710)
+#define RNG_BASE                (AHB2PERIPH_BASE + 0x60800)
+
+#define SMC_Bank1_R_BASE        (SMC_R_BASE + 0x0000)
+#define SMC_Bank1E_R_BASE       (SMC_R_BASE + 0x0104)
+#define SMC_Bank2_R_BASE        (SMC_R_BASE + 0x0060)
+#define SMC_Bank3_R_BASE        (SMC_R_BASE + 0x0080)
+#define SMC_Bank4_R_BASE        (SMC_R_BASE + 0x00A0)
+
+/* Debug MCU registers base address */
+#define DBGMCU_BASE             ((uint32_t )0xE0042000)
+/** Big number (BN) registers base address */
+#define BN_BASE                 ((uint32_t )0x500A0000)
+/** SM3 registers base address */
+#define SM3_BASE                ((uint32_t )0x50080000)
+/** SM4 registers base address */
+#define SM4_BASE                ((uint32_t )0x50080400)
+
+/**
+  * @}
+  */
+
+/** @defgroup Peripheral_declaration
+  @{
+*/
+
+#define TMR2                    ((TMR_T *) TMR2_BASE)
+#define TMR3                    ((TMR_T *) TMR3_BASE)
+#define TMR4                    ((TMR_T *) TMR4_BASE)
+#define TMR5                    ((TMR_T *) TMR5_BASE)
+#define TMR6                    ((TMR_T *) TMR6_BASE)
+#define TMR7                    ((TMR_T *) TMR7_BASE)
+#define TMR12                   ((TMR_T *) TMR12_BASE)
+#define TMR13                   ((TMR_T *) TMR13_BASE)
+#define TMR14                   ((TMR_T *) TMR14_BASE)
+#define RTC                     ((RTC_T *) RTC_BASE)
+#define WWDT                    ((WWDT_T *) WWDT_BASE)
+#define IWDT                    ((IWDT_T *) IWDT_BASE)
+#define I2S2ext                 ((SPI_T *) I2S2ext_BASE)
+#define SPI2                    ((SPI_T *) SPI2_BASE)
+#define SPI3                    ((SPI_T *) SPI3_BASE)
+#define I2S3ext                 ((SPI_T *) I2S3ext_BASE)
+#define USART2                  ((USART_T *) USART2_BASE)
+#define USART3                  ((USART_T *) USART3_BASE)
+#define UART4                   ((USART_T *) UART4_BASE)
+#define UART5                   ((USART_T *) UART5_BASE)
+#define I2C1                    ((I2C_T *) I2C1_BASE)
+#define I2C2                    ((I2C_T *) I2C2_BASE)
+#define I2C3                    ((I2C_T *) I2C3_BASE)
+#define CAN1                    ((CAN_T *) CAN1_BASE)
+#define CAN2                    ((CAN_T *) CAN2_BASE)
+#define PMU                     ((PMU_T *) PMU_BASE)
+#define DAC                     ((DAC_T *) DAC_BASE)
+#define UART7                   ((USART_T *) UART7_BASE)
+#define UART8                   ((USART_T *) UART8_BASE)
+#define UART9                   ((USART_T *) UART9_BASE)
+#define UART10                  ((USART_T *) UART10_BASE)
+#define TMR1                    ((TMR_T *) TMR1_BASE)
+#define TMR8                    ((TMR_T *) TMR8_BASE)
+#define USART1                  ((USART_T *) USART1_BASE)
+#define USART6                  ((USART_T *) USART6_BASE)
+#define ADC                     ((ADC_Common_T *) ADC_BASE)
+#define ADC1                    ((ADC_T *) ADC1_BASE)
+#define ADC2                    ((ADC_T *) ADC2_BASE)
+#define ADC3                    ((ADC_T *) ADC3_BASE)
+#define SDIO                    ((SDIO_T *) SDIO_BASE)
+#define SPI1                    ((SPI_T *) SPI1_BASE)
+#define SPI4                    ((SPI_T *) SPI4_BASE)
+#define SYSCFG                  ((SYSCFG_T *) SYSCFG_BASE)
+#define EINT                    ((EINT_T *) EINT_BASE)
+#define TMR9                    ((TMR_T *) TMR9_BASE)
+#define TMR10                   ((TMR_T *) TMR10_BASE)
+#define TMR11                   ((TMR_T *) TMR11_BASE)
+#define SPI5                    ((SPI_T *) SPI5_BASE)
+#define SPI6                    ((SPI_T *) SPI6_BASE)
+#define SAI1                    ((SAI_T *) SAI1_BASE)
+#define SAI1_Block_A            ((SAI_Block_T *)SAI1_Block_A_BASE)
+#define SAI1_Block_B            ((SAI_Block_T *)SAI1_Block_B_BASE)
+#define GPIOA                   ((GPIO_T *) GPIOA_BASE)
+#define GPIOB                   ((GPIO_T *) GPIOB_BASE)
+#define GPIOC                   ((GPIO_T *) GPIOC_BASE)
+#define GPIOD                   ((GPIO_T *) GPIOD_BASE)
+#define GPIOE                   ((GPIO_T *) GPIOE_BASE)
+#define GPIOF                   ((GPIO_T *) GPIOF_BASE)
+#define GPIOG                   ((GPIO_T *) GPIOG_BASE)
+#define GPIOH                   ((GPIO_T *) GPIOH_BASE)
+#define GPIOI                   ((GPIO_T *) GPIOI_BASE)
+#define GPIOJ                   ((GPIO_T *) GPIOJ_BASE)
+#define GPIOK                   ((GPIO_T *) GPIOK_BASE)
+#define CRC                     ((CRC_T *) CRC_BASE)
+#define RCM                     ((RCM_T *) RCM_BASE)
+#define FMC                     ((FMC_T *) FMC_R_BASE)
+#define DMA1                    ((DMA_T *) DMA1_BASE)
+#define DMA1_Stream0            ((DMA_Stream_T *) DMA1_Stream0_BASE)
+#define DMA1_Stream1            ((DMA_Stream_T *) DMA1_Stream1_BASE)
+#define DMA1_Stream2            ((DMA_Stream_T *) DMA1_Stream2_BASE)
+#define DMA1_Stream3            ((DMA_Stream_T *) DMA1_Stream3_BASE)
+#define DMA1_Stream4            ((DMA_Stream_T *) DMA1_Stream4_BASE)
+#define DMA1_Stream5            ((DMA_Stream_T *) DMA1_Stream5_BASE)
+#define DMA1_Stream6            ((DMA_Stream_T *) DMA1_Stream6_BASE)
+#define DMA1_Stream7            ((DMA_Stream_T *) DMA1_Stream7_BASE)
+#define DMA2                    ((DMA_T *) DMA2_BASE)
+#define DMA2_Stream0            ((DMA_Stream_T *) DMA2_Stream0_BASE)
+#define DMA2_Stream1            ((DMA_Stream_T *) DMA2_Stream1_BASE)
+#define DMA2_Stream2            ((DMA_Stream_T *) DMA2_Stream2_BASE)
+#define DMA2_Stream3            ((DMA_Stream_T *) DMA2_Stream3_BASE)
+#define DMA2_Stream4            ((DMA_Stream_T *) DMA2_Stream4_BASE)
+#define DMA2_Stream5            ((DMA_Stream_T *) DMA2_Stream5_BASE)
+#define DMA2_Stream6            ((DMA_Stream_T *) DMA2_Stream6_BASE)
+#define DMA2_Stream7            ((DMA_Stream_T *) DMA2_Stream7_BASE)
+#define ETH                     ((ETH_T *) ETH_BASE)
+#define DMA2D                   ((DMA2D_T *)DMA2D_BASE)
+#define DCI                     ((DCI_T *) DCI_BASE)
+#define CRYP                    ((CRYP_T *) CRYP_BASE)
+#define HASH                    ((HASH_T *) HASH_BASE)
+#define RNG                     ((RNG_T *) RNG_BASE)
+
+#define SMC_Bank1               ((SMC_Bank1_T *) SMC_Bank1_R_BASE)
+#define SMC_Bank1E              ((SMC_Bank1E_T *) SMC_Bank1E_R_BASE)
+#define SMC_Bank2               ((SMC_Bank2_T *) SMC_Bank2_R_BASE)
+#define SMC_Bank3               ((SMC_Bank3_T *) SMC_Bank3_R_BASE)
+#define SMC_Bank4               ((SMC_Bank4_T *) SMC_Bank4_R_BASE)
+
+#define DBGMCU                  ((DBGMCU_T *) DBGMCU_BASE)
+#define BN                      ((BN_T *) BN_BASE)
+#define SM3                     ((SM3_T *) SM3_BASE)
+#define SM4                     ((SM4_T *) SM4_BASE)
+#define DMC                     ((DMC_T *) DMC_BASE)
+
+/**
+  * @}
+  */
+
+/** @defgroup Exported_Macros
+  @{
+*/
+
+/* Define one bit mask */
+#define BIT0                    ((uint32_t)0x00000001)
+#define BIT1                    ((uint32_t)0x00000002)
+#define BIT2                    ((uint32_t)0x00000004)
+#define BIT3                    ((uint32_t)0x00000008)
+#define BIT4                    ((uint32_t)0x00000010)
+#define BIT5                    ((uint32_t)0x00000020)
+#define BIT6                    ((uint32_t)0x00000040)
+#define BIT7                    ((uint32_t)0x00000080)
+#define BIT8                    ((uint32_t)0x00000100)
+#define BIT9                    ((uint32_t)0x00000200)
+#define BIT10                   ((uint32_t)0x00000400)
+#define BIT11                   ((uint32_t)0x00000800)
+#define BIT12                   ((uint32_t)0x00001000)
+#define BIT13                   ((uint32_t)0x00002000)
+#define BIT14                   ((uint32_t)0x00004000)
+#define BIT15                   ((uint32_t)0x00008000)
+#define BIT16                   ((uint32_t)0x00010000)
+#define BIT17                   ((uint32_t)0x00020000)
+#define BIT18                   ((uint32_t)0x00040000)
+#define BIT19                   ((uint32_t)0x00080000)
+#define BIT20                   ((uint32_t)0x00100000)
+#define BIT21                   ((uint32_t)0x00200000)
+#define BIT22                   ((uint32_t)0x00400000)
+#define BIT23                   ((uint32_t)0x00800000)
+#define BIT24                   ((uint32_t)0x01000000)
+#define BIT25                   ((uint32_t)0x02000000)
+#define BIT26                   ((uint32_t)0x04000000)
+#define BIT27                   ((uint32_t)0x08000000)
+#define BIT28                   ((uint32_t)0x10000000)
+#define BIT29                   ((uint32_t)0x20000000)
+#define BIT30                   ((uint32_t)0x40000000)
+#define BIT31                   ((uint32_t)0x80000000)
+
+#define SET_BIT(REG, BIT)       ((REG) |= (BIT))
+
+#define CLEAR_BIT(REG, BIT)     ((REG) &= ~(BIT))
+
+#define READ_BIT(REG, BIT)      ((REG) & (BIT))
+
+#define CLEAR_REG(REG)          ((REG) = (0x0))
+
+#define WRITE_REG(REG, VAL)     ((REG) = (VAL))
+
+#define READ_REG(REG)           ((REG))
+
+#define MODIFY_REG(REG, CLEARMASK, SETMASK)  WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APM32F4XX_H */
+
+/**@} end of group APM32F4xx */
+/**@} end of group CMSIS */

+ 68 - 0
project_0/libraries/APM32F4xx_Library/Device/Geehy/APM32F4xx/Include/system_apm32f4xx.h

@@ -0,0 +1,68 @@
+/*!
+ * @file        system_apm32f4xx.h
+ *
+ * @brief       CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __SYSTEM_APM32F4XX_H
+#define __SYSTEM_APM32F4XX_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/** @addtogroup CMSIS
+  @{
+*/
+
+/** @addtogroup APM32F4xx_System
+  @{
+*/
+
+/** @defgroup System_Variables
+  @{
+*/
+
+/* System Clock Frequency (Core Clock) */
+extern uint32_t SystemCoreClock;
+
+/**
+  * @}
+  */
+
+/** @defgroup System_Functions
+  @{
+*/
+
+extern void SystemInit(void);
+extern void SystemCoreClockUpdate(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SYSTEM_APM32F4XX_H */
+
+/**@} end of group System_Functions */
+/**@} end of group APM32F4xx_System */
+/**@} end of group CMSIS */

+ 424 - 0
project_0/libraries/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/arm/startup_apm32f40x.s

@@ -0,0 +1,424 @@
+;/*!
+; * @file       startup_apm32f40x.s
+; *
+; * @brief      CMSIS Cortex-M4 based Core Device Startup File for Device startup_apm32f40x
+; *
+; * @version     V1.0.2
+; *
+; * @date        2022-06-23
+; *
+; * @attention
+; *
+; *  Copyright (C) 2021-2022 Geehy Semiconductor
+; *
+; *  You may not use this file except in compliance with the
+; *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+; *
+; *  The program is only for reference, which is distributed in the hope
+; *  that it will be usefull and instructional for customers to develop
+; *  their software. Unless required by applicable law or agreed to in
+; *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+; *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+; *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+; *  and limitations under the License.
+; */
+
+; <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
+
+; <h> Heap Configuration
+;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Heap_Size       EQU     0x00000200
+
+                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     MemManage_Handler          ; MPU Fault Handler
+                DCD     BusFault_Handler           ; Bus Fault Handler
+                DCD     UsageFault_Handler         ; Usage Fault Handler
+                DCD     0                          ; Reserved
+                DCD     0                          ; Reserved
+                DCD     0                          ; Reserved
+                DCD     0                          ; Reserved
+                DCD     SVC_Handler                ; SVCall Handler
+                DCD     DebugMon_Handler           ; Debug Monitor Handler
+                DCD     0                          ; Reserved
+                DCD     PendSV_Handler             ; PendSV Handler
+                DCD     SysTick_Handler            ; SysTick Handler
+
+                ; External Interrupts
+                DCD     WWDT_IRQHandler                 ; Window WatchDog
+                DCD     PVD_IRQHandler                  ; PVD through EINT Line detection
+                DCD     TAMP_STAMP_IRQHandler           ; Tamper and TimeStamps through the EINT line
+                DCD     RTC_WKUP_IRQHandler             ; RTC Wakeup through the EINT line
+                DCD     FLASH_IRQHandler                ; FLASH
+                DCD     RCM_IRQHandler                  ; RCM
+                DCD     EINT0_IRQHandler                ; EINT Line0
+                DCD     EINT1_IRQHandler                ; EINT Line1
+                DCD     EINT2_IRQHandler                ; EINT Line2
+                DCD     EINT3_IRQHandler                ; EINT Line3
+                DCD     EINT4_IRQHandler                ; EINT Line4
+                DCD     DMA1_STR0_IRQHandler            ; DMA1 Stream 0
+                DCD     DMA1_STR1_IRQHandler            ; DMA1 Stream 1
+                DCD     DMA1_STR2_IRQHandler            ; DMA1 Stream 2
+                DCD     DMA1_STR3_IRQHandler            ; DMA1 Stream 3
+                DCD     DMA1_STR4_IRQHandler            ; DMA1 Stream 4
+                DCD     DMA1_STR5_IRQHandler            ; DMA1 Stream 5
+                DCD     DMA1_STR6_IRQHandler            ; DMA1 Stream 6
+                DCD     ADC_IRQHandler                  ; ADC1, ADC2 and ADC3s
+                DCD     CAN1_TX_IRQHandler              ; CAN1 TX
+                DCD     CAN1_RX0_IRQHandler             ; CAN1 RX0
+                DCD     CAN1_RX1_IRQHandler             ; CAN1 RX1
+                DCD     CAN1_SCE_IRQHandler             ; CAN1 SCE
+                DCD     EINT9_5_IRQHandler              ; External Line[9:5]s
+                DCD     TMR1_BRK_TMR9_IRQHandler        ; TMR1 Break and TMR9
+                DCD     TMR1_UP_TMR10_IRQHandler        ; TMR1 Update and TMR10
+                DCD     TMR1_TRG_COM_TMR11_IRQHandler   ; TMR1 Trigger and Commutation and TMR11
+                DCD     TMR1_CC_IRQHandler              ; TMR1 Capture Compare
+                DCD     TMR2_IRQHandler                 ; TMR2
+                DCD     TMR3_IRQHandler                 ; TMR3
+                DCD     TMR4_IRQHandler                 ; TMR4
+                DCD     I2C1_EV_IRQHandler              ; I2C1 Event
+                DCD     I2C1_ER_IRQHandler              ; I2C1 Error
+                DCD     I2C2_EV_IRQHandler              ; I2C2 Event
+                DCD     I2C2_ER_IRQHandler              ; I2C2 Error
+                DCD     SPI1_IRQHandler                 ; SPI1
+                DCD     SPI2_IRQHandler                 ; SPI2
+                DCD     USART1_IRQHandler               ; USART1
+                DCD     USART2_IRQHandler               ; USART2
+                DCD     USART3_IRQHandler               ; USART3
+                DCD     EINT15_10_IRQHandler            ; External Line[15:10]s
+                DCD     RTC_Alarm_IRQHandler            ; RTC Alarm (A and B) through EINT Line
+                DCD     OTG_FS_WKUP_IRQHandler          ; OTG_FS Wakeup through EINT line
+                DCD     TMR8_BRK_TMR12_IRQHandler       ; TMR8 Break and TMR12
+                DCD     TMR8_UP_TMR13_IRQHandler        ; TMR8 Update and TMR13
+                DCD     TMR8_TRG_COM_TMR14_IRQHandler   ; TMR8 Trigger and Commutation and TMR14
+                DCD     TMR8_CC_IRQHandler              ; TMR8 Capture Compare
+                DCD     DMA1_STR7_IRQHandler            ; DMA1 Stream 7
+                DCD     EMMC_IRQHandler                 ; EMMC
+                DCD     SDIO_IRQHandler                 ; SDIO
+                DCD     TMR5_IRQHandler                 ; TMR5
+                DCD     SPI3_IRQHandler                 ; SPI3
+                DCD     UART4_IRQHandler                ; UART4
+                DCD     UART5_IRQHandler                ; UART5
+                DCD     TMR6_DAC_IRQHandler             ; TMR6 and DAC1&2 underrun errors
+                DCD     TMR7_IRQHandler                 ; TMR7
+                DCD     DMA2_STR0_IRQHandler            ; DMA2 Stream 0
+                DCD     DMA2_STR1_IRQHandler            ; DMA2 Stream 1
+                DCD     DMA2_STR2_IRQHandler            ; DMA2 Stream 2
+                DCD     DMA2_STR3_IRQHandler            ; DMA2 Stream 3
+                DCD     DMA2_STR4_IRQHandler            ; DMA2 Stream 4
+                DCD     ETH_IRQHandler                  ; Ethernet
+                DCD     ETH_WKUP_IRQHandler             ; Ethernet Wakeup through EINT line
+                DCD     CAN2_TX_IRQHandler              ; CAN2 TX
+                DCD     CAN2_RX0_IRQHandler             ; CAN2 RX0
+                DCD     CAN2_RX1_IRQHandler             ; CAN2 RX1
+                DCD     CAN2_SCE_IRQHandler             ; CAN2 SCE
+                DCD     OTG_FS_IRQHandler               ; OTG_FS
+                DCD     DMA2_STR5_IRQHandler            ; DMA2 Stream 5
+                DCD     DMA2_STR6_IRQHandler            ; DMA2 Stream 6
+                DCD     DMA2_STR7_IRQHandler            ; DMA2 Stream 7
+                DCD     USART6_IRQHandler               ; USART6
+                DCD     I2C3_EV_IRQHandler              ; I2C3 event
+                DCD     I2C3_ER_IRQHandler              ; I2C3 error
+                DCD     OTG_HS1_EP1_OUT_IRQHandler      ; OTG_HS1 End Point 1 Out
+                DCD     OTG_HS1_EP1_IN_IRQHandler       ; OTG_HS1 End Point 1 In
+                DCD     OTG_HS1_WKUP_IRQHandler         ; OTG_HS1 Wakeup through EINT
+                DCD     OTG_HS1_IRQHandler              ; OTG_HS1
+                DCD     DCI_IRQHandler                  ; DCI
+                DCD     0                               ; Reserved
+                DCD     0                               ; Reserved
+                DCD     FPU_IRQHandler                  ; FPU
+                DCD     SM3_IRQHandler                  ; SM3
+                DCD     SM4_IRQHandler                  ; SM4
+                DCD     BN_IRQHandler                   ; BN
+__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, =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
+MemManage_Handler\
+                PROC
+                EXPORT  MemManage_Handler          [WEAK]
+                B       .
+                ENDP
+BusFault_Handler\
+                PROC
+                EXPORT  BusFault_Handler           [WEAK]
+                B       .
+                ENDP
+UsageFault_Handler\
+                PROC
+                EXPORT  UsageFault_Handler         [WEAK]
+                B       .
+                ENDP
+SVC_Handler     PROC
+                EXPORT  SVC_Handler                [WEAK]
+                B       .
+                ENDP
+DebugMon_Handler\
+                PROC
+                EXPORT  DebugMon_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  WWDT_IRQHandler                     [WEAK]
+                EXPORT  PVD_IRQHandler                      [WEAK]
+                EXPORT  TAMP_STAMP_IRQHandler               [WEAK]
+                EXPORT  RTC_WKUP_IRQHandler                 [WEAK]
+                EXPORT  FLASH_IRQHandler                    [WEAK]
+                EXPORT  RCM_IRQHandler                      [WEAK]
+                EXPORT  EINT0_IRQHandler                    [WEAK]
+                EXPORT  EINT1_IRQHandler                    [WEAK]
+                EXPORT  EINT2_IRQHandler                    [WEAK]
+                EXPORT  EINT3_IRQHandler                    [WEAK]
+                EXPORT  EINT4_IRQHandler                    [WEAK]
+                EXPORT  DMA1_STR0_IRQHandler                [WEAK]
+                EXPORT  DMA1_STR1_IRQHandler                [WEAK]
+                EXPORT  DMA1_STR2_IRQHandler                [WEAK]
+                EXPORT  DMA1_STR3_IRQHandler                [WEAK]
+                EXPORT  DMA1_STR4_IRQHandler                [WEAK]
+                EXPORT  DMA1_STR5_IRQHandler                [WEAK]
+                EXPORT  DMA1_STR6_IRQHandler                [WEAK]
+                EXPORT  ADC_IRQHandler                      [WEAK]
+                EXPORT  CAN1_TX_IRQHandler                  [WEAK]
+                EXPORT  CAN1_RX0_IRQHandler                 [WEAK]
+                EXPORT  CAN1_RX1_IRQHandler                 [WEAK]
+                EXPORT  CAN1_SCE_IRQHandler                 [WEAK]
+                EXPORT  EINT9_5_IRQHandler                  [WEAK]
+                EXPORT  TMR1_BRK_TMR9_IRQHandler            [WEAK]
+                EXPORT  TMR1_UP_TMR10_IRQHandler            [WEAK]
+                EXPORT  TMR1_TRG_COM_TMR11_IRQHandler       [WEAK]
+                EXPORT  TMR1_CC_IRQHandler                  [WEAK]
+                EXPORT  TMR2_IRQHandler                     [WEAK]
+                EXPORT  TMR3_IRQHandler                     [WEAK]
+                EXPORT  TMR4_IRQHandler                     [WEAK]
+                EXPORT  I2C1_EV_IRQHandler                  [WEAK]
+                EXPORT  I2C1_ER_IRQHandler                  [WEAK]
+                EXPORT  I2C2_EV_IRQHandler                  [WEAK]
+                EXPORT  I2C2_ER_IRQHandler                  [WEAK]
+                EXPORT  SPI1_IRQHandler                     [WEAK]
+                EXPORT  SPI2_IRQHandler                     [WEAK]
+                EXPORT  USART1_IRQHandler                   [WEAK]
+                EXPORT  USART2_IRQHandler                   [WEAK]
+                EXPORT  USART3_IRQHandler                   [WEAK]
+                EXPORT  EINT15_10_IRQHandler                [WEAK]
+                EXPORT  RTC_Alarm_IRQHandler                [WEAK]
+                EXPORT  OTG_FS_WKUP_IRQHandler              [WEAK]
+                EXPORT  TMR8_BRK_TMR12_IRQHandler           [WEAK]
+                EXPORT  TMR8_UP_TMR13_IRQHandler            [WEAK]
+                EXPORT  TMR8_TRG_COM_TMR14_IRQHandler       [WEAK]
+                EXPORT  TMR8_CC_IRQHandler                  [WEAK]
+                EXPORT  DMA1_STR7_IRQHandler                [WEAK]
+                EXPORT  EMMC_IRQHandler                     [WEAK]
+                EXPORT  SDIO_IRQHandler                     [WEAK]
+                EXPORT  TMR5_IRQHandler                     [WEAK]
+                EXPORT  SPI3_IRQHandler                     [WEAK]
+                EXPORT  UART4_IRQHandler                    [WEAK]
+                EXPORT  UART5_IRQHandler                    [WEAK]
+                EXPORT  TMR6_DAC_IRQHandler                 [WEAK]
+                EXPORT  TMR7_IRQHandler                     [WEAK]
+                EXPORT  DMA2_STR0_IRQHandler                [WEAK]
+                EXPORT  DMA2_STR1_IRQHandler                [WEAK]
+                EXPORT  DMA2_STR2_IRQHandler                [WEAK]
+                EXPORT  DMA2_STR3_IRQHandler                [WEAK]
+                EXPORT  DMA2_STR4_IRQHandler                [WEAK]
+                EXPORT  ETH_IRQHandler                      [WEAK]
+                EXPORT  ETH_WKUP_IRQHandler                 [WEAK]
+                EXPORT  CAN2_TX_IRQHandler                  [WEAK]
+                EXPORT  CAN2_RX0_IRQHandler                 [WEAK]
+                EXPORT  CAN2_RX1_IRQHandler                 [WEAK]
+                EXPORT  CAN2_SCE_IRQHandler                 [WEAK]
+                EXPORT  OTG_FS_IRQHandler                   [WEAK]
+                EXPORT  DMA2_STR5_IRQHandler                [WEAK]
+                EXPORT  DMA2_STR6_IRQHandler                [WEAK]
+                EXPORT  DMA2_STR7_IRQHandler                [WEAK]
+                EXPORT  USART6_IRQHandler                   [WEAK]
+                EXPORT  I2C3_EV_IRQHandler                  [WEAK]
+                EXPORT  I2C3_ER_IRQHandler                  [WEAK]
+                EXPORT  OTG_HS1_EP1_OUT_IRQHandler          [WEAK]
+                EXPORT  OTG_HS1_EP1_IN_IRQHandler           [WEAK]
+                EXPORT  OTG_HS1_WKUP_IRQHandler             [WEAK]
+                EXPORT  OTG_HS1_IRQHandler                  [WEAK]
+                EXPORT  DCI_IRQHandler                      [WEAK]
+                EXPORT  FPU_IRQHandler                      [WEAK]
+                EXPORT  SM3_IRQHandler                      [WEAK]
+                EXPORT  SM4_IRQHandler                      [WEAK]
+                EXPORT  BN_IRQHandler                       [WEAK]
+
+WWDT_IRQHandler
+PVD_IRQHandler
+TAMP_STAMP_IRQHandler
+RTC_WKUP_IRQHandler
+FLASH_IRQHandler
+RCM_IRQHandler
+EINT0_IRQHandler
+EINT1_IRQHandler
+EINT2_IRQHandler
+EINT3_IRQHandler
+EINT4_IRQHandler
+DMA1_STR0_IRQHandler
+DMA1_STR1_IRQHandler
+DMA1_STR2_IRQHandler
+DMA1_STR3_IRQHandler
+DMA1_STR4_IRQHandler
+DMA1_STR5_IRQHandler
+DMA1_STR6_IRQHandler
+ADC_IRQHandler
+CAN1_TX_IRQHandler
+CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EINT9_5_IRQHandler
+TMR1_BRK_TMR9_IRQHandler
+TMR1_UP_TMR10_IRQHandler
+TMR1_TRG_COM_TMR11_IRQHandler
+TMR1_CC_IRQHandler
+TMR2_IRQHandler
+TMR3_IRQHandler
+TMR4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EINT15_10_IRQHandler
+RTC_Alarm_IRQHandler
+OTG_FS_WKUP_IRQHandler
+TMR8_BRK_TMR12_IRQHandler
+TMR8_UP_TMR13_IRQHandler
+TMR8_TRG_COM_TMR14_IRQHandler
+TMR8_CC_IRQHandler
+DMA1_STR7_IRQHandler
+EMMC_IRQHandler
+SDIO_IRQHandler
+TMR5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TMR6_DAC_IRQHandler
+TMR7_IRQHandler
+DMA2_STR0_IRQHandler
+DMA2_STR1_IRQHandler
+DMA2_STR2_IRQHandler
+DMA2_STR3_IRQHandler
+DMA2_STR4_IRQHandler
+ETH_IRQHandler
+ETH_WKUP_IRQHandler
+CAN2_TX_IRQHandler
+CAN2_RX0_IRQHandler
+CAN2_RX1_IRQHandler
+CAN2_SCE_IRQHandler
+OTG_FS_IRQHandler
+DMA2_STR5_IRQHandler
+DMA2_STR6_IRQHandler
+DMA2_STR7_IRQHandler
+USART6_IRQHandler
+I2C3_EV_IRQHandler
+I2C3_ER_IRQHandler
+OTG_HS1_EP1_OUT_IRQHandler
+OTG_HS1_EP1_IN_IRQHandler
+OTG_HS1_WKUP_IRQHandler
+OTG_HS1_IRQHandler
+DCI_IRQHandler
+FPU_IRQHandler
+SM3_IRQHandler
+SM4_IRQHandler
+BN_IRQHandler
+
+                B       .
+
+                ENDP
+
+                ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+                 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
+
+                 LDR     R0, =  Heap_Mem
+                 LDR     R1, =(Stack_Mem + Stack_Size)
+                 LDR     R2, = (Heap_Mem +  Heap_Size)
+                 LDR     R3, = Stack_Mem
+                 BX      LR
+
+                 ALIGN
+
+                 ENDIF
+
+                 END
+
+;************************ (C) COPYRIGHT Geehy Semiconductor Co.,Ltd *****END OF FILE*****

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott