luobeihai преди 2 години
ревизия
63499cd56e
променени са 100 файла, в които са добавени 38994 реда и са изтрити 0 реда
  1. 1 0
      README.md
  2. BIN
      documents/APM32F405xG 407xExG datasheet V1.5.pdf
  3. BIN
      documents/APM32F407 EVAL V1.1 Schematic.pdf
  4. BIN
      documents/APM32F407ZG Core V1 Schematic.pdf
  5. BIN
      documents/APM32F4xxx User Manual V1.6.pdf
  6. BIN
      documents/images/APM32F407ZG-EVAL.png
  7. BIN
      documents/images/APM32F407ZG-EVAL_small.png
  8. 996 0
      project_0/.config
  9. 184 0
      project_0/.cproject
  10. 42 0
      project_0/.gitignore
  11. 28 0
      project_0/.project
  12. 3 0
      project_0/.settings/org.eclipse.core.runtime.prefs
  13. 20 0
      project_0/.settings/projcfg.ini
  14. 22 0
      project_0/Kconfig
  15. 116 0
      project_0/README.md
  16. 15 0
      project_0/SConscript
  17. 64 0
      project_0/SConstruct
  18. 11 0
      project_0/applications/SConscript
  19. 35 0
      project_0/applications/main.c
  20. 256 0
      project_0/board/Kconfig
  21. 35 0
      project_0/board/SConscript
  22. 204 0
      project_0/board/board.c
  23. 85 0
      project_0/board/board.h
  24. 28 0
      project_0/board/linker_scripts/link.icf
  25. 147 0
      project_0/board/linker_scripts/link.lds
  26. 17 0
      project_0/board/linker_scripts/link.sct
  27. 31 0
      project_0/board/ports/spi_flash_init.c
  28. BIN
      project_0/figures/APM32F407ZG-EVAL.png
  29. BIN
      project_0/figures/JFlash_Leader_01.png
  30. BIN
      project_0/figures/JFlash_Leader_02.png
  31. BIN
      project_0/figures/JFlash_Leader_03.png
  32. BIN
      project_0/figures/JFlash_Leader_04.png
  33. 1424 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/inc/apm32f4xx_eth.h
  34. 2308 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/src/apm32f4xx_eth.c
  35. 432 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_adc.h
  36. 349 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_can.h
  37. 66 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_crc.h
  38. 272 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_cryp.h
  39. 203 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dac.h
  40. 106 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dbgmcu.h
  41. 241 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dci.h
  42. 414 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dma.h
  43. 359 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_dmc.h
  44. 139 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_eint.h
  45. 361 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_fmc.h
  46. 285 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_gpio.h
  47. 215 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_hash.h
  48. 352 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_i2c.h
  49. 123 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_iwdt.h
  50. 119 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_misc.h
  51. 142 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_pmu.h
  52. 485 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rcm.h
  53. 98 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rng.h
  54. 597 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_rtc.h
  55. 377 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_sdio.h
  56. 370 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_smc.h
  57. 346 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_spi.h
  58. 132 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_syscfg.h
  59. 709 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_tmr.h
  60. 314 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_usart.h
  61. 94 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/inc/apm32f4xx_wwdt.h
  62. 1028 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_adc.c
  63. 1072 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_can.c
  64. 125 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_crc.c
  65. 463 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp.c
  66. 553 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_aes.c
  67. 232 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_des.c
  68. 248 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_cryp_tdes.c
  69. 538 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dac.c
  70. 197 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dbgmcu.c
  71. 369 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dci.c
  72. 652 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dma.c
  73. 435 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_dmc.c
  74. 324 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_eint.c
  75. 791 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_fmc.c
  76. 442 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_gpio.c
  77. 401 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash.c
  78. 253 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash_md5.c
  79. 253 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_hash_sha1.c
  80. 1070 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_i2c.c
  81. 150 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_iwdt.c
  82. 225 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_misc.c
  83. 339 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_pmu.c
  84. 1574 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rcm.c
  85. 195 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rng.c
  86. 1899 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_rtc.c
  87. 720 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_sdio.c
  88. 969 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_smc.c
  89. 714 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_spi.c
  90. 194 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_syscfg.c
  91. 2300 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_tmr.c
  92. 862 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_usart.c
  93. 153 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_StdPeriphDriver/src/apm32f4xx_wwdt.c
  94. 176 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/LICENSE.txt
  95. 888 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/cmsis_armcc.h
  96. 283 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/cmsis_compiler.h
  97. 1858 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cm4.h
  98. 664 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmFunc.h
  99. 916 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmInstr.h
  100. 697 0
      project_0/libraries/APM32F4xx_Library/CMSIS/Include/core_cmSimd.h

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# sdk-bsp-apm32f407zg-geehy-eval

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


BIN
documents/APM32F407 EVAL V1.1 Schematic.pdf


BIN
documents/APM32F407ZG Core V1 Schematic.pdf


BIN
documents/APM32F4xxx User Manual V1.6.pdf


BIN
documents/images/APM32F407ZG-EVAL.png


BIN
documents/images/APM32F407ZG-EVAL_small.png


+ 996 - 0
project_0/.config

@@ -0,0 +1,996 @@
+#
+# 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_SMART is not set
+# CONFIG_RT_USING_SMP is not set
+CONFIG_RT_ALIGN_SIZE=8
+# 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_PAGE_MAX_ORDER=11
+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_DM 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=0x50000
+# CONFIG_RT_USING_CACHE is not set
+# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
+CONFIG_RT_USING_CPU_FFS=y
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_CORTEX_M=y
+CONFIG_ARCH_ARM_CORTEX_M4=y
+
+#
+# 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 is not set
+# CONFIG_RT_USING_FAL is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_UNAMED_PIPE_NUMBER=64
+CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
+CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
+CONFIG_RT_SERIAL_USING_DMA=y
+CONFIG_RT_SERIAL_RB_BUFSZ=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_NULL is not set
+# CONFIG_RT_USING_ZERO is not set
+# CONFIG_RT_USING_RANDOM 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_FDT 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_LCD is not set
+# CONFIG_RT_USING_HWCRYPTO is not set
+# CONFIG_RT_USING_PULSE_ENCODER is not set
+# CONFIG_RT_USING_INPUT_CAPTURE is not set
+# CONFIG_RT_USING_DEV_BUS is not set
+# CONFIG_RT_USING_WIFI is not set
+# CONFIG_RT_USING_VIRTIO is not set
+
+#
+# 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_LWIP is not set
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_MYMQTT is not set
+# CONFIG_PKG_USING_KAWAII_MQTT is not set
+# CONFIG_PKG_USING_BC28_MQTT is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_FREEMODBUS is not set
+# CONFIG_PKG_USING_NANOPB is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_RW007 is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_CMUX is not set
+# CONFIG_PKG_USING_PPP_DEVICE is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+# CONFIG_PKG_USING_ZB_COORDINATOR is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
+# CONFIG_PKG_USING_JIOT-C-SDK is not set
+# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
+# CONFIG_PKG_USING_JOYLINK is not set
+# CONFIG_PKG_USING_EZ_IOT_OS is not set
+# CONFIG_PKG_USING_IOTSHARP_SDK is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+# CONFIG_PKG_USING_TCPSERVER is not set
+# CONFIG_PKG_USING_PROTOBUF_C is not set
+# CONFIG_PKG_USING_DLT645 is not set
+# CONFIG_PKG_USING_QXWZ is not set
+# CONFIG_PKG_USING_SMTP_CLIENT is not set
+# CONFIG_PKG_USING_ABUP_FOTA is not set
+# CONFIG_PKG_USING_LIBCURL2RTT is not set
+# CONFIG_PKG_USING_CAPNP is not set
+# CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
+# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
+# CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_RYANMQTT is not set
+# CONFIG_PKG_USING_RYANW5500 is not set
+# CONFIG_PKG_USING_LORA_PKT_FWD is not set
+# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
+# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
+# CONFIG_PKG_USING_HM is not set
+# CONFIG_PKG_USING_SMALL_MODBUS is not set
+# CONFIG_PKG_USING_NET_SERVER is not set
+# CONFIG_PKG_USING_ZFTP is not set
+# CONFIG_PKG_USING_WOL is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_LIBSODIUM is not set
+# CONFIG_PKG_USING_LIBHYDROGEN is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+# CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
+
+#
+# language packages
+#
+
+#
+# JSON: JavaScript Object Notation, a lightweight data-interchange format
+#
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PARSON is not set
+
+#
+# XML: Extensible Markup Language
+#
+# CONFIG_PKG_USING_SIMPLE_XML is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_LUATOS_SOC is not set
+# CONFIG_PKG_USING_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+# CONFIG_PKG_USING_PIKASCRIPT is not set
+# CONFIG_PKG_USING_RTT_RUST is not set
+
+#
+# multimedia packages
+#
+
+#
+# LVGL: powerful and easy-to-use embedded GUI library
+#
+# CONFIG_PKG_USING_LVGL is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
+# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
+
+#
+# u8g2: a monochrome graphic library
+#
+# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+# CONFIG_PKG_USING_WAVPLAYER is not set
+# CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
+# CONFIG_PKG_USING_MP3PLAYER is not set
+# CONFIG_PKG_USING_TINYJPEG is not set
+# CONFIG_PKG_USING_UGUI is not set
+
+#
+# PainterEngine: A cross-platform graphics application framework written in C language
+#
+# CONFIG_PKG_USING_PAINTERENGINE is not set
+# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_SEGGER_RTT is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_LOGMGR is not set
+# CONFIG_PKG_USING_ADBD is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
+# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
+# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
+# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
+# CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
+# CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
+# CONFIG_PKG_USING_CPU_USAGE is not set
+# CONFIG_PKG_USING_GBK2UTF8 is not set
+# CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
+# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
+# CONFIG_PKG_USING_LWLOG is not set
+# CONFIG_PKG_USING_ANV_TRACE is not set
+# CONFIG_PKG_USING_ANV_MEMLEAK is not set
+# CONFIG_PKG_USING_ANV_TESTSUIT is not set
+# CONFIG_PKG_USING_ANV_BENCH is not set
+# CONFIG_PKG_USING_DEVMEM is not set
+# CONFIG_PKG_USING_REGEX is not set
+# CONFIG_PKG_USING_MEM_SANDBOX is not set
+# CONFIG_PKG_USING_SOLAR_TERMS is not set
+# CONFIG_PKG_USING_GAN_ZHI is not set
+# CONFIG_PKG_USING_FDT is not set
+# CONFIG_PKG_USING_CBOX is not set
+# CONFIG_PKG_USING_SNOWFLAKE is not set
+# CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
+# CONFIG_PKG_USING_VOFA_PLUS is not set
+
+#
+# system packages
+#
+
+#
+# enhanced kernel services
+#
+# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
+# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
+# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
+
+#
+# acceleration: Assembly language or algorithmic acceleration packages
+#
+# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
+# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
+# CONFIG_PKG_USING_QFPLIB_M3 is not set
+
+#
+# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
+#
+# CONFIG_PKG_USING_CMSIS_5 is not set
+# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
+# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
+# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_PERF_COUNTER is not set
+# CONFIG_PKG_USING_FLASHDB is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+# CONFIG_PKG_USING_ROBOTS is not set
+# CONFIG_PKG_USING_EV is not set
+# CONFIG_PKG_USING_SYSWATCH is not set
+# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
+# CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+# CONFIG_PKG_USING_PPOOL is not set
+# CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
+# CONFIG_PKG_USING_MCUBOOT is not set
+# CONFIG_PKG_USING_TINYUSB is not set
+# CONFIG_PKG_USING_CHERRYUSB is not set
+# CONFIG_PKG_USING_KMULTI_RTIMER is not set
+# CONFIG_PKG_USING_TFDB is not set
+# CONFIG_PKG_USING_QPC is not set
+# CONFIG_PKG_USING_AGILE_UPGRADE is not set
+# CONFIG_PKG_USING_FLASH_BLOB is not set
+
+#
+# peripheral libraries and drivers
+#
+
+#
+# sensors drivers
+#
+# CONFIG_PKG_USING_LSM6DSM is not set
+# CONFIG_PKG_USING_LSM6DSL is not set
+# CONFIG_PKG_USING_LPS22HB is not set
+# CONFIG_PKG_USING_HTS221 is not set
+# CONFIG_PKG_USING_LSM303AGR is not set
+# CONFIG_PKG_USING_BME280 is not set
+# CONFIG_PKG_USING_BME680 is not set
+# CONFIG_PKG_USING_BMA400 is not set
+# CONFIG_PKG_USING_BMI160_BMX160 is not set
+# CONFIG_PKG_USING_SPL0601 is not set
+# CONFIG_PKG_USING_MS5805 is not set
+# CONFIG_PKG_USING_DA270 is not set
+# CONFIG_PKG_USING_DF220 is not set
+# CONFIG_PKG_USING_HSHCAL001 is not set
+# CONFIG_PKG_USING_BH1750 is not set
+# CONFIG_PKG_USING_MPU6XXX is not set
+# CONFIG_PKG_USING_AHT10 is not set
+# CONFIG_PKG_USING_AP3216C is not set
+# CONFIG_PKG_USING_TSL4531 is not set
+# CONFIG_PKG_USING_DS18B20 is not set
+# CONFIG_PKG_USING_DHT11 is not set
+# CONFIG_PKG_USING_DHTXX is not set
+# CONFIG_PKG_USING_GY271 is not set
+# CONFIG_PKG_USING_GP2Y10 is not set
+# CONFIG_PKG_USING_SGP30 is not set
+# CONFIG_PKG_USING_HDC1000 is not set
+# CONFIG_PKG_USING_BMP180 is not set
+# CONFIG_PKG_USING_BMP280 is not set
+# CONFIG_PKG_USING_SHTC1 is not set
+# CONFIG_PKG_USING_BMI088 is not set
+# CONFIG_PKG_USING_HMC5883 is not set
+# CONFIG_PKG_USING_MAX6675 is not set
+# CONFIG_PKG_USING_TMP1075 is not set
+# CONFIG_PKG_USING_SR04 is not set
+# CONFIG_PKG_USING_CCS811 is not set
+# CONFIG_PKG_USING_PMSXX is not set
+# CONFIG_PKG_USING_RT3020 is not set
+# CONFIG_PKG_USING_MLX90632 is not set
+# CONFIG_PKG_USING_MLX90393 is not set
+# CONFIG_PKG_USING_MLX90392 is not set
+# CONFIG_PKG_USING_MLX90397 is not set
+# CONFIG_PKG_USING_MS5611 is not set
+# CONFIG_PKG_USING_MAX31865 is not set
+# CONFIG_PKG_USING_VL53L0X is not set
+# CONFIG_PKG_USING_INA260 is not set
+# CONFIG_PKG_USING_MAX30102 is not set
+# CONFIG_PKG_USING_INA226 is not set
+# CONFIG_PKG_USING_LIS2DH12 is not set
+# CONFIG_PKG_USING_HS300X is not set
+# CONFIG_PKG_USING_ZMOD4410 is not set
+# CONFIG_PKG_USING_ISL29035 is not set
+# CONFIG_PKG_USING_MMC3680KJ is not set
+# CONFIG_PKG_USING_QMP6989 is not set
+# CONFIG_PKG_USING_BALANCE is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_ADT74XX is not set
+# CONFIG_PKG_USING_MAX17048 is not set
+# CONFIG_PKG_USING_AS7341 is not set
+# CONFIG_PKG_USING_CW2015 is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+
+#
+# touch drivers
+#
+# CONFIG_PKG_USING_GT9147 is not set
+# CONFIG_PKG_USING_GT1151 is not set
+# CONFIG_PKG_USING_GT917S is not set
+# CONFIG_PKG_USING_GT911 is not set
+# CONFIG_PKG_USING_FT6206 is not set
+# CONFIG_PKG_USING_FT5426 is not set
+# CONFIG_PKG_USING_FT6236 is not set
+# CONFIG_PKG_USING_XPT2046_TOUCH is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ESP_IDF is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_LITTLED is not set
+# CONFIG_PKG_USING_LKDGUI is not set
+# CONFIG_PKG_USING_NRF5X_SDK is not set
+# CONFIG_PKG_USING_NRFX is not set
+# CONFIG_PKG_USING_WM_LIBRARIES is not set
+
+#
+# Kendryte SDK
+#
+# CONFIG_PKG_USING_K210_SDK is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_MULTI_INFRARED is not set
+# CONFIG_PKG_USING_AGILE_BUTTON is not set
+# CONFIG_PKG_USING_AGILE_LED is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_RPLIDAR is not set
+# CONFIG_PKG_USING_AS608 is not set
+# CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
+# CONFIG_PKG_USING_EMBARC_BSP is not set
+# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
+# CONFIG_PKG_USING_MULTI_RTIMER is not set
+# CONFIG_PKG_USING_MAX7219 is not set
+# CONFIG_PKG_USING_BEEP is not set
+# CONFIG_PKG_USING_EASYBLINK is not set
+# CONFIG_PKG_USING_PMS_SERIES is not set
+# CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
+# CONFIG_PKG_USING_RS485 is not set
+# CONFIG_PKG_USING_RS232 is not set
+# CONFIG_PKG_USING_NES is not set
+# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
+# CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+# CONFIG_PKG_USING_KOBUKI is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_MICRO_ROS is not set
+# CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
+# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
+# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
+# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
+# CONFIG_PKG_USING_BL_MCU_SDK is not set
+# CONFIG_PKG_USING_SOFT_SERIAL is not set
+# CONFIG_PKG_USING_MB85RS16 is not set
+# CONFIG_PKG_USING_RFM300 is not set
+# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
+# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
+# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
+# CONFIG_PKG_USING_FINGERPRINT is not set
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
+
+#
+# Signal Processing and Control Algorithm Packages
+#
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
+# CONFIG_PKG_USING_UKAL is not set
+
+#
+# miscellaneous packages
+#
+
+#
+# project laboratory
+#
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_COWSAY is not set
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_LZMA is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_MINIZIP is not set
+# CONFIG_PKG_USING_HEATSHRINK is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+# CONFIG_PKG_USING_UPACKER is not set
+# CONFIG_PKG_USING_UPARAM is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_KI is not set
+# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_CRCLIB is not set
+# CONFIG_PKG_USING_LWGPS is not set
+# CONFIG_PKG_USING_STATE_MACHINE is not set
+# CONFIG_PKG_USING_DESIGN_PATTERN is not set
+# CONFIG_PKG_USING_CONTROLLER is not set
+# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
+# CONFIG_PKG_USING_MFBD is not set
+# CONFIG_PKG_USING_SLCAN2RTT is not set
+# CONFIG_PKG_USING_SOEM is not set
+# CONFIG_PKG_USING_QPARAM is not set
+# CONFIG_PKG_USING_CorevMCU_CLI is not set
+
+#
+# Arduino libraries
+#
+# CONFIG_PKG_USING_RTDUINO is not set
+
+#
+# Projects
+#
+# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
+# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
+# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
+
+#
+# Sensors
+#
+# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set
+# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
+# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
+# CONFIG_PKG_USING_SEEED_ITG3200 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
+# CONFIG_PKG_USING_SEEED_MP503 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
+
+#
+# Display
+#
+# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
+# CONFIG_PKG_USING_SEEED_TM1637 is not set
+
+#
+# Timing
+#
+# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
+
+#
+# Data Processing
+#
+# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
+# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
+
+#
+# Data Storage
+#
+
+#
+# Communication
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
+
+#
+# Device Control
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
+
+#
+# Other
+#
+
+#
+# Signal IO
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
+
+#
+# Uncategorized
+#
+CONFIG_SOC_FAMILY_APM32=y
+CONFIG_SOC_SERIES_APM32F4=y
+
+#
+# Hardware Drivers Config
+#
+CONFIG_SOC_APM32F407ZG=y
+
+#
+# Onboard Peripheral Drivers
+#
+CONFIG_BSP_USING_USB_TO_USART=y
+# CONFIG_BSP_USING_SPI_FLASH is not set
+# CONFIG_BSP_USING_ETH is not set
+
+#
+# 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_I2C 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
+
+#
+# Board extended module Drivers
+#

Файловите разлики са ограничени, защото са твърде много
+ 184 - 0
project_0/.cproject


+ 42 - 0
project_0/.gitignore

@@ -0,0 +1,42 @@
+*.pyc
+*.map
+*.dblite
+*.elf
+*.bin
+*.hex
+*.axf
+*.exe
+*.pdb
+*.idb
+*.ilk
+*.old
+build
+Debug
+documentation/html
+packages/
+*~
+*.o
+*.obj
+*.out
+*.bak
+*.dep
+*.lib
+*.i
+*.d
+.DS_Stor*
+.config 3
+.config 4
+.config 5
+Midea-X1
+*.uimg
+GPATH
+GRTAGS
+GTAGS
+.vscode
+JLinkLog.txt
+JLinkSettings.ini
+DebugConfig/
+RTE/
+settings/
+*.uvguix*
+cconfig.h

+ 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
+# Fri Mar 10 17:18:19 2023
+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=D:\study material\RT-Thread\2023011402\rt-thread\bsp\apm32\apm32f407zg-evalboard - 01\project_0

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

+ 116 - 0
project_0/README.md

@@ -0,0 +1,116 @@
+# APM32F407ZG EVAL BOARD BSP 说明
+
+## 简介
+
+本文档为 APM32F407ZG EVAL 开发板(EVAL BOARD)的 BSP (板级支持包) 说明。
+
+主要内容如下:
+
+- 开发板资源介绍
+- BSP 快速上手
+
+通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。
+
+## 开发板介绍
+
+APM32F407ZG EVAL BOARD,采用标准JTAG/SWD调试接口,引出了全部的IO。开发板外观如下图所示:
+
+![image-20230112193936832](figures/APM32F407ZG-EVAL.png)
+
+- 有关开发板和芯片的详情可至极海官网查阅。[官网开发板链接 ](https://www.geehy.com/support/apm32?id=192)
+
+
+该开发板常用 **板载资源** 如下:
+
+- MCU:APM32F407ZGT6,主频 168MHz,1MKB FLASH ,192+4KB RAM
+- 外部 RAM:无
+- 外部 FLASH:W25Q16(SPI, 16M bit)
+- 常用外设
+  - LED:3个,(绿色,PC0/PC2/PC3)
+  - 按键:4个,K1(PB0),K2(PB1),K3(PF12),K4(PA5)
+- 常用接口:RS232转串口、以太网接口、LCD接口、USB Host、USB Device
+- 调试接口:标准 JTAG/SWD
+
+## 外设支持
+
+本 BSP 目前对外设的支持情况如下:
+
+| **板载外设** | **支持情况** | **备注**                             |
+| :----------- | :----------: | :------------------------------------ |
+| RS232转串口  |     支持     | 使用 UART1       |
+| SPI Flash | 支持 | W25Q16 |
+| 以太网 | 支持 | PHY: LAN8720, RMII 接口 |
+| **片上外设** | **支持情况** | **备注**                             |
+| 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)
+
+**注意**:步骤4选择芯片型号时,要根据自己的开发板所用的芯片型号进行选择。比如本开发板,则选择对应的 **APM32F407ZGT6** 。
+
+##### 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)
+
+-[luobeihai](https://github.com/luobeihai)

+ 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 in ['iccarm']:
+    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')

+ 35 - 0
project_0/applications/main.c

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-01-10     luobeihai    first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <board.h>
+
+/* defined the LED1 pin: PC0 */
+#define LED1_PIN    GET_PIN(C, 0)
+
+int main(void)
+{
+    uint32_t sysclock = 0;
+    /* set LED1 pin mode to output */
+    rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
+
+    /* Print system clock */
+    sysclock = RCM_ReadSYSCLKFreq();
+    rt_kprintf("System Clock: %d\n", sysclock);
+
+    while (1)
+    {
+        rt_pin_write(LED1_PIN, PIN_HIGH);
+        rt_thread_mdelay(500);
+        rt_pin_write(LED1_PIN, PIN_LOW);
+        rt_thread_mdelay(500);
+    }
+}

+ 256 - 0
project_0/board/Kconfig

@@ -0,0 +1,256 @@
+menu "Hardware Drivers Config"
+
+config SOC_APM32F407ZG
+    bool
+    select SOC_SERIES_APM32F4
+    select RT_USING_COMPONENTS_INIT
+    select RT_USING_USER_MAIN
+    default y
+
+menu "Onboard Peripheral Drivers"
+
+    config BSP_USING_USB_TO_USART
+        bool "Enable USB TO USART (uart1)"
+        select BSP_USING_UART
+        select BSP_USING_UART1
+        default y
+
+    config BSP_USING_SPI_FLASH
+        bool "Enable SPI FLASH (W25Q16 spi1)"
+        select BSP_USING_SPI
+        select BSP_USING_SPI1
+        select RT_USING_SFUD
+        select RT_SFUD_USING_SFDP
+        default n
+
+    config BSP_USING_ETH
+        bool "Enable Ethernet"
+        default n
+        select RT_USING_LWIP
+        select RT_USING_POSIX_FS
+        select RT_USING_POSIX_SOCKET
+
+    config PHY_USING_LAN8720A
+        bool
+        depends on BSP_USING_ETH
+        default y
+
+endmenu
+
+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_I2C
+        bool "Enable I2C BUS (software simulation)"
+        default n
+        select RT_USING_I2C
+        select RT_USING_I2C_BITOPS
+        select RT_USING_PIN
+        if BSP_USING_I2C
+            config BSP_USING_I2C1
+                bool "Enable I2C1 BUS"
+                if BSP_USING_I2C1
+                    comment "Notice: PB6 --> 22; PB7 --> 23"
+                    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
+            config BSP_USING_I2C2
+                bool "Enable I2C2 BUS"
+                if BSP_USING_I2C2
+                    comment "Notice: PA0 --> 0; PA1 --> 1"
+                    config BSP_I2C2_SCL_PIN
+                        int "i2c2 scl pin number"
+                        range 0 63
+                        default 0
+                    config BSP_I2C2_SDA_PIN
+                        int "I2C2 sda pin number"
+                        range 0 63
+                        default 1
+                endif
+        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
+
+menu "Board extended module Drivers"
+
+endmenu
+
+endmenu

+ 35 - 0
project_0/board/SConscript

@@ -0,0 +1,35 @@
+import os
+import rtconfig
+from building import *
+
+Import('SDK_LIB')
+
+cwd = GetCurrentDir()
+
+# add general drivers
+src = Split('''
+board.c
+''')
+
+if GetDepend(['BSP_USING_SPI_FLASH']):
+    src += Glob('ports/spi_flash_init.c')
+
+path =  [cwd]
+path += [cwd + '/ports']
+
+startup_path_prefix = SDK_LIB
+
+if rtconfig.PLATFORM in ['armcc', 'armclang']:
+    src += [startup_path_prefix + '/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/arm/startup_apm32f40x.s']
+
+if rtconfig.PLATFORM in ['iccarm']:
+    src += [startup_path_prefix + '/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/iar/startup_apm32f40x.s']
+
+if rtconfig.PLATFORM in ['gcc']:
+    src += [startup_path_prefix + '/APM32F4xx_Library/Device/Geehy/APM32F4xx/Source/gcc/startup_apm32f40x.s']
+
+# APM32F40X || APM32F41X
+# You can select chips from the list above
+CPPDEFINES = ['APM32F40X']
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
+Return('group')

+ 204 - 0
project_0/board/board.c

@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-01-10     luobeihai    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_AF;
+    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_AF;
+    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
+}
+
+void apm32_msp_spi_init(void *Instance)
+{
+#ifdef BSP_USING_SPI
+    GPIO_Config_T gpioConfig;
+    SPI_T *spi_x = (SPI_T *)Instance;
+
+    if(spi_x == SPI1)
+    {
+        /* Enable related Clock */
+        RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
+        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SPI1);
+        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
+
+        /* Config SPI1 PinAF */
+        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_3, GPIO_AF_SPI1);
+        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_4, GPIO_AF_SPI1);
+        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_5, GPIO_AF_SPI1);
+
+        /* Config SPI GPIO, SCK=PB3, MISO=PB4, MOSI=PB5 */
+        GPIO_ConfigStructInit(&gpioConfig);
+        gpioConfig.pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
+        gpioConfig.speed = GPIO_SPEED_100MHz;
+        gpioConfig.mode = GPIO_MODE_AF;
+        gpioConfig.otype = GPIO_OTYPE_PP;
+        gpioConfig.pupd = GPIO_PUPD_NOPULL;
+        GPIO_Config(GPIOB, &gpioConfig);
+    }
+#endif
+}
+
+void apm32_msp_timer_init(void *Instance)
+{
+#ifdef BSP_USING_PWM
+    GPIO_Config_T gpio_config;
+    TMR_T *tmr_x = (TMR_T *)Instance;
+
+    if (tmr_x == TMR3)
+    {
+        RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOC);
+        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
+
+        /* TMR3 channel 1 gpio init */
+        GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_6, GPIO_AF_TMR3);
+        gpio_config.pin = GPIO_PIN_6;
+        gpio_config.mode = GPIO_MODE_AF;
+        gpio_config.otype = GPIO_OTYPE_PP;
+        gpio_config.speed = GPIO_SPEED_50MHz;
+        GPIO_Config(GPIOC, &gpio_config);
+
+        /* TMR3 channel 2 gpio init */
+        GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_7, GPIO_AF_TMR3);
+        gpio_config.pin = GPIO_PIN_7;
+        GPIO_Config(GPIOC, &gpio_config);
+
+        /* TMR3 channel 3 gpio init */
+        GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_8, GPIO_AF_TMR3);
+        gpio_config.pin = GPIO_PIN_8;
+        GPIO_Config(GPIOC, &gpio_config);
+
+        /* TMR3 channel 4 gpio init */
+        GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_9, GPIO_AF_TMR3);
+        gpio_config.pin = GPIO_PIN_9;
+        GPIO_Config(GPIOC, &gpio_config);
+    }
+#endif
+}
+
+/*
+ * phy reset
+ */
+void phy_reset(void)
+{
+#ifdef BSP_USING_ETH
+    /* PHY RESET PIN: PD11 */
+    GPIO_Config_T GPIO_ConfigStruct;
+
+    GPIO_ConfigStruct.mode  = GPIO_MODE_OUT;
+    GPIO_ConfigStruct.speed = GPIO_SPEED_2MHz;
+    GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
+    GPIO_ConfigStruct.pupd  = GPIO_PUPD_NOPULL;
+
+    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOD);
+
+    GPIO_ConfigStruct.pin = GPIO_PIN_11;
+    GPIO_Config(GPIOD, &GPIO_ConfigStruct);
+
+    GPIO_ResetBit(GPIOD, GPIO_PIN_11);
+    rt_thread_delay(2);
+    GPIO_SetBit(GPIOD, GPIO_PIN_11);
+    rt_thread_delay(2);
+#endif
+}
+
+/*
+ * GPIO Configuration for ETH
+ */
+void ETH_GPIO_Configuration(void)
+{
+#ifdef BSP_USING_ETH
+    GPIO_Config_T GPIO_ConfigStruct;
+
+    /* Enable SYSCFG clock */
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
+
+    /* Enable GPIOs clocks */
+    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA | RCM_AHB1_PERIPH_GPIOC | RCM_AHB1_PERIPH_GPIOG);
+
+    /* MII/RMII Media interface selection */
+    SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_RMII);
+
+    /*********************** Ethernet pins configuration ***************************/
+    /*
+        ETH_MDIO -------------------------> PA2
+        ETH_MDC --------------------------> PC1
+        ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
+        ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7
+        ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4
+        ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5
+        ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11
+        ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13
+        ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14
+    */
+    /* Configure PC1, PC4 and PC5 */
+    GPIO_ConfigStruct.pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
+    GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
+    GPIO_ConfigStruct.mode  = GPIO_MODE_AF;
+    GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
+    GPIO_ConfigStruct.pupd  = GPIO_PUPD_NOPULL;
+
+    GPIO_Config(GPIOC, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
+    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_4, GPIO_AF_ETH);
+    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_5, GPIO_AF_ETH);
+
+    /* Configure PG11, PG13 and PG14 */
+    GPIO_ConfigStruct.pin =  GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
+    GPIO_Config(GPIOG, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_11, GPIO_AF_ETH);
+    GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_13, GPIO_AF_ETH);
+    GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_14, GPIO_AF_ETH);
+
+    /* Configure PA1, PA2 and PA7 */
+    GPIO_ConfigStruct.pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
+    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_2, GPIO_AF_ETH);
+    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_ETH);
+#endif
+}

+ 85 - 0
project_0/board/board.h

@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2023-01-10     luobeihai      first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <rtthread.h>
+#include <apm32f4xx.h>
+
+#include "apm32f4xx_gpio.h"
+#include "apm32f4xx_syscfg.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
+#if defined(BSP_USING_ETH)
+    #include "apm32f4xx_eth.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};

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

@@ -0,0 +1,147 @@
+/*
+ * linker script for APM32F40x 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 = .;
+        _start_address_init_data = .;
+    } > 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 = . ;
+        _start_address_data = .;
+
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d*)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _edata = . ;
+        _end_address_data = .;
+    } >DATA
+
+    .stack :
+    {
+        . = . + _system_stack_size;
+        . = ALIGN(4);
+        _estack = .;
+        _end_stack = .;
+    } >DATA
+
+    __bss_start = .;
+    _start_address_bss = .;
+    .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_address_bss = .;
+
+    _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)
+  }
+}
+
+

+ 31 - 0
project_0/board/ports/spi_flash_init.c

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-01-10     luobeihai    first version
+ */
+
+#include <rtthread.h>
+#include "spi_flash.h"
+#include "spi_flash_sfud.h"
+#include "drv_spi.h"
+
+#if defined(BSP_USING_SPI_FLASH)
+static int rt_hw_spi_flash_init(void)
+{
+    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOF);
+    rt_hw_spi_device_attach("spi1", "spi10", GPIOF, GPIO_PIN_5);
+
+    if (RT_NULL == rt_sfud_flash_probe("W25Q16", "spi10"))
+    {
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
+#endif
+

BIN
project_0/figures/APM32F407ZG-EVAL.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


+ 1424 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/inc/apm32f4xx_eth.h

@@ -0,0 +1,1424 @@
+/*!
+ * @file        apm32f4xx_eth.c
+ *
+ * @brief       This file provides all the ETH 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_ETH_H
+#define __APM32F4xx_ETH_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_ETHDriver
+  @{
+*/
+
+/** @addtogroup ETH_Driver
+  @{
+*/
+
+/** @defgroup ETH_Enumerations
+  @{
+*/
+
+/**
+ * @brief    ETH AutoNegotiation
+ */
+typedef enum
+{
+    ETH_AUTONEGOTIATION_DISABLE,    /*!< Disable negotiation */
+    ETH_AUTONEGOTIATION_ENABLE      /*!< Enable negotiation */
+} ETH_AUTONEGOTIATION_T;
+
+/**
+ * @brief    ETH Watchdog
+ */
+typedef enum
+{
+    ETH_WATCHDOG_ENABLE,    /*!< Enable watch dog */
+    ETH_WATCHDOG_DISABLE    /*!< Disable watch dog */
+} ETH_WATCHDOG_T;
+
+/**
+ * @brief    ETH Jabber
+ */
+typedef enum
+{
+    ETH_JABBER_ENABLE,  /*!< Enable jabber */
+    ETH_JABBER_DISABLE  /*!< Disable jabber */
+} ETH_JABBER_T;
+
+/**
+ * @brief    ETH Inter Frame Gap
+ */
+typedef enum
+{
+    ETH_INTERFRAMEGAP_96BIT = 0x00, /*!< Inter-Frame gap = 96-bit */
+    ETH_INTERFRAMEGAP_88BIT = 0x01, /*!< Inter-Frame gap = 88-bit */
+    ETH_INTERFRAMEGAP_80BIT = 0x02, /*!< Inter-Frame gap = 80-bit */
+    ETH_INTERFRAMEGAP_72BIT = 0x03, /*!< Inter-Frame gap = 72-bit */
+    ETH_INTERFRAMEGAP_64BIT = 0x04, /*!< Inter-Frame gap = 64-bit */
+    ETH_INTERFRAMEGAP_56BIT = 0x05, /*!< Inter-Frame gap = 56-bit */
+    ETH_INTERFRAMEGAP_48BIT = 0x06, /*!< Inter-Frame gap = 48-bit */
+    ETH_INTERFRAMEGAP_40BIT = 0x07  /*!< Inter-Frame gap = 40-bit */
+} ETH_INTERFRAMEGAP_T;
+
+/**
+ * @brief    ETH Carrier Sense
+ */
+typedef enum
+{
+    ETH_CARRIERSENCE_ENABLE,    /*!< Disable carrier sense during transmission */
+    ETH_CARRIERSENCE_DISABLE    /*!< Ignore MII CRS signal */
+} ETH_CARRIERSENCE_T;
+
+/**
+ * @brief    ETH Speed
+ */
+typedef enum
+{
+    ETH_SPEED_10M,  /*!< 10M speed */
+    ETH_SPEED_100M  /*!< 100M speed */
+} ETH_SPEED_T;
+
+/**
+ * @brief    ETH Receive Own
+ */
+typedef enum
+{
+    ETH_RECEIVEOWN_ENABLE,  /*!< Enable receive own */
+    ETH_RECEIVEOWN_DISABLE  /*!< Disable receive own */
+} ETH_RECEIVEOWN_T;
+
+/**
+ * @brief    ETH Loop Back Mode
+ */
+typedef enum
+{
+    ETH_LOOPBACKMODE_DISABLE,   /*!< Disable loopback mode */
+    ETH_LOOPBACKMODE_ENABLE     /*!< Enable loopback mode */
+} ETH_LOOPBACKMODE_T;
+
+/**
+ * @brief    ETH Duplex Mode
+ */
+typedef enum
+{
+    ETH_MODE_HALFDUPLEX,    /*!< Half-Duplex */
+    ETH_MODE_FULLDUPLEX     /*!< Full-Duplex */
+} ETH_MODE_T;
+
+/**
+ * @brief    ETH Checksum Offload
+ */
+typedef enum
+{
+    ETH_CHECKSUMOFFLAOD_DISABLE,    /*!< Disable IPv4 checksum offload */
+    ETH_CHECKSUMOFFLAOD_ENABLE      /*!< Enable Ipv4 checksum offload */
+} ETH_CHECKSUMOFFLAOD_T;
+
+/**
+ * @brief    ETH Retry Transmission
+ */
+typedef enum
+{
+    ETH_RETRYTRANSMISSION_ENABLE,   /*!< Enable retry */
+    ETH_RETRYTRANSMISSION_DISABLE   /*!< Disable retry */
+} ETH_RETRYTRANSMISSION_T;
+
+/**
+ * @brief    ETH Automatic Pad CRC Strip
+ */
+typedef enum
+{
+    ETH_AUTOMATICPADCRCSTRIP_DISABLE,   /*!< Disable automatic pad or CRC stripping */
+    ETH_AUTOMATICPADCRCSTRIP_ENABLE     /*!< Enable automatic pad or CRC stripping */
+} ETH_AUTOMATICPADCRCSTRIP_T;
+
+/**
+ * @brief    ETH Back Off Limit
+ */
+typedef enum
+{
+    ETH_BACKOFFLIMIT_10,    /*!< Set back off limit to 10 */
+    ETH_BACKOFFLIMIT_8,     /*!< Set back off limit to 18 */
+    ETH_BACKOFFLIMIT_4,     /*!< Set back off limit to 4 */
+    ETH_BACKOFFLIMIT_1      /*!< Set back off limit to 1 */
+} ETH_BACKOFFLIMIT_T;
+
+/**
+ * @brief    ETH Deferral Check
+ */
+typedef enum
+{
+    ETH_DEFFERRALCHECK_DISABLE, /*!< Disable deferral check */
+    ETH_DEFFERRALCHECK_ENABLE   /*!< Enable deferral check */
+} ETH_DEFFERRALCHECK_T;
+
+/**
+ * @brief    ETH Receive All
+ */
+typedef enum
+{
+    ETH_RECEIVEAll_DISABLE, /*!< Disable receive all */
+    ETH_RECEIVEALL_ENABLE   /*!< Enable receive all */
+} ETH_RECEIVEAll_T;
+
+/**
+ * @brief    ETH Source Addr Filter
+ */
+typedef enum
+{
+    ETH_SOURCEADDRFILTER_DISABLE,                       /*!< Disable source address filter */
+    ETH_SOURCEADDRFILTER_NORMAL_ENABLE = BIT9,          /*!< Enable normal source address filter */
+    ETH_SOURCEADDRFILTER_INVERSE_ENABLE = BIT8 | BIT9,  /*!< Enable inverse source address filter */
+} ETH_SOURCEADDRFILTER_T;
+
+/**
+ * @brief    ETH Pass Control Frames
+ */
+typedef enum
+{
+    ETH_PASSCONTROLFRAMES_BLOCKALL = 1,             /*!< Even if all control frames except pause frames fail the
+                                                        address filter, MAC forwards them to the application */
+    ETH_PASSCONTROLFRAMES_FORWARDALL,               /*!< MAC forwards control frames to the application even if
+                                                        they do not pass the address filter */
+    ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER   /*!< MAC forwards control frames that pass through the address filter */
+} ETH_PASSCONTROLFRAMES_T;
+
+/**
+ * @brief    ETH Broadcast Frames Reception
+ */
+typedef enum
+{
+    ETH_BROADCASTFRAMESRECEPTION_ENABLE,    /*!< Enable broadcast frames */
+    ETH_BROADCASTFRAMESRECEPTION_DISABLE    /*!< Disable broadcast frames */
+} ETH_BROADCASTFRAMESRECEPTION_T;
+
+/**
+ * @brief    ETH Destination Addr Filter
+ */
+typedef enum
+{
+    ETH_DESTINATIONADDRFILTER_NORMAL,   /*!< Normal destination address filter */
+    ETH_DESTINATIONADDRFILTER_INVERSE   /*!< Inverse destination address filter */
+} ETH_DESTINATIONADDRFILTER_T;
+
+/**
+ * @brief    ETH Destination Addr Filter
+ */
+typedef enum
+{
+    ETH_PROMISCUOUS_MODE_DISABLE,   /*!< Disable promiscuous mode */
+    ETH_PROMISCUOUS_MODE_ENABLE     /*!< Enable promiscuous mode */
+} ETH_PROMISCUOUS_MODE_T;
+
+/**
+ * @brief    ETH Multicast Frames Filter
+ */
+typedef enum
+{
+    ETH_MULTICASTFRAMESFILTER_PERFECT,                      /*!< Multicast perfect filter */
+    ETH_MULTICASTFRAMESFILTER_NONE = BIT4,                  /*!< Multicast pass all multicast */
+    ETH_MULTICASTFRAMESFILTER_HASHTABLE = BIT2,             /*!< Multicast hash multicast */
+    ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE = BIT2|BIT10 /*!< Multicast perfect hash table */
+} ETH_MULTICASTFRAMESFILTER_T;
+
+/**
+ * @brief    ETH Unicast Frames Filter
+ */
+typedef enum
+{
+    ETH_UNICASTFRAMESFILTER_PERFECT,                        /*!< Unicast perfect filter */
+    ETH_UNICASTFRAMESFILTER_HASHTABLE = BIT1,               /*!< Unicast hash table */
+    ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE = BIT1|BIT10   /*!< Unicast perfect hash table */
+} ETH_UNICASTFRAMESFILTER_T;
+
+/**
+ * @brief    ETH Zero Quanta Pause
+ */
+typedef enum
+{
+    ETH_ZEROQUANTAPAUSE_ENABLE,     /*!< Enable zero-quanta pause */
+    ETH_ZEROQUANTAPAUSE_DISABLE     /*!< Disable zero-quanta pause */
+} ETH_ZEROQUANTAPAUSE_T;
+
+/**
+ * @brief    ETH Pause Low Threshold
+ */
+typedef enum
+{
+    ETH_PAUSELOWTHRESHOLD_MINUS4,   /*!< Minus 4 slot-time */
+    ETH_PAUSELOWTHRESHOLD_MINUS28,  /*!< Minus 28 slot-time */
+    ETH_PAUSELOWTHRESHOLD_MINUS144, /*!< Minus 144 slot-time */
+    ETH_PAUSELOWTHRESHOLD_MINUS256  /*!< Minus 256 slot-time */
+} ETH_PAUSELOWTHRESHOLD_T;
+
+/**
+ * @brief    ETH Unicast Pause Frame Detect
+ */
+typedef enum
+{
+    ETH_UNICASTPAUSEFRAMEDETECT_DISABLE,    /*!< Disable unicast pause frame detect */
+    ETH_UNICASTPAUSEFRAMEDETECT_ENABLE      /*!< Enable unicast pause frame detect */
+} ETH_UNICASTPAUSEFRAMEDETECT_T;
+
+/**
+ * @brief    ETH Receive Flow Control
+ */
+typedef enum
+{
+    ETH_RECEIVEFLOWCONTROL_DISABLE, /*!< Disable receive flow control */
+    ETH_RECEIVEFLOWCONTROL_ENABLE   /*!< Enable receive flow control */
+} ETH_RECEIVEFLOWCONTROL_T;
+
+/**
+ * @brief    ETH Transmit Flow Control
+ */
+typedef enum
+{
+    ETH_TRANSMITFLOWCONTROL_DISABLE,    /*!< Disable transmit flow control */
+    ETH_TRANSMITFLOWCONTROL_ENABLE      /*!< Enable transmit flow control */
+} ETH_TRANSMITFLOWCONTROL_T;
+
+/**
+ * @brief    ETH VLAN Tag Comparison
+ */
+typedef enum
+{
+    ETH_VLANTAGCOMPARISON_16BIT,    /*!< 16-bit VLAN tag comparison */
+    ETH_VLANTAGCOMPARISON_12BIT     /*!< 12-bit VLAN tag comparison */
+} ETH_VLANTAGCOMPARISON_T;
+
+/**
+ * @brief    ETH MAC Flags
+ */
+typedef enum
+{
+    ETH_MAC_FLAG_TST  = 0x00000200, /*!< Time stamp trigger flag */
+    ETH_MAC_FLAG_MMCT = 0x00000040, /*!< MMC transmit flag */
+    ETH_MAC_FLAG_MMCR = 0x00000020, /*!< MMC receive flag */
+    ETH_MAC_FLAG_MMC  = 0x00000010, /*!< MMC flag */
+    ETH_MAC_FLAG_PMT  = 0x00000008  /*!< PMT flag */
+} ETH_MAC_FLAG_T;
+
+/**
+ * @brief    ETH MAC Interrupts
+ */
+typedef enum
+{
+    ETH_MAC_INT_TST  = 0x00000200,  /*!< Time stamp trigger interrupt */
+    ETH_MAC_INT_MMCT = 0x00000040,  /*!< MMC transmit interrupt */
+    ETH_MAC_INT_MMCR = 0x00000020,  /*!< MMC receive interrupt */
+    ETH_MAC_INT_MMC  = 0x00000010,  /*!< MMC interrupt */
+    ETH_MAC_INT_PMT  = 0x00000008   /*!< PMT interrupt */
+} ETH_MAC_INT_T;
+
+/**
+ * @brief    ETH MAC Interrupts
+ */
+typedef enum
+{
+    ETH_MAC_ADDRESS0 = 0x00000000,  /*!< MAC Address0 */
+    ETH_MAC_ADDRESS1 = 0x00000008,  /*!< MAC Address1 */
+    ETH_MAC_ADDRESS2 = 0x00000010,  /*!< MAC Address2 */
+    ETH_MAC_ADDRESS3 = 0x00000018   /*!< MAC Address3 */
+} ETH_MAC_ADDRESS_T;
+
+/**
+ * @brief    ETH MAC addresses filter SA/DA
+ */
+typedef enum
+{
+    ETH_MAC_ADDRESSFILTER_SA,           /*!< MAC Address is used to compare with the
+                                            SA fields of the received frame */
+    ETH_MAC_ADDRESSFILTER_DA = BIT30    /*!< MAC Address is used to compare with the
+                                            DA fields of the received frame */
+} ETH_MAC_ADDRESSFILTER_T;
+
+/**
+ * @brief    ETH MAC addresses filter Mask bytes
+ */
+typedef enum
+{
+    ETH_MAC_ADDRESSMASK_BYTE6 = 0x20000000,  /*!< Mask MAC Address high reg bits [15:8] */
+    ETH_MAC_ADDRESSMASK_BYTE5 = 0x10000000,  /*!< Mask MAC Address high reg bits [7:0] */
+    ETH_MAC_ADDRESSMASK_BYTE4 = 0x08000000,  /*!< Mask MAC Address low reg bits [31:24] */
+    ETH_MAC_ADDRESSMASK_BYTE3 = 0x04000000,  /*!< Mask MAC Address low reg bits [23:16] */
+    ETH_MAC_ADDRESSMASK_BYTE2 = 0x02000000,  /*!< Mask MAC Address low reg bits [15:8] */
+    ETH_MAC_ADDRESSMASK_BYTE1 = 0x01000000   /*!< Mask MAC Address low reg bits [70] */
+} ETH_MAC_ADDRESSMASK_T;
+
+/**
+ * @brief    DMA Tx descriptor flags
+ */
+typedef enum
+{
+    ETH_DMATXDESC_OWN      = (int)0x80000000,   /*!< Descriptor is owned by DMA engine */
+    ETH_DMATXDESC_INTC     = 0x40000000,        /*!< Interrupt on completion */
+    ETH_DMATXDESC_LS       = 0x20000000,        /*!< Last Segment */
+    ETH_DMATXDESC_FS       = 0x10000000,        /*!< First Segment */
+    ETH_DMATXDESC_DISC     = 0x08000000,        /*!< Disable CRC */
+    ETH_DMATXDESC_DISP     = 0x04000000,        /*!< Disable Pad */
+    ETH_DMATXDESC_TXTSEN   = 0x02000000,        /*!< Transmit Time Stamp Enable */
+    ETH_DMATXDESC_TXENDR   = 0x00200000,        /*!< Transmit End of Ring */
+    ETH_DMATXDESC_TXCH     = 0x00100000,        /*!< Second Address Chained */
+    ETH_DMATXDESC_TXTSS    = 0x00020000,        /*!< Tx Time Stamp Status */
+    ETH_DMATXDESC_IHERR    = 0x00010000,        /*!< IP Header Error */
+    ETH_DMATXDESC_ERRS     = 0x00008000,        /*!< Error summary */
+    ETH_DMATXDESC_JTO      = 0x00004000,        /*!< Jabber Timeout */
+    ETH_DMATXDESC_FF       = 0x00002000,        /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
+    ETH_DMATXDESC_IPERR    = 0x00001000,        /*!< Payload Checksum Error */
+    ETH_DMATXDESC_LSC      = 0x00000800,        /*!< Loss of Carrier: carrier lost during transmission */
+    ETH_DMATXDESC_NC       = 0x00000400,        /*!< No Carrier: no carrier signal from the transceiver */
+    ETH_DMATXDESC_LC       = 0x00000200,        /*!< Late Collision: transmission aborted due to collision */
+    ETH_DMATXDESC_EC       = 0x00000100,        /*!< Excessive Collision: transmission aborted after 16 collisions */
+    ETH_DMATXDESC_VLANF    = 0x00000080,        /*!< VLAN Frame */
+    ETH_DMATXDESC_CCNT     = 0x00000078,        /*!< Collision Count */
+    ETH_DMATXDESC_EDEF     = 0x00000004,        /*!< Excessive Deferral */
+    ETH_DMATXDESC_UFERR    = 0x00000002,        /*!< Underflow Error: late data arrival from the memory */
+    ETH_DMATXDESC_DEF      = 0x00000001         /*!< Deferred Bit */
+} ETH_DMATXDESC_FLAG_T;
+
+/**
+ * @brief    ETH DMA Tx descriptor segment
+ */
+typedef enum
+{
+    ETH_DMATXDESC_LASTSEGMENTS = BIT30, /*!< Actual Tx desc contain last segment */
+    ETH_DMATXDESC_FIRSTSEGMENT = BIT29  /*!< Actual Tx desc contain first segment */
+} ETH_DMATXDESC_SEGMENTS_T;
+
+/**
+ * @brief    ETH DMA Tx descriptor Checksum Insertion Control
+ */
+typedef enum
+{
+    ETH_DMATXDESC_CHECKSUMBYPASS,                       /*!< Checksum bypass */
+    ETH_DMATXDESC_CHECKSUMIPV4HEADER = BIT22,           /*!< IPv4 header checksum */
+    ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT = BIT23,    /*!< TCP/UDP/ICMP checksum. Pseudo header
+                                                            checksum is assumed to be present */
+    ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL = BIT22|BIT23  /*!< TCP/UDP/ICMP checksum fully in hardware
+                                                            including pseudo header */
+} ETH_DMATXDESC_CHECKSUMB_T;
+
+/**
+ * @brief    DMA Rx descriptor status
+ */
+typedef enum
+{
+    ETH_DMARXDESC_OWN      =  (int)0x80000000U, /*!< Descriptor is owned by DMA engine */
+    ETH_DMARXDESC_ADDRF    =  0x40000000,       /*!< DA Filter Fail for the rx frame */
+    ETH_DMARXDESC_ERRS     =  0x00008000,       /*!< Error summary */
+    ETH_DMARXDESC_DESERR   =  0x00004000,       /*!< Descriptor error: no more descriptors for receive frame */
+    ETH_DMARXDESC_SADDRF   =  0x00002000,       /*!< SA Filter Fail for the received frame */
+    ETH_DMARXDESC_LERR     =  0x00001000,       /*!< Frame size not matching with length field */
+    ETH_DMARXDESC_OFERR    =  0x00000800,       /*!< Overflow Error: Frame was damaged due to buffer overflow */
+    ETH_DMARXDESC_VLANF    =  0x00000400,       /*!< VLAN Tag: received frame is a VLAN frame */
+    ETH_DMARXDESC_FDES     =  0x00000200,       /*!< First descriptor of the frame */
+    ETH_DMARXDESC_LDES     =  0x00000100,       /*!< Last descriptor of the frame */
+    ETH_DMARXDESC_IPV4HCE  =  0x00000080,       /*!< IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error */
+    ETH_DMARXDESC_LC       =  0x00000040,       /*!< Late collision occurred during reception */
+    ETH_DMARXDESC_FT       =  0x00000020,       /*!< Frame type - Ethernet, otherwise 802.3 */
+    ETH_DMARXDESC_RXWDTTO  =  0x00000010,       /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
+    ETH_DMARXDESC_RERR     =  0x00000008,       /*!< Receive error: error reported by MII interface */
+    ETH_DMARXDESC_DERR     =  0x00000004,       /*!< Dribble bit error: frame contains non int multiple of 8 bits */
+    ETH_DMARXDESC_CERR     =  0x00000002,       /*!< CRC error */
+    ETH_DMARXDESC_MAMPCE   =  0x00000001        /*!< Rx MAC Address/Payload Checksum Error:
+                                                    Rx MAC address matched/ Rx Payload Checksum Error */
+} ETH_DMARXDESC_FLAG_T;
+
+/**
+ * @brief    DMA Rx descriptor extended flags
+ */
+typedef enum
+{
+    ETH_DMAPTPRXDESC_PTPV   =  0x00002000,  /*!< PTP version */
+    ETH_DMAPTPRXDESC_PTPFT  =  0x00001000,  /*!< PTP frame type */
+    ETH_DMAPTPRXDESC_PTPMT  =  0x00000F00,  /*!< PTP message type */
+    ETH_DMAPTPRXDESC_IPV6P  =  0x00000080,  /*!< IPv6 packet received */
+    ETH_DMAPTPRXDESC_IPV4P  =  0x00000040,  /*!< IPv4 packet received */
+    ETH_DMAPTPRXDESC_IPCBP  =  0x00000020,  /*!< IP checksum bypassed */
+    ETH_DMAPTPRXDESC_IPPERR =  0x00000010,  /*!< IP payload error */
+    ETH_DMAPTPRXDESC_IPHERR =  0x00000008,  /*!< IP header error */
+    ETH_DMAPTPRXDESC_IPPT   =  0x00000007   /*!< IP payload type */
+} ETH_DMAPTPRXDESC_FLAG_T;
+
+/**
+ * @brief    ETH DMA Rx descriptor buffers
+ */
+typedef enum
+{
+    ETH_DMARXDESC_BUFFER1,  /*!< DMA Rx Desc Buffer1 */
+    ETH_DMARXDESC_BUFFER2   /*!< DMA Rx Desc Buffer2 */
+} ETH_DMARXDESC_BUFFER_T;
+
+/**
+ * @brief    ETH Drop TCP IP Checksum Error Frame
+ */
+typedef enum
+{
+    ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE,     /*!< Enable dropping of TCP/IP checksum error frame */
+    ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE     /*!< Disable dropping of TCP/IP checksum error frame */
+} ETH_DROPTCPIPCHECKSUMERRORFRAME_T;
+
+/**
+ * @brief    ETH Receive Store Forward
+ */
+typedef enum
+{
+    ETH_RECEIVESTOREFORWARD_DISABLE,    /*!< Disable receive store and forward */
+    ETH_RECEIVESTOREFORWARD_ENABLE      /*!< Enable receive store and forward */
+} ETH_RECEIVESTOREFORWARD_T;
+
+/**
+ * @brief    ETH Flush Received Frame
+ */
+typedef enum
+{
+    ETH_FLUSHRECEIVEDFRAME_ENABLE,  /*!< Enable flushing of received frames */
+    ETH_FLUSHRECEIVEDFRAME_DISABLE  /*!< Disable flushing of received frames */
+} ETH_FLUSHRECEIVEDFRAME_T;
+
+/**
+ * @brief    ETH Transmit Store Forward
+ */
+typedef enum
+{
+    ETH_TRANSMITSTOREFORWARD_DISABLE,   /*!< Disable transmit store and forward */
+    ETH_TRANSMITSTOREFORWARD_ENABLE     /*!< Enable transmit store and forward */
+} ETH_TRANSMITSTOREFORWARD_T;
+
+/**
+ * @brief    ETH Transmit Threshold Control
+ */
+typedef enum
+{
+    ETH_TRANSMITTHRESHOLDCONTROL_64BYTES,   /*!< Select 64 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_128BYTES,  /*!< Select 128 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_192BYTES,  /*!< Select 192 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_256BYTES,  /*!< Select 256 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_40BYTES,   /*!< Select 40 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_32BYTES,   /*!< Select 32 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_24BYTES,   /*!< Select 24 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_16BYTES    /*!< Select 16 bytes transmit threshild level */
+} ETH_TRANSMITTHRESHOLDCONTROL_T;
+
+/**
+ * @brief    ETH Forward Error Frames
+ */
+typedef enum
+{
+    ETH_FORWARDERRORFRAMES_DISABLE, /*!< Disable forward error frames */
+    ETH_FORWARDERRORFRAMES_ENABLE   /*!< Enable forward error frames */
+} ETH_FORWARDERRORFRAMES_T;
+
+/**
+ * @brief    ETH Forward Undersized Good Frames
+ */
+typedef enum
+{
+    ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE,    /*!< Disable forward undersized good frames */
+    ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE      /*!< Enable forward undersized good frames */
+} ETH_FORWARDUNDERSIZEDGOODFRAMES_T;
+
+/**
+ * @brief    ETH Receive Threshold Control
+ */
+typedef enum
+{
+    ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES,   /*!< Select 64 bytes receive threshold level */
+    ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES,   /*!< Select 32 bytes receive threshold level */
+    ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES,   /*!< Select 96 bytes receive threshold level */
+    ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES   /*!< Select 128 bytes receive threshold level */
+} ETH_RECEIVEDTHRESHOLDCONTROL_T;
+
+/**
+ * @brief    ETH Second Frame Operate
+ */
+typedef enum
+{
+    ETH_SECONDFRAMEOPERARTE_DISABLE,    /*!< Disable second frame operate */
+    ETH_SECONDFRAMEOPERARTE_ENABLE      /*!< Enable second frame operate */
+} ETH_SECONDFRAMEOPERARTE_T;
+
+/**
+ * @brief    ETH Address Aligned Beats
+ */
+typedef enum
+{
+    ETH_ADDRESSALIGNEDBEATS_DISABLE,    /*!< Disable address aligned beats */
+    ETH_ADDRESSALIGNEDBEATS_ENABLE      /*!< Enable address aligned beats */
+} ETH_ADDRESSALIGNEDBEATS_T;
+
+/**
+ * @brief    ETH Fixed Burst
+ */
+typedef enum
+{
+    ETH_FIXEDBURST_DISABLE, /*!< Disable fixed burst */
+    ETH_FIXEDBURST_ENABLE   /*!< Enable fixed burst */
+} ETH_FIXEDBURST_T;
+
+/**
+ * @brief    ETH Rx DMA Burst Length
+ */
+typedef enum
+{
+    ETH_RXDMABURSTLENGTH_1BEAT        = BIT17,          /*!< Maxnum number of Rx DMA transaction = 1 beat */
+    ETH_RXDMABURSTLENGTH_2BEAT        = BIT18,          /*!< Maxnum number of Rx DMA transaction = 2 beat */
+    ETH_RXDMABURSTLENGTH_4BEAT        = BIT19,          /*!< Maxnum number of Rx DMA transaction = 4 beat */
+    ETH_RXDMABURSTLENGTH_8BEAT        = BIT20,          /*!< Maxnum number of Rx DMA transaction = 8 beat */
+    ETH_RXDMABURSTLENGTH_16BEAT       = BIT21,          /*!< Maxnum number of Rx DMA transaction = 16 beat */
+    ETH_RXDMABURSTLENGTH_32BEAT       = BIT22,          /*!< Maxnum number of Rx DMA transaction = 32 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_4BEAT  = BIT17|BIT24,    /*!< Maxnum number of Rx DMA transaction = 4 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_8BEAT  = BIT18|BIT24,    /*!< Maxnum number of Rx DMA transaction = 8 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_16BEAT = BIT19|BIT24,    /*!< Maxnum number of Rx DMA transaction = 16 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_32BEAT = BIT20|BIT24,    /*!< Maxnum number of Rx DMA transaction = 32 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_64BEAT = BIT21|BIT24,    /*!< Maxnum number of Rx DMA transaction = 64 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_128BEAT= BIT22|BIT24     /*!< Maxnum number of Rx DMA transaction = 128 beat */
+} ETH_RXDMABURSTLENGTH_T;
+
+/**
+ * @brief    ETH Tx DMA Burst Length
+ */
+typedef enum
+{
+    ETH_TXDMABURSTLENGTH_1BEAT        = BIT8,           /*!< Maxnum number of Tx DMA transaction = 1 beat */
+    ETH_TXDMABURSTLENGTH_2BEAT        = BIT9,           /*!< Maxnum number of Tx DMA transaction = 2 beat */
+    ETH_TXDMABURSTLENGTH_4BEAT        = BIT10,          /*!< Maxnum number of Tx DMA transaction = 4 beat */
+    ETH_TXDMABURSTLENGTH_8BEAT        = BIT11,          /*!< Maxnum number of Tx DMA transaction = 8 beat */
+    ETH_TXDMABURSTLENGTH_16BEAT       = BIT12,          /*!< Maxnum number of Tx DMA transaction = 16 beat */
+    ETH_TXDMABURSTLENGTH_32BEAT       = BIT13,          /*!< Maxnum number of Tx DMA transaction = 32 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_4BEAT  = BIT8|BIT24,     /*!< Maxnum number of Tx DMA transaction = 4 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_8BEAT  = BIT9|BIT24,     /*!< Maxnum number of Tx DMA transaction = 8 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_16BEAT = BIT10|BIT24,    /*!< Maxnum number of Tx DMA transaction = 16 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_32BEAT = BIT11|BIT24,    /*!< Maxnum number of Tx DMA transaction = 32 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_64BEAT = BIT12|BIT24,    /*!< Maxnum number of Tx DMA transaction = 64 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_128BEAT= BIT13|BIT24     /*!< Maxnum number of Tx DMA transaction = 128 beat */
+} ETH_TXDMABURSTLENGTH_T;
+
+/**
+ * @brief    ETH DMA Arbitration
+ */
+typedef enum
+{
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1,                 /*!< Priority ratio RX : TX = 1 : 1 */
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1 = BIT14,         /*!< Priority ratio RX : TX = 2 : 1 */
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1 = BIT15,         /*!< Priority ratio RX : TX = 3 : 1 */
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 = BIT14|BIT15,   /*!< Priority ratio RX : TX = 4 : 1 */
+    ETH_DMAARBITRATION_RXPRIORTX = BIT1                     /*!< Rx priority ratio higher than Tx */
+} ETH_DMAARBITRATION_T;
+
+/**
+ * @brief    ETH DMA Flags
+ */
+typedef enum
+{
+    ETH_DMA_FLAG_TST               = 0x20000000,   /*!< Time-stamp trigger interrupt (on DMA) */
+    ETH_DMA_FLAG_PMT               = 0x10000000,   /*!< PMT interrupt (on DMA) */
+    ETH_DMA_FLAG_MMC               = 0x08000000,   /*!< MMC interrupt (on DMA) */
+    ETH_DMA_FLAG_DATATRANSFERERROR = 0x00800000,   /*!< Error bits 0-Rx DMA, 1-Tx DMA */
+    ETH_DMA_FLAG_READWRITEERROR    = 0x01000000,   /*!< Error bits 0-write transfer, 1-read transfer */
+    ETH_DMA_FLAG_ACCESSERROR       = 0x02000000,   /*!< Error bits 0-data buffer, 1-desc. access */
+    ETH_DMA_FLAG_NIS               = 0x00010000,   /*!< Normal interrupt summary flag */
+    ETH_DMA_FLAG_AIS               = 0x00008000,   /*!< Abnormal interrupt summary flag */
+    ETH_DMA_FLAG_ER                = 0x00004000,   /*!< Early receive flag */
+    ETH_DMA_FLAG_FBE               = 0x00002000,   /*!< Fatal bus error flag */
+    ETH_DMA_FLAG_ET                = 0x00000400,   /*!< Early transmit flag */
+    ETH_DMA_FLAG_RWT               = 0x00000200,   /*!< Receive watchdog timeout flag */
+    ETH_DMA_FLAG_RPS               = 0x00000100,   /*!< Receive process stopped flag */
+    ETH_DMA_FLAG_RBU               = 0x00000080,   /*!< Receive buffer unavailable flag */
+    ETH_DMA_FLAG_RX                = 0x00000040,   /*!< Receive flag */
+    ETH_DMA_FLAG_TU                = 0x00000020,   /*!< Underflow flag */
+    ETH_DMA_FLAG_RO                = 0x00000010,   /*!< Overflow flag */
+    ETH_DMA_FLAG_TJT               = 0x00000008,   /*!< Transmit jabber timeout flag */
+    ETH_DMA_FLAG_TBU               = 0x00000004,   /*!< Transmit buffer unavailable flag */
+    ETH_DMA_FLAG_TPS               = 0x00000002,   /*!< Transmit process stopped flag */
+    ETH_DMA_FLAG_TX                = 0x00000001    /*!< Transmit flag */
+} ETH_DMA_FLAG_T;
+
+/**
+ * @brief    ETH DMA Interrupts
+ */
+typedef enum
+{
+    ETH_DMA_INT_TST   =   0x20000000,   /*!< Time-stamp trigger interrupt (on DMA) */
+    ETH_DMA_INT_PMT   =   0x10000000,   /*!< PMT interrupt (on DMA) */
+    ETH_DMA_INT_MMC   =   0x08000000,   /*!< MMC interrupt (on DMA) */
+    ETH_DMA_INT_NIS   =   0x00010000,   /*!< Normal interrupt summary */
+    ETH_DMA_INT_AIS   =   0x00008000,   /*!< Abnormal interrupt summary */
+    ETH_DMA_INT_ER    =   0x00004000,   /*!< Early receive interrupt */
+    ETH_DMA_INT_FBE   =   0x00002000,   /*!< Fatal bus error interrupt */
+    ETH_DMA_INT_ET    =   0x00000400,   /*!< Early transmit interrupt */
+    ETH_DMA_INT_RWT   =   0x00000200,   /*!< Receive watchdog timeout interrupt */
+    ETH_DMA_INT_RPS   =   0x00000100,   /*!< Receive process stopped interrupt */
+    ETH_DMA_INT_RBU   =   0x00000080,   /*!< Receive buffer unavailable interrupt */
+    ETH_DMA_INT_RX    =   0x00000040,   /*!< Receive interrupt */
+    ETH_DMA_INT_TU    =   0x00000020,   /*!< Underflow interrupt */
+    ETH_DMA_INT_RO    =   0x00000010,   /*!< Overflow interrupt */
+    ETH_DMA_INT_TJT   =   0x00000008,   /*!< Transmit jabber timeout interrupt */
+    ETH_DMA_INT_TBU   =   0x00000004,   /*!< Transmit buffer unavailable interrupt */
+    ETH_DMA_INT_TPS   =   0x00000002,   /*!< Transmit process stopped interrupt */
+    ETH_DMA_INT_TX    =   0x00000001    /*!< Transmit interrupt */
+} ETH_DMA_INT_T;
+
+/**
+ * @brief    ETH DMA transmit process state
+ */
+typedef enum
+{
+    ETH_DMA_TRANSMITPROCESS_STOPPED,            /*!< Stopped - Reset or Stop Tx Command issued */
+    ETH_DMA_TRANSMITPROCESS_FETCHING,           /*!< Running - fetching the Tx descriptor */
+    ETH_DMA_TRANSMITPROCESS_WAITING,            /*!< Running - waiting for status */
+    ETH_DMA_TRANSMITPROCESS_READING,            /*!< Running - reading the data from host memory */
+    ETH_DMA_TRANSMITPROCESS_SUSPENDED = 0x06,   /*!< Suspended - Tx Descriptor unavailable */
+    ETH_DMA_TRANSMITPROCESS_CLOSING = 0x07,     /*!< Running - closing Rx descriptor */
+} ETH_DMA_TRANSMITPROCESS_T;
+
+/**
+ * @brief    ETH DMA receive process state
+ */
+typedef enum
+{
+    ETH_DMA_RECEIVEPROCESS_STOPPED,             /*!< Stopped - Reset or Stop Rx Command issued */
+    ETH_DMA_RECEIVEPROCESS_FETCHING  = 0x02,    /*!< Running - fetching the Rx descriptor */
+    ETH_DMA_RECEIVEPROCESS_WAITING   = 0x06,    /*!< Running - waiting for packet */
+    ETH_DMA_RECEIVEPROCESS_SUSPENDED = 0x08,    /*!< Suspended - Rx Descriptor unavailable */
+    ETH_DMA_RECEIVEPROCESS_CLOSING   = 0x0A,    /*!< Running - closing descriptor */
+    ETH_DMA_RECEIVEPROCESS_QUEUING   = 0x0E     /*!< Running - queuing the receive frame into host memory */
+} ETH_DMA_RECEIVEPROCESS_T;
+
+/**
+ * @brief    ETH DMA overflow
+ */
+typedef enum
+{
+    ETH_DMA_OVERFLOW_RXFIFOCOUNTER = BIT28,     /*!< Overflow for FIFO Overflows Counter */
+    ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER = BIT16 /*!< Overflow for Buffer Unavailable Missed Frame Counter */
+} ETH_DMA_OVERFLOW_T;
+
+/**
+ * @brief    ETH PMT Flags
+ */
+typedef enum
+{
+    ETH_PMT_FLAG_WUFFRPR = (int)BIT31,  /*!< Wake-Up Frame Filter Register Pointer Reset */
+    ETH_PMT_FLAG_WUFR = BIT6,           /*!< Wake-Up Frame Received */
+    ETH_PMT_FLAG_MPR = BIT5             /*!< Magic Packet Received */
+} ETH_PMT_FLAG_T;
+
+/**
+ * @brief    ETH MMC Tx/RX Interrupts
+ */
+typedef enum
+{
+    ETH_MMC_INT_TGF    = BIT21,         /*!< When Tx good frame counter reaches half the maximum value */
+    ETH_MMC_INT_TGFMSC = BIT15,         /*!< When Tx good multi col counter reaches half the maximum value */
+    ETH_MMC_INT_TGFSC  = BIT14,         /*!< When Tx good single col counter reaches half the maximum value */
+    ETH_MMC_INT_RGUF   = BIT21|BIT30,   /*!< When Rx good unicast frames counter reaches half the maximum value */
+    ETH_MMC_INT_RFAE   = BIT6|BIT30,    /*!< When Rx alignment error counter reaches half the maximum value */
+    ETH_MMC_INT_RFCE   = BIT5|BIT30     /*!< When Rx crc error counter reaches half the maximum value */
+} ETH_MMC_INT_T;
+
+/**
+ * @brief    ETH MMC Registers
+ */
+typedef enum
+{
+    ETH_MMC_CTRL       =  0x00000100,   /*!< MMC CTRL register */
+    ETH_MMC_RXINT      =  0x00000104,   /*!< MMC RXINT register */
+    ETH_MMC_TXINT      =  0x00000108,   /*!< MMC TXINT register */
+    ETH_MMC_RXINTMASK  =  0x0000010C,   /*!< MMC RXINTMASK register */
+    ETH_MMC_TXINTMASK  =  0x00000110,   /*!< MMC TXINTMASK register */
+    ETH_MMC_TXGFSCCNT  =  0x0000014C,   /*!< MMC TXGFSCCNT register */
+    ETH_MMC_TXGFMCCNT  =  0x00000150,   /*!< MMC TXGFMCCNT register */
+    ETH_MMC_TXGFCNT    =  0x00000168,   /*!< MMC TXGFCNT register */
+    ETH_MMC_RXFCECNT   =  0x00000194,   /*!< MMC RXFCECNT register */
+    ETH_MMC_RXFAECNT   =  0x00000198,   /*!< MMC RXFAECNT register */
+    ETH_MMC_RXGUNCNT   =  0x000001C4    /*!< MMC RXGUNCNT register */
+} ETH_MMC_REG_T;
+
+/**@} end of group ETH_Enumerations*/
+
+
+/** @defgroup ETH_DMA_TX_Descriptor ETH DMA TX Descriptor
+  @{
+  */
+
+/**
+*  DMA Tx Descriptor
+*  -----------------------------------------------------------------------------------------------
+*  TXDES0 | OWN(31) | CTRL[30:25] | Reserved(24) | CTRL[23:20] | Reserved[19:18] | Status[17:0]   |
+*  -----------------------------------------------------------------------------------------------
+*  TXDES1 | Reserved[31:29] | Buffer2 Size[28:16] | Reserved[15:13] | Buffer1 Size[12:0]          |
+*  -----------------------------------------------------------------------------------------------
+*  TXDES2 |                         Buffer1 Address [31:0]                                        |
+*  -----------------------------------------------------------------------------------------------
+*  TXDES3 |                   Buffer2 Address [31:0] / Next Descriptor Address [31:0]             |
+*  -----------------------------------------------------------------------------------------------
+*/
+
+/**
+  * @brief  Bit definition of TXDES0 register: DMA Tx descriptor status register
+  */
+#define ETH_DMATXDESC_OWN                     0x80000000U   /*!< OWN bit: descriptor is owned by DMA engine */
+#define ETH_DMATXDESC_INTC                    0x40000000U   /*!< Interrupt on Completion */
+#define ETH_DMATXDESC_LS                      0x20000000U   /*!< Last Segment */
+#define ETH_DMATXDESC_FS                      0x10000000U   /*!< First Segment */
+#define ETH_DMATXDESC_DISC                    0x08000000U   /*!< Disable CRC */
+#define ETH_DMATXDESC_DISP                    0x04000000U   /*!< Disable Padding */
+#define ETH_DMATXDESC_TXTSEN                  0x02000000U   /*!< Transmit Time Stamp Enable */
+#define ETH_DMATXDESC_CIC                     0x00C00000U   /*!< Checksum Insertion Control: 4 cases */
+#define ETH_DMATXDESC_CIC_BYPASS              0x00000000U   /*!< Do Nothing: Checksum Engine is bypassed */
+#define ETH_DMATXDESC_CIC_IPV4HEADER          0x00400000U   /*!< IPV4 header Checksum Insertion */
+#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT  0x00800000U   /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */
+#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL     0x00C00000U   /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */
+#define ETH_DMATXDESC_TXENDR                  0x00200000U   /*!< Transmit End of Ring */
+#define ETH_DMATXDESC_TXCH                    0x00100000U   /*!< Second Address Chained */
+#define ETH_DMATXDESC_TXTSS                   0x00020000U   /*!< Tx Time Stamp Status */
+#define ETH_DMATXDESC_IHERR                   0x00010000U   /*!< IP Header Error */
+#define ETH_DMATXDESC_ERRS                    0x00008000U   /*!< Error summary: OR of the following bits: UFERR || EDEF || EC || LC || NC || LSC || FF || JTO */
+#define ETH_DMATXDESC_JTO                     0x00004000U   /*!< Jabber Timeout */
+#define ETH_DMATXDESC_FF                      0x00002000U   /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
+#define ETH_DMATXDESC_IPERR                   0x00001000U   /*!< Payload Checksum Error */
+#define ETH_DMATXDESC_LSC                     0x00000800U   /*!< Loss of Carrier: carrier lost during transmission */
+#define ETH_DMATXDESC_NC                      0x00000400U   /*!< No Carrier: no carrier signal from the transceiver */
+#define ETH_DMATXDESC_LC                      0x00000200U   /*!< Late Collision: transmission aborted due to collision */
+#define ETH_DMATXDESC_EC                      0x00000100U   /*!< Excessive Collision: transmission aborted after 16 collisions */
+#define ETH_DMATXDESC_VLANF                   0x00000080U   /*!< VLAN Frame */
+#define ETH_DMATXDESC_CCNT                    0x00000078U   /*!< Collision Count */
+#define ETH_DMATXDESC_EDEF                    0x00000004U   /*!< Excessive Deferral */
+#define ETH_DMATXDESC_UFERR                   0x00000002U   /*!< Underflow Error: late data arrival from the memory */
+#define ETH_DMATXDESC_DEF                     0x00000001U   /*!< Deferred Bit */
+
+/**
+  * @brief  Bit definition of TXDES1 register
+  */
+#define ETH_DMATXDESC_TXBS2  0x1FFF0000U /*!< Transmit Buffer2 Size */
+#define ETH_DMATXDESC_TXBS1  0x00001FFFU /*!< Transmit Buffer1 Size */
+
+/**
+  * @brief  Bit definition of TXDES2 register
+  */
+#define ETH_DMATXDESC_B1AP  0xFFFFFFFFU /*!< Buffer1 Address Pointer */
+
+/**
+  * @brief  Bit definition of TXDES3 register
+  */
+#define ETH_DMATXDESC_B2AP  0xFFFFFFFFU /*!< Buffer2 Address Pointer */
+
+/**
+*  ---------------------------------------------------------------------------------------------
+*  TXDES6 |                         Transmit Time Stamp Low [31:0]                               |
+*  ---------------------------------------------------------------------------------------------
+*  TXDES7 |                         Transmit Time Stamp High [31:0]                              |
+*  ----------------------------------------------------------------------------------------------
+*/
+
+/** Bit definition of TXDES6 register */
+#define ETH_DMAPTPTXDESC_TXTSL  0xFFFFFFFFU  /*!< Transmit Time Stamp Low */
+
+/** Bit definition of TXDES7 register */
+#define ETH_DMAPTPTXDESC_TXTSH  0xFFFFFFFFU  /*!< Transmit Time Stamp High */
+
+/**
+  * @}
+  */
+/** @defgroup ETH_DMA_RX_Descriptor ETH DMA RX Descriptor
+  @{
+  */
+
+/**
+  *DMA Rx Descriptor
+  *--------------------------------------------------------------------------------------------------------------------
+  *RXDES0 | OWN(31) |                                             Status [30:0]                                         |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES1 | CTRL(31) | Reserved[30:29] | Buffer2 Size[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 Size[12:0]          |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES2 |                                       Buffer1 Address [31:0]                                                |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES3 |                          Buffer2 Address [31:0] / Next Descriptor Address [31:0]                            |
+  *---------------------------------------------------------------------------------------------------------------------
+*/
+
+/**
+  * @brief  Bit definition of RXDES0 register: DMA Rx descriptor status register
+  */
+#define ETH_DMARXDESC_OWN         0x80000000U   /*!< OWN bit: descriptor is owned by DMA engine */
+#define ETH_DMARXDESC_ADDRF       0x40000000U   /*!< DA Filter Fail for the rx frame */
+#define ETH_DMARXDESC_FL          0x3FFF0000U   /*!< Receive descriptor frame length */
+#define ETH_DMARXDESC_ERRS        0x00008000U   /*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */
+#define ETH_DMARXDESC_DESERR      0x00004000U   /*!< Descriptor error: no more descriptors for receive frame */
+#define ETH_DMARXDESC_SADDRF      0x00002000U   /*!< SA Filter Fail for the received frame */
+#define ETH_DMARXDESC_LERR        0x00001000U   /*!< Frame size not matching with length field */
+#define ETH_DMARXDESC_OFERR       0x00000800U   /*!< Overflow Error: Frame was damaged due to buffer overflow */
+#define ETH_DMARXDESC_VLANF       0x00000400U   /*!< VLAN Tag: received frame is a VLAN frame */
+#define ETH_DMARXDESC_FDES        0x00000200U   /*!< First descriptor of the frame */
+#define ETH_DMARXDESC_LDES        0x00000100U   /*!< Last descriptor of the frame */
+#define ETH_DMARXDESC_IPV4HCE     0x00000080U   /*!< IPC Checksum Error: Rx Ipv4 header checksum error */
+#define ETH_DMARXDESC_LC          0x00000040U   /*!< Late collision occurred during reception */
+#define ETH_DMARXDESC_FT          0x00000020U   /*!< Frame type - Ethernet, otherwise 802.3 */
+#define ETH_DMARXDESC_RXWWTTO     0x00000010U   /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
+#define ETH_DMARXDESC_RERR        0x00000008U   /*!< Receive error: error reported by MII interface */
+#define ETH_DMARXDESC_DERR        0x00000004U   /*!< Dribble bit error: frame contains non int multiple of 8 bits */
+#define ETH_DMARXDESC_CERR        0x00000002U   /*!< CRC error */
+#define ETH_DMARXDESC_MAMPCE      0x00000001U   /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
+
+/**
+  * @brief  Bit definition of RXDES1 register
+  */
+#define ETH_DMARXDESC_DINTC  0x80000000U /*!< Disable Interrupt on Completion */
+#define ETH_DMARXDESC_RXBS2  0x1FFF0000U /*!< Receive Buffer2 Size */
+#define ETH_DMARXDESC_RXER   0x00008000U /*!< Receive End of Ring */
+#define ETH_DMARXDESC_RXCH   0x00004000U /*!< Second Address Chained */
+#define ETH_DMARXDESC_RXBS1  0x00001FFFU /*!< Receive Buffer1 Size */
+
+/**
+  * @brief  Bit definition of RXDES2 register
+  */
+#define ETH_DMARXDESC_B1AP  0xFFFFFFFFU /*!< Buffer1 Address Pointer */
+
+/**
+  * @brief  Bit definition of RXDES3 register
+  */
+#define ETH_DMARXDESC_B2AP  0xFFFFFFFFU /*!< Buffer2 Address Pointer */
+
+/**
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES4 |                   Reserved[31:14]              |             Extended Status [13:0]                         |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES5 |                                            Reserved[31:0]                                                   |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES6 |                                       Receive Time Stamp Low [31:0]                                         |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES7 |                                       Receive Time Stamp High [31:0]                                        |
+  *---------------------------------------------------------------------------------------------------------------------
+*/
+
+/** Bit definition of RXDES4 register */
+#define ETH_DMAPTPRXDESC_PTPV     0x00002000U                           /*!< PTP Version */
+#define ETH_DMAPTPRXDESC_PTPFT    0x00001000U                           /*!< PTP Frame Type */
+#define ETH_DMAPTPRXDESC_PTPMT    0x00000F00U                           /*!< PTP Message Type */
+#define ETH_DMAPTPRXDESC_PTPMT_SYNC                      0x00000100U    /*!< SYNC message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_FOLLOWUP                  0x00000200U    /*!< FollowUp message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_DELAYREQ                  0x00000300U    /*!< DelayReq message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_DELAYRESP                 0x00000400U    /*!< DelayResp message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_PDELAYREQ_ANNOUNCE        0x00000500U    /*!< PdelayReq message (peer-to-peer transparent clock) or Announce message (Ordinary or Boundary clock) */
+#define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESP_MANAG          0x00000600U    /*!< PdelayResp message (peer-to-peer transparent clock) or Management message (Ordinary or Boundary clock) */
+#define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESPFOLLOWUP_SIGNAL 0x00000700U    /*!< PdelayRespFollowUp message (peer-to-peer transparent clock) or Signaling message (Ordinary or Boundary clock) */
+#define ETH_DMAPTPRXDESC_IPV6P    0x00000080U                           /*!< IPv6 Packet Received */
+#define ETH_DMAPTPRXDESC_IPV4P    0x00000040U                           /*!< IPv4 Packet Received */
+#define ETH_DMAPTPRXDESC_IPCBP    0x00000020U                           /*!< IP Checksum Bypassed */
+#define ETH_DMAPTPRXDESC_IPPERR   0x00000010U                           /*!< IP Payload Error */
+#define ETH_DMAPTPRXDESC_IPHERR   0x00000008U                           /*!< IP Header Error */
+#define ETH_DMAPTPRXDESC_IPPT     0x00000007U                           /*!< IP Payload Type */
+#define ETH_DMAPTPRXDESC_IPPT_UDP                 0x00000001U           /*!< UDP payload encapsulated in the IP datagram */
+#define ETH_DMAPTPRXDESC_IPPT_TCP                 0x00000002U           /*!< TCP payload encapsulated in the IP datagram */
+#define ETH_DMAPTPRXDESC_IPPT_ICMP                0x00000003U           /*!< ICMP payload encapsulated in the IP datagram */
+
+/** Bit definition of RXDES6 register */
+#define ETH_DMAPTPRXDESC_RXTSL  0xFFFFFFFFU  /*!< Receive Time Stamp Low */
+
+/** Bit definition of RXDES7 register */
+#define ETH_DMAPTPRXDESC_RXTSH  0xFFFFFFFFU  /*!< Receive Time Stamp High */
+/**
+  * @}
+  */
+
+
+/** @addtogroup ETH_Macros Macros
+  *@{
+  */
+
+/** ETH Frames defines */
+
+/** Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE                ETH_MAX_PACKET_SIZE  /*!< buffer size for receive */
+#define ETH_TX_BUF_SIZE                ETH_MAX_PACKET_SIZE  /*!< buffer size for transmit */
+#define ETH_RXBUFNB                    (10U)                /*!< 10 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB                    (10U)                /*!< 10 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/** ETH_Buffers_setting ETH Buffers setting */
+#define ETH_MAX_PACKET_SIZE       1524U /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */
+#define ETH_HEADER                14U   /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */
+#define ETH_CRC                   4U    /*!< Ethernet CRC */
+#define ETH_EXTRA                 2U    /*!< Extra bytes in some cases */
+#define ETH_VLAN_TAG              4U    /*!< optional 802.1q VLAN Tag */
+#define ETH_MIN_ETH_PAYLOAD       46U   /*!< Minimum Ethernet payload size */
+#define ETH_MAX_ETH_PAYLOAD       1500U /*!< Maximum Ethernet payload size */
+#define ETH_JUMBO_FRAME_PAYLOAD   9000U /*!< Jumbo frame payload size */
+
+/**
+*  Ethernet driver receive buffers are organized in a chained linked-list, when
+*  an ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO
+*  to the driver receive buffers memory.
+*
+*  Depending on the size of the received ethernet packet and the size of
+*  each ethernet driver receive buffer, the received packet can take one or more
+*  ethernet driver receive buffer.
+*
+*  In below are defined the size of one ethernet driver receive buffer ETH_RX_BUF_SIZE
+*  and the total count of the driver receive buffers ETH_RXBUFNB.
+*
+*  The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as
+*  example, they can be reconfigured in the application layer to fit the application
+*  needs
+*/
+
+/** Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet
+*   packet
+*/
+#ifndef ETH_RX_BUF_SIZE
+#define ETH_RX_BUF_SIZE         ETH_MAX_PACKET_SIZE
+#endif
+
+/** 5 Ethernet driver receive buffers are used (in a chained linked list)*/
+#ifndef ETH_RXBUFNB
+#define ETH_RXBUFNB             5U  /*!< 5 Rx buffers of size ETH_RX_BUF_SIZE */
+#endif
+
+/**
+*  Ethernet driver transmit buffers are organized in a chained linked-list, when
+*  an ethernet packet is transmitted, Tx-DMA will transfer the packet from the
+*  driver transmit buffers memory to the TxFIFO.
+*
+*  Depending on the size of the Ethernet packet to be transmitted and the size of
+*  each ethernet driver transmit buffer, the packet to be transmitted can take
+*  one or more ethernet driver transmit buffer.
+*
+*  In below are defined the size of one ethernet driver transmit buffer ETH_TX_BUF_SIZE
+*  and the total count of the driver transmit buffers ETH_TXBUFNB.
+*
+*  The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as
+*  example, they can be reconfigured in the application layer to fit the application
+*  needs
+*/
+
+/** Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet
+*   packet
+*/
+#ifndef ETH_TX_BUF_SIZE
+#define ETH_TX_BUF_SIZE         ETH_MAX_PACKET_SIZE
+#endif
+
+/** 5 ethernet driver transmit buffers are used (in a chained linked list)*/
+#ifndef ETH_TXBUFNB
+#define ETH_TXBUFNB             5U  /*!< 5  Tx buffers of size ETH_TX_BUF_SIZE */
+#endif
+
+/** ETHERNET MAC address offsets */
+#define ETH_MAC_ADDR_HBASE   (ETH_MAC_BASE + 0x40)      /*!< ETHERNET MAC address high offset */
+#define ETH_MAC_ADDR_LBASE    (ETH_MAC_BASE + 0x44)     /*!< ETHERNET MAC address low offset */
+
+/** ETHERNET Errors */
+#define  ETH_SUCCESS            1U
+#define  ETH_ERROR              0U
+
+/** ETHERNET DMA Tx descriptors Collision Count Shift */
+#define  ETH_DMATXDESC_COLLISION_COUNTSHIFT        3U
+
+/** ETHERNET DMA Tx descriptors Buffer2 Size Shift */
+#define  ETH_DMATXDESC_BUFFER2_SIZESHIFT           16U
+
+/** ETHERNET DMA Rx descriptors Frame Length Shift */
+#define  ETH_DMARXDESC_FRAME_LENGTHSHIFT           16U
+
+/** ETHERNET DMA Rx descriptors Buffer2 Size Shift */
+#define  ETH_DMARXDESC_BUFFER2_SIZESHIFT           16U
+
+/** ETHERNET DMA Rx descriptors Frame length Shift */
+#define  ETH_DMARXDESC_FRAMELENGTHSHIFT            16U
+
+/** ETHERNET MACMIIAR register Mask */
+#define ETH_MACMIIAR_CR_MASK    0xFFFFFFE3U
+
+/** ETHERNET MACCR register Mask */
+#define ETH_MACCR_CLEAR_MASK    0xFF20010FU
+
+/** ETHERNET MACFCR register Mask */
+#define ETH_MACFCR_CLEAR_MASK   0x0000FF41U
+
+/** ETHERNET DMAOMR register Mask */
+#define ETH_DMAOMR_CLEAR_MASK   0xF8DE3F23U
+
+/** ETHERNET Remote Wake-up frame register length */
+#define ETH_WAKEUP_REGISTER_LENGTH      8U
+
+/** ETHERNET Missed frames counter Shift */
+#define  ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT     17U
+
+/** PHY registers defines */
+
+/** PHY Read write Timeouts */
+#define PHY_READ_TIMEOUT                ((uint32_t)0x0004FFFF)
+#define PHY_WRITE_TIMEOUT               ((uint32_t)0x0004FFFF)
+
+/** PHY Register address */
+#define PHY_BCR                                      0         /*!< Transceiver Basic Control Register */
+#define PHY_BSR                                      1         /*!< Transceiver Basic Status Register */
+#define PHY_SR                                       16        /*!< Transceiver Status Register for dp83848 */
+
+/** PHY Status Register (PHYSTS), address 0x10 */
+#define PHY_DUPLEX_STATUS               ((uint16_t)0x0004)     /*!< for dp83848 ((uint16_t)0x0010) */
+#define PHY_SPEED_STATUS                ((uint16_t)0x0002)     /*!< for dp83848 ((uint16_t)0x0004) */
+
+/** PHY basic status register */
+#define PHY_AUTONEGO_COMPLETE           ((uint16_t)0x0020)     /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS               ((uint16_t)0x0004)     /*!< Valid link established */
+#define PHY_JABBER_DETECTION            ((uint16_t)0x0002)     /*!< Jabber condition detected */
+
+/** PHY basic Control register */
+#define PHY_RESET                       ((uint16_t)0x8000)     /*!< PHY Reset */
+#define PHY_LOOPBACK                    ((uint16_t)0x4000)     /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M             ((uint16_t)0x2100)     /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M             ((uint16_t)0x2000)     /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M              ((uint16_t)0x0100)     /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M              ((uint16_t)0x0000)     /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION             ((uint16_t)0x1000)     /*!< Enable auto-negotiation function */
+#define PHY_RESTAET_AUTONEGOTIATION     ((uint16_t)0x0200)     /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN                   ((uint16_t)0x0800)     /*!< Select the power down mode */
+#define PHY_ISOLATE                     ((uint16_t)0x0400)     /*!< Isolate PHY from MII */
+
+/** PHY Delay */
+#define PHY_RESET_DELAY                 ((uint32_t)0x000FFFFF) /*!< PHY reset delay */
+#define PHY_CONFIG_DELAY                ((uint32_t)0x00FFFFFF) /*!< PHY configuration delay */
+/** Delay to wait when writing to some Ethernet registers */
+#define ETH_REG_WRITE_DELAY             ((uint32_t)0x0000FFFF)
+
+/** Ethernet MAC MII Address Clock Range*/
+#define ETH_MACMIIAR_CR_DIV42   ((uint8_t)0x00)                 /*!< HCLK:60-100 MHz; MDC clock = HCLK/42 */
+#define ETH_MACMIIAR_CR_DIV62   ((uint8_t)0x01)                 /*!< HCLK:100-150 MHz; MDC clock = HCLK/62 */
+#define ETH_MACMIIAR_CR_DIV16   ((uint8_t)0x02)                 /*!< HCLK:20-35 MHz; MDC clock = HCLK/16 */
+#define ETH_MACMIIAR_CR_DIV26   ((uint8_t)0x03)                 /*!< HCLK:35-60 MHz; MDC clock = HCLK/26 */
+#define ETH_MACMIIAR_CR_DIV102  ((uint8_t)0x04)                 /*!< HCLK:150-168 MHz; MDC clock = HCLK/102 */
+
+/** Control the Enhanced DMA descriptors */
+#define USE_ENHANCED_DMA_DESCRIPTORS     1
+
+/**@} end of group ETH_Macros */
+
+
+/** @addtogroup ETH_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief    ETH MAC Config structure types
+ */
+typedef struct
+{
+    /** MAC Configuration */
+    ETH_AUTONEGOTIATION_T           autoNegotiation;            /*!< Selects or not the AutoNegotiation mode for the external PHY
+                                                                    The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps)
+                                                                    and the mode (half/full-duplex) */
+
+    ETH_WATCHDOG_T                  watchDog;                   /*!< Selects or not the Watchdog timer
+                                                                    When enabled, the MAC allows no more then 2048 bytes to be received.
+                                                                    When disabled, the MAC can receive up to 16384 bytes. */
+
+    ETH_JABBER_T                    jabber;                     /*!< Selects or not Jabber timer
+                                                                    When enabled, the MAC allows no more then 2048 bytes to be sent.
+                                                                    When disabled, the MAC can send up to 16384 bytes. */
+    ETH_INTERFRAMEGAP_T             interFrameGap;              /*!< Selects the minimum IFG between frames during transmission */
+
+    ETH_CARRIERSENCE_T              carrierSense;               /*!< Selects or not the Carrier Sense */
+
+    ETH_SPEED_T                     speed;                      /*!< Sets the Ethernet speed: 10/100 Mbps */
+
+    ETH_RECEIVEOWN_T                receiveOwn;                 /*!< Selects or not the ReceiveOwn
+                                                                    ReceiveOwn allows the reception of frames when the TX_EN signal is asserted
+                                                                    in Half-Duplex mode */
+
+    ETH_LOOPBACKMODE_T              loopbackMode;               /*!< Selects or not the internal MAC MII Loopback mode */
+
+    ETH_MODE_T                      mode;                       /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode */
+
+    ETH_CHECKSUMOFFLAOD_T           checksumOffload;            /*!< Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers. */
+
+    ETH_RETRYTRANSMISSION_T         retryTransmission;          /*!< Selects or not the MAC attempt retries transmission, based on the settings of BL,
+                                                                    when a collision occurs (Half-Duplex mode) */
+
+    ETH_AUTOMATICPADCRCSTRIP_T      automaticPadCRCStrip;       /*!< Selects or not the Automatic MAC Pad/CRC Stripping */
+
+    ETH_BACKOFFLIMIT_T              backOffLimit;               /*!< Selects the BackOff limit value */
+
+    ETH_DEFFERRALCHECK_T            deferralCheck;              /*!< Selects or not the deferral check function (Half-Duplex mode) */
+
+    ETH_RECEIVEAll_T                receiveAll;                 /*!< Selects or not all frames reception by the MAC (No filtering) */
+
+    ETH_SOURCEADDRFILTER_T          sourceAddrFilter;           /*!< Selects the Source Address Filter mode */
+
+    ETH_PASSCONTROLFRAMES_T         passControlFrames;          /*!< Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames) */
+
+    ETH_BROADCASTFRAMESRECEPTION_T  broadcastFramesReception;   /*!< Selects or not the reception of Broadcast Frames */
+
+    ETH_DESTINATIONADDRFILTER_T     destinationAddrFilter;      /*!< Sets the destination filter mode for both unicast and multicast frames */
+
+    ETH_PROMISCUOUS_MODE_T          promiscuousMode;            /*!< Selects or not the Promiscuous Mode */
+
+    ETH_MULTICASTFRAMESFILTER_T     multicastFramesFilter;      /*!< Selects the Multicast Frames filter mode */
+
+    ETH_UNICASTFRAMESFILTER_T       unicastFramesFilter;        /*!< Selects the Unicast Frames filter mode */
+
+
+    uint32_t                        hashTableHigh;              /*!< This field holds the higher 32 bits of Hash table. */
+
+    uint32_t                        hashTableLow;               /*!< This field holds the lower 32 bits of Hash table. */
+
+    uint32_t                        pauseTime;                  /*!< This field holds the (value<=0xFFFF) to be used in the Pause Time */
+
+    ETH_ZEROQUANTAPAUSE_T           zeroQuantaPause;            /*!< Selects or not the automatic generation of Zero-Quanta Pause Control frames */
+
+    ETH_PAUSELOWTHRESHOLD_T         pauseLowThreshold;          /*!< This field configures the threshold of the PAUSE to be checked for
+                                                                    automatic retransmission of PAUSE Frame */
+
+    ETH_UNICASTPAUSEFRAMEDETECT_T   unicastPauseFrameDetect;    /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0
+                                                                    unicast address and unique multicast address) */
+
+    ETH_RECEIVEFLOWCONTROL_T        receiveFlowControl;         /*!< Enables or disables the MAC to decode the received Pause frame and
+                                                                    disable its transmitter for a specified time (Pause Time) */
+
+    ETH_TRANSMITFLOWCONTROL_T       transmitFlowControl;        /*!< Enables or disables the MAC to transmit Pause frames (Full-Duplex mode)
+                                                                    or the MAC back-pressure operation (Half-Duplex mode) */
+
+    ETH_VLANTAGCOMPARISON_T         VLANTagComparison;          /*!< Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for
+                                                                    comparison and filtering */
+
+    uint32_t                        VLANTagIdentifier;          /*!< Holds the (value <=0xFFFF) VLAN tag identifier for receive frames */
+
+    /** DMA Configuration */
+    ETH_DROPTCPIPCHECKSUMERRORFRAME_T   dropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames */
+
+    ETH_RECEIVESTOREFORWARD_T           receiveStoreForward;         /*!< Enables or disables the Receive store and forward mode */
+
+    ETH_FLUSHRECEIVEDFRAME_T            flushReceivedFrame;          /*!< Enables or disables the flushing of received frames */
+
+    ETH_TRANSMITSTOREFORWARD_T          transmitStoreForward;        /*!< Enables or disables Transmit store and forward mode */
+
+    ETH_TRANSMITTHRESHOLDCONTROL_T      transmitThresholdControl;    /*!< Selects or not the Transmit Threshold Control */
+
+    ETH_FORWARDERRORFRAMES_T            forwardErrorFrames;          /*!< Selects or not the forward to the DMA of erroneous frames */
+
+    ETH_FORWARDUNDERSIZEDGOODFRAMES_T   forwardUndersizedGoodFrames; /*!< Enables or disables the Rx FIFO to forward Undersized frames (frames with no Error
+                                                                        and length less than 64 bytes) including pad-bytes and CRC) */
+
+    ETH_RECEIVEDTHRESHOLDCONTROL_T      receiveThresholdControl;     /*!< Selects the threshold level of the Receive FIFO */
+
+    ETH_SECONDFRAMEOPERARTE_T           secondFrameOperate;          /*!< Selects or not the Operate on second frame mode, which allows the DMA to process a second
+                                                                        frame of Transmit data even before obtaining the status for the first frame. */
+
+    ETH_ADDRESSALIGNEDBEATS_T           addressAlignedBeats;         /*!< Enables or disables the Address Aligned Beats */
+
+    ETH_FIXEDBURST_T                    fixedBurst;                  /*!< Enables or disables the AHB Master interface fixed burst transfers */
+
+    ETH_RXDMABURSTLENGTH_T              rxDMABurstLength;            /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction */
+
+    ETH_TXDMABURSTLENGTH_T              txDMABurstLength;            /*!< Indicates the maximum number of beats to be transferred in one Tx DMA transaction */
+
+    uint32_t                            descriptorSkipLength;        /*!< Specifies the number of word to skip between two unchained descriptors (Ring mode) (value <= 0x1F) */
+
+    ETH_DMAARBITRATION_T                DMAArbitration;              /*!< Selects the DMA Tx/Rx arbitration */
+} ETH_Config_T;
+
+/**
+  * @brief  ETH DMA Descriptors data structure types
+  */
+typedef struct
+{
+    __IO uint32_t   Status;                            /*!< Status */
+    uint32_t        ControlBufferSize;                 /*!< Control and Buffer1, Buffer2 lengths */
+    uint32_t        Buffer1Addr;                       /*!< Buffer1 address pointer */
+    uint32_t        Buffer2NextDescAddr;               /*!< Buffer2 or next descriptor address pointer */
+    /* Enhanced ETHERNET DMA PTP Descriptors */
+    #if USE_ENHANCED_DMA_DESCRIPTORS
+    uint32_t        ExtendedStatus;                    /*!< Extended status for PTP receive descriptor */
+    uint32_t        Reserved1;                         /*!< Reserved */
+    uint32_t        TimeStampLow;                      /*!< Time Stamp Low value for transmit and receive */
+    uint32_t        TimeStampHigh;                     /*!< Time Stamp High value for transmit and receive */
+    #endif /* USE_ENHANCED_DMA_DESCRIPTORS */
+} ETH_DMADescConfig_T;
+
+/**
+  * @brief  ETH DMA Descriptors data structure types
+  */
+typedef struct
+{
+    uint32_t        length;                 /*!< Data length */
+    uint32_t        buffer;                 /*!< Data buffer */
+    __IO ETH_DMADescConfig_T *descriptor;   /*!< DMA descriptor */
+} ETH_Frame_T;
+
+/**
+  * @brief  ETH DMA Descriptors Received Frame Informations structure types
+  */
+typedef struct  {
+  __IO ETH_DMADescConfig_T   *FS_RxDesc;              /*!< First Segment Rx Desc */
+  __IO ETH_DMADescConfig_T   *LS_RxDesc;              /*!< Last Segment Rx Desc */
+  __IO uint32_t               segCount;               /*!< Segment count */
+} ETH_DMARxFrameInformations;
+
+/**@} end of group ETH_Structure*/
+
+/** @defgroup ETH_Functions
+  @{
+*/
+
+/* ETH Configuration */
+void ETH_Reset(void);
+void ETH_ConfigStructInit(ETH_Config_T* ethConfig);
+uint32_t ETH_Config(ETH_Config_T* ethConfig, uint16_t addr);
+void ETH_SoftwareReset(void);
+uint8_t ETH_ReadSoftwareReset(void);
+void ETH_Start(void);
+void ETH_Stop(void);
+uint32_t ETH_ReadRxPacketSize(ETH_DMADescConfig_T *DMARxDesc);
+#if USE_ENHANCED_DMA_DESCRIPTORS
+void ETH_EnableEnhancedDescriptor(void);
+void ETH_DisableEnhancedDescriptor(void);
+#endif /*!< USE_ENHANCED_DMA_DESCRIPTORS */
+
+/* PHY */
+uint16_t ETH_ReadPHYRegister(uint16_t addr, uint16_t reg);
+uint32_t ETH_WritePHYRegister(uint16_t addr, uint16_t reg, uint16_t data);
+uint32_t ETH_EnablePHYLoopBack(uint16_t addr);
+uint32_t ETH_DisablePHYLoopBack(uint16_t addr);
+
+/* MAC */
+void ETH_EnableMACTransmission(void);
+void ETH_DisableMACTransmission(void);
+void ETH_EnableMACReceiver(void);
+void ETH_DisableMACReceiver(void);
+uint8_t ETH_ReadFlowControlBusyStatus(void);
+void ETH_SetPauseControlFrame(void);
+void ETH_EnableBackPressureActivation(void);
+void ETH_DisableBackPressureActivation(void);
+uint8_t ETH_ReadMACFlagStatus(ETH_MAC_FLAG_T flag);
+void ETH_EnableMACInterrupt(uint32_t interrupt);
+void ETH_DisableMACInterrupt(uint32_t interrupt);
+void ETH_ConfigMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr);
+void ETH_ReadMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr);
+void ETH_EnableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr);
+void ETH_DisableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr);
+void ETH_ConfigMACAddressFilter(ETH_MAC_ADDRESS_T macAddr, ETH_MAC_ADDRESSFILTER_T filter);
+void ETH_ConfigMACAddressMaskBytesFilter(ETH_MAC_ADDRESS_T macAddr, uint32_t maskByte);
+
+/* DMA descriptors */
+void ETH_ConfigDMARxDescChain(ETH_DMADescConfig_T *DMARxDescTab, uint8_t *rxBuff, uint32_t rxBuffcount);
+void ETH_ConfigDMATxDescChain(ETH_DMADescConfig_T *DMATxDescTab, uint8_t* txBuff, uint32_t txBuffcount);
+uint32_t ETH_CheckReceivedFrame(void);
+uint32_t ETH_Transmit_Descriptors(u16 frameLength);
+ETH_Frame_T ETH_ReadReceivedFrame(void);
+uint8_t ETH_ReadDMATxDescFlagStatus(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_FLAG_T flag);
+uint32_t ETH_ReadDMATxDescCollisionCount(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_ConfigDMATxDescOwnBit(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_EnableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_ConfigDMATxDescFrameSegment(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_SEGMENTS_T frameSegment);
+void ETH_ConfigDMATxDescChecksumInsertion(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_CHECKSUMB_T checksum);
+void ETH_EnableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_EnableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_EnableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_ConfigDMATxDescBufferSize(ETH_DMADescConfig_T *DMATxDesc, uint32_t bufferSize1, uint32_t bufferSize2);
+uint8_t ETH_ReadDMARxDescFlagStatus(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_FLAG_T flag);
+#if USE_ENHANCED_DMA_DESCRIPTORS
+uint8_t ETH_ReadDMAPTPRxDescExtendedFlagStatus(ETH_DMADescConfig_T *DMAPTPRxDesc, ETH_DMAPTPRXDESC_FLAG_T flag);
+#endif
+void ETH_ConfigDMARxDescOwnBit(ETH_DMADescConfig_T *DMARxDesc);
+uint32_t ETH_ReadDMARxDescFrameLength(ETH_DMADescConfig_T *DMARxDesc);
+void ETH_EnableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMARxDesc);
+void ETH_DisableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMATxDesc);
+uint32_t ETH_ReadDMARxDescBufferSize(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_BUFFER_T buffer);
+ETH_Frame_T ETH_ReadReceivedFrameInterrupt(void);
+
+/* DMA */
+uint8_t ETH_ReadDMAFlagStatus(ETH_DMA_FLAG_T flag);
+void ETH_ClearDMAFlag(uint32_t flag);
+uint8_t ETH_ReadDMAIntFlag(ETH_DMA_INT_T flag);
+void ETH_ClearDMAIntFlag(uint32_t flag);
+uint32_t ETH_ReadTransmitProcessState(void);
+uint32_t ETH_ReadReceiveProcessState(void);
+void ETH_FlushTransmitFIFO(void);
+uint8_t ETH_ReadFlushTransmitFIFOStatus(void);
+void ETH_EnableDMATransmission(void);
+void ETH_DisableDMATransmission(void);
+void ETH_EnableDMAReceiver(void);
+void ETH_DisableDMAReceiver(void);
+void ETH_EnableDMAInterrupt(uint32_t interrupt);
+void ETH_DisableDMAInterrupt(uint32_t interrupt);
+uint8_t ETH_ReadDMAOverflowStatus(ETH_DMA_OVERFLOW_T overflow);
+uint32_t ETH_ReadRxOverflowMissedFrameCounter(void);
+uint32_t ETH_ReadBufferUnavailableMissedFrameCounter(void);
+uint32_t ETH_ReadCurrentTxDescStartAddress(void);
+uint32_t ETH_ReadCurrentRxDescStartAddress(void);
+uint32_t ETH_ReadCurrentTxBufferAddress(void);
+uint32_t ETH_ReadCurrentRxBufferAddress(void);
+void ETH_ResetDMATransmission(void);
+void ETH_ResetDMAReception(void);
+void ETH_ConfigReceiveWatchdogTimer(uint8_t value);
+
+/* PMT */
+void ETH_ResetWakeUpFrameFilterRegisterPointer(void);
+void ETH_ConfigWakeUpFrameFilterRegister(uint32_t *buffer);
+void ETH_EnableGlobalUnicastWakeUp(void);
+void ETH_DisableGlobalUnicastWakeUp(void);
+uint8_t ETH_ReadPMTFlagStatus(ETH_PMT_FLAG_T flag);
+void ETH_EnableWakeUpFrameDetection(void);
+void ETH_DisableWakeUpFrameDetection(void);
+void ETH_EnableMagicPacketDetection(void);
+void ETH_DisableMagicPacketDetection(void);
+void ETH_EnablePowerDown(void);
+void ETH_DisablePowerDown(void);
+
+/* MMC */
+void ETH_PresetMMCCounterFull(void);
+void ETH_PresetMMCCounterHalf(void);
+void ETH_EnableMMCCounterFreeze(void);
+void ETH_DisableMMCCounterFreeze(void);
+void ETH_EnableMMCResetOnRead(void);
+void ETH_DisableMMCResetOnRead(void);
+void ETH_EnableMMCCounterRollover(void);
+void ETH_DisableMMCCounterRollover(void);
+void ETH_ResetMMCCounters(void);
+void ETH_EnableMMCInterrupt(uint32_t interrupt);
+void ETH_DisableMMCInterrupt(uint32_t interrupt);
+uint8_t ETH_ReadMMCIntFlag(uint32_t flag);
+uint32_t ETH_ReadMMCRegister(ETH_MMC_REG_T MMCReg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /** __APM32F4xx_ETH_H */
+
+/**@} end of group ETH_Functions */
+/**@} end of group ETH_Driver */
+/**@} end of group APM32F4xx_ETHDriver */

+ 2308 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/src/apm32f4xx_eth.c

@@ -0,0 +1,2308 @@
+/*!
+ * @file        apm32f4xx_eth.c
+ *
+ * @brief       This file provides all the ETH 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_eth.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_ETHDriver
+  @{
+*/
+
+/** @defgroup ETH_Driver
+  * @brief ETH driver modules
+  @{
+*/
+
+#if defined   (__CC_ARM) /*!< ARM Compiler */
+__align(4)
+ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB]; /*!< Ethernet Rx MA Descriptor */
+__align(4)
+ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB]; /*!< Ethernet Tx DMA Descriptor */
+__align(4)
+uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];  /*!< Ethernet Receive Buffer */
+__align(4)
+uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];  /*!< Ethernet Transmit Buffer */
+
+#elif defined ( __ICCARM__ )
+ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB]; /*!< Ethernet Rx MA Descriptor */
+ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB]; /*!< Ethernet Tx DMA Descriptor */
+uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];  /*!< Ethernet Receive Buffer */
+uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];  /*!< Ethernet Transmit Buffer */
+
+#elif defined (__GNUC__) /*!< GNU Compiler */
+ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB] __attribute__ ((aligned (4))); /*!< Ethernet Rx MA Descriptor */
+ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB] __attribute__ ((aligned (4))); /*!< Ethernet Tx DMA Descriptor */
+uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__ ((aligned (4)));  /*!< Ethernet Receive Buffer */
+uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__ ((aligned (4)));  /*!< Ethernet Transmit Buffer */
+
+#endif
+
+/** @defgroup Global_Definition
+  @{
+*/
+
+/* Global pointers on Tx and Rx descriptor used to transmit and receive descriptors */
+__IO ETH_DMADescConfig_T  *DMATxDescToSet;
+__IO ETH_DMADescConfig_T  *DMARxDescToGet;
+
+/* Structure used to hold the last received packet descriptors info */
+ETH_DMARxFrameInformations      RxFrameDescriptor;
+__IO ETH_DMARxFrameInformations *DMARxFraminfos;
+__IO uint32_t FrameRxindex;
+
+/**
+  * @}
+  */
+
+/** @defgroup ETH_Functions
+  @{
+*/
+
+/*!
+ * @brief  Inserts a delay time.
+ *
+ * @param  count: specifies the delay time length.
+ *
+ * @retval None
+ */
+static void ETH_Delay(__IO uint32_t count)
+{
+    __IO uint32_t i = 0;
+    for(i = count; i!= 0; i--)
+    {
+    }
+}
+
+/** ETH Configuration */
+
+/*!
+ * @brief  Reset ETH peripheral registers to their default reset values.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_Reset(void)
+{
+    RCM_EnableAHB1PeriphReset(RCM_AHB1_PERIPH_ETH_MAC);
+    RCM_DisableAHB1PeriphReset(RCM_AHB1_PERIPH_ETH_MAC);
+}
+
+/*!
+ * @brief  Config ETH_Config_T member with its default value.
+ *
+ * @param  ethConfig: pointer to a ETH_Config_T structure which will be initialized.
+ *
+ * @retval None
+ */
+void ETH_ConfigStructInit(ETH_Config_T* ethConfig)
+{
+    /* MAC Configuration */
+    ethConfig->autoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
+    ethConfig->watchDog = ETH_WATCHDOG_ENABLE;
+    ethConfig->jabber = ETH_JABBER_ENABLE;
+    ethConfig->interFrameGap = ETH_INTERFRAMEGAP_96BIT;
+    ethConfig->carrierSense = ETH_CARRIERSENCE_ENABLE;
+    ethConfig->speed = ETH_SPEED_100M;
+    ethConfig->receiveOwn = ETH_RECEIVEOWN_ENABLE;
+    ethConfig->loopbackMode = ETH_LOOPBACKMODE_DISABLE;
+    ethConfig->mode = ETH_MODE_FULLDUPLEX;
+    ethConfig->checksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
+    ethConfig->retryTransmission = ETH_RETRYTRANSMISSION_ENABLE;
+    ethConfig->automaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
+    ethConfig->backOffLimit = ETH_BACKOFFLIMIT_10;
+    ethConfig->deferralCheck = ETH_DEFFERRALCHECK_DISABLE;
+    ethConfig->receiveAll = ETH_RECEIVEAll_DISABLE;
+    ethConfig->sourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
+    ethConfig->passControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
+    ethConfig->broadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE;
+    ethConfig->destinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
+    ethConfig->promiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
+    ethConfig->multicastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
+    ethConfig->unicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
+    ethConfig->hashTableHigh = 0x0000;
+    ethConfig->hashTableLow = 0x0000;
+    ethConfig->pauseTime = 0x0000;
+    ethConfig->zeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
+    ethConfig->pauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
+    ethConfig->unicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
+    ethConfig->receiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
+    ethConfig->transmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
+    ethConfig->VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
+    ethConfig->VLANTagIdentifier = 0x0000;
+    /* DMA Configuration */
+    ethConfig->dropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE;
+    ethConfig->receiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
+    ethConfig->flushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
+    ethConfig->transmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
+    ethConfig->transmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
+    ethConfig->forwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
+    ethConfig->forwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
+    ethConfig->receiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
+    ethConfig->secondFrameOperate = ETH_SECONDFRAMEOPERARTE_DISABLE;
+    ethConfig->addressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
+    ethConfig->fixedBurst = ETH_FIXEDBURST_ENABLE;
+    ethConfig->rxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
+    ethConfig->txDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
+    ethConfig->descriptorSkipLength = 0x00;
+    ethConfig->DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
+}
+
+/*!
+ * @brief  Config the ETH peripheral parameters in the ethConfig.
+ *
+ * @param  ethConfig: pointer to a ETH_Config_T structure.
+ *
+ * @param  addr: external PHY address
+ *
+ * @retval ETH_ERROR: Ethernet initialization error
+ *         ETH_SUCCESS: Ethernet initialization success
+ */
+uint32_t ETH_Config(ETH_Config_T* ethConfig, uint16_t addr)
+{
+    uint32_t regValue = 0;
+    uint32_t hclk = 60000000;
+    __IO uint32_t timeout = 0, err = ETH_SUCCESS;
+
+    hclk = RCM_ReadHCLKFreq();
+
+    if((hclk >= 20000000) && (hclk <= 35000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV16;
+    }
+    else if((hclk >= 35000000)&&(hclk < 60000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV26;
+    }
+    else if((hclk >= 60000000)&&(hclk < 100000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV42;
+    }
+    else if((hclk >= 100000000)&&(hclk < 150000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV62;
+    }
+    else
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV102;
+    }
+
+    /* PHY initialization and configuration */
+    if(!(ETH_WritePHYRegister(addr, PHY_BCR, PHY_RESET)))
+    {
+    /* Return ERROR in case of write timeout */
+    err = ETH_ERROR;
+    goto error;
+    }
+
+    ETH_Delay(PHY_RESET_DELAY);
+
+    if(ethConfig->autoNegotiation == ETH_AUTONEGOTIATION_ENABLE)
+    {
+        /* Wait for linked status */
+        do
+        {
+            timeout++ ;
+        } while(!(ETH_ReadPHYRegister(addr,PHY_BSR) & PHY_LINKED_STATUS) && (timeout < PHY_READ_TIMEOUT));
+
+        /* Return ERROR in case of timeout */
+        if(timeout == PHY_READ_TIMEOUT)
+        {
+            err = ETH_ERROR;
+            goto error;
+        }
+
+        timeout = 0;
+        /* Enable Auto-Negotiation */
+        if(!(ETH_WritePHYRegister(addr, PHY_BCR, PHY_AUTONEGOTIATION)))
+        {
+            /* Return ERROR in case of write timeout */
+            err = ETH_ERROR;
+        }
+
+        /* Wait until the auto-negotiation will be completed */
+        do
+        {
+        timeout++;
+        } while (!(ETH_ReadPHYRegister(addr, PHY_BSR) & PHY_AUTONEGO_COMPLETE) && (timeout < (uint32_t)PHY_READ_TIMEOUT));
+
+        /* Return ERROR in case of timeout */
+        if(timeout == PHY_READ_TIMEOUT)
+        {
+            err = ETH_ERROR;
+            goto error;
+        }
+
+        timeout = 0;
+        /* Read the result of the auto-negotiation */
+        regValue = ETH_ReadPHYRegister(addr, PHY_SR);
+
+        if((regValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
+        {
+            ethConfig->mode = ETH_MODE_FULLDUPLEX;
+        }
+        else
+        {
+            ethConfig->mode = ETH_MODE_HALFDUPLEX;
+        }
+        if(regValue & PHY_SPEED_STATUS)
+        {
+            ethConfig->speed = ETH_SPEED_10M;
+        }
+        else
+        {
+            ethConfig->speed = ETH_SPEED_100M;
+        }
+    }
+    else
+    {
+        if(!ETH_WritePHYRegister(addr, PHY_BCR,((uint16_t)(ethConfig->speed << 8) |
+                                                (uint16_t)(ethConfig->mode  << 13))))
+        {
+            err = ETH_ERROR;
+        }
+
+        ETH_Delay(PHY_CONFIG_DELAY);
+    }
+error:
+    if(err == ETH_ERROR)
+    {
+        ethConfig->speed = ETH_SPEED_100M;
+        ethConfig->mode = ETH_MODE_FULLDUPLEX;
+    }
+
+    /* ETHERNET MAC_CFG Configuration */
+    ETH->CFG_B.WDTDIS = ethConfig->watchDog;
+    ETH->CFG_B.JDIS   = ethConfig->jabber;
+    ETH->CFG_B.IFG    = ethConfig->interFrameGap;
+    ETH->CFG_B.DISCRS = ethConfig->carrierSense;
+    ETH->CFG_B.SSEL   = ethConfig->speed;
+    ETH->CFG_B.DISRXO = ethConfig->receiveOwn;
+    ETH->CFG_B.LBM    = ethConfig->loopbackMode;
+    ETH->CFG_B.DM     = ethConfig->mode;
+    ETH->CFG_B.IPC    = ethConfig->checksumOffload;
+    ETH->CFG_B.DISR   = ethConfig->retryTransmission;
+    ETH->CFG_B.ACS    = ethConfig->automaticPadCRCStrip;
+    ETH->CFG_B.BL     = ethConfig->backOffLimit;
+    ETH->CFG_B.DC     = ethConfig->deferralCheck;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET MAC_FRAF Configuration */
+    ETH->FRAF_B.RXA    = ethConfig->receiveAll;
+    ETH->FRAF         |= ethConfig->sourceAddrFilter;
+    ETH->FRAF_B.PCTRLF = ethConfig->passControlFrames;
+    ETH->FRAF_B.DISBF  = ethConfig->broadcastFramesReception;
+    ETH->FRAF_B.DAIF   = ethConfig->destinationAddrFilter;
+    ETH->FRAF_B.PR     = ethConfig->promiscuousMode;
+    ETH->FRAF         |= ethConfig->multicastFramesFilter;
+    ETH->FRAF         |= ethConfig->unicastFramesFilter;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET MAC_HTH/HTL Configuration */
+    ETH->HTH = ethConfig->hashTableHigh;
+    ETH->HTL = ethConfig->hashTableLow;
+
+    /* ETHERNET MAC_FCTRL Configuration */
+    ETH->FCTRL_B.PT        = ethConfig->pauseTime;
+    ETH->FCTRL_B.ZQPDIS    = ethConfig->zeroQuantaPause;
+    ETH->FCTRL_B.PTSEL     = ethConfig->pauseLowThreshold;
+    ETH->FCTRL_B.UNPFDETE  = ethConfig->unicastPauseFrameDetect;
+    ETH->FCTRL_B.RXFCTRLEN = ethConfig->receiveFlowControl;
+    ETH->FCTRL_B.TXFCTRLEN = ethConfig->transmitFlowControl;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET MAC_VLANT Configuration */
+    ETH->VLANT_B.VLANTCOMP = ethConfig->VLANTagComparison;
+    ETH->VLANT_B.VLANTID   = ethConfig->VLANTagIdentifier;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET DMA_OPMOD Configuration */
+    ETH->DMAOPMOD_B.DISDT    = ethConfig->dropTCPIPChecksumErrorFrame;
+    ETH->DMAOPMOD_B.RXSF     = ethConfig->receiveStoreForward;
+    ETH->DMAOPMOD_B.DISFRXF  = ethConfig->flushReceivedFrame;
+    ETH->DMAOPMOD_B.TXSF     = ethConfig->transmitStoreForward;
+    ETH->DMAOPMOD_B.TXTHCTRL = ethConfig->transmitThresholdControl;
+    ETH->DMAOPMOD_B.FERRF    = ethConfig->forwardErrorFrames;
+    ETH->DMAOPMOD_B.FUF      = ethConfig->forwardUndersizedGoodFrames;
+    ETH->DMAOPMOD_B.RXTHCTRL = ethConfig->receiveThresholdControl;
+    ETH->DMAOPMOD_B.OSECF    = ethConfig->secondFrameOperate;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET DMA_BMOD Configuration */
+    ETH->DMABMOD = RESET;
+    ETH->DMABMOD_B.AAL = ethConfig->addressAlignedBeats;
+    ETH->DMABMOD_B.FB = ethConfig->fixedBurst;
+    ETH->DMABMOD |= ethConfig->rxDMABurstLength;
+    ETH->DMABMOD |= ethConfig->txDMABurstLength;
+    ETH->DMABMOD_B.DSL = ethConfig->descriptorSkipLength;
+    ETH->DMABMOD |= ethConfig->DMAArbitration;
+    ETH->DMABMOD_B.USP = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+#if USE_ENHANCED_DMA_DESCRIPTORS
+    ETH->DMABMOD_B.EDFEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+#endif
+
+    if(err == ETH_SUCCESS)
+    {
+        return ETH_SUCCESS;
+    }
+    else
+    {
+        return ETH_ERROR;
+    }
+}
+
+/*!
+ * @brief  Resets all MAC subsystem internal registers and logic.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_SoftwareReset(void)
+{
+    ETH->DMABMOD_B.SWR = SET;
+}
+
+/*!
+ * @brief  Read the ETH software reset bit.
+ *
+ * @param  None
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadSoftwareReset(void)
+{
+    return ETH->DMABMOD_B.SWR;
+}
+
+/*!
+ * @brief     Enables ETH MAC and DMA reception/transmission
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ETH_Start(void)
+{
+    ETH_EnableMACTransmission();
+    ETH_EnableMACReceiver();
+    ETH_FlushTransmitFIFO();
+    ETH_EnableDMATransmission();
+    ETH_EnableDMAReceiver();
+}
+
+/*!
+ * @brief     Disables ETH MAC and DMA reception/transmission
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ETH_Stop(void)
+{
+    ETH_DisableDMATransmission();
+    ETH_DisableDMAReceiver();
+    ETH_DisableMACReceiver();
+    ETH_FlushTransmitFIFO();
+    ETH_DisableMACTransmission();
+}
+
+/*!
+ * @brief  Read the size of the received packet.
+ *
+ * @param  None
+ *
+ * @retval frameLength: received packet size
+ */
+uint32_t ETH_ReadRxPacketSize(ETH_DMADescConfig_T *DMARxDesc)
+{
+    uint32_t frameLength = 0;
+    if(((DMARxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+       ((DMARxDesc->Status & ETH_DMARXDESC_ERRS)  == (uint32_t)RESET) &&
+       ((DMARxDesc->Status & ETH_DMARXDESC_LDES)  != (uint32_t)RESET))
+    {
+        frameLength =  ETH_ReadDMARxDescFrameLength(DMARxDesc);
+    }
+    return frameLength;
+}
+
+#if USE_ENHANCED_DMA_DESCRIPTORS
+/*!
+ * @brief  Enable the Enhanced descriptor structure.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableEnhancedDescriptor(void)
+{
+     ETH->DMABMOD_B.EDFEN = SET;
+}
+
+/*!
+ * @brief  Disable the Enhanced descriptor structure.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableEnhancedDescriptor(void)
+{
+     ETH->DMABMOD_B.EDFEN = RESET;
+}
+#endif /** USE_ENHANCED_DMA_DESCRIPTORS */
+
+/** PHY functions */
+
+/*!
+ * @brief  Read a PHY register
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+ *
+ * @param  reg:  PHY register
+ *               This parameter can be one of the following values:
+ *               @arg PHY_BCR : Transceiver Basic Control Register
+ *               @arg PHY_BSR : Transceiver Basic Status Register
+ *               @arg PHY_SR  :  Transceiver Status Register
+ *
+ * @retval ETH_ERROR: in case of timeout
+ *         MAC DATA register value: Data read from the selected PHY register
+ */
+uint16_t ETH_ReadPHYRegister(uint16_t addr, uint16_t reg)
+{
+    __IO uint32_t timeout = 0;
+
+    ETH->ADDR_B.PA = addr;
+    ETH->ADDR_B.MR = reg;
+    ETH->ADDR_B.MW = RESET;
+    ETH->ADDR_B.MB = SET;
+    /* Check for the Busy flag */
+    do
+    {
+        timeout++ ;
+    } while ((ETH->ADDR_B.MB == SET) && (timeout < PHY_READ_TIMEOUT));
+    /* Return ERROR in case of timeout */
+    if(timeout == PHY_READ_TIMEOUT)
+    {
+        return ETH_ERROR;
+    }
+    /* Return data register value */
+    return (uint16_t)(ETH->DATA);
+}
+
+/*!
+ * @brief  Write to a PHY register
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+
+ * @param  reg:  PHY register
+ *               This parameter can be one of the following values:
+ *               @arg PHY_BCR : Transceiver Basic Control Register
+
+ * @param  data: the data to write
+ *
+ * @retval ETH_ERROR: write timeout
+ *         ETH_SUCCESS: write success
+ */
+uint32_t ETH_WritePHYRegister(uint16_t addr, uint16_t reg, uint16_t data)
+{
+    __IO uint32_t timeout = 0;
+
+    ETH->DATA = data;
+    ETH->ADDR_B.PA = addr;
+    ETH->ADDR_B.MR = reg;
+    ETH->ADDR_B.MW = SET;
+    ETH->ADDR_B.MB = SET;
+
+    /* Check for the Busy flag */
+    do
+    {
+        timeout++ ;
+    } while ((ETH->ADDR_B.MB == SET) && (timeout < PHY_WRITE_TIMEOUT));
+    /* Return ERROR in case of timeout */
+    if(timeout == PHY_WRITE_TIMEOUT)
+    {
+        return ETH_ERROR;
+    }
+    /* Return data register value */
+    return ETH_SUCCESS;
+}
+
+/*!
+ * @brief  Enable the PHY loopBack mode.
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+ *
+ * @retval ETH_ERROR or ETH_SUCCESS
+ */
+uint32_t ETH_EnablePHYLoopBack(uint16_t addr)
+{
+    uint16_t temp = 0;
+
+    temp = ETH_ReadPHYRegister(addr,PHY_BCR);
+    temp |= PHY_LOOPBACK;
+
+    if(ETH_WritePHYRegister(addr,PHY_BCR,temp) == SET)
+    {
+        return ETH_SUCCESS;
+    }
+    else
+    {
+        return ETH_ERROR;
+    }
+}
+
+/*!
+ * @brief  Disable the PHY loopBack mode.
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+ *
+ * @retval ETH_ERROR or ETH_SUCCESS
+ */
+uint32_t ETH_DisablePHYLoopBack(uint16_t addr)
+{
+    uint16_t temp = 0;
+
+    temp = ETH_ReadPHYRegister(addr,PHY_BCR);
+    temp &= ((uint16_t)~PHY_LOOPBACK);
+
+    if(ETH_WritePHYRegister(addr,PHY_BCR,temp) == SET)
+    {
+        return ETH_SUCCESS;
+    }
+    else
+    {
+        return ETH_ERROR;
+    }
+}
+
+/* MAC functions */
+
+/*!
+ * @brief  Enable the MAC transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMACTransmission(void)
+{
+    ETH->CFG_B.TXEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMACTransmission(void)
+{
+    ETH->CFG_B.TXEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMACReceiver(void)
+{
+    ETH->CFG_B.RXEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMACReceiver(void)
+{
+    ETH->CFG_B.RXEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the ETH flow control busy status
+ *
+ * @param  None
+ *
+ * @retval SET or RESET
+ */
+uint8_t ETH_ReadFlowControlBusyStatus(void)
+{
+    return ETH->FCTRL_B.FCTRLB;
+}
+
+/*!
+ * @brief  Set a Pause Control Frame (Full-duplex only).
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_SetPauseControlFrame(void)
+{
+    ETH->FCTRL_B.FCTRLB = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC Back Pressure operation activation (Half-duplex only).
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableBackPressureActivation(void)
+{
+    ETH->FCTRL_B.FCTRLB = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Back Pressure operation activation (Half-duplex only).
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableBackPressureActivation(void)
+{
+    ETH->FCTRL_B.FCTRLB = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the specified ETH MAC flag
+ *
+ * @param  flag: Ethernet MAC flag:
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_FLAG_TST  : Time stamp trigger flag
+ *           @arg ETH_MAC_FLAG_MMCT : MMC transmit flag
+ *           @arg ETH_MAC_FLAG_MMCR : MMC receive flag
+ *           @arg ETH_MAC_FLAG_MMC  : MMC flag
+ *           @arg ETH_MAC_FLAG_PMT  : PMT flag
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadMACFlagStatus(ETH_MAC_FLAG_T flag)
+{
+    return (ETH->ISTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Enable the specified ETH MAC interrupts.
+ *
+ * @param  interrupt: Ethernet MAC interrupt flag:
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_MAC_INT_TST : Time stamp trigger interrupt
+ *           @arg ETH_MAC_INT_PMT : PMT interrupt
+ *
+ * @retval None
+ */
+void ETH_EnableMACInterrupt(uint32_t interrupt)
+{
+    ETH->IMASK |= interrupt;
+}
+
+/*!
+ * @brief  Disable the specified ETH MAC interrupts.
+ *
+ * @param  interrupt: Ethernet MAC interrupt flag:
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_MAC_INT_TST : Time stamp trigger interrupt
+ *           @arg ETH_MAC_INT_PMT : PMT interrupt
+ *
+ * @retval None
+ */
+void ETH_DisableMACInterrupt(uint32_t interrupt)
+{
+    ETH->IMASK &= (~(uint32_t)interrupt);
+}
+
+/*!
+ * @brief  Config the MAC address.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS0 : MAC Address0
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  addr: Pointer on MAC address buffer data (6 bytes).
+ *
+ * @retval None
+ */
+void ETH_ConfigMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr)
+{
+    uint32_t temp;
+
+    temp = ((uint32_t)addr[5] << 8) | (uint32_t)addr[4];
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+
+    temp = ((uint32_t)addr[3] << 24) | ((uint32_t)addr[2] << 16) | ((uint32_t)addr[1] << 8) | addr[0];
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + macAddr)) = temp;
+}
+
+/*!
+ * @brief  Read the MAC address.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS0 : MAC Address0
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  addr: Pointer on MAC address buffer data (6 bytes).
+ *
+ * @retval None
+ */
+void ETH_ReadMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr)
+{
+    uint32_t temp;
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr));
+
+    addr[5] = ((temp >> 8) & 0xFF);
+    addr[4] = (temp & 0xFF);
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + macAddr));
+    addr[3] = ((temp >> 24) & 0xFF);
+    addr[2] = ((temp >> 16) & 0xFF);
+    addr[1] = ((temp >> 8)  & 0xFF);
+    addr[0] = (temp & 0xFF);
+}
+
+/*!
+ * @brief  Enable address filters module uses the MAC address for perfect filtering.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @retval None
+ */
+void ETH_EnableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr)
+{
+    __IO uint32_t temp = 0;
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= BIT31;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+}
+
+/*!
+ * @brief  Disable address filters module uses the MAC address for perfect filtering.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @retval None
+ */
+void ETH_DisableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr)
+{
+    __IO uint32_t temp = 0;
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) &= (~BIT31);
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+}
+
+/*!
+ * @brief  Config the filter type for the MAC address
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  filter: Comparison with the SA/DA fields of the received frame.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESSFILTER_SA : MAC Address is used to compare with the
+ *                                           SA fields of the received frame.
+ *           @arg ETH_MAC_ADDRESSFILTER_DA : MAC Address is used to compare with the
+ *                                           DA fields of the received frame.
+ * @retval None
+ */
+void ETH_ConfigMACAddressFilter(ETH_MAC_ADDRESS_T macAddr, ETH_MAC_ADDRESSFILTER_T filter)
+{
+    if(filter == ETH_MAC_ADDRESSFILTER_SA)
+    {
+        (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= ETH_MAC_ADDRESSFILTER_SA;
+    }
+    else
+    {
+        (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= ETH_MAC_ADDRESSFILTER_DA;
+    }
+
+}
+
+/*!
+ * @brief  Config the filter type for the ETH MAC address.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  MaskByte: specifies the used address bytes for comparison
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE6 : Mask MAC Address high reg bits [15:8].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE5 : Mask MAC Address high reg bits [7:0].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE4 : Mask MAC Address low reg bits [31:24].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE3 : Mask MAC Address low reg bits [23:16].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE2 : Mask MAC Address low reg bits [15:8].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE1 : Mask MAC Address low reg bits [7:0].
+ *
+ * @retval None
+ */
+void ETH_ConfigMACAddressMaskBytesFilter(ETH_MAC_ADDRESS_T macAddr, uint32_t maskByte)
+{
+    __IO uint32_t temp = 0;
+
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) &=(~(uint32_t)0x3F000000);
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr));
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+
+    /* Set the selected Filter mask bytes */
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= maskByte;
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr));
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+}
+
+/** DMA Descriptors functions */
+
+/*!
+ * @brief  Config the DMA Rx descriptors in chain mode.
+ *
+ * @param  DMARxDescTab: Pointer on the first Rx desc list
+ *
+ * @param  rxBuff: Pointer on the first RxBuffer list
+ *
+ * @param  rxBuffcount: Number of the used Rx desc in the list
+ *
+ * @retval None
+ */
+void ETH_ConfigDMARxDescChain(ETH_DMADescConfig_T *DMARxDescTab, uint8_t *rxBuff, uint32_t rxBuffcount)
+{
+    uint32_t i = 0;
+    ETH_DMADescConfig_T *DMARxDesc;
+    DMARxDescToGet = DMARxDescTab;
+
+    for(i=0; i< rxBuffcount; i++)
+    {
+        DMARxDesc = DMARxDescTab+i;
+        DMARxDesc->Status = ETH_DMARXDESC_OWN;
+        DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RXCH | ETH_RX_BUF_SIZE;
+        DMARxDesc->Buffer1Addr = (uint32_t)(&rxBuff[i*ETH_RX_BUF_SIZE]);
+        if(i < (rxBuffcount-1))
+        {
+            DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1);
+        }
+        else
+        {
+            DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
+        }
+    }
+
+
+    ETH->DMARXDLADDR = (uint32_t) DMARxDescTab;
+    DMARxFraminfos =&RxFrameDescriptor;
+}
+
+/*!
+ * @brief  Initializes the DMA Tx descriptors in chain mode.
+ *
+ * @param  DMATxDescTab: Pointer on the first Tx desc list
+ *
+ * @param  txBuff: Pointer on the first TxBuffer list
+ *
+ * @param  txBuffcount: Number of the used Tx desc in the list
+ *
+ * @retval None
+  */
+void ETH_ConfigDMATxDescChain(ETH_DMADescConfig_T *DMATxDescTab, uint8_t* txBuff, uint32_t txBuffcount)
+{
+    uint32_t i = 0;
+    ETH_DMADescConfig_T *DMATxDesc;
+    DMATxDescToSet = DMATxDescTab;
+
+    for(i=0; i< txBuffcount; i++)
+    {
+        DMATxDesc = DMATxDescTab+i;
+        DMATxDesc->Status = ETH_DMATXDESC_TXCH;
+        DMATxDesc->Buffer1Addr = (uint32_t)(&txBuff[i*ETH_TX_BUF_SIZE]);
+        if(i < (txBuffcount-1))
+        {
+            DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1);
+        }
+        else
+        {
+            DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab);
+        }
+    }
+
+    ETH->DMATXDLADDR = (uint32_t) DMATxDescTab;
+}
+
+/*!
+ * @brief  This function polls for a frame receiver
+ *
+ * @param  None
+ *
+ * @retval Returns 1 when a frame is received, 0 if none.
+ */
+uint32_t ETH_CheckReceivedFrame(void)
+{
+    if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+        ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) != (uint32_t)RESET))
+    {
+        DMARxFraminfos->segCount++;
+        if(DMARxFraminfos->segCount == 1)
+        {
+            DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+        }
+        DMARxFraminfos->LS_RxDesc = DMARxDescToGet;
+        return 1;
+    }
+    else if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+    {
+        DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+        DMARxFraminfos->LS_RxDesc = NULL;
+        DMARxFraminfos->segCount  = 1;
+        DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+    }
+    else if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) == (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+    {
+        (DMARxFraminfos->segCount) ++;
+        DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+    }
+    return 0;
+}
+
+/*!
+ * @brief  Prepares DMA Tx descriptors to transmit an ethernet frame
+ *
+ * @param  FrameLength : length of the frame to send
+ *
+ * @retval ETH_ERROR or ETH_SUCCESS
+ */
+uint32_t ETH_Transmit_Descriptors(u16 frameLength)
+{
+    uint32_t count=0, size=0, i=0;
+    __IO ETH_DMADescConfig_T  *DMATxDesc;
+
+    if((DMATxDescToSet->Status & ETH_DMATXDESC_OWN) == SET)
+    {
+        return ETH_ERROR;
+    }
+
+    DMATxDesc = DMATxDescToSet;
+
+    if(frameLength > ETH_TX_BUF_SIZE)
+    {
+        count = frameLength/ETH_TX_BUF_SIZE;
+        if(frameLength%ETH_TX_BUF_SIZE) count++;
+    }
+    else count =1;
+
+    if(count == 1)
+    {
+        DMATxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
+        DMATxDesc->ControlBufferSize = (frameLength & ETH_DMATXDESC_TXBS1);
+        DMATxDesc->Status |= ETH_DMATXDESC_OWN;
+        DMATxDesc = (ETH_DMADescConfig_T*) (DMATxDesc->Buffer2NextDescAddr);
+    }
+    else
+    {
+        for(i=0; i<count; i++)
+        {
+            DMATxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
+
+            if(i==0)
+            {
+                DMATxDesc->Status |= ETH_DMATXDESC_FS;
+            }
+            DMATxDesc->ControlBufferSize =(ETH_TX_BUF_SIZE & ETH_DMATXDESC_TXBS1);
+
+            if(i== (count-1))
+            {
+                DMATxDesc->Status |= ETH_DMATXDESC_LS;
+                size = frameLength - (count-1)*ETH_TX_BUF_SIZE;
+                DMATxDesc->ControlBufferSize =(size & ETH_DMATXDESC_TXBS1);
+            }
+
+            DMATxDesc->Status |= ETH_DMATXDESC_OWN;
+            DMATxDesc = (ETH_DMADescConfig_T*) (DMATxDesc->Buffer2NextDescAddr);
+        }
+    }
+    DMATxDescToSet = DMATxDesc;
+
+    if(ETH->DMASTS_B.TXBU == SET)
+    {
+        ETH->DMASTS = BIT2;
+        ETH->DMATXPD = 0;
+    }
+
+    return ETH_SUCCESS;
+}
+
+/*!
+ * @brief  Read the received frame.
+ *
+ * @param  none
+ *
+ * @retval Structure of type ETH_Frame_T
+ */
+ETH_Frame_T ETH_ReadReceivedFrame(void)
+{
+    uint32_t frameLength = 0;
+    ETH_Frame_T frame = {0,0,0};
+
+    frameLength = ((DMARxDescToGet->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4;
+    frame.length = frameLength;
+
+    frame.descriptor = DMARxFraminfos->FS_RxDesc;
+    frame.buffer = (DMARxFraminfos->FS_RxDesc)->Buffer1Addr;
+    DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+
+    return(frame);
+}
+
+/*!
+ * @brief  Read ETH DMA Tx Descriptor flag.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  flag: Specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMATXDESC_OWN   : Descriptor is owned by DMA engine
+ *           @arg ETH_DMATXDESC_INTC  : Interrupt on completion
+ *           @arg ETH_DMATXDESC_LS    : Last Segment
+ *           @arg ETH_DMATXDESC_FS    : First Segment
+ *           @arg ETH_DMATXDESC_DISC  : Disable CRC
+ *           @arg ETH_DMATXDESC_DISP  : Disable Pad
+ *           @arg ETH_DMATXDESC_TXTSEN: Transmit Time Stamp Enable
+ *           @arg ETH_DMATXDESC_TXENDR: Transmit End of Ring
+ *           @arg ETH_DMATXDESC_TXCH  : Second Address Chained
+ *           @arg ETH_DMATXDESC_TXTSS : Tx Time Stamp Status
+ *           @arg ETH_DMATXDESC_IHERR : IP Header Error
+ *           @arg ETH_DMATXDESC_ERRS  : Error summary
+ *           @arg ETH_DMATXDESC_JTO   : Jabber Timeout
+ *           @arg ETH_DMATXDESC_FF    : Frame Flushed: DMA/MTL flushed the frame due to SW flush
+ *           @arg ETH_DMATXDESC_IPERR : Payload Checksum Error
+ *           @arg ETH_DMATXDESC_LSC   : Loss of Carrier: carrier lost during transmission
+ *           @arg ETH_DMATXDESC_NC    : No Carrier: no carrier signal from the transceiver
+ *           @arg ETH_DMATXDESC_LC    : Late Collision: transmission aborted due to collision
+ *           @arg ETH_DMATXDESC_EC    : Excessive Collision: transmission aborted after 16 collisions
+ *           @arg ETH_DMATXDESC_VLANF : VLAN Frame
+ *           @arg ETH_DMATXDESC_CCNT  : Collision Count
+ *           @arg ETH_DMATXDESC_EDEF  : Excessive Deferral
+ *           @arg ETH_DMATXDESC_UFERR : Underflow Error: late data arrival from the memory
+ *           @arg ETH_DMATXDESC_DEF   : Deferred Bit
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMATxDescFlagStatus(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_FLAG_T flag)
+{
+    return (DMATxDesc->Status & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Returns ETH DMA Tx Descriptor collision count.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval The Transmit descriptor collision counter value.
+ */
+uint32_t ETH_ReadDMATxDescCollisionCount(ETH_DMADescConfig_T *DMATxDesc)
+{
+    return ((DMATxDesc->Status & ETH_DMATXDESC_CCNT) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT);
+}
+
+/*!
+ * @brief  Config the ETH DMA Tx Descriptor Own bit.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescOwnBit(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_OWN;
+}
+
+/*!
+ * @brief  Enable the ETH DMA Tx Descriptor Transmit interrupt.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_INTC;
+}
+
+/*!
+ * @brief  Disable the ETH DMA Tx Descriptor Transmit interrupt.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_INTC);
+}
+
+/*!
+ * @brief  Config Tx descriptor as last or first segment
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  frameSegment: Tx desc contain last or first segment.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMATXDESC_LASTSEGMENTS : Actual Tx desc contain last segment
+ *           @arg ETH_DMATXDESC_FIRSTSEGMENT : Actual Tx desc contain first segment
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescFrameSegment(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_SEGMENTS_T frameSegment)
+{
+    DMATxDesc->Status |= frameSegment;
+}
+/*!
+ * @brief  Config ETH DMA Tx Desc Checksum Insertion.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  checksum: specifies is the DMA Tx desc checksum insertion.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMATXDESC_CHECKSUMBYPASS              : Checksum bypass
+ *           @arg ETH_DMATXDESC_CHECKSUMIPV4HEADER          : IPv4 header checksum
+ *           @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT   : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
+ *           @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL      : TCP/UDP/ICMP checksum fully in hardware including pseudo header
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescChecksumInsertion(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_CHECKSUMB_T checksum)
+{
+    DMATxDesc->Status |= checksum;
+}
+
+/*!
+ * @brief  Enable the DMA Tx Desc CRC.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_DISC);
+}
+
+/*!
+ * @brief  Disable the DMA Tx Desc CRC.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_DISC;
+}
+
+/*!
+ * @brief  Enable the DMA Tx Desc second address chained.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_TXCH;
+}
+
+/*!
+ * @brief  Disable the DMA Tx Desc second address chained.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &=(~(uint32_t)ETH_DMATXDESC_TXCH);
+}
+
+/*!
+ * @brief  Enable the DMA Tx Desc padding for frame shorter than 64 bytes.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_DISP);
+}
+
+/*!
+ * @brief  Disable the DMA Tx Desc padding for frame shorter than 64 bytes.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_DISP;
+}
+
+/*!
+ * @brief  Config the ETH DMA Tx Desc buffer1 and buffer2 sizes.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  bufferSize1: specifies the Tx desc buffer1 size.
+ *
+ * @param  bufferSize2: specifies the Tx desc buffer2 size.
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescBufferSize(ETH_DMADescConfig_T *DMATxDesc, uint32_t bufferSize1, uint32_t bufferSize2)
+{
+    DMATxDesc->ControlBufferSize |= (bufferSize1 | (bufferSize2 << ETH_DMATXDESC_BUFFER2_SIZESHIFT));
+}
+
+/*!
+ * @brief  Checks whether the specified ETHERNET Rx Desc flag is set or not.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+
+ * @param  flag: specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMARXDESC_OWN    :    Descriptor is owned by DMA engine
+ *           @arg ETH_DMARXDESC_ADDRF  :    DA Filter Fail for the rx frame
+ *           @arg ETH_DMARXDESC_ERRS   :    Error summary
+ *           @arg ETH_DMARXDESC_DESERR :    Descriptor error: no more descriptors for receive frame
+ *           @arg ETH_DMARXDESC_SADDRF :    SA Filter Fail for the received frame
+ *           @arg ETH_DMARXDESC_LERR   :    Frame size not matching with length field
+ *           @arg ETH_DMARXDESC_OFERR  :    Overflow Error: Frame was damaged due to buffer overflow
+ *           @arg ETH_DMARXDESC_VLANF  :    VLAN Tag: received frame is a VLAN frame
+ *           @arg ETH_DMARXDESC_FDES   :    First descriptor of the frame
+ *           @arg ETH_DMARXDESC_LDES   :    Last descriptor of the frame
+ *           @arg ETH_DMARXDESC_IPV4HCE:    IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error
+ *           @arg ETH_DMARXDESC_LC     :    Late collision occurred during reception
+ *           @arg ETH_DMARXDESC_FT     :    Frame type - Ethernet, otherwise 802.3
+ *           @arg ETH_DMARXDESC_RXWDTTO:    Receive Watchdog Timeout: watchdog timer expired during reception
+ *           @arg ETH_DMARXDESC_RERR   :    Receive error: error reported by MII interface
+ *           @arg ETH_DMARXDESC_DERR   :    Dribble bit error: frame contains non int multiple of 8 bits
+ *           @arg ETH_DMARXDESC_CERR   :    CRC error
+ *           @arg ETH_DMARXDESC_MAMPCE :    Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMARxDescFlagStatus(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_FLAG_T flag)
+{
+    return (DMARxDesc->Status & flag) ? SET : RESET;
+}
+
+#if USE_ENHANCED_DMA_DESCRIPTORS
+/*!
+ * @brief  Checks whether the specified ETHERNET PTP Rx Desc extended flag is set or not.
+ *
+ * @param  DMAPTPRxDesc: pointer on a DMA PTP Rx descriptor
+ *
+ * @param  flag: specifies the extended flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMAPTPRXDESC_PTPV  :  PTP version
+ *           @arg ETH_DMAPTPRXDESC_PTPFT :  PTP frame type
+ *           @arg ETH_DMAPTPRXDESC_PTPMT :  PTP message type
+ *           @arg ETH_DMAPTPRXDESC_IPV6P :  IPv6 packet received
+ *           @arg ETH_DMAPTPRXDESC_IPV4P :  IPv4 packet received
+ *           @arg ETH_DMAPTPRXDESC_IPCBP :  IP checksum bypassed
+ *           @arg ETH_DMAPTPRXDESC_IPPERR:  IP payload error
+ *           @arg ETH_DMAPTPRXDESC_IPHERR:  IP header error
+ *           @arg ETH_DMAPTPRXDESC_IPPT  :  IP payload type
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAPTPRxDescExtendedFlagStatus(ETH_DMADescConfig_T *DMAPTPRxDesc, ETH_DMAPTPRXDESC_FLAG_T flag)
+{
+    return (DMAPTPRxDesc->Status & flag) ? SET : RESET;
+}
+#endif
+
+/*!
+ * @brief  Config the ETH DMA Rx Desc Own bit.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval None
+ */
+void ETH_ConfigDMARxDescOwnBit(ETH_DMADescConfig_T *DMARxDesc)
+{
+    DMARxDesc->Status |= ETH_DMARXDESC_OWN;
+}
+
+/*!
+ * @brief  Returns the ETH DMA Rx descriptor frame length.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval The Rx descriptor received frame length.
+ */
+uint32_t ETH_ReadDMARxDescFrameLength(ETH_DMADescConfig_T *DMARxDesc)
+{
+    return ((DMARxDesc->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT);
+}
+
+/*!
+ * @brief  Enable the ETH DMA Rx Desc receive interrupt.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMARxDesc)
+{
+    DMARxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARXDESC_DINTC);
+}
+
+/*!
+ * @brief  Disable the ETH DMA Rx Desc receive interrupt.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMARxDesc)
+{
+    DMARxDesc->ControlBufferSize |= ETH_DMARXDESC_DINTC;
+}
+
+/*!
+ * @brief  Returns the ETH DMA Rx Desc buffer size.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @param  buffer: specifies the DMA Rx Desc buffer.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMARxDesc_Buffer1 : DMA Rx Desc Buffer1
+ *           @arg ETH_DMARxDesc_Buffer2 : DMA Rx Desc Buffer2
+ *
+ * @retval The Receive descriptor frame length.
+ */
+uint32_t ETH_ReadDMARxDescBufferSize(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_BUFFER_T buffer)
+{
+    if(buffer == ETH_DMARXDESC_BUFFER1)
+    {
+        return (DMARxDesc->ControlBufferSize & ETH_DMARXDESC_RXBS1);
+    }
+    else
+    {
+        return ((DMARxDesc->ControlBufferSize & ETH_DMARXDESC_RXBS2) >> ETH_DMARXDESC_BUFFER2_SIZESHIFT);
+    }
+}
+
+/*!
+ * @brief  Read frame using DMA Receive interrupt.
+ *         it allows scanning of Rx descriptors to get the the receive frame
+ *
+ * @param  None
+ *
+ * @retval Structure of type ETH_Frame_T
+ */
+ETH_Frame_T ETH_ReadReceivedFrameInterrupt(void)
+{
+    __IO uint32_t count = 0;
+    ETH_Frame_T frame = {0,0,0};
+
+    while (((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET)&& (count < ETH_RXBUFNB))
+    {
+        count ++;
+
+        if(((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET)&&
+        ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+        {
+            DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+            DMARxFraminfos->segCount = 1;
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+        }
+        else if (((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) == (uint32_t)RESET)&&
+                ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+        {
+            (DMARxFraminfos->segCount) ++;
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+        }
+        else
+        {
+            DMARxFraminfos->LS_RxDesc = DMARxDescToGet;
+            (DMARxFraminfos->segCount)++;
+
+            if ((DMARxFraminfos->segCount)==1)
+            DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+
+            frame.length = ((DMARxDescToGet->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4;
+
+            if(DMARxFraminfos->segCount >1)
+            {
+                frame.buffer = (DMARxFraminfos->FS_RxDesc)->Buffer1Addr;
+            }
+            else
+            {
+                frame.buffer = DMARxDescToGet->Buffer1Addr;
+            }
+
+            frame.descriptor = DMARxFraminfos->FS_RxDesc;
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+
+            return (frame);
+        }
+    }
+    return (frame);
+}
+
+/** DMA functions */
+
+/*!
+ * @brief  Read the ETH DMA flag.
+ *
+ * @param  flag: specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMA_FLAG_TST                  : Time-stamp trigger flag
+ *           @arg ETH_DMA_FLAG_PMT                  : PMT flag
+ *           @arg ETH_DMA_FLAG_MMC                  : MMC flag
+ *           @arg ETH_DMA_FLAG_DATATRANSFERERROR    : Error bits 0-data buffer, 1-desc. access
+ *           @arg ETH_DMA_FLAG_READWRITEERROR       : Error bits 0-write trnsf, 1-read transfr
+ *           @arg ETH_DMA_FLAG_ACCESSERROR          : Error bits 0-Rx DMA, 1-Tx DMA
+ *           @arg ETH_DMA_FLAG_NIS                  : Normal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_AIS                  : Abnormal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_ER                   : Early receive flag
+ *           @arg ETH_DMA_FLAG_FBE                  : Fatal bus error flag
+ *           @arg ETH_DMA_FLAG_ET                   : Early transmit flag
+ *           @arg ETH_DMA_FLAG_RWT                  : Receive watchdog timeout flag
+ *           @arg ETH_DMA_FLAG_RPS                  : Receive process stopped flag
+ *           @arg ETH_DMA_FLAG_RBU                  : Receive buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_RX                   : Receive flag
+ *           @arg ETH_DMA_FLAG_TU                   : Underflow flag
+ *           @arg ETH_DMA_FLAG_RO                   : Overflow flag
+ *           @arg ETH_DMA_FLAG_TJT                  : Transmit jabber timeout flag
+ *           @arg ETH_DMA_FLAG_TBU                  : Transmit buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_TPS                  : Transmit process stopped flag
+ *           @arg ETH_DMA_FLAG_TX                   : Transmit flag
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAFlagStatus(ETH_DMA_FLAG_T flag)
+{
+    return (ETH->DMASTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Clears the ETH DMA flag.
+ *
+ * @param  flag: specifies the flag to clear.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_ER  : Early receive flag
+ *           @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
+ *           @arg ETH_DMA_FLAG_ET  : Early transmit flag
+ *           @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
+ *           @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
+ *           @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_RX  : Receive flag
+ *           @arg ETH_DMA_FLAG_TU  : Transmit Underflow flag
+ *           @arg ETH_DMA_FLAG_RO  : Receive Overflow flag
+ *           @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
+ *           @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
+ *           @arg ETH_DMA_FLAG_TX  : Transmit flag
+ *
+ * @retval None
+ */
+void ETH_ClearDMAFlag(uint32_t flag)
+{
+    ETH->DMASTS = flag;
+}
+
+/*!
+ * @brief  Read the ETH DMA interrupt flag.
+ *
+ * @param  flag: specifies the interrupt source to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMA_INT_TST : Time-stamp trigger interrupt
+ *           @arg ETH_DMA_INT_PMT : PMT interrupt
+ *           @arg ETH_DMA_INT_MMC : MMC interrupt
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAIntFlag(ETH_DMA_INT_T flag)
+{
+    return (ETH->DMASTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Clears the ETH DMA interrupt flag.
+ *
+ * @param  flag: specifies the interrupt flag to clear.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Transmit Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Receive Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval None
+ */
+void ETH_ClearDMAIntFlag(uint32_t flag)
+{
+    ETH->DMASTS = flag;
+}
+
+/*!
+ * @brief  Returns the ETH DMA Transmit Process State.
+ *
+ * @param  None
+
+ * @retval The new ETH DMA Transmit Process State:
+ *         This can be one of the following values:
+ *           - ETH_DMA_TRANSMITPROCESS_STOPPED   : Stopped - Reset or Stop Tx Command issued
+ *           - ETH_DMA_TRANSMITPROCESS_FETCHING  : Running - fetching the Tx descriptor
+ *           - ETH_DMA_TRANSMITPROCESS_WAITING   : Running - waiting for status
+ *           - ETH_DMA_TRANSMITPROCESS_READING   : Running - reading the data from host memory
+ *           - ETH_DMA_TRANSMITPROCESS_SUSPENDED : Suspended - Tx Descriptor unavailable
+ *           - ETH_DMA_TRANSMITPROCESS_CLOSING   : Running - closing Rx descriptor
+ */
+uint32_t ETH_ReadTransmitProcessState(void)
+{
+    return ((uint32_t)(ETH->DMASTS & BIT0) ? SET : RESET);
+}
+
+/*!
+ * @brief  Returns the ETH DMA Receive Process State.
+ *
+ * @param  None
+ *
+ * @retval The new ETH DMA Receive Process State:
+ *         This can be one of the following values:
+ *           - ETH_DMA_RECEIVEPROCESS_STOPPED   : Stopped - Reset or Stop Rx Command issued
+ *           - ETH_DMA_RECEIVEPROCESS_FETCHING  : Running - fetching the Rx descriptor
+ *           - ETH_DMA_RECEIVEPROCESS_WAITING   : Running - waiting for packet
+ *           - ETH_DMA_RECEIVEPROCESS_SUSPENDED : Suspended - Rx Descriptor unavailable
+ *           - ETH_DMA_RECEIVEPROCESS_CLOSING   : Running - closing descriptor
+ *           - ETH_DMA_RECEIVEPROCESS_QUEUING   : Running - queuing the receive frame into host memory
+ */
+uint32_t ETH_ReadReceiveProcessState(void)
+{
+    return ((uint32_t)(ETH->DMASTS & BIT6) ? SET : RESET);
+}
+
+/*!
+ * @brief  Flush the ETH transmit FIFO.
+ *
+ * @param  None
+ *
+ * @retval None
+  */
+void ETH_FlushTransmitFIFO(void)
+{
+    ETH->DMAOPMOD_B.FTXF = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the ETH flush transmit FIFO status.
+ *
+ * @param  None
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadFlushTransmitFIFOStatus(void)
+{
+    return ETH->DMAOPMOD_B.FTXF;
+}
+
+/*!
+ * @brief  Enable the DMA transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableDMATransmission(void)
+{
+    ETH->DMAOPMOD_B.STTX = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the DMA transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableDMATransmission(void)
+{
+    ETH->DMAOPMOD_B.STTX = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the DMA receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableDMAReceiver(void)
+{
+    ETH->DMAOPMOD_B.STRX = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the DMA receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableDMAReceiver(void)
+{
+    ETH->DMAOPMOD_B.STRX = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the ETH DMA interrupts.
+ *
+ * @param  interrupt: specifies the ETH DMA interrupt sources.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval None
+ */
+void ETH_EnableDMAInterrupt(uint32_t interrupt)
+{
+    ETH->DMAINTEN |= interrupt;
+}
+
+/*!
+ * @brief  Disable the ETH DMA interrupts.
+ *
+ * @param  interrupt: specifies the ETH DMA interrupt sources.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval None
+ */
+void ETH_DisableDMAInterrupt(uint32_t interrupt)
+{
+    ETH->DMAINTEN &= ((uint32_t)~interrupt);
+}
+
+/*!
+ * @brief  Read the ETH DMA overflow flag.
+ *
+ * @param  overflow: specifies the DMA overflow flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMA_OVERFLOW_RXFIFOCOUNTER        : Overflow for FIFO Overflows Counter
+ *           @arg ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER   : Overflow for Buffer Unavailable Missed Frame Counter
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAOverflowStatus(ETH_DMA_OVERFLOW_T overflow)
+{
+    return (ETH->DMAMFABOCNT & overflow) ? SET : RESET;
+}
+
+/*!
+ * @brief  Read the ETH DMA Rx Overflow Missed Frame Counter value.
+ *
+ * @param  None
+ *
+ * @retval The value of Rx overflow Missed Frame Counter.
+ */
+uint32_t ETH_ReadRxOverflowMissedFrameCounter(void)
+{
+    return (uint32_t)(ETH->DMAMFABOCNT_B.AMISFCNT);
+}
+
+/*!
+ * @brief  Read the ETH DMA Buffer Unavailable Missed Frame Counter value.
+ *
+ * @param  None
+ *
+ * @retval The value of Buffer unavailable Missed Frame Counter.
+ */
+uint32_t ETH_ReadBufferUnavailableMissedFrameCounter(void)
+{
+    return (uint32_t)(ETH->DMAMFABOCNT_B.MISFCNT);
+}
+
+/*!
+ * @brief  Read the ETH DMA DMAHTXD register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current Tx desc start address.
+ */
+uint32_t ETH_ReadCurrentTxDescStartAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHTXD));
+}
+
+/*!
+ * @brief  Read the ETHERNET DMA DMAHRXD register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current Rx desc start address.
+ */
+uint32_t ETH_ReadCurrentRxDescStartAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHRXD));
+}
+
+/*!
+ * @brief  Read the ETH DMA DMAHTXBADDR register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current transmit descriptor data buffer address.
+ */
+uint32_t ETH_ReadCurrentTxBufferAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHTXBADDR));
+}
+
+/*!
+ * @brief  Read the ETH DMA DMAHRXBADDR register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current receive descriptor data buffer address.
+ */
+uint32_t ETH_ReadCurrentRxBufferAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHRXBADDR));
+}
+
+/*!
+ * @brief  Reset the DMA Transmission by writing to the DmaTxPollDemand register
+ *
+ * @param  None
+
+ * @retval None.
+ */
+void ETH_ResetDMATransmission(void)
+{
+    ETH->DMATXPD = 0;
+}
+
+/*!
+ * @brief  Reset the DMA Transmission by writing to the DmaRxPollDemand register
+ *
+ * @param  None
+ *
+ * @retval None.
+ */
+void ETH_ResetDMAReception(void)
+{
+    ETH->DMARXPD = 0;
+}
+
+/*!
+ * @brief  Config the DMA Receive status watchdog timer register value
+ *
+ * @param  value: watchdog timer register value
+ *
+ * @retval None
+ */
+void ETH_ConfigReceiveWatchdogTimer(uint8_t value)
+{
+    ETH->DMARXFLGWDT_B.RXWDTCNT = value;
+}
+
+/** Power Management(PMT) functions */
+
+/*!
+ * @brief  Reset Wakeup frame filter register pointer.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_ResetWakeUpFrameFilterRegisterPointer(void)
+{
+    ETH->PMTCTRLSTS_B.WKUPFRST = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Populates the remote wakeup frame registers.
+ *
+ * @param  buffer: WakeUp Frame Filter Register buffer data (8 words).
+ *
+ * @retval None
+ */
+void ETH_ConfigWakeUpFrameFilterRegister(uint32_t *buffer)
+{
+    uint32_t i = 0;
+    __IO uint32_t temp = 0;
+
+    for(i = 0; i < ETH_WAKEUP_REGISTER_LENGTH; i++)
+    {
+        ETH->WKUPFFL = buffer[i];
+
+        temp = ETH->WKUPFFL;
+        ETH_Delay(ETH_REG_WRITE_DELAY);
+        ETH->WKUPFFL = temp;
+    }
+}
+
+/*!
+ * @brief  Enable any unicast packet filtered by the MAC address
+ *         recognition to be a wake-up frame.
+ *
+ * @retval None
+ */
+void ETH_EnableGlobalUnicastWakeUp(void)
+{
+    ETH->PMTCTRLSTS_B.GUN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable any unicast packet filtered by the MAC address
+ *         recognition to be a wake-up frame.
+ *
+ * @retval None
+ */
+void ETH_DisableGlobalUnicastWakeUp(void)
+{
+    ETH->PMTCTRLSTS_B.GUN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the ETH PMT flag.
+ *
+ * @param  flag: specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset
+ *           @arg ETH_PMT_FLAG_WUFR    : Wake-Up Frame Received
+ *           @arg ETH_PMT_FLAG_MPR     : Magic Packet Received
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadPMTFlagStatus(ETH_PMT_FLAG_T flag)
+{
+    return (ETH->PMTCTRLSTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Enable the MAC Wake-Up Frame Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableWakeUpFrameDetection(void)
+{
+    ETH->PMTCTRLSTS_B.WKUPFEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Wake-Up Frame Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableWakeUpFrameDetection(void)
+{
+    ETH->PMTCTRLSTS_B.WKUPFEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC Magic Packet Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMagicPacketDetection(void)
+{
+    ETH->PMTCTRLSTS_B.MPEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Magic Packet Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMagicPacketDetection(void)
+{
+    ETH->PMTCTRLSTS_B.MPEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC Power Down.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnablePowerDown(void)
+{
+    ETH->PMTCTRLSTS_B.PD = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Power Down.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisablePowerDown(void)
+{
+    ETH->PMTCTRLSTS_B.PD = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/** MMC functions */
+
+/**
+  * @brief  Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16)
+  * @param  None
+  * @retval None
+  */
+void ETH_PresetMMCCounterFull(void)
+{
+    ETH->CTRL_B.MCNTP = SET;
+    ETH->CTRL_B.MCNTVALP = SET;
+}
+
+/**
+  * @brief  Preset and Initialize the MMC counters to almost-hal value: 0x7FFF_FFF0 (half - 16)
+  * @param  None
+  * @retval None
+  */
+void ETH_PresetMMCCounterHalf(void)
+{
+    ETH->CTRL_B.MCNTP = SET;
+    ETH->CTRL_B.MCNTVALP = RESET;
+}
+
+/*!
+ * @brief  Enable the MMC Counter Freeze.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMMCCounterFreeze(void)
+{
+    ETH->CTRL_B.MCNTF = SET;
+}
+
+/*!
+ * @brief  Disable the MMC Counter Freeze.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMMCCounterFreeze(void)
+{
+    ETH->CTRL_B.MCNTF = RESET;
+}
+
+/*!
+ * @brief  Enable the MMC Reset On Read.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMMCResetOnRead(void)
+{
+    ETH->CTRL_B.RSTOR = SET;
+}
+
+/*!
+ * @brief  Disable the MMC Reset On Read.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMMCResetOnRead(void)
+{
+    ETH->CTRL_B.RSTOR = RESET;
+}
+
+/*!
+ * @brief  Enble the MMC Counter Stop Rollover.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMMCCounterRollover(void)
+{
+    ETH->CTRL_B.CNTSTOPRO = RESET;
+}
+
+/*!
+ * @brief  Disable the MMC Counter Stop Rollover.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMMCCounterRollover(void)
+{
+    ETH->CTRL_B.CNTSTOPRO = SET;
+}
+
+/**
+  * @brief  Resets the MMC Counters.
+  * @param  None
+  * @retval None
+  */
+void ETH_ResetMMCCounters(void)
+{
+    ETH->CTRL_B.CNTRST = SET;
+}
+
+/*!
+ * @brief  Enable the ETH MMC interrupts.
+ *
+ * @param  interrupt: specifies the ETH MMC interrupt sources.
+ *         This parameter can be any combination of Tx interrupt or
+ *         any combination of Rx interrupt (but not both)of the following values:
+ *           @arg ETH_MMC_INT_TGF   : When Tx good frame counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFAE  : When Rx alignment error counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFCE  : When Rx crc error counter reaches half the maximum value
+ *
+ * @retval None
+ */
+void ETH_EnableMMCInterrupt(uint32_t interrupt)
+{
+   if((interrupt & 0x10000000) == SET)
+   {
+        ETH->RXINTMASK &= (~(uint32_t)interrupt);
+   }
+   else
+   {
+        ETH->TXINTMASK &= (~(uint32_t)interrupt);
+   }
+}
+
+/*!
+ * @brief  Disable the ETH MMC interrupts.
+ *
+ * @param  interrupt: specifies the ETH MMC interrupt sources.
+ *         This parameter can be any combination of Tx interrupt or
+ *         any combination of Rx interrupt (but not both)of the following values:
+ *           @arg ETH_MMC_INT_TGF   : When Tx good frame counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFAE  : When Rx alignment error counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFCE  : When Rx crc error counter reaches half the maximum value
+ *
+ * @retval None
+ */
+void ETH_DisableMMCInterrupt(uint32_t interrupt)
+{
+   if((interrupt & 0x10000000) == SET)
+   {
+        ETH->RXINTMASK |= interrupt;
+   }
+   else
+   {
+        ETH->TXINTMASK |= interrupt;
+   }
+}
+
+/*!
+ * @brief  Read the ETH MMC interrupt flag.
+ *
+ * @param  flag: specifies the ETH MMC interrupt.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MMC_INT_TGF   : When Tx good frame counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFAE  : When Rx alignment error counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFCE  : When Rx crc error counter reaches half the maximum value
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadMMCIntFlag(uint32_t flag)
+{
+    if((flag & 0x10000000) == SET)
+    {
+        return ((((ETH->RXINT & flag) != RESET)) && ((ETH->RXINTMASK & flag) == RESET));
+    }
+    else
+    {
+        return ((((ETH->TXINT & flag) != RESET)) && ((ETH->TXINTMASK & flag) == RESET));
+    }
+}
+
+/*!
+ * @brief  Read the ETH MMC register value.
+ *
+ * @param  MMCReg: specifies the ETH MMC register.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MMC_CTRL      : MMC CTRL register
+ *           @arg ETH_MMC_RXINT     : MMC RXINT register
+ *           @arg ETH_MMC_TXINT     : MMC TXINT register
+ *           @arg ETH_MMC_RXINTMASK : MMC RXINTMASK register
+ *           @arg ETH_MMC_TXINTMASK : MMC TXINTMASK register
+ *           @arg ETH_MMC_TXGFSCCNT : MMC TXGFSCCNT register
+ *           @arg ETH_MMC_TXGFMCCNT : MMC TXGFMCCNT register
+ *           @arg ETH_MMC_TXGFCNT   : MMC TXGFCNT register
+ *           @arg ETH_MMC_RXFCECNT  : MMC RXFCECNT register
+ *           @arg ETH_MMC_RXFAECNT  : MMC RXFAECNT register
+ *           @arg ETH_MMC_RXGUNCNT  : MMC RXGUNCNT register
+ *
+ * @retval Return ETH MMC Register value.
+ */
+uint32_t ETH_ReadMMCRegister(ETH_MMC_REG_T MMCReg)
+{
+    return (*(__IO uint32_t *)(ETH_MAC_BASE + MMCReg));
+}
+
+/**@} end of group ETH_Functions */
+/**@} end of group ETH_Driver */
+/**@} end of group APM32F4xx_ETHDriver */

+ 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 */

Някои файлове не бяха показани, защото твърде много файлове са промени