Browse Source

add gd32f450 bsp

tanek liang 7 years ago
parent
commit
2c056a3aad
100 changed files with 46642 additions and 0 deletions
  1. 265 0
      bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h
  2. 58 0
      bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h
  3. 427 0
      bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s
  4. 640 0
      bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s
  5. 941 0
      bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c
  6. 1790 0
      bsp/gd32450z-eval/Libraries/CMSIS/core_cm4.h
  7. 697 0
      bsp/gd32450z-eval/Libraries/CMSIS/core_cm4_simd.h
  8. 664 0
      bsp/gd32450z-eval/Libraries/CMSIS/core_cmFunc.h
  9. 916 0
      bsp/gd32450z-eval/Libraries/CMSIS/core_cmInstr.h
  10. 461 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h
  11. 652 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h
  12. 55 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h
  13. 168 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h
  14. 240 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h
  15. 121 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h
  16. 200 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h
  17. 380 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h
  18. 1664 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h
  19. 781 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h
  20. 246 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h
  21. 371 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h
  22. 75 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h
  23. 383 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h
  24. 331 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h
  25. 320 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h
  26. 161 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h
  27. 68 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h
  28. 173 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h
  29. 1152 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h
  30. 597 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h
  31. 378 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h
  32. 327 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h
  33. 158 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h
  34. 735 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h
  35. 326 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h
  36. 78 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h
  37. 467 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h
  38. 63 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h
  39. 1042 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c
  40. 863 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c
  41. 101 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c
  42. 358 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c
  43. 650 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c
  44. 122 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c
  45. 341 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c
  46. 820 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c
  47. 3449 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c
  48. 1138 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c
  49. 229 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c
  50. 824 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c
  51. 120 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c
  52. 357 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c
  53. 730 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c
  54. 409 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c
  55. 101 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c
  56. 146 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c
  57. 348 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c
  58. 1281 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c
  59. 1257 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c
  60. 759 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c
  61. 811 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c
  62. 172 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c
  63. 1892 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c
  64. 443 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c
  65. 144 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c
  66. 952 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c
  67. 122 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_wwdgt.c
  68. 287 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_core.h
  69. 100 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_defines.h
  70. 676 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_regs.h
  71. 188 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_std.h
  72. 54 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_core.h
  73. 31 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_int.h
  74. 70 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_std.h
  75. 283 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_core.h
  76. 45 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_ctrl.h
  77. 46 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_hcs.h
  78. 30 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_int.h
  79. 74 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_std.h
  80. 1132 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usb_core.c
  81. 520 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_core.c
  82. 758 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_int.c
  83. 699 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_std.c
  84. 710 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_core.c
  85. 620 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_ctrl.c
  86. 162 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_hcs.c
  87. 591 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_int.c
  88. 808 0
      bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_std.c
  89. 36 0
      bsp/gd32450z-eval/Libraries/SConscript
  90. 14 0
      bsp/gd32450z-eval/SConscript
  91. 39 0
      bsp/gd32450z-eval/SConstruct
  92. 11 0
      bsp/gd32450z-eval/applications/SConscript
  93. 45 0
      bsp/gd32450z-eval/applications/application.c
  94. 107 0
      bsp/gd32450z-eval/applications/startup.c
  95. 17 0
      bsp/gd32450z-eval/drivers/SConscript
  96. 139 0
      bsp/gd32450z-eval/drivers/board.c
  97. 74 0
      bsp/gd32450z-eval/drivers/board.h
  98. 695 0
      bsp/gd32450z-eval/drivers/drv_usart.c
  99. 26 0
      bsp/gd32450z-eval/drivers/drv_usart.h
  100. 45 0
      bsp/gd32450z-eval/drivers/gd32f4xx_libopt.h

+ 265 - 0
bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h

@@ -0,0 +1,265 @@
+/*!
+    \file  gd32f4xx.h
+    \brief general definitions for GD32F4xx
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware update for GD32F4xx
+*/
+
+#ifndef GD32F4XX_H
+#define GD32F4XX_H
+
+#ifdef cplusplus
+ extern "C" {
+#endif 
+
+/* define GD32F4xx */
+#if !defined (GD32F4xx)
+  #define GD32F4xx
+#endif /* define GD32F4xx */
+#if !defined (GD32F4xx)
+ #error "Please select the target GD32F4xx device used in your application (in gd32f4xx.h file)"
+#endif /* undefine GD32F4xx tip */
+
+/* define value of high speed crystal oscillator (HXTAL) in Hz */
+#if !defined  (HXTAL_VALUE)
+#define HXTAL_VALUE    ((uint32_t)25000000)
+#endif /* high speed crystal oscillator value */
+
+/* define startup timeout value of high speed crystal oscillator (HXTAL) */
+#if !defined  (HXTAL_STARTUP_TIMEOUT)
+#define HXTAL_STARTUP_TIMEOUT   ((uint16_t)0x0800)
+#endif /* high speed crystal oscillator startup timeout */
+
+/* define value of internal 16MHz RC oscillator (IRC16M) in Hz */
+#if !defined  (IRC16M_VALUE) 
+#define IRC16M_VALUE  ((uint32_t)16000000)
+#endif /* internal 16MHz RC oscillator value */
+
+/* define startup timeout value of internal 16MHz RC oscillator (IRC16M) */
+#if !defined  (IRC16M_STARTUP_TIMEOUT)
+#define IRC16M_STARTUP_TIMEOUT   ((uint16_t)0x0500)
+#endif /* internal 16MHz RC oscillator startup timeout */
+
+/* define value of internal 32KHz RC oscillator(IRC32K) in Hz */
+#if !defined  (IRC32K_VALUE) 
+#define IRC32K_VALUE  ((uint32_t)32000)
+#endif /* internal 32KHz RC oscillator value */
+
+/* define value of low speed crystal oscillator (LXTAL)in Hz */
+#if !defined  (LXTAL_VALUE) 
+#define LXTAL_VALUE  ((uint32_t)32768)
+#endif /* low speed crystal oscillator value */
+
+/* I2S external clock in selection */
+//#define I2S_EXTERNAL_CLOCK_IN          (uint32_t)12288000U
+
+/* GD32F4xx firmware library version number V1.0 */
+#define __GD32F4xx_STDPERIPH_VERSION_MAIN   (0x03) /*!< [31:24] main version     */
+#define __GD32F4xx_STDPERIPH_VERSION_SUB1   (0x00) /*!< [23:16] sub1 version     */
+#define __GD32F4xx_STDPERIPH_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version     */
+#define __GD32F4xx_STDPERIPH_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
+#define __GD32F4xx_STDPERIPH_VERSION        ((__GD32F4xx_STDPERIPH_VERSION_MAIN << 24)\
+                                            |(__GD32F4xx_STDPERIPH_VERSION_SUB1 << 16)\
+                                            |(__GD32F4xx_STDPERIPH_VERSION_SUB2 << 8)\
+                                            |(__GD32F4xx_STDPERIPH_VERSION_RC))
+
+/* configuration of the Cortex-M4 processor and core peripherals */
+#define __CM4_REV                 0x0001   /*!< Core revision r0p1                                       */
+#define __MPU_PRESENT             1        /*!< GD32F4xx do not provide MPU                              */
+#define __NVIC_PRIO_BITS          4        /*!< GD32F4xx uses 4 bits for the priority levels             */
+#define __VENDOR_SYSTICKCONFIG    0        /*!< set to 1 if different sysTick config is used             */
+#define __FPU_PRESENT             1        /*!< FPU present                                              */
+/* define interrupt number */
+typedef enum IRQn
+{
+    /* Cortex-M4 processor exceptions numbers */
+    NonMaskableInt_IRQn          = -14,    /*!< 2 non maskable interrupt                                 */
+    MemoryManagement_IRQn        = -12,    /*!< 4 Cortex-M4 memory management interrupt                  */
+    BusFault_IRQn                = -11,    /*!< 5 Cortex-M4 bus fault interrupt                          */
+    UsageFault_IRQn              = -10,    /*!< 6 Cortex-M4 usage fault interrupt                        */
+    SVCall_IRQn                  = -5,     /*!< 11 Cortex-M4 SV call interrupt                           */
+    DebugMonitor_IRQn            = -4,     /*!< 12 Cortex-M4 debug monitor interrupt                     */
+    PendSV_IRQn                  = -2,     /*!< 14 Cortex-M4 pend SV interrupt                           */
+    SysTick_IRQn                 = -1,     /*!< 15 Cortex-M4 system tick interrupt                       */
+    /* interruput numbers */
+    WWDGT_IRQn                   = 0,      /*!< window watchDog timer interrupt                          */
+    LVD_IRQn                     = 1,      /*!< LVD through EXTI line detect interrupt                   */
+    TAMPER_STAMP_IRQn            = 2,      /*!< Tamper and TimeStamp through EXTI Line detect            */
+    RTC_WKUP_IRQn                = 3,      /*!< RTC Wakeup through EXTI line interrupt                   */
+    FMC_IRQn                     = 4,      /*!< FMC interrupt                                            */
+    RCU_CTC_IRQn                 = 5,      /*!< RCU and CTC interrupt                                    */
+    EXTI0_IRQn                   = 6,      /*!< EXTI line 0 interrupts                                   */
+    EXTI1_IRQn                   = 7,      /*!< EXTI line 1 interrupts                                   */
+    EXTI2_IRQn                   = 8,      /*!< EXTI line 2 interrupts                                   */
+    EXTI3_IRQn                   = 9,      /*!< EXTI line 3 interrupts                                   */
+    EXTI4_IRQn                   = 10,     /*!< EXTI line 4 interrupts                                   */
+    DMA0_Channel0_IRQn           = 11,     /*!< DMA0 Channel0 Interrupt                                  */
+    DMA0_Channel1_IRQn           = 12,     /*!< DMA0 Channel1 Interrupt                                  */
+    DMA0_Channel2_IRQn           = 13,     /*!< DMA0 Channel2 Interrupt                                  */
+    DMA0_Channel3_IRQn           = 14,     /*!< DMA0 Channel3 Interrupt                                  */
+    DMA0_Channel4_IRQn           = 15,     /*!< DMA0 Channel4 Interrupt                                  */
+    DMA0_Channel5_IRQn           = 16,     /*!< DMA0 Channel5 Interrupt                                  */
+    DMA0_Channel6_IRQn           = 17,     /*!< DMA0 Channel6 Interrupt                                  */
+    ADC_IRQn                     = 18,     /*!< ADC interrupt                                            */
+    CAN0_TX_IRQn                 = 19,     /*!< CAN0 TX interrupts                                       */
+    CAN0_RX0_IRQn                = 20,     /*!< CAN0 RX0 interrupts                                      */
+    CAN0_RX1_IRQn                = 21,     /*!< CAN0 RX1 interrupts                                      */
+    CAN0_EWMC_IRQn                = 22,    /*!< CAN0 EWMC interrupts                                     */
+    EXTI5_9_IRQn                 = 23,     /*!< EXTI[9:5] interrupts                                     */
+    TIMER0_BRK_TIMER8_IRQn       = 24,     /*!< TIMER0 Break and TIMER8 interrupts                       */
+    TIMER0_UP_TIMER9_IRQn        = 25,     /*!< TIMER0 Update and TIMER9 interrupts                      */
+    TIMER0_TRG_CMT_TIMER10_IRQn  = 26,     /*!< TIMER0 Trigger and Commutation  and TIMER10 interrupts   */
+    TIMER0_CC_IRQn               = 27,     /*!< TIMER0 Capture Compare interrupts                        */
+    TIMER1_IRQn                  = 28,     /*!< TIMER1 interrupt                                         */
+    TIMER2_IRQn                  = 29,     /*!< TIMER2 interrupt                                         */
+    TIMER3_IRQn                  = 30,     /*!< TIMER3 interrupts                                        */
+    I2C0_EV_IRQn                 = 31,     /*!< I2C0 event interrupt                                     */
+    I2C0_ER_IRQn                 = 32,     /*!< I2C0 error interrupt                                     */
+    I2C1_EV_IRQn                 = 33,     /*!< I2C1 event interrupt                                     */
+    I2C1_ER_IRQn                 = 34,     /*!< I2C1 error interrupt                                     */
+    SPI0_IRQn                    = 35,     /*!< SPI0 interrupt                                           */
+    SPI1_IRQn                    = 36,     /*!< SPI1 interrupt                                           */
+    USART0_IRQn                  = 37,     /*!< USART0 interrupt                                         */
+    USART1_IRQn                  = 38,     /*!< USART1 interrupt                                         */
+    USART2_IRQn                  = 39,     /*!< USART2 interrupt                                         */
+    EXTI10_15_IRQn               = 40,     /*!< EXTI[15:10] interrupts                                   */
+    RTC_Alarm_IRQn               = 41,     /*!< RTC Alarm interrupt                                      */
+    USBFS_WKUP_IRQn              = 42,     /*!< USBFS Wakeup interrupt                                   */
+    TIMER7_BRK_TIMER11_IRQn      = 43,     /*!< TIMER7 Break and TIMER11 interrupts                      */
+    TIMER7_UP_TIMER12_IRQn       = 44,     /*!< TIMER7 Update and TIMER12 interrupts                     */
+    TIMER7_TRG_CMT_TIMER13_IRQn  = 45,     /*!< TIMER7 Trigger and Commutation and TIMER13 interrupts    */
+    TIMER7_CC_IRQn               = 46,     /*!< TIMER7 Capture Compare interrupts                        */
+    DMA0_Channel7_IRQn           = 47,     /*!< DMA0 Channel7 Interrupt                                  */
+    EXMC_IRQn                    = 48,     /*!< EXMC Interrupt                                           */
+    SDIO_IRQn                    = 49,     /*!< SDIO Interrupt                                           */
+    TIMER4_IRQn                  = 50,     /*!< TIMER4 Interrupt                                         */
+    SPI2_IRQn                    = 51,     /*!< SPI2 Interrupt                                           */
+    UART3_IRQn                   = 52,     /*!< UART3 Interrupt                                          */
+    UART4_IRQn                   = 53,     /*!< UART4 Interrupt                                          */
+    TIMER5_DAC_IRQn              = 54,     /*!< TIMER5 and DAC0 DAC1 Underrun error Interrupt            */
+    TIMER6_IRQn                  = 55,     /*!< TIMER6 Interrupt                                         */
+    DMA1_Channel0_IRQn           = 56,     /*!< DMA1 Channel0 Interrupt                                  */
+    DMA1_Channel1_IRQn           = 57,     /*!< DMA1 Channel1 Interrupt                                  */
+    DMA1_Channel2_IRQn           = 58,     /*!< DMA1 Channel2 Interrupt                                  */
+    DMA1_Channel3_IRQn           = 59,     /*!< DMA1 Channel3 Interrupt                                  */
+    DMA1_Channel4_IRQn           = 60,     /*!< DMA1 Channel4 Interrupt                                  */
+    ENET_IRQn                    = 61,     /*!< Ethernet Interrupt                                       */
+    ENET_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EXTI Line Interrupt              */
+    CAN1_TX_IRQn                 = 63,     /*!< CAN1 TX Interrupt                                        */
+    CAN1_RX0_IRQn                = 64,     /*!< CAN1 RX0 Interrupt                                       */
+    CAN1_RX1_IRQn                = 65,     /*!< CAN1 RX1 Interrupt                                       */
+    CAN1_EWMC_IRQn                = 66,    /*!< CAN1 EWMC Interrupt                                      */
+    USBFS_IRQn                   = 67,     /*!< USBFS Interrupt                                          */
+    DMA1_Channel5_IRQn           = 68,     /*!< DMA1 Channel5 Interrupt                                  */
+    DMA1_Channel6_IRQn           = 69,     /*!< DMA1 Channel6 Interrupt                                  */
+    DMA1_Channel7_IRQn           = 70,     /*!< DMA1 Channel7 Interrupt                                  */
+    USART5_IRQn                  = 71,     /*!< USART5 Interrupt                                         */
+    I2C2_EV_IRQn                 = 72,     /*!< I2C2 Event Interrupt                                     */
+    I2C2_ER_IRQn                 = 73,     /*!< I2C2 Error Interrupt                                     */
+    USBHS_EP1_Out_IRQn           = 74,     /*!< USBHS Endpoint 1 Out Interrupt                           */
+    USBHS_EP1_In_IRQn            = 75,     /*!< USBHS Endpoint 1 in Interrupt                            */
+    USBHS_WKUP_IRQn              = 76,     /*!< USBHS Wakeup through EXTI Line Interrupt                 */
+    USBHS_IRQn                   = 77,     /*!< USBHS Interrupt                                          */
+    DCI_IRQn                     = 78,     /*!< DCI Interrupt                                            */
+    TRNG_IRQn                    = 80,     /*!< TRNG Interrupt                                           */
+    FPU_IRQn                     = 81,     /*!< FPU Interrupt                                            */
+    UART6_IRQn                   = 82,     /*!< UART6 Interrupt                                          */
+    UART7_IRQn                   = 83,     /*!< UART7 Interrupt                                          */
+    SPI3_IRQn                    = 84,     /*!< SPI3 Interrupt                                           */
+    SPI4_IRQn                    = 85,     /*!< SPI4 Interrupt                                           */
+    SPI5_IRQn                    = 86,     /*!< SPI5 Interrupt                                           */
+    TLI_IRQn                     = 88,     /*!< TLI Interrupt                                            */
+    TLI_ER_IRQn                  = 89,     /*!< TLI Error Interrupt                                      */
+    IPA_IRQn                     = 90,     /*!< IPA Interrupt                                            */
+} IRQn_Type;
+
+/* includes */
+#include "core_cm4.h"
+#include "system_gd32f4xx.h"
+#include <stdint.h>
+
+/* enum definitions */
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
+typedef enum {FALSE = 0, TRUE = !FALSE} bool;
+typedef enum {RESET = 0, SET = !RESET} FlagStatus;
+typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus;
+
+/* bit operations */
+#define REG32(addr)                  (*(volatile uint32_t *)(uint32_t)(addr))
+#define REG16(addr)                  (*(volatile uint16_t *)(uint32_t)(addr))
+#define REG8(addr)                   (*(volatile uint8_t *)(uint32_t)(addr))
+#define BIT(x)                       ((uint32_t)((uint32_t)0x01U<<(x)))
+#define BITS(start, end)             ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) 
+#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start))
+
+/* main flash and SRAM memory map */
+#define FLASH_BASE            ((uint32_t)0x08000000U)        /*!< main FLASH base address          */
+#define TCMSRAM_BASE          ((uint32_t)0x10000000U)        /*!< TCMSRAM(64KB) base address       */
+#define OPTION_BASE           ((uint32_t)0x1FFEC000U)        /*!< Option bytes base address        */
+#define SRAM_BASE             ((uint32_t)0x20000000U)        /*!< SRAM0 base address               */
+
+/* peripheral memory map */
+#define APB1_BUS_BASE         ((uint32_t)0x40000000U)        /*!< apb1 base address                */
+#define APB2_BUS_BASE         ((uint32_t)0x40010000U)        /*!< apb2 base address                */
+#define AHB1_BUS_BASE         ((uint32_t)0x40020000U)        /*!< ahb1 base address                */
+#define AHB2_BUS_BASE         ((uint32_t)0x50000000U)        /*!< ahb2 base address                */
+
+/* EXMC memory map */
+#define EXMC_BASE             ((uint32_t)0xA0000000U)        /*!< EXMC register base address       */
+
+/* advanced peripheral bus 1 memory map */
+#define TIMER_BASE            (APB1_BUS_BASE + 0x00000000U)  /*!< TIMER base address               */
+#define RTC_BASE              (APB1_BUS_BASE + 0x00002800U)  /*!< RTC base address                 */
+#define WWDGT_BASE            (APB1_BUS_BASE + 0x00002C00U)  /*!< WWDGT base address               */
+#define FWDGT_BASE            (APB1_BUS_BASE + 0x00003000U)  /*!< FWDGT base address               */
+#define I2S_ADD_BASE          (APB1_BUS_BASE + 0x00003400U)  /*!< I2S1_add base address            */
+#define SPI_BASE              (APB1_BUS_BASE + 0x00003800U)  /*!< SPI base address                 */
+#define USART_BASE            (APB1_BUS_BASE + 0x00004400U)  /*!< USART base address               */
+#define I2C_BASE              (APB1_BUS_BASE + 0x00005400U)  /*!< I2C base address                 */
+#define CAN_BASE              (APB1_BUS_BASE + 0x00006400U)  /*!< CAN base address                 */
+#define CTC_BASE              (APB1_BUS_BASE + 0x00006C00U)  /*!< CTC base address                 */
+#define PMU_BASE              (APB1_BUS_BASE + 0x00007000U)  /*!< PMU base address                 */
+#define DAC_BASE              (APB1_BUS_BASE + 0x00007400U)  /*!< DAC base address                 */
+#define IREF_BASE             (APB1_BUS_BASE + 0x0000C400U)  /*!< IREF base address                */
+
+/* advanced peripheral bus 2 memory map */
+#define TLI_BASE              (APB2_BUS_BASE + 0x00006800U)  /*!< TLI base address                 */
+#define SYSCFG_BASE           (APB2_BUS_BASE + 0x00003800U)  /*!< SYSCFG base address              */
+#define EXTI_BASE             (APB2_BUS_BASE + 0x00003C00U)  /*!< EXTI base address                */
+#define SDIO_BASE             (APB2_BUS_BASE + 0x00002C00U)  /*!< SDIO base address                */
+#define ADC_BASE              (APB2_BUS_BASE + 0x00002000U)  /*!< ADC base address                 */
+/* advanced high performance bus 1 memory map */
+#define GPIO_BASE             (AHB1_BUS_BASE + 0x00000000U)  /*!< GPIO base address                */
+#define CRC_BASE              (AHB1_BUS_BASE + 0x00003000U)  /*!< CRC base address                 */
+#define RCU_BASE              (AHB1_BUS_BASE + 0x00003800U)  /*!< RCU base address                 */
+#define FMC_BASE              (AHB1_BUS_BASE + 0x00003C00U)  /*!< FMC base address                 */
+#define BKPSRAM_BASE          (AHB1_BUS_BASE + 0x00004000U)  /*!< BKPSRAM base address             */
+#define DMA_BASE              (AHB1_BUS_BASE + 0x00006000U)  /*!< DMA base address                 */
+#define ENET_BASE             (AHB1_BUS_BASE + 0x00008000U)  /*!< ENET base address                */
+#define IPA_BASE              (AHB1_BUS_BASE + 0x0000B000U)  /*!< IPA base address                 */
+#define USBHS_BASE            (AHB1_BUS_BASE + 0x00020000U)  /*!< USBHS base address               */
+
+/* advanced high performance bus 2 memory map */
+#define USBFS_BASE            (AHB2_BUS_BASE + 0x00000000U)  /*!< USBFS base address               */
+#define DCI_BASE              (AHB2_BUS_BASE + 0x00050000U)  /*!< DCI base address                 */
+#define TRNG_BASE             (AHB2_BUS_BASE + 0x00060800U)  /*!< TRNG base address                */
+/* option byte and debug memory map */
+#define OB_BASE               ((uint32_t)0x1FFEC000U)        /*!< OB base address                  */
+#define DBG_BASE              ((uint32_t)0xE0042000U)        /*!< DBG base address                 */
+
+/* define marco USE_STDPERIPH_DRIVER */
+#if !defined  USE_STDPERIPH_DRIVER
+#define USE_STDPERIPH_DRIVER
+#endif 
+#ifdef USE_STDPERIPH_DRIVER
+#include "gd32f4xx_libopt.h"
+#endif /* USE_STDPERIPH_DRIVER */
+
+#ifdef cplusplus
+}
+#endif
+#endif 

+ 58 - 0
bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h

@@ -0,0 +1,58 @@
+/*!
+    \file  system_gd32f4xx.h
+    \brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for
+           GD32F4xx Device Series
+*/
+
+/* Copyright (c) 2012 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
+
+#ifndef SYSTEM_GD32F4XX_H
+#define SYSTEM_GD32F4XX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/* system clock frequency (core clock) */
+extern uint32_t SystemCoreClock;
+
+/* function declarations */
+/* initialize the system and update the SystemCoreClock variable */
+extern void SystemInit (void);
+/* update the SystemCoreClock with current core clock retrieved from cpu registers */
+extern void SystemCoreClockUpdate (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_GD32F4XX_H */

+ 427 - 0
bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s

@@ -0,0 +1,427 @@
+;/*!
+;    \file  startup_gd32f4xx.s
+;    \brief start up file
+;*/
+
+;/*
+;    Copyright (C) 2016 GigaDevice
+
+;    2016-08-15, V1.0.0, firmware for GD32F4xx
+;*/
+
+; <h> Stack Configuration
+;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Stack_Size      EQU     0x00000400
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem       SPACE   Stack_Size
+__initial_sp
+
+
+; <h> Heap Configuration
+;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Heap_Size       EQU     0x00000400
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+                PRESERVE8
+                THUMB
+
+;               /* reset Vector Mapped to at Address 0 */
+                AREA    RESET, DATA, READONLY
+                EXPORT  __Vectors
+                EXPORT  __Vectors_End
+                EXPORT  __Vectors_Size
+
+__Vectors       DCD     __initial_sp                      ; Top of Stack
+                DCD     Reset_Handler                     ; Reset Handler
+                DCD     NMI_Handler                       ; NMI Handler
+                DCD     HardFault_Handler                 ; Hard Fault Handler
+                DCD     MemManage_Handler                 ; MPU Fault Handler
+                DCD     BusFault_Handler                  ; Bus Fault Handler
+                DCD     UsageFault_Handler                ; Usage Fault Handler
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     SVC_Handler                       ; SVCall Handler
+                DCD     DebugMon_Handler                  ; Debug Monitor Handler
+                DCD     0                                 ; Reserved
+                DCD     PendSV_Handler                    ; PendSV Handler
+                DCD     SysTick_Handler                   ; SysTick Handler
+
+;               /* external interrupts handler */
+                DCD     WWDGT_IRQHandler                  ; 16:Window Watchdog Timer
+                DCD     LVD_IRQHandler                    ; 17:LVD through EXTI Line detect
+                DCD     TAMPER_STAMP_IRQHandler           ; 18:Tamper and TimeStamp through EXTI Line detect
+                DCD     RTC_WKUP_IRQHandler               ; 19:RTC Wakeup through EXTI Line
+                DCD     FMC_IRQHandler                    ; 20:FMC
+                DCD     RCU_CTC_IRQHandler                ; 21:RCU and CTC
+                DCD     EXTI0_IRQHandler                  ; 22:EXTI Line 0
+                DCD     EXTI1_IRQHandler                  ; 23:EXTI Line 1
+                DCD     EXTI2_IRQHandler                  ; 24:EXTI Line 2
+                DCD     EXTI3_IRQHandler                  ; 25:EXTI Line 3
+                DCD     EXTI4_IRQHandler                  ; 26:EXTI Line 4
+                DCD     DMA0_Channel0_IRQHandler          ; 27:DMA0 Channel0
+                DCD     DMA0_Channel1_IRQHandler          ; 28:DMA0 Channel1
+                DCD     DMA0_Channel2_IRQHandler          ; 29:DMA0 Channel2
+                DCD     DMA0_Channel3_IRQHandler          ; 30:DMA0 Channel3
+                DCD     DMA0_Channel4_IRQHandler          ; 31:DMA0 Channel4
+                DCD     DMA0_Channel5_IRQHandler          ; 32:DMA0 Channel5
+                DCD     DMA0_Channel6_IRQHandler          ; 33:DMA0 Channel6
+                DCD     ADC_IRQHandler                    ; 34:ADC
+                DCD     CAN0_TX_IRQHandler                ; 35:CAN0 TX
+                DCD     CAN0_RX0_IRQHandler               ; 36:CAN0 RX0
+                DCD     CAN0_RX1_IRQHandler               ; 37:CAN0 RX1
+                DCD     CAN0_EWMC_IRQHandler              ; 38:CAN0 EWMC
+                DCD     EXTI5_9_IRQHandler                ; 39:EXTI5 to EXTI9
+                DCD     TIMER0_BRK_TIMER8_IRQHandler      ; 40:TIMER0 Break and TIMER8
+                DCD     TIMER0_UP_TIMER9_IRQHandler       ; 41:TIMER0 Update and TIMER9
+                DCD     TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commutation and TIMER10
+                DCD     TIMER0_CC_IRQHandler              ; 43:TIMER0 Capture Compare
+                DCD     TIMER1_IRQHandler                 ; 44:TIMER1
+                DCD     TIMER2_IRQHandler                 ; 45:TIMER2
+                DCD     TIMER3_IRQHandler                 ; 46:TIMER3
+                DCD     I2C0_EV_IRQHandler                ; 47:I2C0 Event
+                DCD     I2C0_ER_IRQHandler                ; 48:I2C0 Error
+                DCD     I2C1_EV_IRQHandler                ; 49:I2C1 Event
+                DCD     I2C1_ER_IRQHandler                ; 50:I2C1 Error
+                DCD     SPI0_IRQHandler                   ; 51:SPI0
+                DCD     SPI1_IRQHandler                   ; 52:SPI1
+                DCD     USART0_IRQHandler                 ; 53:USART0
+                DCD     USART1_IRQHandler                 ; 54:USART1
+                DCD     USART2_IRQHandler                 ; 55:USART2
+                DCD     EXTI10_15_IRQHandler              ; 56:EXTI10 to EXTI15
+                DCD     RTC_Alarm_IRQHandler              ; 57:RTC Alarm
+                DCD     USBFS_WKUP_IRQHandler             ; 58:USBFS Wakeup
+                DCD     TIMER7_BRK_TIMER11_IRQHandler     ; 59:TIMER7 Break and TIMER11
+                DCD     TIMER7_UP_TIMER12_IRQHandler      ; 60:TIMER7 Update and TIMER12
+                DCD     TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commutation and TIMER13
+                DCD     TIMER7_CC_IRQHandler              ; 62:TIMER7 Capture Compare
+                DCD     DMA0_Channel7_IRQHandler          ; 63:DMA0 Channel7
+                DCD     EXMC_IRQHandler                   ; 64:EXMC
+                DCD     SDIO_IRQHandler                   ; 65:SDIO
+                DCD     TIMER4_IRQHandler                 ; 66:TIMER4
+                DCD     SPI2_IRQHandler                   ; 67:SPI2
+                DCD     UART3_IRQHandler                  ; 68:UART3
+                DCD     UART4_IRQHandler                  ; 69:UART4
+                DCD     TIMER5_DAC_IRQHandler             ; 70:TIMER5 and DAC0 DAC1 Underrun error
+                DCD     TIMER6_IRQHandler                 ; 71:TIMER6
+                DCD     DMA1_Channel0_IRQHandler          ; 72:DMA1 Channel0
+                DCD     DMA1_Channel1_IRQHandler          ; 73:DMA1 Channel1
+                DCD     DMA1_Channel2_IRQHandler          ; 74:DMA1 Channel2
+                DCD     DMA1_Channel3_IRQHandler          ; 75:DMA1 Channel3
+                DCD     DMA1_Channel4_IRQHandler          ; 76:DMA1 Channel4
+                DCD     ENET_IRQHandler                   ; 77:Ethernet
+                DCD     ENET_WKUP_IRQHandler              ; 78:Ethernet Wakeup through EXTI Line
+                DCD     CAN1_TX_IRQHandler                ; 79:CAN1 TX
+                DCD     CAN1_RX0_IRQHandler               ; 80:CAN1 RX0
+                DCD     CAN1_RX1_IRQHandler               ; 81:CAN1 RX1
+                DCD     CAN1_EWMC_IRQHandler              ; 82:CAN1 EWMC
+                DCD     USBFS_IRQHandler                  ; 83:USBFS
+                DCD     DMA1_Channel5_IRQHandler          ; 84:DMA1 Channel5
+                DCD     DMA1_Channel6_IRQHandler          ; 85:DMA1 Channel6
+                DCD     DMA1_Channel7_IRQHandler          ; 86:DMA1 Channel7
+                DCD     USART5_IRQHandler                 ; 87:USART5
+                DCD     I2C2_EV_IRQHandler                ; 88:I2C2 Event
+                DCD     I2C2_ER_IRQHandler                ; 89:I2C2 Error
+                DCD     USBHS_EP1_Out_IRQHandler          ; 90:USBHS Endpoint 1 Out 
+                DCD     USBHS_EP1_In_IRQHandler           ; 91:USBHS Endpoint 1 in
+                DCD     USBHS_WKUP_IRQHandler             ; 92:USBHS Wakeup through EXTI Line
+                DCD     USBHS_IRQHandler                  ; 93:USBHS
+                DCD     DCI_IRQHandler                    ; 94:DCI
+                DCD     0                                 ; 95:Reserved
+                DCD     TRNG_IRQHandler                   ; 96:TRNG
+                DCD     FPU_IRQHandler                    ; 97:FPU
+                DCD     UART6_IRQHandler                  ; 98:UART6
+                DCD     UART7_IRQHandler                  ; 98:UART7
+                DCD     SPI3_IRQHandler                   ; 100:SPI3
+                DCD     SPI4_IRQHandler                   ; 101:SPI4
+                DCD     SPI5_IRQHandler                   ; 102:SPI5
+                DCD     TLI_IRQHandler                    ; 104:TLI
+                DCD     TLI_ER_IRQHandler                 ; 105:TLI Error
+                DCD     IPA_IRQHandler                    ; 106:IPA
+
+__Vectors_End
+
+__Vectors_Size  EQU     __Vectors_End - __Vectors
+
+                AREA    |.text|, CODE, READONLY
+
+;/* reset Handler */
+Reset_Handler   PROC
+                EXPORT  Reset_Handler                     [WEAK]
+                IMPORT  SystemInit
+                IMPORT  __main
+                LDR     R0, =SystemInit
+                BLX     R0
+                LDR     R0, =__main
+                BX      R0
+                ENDP
+
+;/* dummy Exception Handlers */
+NMI_Handler     PROC
+                EXPORT  NMI_Handler                       [WEAK]
+                B       .
+                ENDP
+HardFault_Handler\
+                PROC
+                EXPORT  HardFault_Handler                 [WEAK]
+                B       .
+                ENDP
+MemManage_Handler\
+                PROC
+                EXPORT  MemManage_Handler                 [WEAK]
+                B       .
+                ENDP
+BusFault_Handler\
+                PROC
+                EXPORT  BusFault_Handler                  [WEAK]
+                B       .
+                ENDP
+UsageFault_Handler\
+                PROC
+                EXPORT  UsageFault_Handler                [WEAK]
+                B       .
+                ENDP
+SVC_Handler     PROC
+                EXPORT  SVC_Handler                       [WEAK]
+                B       .
+                ENDP
+DebugMon_Handler\
+                PROC
+                EXPORT  DebugMon_Handler                  [WEAK]
+                B       .
+                ENDP
+PendSV_Handler\
+                PROC
+                EXPORT  PendSV_Handler                    [WEAK]
+                B       .
+                ENDP
+SysTick_Handler\
+                PROC
+                EXPORT  SysTick_Handler                   [WEAK]
+                B       .
+                ENDP
+
+Default_Handler PROC
+;               /* external interrupts handler */
+                EXPORT  WWDGT_IRQHandler                  [WEAK]
+                EXPORT  LVD_IRQHandler                    [WEAK]                  
+                EXPORT  TAMPER_STAMP_IRQHandler           [WEAK]           
+                EXPORT  RTC_WKUP_IRQHandler               [WEAK]               
+                EXPORT  FMC_IRQHandler                    [WEAK]                
+                EXPORT  RCU_CTC_IRQHandler                [WEAK]                 
+                EXPORT  EXTI0_IRQHandler                  [WEAK]                  
+                EXPORT  EXTI1_IRQHandler                  [WEAK]                 
+                EXPORT  EXTI2_IRQHandler                  [WEAK]               
+                EXPORT  EXTI3_IRQHandler                  [WEAK]                
+                EXPORT  EXTI4_IRQHandler                  [WEAK]                 
+                EXPORT  DMA0_Channel0_IRQHandler          [WEAK]         
+                EXPORT  DMA0_Channel1_IRQHandler          [WEAK]          
+                EXPORT  DMA0_Channel2_IRQHandler          [WEAK]        
+                EXPORT  DMA0_Channel3_IRQHandler          [WEAK]         
+                EXPORT  DMA0_Channel4_IRQHandler          [WEAK]          
+                EXPORT  DMA0_Channel5_IRQHandler          [WEAK]          
+                EXPORT  DMA0_Channel6_IRQHandler          [WEAK]          
+                EXPORT  ADC_IRQHandler                    [WEAK]         
+                EXPORT  CAN0_TX_IRQHandler                [WEAK]          
+                EXPORT  CAN0_RX0_IRQHandler               [WEAK]          
+                EXPORT  CAN0_RX1_IRQHandler               [WEAK]           
+                EXPORT  CAN0_EWMC_IRQHandler              [WEAK]           
+                EXPORT  EXTI5_9_IRQHandler                [WEAK]           
+                EXPORT  TIMER0_BRK_TIMER8_IRQHandler      [WEAK]  
+                EXPORT  TIMER0_UP_TIMER9_IRQHandler       [WEAK]  
+                EXPORT  TIMER0_TRG_CMT_TIMER10_IRQHandler [WEAK]
+                EXPORT  TIMER0_CC_IRQHandler              [WEAK]        
+                EXPORT  TIMER1_IRQHandler                 [WEAK]       
+                EXPORT  TIMER2_IRQHandler                 [WEAK]           
+                EXPORT  TIMER3_IRQHandler                 [WEAK]           
+                EXPORT  I2C0_EV_IRQHandler                [WEAK]          
+                EXPORT  I2C0_ER_IRQHandler                [WEAK]         
+                EXPORT  I2C1_EV_IRQHandler                [WEAK]         
+                EXPORT  I2C1_ER_IRQHandler                [WEAK]         
+                EXPORT  SPI0_IRQHandler                   [WEAK]        
+                EXPORT  SPI1_IRQHandler                   [WEAK]          
+                EXPORT  USART0_IRQHandler                 [WEAK]         
+                EXPORT  USART1_IRQHandler                 [WEAK]         
+                EXPORT  USART2_IRQHandler                 [WEAK]        
+                EXPORT  EXTI10_15_IRQHandler              [WEAK]        
+                EXPORT  RTC_Alarm_IRQHandler              [WEAK]        
+                EXPORT  USBFS_WKUP_IRQHandler             [WEAK]        
+                EXPORT  TIMER7_BRK_TIMER11_IRQHandler     [WEAK] 
+                EXPORT  TIMER7_UP_TIMER12_IRQHandler      [WEAK] 
+                EXPORT  TIMER7_TRG_CMT_TIMER13_IRQHandler [WEAK]
+                EXPORT  TIMER7_CC_IRQHandler              [WEAK]        
+                EXPORT  DMA0_Channel7_IRQHandler          [WEAK]       
+                EXPORT  EXMC_IRQHandler                   [WEAK]         
+                EXPORT  SDIO_IRQHandler                   [WEAK]           
+                EXPORT  TIMER4_IRQHandler                 [WEAK]           
+                EXPORT  SPI2_IRQHandler                   [WEAK]          
+                EXPORT  UART3_IRQHandler                  [WEAK]          
+                EXPORT  UART4_IRQHandler                  [WEAK]          
+                EXPORT  TIMER5_DAC_IRQHandler             [WEAK]         
+                EXPORT  TIMER6_IRQHandler                 [WEAK]        
+                EXPORT  DMA1_Channel0_IRQHandler          [WEAK]          
+                EXPORT  DMA1_Channel1_IRQHandler          [WEAK]          
+                EXPORT  DMA1_Channel2_IRQHandler          [WEAK]         
+                EXPORT  DMA1_Channel3_IRQHandler          [WEAK]         
+                EXPORT  DMA1_Channel4_IRQHandler          [WEAK]          
+                EXPORT  ENET_IRQHandler                   [WEAK]         
+                EXPORT  ENET_WKUP_IRQHandler              [WEAK]         
+                EXPORT  CAN1_TX_IRQHandler                [WEAK]          
+                EXPORT  CAN1_RX0_IRQHandler               [WEAK]         
+                EXPORT  CAN1_RX1_IRQHandler               [WEAK]          
+                EXPORT  CAN1_EWMC_IRQHandler              [WEAK]          
+                EXPORT  USBFS_IRQHandler                  [WEAK]          
+                EXPORT  DMA1_Channel5_IRQHandler          [WEAK]          
+                EXPORT  DMA1_Channel6_IRQHandler          [WEAK]          
+                EXPORT  DMA1_Channel7_IRQHandler          [WEAK]          
+                EXPORT  USART5_IRQHandler                 [WEAK]          
+                EXPORT  I2C2_EV_IRQHandler                [WEAK]         
+                EXPORT  I2C2_ER_IRQHandler                [WEAK]          
+                EXPORT  USBHS_EP1_Out_IRQHandler          [WEAK]    
+                EXPORT  USBHS_EP1_In_IRQHandler           [WEAK]    
+                EXPORT  USBHS_WKUP_IRQHandler             [WEAK]             
+                EXPORT  USBHS_IRQHandler                  [WEAK]            
+                EXPORT  DCI_IRQHandler                    [WEAK]                      
+                EXPORT  TRNG_IRQHandler                   [WEAK]          
+                EXPORT  FPU_IRQHandler                    [WEAK]          
+                EXPORT  UART6_IRQHandler                  [WEAK]          
+                EXPORT  UART7_IRQHandler                  [WEAK]          
+                EXPORT  SPI3_IRQHandler                   [WEAK]          
+                EXPORT  SPI4_IRQHandler                   [WEAK]          
+                EXPORT  SPI5_IRQHandler                   [WEAK]                 
+                EXPORT  TLI_IRQHandler                    [WEAK]         
+                EXPORT  TLI_ER_IRQHandler                 [WEAK]         
+                EXPORT  IPA_IRQHandler                    [WEAK]          
+  
+;/* external interrupts handler */
+WWDGT_IRQHandler                  
+LVD_IRQHandler                    
+TAMPER_STAMP_IRQHandler           
+RTC_WKUP_IRQHandler               
+FMC_IRQHandler                   
+RCU_CTC_IRQHandler                   
+EXTI0_IRQHandler                  
+EXTI1_IRQHandler                 
+EXTI2_IRQHandler                
+EXTI3_IRQHandler                 
+EXTI4_IRQHandler                  
+DMA0_Channel0_IRQHandler         
+DMA0_Channel1_IRQHandler          
+DMA0_Channel2_IRQHandler        
+DMA0_Channel3_IRQHandler         
+DMA0_Channel4_IRQHandler          
+DMA0_Channel5_IRQHandler          
+DMA0_Channel6_IRQHandler          
+ADC_IRQHandler                   
+CAN0_TX_IRQHandler                
+CAN0_RX0_IRQHandler               
+CAN0_RX1_IRQHandler               
+CAN0_EWMC_IRQHandler               
+EXTI5_9_IRQHandler                
+TIMER0_BRK_TIMER8_IRQHandler    
+TIMER0_UP_TIMER9_IRQHandler   
+TIMER0_TRG_CMT_TIMER10_IRQHandler 
+TIMER0_CC_IRQHandler        
+TIMER1_IRQHandler             
+TIMER2_IRQHandler                 
+TIMER3_IRQHandler                 
+I2C0_EV_IRQHandler                
+I2C0_ER_IRQHandler               
+I2C1_EV_IRQHandler               
+I2C1_ER_IRQHandler               
+SPI0_IRQHandler                  
+SPI1_IRQHandler                   
+USART0_IRQHandler                 
+USART1_IRQHandler                 
+USART2_IRQHandler                
+EXTI10_15_IRQHandler              
+RTC_Alarm_IRQHandler             
+USBFS_WKUP_IRQHandler             
+TIMER7_BRK_TIMER11_IRQHandler   
+TIMER7_UP_TIMER12_IRQHandler  
+TIMER7_TRG_CMT_TIMER13_IRQHandler 
+TIMER7_CC_IRQHandler         
+DMA0_Channel7_IRQHandler         
+EXMC_IRQHandler                   
+SDIO_IRQHandler                   
+TIMER4_IRQHandler                 
+SPI2_IRQHandler                  
+UART3_IRQHandler                  
+UART4_IRQHandler                  
+TIMER5_DAC_IRQHandler             
+TIMER6_IRQHandler                
+DMA1_Channel0_IRQHandler          
+DMA1_Channel1_IRQHandler         
+DMA1_Channel2_IRQHandler         
+DMA1_Channel3_IRQHandler         
+DMA1_Channel4_IRQHandler          
+ENET_IRQHandler                  
+ENET_WKUP_IRQHandler             
+CAN1_TX_IRQHandler                
+CAN1_RX0_IRQHandler              
+CAN1_RX1_IRQHandler               
+CAN1_EWMC_IRQHandler               
+USBFS_IRQHandler                  
+DMA1_Channel5_IRQHandler          
+DMA1_Channel6_IRQHandler          
+DMA1_Channel7_IRQHandler          
+USART5_IRQHandler                 
+I2C2_EV_IRQHandler               
+I2C2_ER_IRQHandler                
+USBHS_EP1_Out_IRQHandler    
+USBHS_EP1_In_IRQHandler     
+USBHS_WKUP_IRQHandler             
+USBHS_IRQHandler                  
+DCI_IRQHandler                                    
+TRNG_IRQHandler                  
+FPU_IRQHandler                    
+UART6_IRQHandler                  
+UART7_IRQHandler                  
+SPI3_IRQHandler                   
+SPI4_IRQHandler                   
+SPI5_IRQHandler                                     
+TLI_IRQHandler                    
+TLI_ER_IRQHandler                 
+IPA_IRQHandler                    
+
+                B       .
+                ENDP
+
+                ALIGN
+
+; user Initial Stack & Heap
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __initial_sp
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+
+__user_initial_stackheap PROC
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + Stack_Size)
+                LDR     R2, = (Heap_Mem +  Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDP
+
+                ALIGN
+
+                ENDIF
+
+                END

+ 640 - 0
bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s

@@ -0,0 +1,640 @@
+;/*!
+;    \file  startup_gd32f4xx.s
+;    \brief start up file
+;*/
+
+;/*
+;    Copyright (C) 2016 GigaDevice
+
+;    2016-08-15, V1.0.0, firmware for GD32F4xx
+
+;*/
+
+        MODULE  ?cstartup
+
+        ;; Forward declaration of sections.
+        SECTION CSTACK:DATA:NOROOT(3)
+
+        SECTION .intvec:CODE:NOROOT(2)
+
+        EXTERN  __iar_program_start
+        EXTERN  SystemInit
+        PUBLIC  __vector_table
+
+        DATA
+__vector_table
+        DCD     sfe(CSTACK)                         ; top of stack
+        DCD     Reset_Handler                       ; Vector Number 1,Reset Handler
+
+        DCD     NMI_Handler                         ; Vector Number 2,NMI Handler
+        DCD     HardFault_Handler                   ; Vector Number 3,Hard Fault Handler
+        DCD     MemManage_Handler                   ; Vector Number 4,MPU Fault Handler
+        DCD     BusFault_Handler                    ; Vector Number 5,Bus Fault Handler
+        DCD     UsageFault_Handler                  ; Vector Number 6,Usage Fault Handler
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     SVC_Handler                         ; Vector Number 11,SVCall Handler
+        DCD     DebugMon_Handler                    ; Vector Number 12,Debug Monitor Handler
+        DCD     0                                   ; Reserved
+        DCD     PendSV_Handler                      ; Vector Number 14,PendSV Handler
+        DCD     SysTick_Handler                     ; Vector Number 15,SysTick Handler
+
+        ; External Interrupts
+                DCD     WWDGT_IRQHandler                  ; 16:Window Watchdog Timer
+                DCD     LVD_IRQHandler                    ; 17:LVD through EXTI Line detect
+                DCD     TAMPER_STAMP_IRQHandler           ; 18:Tamper and TimeStamp through EXTI Line detect
+                DCD     RTC_WKUP_IRQHandler               ; 19:RTC Wakeup through EXTI Line
+                DCD     FMC_IRQHandler                    ; 20:FMC
+                DCD     RCU_CTC_IRQHandler                ; 21:RCU and CTC
+                DCD     EXTI0_IRQHandler                  ; 22:EXTI Line 0
+                DCD     EXTI1_IRQHandler                  ; 23:EXTI Line 1
+                DCD     EXTI2_IRQHandler                  ; 24:EXTI Line 2
+                DCD     EXTI3_IRQHandler                  ; 25:EXTI Line 3
+                DCD     EXTI4_IRQHandler                  ; 26:EXTI Line 4
+                DCD     DMA0_Channel0_IRQHandler          ; 27:DMA0 Channel0
+                DCD     DMA0_Channel1_IRQHandler          ; 28:DMA0 Channel1
+                DCD     DMA0_Channel2_IRQHandler          ; 29:DMA0 Channel2
+                DCD     DMA0_Channel3_IRQHandler          ; 30:DMA0 Channel3
+                DCD     DMA0_Channel4_IRQHandler          ; 31:DMA0 Channel4
+                DCD     DMA0_Channel5_IRQHandler          ; 32:DMA0 Channel5
+                DCD     DMA0_Channel6_IRQHandler          ; 33:DMA0 Channel6
+                DCD     ADC_IRQHandler                    ; 34:ADC
+                DCD     CAN0_TX_IRQHandler                ; 35:CAN0 TX
+                DCD     CAN0_RX0_IRQHandler               ; 36:CAN0 RX0
+                DCD     CAN0_RX1_IRQHandler               ; 37:CAN0 RX1
+                DCD     CAN0_EWMC_IRQHandler              ; 38:CAN0 EWMC
+                DCD     EXTI5_9_IRQHandler                ; 39:EXTI5 to EXTI9
+                DCD     TIMER0_BRK_TIMER8_IRQHandler      ; 40:TIMER0 Break and TIMER8
+                DCD     TIMER0_UP_TIMER9_IRQHandler       ; 41:TIMER0 Update and TIMER9
+                DCD     TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commucation and TIMER10
+                DCD     TIMER0_CC_IRQHandler              ; 43:TIMER0 Capture Compare
+                DCD     TIMER1_IRQHandler                 ; 44:TIMER1
+                DCD     TIMER2_IRQHandler                 ; 45:TIMER2
+                DCD     TIMER3_IRQHandler                 ; 46:TIMER3
+                DCD     I2C0_EV_IRQHandler                ; 47:I2C0 Event
+                DCD     I2C0_ER_IRQHandler                ; 48:I2C0 Error
+                DCD     I2C1_EV_IRQHandler                ; 49:I2C1 Event
+                DCD     I2C1_ER_IRQHandler                ; 50:I2C1 Error
+                DCD     SPI0_IRQHandler                   ; 51:SPI0
+                DCD     SPI1_IRQHandler                   ; 52:SPI1
+                DCD     USART0_IRQHandler                 ; 53:USART0
+                DCD     USART1_IRQHandler                 ; 54:USART1
+                DCD     USART2_IRQHandler                 ; 55:USART2
+                DCD     EXTI10_15_IRQHandler              ; 56:EXTI10 to EXTI15
+                DCD     RTC_Alarm_IRQHandler              ; 57:RTC Alarm
+                DCD     USBFS_WKUP_IRQHandler             ; 58:USBFS Wakeup
+                DCD     TIMER7_BRK_TIMER11_IRQHandler     ; 59:TIMER7 Break and TIMER11
+                DCD     TIMER7_UP_TIMER12_IRQHandler      ; 60:TIMER7 Update and TIMER12
+                DCD     TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commucation and TIMER13
+                DCD     TIMER7_CC_IRQHandler              ; 62:TIMER7 Capture Compare
+                DCD     DMA0_Channel7_IRQHandler          ; 63:DMA0 Channel7
+                DCD     EXMC_IRQHandler                   ; 64:EXMC
+                DCD     SDIO_IRQHandler                   ; 65:SDIO
+                DCD     TIMER4_IRQHandler                 ; 66:TIMER4
+                DCD     SPI2_IRQHandler                   ; 67:SPI2
+                DCD     UART3_IRQHandler                  ; 68:UART3
+                DCD     UART4_IRQHandler                  ; 69:UART4
+                DCD     TIMER5_DAC_IRQHandler             ; 70:TIMER5 and DAC0 DAC1 Underrun error
+                DCD     TIMER6_IRQHandler                 ; 71:TIMER6
+                DCD     DMA1_Channel0_IRQHandler          ; 72:DMA1 Channel0
+                DCD     DMA1_Channel1_IRQHandler          ; 73:DMA1 Channel1
+                DCD     DMA1_Channel2_IRQHandler          ; 74:DMA1 Channel2
+                DCD     DMA1_Channel3_IRQHandler          ; 75:DMA1 Channel3
+                DCD     DMA1_Channel4_IRQHandler          ; 76:DMA1 Channel4
+                DCD     ENET_IRQHandler                   ; 77:Ethernet
+                DCD     ENET_WKUP_IRQHandler              ; 78:Ethernet Wakeup through EXTI Line
+                DCD     CAN1_TX_IRQHandler                ; 79:CAN1 TX
+                DCD     CAN1_RX0_IRQHandler               ; 80:CAN1 RX0
+                DCD     CAN1_RX1_IRQHandler               ; 81:CAN1 RX1
+                DCD     CAN1_EWMC_IRQHandler              ; 82:CAN1 EWMC
+                DCD     USBFS_IRQHandler                  ; 83:USBFS
+                DCD     DMA1_Channel5_IRQHandler          ; 84:DMA1 Channel5
+                DCD     DMA1_Channel6_IRQHandler          ; 85:DMA1 Channel6
+                DCD     DMA1_Channel7_IRQHandler          ; 86:DMA1 Channel7
+                DCD     USART5_IRQHandler                 ; 87:USART5
+                DCD     I2C2_EV_IRQHandler                ; 88:I2C2 Event
+                DCD     I2C2_ER_IRQHandler                ; 89:I2C2 Error
+                DCD     USBHS_EP1_Out_IRQHandler          ; 90:USBHS Endpoint 1 Out 
+                DCD     USBHS_EP1_In_IRQHandler           ; 91:USBHS Endpoint 1 in
+                DCD     USBHS_WKUP_IRQHandler             ; 92:USBHS Wakeup through EXTI Line
+                DCD     USBHS_IRQHandler                  ; 93:USBHS
+                DCD     DCI_IRQHandler                    ; 94:DCI
+                DCD     0                                 ; 95:Reserved
+                DCD     TRNG_IRQHandler                   ; 96:TRNG
+                DCD     FPU_IRQHandler                    ; 97:FPU
+                DCD     UART6_IRQHandler                  ; 98:UART6
+                DCD     UART7_IRQHandler                  ; 98:UART7
+                DCD     SPI3_IRQHandler                   ; 100:SPI3
+                DCD     SPI4_IRQHandler                   ; 101:SPI4
+                DCD     SPI5_IRQHandler                   ; 102:SPI5
+                DCD     TLI_IRQHandler                    ; 104:TLI
+                DCD     TLI_ER_IRQHandler                 ; 105:TLI Error
+                DCD     IPA_IRQHandler                    ; 106:IPA
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+        THUMB
+
+        PUBWEAK Reset_Handler
+        SECTION .text:CODE:NOROOT:REORDER(2)
+Reset_Handler
+        LDR     R0, =SystemInit
+        BLX     R0
+        LDR     R0, =__iar_program_start
+        BX      R0
+        
+        PUBWEAK NMI_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+NMI_Handler
+        B NMI_Handler
+       
+        PUBWEAK HardFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+HardFault_Handler
+        B HardFault_Handler
+       
+        PUBWEAK MemManage_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+MemManage_Handler
+        B MemManage_Handler
+
+        PUBWEAK BusFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+BusFault_Handler
+        B BusFault_Handler
+
+        PUBWEAK UsageFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UsageFault_Handler
+        B UsageFault_Handler
+        
+        PUBWEAK SVC_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SVC_Handler
+        B SVC_Handler
+       
+        PUBWEAK DebugMon_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DebugMon_Handler
+        B DebugMon_Handler
+        
+        PUBWEAK PendSV_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+PendSV_Handler
+        B PendSV_Handler
+        
+        PUBWEAK SysTick_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SysTick_Handler
+        B SysTick_Handler
+        
+        PUBWEAK WWDGT_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+WWDGT_IRQHandler
+        B WWDGT_IRQHandler
+        
+        PUBWEAK LVD_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+LVD_IRQHandler
+        B LVD_IRQHandler
+        
+        PUBWEAK TAMPER_STAMP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TAMPER_STAMP_IRQHandler
+        B TAMPER_STAMP_IRQHandler
+        
+        PUBWEAK RTC_WKUP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+RTC_WKUP_IRQHandler
+        B RTC_WKUP_IRQHandler
+        
+        PUBWEAK FMC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+FMC_IRQHandler
+        B FMC_IRQHandler
+        
+        PUBWEAK RCU_CTC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+RCU_CTC_IRQHandler
+        B RCU_CTC_IRQHandler
+        
+        PUBWEAK EXTI0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI0_IRQHandler
+        B EXTI0_IRQHandler
+        
+        PUBWEAK EXTI1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI1_IRQHandler
+        B EXTI1_IRQHandler
+        
+        PUBWEAK EXTI2_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI2_IRQHandler                  
+        B EXTI2_IRQHandler                  
+        
+        PUBWEAK EXTI3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI3_IRQHandler
+        B EXTI3_IRQHandler
+        
+        PUBWEAK EXTI4_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI4_IRQHandler
+        B EXTI4_IRQHandler
+        
+        PUBWEAK DMA0_Channel0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel0_IRQHandler
+        B DMA0_Channel0_IRQHandler
+        
+        PUBWEAK DMA0_Channel1_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel1_IRQHandler          
+        B DMA0_Channel1_IRQHandler          
+        
+        PUBWEAK DMA0_Channel2_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel2_IRQHandler          
+        B DMA0_Channel2_IRQHandler          
+        
+        PUBWEAK DMA0_Channel3_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel3_IRQHandler          
+        B DMA0_Channel3_IRQHandler          
+        
+        PUBWEAK DMA0_Channel4_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel4_IRQHandler          
+        B DMA0_Channel4_IRQHandler          
+        
+        PUBWEAK DMA0_Channel5_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel5_IRQHandler          
+        B DMA0_Channel5_IRQHandler          
+        
+        PUBWEAK DMA0_Channel6_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel6_IRQHandler          
+        B DMA0_Channel6_IRQHandler                
+        
+        PUBWEAK ADC_IRQHandler                    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+ADC_IRQHandler                    
+        B ADC_IRQHandler                    
+        
+        PUBWEAK CAN0_TX_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN0_TX_IRQHandler                
+        B CAN0_TX_IRQHandler                
+        
+        PUBWEAK CAN0_RX0_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN0_RX0_IRQHandler               
+        B CAN0_RX0_IRQHandler               
+        
+        PUBWEAK CAN0_RX1_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN0_RX1_IRQHandler               
+        B CAN0_RX1_IRQHandler               
+      
+        PUBWEAK CAN0_EWMC_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN0_EWMC_IRQHandler               
+        B CAN0_EWMC_IRQHandler               
+        
+        PUBWEAK EXTI5_9_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI5_9_IRQHandler                
+        B EXTI5_9_IRQHandler                
+        
+        PUBWEAK TIMER0_BRK_TIMER8_IRQHandler    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_BRK_TIMER8_IRQHandler    
+        B TIMER0_BRK_TIMER8_IRQHandler    
+        
+        PUBWEAK TIMER0_UP_TIMER9_IRQHandler   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_UP_TIMER9_IRQHandler   
+        B TIMER0_UP_TIMER9_IRQHandler   
+        
+        PUBWEAK TIMER0_TRG_CMT_TIMER10_IRQHandler 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_TRG_CMT_TIMER10_IRQHandler 
+        B TIMER0_TRG_CMT_TIMER10_IRQHandler 
+        
+        PUBWEAK TIMER0_CC_IRQHandler         
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_CC_IRQHandler         
+        B TIMER0_CC_IRQHandler         
+        
+        PUBWEAK TIMER1_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER1_IRQHandler                 
+        B TIMER1_IRQHandler                 
+        
+        PUBWEAK TIMER2_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER2_IRQHandler
+        B TIMER2_IRQHandler                 
+
+        PUBWEAK TIMER3_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER3_IRQHandler                 
+        B TIMER3_IRQHandler
+
+        PUBWEAK I2C0_EV_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C0_EV_IRQHandler                
+        B I2C0_EV_IRQHandler                
+
+        PUBWEAK I2C0_ER_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C0_ER_IRQHandler
+        B I2C0_ER_IRQHandler                
+
+        PUBWEAK I2C1_EV_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C1_EV_IRQHandler                
+        B I2C1_EV_IRQHandler                
+
+        PUBWEAK I2C1_ER_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C1_ER_IRQHandler                
+        B I2C1_ER_IRQHandler                
+
+        PUBWEAK SPI0_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI0_IRQHandler                   
+        B SPI0_IRQHandler                   
+
+        PUBWEAK SPI1_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI1_IRQHandler                   
+        B SPI1_IRQHandler
+
+        PUBWEAK USART0_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART0_IRQHandler                 
+        B USART0_IRQHandler                 
+
+        PUBWEAK USART1_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART1_IRQHandler                 
+        B USART1_IRQHandler                 
+
+        PUBWEAK USART2_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART2_IRQHandler                
+        B USART2_IRQHandler
+
+        PUBWEAK EXTI10_15_IRQHandler              
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI10_15_IRQHandler              
+        B EXTI10_15_IRQHandler              
+
+        PUBWEAK RTC_Alarm_IRQHandler             
+        SECTION .text:CODE:NOROOT:REORDER(1)
+RTC_Alarm_IRQHandler             
+        B RTC_Alarm_IRQHandler             
+
+        PUBWEAK USBFS_WKUP_IRQHandler             
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USBFS_WKUP_IRQHandler             
+        B USBFS_WKUP_IRQHandler             
+
+        PUBWEAK TIMER7_BRK_TIMER11_IRQHandler   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER7_BRK_TIMER11_IRQHandler   
+        B TIMER7_BRK_TIMER11_IRQHandler   
+
+        PUBWEAK TIMER7_UP_TIMER12_IRQHandler  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER7_UP_TIMER12_IRQHandler  
+        B TIMER7_UP_TIMER12_IRQHandler  
+
+        PUBWEAK TIMER7_TRG_CMT_TIMER13_IRQHandler 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER7_TRG_CMT_TIMER13_IRQHandler 
+        B TIMER7_TRG_CMT_TIMER13_IRQHandler 
+
+        PUBWEAK TIMER7_CC_IRQHandler         
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER7_CC_IRQHandler         
+        B TIMER7_CC_IRQHandler         
+
+        PUBWEAK DMA0_Channel7_IRQHandler         
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA0_Channel7_IRQHandler         
+        B DMA0_Channel7_IRQHandler         
+
+        PUBWEAK EXMC_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXMC_IRQHandler                   
+        B EXMC_IRQHandler                   
+
+        PUBWEAK SDIO_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SDIO_IRQHandler                   
+        B SDIO_IRQHandler                   
+
+        PUBWEAK TIMER4_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER4_IRQHandler                 
+        B TIMER4_IRQHandler                 
+
+        PUBWEAK SPI2_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI2_IRQHandler                  
+        B SPI2_IRQHandler                  
+
+        PUBWEAK UART3_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UART3_IRQHandler                  
+        B UART3_IRQHandler                  
+
+        PUBWEAK UART4_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UART4_IRQHandler                  
+        B UART4_IRQHandler                  
+
+        PUBWEAK TIMER5_DAC_IRQHandler             
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER5_DAC_IRQHandler             
+        B TIMER5_DAC_IRQHandler             
+
+        PUBWEAK TIMER6_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER6_IRQHandler                
+        B TIMER6_IRQHandler                
+
+        PUBWEAK DMA1_Channel0_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel0_IRQHandler          
+        B DMA1_Channel0_IRQHandler          
+
+        PUBWEAK DMA1_Channel1_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel1_IRQHandler          
+        B DMA1_Channel1_IRQHandler          
+
+        PUBWEAK DMA1_Channel2_IRQHandler         
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel2_IRQHandler         
+        B DMA1_Channel2_IRQHandler         
+
+        PUBWEAK DMA1_Channel3_IRQHandler         
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel3_IRQHandler         
+        B DMA1_Channel3_IRQHandler         
+
+        PUBWEAK DMA1_Channel4_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel4_IRQHandler          
+        B DMA1_Channel4_IRQHandler          
+
+        PUBWEAK ENET_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+ENET_IRQHandler                  
+        B ENET_IRQHandler                  
+        
+        PUBWEAK ENET_WKUP_IRQHandler             
+        SECTION .text:CODE:NOROOT:REORDER(1)
+ENET_WKUP_IRQHandler             
+        B ENET_WKUP_IRQHandler             
+
+        PUBWEAK CAN1_TX_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN1_TX_IRQHandler                
+        B CAN1_TX_IRQHandler                
+
+        PUBWEAK CAN1_RX0_IRQHandler              
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN1_RX0_IRQHandler              
+        B CAN1_RX0_IRQHandler              
+
+        PUBWEAK CAN1_RX1_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN1_RX1_IRQHandler               
+        B CAN1_RX1_IRQHandler               
+
+        PUBWEAK CAN1_EWMC_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CAN1_EWMC_IRQHandler               
+        B CAN1_EWMC_IRQHandler               
+
+        PUBWEAK USBFS_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USBFS_IRQHandler                  
+        B USBFS_IRQHandler                  
+
+        PUBWEAK DMA1_Channel5_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel5_IRQHandler          
+        B DMA1_Channel5_IRQHandler          
+
+        PUBWEAK DMA1_Channel6_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel6_IRQHandler          
+        B DMA1_Channel6_IRQHandler          
+
+        PUBWEAK DMA1_Channel7_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA1_Channel7_IRQHandler          
+        B DMA1_Channel7_IRQHandler          
+
+        PUBWEAK USART5_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART5_IRQHandler                 
+        B USART5_IRQHandler                 
+
+        PUBWEAK I2C2_EV_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C2_EV_IRQHandler               
+        B I2C2_EV_IRQHandler               
+
+        PUBWEAK I2C2_ER_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C2_ER_IRQHandler                
+        B I2C2_ER_IRQHandler                
+
+        PUBWEAK USBHS_EP1_Out_IRQHandler    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USBHS_EP1_Out_IRQHandler    
+        B USBHS_EP1_Out_IRQHandler    
+
+        PUBWEAK USBHS_EP1_In_IRQHandler     
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USBHS_EP1_In_IRQHandler     
+        B USBHS_EP1_In_IRQHandler     
+
+        PUBWEAK USBHS_WKUP_IRQHandler             
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USBHS_WKUP_IRQHandler             
+        B USBHS_WKUP_IRQHandler             
+
+        PUBWEAK USBHS_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USBHS_IRQHandler                  
+        B USBHS_IRQHandler                  
+
+        PUBWEAK DCI_IRQHandler                    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DCI_IRQHandler                    
+        B DCI_IRQHandler                    
+
+        PUBWEAK TRNG_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TRNG_IRQHandler                  
+        B TRNG_IRQHandler                  
+
+        PUBWEAK FPU_IRQHandler                    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+FPU_IRQHandler                    
+        B FPU_IRQHandler                    
+
+        PUBWEAK UART6_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UART6_IRQHandler                  
+        B UART6_IRQHandler                  
+
+        PUBWEAK UART7_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UART7_IRQHandler                  
+        B UART7_IRQHandler                  
+
+        PUBWEAK SPI3_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI3_IRQHandler                   
+        B SPI3_IRQHandler                   
+
+        PUBWEAK SPI4_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI4_IRQHandler                   
+        B SPI4_IRQHandler                   
+
+        PUBWEAK SPI5_IRQHandler                   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI5_IRQHandler                   
+        B SPI5_IRQHandler                   
+
+        PUBWEAK TLI_IRQHandler                    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TLI_IRQHandler                    
+        B TLI_IRQHandler                    
+
+        PUBWEAK TLI_ER_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TLI_ER_IRQHandler                 
+        B TLI_ER_IRQHandler                 
+
+        PUBWEAK IPA_IRQHandler                    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+IPA_IRQHandler                    
+        B IPA_IRQHandler                    
+        END

+ 941 - 0
bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c

@@ -0,0 +1,941 @@
+/*!
+    \file  system_gd32f4xx.c
+    \brief CMSIS Cortex-M4 Device Peripheral Access Layer Source File for
+           GD32F4xx Device Series
+*/
+
+/* Copyright (c) 2012 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
+
+#include "gd32f4xx.h"
+
+/* system frequency define */
+#define __IRC16M          (IRC16M_VALUE)            /* internal 16 MHz RC oscillator frequency */
+#define __HXTAL           (HXTAL_VALUE)             /* high speed crystal oscillator frequency */
+#define __SYS_OSC_CLK     (__IRC16M)                /* main oscillator frequency */
+
+/* select a system clock by uncommenting the following line */
+//#define __SYSTEM_CLOCK_IRC16M                   (uint32_t)(__IRC16M)
+//#define __SYSTEM_CLOCK_HXTAL                    (uint32_t)(__HXTAL)
+//#define __SYSTEM_CLOCK_120M_PLL_IRC16M          (uint32_t)(120000000)
+//#define __SYSTEM_CLOCK_120M_PLL_8M_HXTAL        (uint32_t)(120000000)
+//#define __SYSTEM_CLOCK_120M_PLL_25M_HXTAL       (uint32_t)(120000000)
+//#define __SYSTEM_CLOCK_168M_PLL_IRC16M          (uint32_t)(168000000)
+//#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)
+//#define __SYSTEM_CLOCK_168M_PLL_25M_HXTAL       (uint32_t)(168000000)
+//#define __SYSTEM_CLOCK_200M_PLL_IRC16M          (uint32_t)(200000000)
+//#define __SYSTEM_CLOCK_200M_PLL_8M_HXTAL        (uint32_t)(200000000)
+#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL       (uint32_t)(200000000)
+
+#define SEL_IRC16M      0x00U
+#define SEL_HXTAL       0x01U
+#define SEL_PLLP        0x02U
+
+/* set the system clock frequency and declare the system clock configuration function */
+#ifdef __SYSTEM_CLOCK_IRC16M
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC16M;
+static void system_clock_16m_irc16m(void);
+#elif defined (__SYSTEM_CLOCK_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
+static void system_clock_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_IRC16M;
+static void system_clock_120m_irc16m(void);
+#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_8M_HXTAL;
+static void system_clock_120m_8m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_25M_HXTAL;
+static void system_clock_120m_25m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_IRC16M;
+static void system_clock_168m_irc16m(void);
+#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_8M_HXTAL;
+static void system_clock_168m_8m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_25M_HXTAL;
+static void system_clock_168m_25m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_IRC16M;
+static void system_clock_200m_irc16m(void);
+#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_8M_HXTAL;
+static void system_clock_200m_8m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_25M_HXTAL;
+static void system_clock_200m_25m_hxtal(void);
+
+#endif /* __SYSTEM_CLOCK_IRC16M */
+
+/* configure the system clock */
+static void system_clock_config(void);
+
+/*!
+    \brief      setup the microcontroller system, initialize the system
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void SystemInit (void)
+{
+  /* FPU settings ------------------------------------------------------------*/
+  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
+  #endif
+  /* Reset the RCC clock configuration to the default reset state ------------*/
+  /* Set IRC16MEN bit */
+  RCU_CTL |= RCU_CTL_IRC16MEN;
+
+  /* Reset CFG0 register */
+  RCU_CFG0 = 0x00000000U;
+
+  /* Reset HXTALEN, CKMEN and PLLEN bits */
+  RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
+
+  /* Reset PLLCFGR register */
+  RCU_PLL = 0x24003010U;
+
+  /* Reset HSEBYP bit */
+  RCU_CTL &= ~(RCU_CTL_HXTALBPS);
+
+  /* Disable all interrupts */
+  RCU_INT = 0x00000000U;
+         
+  /* Configure the System clock source, PLL Multiplier and Divider factors, 
+     AHB/APBx prescalers and Flash settings ----------------------------------*/
+  system_clock_config();
+
+
+}
+/*!
+    \brief      configure the system clock
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_config(void)
+{
+#ifdef __SYSTEM_CLOCK_IRC16M
+    system_clock_16m_irc16m();
+#elif defined (__SYSTEM_CLOCK_HXTAL)
+    system_clock_hxtal();
+#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M)
+    system_clock_120m_irc16m();
+#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL)
+    system_clock_120m_8m_hxtal();
+#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL)
+    system_clock_120m_25m_hxtal();
+#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M)
+    system_clock_168m_irc16m();
+#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL)
+    system_clock_168m_8m_hxtal();
+#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL)
+    system_clock_168m_25m_hxtal();
+#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M)
+    system_clock_200m_irc16m();
+#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL)
+    system_clock_200m_8m_hxtal();
+#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL)
+    system_clock_200m_25m_hxtal();
+#endif /* __SYSTEM_CLOCK_IRC16M */   
+}
+
+#ifdef __SYSTEM_CLOCK_IRC16M
+/*!
+    \brief      configure the system clock to 16M by IRC16M
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_16m_irc16m(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable IRC16M */
+    RCU_CTL |= RCU_CTL_IRC16MEN;
+    
+    /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB);
+    }
+    while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout));
+    
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){
+      while(1){
+      }
+    }
+    
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
+    
+    /* select IRC16M as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_IRC16M;
+    
+    /* wait until IRC16M is selected as system clock */
+    while(0 != (RCU_CFG0 & RCU_SCSS_IRC16M)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_HXTAL)
+/*!
+    \brief      configure the system clock to HXTAL
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+    
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+    
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+    
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
+    
+    /* select HXTAL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
+    
+    /* wait until HXTAL is selected as system clock */
+    while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M)
+/*!
+    \brief      configure the system clock to 120M by PLL which selects IRC16M as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_120m_irc16m(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable IRC16M */
+    RCU_CTL |= RCU_CTL_IRC16MEN;
+
+    /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB);
+    }
+    while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* IRC16M is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 16, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ 
+    RCU_PLL = (16U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_IRC16M) | (5U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 120 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL)
+/*!
+    \brief      configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_120m_8m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 8, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ 
+    RCU_PLL = (8U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_HXTAL) | (5U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 120 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL)
+/*!
+    \brief      configure the system clock to 120M by PLL which selects HXTAL(25M) as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_120m_25m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 25, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ 
+    RCU_PLL = (25U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_HXTAL) | (5U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 120 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M)
+/*!
+    \brief      configure the system clock to 168M by PLL which selects IRC16M as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_168m_irc16m(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable IRC16M */
+    RCU_CTL |= RCU_CTL_IRC16MEN;
+
+    /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB);
+    }
+    while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* IRC16M is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 16, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ 
+    RCU_PLL = (16U | (336U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_IRC16M) | (7U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 168 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL)
+/*!
+    \brief      configure the system clock to 168M by PLL which selects HXTAL(8M) as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_168m_8m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    while((0U == (RCU_CTL & RCU_CTL_HXTALSTB)) && (HXTAL_STARTUP_TIMEOUT != timeout++)){
+    }
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 8, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ 
+    RCU_PLL = (8U | (336 << 6U) | (((2 >> 1U) -1U) << 16U) |
+                   (RCU_PLLSRC_HXTAL) | (7 << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+  
+    /* Enable the high-drive to extend the clock frequency to 168 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    }
+
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL)
+/*!
+    \brief      configure the system clock to 168M by PLL which selects HXTAL(25M) as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_168m_25m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 25, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ 
+    RCU_PLL = (25U | (336U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_HXTAL) | (7U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 168 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M)
+/*!
+    \brief      configure the system clock to 200M by PLL which selects IRC16M as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_200m_irc16m(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable IRC16M */
+    RCU_CTL |= RCU_CTL_IRC16MEN;
+
+    /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB);
+    }
+    while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* IRC16M is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 16, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ 
+    RCU_PLL = (16U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_IRC16M) | (9U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 200 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL)
+/*!
+    \brief      configure the system clock to 200M by PLL which selects HXTAL(8M) as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_200m_8m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 8, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ 
+    RCU_PLL = (8U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_HXTAL) | (9U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 200 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL)
+/*!
+    \brief      configure the system clock to 200M by PLL which selects HXTAL(25M) as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_200m_25m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable HXTAL */
+    RCU_CTL |= RCU_CTL_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
+      while(1){
+      }
+    }
+         
+    RCU_APB1EN |= RCU_APB1EN_PMUEN;
+    PMU_CTL |= PMU_CTL_LDOVS;
+
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB/2 */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+    /* APB1 = AHB/4 */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
+
+    /* Configure the main PLL, PLL_M = 25, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ 
+    RCU_PLL = (25U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) |
+                   (RCU_PLLSRC_HXTAL) | (9U << 24U));
+
+    /* enable PLL */
+    RCU_CTL |= RCU_CTL_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
+    }
+    
+    /* Enable the high-drive to extend the clock frequency to 200 Mhz */
+    PMU_CTL |= PMU_CTL_HDEN;
+    while(0U == (PMU_CS & PMU_CS_HDRF))
+    {
+    }
+    
+    /* select the high-drive mode */
+    PMU_CTL |= PMU_CTL_HDS;
+    while(0U == (PMU_CS & PMU_CS_HDSRF))
+    {
+    } 
+    
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
+    }
+}
+
+#endif /* __SYSTEM_CLOCK_IRC16M */
+/*!
+    \brief      update the SystemCoreClock with current core clock retrieved from cpu registers
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void SystemCoreClockUpdate (void)
+{
+    uint32_t sws;
+    uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp;
+    
+    /* exponent of AHB, APB1 and APB2 clock divider */
+    const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+    sws = GET_BITS(RCU_CFG0, 2, 3);
+    switch(sws){
+    /* IRC16M is selected as CK_SYS */
+    case SEL_IRC16M:
+        SystemCoreClock = IRC16M_VALUE;
+        break;
+    /* HXTAL is selected as CK_SYS */
+    case SEL_HXTAL:
+        SystemCoreClock = HXTAL_VALUE;
+        break;
+    /* PLLP is selected as CK_SYS */
+    case SEL_PLLP:
+        /* get the value of PLLPSC[5:0] */
+        pllpsc = GET_BITS(RCU_PLL, 0U, 5U);
+        plln = GET_BITS(RCU_PLL, 6U, 14U);
+        pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U;
+        /* PLL clock source selection, HXTAL or IRC8M/2 */
+        pllsel = (RCU_PLL & RCU_PLL_PLLSEL);
+        if (RCU_PLLSRC_HXTAL == pllsel) {
+            ck_src = HXTAL_VALUE;
+        } else {
+            ck_src = IRC16M_VALUE;
+        }
+        SystemCoreClock = ((ck_src / pllpsc) * plln)/pllp;
+        break;
+    /* IRC16M is selected as CK_SYS */
+    default:
+        SystemCoreClock = IRC16M_VALUE;
+        break;
+    }
+    /* calculate AHB clock frequency */
+    idx = GET_BITS(RCU_CFG0, 4, 7);
+    clk_exp = ahb_exp[idx];
+    SystemCoreClock = SystemCoreClock >> clk_exp;
+}

+ 1790 - 0
bsp/gd32450z-eval/Libraries/CMSIS/core_cm4.h

@@ -0,0 +1,1790 @@
+/**************************************************************************//**
+ * @file     core_cm4.h
+ * @brief    CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version  V3.30
+ * @date     17. February 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+/** \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  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM4_CMSIS_VERSION_SUB   (0x20)                                   /*!< [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__ )		/* Cosmic */
+  #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_cm4_simd.h>               /* Compiler specific SIMD Intrinsics               */
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+/* 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
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[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_VAL_CURRENT_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_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL << TPI_DEVTYPE_SubType_Pos)          /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType 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)0x07);               /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */
+  reg_value  =  (reg_value                                 |
+                ((uint32_t)0x5FA << 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 ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);   /* read priority grouping field */
+}
+
+
+/** \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)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));  enable interrupt */
+  NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */
+}
+
+
+/** \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)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \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)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \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)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \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)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M  System Interrupts */
+  else {
+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M  system interrupts */
+  else {
+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \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 samllest 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 & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  return (
+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
+         );
+}
+
+
+/** \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 samllest 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 & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### 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)                  &&      /* ITM enabled */
+      (ITM->TER & (1UL << 0)        )                    )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0);
+    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 */
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif

+ 697 - 0
bsp/gd32450z-eval/Libraries/CMSIS/core_cm4_simd.h

@@ -0,0 +1,697 @@
+/**************************************************************************//**
+ * @file     core_cm4_simd.h
+ * @brief    CMSIS Cortex-M4 SIMD Header File
+ * @version  V3.30
+ * @date     17. February 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifndef __CORE_CM4_SIMD_H
+#define __CORE_CM4_SIMD_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_CM4_SIMD_H */

+ 664 - 0
bsp/gd32450z-eval/Libraries/CMSIS/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
bsp/gd32450z-eval/Libraries/CMSIS/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 */

+ 461 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h

@@ -0,0 +1,461 @@
+/*!
+    \file  gd32f4xx_adc.h
+    \brief definitions for the ADC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_ADC_H
+#define GD32F4XX_ADC_H
+
+#include "gd32f4xx.h"
+
+/* ADC definitions */
+#define ADC0                            ADC_BASE
+#define ADC1                            (ADC_BASE + 0x100U)
+#define ADC2                            (ADC_BASE + 0x200U)
+
+/* registers definitions */
+#define ADC_STAT(adcx)                  REG32((adcx) + 0x00U)             /*!< ADC status register */
+#define ADC_CTL0(adcx)                  REG32((adcx) + 0x04U)             /*!< ADC control register 0 */
+#define ADC_CTL1(adcx)                  REG32((adcx) + 0x08U)             /*!< ADC control register 1 */
+#define ADC_SAMPT0(adcx)                REG32((adcx) + 0x0CU)             /*!< ADC sampling time register 0 */
+#define ADC_SAMPT1(adcx)                REG32((adcx) + 0x10U)             /*!< ADC sampling time register 1 */
+#define ADC_IOFF0(adcx)                 REG32((adcx) + 0x14U)             /*!< ADC inserted channel data offset register 0 */
+#define ADC_IOFF1(adcx)                 REG32((adcx) + 0x18U)             /*!< ADC inserted channel data offset register 1 */
+#define ADC_IOFF2(adcx)                 REG32((adcx) + 0x1CU)             /*!< ADC inserted channel data offset register 2 */
+#define ADC_IOFF3(adcx)                 REG32((adcx) + 0x20U)             /*!< ADC inserted channel data offset register 3 */
+#define ADC_WDHT(adcx)                  REG32((adcx) + 0x24U)             /*!< ADC watchdog high threshold register */
+#define ADC_WDLT(adcx)                  REG32((adcx) + 0x28U)             /*!< ADC watchdog low threshold register */
+#define ADC_RSQ0(adcx)                  REG32((adcx) + 0x2CU)             /*!< ADC regular sequence register 0 */
+#define ADC_RSQ1(adcx)                  REG32((adcx) + 0x30U)             /*!< ADC regular sequence register 1 */
+#define ADC_RSQ2(adcx)                  REG32((adcx) + 0x34U)             /*!< ADC regular sequence register 2 */
+#define ADC_ISQ(adcx)                   REG32((adcx) + 0x38U)             /*!< ADC inserted sequence register */
+#define ADC_IDATA0(adcx)                REG32((adcx) + 0x3CU)             /*!< ADC inserted data register 0 */
+#define ADC_IDATA1(adcx)                REG32((adcx) + 0x40U)             /*!< ADC inserted data register 1 */
+#define ADC_IDATA2(adcx)                REG32((adcx) + 0x44U)             /*!< ADC inserted data register 2 */
+#define ADC_IDATA3(adcx)                REG32((adcx) + 0x48U)             /*!< ADC inserted data register 3 */
+#define ADC_RDATA(adcx)                 REG32((adcx) + 0x4CU)             /*!< ADC regular data register */
+#define ADC_OVSAMPCTL(adcx)             REG32((adcx) + 0x80U)             /*!< ADC oversampling control register */
+#define ADC_SSTAT                       REG32((ADC_BASE) + 0x300U)        /*!< ADC summary status register */
+#define ADC_SYNCCTL                     REG32((ADC_BASE) + 0x304U)        /*!< ADC synchronization control register */
+#define ADC_SYNCDATA                    REG32((ADC_BASE) + 0x308U)        /*!< ADC synchronization regular data register */
+
+/* bits definitions */
+/* ADC_STAT */
+#define ADC_STAT_WDE                    BIT(0)                           /*!< analog watchdog event flag */
+#define ADC_STAT_EOC                    BIT(1)                           /*!< end of conversion */
+#define ADC_STAT_EOIC                   BIT(2)                           /*!< inserted channel end of conversion */
+#define ADC_STAT_STIC                   BIT(3)                           /*!< inserted channel start flag */
+#define ADC_STAT_STRC                   BIT(4)                           /*!< regular channel start flag */
+#define ADC_STAT_ROVF                   BIT(5)                           /*!< regular data register overflow */
+
+/* ADC_CTL0 */
+#define ADC_CTL0_WDCHSEL                BITS(0,4)                        /*!< analog watchdog channel select bits */
+#define ADC_CTL0_EOCIE                  BIT(5)                           /*!< interrupt enable for EOC */
+#define ADC_CTL0_WDEIE                  BIT(6)                           /*!< analog watchdog interrupt enable */
+#define ADC_CTL0_EOICIE                 BIT(7)                           /*!< interrupt enable for inserted channels */
+#define ADC_CTL0_SM                     BIT(8)                           /*!< scan mode */
+#define ADC_CTL0_WDSC                   BIT(9)                           /*!< when in scan mode, analog watchdog is effective on a single channel */
+#define ADC_CTL0_ICA                    BIT(10)                          /*!< automatic inserted group conversion */
+#define ADC_CTL0_DISRC                  BIT(11)                          /*!< discontinuous mode on regular channels */
+#define ADC_CTL0_DISIC                  BIT(12)                          /*!< discontinuous mode on inserted channels */
+#define ADC_CTL0_DISNUM                 BITS(13,15)                      /*!< discontinuous mode channel count */
+#define ADC_CTL0_IWDEN                  BIT(22)                          /*!< analog watchdog enable on inserted channels */
+#define ADC_CTL0_RWDEN                  BIT(23)                          /*!< analog watchdog enable on regular channels */
+#define ADC_CTL0_DRES                   BITS(24,25)                      /*!< ADC data resolution */
+#define ADC_CTL0_ROVFIE                 BIT(26)                          /*!< interrupt enable for ROVF */ 
+
+/* ADC_CTL1 */
+#define ADC_CTL1_ADCON                  BIT(0)                           /*!< ADC converter on */
+#define ADC_CTL1_CTN                    BIT(1)                           /*!< continuous conversion */
+#define ADC_CTL1_CLB                    BIT(2)                           /*!< ADC calibration */
+#define ADC_CTL1_RSTCLB                 BIT(3)                           /*!< reset calibration */
+#define ADC_CTL1_DMA                    BIT(8)                           /*!< direct memory access mode */
+#define ADC_CTL1_DDM                    BIT(9)                           /*!< DMA disable mode */
+#define ADC_CTL1_EOCM                   BIT(10)                          /*!< end of conversion mode */
+#define ADC_CTL1_DAL                    BIT(11)                          /*!< data alignment */
+#define ADC_CTL1_ETSIC                  BITS(16,19)                      /*!< external event select for inserted group */
+#define ADC_CTL1_ETMIC                  BITS(20,21)                      /*!< external trigger conversion mode for inserted channels */
+#define ADC_CTL1_SWICST                 BIT(22)                          /*!< start conversion of inserted channels */
+#define ADC_CTL1_ETSRC                  BITS(24,27)                      /*!< external event select for regular group */
+#define ADC_CTL1_ETMRC                  BITS(28,29)                      /*!< external trigger conversion mode for regular channels */
+#define ADC_CTL1_SWRCST                 BIT(30)                          /*!< start conversion of regular channels */
+
+/* ADC_SAMPTx x=0..1 */
+#define ADC_SAMPTX_SPTN                 BITS(0,2)                        /*!< channel x sample time selection */
+
+/* ADC_IOFFx x=0..3 */
+#define ADC_IOFFX_IOFF                  BITS(0,11)                       /*!< data offset for inserted channel x */
+
+/* ADC_WDHT */
+#define ADC_WDHT_WDHT                   BITS(0,11)                       /*!< analog watchdog high threshold */
+
+/* ADC_WDLT */
+#define ADC_WDLT_WDLT                   BITS(0,11)                       /*!< analog watchdog low threshold */
+
+/* ADC_RSQx */
+#define ADC_RSQX_RSQN                   BITS(0,4)                        /*!< x conversion in regular sequence */
+#define ADC_RSQ0_RL                     BITS(20,23)                      /*!< regular channel sequence length */
+
+/* ADC_ISQ */
+#define ADC_ISQ_ISQN                    BITS(0,4)                        /*!< x conversion in regular sequence */
+#define ADC_ISQ_IL                      BITS(20,21)                      /*!< inserted sequence length */
+
+/* ADC_IDATAx x=0..3*/
+#define ADC_IDATAX_IDATAN               BITS(0,15)                       /*!< inserted data x */
+
+/* ADC_RDATA */
+#define ADC_RDATA_RDATA                 BITS(0,15)                       /*!< regular data */
+
+/* ADC_OVSAMPCTL */
+#define ADC_OVSAMPCTL_OVSEN             BIT(0)                           /*!< oversampling enable */
+#define ADC_OVSAMPCTL_OVSR              BITS(2,4)                        /*!< oversampling ratio */
+#define ADC_OVSAMPCTL_OVSS              BITS(5,8)                        /*!< oversampling shift */
+#define ADC_OVSAMPCTL_TOVS              BIT(9)                           /*!< triggered oversampling */
+
+/* ADC_SSTAT */
+#define ADC_SSTAT_WDE0                  BIT(0)                           /*!< the mirror image of the WDE bit of ADC0 */
+#define ADC_SSTAT_EOC0                  BIT(1)                           /*!< the mirror image of the EOC bit of ADC0 */
+#define ADC_SSTAT_EOIC0                 BIT(2)                           /*!< the mirror image of the EOIC bit of ADC0 */
+#define ADC_SSTAT_STIC0                 BIT(3)                           /*!< the mirror image of the STIC bit of ADC0 */
+#define ADC_SSTAT_STRC0                 BIT(4)                           /*!< the mirror image of the STRC bit of ADC0 */
+#define ADC_SSTAT_ROVF0                 BIT(5)                           /*!< the mirror image of the ROVF bit of ADC0 */
+#define ADC_SSTAT_WDE1                  BIT(8)                           /*!< the mirror image of the WDE bit of ADC1 */
+#define ADC_SSTAT_EOC1                  BIT(9)                           /*!< the mirror image of the EOC bit of ADC1 */
+#define ADC_SSTAT_EOIC1                 BIT(10)                          /*!< the mirror image of the EOIC bit of ADC1 */
+#define ADC_SSTAT_STIC1                 BIT(11)                          /*!< the mirror image of the STIC bit of ADC1 */
+#define ADC_SSTAT_STRC1                 BIT(12)                          /*!< the mirror image of the STRC bit of ADC1 */
+#define ADC_SSTAT_ROVF1                 BIT(13)                          /*!< the mirror image of the ROVF bit of ADC1 */
+#define ADC_SSTAT_WDE2                  BIT(16)                          /*!< the mirror image of the WDE bit of ADC2 */
+#define ADC_SSTAT_EOC2                  BIT(17)                          /*!< the mirror image of the EOC bit of ADC2 */
+#define ADC_SSTAT_EOIC2                 BIT(18)                          /*!< the mirror image of the EOIC bit of ADC2 */
+#define ADC_SSTAT_STIC2                 BIT(19)                          /*!< the mirror image of the STIC bit of ADC2 */
+#define ADC_SSTAT_STRC2                 BIT(20)                          /*!< the mirror image of the STRC bit of ADC2 */
+#define ADC_SSTAT_ROVF2                 BIT(21)                          /*!< the mirror image of the ROVF bit of ADC2 */
+
+/* ADC_SYNCCTL */
+#define ADC_SYNCCTL_SYNCM               BITS(0,4)                        /*!< ADC synchronization mode */
+#define ADC_SYNCCTL_SYNCDLY             BITS(8,11)                       /*!< ADC synchronization delay */
+#define ADC_SYNCCTL_SYNCDDM             BIT(13)                          /*!< ADC synchronization DMA disable mode */
+#define ADC_SYNCCTL_SYNCDMA             BITS(14,15)                      /*!< ADC synchronization DMA mode selection */
+#define ADC_SYNCCTL_ADCCK               BITS(16,18)                      /*!< ADC clock */
+#define ADC_SYNCCTL_VBATEN              BIT(22)                          /*!< channel 18 (1/4 voltate of external battery) enable of ADC0 */
+#define ADC_SYNCCTL_TSVREN              BIT(23)                          /*!< channel 16 (temperature sensor) and 17 (internal reference voltage) enable of ADC0 */
+
+/* ADC_SYNCDATA */
+#define ADC_SYNCDATA_SYNCDATA0          BITS(0,15)                       /*!< regular data1 in ADC synchronization mode */
+#define ADC_SYNCDATA_SYNCDATA1          BITS(16,31)                      /*!< regular data2 in ADC synchronization mode */
+
+/* constants definitions */
+/* ADC channel group definitions */
+#define ADC_REGULAR_CHANNEL             ((uint8_t)0x00U)                  /*!< adc regular channel group */
+#define ADC_INSERTED_CHANNEL            ((uint8_t)0x01U)                  /*!< adc inserted channel group */
+#define ADC_REGULAR_INSERTED_CHANNEL    ((uint8_t)0x02U)                  /*!< both regular and inserted channel group */
+
+/* external trigger mode for regular and inserted  channel */
+#define EXTERNAL_TRIGGER_DISABLE        ((uint32_t)0x00000000U)           /*!< external trigger disable */
+#define EXTERNAL_TRIGGER_RISING         ((uint32_t)0x00000001U)           /*!< rising edge of external trigger */
+#define EXTERNAL_TRIGGER_FALLING        ((uint32_t)0x00000002U)           /*!< falling edge of external trigger */
+#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U)           /*!< rising and falling edge of external trigger */
+
+/* ADC inserted channel definitions */
+#define ADC_INSERTED_CHANNEL_0          ((uint8_t)0x00U)                  /*!< adc inserted channel 0 */
+#define ADC_INSERTED_CHANNEL_1          ((uint8_t)0x01U)                  /*!< adc inserted channel 1 */
+#define ADC_INSERTED_CHANNEL_2          ((uint8_t)0x02U)                  /*!< adc inserted channel 2 */
+#define ADC_INSERTED_CHANNEL_3          ((uint8_t)0x03U)                  /*!< adc inserted channel 3 */
+
+/* ADC special function definitions */
+#define ADC_SCAN_MODE                   ((uint8_t)0x00U)                  /*!< scan mode */
+#define ADC_INSERTED_CHANNEL_AUTO       ((uint8_t)0x01U)                  /*!< inserted channel group convert automatically */
+#define ADC_VBAT_CHANNEL_SWITCH         ((uint8_t)0x02U)                  /*!< VBAT channel */
+#define ADC_TEMP_VREF_CHANNEL_SWITCH    ((uint8_t)0x03U)                  /*!< Vref and Vtemp channel */
+#define ADC_CONTINUOUS_MODE             ((uint8_t)0x04U)                  /*!< continuous mode */
+
+/* ADC channel definitions */
+#define ADC_CHANNEL_0                   ((uint8_t)0x00U)                  /*!< ADC channel 0 */
+#define ADC_CHANNEL_1                   ((uint8_t)0x01U)                  /*!< ADC channel 1 */
+#define ADC_CHANNEL_2                   ((uint8_t)0x02U)                  /*!< ADC channel 2 */
+#define ADC_CHANNEL_3                   ((uint8_t)0x03U)                  /*!< ADC channel 3 */
+#define ADC_CHANNEL_4                   ((uint8_t)0x04U)                  /*!< ADC channel 4 */
+#define ADC_CHANNEL_5                   ((uint8_t)0x05U)                  /*!< ADC channel 5 */
+#define ADC_CHANNEL_6                   ((uint8_t)0x06U)                  /*!< ADC channel 6 */
+#define ADC_CHANNEL_7                   ((uint8_t)0x07U)                  /*!< ADC channel 7 */
+#define ADC_CHANNEL_8                   ((uint8_t)0x08U)                  /*!< ADC channel 8 */
+#define ADC_CHANNEL_9                   ((uint8_t)0x09U)                  /*!< ADC channel 9 */
+#define ADC_CHANNEL_10                  ((uint8_t)0x0AU)                  /*!< ADC channel 10 */
+#define ADC_CHANNEL_11                  ((uint8_t)0x0BU)                  /*!< ADC channel 11 */
+#define ADC_CHANNEL_12                  ((uint8_t)0x0CU)                  /*!< ADC channel 12 */
+#define ADC_CHANNEL_13                  ((uint8_t)0x0DU)                  /*!< ADC channel 13 */
+#define ADC_CHANNEL_14                  ((uint8_t)0x0EU)                  /*!< ADC channel 14 */
+#define ADC_CHANNEL_15                  ((uint8_t)0x0FU)                  /*!< ADC channel 15 */
+#define ADC_CHANNEL_16                  ((uint8_t)0x10U)                  /*!< ADC channel 16 */
+#define ADC_CHANNEL_17                  ((uint8_t)0x11U)                  /*!< ADC channel 17 */
+#define ADC_CHANNEL_18                  ((uint8_t)0x12U)                  /*!< ADC channel 18 */
+
+/* ADC channel sample time */
+#define ADC_SAMPLETIME_3                ((uint8_t)0x00U)                  /*!< 3 sampling cycles */
+#define ADC_SAMPLETIME_15               ((uint8_t)0x01U)                  /*!< 15 sampling cycles */
+#define ADC_SAMPLETIME_28               ((uint8_t)0x02U)                  /*!< 28 sampling cycles */
+#define ADC_SAMPLETIME_56               ((uint8_t)0x03U)                  /*!< 56 sampling cycles */
+#define ADC_SAMPLETIME_84               ((uint8_t)0x04U)                  /*!< 84 sampling cycles */
+#define ADC_SAMPLETIME_112              ((uint8_t)0x05U)                  /*!< 112 sampling cycles */
+#define ADC_SAMPLETIME_144              ((uint8_t)0x06U)                  /*!< 144 sampling cycles */
+#define ADC_SAMPLETIME_480              ((uint8_t)0x07U)                  /*!< 480 sampling cycles */
+
+/* ADC data alignment */
+#define ADC_DATAALIGN_RIGHT             ((uint8_t)0x00U)                  /*!< LSB alignment */
+#define ADC_DATAALIGN_LEFT              ((uint8_t)0x01U)                  /*!< MSB alignment */
+
+/* ADC status flag */
+#define ADC_FLAG_WDE                    ADC_STAT_WDE                     /*!< analog watchdog event flag */
+#define ADC_FLAG_EOC                    ADC_STAT_EOC                     /*!< end of conversion */
+#define ADC_FLAG_EOIC                   ADC_STAT_EOIC                    /*!< inserted channel end of conversion */
+#define ADC_FLAG_STIC                   ADC_STAT_STIC                    /*!< inserted channel start flag */
+#define ADC_FLAG_STRC                   ADC_STAT_STRC                    /*!< regular channel start flag */
+#define ADC_FLAG_ROVF                   ADC_STAT_ROVF                    /*!< regular data register overflow */
+
+/* ADC interrupt flag */
+#define ADC_INT_WDE                     ADC_STAT_WDE                     /*!< analog watchdog event interrupt */
+#define ADC_INT_EOC                     ADC_STAT_EOC                     /*!< end of group conversion interrupt */
+#define ADC_INT_EOIC                    ADC_STAT_EOIC                    /*!< end of inserted group conversion interrupt */
+#define ADC_INT_ROVF                    ADC_STAT_ROVF                    /*!< regular data register overflow */
+
+/* ADC resolution definitions */
+#define CTL0_DRES(regval)               (BITS(24,25) & ((uint32_t)(regval) << 24))
+#define ADC_RESOLUTION_12B              CTL0_DRES(0)                     /*!< 12-bit ADC resolution */
+#define ADC_RESOLUTION_10B              CTL0_DRES(1)                     /*!< 10-bit ADC resolution */
+#define ADC_RESOLUTION_8B               CTL0_DRES(2)                     /*!< 8-bit ADC resolution */
+#define ADC_RESOLUTION_6B               CTL0_DRES(3)                     /*!< 6-bit ADC resolution */
+
+/* ADC external trigger select for regular channel */
+#define CTL1_ETSRC(regval)              (BITS(24,27) & ((uint32_t)(regval) << 24))
+#define ADC_EXTTRIG_REGULAR_T0_CH0      CTL1_ETSRC(0)                    /*!< timer 0 CC0 event select */
+#define ADC_EXTTRIG_REGULAR_T0_CH1      CTL1_ETSRC(1)                    /*!< timer 0 CC1 event select */
+#define ADC_EXTTRIG_REGULAR_T0_CH2      CTL1_ETSRC(2)                    /*!< timer 0 CC2 event select */
+#define ADC_EXTTRIG_REGULAR_T1_CH1      CTL1_ETSRC(3)                    /*!< timer 1 CC1 event select */
+#define ADC_EXTTRIG_REGULAR_T1_CH2      CTL1_ETSRC(4)                    /*!< timer 1 CC2 event select */
+#define ADC_EXTTRIG_REGULAR_T1_CH3      CTL1_ETSRC(5)                    /*!< timer 1 CC3 event select */
+#define ADC_EXTTRIG_REGULAR_T1_TRGO     CTL1_ETSRC(6)                    /*!< timer 1 TRGO event select */
+#define ADC_EXTTRIG_REGULAR_T2_CH0      CTL1_ETSRC(7)                    /*!< timer 2 CC0 event select */
+#define ADC_EXTTRIG_REGULAR_T2_TRGO     CTL1_ETSRC(8)                    /*!< timer 2 TRGO event select */
+#define ADC_EXTTRIG_REGULAR_T3_CH3      CTL1_ETSRC(9)                    /*!< timer 3 CC3 event select */
+#define ADC_EXTTRIG_REGULAR_T4_CH0      CTL1_ETSRC(10)                   /*!< timer 4 CC0 event select */
+#define ADC_EXTTRIG_REGULAR_T4_CH1      CTL1_ETSRC(11)                   /*!< timer 4 CC1 event select */
+#define ADC_EXTTRIG_REGULAR_T4_CH2      CTL1_ETSRC(12)                   /*!< timer 4 CC2 event select */
+#define ADC_EXTTRIG_REGULAR_T7_CH0      CTL1_ETSRC(13)                   /*!< timer 7 CC0 event select */
+#define ADC_EXTTRIG_REGULAR_T7_TRGO     CTL1_ETSRC(14)                   /*!< timer 7 TRGO event select */
+#define ADC_EXTTRIG_REGULAR_EXTI_11     CTL1_ETSRC(15)                   /*!< extiline 11 select  */
+
+/* ADC external trigger select for inserted channel */
+#define CTL1_ETSIC(regval)              (BITS(16,19) & ((uint32_t)(regval) << 16))
+#define ADC_EXTTRIG_INSERTED_T0_CH3     CTL1_ETSIC(0)                    /*!< timer0 capture compare 3 */
+#define ADC_EXTTRIG_INSERTED_T0_TRGO    CTL1_ETSIC(1)                    /*!< timer0 TRGO event */
+#define ADC_EXTTRIG_INSERTED_T1_CH0     CTL1_ETSIC(2)                    /*!< timer1 capture compare 0 */
+#define ADC_EXTTRIG_INSERTED_T1_TRGO    CTL1_ETSIC(3)                    /*!< timer1 TRGO event */
+#define ADC_EXTTRIG_INSERTED_T2_CH1     CTL1_ETSIC(4)                    /*!< timer2 capture compare 1 */
+#define ADC_EXTTRIG_INSERTED_T2_CH3     CTL1_ETSIC(5)                    /*!< timer2 capture compare 3 */
+#define ADC_EXTTRIG_INSERTED_T3_CH0     CTL1_ETSIC(6)                    /*!< timer3 capture compare 0 */
+#define ADC_EXTTRIG_INSERTED_T3_CH1     CTL1_ETSIC(7)                    /*!< timer3 capture compare 1 */
+#define ADC_EXTTRIG_INSERTED_T3_CH2     CTL1_ETSIC(8)                    /*!< timer3 capture compare 2 */
+#define ADC_EXTTRIG_INSERTED_T3_TRGO    CTL1_ETSIC(9)                    /*!< timer3 capture compare TRGO */
+#define ADC_EXTTRIG_INSERTED_T4_CH3     CTL1_ETSIC(10)                   /*!< timer4 capture compare 3 */
+#define ADC_EXTTRIG_INSERTED_T4_TRGO    CTL1_ETSIC(11)                   /*!< timer4 capture compare TRGO */
+#define ADC_EXTTRIG_INSERTED_T7_CH1     CTL1_ETSIC(12)                   /*!< timer7 capture compare 1 */
+#define ADC_EXTTRIG_INSERTED_T7_CH2     CTL1_ETSIC(13)                   /*!< timer7 capture compare 2 */
+#define ADC_EXTTRIG_INSERTED_T7_CH3     CTL1_ETSIC(14)                   /*!< timer7 capture compare 3 */
+#define ADC_EXTTRIG_INSERTED_EXTI_15    CTL1_ETSIC(15)                   /*!< external interrupt line 15 */
+
+/* ADC oversampling mode */
+#define ADC_OVERSAMPLING_ALL_CONVERT    0U                                /*!< all oversampled conversions for a channel are done consecutively after a trigger */
+#define ADC_OVERSAMPLING_ONE_CONVERT    1U                                /*!< each oversampled conversion for a channel needs a trigger */
+
+/* ADC oversampling shift */
+#define OVCTL_OVSS(regval)              (BITS(5,8) & ((uint32_t)(regval) << 5))
+#define ADC_OVERSAMPLING_SHIFT_NONE     OVCTL_OVSS(0)                    /*!< no oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_1B       OVCTL_OVSS(1)                    /*!< 1-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_2B       OVCTL_OVSS(2)                    /*!< 2-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_3B       OVCTL_OVSS(3)                    /*!< 3-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_4B       OVCTL_OVSS(4)                    /*!< 4-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_5B       OVCTL_OVSS(5)                    /*!< 5-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_6B       OVCTL_OVSS(6)                    /*!< 6-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_7B       OVCTL_OVSS(7)                    /*!< 7-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_8B       OVCTL_OVSS(8)                    /*!< 8-bit oversampling shift */
+
+/* ADC oversampling ratio */
+#define OVCTL_OVSR(regval)              (BITS(2,4) & ((uint32_t)(regval) << 2))
+#define ADC_OVERSAMPLING_RATIO_MUL2       OVCTL_OVSR(0)                  /*!< oversampling ratio multiple 2 */
+#define ADC_OVERSAMPLING_RATIO_MUL4       OVCTL_OVSR(1)                  /*!< oversampling ratio multiple 4 */
+#define ADC_OVERSAMPLING_RATIO_MUL8       OVCTL_OVSR(2)                  /*!< oversampling ratio multiple 8 */
+#define ADC_OVERSAMPLING_RATIO_MUL16      OVCTL_OVSR(3)                  /*!< oversampling ratio multiple 16 */
+#define ADC_OVERSAMPLING_RATIO_MUL32      OVCTL_OVSR(4)                  /*!< oversampling ratio multiple 32 */
+#define ADC_OVERSAMPLING_RATIO_MUL64      OVCTL_OVSR(5)                  /*!< oversampling ratio multiple 64 */
+#define ADC_OVERSAMPLING_RATIO_MUL128     OVCTL_OVSR(6)                  /*!< oversampling ratio multiple 128 */
+#define ADC_OVERSAMPLING_RATIO_MUL256     OVCTL_OVSR(7)                  /*!< oversampling ratio multiple 256 */
+
+/* configure the ADC clock for all the ADCs */
+#define SYNCCTL_ADCCK(regval)           (BITS(16,18) & ((uint32_t)(regval) << 16))
+#define ADC_ADCCK_PCLK2_DIV2            SYNCCTL_ADCCK(0)                 /*!< PCLK2 div2 */
+#define ADC_ADCCK_PCLK2_DIV4            SYNCCTL_ADCCK(1)                 /*!< PCLK2 div4 */
+#define ADC_ADCCK_PCLK2_DIV6            SYNCCTL_ADCCK(2)                 /*!< PCLK2 div6 */
+#define ADC_ADCCK_PCLK2_DIV8            SYNCCTL_ADCCK(3)                 /*!< PCLK2 div8 */
+#define ADC_ADCCK_HCLK_DIV5             SYNCCTL_ADCCK(4)                 /*!< HCLK div5 */
+#define ADC_ADCCK_HCLK_DIV6             SYNCCTL_ADCCK(5)                 /*!< HCLK div6 */
+#define ADC_ADCCK_HCLK_DIV10            SYNCCTL_ADCCK(6)                 /*!< HCLK div10 */
+#define ADC_ADCCK_HCLK_DIV20            SYNCCTL_ADCCK(7)                 /*!< HCLK div20 */
+
+/* ADC synchronization mode */
+#define ADC_SYNC_MODE_INDEPENDENT                           ((uint32_t)0x00000000U)    /*!< ADC synchronization mode disabled.All the ADCs work independently */
+#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL         ((uint32_t)0x00000001U)    /*!< ADC0 and ADC1 work in combined regular parallel & inserted parallel mode. ADC2 works independently */
+#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION         ((uint32_t)0x00000002U)    /*!< ADC0 and ADC1 work in combined regular parallel & trigger rotation mode. ADC2 works independently */
+#define ADC_DAUL_INSERTED_PARALLEL                          ((uint32_t)0x00000005U)    /*!< ADC0 and ADC1 work in inserted parallel mode. ADC2 works independently */
+#define ADC_DAUL_REGULAL_PARALLEL                           ((uint32_t)0x00000006U)    /*!< ADC0 and ADC1 work in regular parallel mode. ADC2 works independently */
+#define ADC_DAUL_REGULAL_FOLLOW_UP                          ((uint32_t)0x00000007U)    /*!< ADC0 and ADC1 work in follow-up mode. ADC2 works independently */
+#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION                 ((uint32_t)0x00000009U)    /*!< ADC0 and ADC1 work in trigger rotation mode. ADC2 works independently */
+#define ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL          ((uint32_t)0x00000011U)    /*!< all ADCs work in combined regular parallel & inserted parallel mode */
+#define ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION          ((uint32_t)0x00000012U)    /*!< all ADCs work in combined regular parallel & trigger rotation mode */
+#define ADC_ALL_INSERTED_PARALLEL                           ((uint32_t)0x00000015U)    /*!< all ADCs work in inserted parallel mode */
+#define ADC_ALL_REGULAL_PARALLEL                            ((uint32_t)0x00000016U)    /*!< all ADCs work in regular parallel mode */
+#define ADC_ALL_REGULAL_FOLLOW_UP                           ((uint32_t)0x00000017U)    /*!< all ADCs work in follow-up mode */
+#define ADC_ALL_INSERTED_TRRIGGER_ROTATION                  ((uint32_t)0x00000019U)    /*!< all ADCs work in trigger rotation mode */
+
+/* ADC synchronization delay */
+#define ADC_SYNC_DELAY_5CYCLE                               ((uint32_t)0x00000000U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */
+#define ADC_SYNC_DELAY_6CYCLE                               ((uint32_t)0x00000100U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */
+#define ADC_SYNC_DELAY_7CYCLE                               ((uint32_t)0x00000200U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */
+#define ADC_SYNC_DELAY_8CYCLE                               ((uint32_t)0x00000300U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */
+#define ADC_SYNC_DELAY_9CYCLE                               ((uint32_t)0x00000400U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */
+#define ADC_SYNC_DELAY_10CYCLE                              ((uint32_t)0x00000500U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */
+#define ADC_SYNC_DELAY_11CYCLE                              ((uint32_t)0x00000600U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */
+#define ADC_SYNC_DELAY_12CYCLE                              ((uint32_t)0x00000700U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */
+#define ADC_SYNC_DELAY_13CYCLE                              ((uint32_t)0x00000800U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */
+#define ADC_SYNC_DELAY_14CYCLE                              ((uint32_t)0x00000900U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */
+#define ADC_SYNC_DELAY_15CYCLE                              ((uint32_t)0x00000A00U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */
+#define ADC_SYNC_DELAY_16CYCLE                              ((uint32_t)0x00000B00U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */
+#define ADC_SYNC_DELAY_17CYCLE                              ((uint32_t)0x00000C00U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */
+#define ADC_SYNC_DELAY_18CYCLE                              ((uint32_t)0x00000D00U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */
+#define ADC_SYNC_DELAY_19CYCLE                              ((uint32_t)0x00000E00U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */
+#define ADC_SYNC_DELAY_20CYCLE                              ((uint32_t)0x00000F00U)    /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */
+
+/* ADC synchronization DMA mode selection */
+#define ADC_SYNC_DMA_DISABLE                                ((uint32_t)0x00000000U)    /*!< ADC synchronization DMA disabled */
+#define ADC_SYNC_DMA_MODE0                                  ((uint32_t)0x00004000U)    /*!< ADC synchronization DMA mode 0 */
+#define ADC_SYNC_DMA_MODE1                                  ((uint32_t)0x00008000U)    /*!< ADC synchronization DMA mode 1 */
+
+/* end of conversion mode */
+#define ADC_EOC_SET_SEQUENCE                                ((uint8_t)0x00U)           /*!< only at the end of a sequence of regular conversions, the EOC bit is set */
+#define ADC_EOC_SET_CONVERSION                              ((uint8_t)0x01U)           /*!< at the end of each regular conversion, the EOC bit is set */
+
+/* function declarations */
+/* ADC reset */
+void adc_deinit(void);
+/* enable ADC interface */
+void adc_enable(uint32_t adc_periph);
+/* disable ADC interface */
+void adc_disable(uint32_t adc_periph);
+/* ADC data alignment config */
+void adc_data_alignment_config(uint32_t adc_periph , uint8_t data_alignment);
+/* ADC resolution config */
+void adc_resolution_config(uint32_t adc_periph , uint32_t resolution);
+/* ADC calibration and reset calibration */
+void adc_calibration_enable(uint32_t adc_periph);
+/* ADC discontinuous mode config */
+void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length);
+/* config end of conversion mode */
+void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection);
+/* ADC special function enable or disable */
+void adc_special_function_config(uint32_t adc_periph , uint8_t function , ControlStatus newvalue);
+/* configure the ADC clock for all the ADCs */
+void adc_clock_config(uint32_t prescaler);
+
+/* ADC channel */
+/* configure the ADC clock for all the ADCs */
+void adc_channel_16_to_18(uint8_t function,ControlStatus newvalue);
+/* config the length of regular channel group or inserted channel group */
+void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length);
+
+/* ADC trigger */
+/* ADC external trigger enable */
+void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode);
+/* ADC external trigger source config */
+void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source);
+/* ADC software trigger enable */
+void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group);
+
+/* ADC flag and interrupt */
+/* get the ADC flag bits */
+FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag);
+/* clear the ADC flag bits */
+void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag);
+/* get the ADC interrupt bits */
+FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt);
+/* clear the ADC flag */
+void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt);
+/* ADC interrupt enable */
+void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt);
+/* ADC interrupt disable */
+void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt);
+
+/* ADC analog watchdog  */
+/* ADC analog watchdog single channel disable */
+void adc_watchdog_single_channel_disable(uint32_t adc_periph );
+/* ADC analog watchdog single channel enable */
+void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channel);
+/* adc analog watchdog group channel config */
+void adc_watchdog_enable(uint32_t adc_periph , uint8_t adc_channel_group);
+/* ADC analog watchdog disable */
+void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group);
+/* ADC analog watchdog threshold config */
+void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold);
+
+/* regular channel */
+/* ADC regular channel config */
+void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time);
+/* ADC regular group data register read */
+uint16_t adc_regular_data_read(uint32_t adc_periph);
+
+/* inserted channel */
+/* ADC inserted channel config */
+void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint8_t sample_time);
+/* ADC inserted channel offset config */
+void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset);
+/* ADC inserted group data register read */
+uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel);
+
+/* ADC DMA */
+/* DMA request enable */
+void adc_dma_mode_enable(uint32_t adc_periph);
+/* DMA request disable */
+void adc_dma_mode_disable(uint32_t adc_periph);
+/* when DMA=1, the DMA engine issues a request at end of each regular conversion */
+void adc_dma_request_after_last_enable(uint32_t adc_periph);
+/* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */
+void adc_dma_request_after_last_disable(uint32_t adc_periph);
+
+/* ADC oversample */
+/* ADC oversample mode config */
+void adc_oversample_mode_config(uint32_t adc_periph , uint8_t mode , uint16_t shift , uint8_t ratio);
+/* ADC oversample mode enable */
+void adc_oversample_mode_enable(uint32_t adc_periph );
+/* ADC oversample mode disable */
+void adc_oversample_mode_disable(uint32_t adc_periph );
+
+/* ADC synchronization */
+/* configure the ADC sync mode */
+void adc_sync_mode_config(uint32_t sync_mode);
+/* configure the delay between 2 sampling phases in ADC sync modes */
+void adc_sync_delay_config(uint32_t sample_delay);
+/* configure ADC sync DMA mode selection */
+void adc_sync_dma_config(uint32_t dma_mode );
+/* configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected */
+void adc_sync_dma_request_after_last_enable(void);
+/* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */
+void adc_sync_dma_request_after_last_disable(void);
+/* ADC sync regular data register read */
+uint32_t adc_sync_regular_data_read(void);
+
+#endif /* GD32F4XX_ADC_H */

+ 652 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h

@@ -0,0 +1,652 @@
+/*!
+    \file  gd32f4xx_can.h
+    \brief definitions for the CAN
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_CAN_H
+#define GD32F4XX_CAN_H
+
+#include "gd32f4xx.h"
+
+/* CAN definitions */
+#define CAN0                               CAN_BASE                      /*!< CAN0 base address */
+#define CAN1                               (CAN0 + 0x00000400U)          /*!< CAN1 base address */
+
+/* registers definitions */
+#define CAN_CTL(canx)                      REG32((canx) + 0x00U)         /*!< CAN control register */
+#define CAN_STAT(canx)                     REG32((canx) + 0x04U)         /*!< CAN status register */
+#define CAN_TSTAT(canx)                    REG32((canx) + 0x08U)         /*!< CAN transmit status register*/
+#define CAN_RFIFO0(canx)                   REG32((canx) + 0x0CU)         /*!< CAN receive FIFO0 register */
+#define CAN_RFIFO1(canx)                   REG32((canx) + 0x10U)         /*!< CAN receive FIFO1 register */
+#define CAN_INTEN(canx)                    REG32((canx) + 0x14U)         /*!< CAN interrupt enable register */
+#define CAN_ERR(canx)                      REG32((canx) + 0x18U)         /*!< CAN error register */
+#define CAN_BT(canx)                       REG32((canx) + 0x1CU)         /*!< CAN bit timing register */
+#define CAN_TMI0(canx)                     REG32((canx) + 0x180U)        /*!< CAN transmit mailbox0 identifier register */
+#define CAN_TMP0(canx)                     REG32((canx) + 0x184U)        /*!< CAN transmit mailbox0 property register */
+#define CAN_TMDATA00(canx)                 REG32((canx) + 0x188U)        /*!< CAN transmit mailbox0 data0 register */
+#define CAN_TMDATA10(canx)                 REG32((canx) + 0x18CU)        /*!< CAN transmit mailbox0 data1 register */
+#define CAN_TMI1(canx)                     REG32((canx) + 0x190U)        /*!< CAN transmit mailbox1 identifier register */
+#define CAN_TMP1(canx)                     REG32((canx) + 0x194U)        /*!< CAN transmit mailbox1 property register */
+#define CAN_TMDATA01(canx)                 REG32((canx) + 0x198U)        /*!< CAN transmit mailbox1 data0 register */
+#define CAN_TMDATA11(canx)                 REG32((canx) + 0x19CU)        /*!< CAN transmit mailbox1 data1 register */
+#define CAN_TMI2(canx)                     REG32((canx) + 0x1A0U)        /*!< CAN transmit mailbox2 identifier register */
+#define CAN_TMP2(canx)                     REG32((canx) + 0x1A4U)        /*!< CAN transmit mailbox2 property register */
+#define CAN_TMDATA02(canx)                 REG32((canx) + 0x1A8U)        /*!< CAN transmit mailbox2 data0 register */
+#define CAN_TMDATA12(canx)                 REG32((canx) + 0x1ACU)        /*!< CAN transmit mailbox2 data1 register */
+#define CAN_RFIFOMI0(canx)                 REG32((canx) + 0x1B0U)        /*!< CAN receive FIFO0 mailbox identifier register */
+#define CAN_RFIFOMP0(canx)                 REG32((canx) + 0x1B4U)        /*!< CAN receive FIFO0 mailbox property register */
+#define CAN_RFIFOMDATA00(canx)             REG32((canx) + 0x1B8U)        /*!< CAN receive FIFO0 mailbox data0 register */
+#define CAN_RFIFOMDATA10(canx)             REG32((canx) + 0x1CCU)        /*!< CAN receive FIFO0 mailbox data1 register */
+#define CAN_RFIFOMI1(canx)                 REG32((canx) + 0x1C0U)        /*!< CAN receive FIFO1 mailbox identifier register */
+#define CAN_RFIFOMP1(canx)                 REG32((canx) + 0x1C4U)        /*!< CAN receive FIFO1 mailbox property register */
+#define CAN_RFIFOMDATA01(canx)             REG32((canx) + 0x1C8U)        /*!< CAN receive FIFO1 mailbox data0 register */
+#define CAN_RFIFOMDATA11(canx)             REG32((canx) + 0x1CCU)        /*!< CAN receive FIFO1 mailbox data1 register */
+#define CAN_FCTL(canx)                     REG32((canx) + 0x200U)        /*!< CAN filter control register */
+#define CAN_FMCFG(canx)                    REG32((canx) + 0x204U)        /*!< CAN filter mode register */
+#define CAN_FSCFG(canx)                    REG32((canx) + 0x20CU)        /*!< CAN filter scale register */
+#define CAN_FAFIFO(canx)                   REG32((canx) + 0x214U)        /*!< CAN filter associated FIFO register */
+#define CAN_FW(canx)                       REG32((canx) + 0x21CU)        /*!< CAN filter working register */
+#define CAN_F0DATA0(canx)                  REG32((canx) + 0x240U)        /*!< CAN filter 0 data 0 register */
+#define CAN_F1DATA0(canx)                  REG32((canx) + 0x248U)        /*!< CAN filter 1 data 0 register */
+#define CAN_F2DATA0(canx)                  REG32((canx) + 0x250U)        /*!< CAN filter 2 data 0 register */
+#define CAN_F3DATA0(canx)                  REG32((canx) + 0x258U)        /*!< CAN filter 3 data 0 register */
+#define CAN_F4DATA0(canx)                  REG32((canx) + 0x260U)        /*!< CAN filter 4 data 0 register */
+#define CAN_F5DATA0(canx)                  REG32((canx) + 0x268U)        /*!< CAN filter 5 data 0 register */
+#define CAN_F6DATA0(canx)                  REG32((canx) + 0x270U)        /*!< CAN filter 6 data 0 register */
+#define CAN_F7DATA0(canx)                  REG32((canx) + 0x278U)        /*!< CAN filter 7 data 0 register */
+#define CAN_F8DATA0(canx)                  REG32((canx) + 0x280U)        /*!< CAN filter 8 data 0 register */
+#define CAN_F9DATA0(canx)                  REG32((canx) + 0x288U)        /*!< CAN filter 9 data 0 register */
+#define CAN_F10DATA0(canx)                 REG32((canx) + 0x290U)        /*!< CAN filter 10 data 0 register */
+#define CAN_F11DATA0(canx)                 REG32((canx) + 0x298U)        /*!< CAN filter 11 data 0 register */
+#define CAN_F12DATA0(canx)                 REG32((canx) + 0x2A0U)        /*!< CAN filter 12 data 0 register */
+#define CAN_F13DATA0(canx)                 REG32((canx) + 0x2A8U)        /*!< CAN filter 13 data 0 register */
+#define CAN_F14DATA0(canx)                 REG32((canx) + 0x2B0U)        /*!< CAN filter 14 data 0 register */
+#define CAN_F15DATA0(canx)                 REG32((canx) + 0x2B8U)        /*!< CAN filter 15 data 0 register */
+#define CAN_F16DATA0(canx)                 REG32((canx) + 0x2C0U)        /*!< CAN filter 16 data 0 register */
+#define CAN_F17DATA0(canx)                 REG32((canx) + 0x2C8U)        /*!< CAN filter 17 data 0 register */
+#define CAN_F18DATA0(canx)                 REG32((canx) + 0x2D0U)        /*!< CAN filter 18 data 0 register */
+#define CAN_F19DATA0(canx)                 REG32((canx) + 0x2D8U)        /*!< CAN filter 19 data 0 register */
+#define CAN_F20DATA0(canx)                 REG32((canx) + 0x2E0U)        /*!< CAN filter 20 data 0 register */
+#define CAN_F21DATA0(canx)                 REG32((canx) + 0x2E8U)        /*!< CAN filter 21 data 0 register */
+#define CAN_F22DATA0(canx)                 REG32((canx) + 0x2F0U)        /*!< CAN filter 22 data 0 register */
+#define CAN_F23DATA0(canx)                 REG32((canx) + 0x3F8U)        /*!< CAN filter 23 data 0 register */
+#define CAN_F24DATA0(canx)                 REG32((canx) + 0x300U)        /*!< CAN filter 24 data 0 register */
+#define CAN_F25DATA0(canx)                 REG32((canx) + 0x308U)        /*!< CAN filter 25 data 0 register */
+#define CAN_F26DATA0(canx)                 REG32((canx) + 0x310U)        /*!< CAN filter 26 data 0 register */
+#define CAN_F27DATA0(canx)                 REG32((canx) + 0x318U)        /*!< CAN filter 27 data 0 register */
+#define CAN_F0DATA1(canx)                  REG32((canx) + 0x244U)        /*!< CAN filter 0 data 1 register */
+#define CAN_F1DATA1(canx)                  REG32((canx) + 0x24CU)        /*!< CAN filter 1 data 1 register */
+#define CAN_F2DATA1(canx)                  REG32((canx) + 0x254U)        /*!< CAN filter 2 data 1 register */
+#define CAN_F3DATA1(canx)                  REG32((canx) + 0x25CU)        /*!< CAN filter 3 data 1 register */
+#define CAN_F4DATA1(canx)                  REG32((canx) + 0x264U)        /*!< CAN filter 4 data 1 register */
+#define CAN_F5DATA1(canx)                  REG32((canx) + 0x26CU)        /*!< CAN filter 5 data 1 register */
+#define CAN_F6DATA1(canx)                  REG32((canx) + 0x274U)        /*!< CAN filter 6 data 1 register */
+#define CAN_F7DATA1(canx)                  REG32((canx) + 0x27CU)        /*!< CAN filter 7 data 1 register */
+#define CAN_F8DATA1(canx)                  REG32((canx) + 0x284U)        /*!< CAN filter 8 data 1 register */
+#define CAN_F9DATA1(canx)                  REG32((canx) + 0x28CU)        /*!< CAN filter 9 data 1 register */
+#define CAN_F10DATA1(canx)                 REG32((canx) + 0x294U)        /*!< CAN filter 10 data 1 register */
+#define CAN_F11DATA1(canx)                 REG32((canx) + 0x29CU)        /*!< CAN filter 11 data 1 register */
+#define CAN_F12DATA1(canx)                 REG32((canx) + 0x2A4U)        /*!< CAN filter 12 data 1 register */
+#define CAN_F13DATA1(canx)                 REG32((canx) + 0x2ACU)        /*!< CAN filter 13 data 1 register */
+#define CAN_F14DATA1(canx)                 REG32((canx) + 0x2B4U)        /*!< CAN filter 14 data 1 register */
+#define CAN_F15DATA1(canx)                 REG32((canx) + 0x2BCU)        /*!< CAN filter 15 data 1 register */
+#define CAN_F16DATA1(canx)                 REG32((canx) + 0x2C4U)        /*!< CAN filter 16 data 1 register */
+#define CAN_F17DATA1(canx)                 REG32((canx) + 0x24CU)        /*!< CAN filter 17 data 1 register */
+#define CAN_F18DATA1(canx)                 REG32((canx) + 0x2D4U)        /*!< CAN filter 18 data 1 register */
+#define CAN_F19DATA1(canx)                 REG32((canx) + 0x2DCU)        /*!< CAN filter 19 data 1 register */
+#define CAN_F20DATA1(canx)                 REG32((canx) + 0x2E4U)        /*!< CAN filter 20 data 1 register */
+#define CAN_F21DATA1(canx)                 REG32((canx) + 0x2ECU)        /*!< CAN filter 21 data 1 register */
+#define CAN_F22DATA1(canx)                 REG32((canx) + 0x2F4U)        /*!< CAN filter 22 data 1 register */
+#define CAN_F23DATA1(canx)                 REG32((canx) + 0x2FCU)        /*!< CAN filter 23 data 1 register */
+#define CAN_F24DATA1(canx)                 REG32((canx) + 0x304U)        /*!< CAN filter 24 data 1 register */
+#define CAN_F25DATA1(canx)                 REG32((canx) + 0x30CU)        /*!< CAN filter 25 data 1 register */
+#define CAN_F26DATA1(canx)                 REG32((canx) + 0x314U)        /*!< CAN filter 26 data 1 register */
+#define CAN_F27DATA1(canx)                 REG32((canx) + 0x31CU)        /*!< CAN filter 27 data 1 register */
+
+/* CAN transmit mailbox bank */
+#define CAN_TMI(canx, bank)                REG32((canx) + 0x180U + ((bank) * 0x10U))      /*!< CAN transmit mailbox identifier register */
+#define CAN_TMP(canx, bank)                REG32((canx) + 0x184U + ((bank) * 0x10U))      /*!< CAN transmit mailbox property register */
+#define CAN_TMDATA0(canx, bank)            REG32((canx) + 0x188U + ((bank) * 0x10U))      /*!< CAN transmit mailbox data0 register */
+#define CAN_TMDATA1(canx, bank)            REG32((canx) + 0x18CU + ((bank) * 0x10U))      /*!< CAN transmit mailbox data1 register */
+
+/* CAN filter bank */
+#define CAN_FDATA0(canx, bank)             REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x0U) /*!< CAN filter data 0 register */
+#define CAN_FDATA1(canx, bank)             REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x4U) /*!< CAN filter data 1 register */
+
+/* CAN receive fifo mailbox bank */
+#define CAN_RFIFOMI(canx, bank)            REG32((canx) + 0x1B0U + ((bank) * 0x10U))      /*!< CAN receive FIFO mailbox identifier register */
+#define CAN_RFIFOMP(canx, bank)            REG32((canx) + 0x1B4U + ((bank) * 0x10U))      /*!< CAN receive FIFO mailbox property register */
+#define CAN_RFIFOMDATA0(canx, bank)        REG32((canx) + 0x1B8U + ((bank) * 0x10U))      /*!< CAN receive FIFO mailbox data0 register */
+#define CAN_RFIFOMDATA1(canx, bank)        REG32((canx) + 0x1BCU + ((bank) * 0x10U))      /*!< CAN receive FIFO mailbox data1 register */
+
+/* bits definitions */
+/* CAN_CTL */
+#define CAN_CTL_IWMOD                      BIT(0)                       /*!< initial working mode */
+#define CAN_CTL_SLPWMOD                    BIT(1)                       /*!< sleep working mode */
+#define CAN_CTL_TFO                        BIT(2)                       /*!< transmit FIFO order */
+#define CAN_CTL_RFOD                       BIT(3)                       /*!< receive FIFO overwrite disable */
+#define CAN_CTL_ARD                        BIT(4)                       /*!< automatic retransmission disable */
+#define CAN_CTL_AWU                        BIT(5)                       /*!< automatic wakeup */
+#define CAN_CTL_ABOR                       BIT(6)                       /*!< automatic bus-off recovery */
+#define CAN_CTL_TTC                        BIT(7)                       /*!< time triggered communication */
+#define CAN_CTL_SWRST                      BIT(15)                      /*!< CAN software reset */
+#define CAN_CTL_DFZ                        BIT(16)                      /*!< CAN debug freeze */
+
+/* CAN_STAT */
+#define CAN_STAT_IWS                       BIT(0)                       /*!< initial working state */
+#define CAN_STAT_SLPWS                     BIT(1)                       /*!< sleep working state */
+#define CAN_STAT_ERRIF                     BIT(2)                       /*!< error interrupt flag*/
+#define CAN_STAT_WUIF                      BIT(3)                       /*!< status change interrupt flag of wakeup from sleep working mode */
+#define CAN_STAT_SLPIF                     BIT(4)                       /*!< status change interrupt flag of sleep working mode entering */
+#define CAN_STAT_TS                        BIT(8)                       /*!< transmitting state */
+#define CAN_STAT_RS                        BIT(9)                       /*!< receiving state */
+#define CAN_STAT_LASTRX                    BIT(10)                      /*!< last sample value of rx pin */
+#define CAN_STAT_RXL                       BIT(11)                      /*!< CAN rx signal */
+
+/* CAN_TSTAT */
+#define CAN_TSTAT_MTF0                     BIT(0)                       /*!< mailbox0 transmit finished */
+#define CAN_TSTAT_MTFNERR0                 BIT(1)                       /*!< mailbox0 transmit finished and no error */
+#define CAN_TSTAT_MAL0                     BIT(2)                       /*!< mailbox0 arbitration lost */
+#define CAN_TSTAT_MTE0                     BIT(3)                       /*!< mailbox0 transmit error */
+#define CAN_TSTAT_MST0                     BIT(7)                       /*!< mailbox0 stop transmitting */
+#define CAN_TSTAT_MTF1                     BIT(8)                       /*!< mailbox1 transmit finished */
+#define CAN_TSTAT_MTFNERR1                 BIT(9)                       /*!< mailbox1 transmit finished and no error */
+#define CAN_TSTAT_MAL1                     BIT(10)                      /*!< mailbox1 arbitration lost */
+#define CAN_TSTAT_MTE1                     BIT(11)                      /*!< mailbox1 transmit error */
+#define CAN_TSTAT_MST1                     BIT(15)                      /*!< mailbox1 stop transmitting */
+#define CAN_TSTAT_MTF2                     BIT(16)                      /*!< mailbox2 transmit finished */
+#define CAN_TSTAT_MTFNERR2                 BIT(17)                      /*!< mailbox2 transmit finished and no error */
+#define CAN_TSTAT_MAL2                     BIT(18)                      /*!< mailbox2 arbitration lost */
+#define CAN_TSTAT_MTE2                     BIT(19)                      /*!< mailbox2 transmit error */
+#define CAN_TSTAT_MST2                     BIT(23)                      /*!< mailbox2 stop transmitting */
+#define CAN_TSTAT_NUM                      BITS(24,25)                  /*!< mailbox number */
+#define CAN_TSTAT_TME0                     BIT(26)                      /*!< transmit mailbox0 empty */
+#define CAN_TSTAT_TME1                     BIT(27)                      /*!< transmit mailbox1 empty */
+#define CAN_TSTAT_TME2                     BIT(28)                      /*!< transmit mailbox2 empty */
+#define CAN_TSTAT_TMLS0                    BIT(29)                      /*!< last sending priority flag for mailbox0 */
+#define CAN_TSTAT_TMLS1                    BIT(30)                      /*!< last sending priority flag for mailbox1 */
+#define CAN_TSTAT_TMLS2                    BIT(31)                      /*!< last sending priority flag for mailbox2 */
+
+/* CAN_RFIFO0 */
+#define CAN_RFIFO0_RFL0                    BITS(0,1)                    /*!< receive FIFO0 length */
+#define CAN_RFIFO0_RFF0                    BIT(3)                       /*!< receive FIFO0 full */
+#define CAN_RFIFO0_RFO0                    BIT(4)                       /*!< receive FIFO0 overfull */
+#define CAN_RFIFO0_RFD0                    BIT(5)                       /*!< receive FIFO0 dequeue */
+
+/* CAN_RFIFO1 */
+#define CAN_RFIFO1_RFL1                    BITS(0,1)                    /*!< receive FIFO1 length */
+#define CAN_RFIFO1_RFF1                    BIT(3)                       /*!< receive FIFO1 full */
+#define CAN_RFIFO1_RFO1                    BIT(4)                       /*!< receive FIFO1 overfull */
+#define CAN_RFIFO1_RFD1                    BIT(5)                       /*!< receive FIFO1 dequeue */
+
+/* CAN_INTEN */
+#define CAN_INTEN_TMEIE                    BIT(0)                       /*!< transmit mailbox empty interrupt enable */
+#define CAN_INTEN_RFNEIE0                  BIT(1)                       /*!< receive FIFO0 not empty interrupt enable */
+#define CAN_INTEN_RFFIE0                   BIT(2)                       /*!< receive FIFO0 full interrupt enable */
+#define CAN_INTEN_RFOIE0                   BIT(3)                       /*!< receive FIFO0 overfull interrupt enable */
+#define CAN_INTEN_RFNEIE1                  BIT(4)                       /*!< receive FIFO1 not empty interrupt enable */
+#define CAN_INTEN_RFFIE1                   BIT(5)                       /*!< receive FIFO1 full interrupt enable */
+#define CAN_INTEN_RFOIE1                   BIT(6)                       /*!< receive FIFO1 overfull interrupt enable */
+#define CAN_INTEN_WERRIE                   BIT(8)                       /*!< warning error interrupt enable */
+#define CAN_INTEN_PERRIE                   BIT(9)                       /*!< passive error interrupt enable */
+#define CAN_INTEN_BOIE                     BIT(10)                      /*!< bus-off interrupt enable */
+#define CAN_INTEN_ERRNIE                   BIT(11)                      /*!< error number interrupt enable */
+#define CAN_INTEN_ERRIE                    BIT(15)                      /*!< error interrupt enable */
+#define CAN_INTEN_WUIE                     BIT(16)                      /*!< wakeup interrupt enable */
+#define CAN_INTEN_SLPWIE                   BIT(17)                      /*!< sleep working interrupt enable */
+
+/* CAN_ERR */
+#define CAN_ERR_WERR                       BIT(0)                       /*!< warning error */
+#define CAN_ERR_PERR                       BIT(1)                       /*!< passive error */
+#define CAN_ERR_BOERR                      BIT(2)                       /*!< bus-off error */
+#define CAN_ERR_ERRN                       BITS(4,6)                    /*!< error number */
+#define CAN_ERR_TECNT                      BITS(16,23)                  /*!< transmit error count */
+#define CAN_ERR_RECNT                      BITS(24,31)                  /*!< receive error count */
+
+/* CAN_BT */
+#define CAN_BT_BAUDPSC                     BITS(0,9)                    /*!< baudrate prescaler */
+#define CAN_BT_BS1                         BITS(16,19)                  /*!< bit segment 1 */
+#define CAN_BT_BS2                         BITS(20,22)                  /*!< bit segment 2 */
+#define CAN_BT_SJW                         BITS(24,25)                  /*!< resynchronization jump width */
+#define CAN_BT_LCMOD                       BIT(30)                      /*!< loopback communication mode */
+#define CAN_BT_SCMOD                       BIT(31)                      /*!< silent communication mode */
+
+/* CAN_TMIx */
+#define CAN_TMI_TEN                        BIT(0)                       /*!< transmit enable */
+#define CAN_TMI_FT                         BIT(1)                       /*!< frame type */
+#define CAN_TMI_FF                         BIT(2)                       /*!< frame format */
+#define CAN_TMI_EFID                       BITS(3,31)                   /*!< the frame identifier */
+#define CAN_TMI_SFID                       BITS(21,31)                  /*!< the frame identifier */
+
+/* CAN_TMPx */
+#define CAN_TMP_DLENC                      BITS(0,3)                    /*!< data length code */
+#define CAN_TMP_TSEN                       BIT(8)                       /*!< time stamp enable */
+#define CAN_TMP_TS                         BITS(16,31)                  /*!< time stamp */
+
+/* CAN_TMDATA0x */
+#define CAN_TMDATA0_DB0                    BITS(0,7)                    /*!< transmit data byte 0 */
+#define CAN_TMDATA0_DB1                    BITS(8,15)                   /*!< transmit data byte 1 */
+#define CAN_TMDATA0_DB2                    BITS(16,23)                  /*!< transmit data byte 2 */
+#define CAN_TMDATA0_DB3                    BITS(24,31)                  /*!< transmit data byte 3 */
+
+/* CAN_TMDATA1x */
+#define CAN_TMDATA1_DB4                    BITS(0,7)                    /*!< transmit data byte 4 */
+#define CAN_TMDATA1_DB5                    BITS(8,15)                   /*!< transmit data byte 5 */
+#define CAN_TMDATA1_DB6                    BITS(16,23)                  /*!< transmit data byte 6 */
+#define CAN_TMDATA1_DB7                    BITS(24,31)                  /*!< transmit data byte 7 */
+
+/* CAN_RFIFOMIx */
+#define CAN_RFIFOMI_FT                     BIT(1)                       /*!< frame type */
+#define CAN_RFIFOMI_FF                     BIT(2)                       /*!< frame format */
+#define CAN_RFIFOMI_EFID                   BITS(3,31)                   /*!< the frame identifier */
+#define CAN_RFIFOMI_SFID                   BITS(21,31)                  /*!< the frame identifier */
+
+/* CAN_RFIFOMPx */
+#define CAN_RFIFOMP_DLENC                  BITS(0,3)                    /*!< receive data length code */
+#define CAN_RFIFOMP_FI                     BITS(8,15)                   /*!< filter index */
+#define CAN_RFIFOMP_TS                     BITS(16,31)                  /*!< time stamp */
+
+/* CAN_RFIFOMDATA0x */
+#define CAN_RFIFOMDATA0_DB0                BITS(0,7)                    /*!< receive data byte 0 */
+#define CAN_RFIFOMDATA0_DB1                BITS(8,15)                   /*!< receive data byte 1 */
+#define CAN_RFIFOMDATA0_DB2                BITS(16,23)                  /*!< receive data byte 2 */
+#define CAN_RFIFOMDATA0_DB3                BITS(24,31)                  /*!< receive data byte 3 */
+
+/* CAN_RFIFOMDATA1x */
+#define CAN_RFIFOMDATA1_DB4                BITS(0,7)                    /*!< receive data byte 4 */
+#define CAN_RFIFOMDATA1_DB5                BITS(8,15)                   /*!< receive data byte 5 */
+#define CAN_RFIFOMDATA1_DB6                BITS(16,23)                  /*!< receive data byte 6 */
+#define CAN_RFIFOMDATA1_DB7                BITS(24,31)                  /*!< receive data byte 7 */
+
+/* CAN_FCTL */
+#define CAN_FCTL_FLD                       BIT(0)                       /*!< filter lock disable */
+#define CAN_FCTL_HBC1F                     BITS(8,13)                   /*!< header bank of CAN1 filter */
+
+/* CAN_FMCFG */
+#define CAN_FMCFG_FMOD(regval)             BIT(regval)                  /*!< filter mode, list or mask*/
+
+/* CAN_FSCFG */
+#define CAN_FSCFG_FS(regval)               BIT(regval)                  /*!< filter scale, 32 bits or 16 bits*/
+
+/* CAN_FAFIFO */
+#define CAN_FAFIFOR_FAF(regval)            BIT(regval)                  /*!< filter associated with FIFO */
+
+/* CAN_FW */
+#define CAN_FW_FW(regval)                  BIT(regval)                  /*!< filter working */
+
+/* consts definitions */
+/* define the CAN bit position and its register index offset */
+#define CAN_REGIDX_BIT(regidx, bitpos)    (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define CAN_REG_VAL(canx, offset)         (REG32((canx) + ((uint32_t)(offset) >> 6)))
+#define CAN_BIT_POS(val)                  ((uint32_t)(val) & 0x1FU)
+
+/* register offset */
+#define STAT_REG_OFFSET                    ((uint8_t)0x04U)             /*!< STAT register offset */
+#define TSTAT_REG_OFFSET                   ((uint8_t)0x08U)             /*!< TSTAT register offset */
+#define RFIFO0_REG_OFFSET                  ((uint8_t)0x0CU)             /*!< RFIFO0 register offset */
+#define RFIFO1_REG_OFFSET                  ((uint8_t)0x10U)             /*!< RFIFO1 register offset */
+#define ERR_REG_OFFSET                     ((uint8_t)0x18U)             /*!< ERR register offset */
+
+/* CAN flags */
+typedef enum
+{
+    /* flags in TSTAT register */
+    CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U),              /*!< mailbox 2 transmit error */ 
+    CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U),              /*!< mailbox 1 transmit error */ 
+    CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U),               /*!< mailbox 0 transmit error */ 
+    CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U),              /*!< mailbox 2 transmit finished */ 
+    CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U),               /*!< mailbox 1 transmit finished */ 
+    CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U),               /*!< mailbox 0 transmit finished */ 
+    /* flags in RFIFO0 register */
+    CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U),              /*!< receive FIFO0 overfull */ 
+    CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U),              /*!< receive FIFO0 full */ 
+    /* flags in RFIFO1 register */
+    CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U),              /*!< receive FIFO1 overfull */ 
+    CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U),              /*!< receive FIFO1 full */ 
+    /* flags in ERR register */
+    CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U),                /*!< bus-off error */ 
+    CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U),                 /*!< passive error */ 
+    CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U),                 /*!< warning error */ 
+}can_flag_enum;
+
+/* CAN interrupt flags */
+typedef enum
+{
+    /* interrupt flags in STAT register */
+    CAN_INT_SLPIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U),                /*!< status change interrupt flag of sleep working mode entering */ 
+    CAN_INT_WUIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U),                 /*!< status change interrupt flag of wakeup from sleep working mode */ 
+    CAN_INT_ERRIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U),                /*!< error interrupt flag */ 
+}can_interrupt_flag_enum;
+
+/* CAN initiliaze parameters struct */
+typedef struct
+{
+    uint8_t working_mode;                                               /*!< CAN working mode */ 
+    uint8_t resync_jump_width;                                          /*!< CAN resynchronization jump width */
+    uint8_t time_segment_1;                                             /*!< time segment 1 */
+    uint8_t time_segment_2;                                             /*!< time segment 2 */
+    ControlStatus time_triggered;                                       /*!< time triggered communication mode */
+    ControlStatus auto_bus_off_recovery;                                /*!< automatic bus-off recovery */
+    ControlStatus auto_wake_up;                                         /*!< automatic wake-up mode */
+    ControlStatus auto_retrans;                                         /*!< automatic retransmission mode */
+    ControlStatus rec_fifo_overwrite;                                   /*!< receive FIFO overwrite mode */
+    ControlStatus trans_fifo_order;                                     /*!< transmit FIFO order */
+    uint16_t prescaler;                                                 /*!< baudrate prescaler */
+}can_parameter_struct;
+
+/* CAN transmit message struct */
+typedef struct
+{
+    uint32_t tx_sfid;                                                   /*!< standard format frame identifier */
+    uint32_t tx_efid;                                                   /*!< extended format frame identifier */
+    uint8_t tx_ff;                                                      /*!< format of frame, standard or extended format */
+    uint8_t tx_ft;                                                      /*!< type of frame, data or remote */
+    uint8_t tx_dlen;                                                    /*!< data length */
+    uint8_t tx_data[8];                                                 /*!< transmit data */
+}can_trasnmit_message_struct;
+
+/* CAN receive message struct */
+typedef struct
+{
+    uint32_t rx_sfid;                                                   /*!< standard format frame identifier */
+    uint32_t rx_efid;                                                   /*!< extended format frame identifier */
+    uint8_t rx_ff;                                                      /*!< format of frame, standard or extended format */
+    uint8_t rx_ft;                                                      /*!< type of frame, data or remote */
+    uint8_t rx_dlen;                                                    /*!< data length */
+    uint8_t rx_data[8];                                                 /*!< receive data */
+    uint8_t rx_fi;                                                      /*!< filtering index */
+} can_receive_message_struct;
+
+/* CAN filter parameters struct */
+typedef struct
+{
+    uint16_t filter_list_high;                                          /*!< filter list number high bits*/
+    uint16_t filter_list_low;                                           /*!< filter list number low bits */
+    uint16_t filter_mask_high;                                          /*!< filter mask number high bits */
+    uint16_t filter_mask_low;                                           /*!< filter mask number low bits */
+    uint16_t filter_fifo_number;                                        /*!< receive FIFO associated with the filter */
+    uint16_t filter_number;                                             /*!< filter number */
+    uint16_t filter_mode;                                               /*!< filter mode, list or mask */
+    uint16_t filter_bits;                                               /*!< filter scale */
+    ControlStatus filter_enable;                                        /*!< filter work or not */
+}can_filter_parameter_struct;
+
+/* CAN errors */
+typedef enum
+{
+    CAN_ERROR_NONE = 0,                                                 /*!< no error */
+    CAN_ERROR_FILL,                                                     /*!< fill error */
+    CAN_ERROR_FORMATE,                                                  /*!< format error */
+    CAN_ERROR_ACK,                                                      /*!< ACK error */
+    CAN_ERROR_BITRECESSIVE,                                             /*!< bit recessive error */
+    CAN_ERROR_BITDOMINANTER,                                            /*!< bit dominant error */
+    CAN_ERROR_CRC,                                                      /*!< CRC error */
+    CAN_ERROR_SOFTWARECFG                                               /*!< software configure */
+}can_error_enum;
+
+/* transmit states */
+typedef enum
+{
+    CAN_TRANSMIT_FAILED = 0,                                            /*!< CAN transmitted failure */
+    CAN_TRANSMIT_OK = 1,                                                /*!< CAN transmitted success */
+    CAN_TRANSMIT_PENDING = 2,                                           /*!< CAN transmitted pending */
+    CAN_TRANSMIT_NOMAILBOX = 4,                                         /*!< no empty mailbox to be used for CAN */
+}can_transmit_state_enum;
+
+/* CAN baudrate prescaler*/
+#define BT_BAUDPSC(regval)                 (BITS(0,9) & ((uint32_t)(regval) << 0))
+
+/* CAN bit segment 1*/
+#define BT_BS1(regval)                     (BITS(16,19) & ((uint32_t)(regval) << 16))
+
+/* CAN bit segment 2*/
+#define BT_BS2(regval)                     (BITS(20,22) & ((uint32_t)(regval) << 20))
+
+/* CAN resynchronization jump width*/
+#define BT_SJW(regval)                     (BITS(24,25) & ((uint32_t)(regval) << 24))
+
+/* CAN communication mode*/
+#define BT_MODE(regval)                    (BITS(30,31) & ((uint32_t)(regval) << 30))
+
+/* CAN FDATA high 16 bits */
+#define FDATA_MASK_HIGH(regval)            (BITS(16,31) & ((uint32_t)(regval) << 16))
+
+/* CAN FDATA low 16 bits */
+#define FDATA_MASK_LOW(regval)             (BITS(0,15) & ((uint32_t)(regval) << 0))
+
+/* CAN1 filter start bank_number*/
+#define FCTL_HBC1F(regval)                 (BITS(8,13) & ((uint32_t)(regval) << 8))
+
+/* CAN transmit mailbox extended identifier*/
+#define TMI_EFID(regval)                   (BITS(3,31) & ((uint32_t)(regval) << 3))
+
+/* CAN transmit mailbox standard identifier*/
+#define TMI_SFID(regval)                   (BITS(21,31) & ((uint32_t)(regval) << 21))
+
+/* transmit data byte 0 */
+#define TMDATA0_DB0(regval)                (BITS(0,7) & ((uint32_t)(regval) << 0))
+
+/* transmit data byte 1 */
+#define TMDATA0_DB1(regval)                (BITS(8,15) & ((uint32_t)(regval) << 8))
+
+/* transmit data byte 2 */
+#define TMDATA0_DB2(regval)                (BITS(16,23) & ((uint32_t)(regval) << 16))
+
+/* transmit data byte 3 */                 
+#define TMDATA0_DB3(regval)                (BITS(24,31) & ((uint32_t)(regval) << 24))
+
+/* transmit data byte 4 */                 
+#define TMDATA1_DB4(regval)                (BITS(0,7) & ((uint32_t)(regval) << 0))
+
+/* transmit data byte 5 */                 
+#define TMDATA1_DB5(regval)                (BITS(8,15) & ((uint32_t)(regval) << 8))
+
+/* transmit data byte 6 */                 
+#define TMDATA1_DB6(regval)                (BITS(16,23) & ((uint32_t)(regval) << 16))
+
+/* transmit data byte 7 */                 
+#define TMDATA1_DB7(regval)                (BITS(24,31) & ((uint32_t)(regval) << 24))
+
+/* receive mailbox extended identifier*/
+#define RFIFOMI_EFID(regval)               GET_BITS((uint32_t)(regval), 3, 31)
+
+/* receive mailbox standrad identifier*/
+#define RFIFOMI_SFID(regval)               GET_BITS((uint32_t)(regval), 21, 31)
+
+/* receive data length */
+#define RFIFOMP_DLENC(regval)              GET_BITS((uint32_t)(regval), 0, 3)
+
+#define RFIFOMP_FI(regval)                 GET_BITS((uint32_t)(regval), 8, 15)
+
+/* receive data byte 0 */
+#define RFIFOMDATA0_DB0(regval)            GET_BITS((uint32_t)(regval), 0, 7)
+
+/* receive data byte 1 */
+#define RFIFOMDATA0_DB1(regval)            GET_BITS((uint32_t)(regval), 8, 15)
+
+/* receive data byte 2 */
+#define RFIFOMDATA0_DB2(regval)            GET_BITS((uint32_t)(regval), 16, 23)
+
+/* receive data byte 3 */
+#define RFIFOMDATA0_DB3(regval)            GET_BITS((uint32_t)(regval), 24, 31)
+
+/* receive data byte 4 */
+#define RFIFOMDATA1_DB4(regval)            GET_BITS((uint32_t)(regval), 0, 7)
+
+/* receive data byte 5 */
+#define RFIFOMDATA1_DB5(regval)            GET_BITS((uint32_t)(regval), 8, 15)
+
+/* receive data byte 6 */
+#define RFIFOMDATA1_DB6(regval)            GET_BITS((uint32_t)(regval), 16, 23)
+
+/* receive data byte 7 */
+#define RFIFOMDATA1_DB7(regval)            GET_BITS((uint32_t)(regval), 24, 31)
+
+/* CAN errors */
+#define ERR_ERRN(regval)                   (BITS(4,6) & ((uint32_t)(regval) << 4))
+#define CAN_ERRN_0                         ERR_ERRN(0)                  /* no error */
+#define CAN_ERRN_1                         ERR_ERRN(1)                  /*!< fill error */
+#define CAN_ERRN_2                         ERR_ERRN(2)                  /*!< format error */
+#define CAN_ERRN_3                         ERR_ERRN(3)                  /*!< ACK error */
+#define CAN_ERRN_4                         ERR_ERRN(4)                  /*!< bit recessive error */
+#define CAN_ERRN_5                         ERR_ERRN(5)                  /*!< bit dominant error */
+#define CAN_ERRN_6                         ERR_ERRN(6)                  /*!< CRC error */
+#define CAN_ERRN_7                         ERR_ERRN(7)                  /*!< software error */
+
+#define CAN_STATE_PENDING                  ((uint32_t)0x00000000U)      /*!< CAN pending */
+
+/* CAN communication mode */
+#define CAN_NORMAL_MODE                    ((uint8_t)0x00U)             /*!< normal communication mode */
+#define CAN_LOOPBACK_MODE                  ((uint8_t)0x01U)             /*!< loopback communication mode */
+#define CAN_SILENT_MODE                    ((uint8_t)0x02U)             /*!< silent communication mode */
+#define CAN_SILENT_LOOPBACK_MODE           ((uint8_t)0x03U)             /*!< loopback and silent communication mode */
+
+/* CAN resynchronisation jump width */
+#define CAN_BT_SJW_1TQ                     ((uint8_t)0x00U)             /*!< 1 time quanta */
+#define CAN_BT_SJW_2TQ                     ((uint8_t)0x01U)             /*!< 2 time quanta */
+#define CAN_BT_SJW_3TQ                     ((uint8_t)0x02U)             /*!< 3 time quanta */
+#define CAN_BT_SJW_4TQ                     ((uint8_t)0x03U)             /*!< 4 time quanta */
+
+/* CAN time segment 1 */
+#define CAN_BT_BS1_1TQ                     ((uint8_t)0x00U)             /*!< 1 time quanta */
+#define CAN_BT_BS1_2TQ                     ((uint8_t)0x01U)             /*!< 2 time quanta */
+#define CAN_BT_BS1_3TQ                     ((uint8_t)0x02U)             /*!< 3 time quanta */
+#define CAN_BT_BS1_4TQ                     ((uint8_t)0x03U)             /*!< 4 time quanta */
+#define CAN_BT_BS1_5TQ                     ((uint8_t)0x04U)             /*!< 5 time quanta */
+#define CAN_BT_BS1_6TQ                     ((uint8_t)0x05U)             /*!< 6 time quanta */
+#define CAN_BT_BS1_7TQ                     ((uint8_t)0x06U)             /*!< 7 time quanta */
+#define CAN_BT_BS1_8TQ                     ((uint8_t)0x07U)             /*!< 8 time quanta */
+#define CAN_BT_BS1_9TQ                     ((uint8_t)0x08U)             /*!< 9 time quanta */
+#define CAN_BT_BS1_10TQ                    ((uint8_t)0x09U)             /*!< 10 time quanta */
+#define CAN_BT_BS1_11TQ                    ((uint8_t)0x0AU)             /*!< 11 time quanta */
+#define CAN_BT_BS1_12TQ                    ((uint8_t)0x0BU)             /*!< 12 time quanta */
+#define CAN_BT_BS1_13TQ                    ((uint8_t)0x0CU)             /*!< 13 time quanta */
+#define CAN_BT_BS1_14TQ                    ((uint8_t)0x0DU)             /*!< 14 time quanta */
+#define CAN_BT_BS1_15TQ                    ((uint8_t)0x0EU)             /*!< 15 time quanta */
+#define CAN_BT_BS1_16TQ                    ((uint8_t)0x0FU)             /*!< 16 time quanta */
+
+/* CAN time segment 2 */
+#define CAN_BT_BS2_1TQ                     ((uint8_t)0x00U)             /*!< 1 time quanta */
+#define CAN_BT_BS2_2TQ                     ((uint8_t)0x01U)             /*!< 2 time quanta */
+#define CAN_BT_BS2_3TQ                     ((uint8_t)0x02U)             /*!< 3 time quanta */
+#define CAN_BT_BS2_4TQ                     ((uint8_t)0x03U)             /*!< 4 time quanta */
+#define CAN_BT_BS2_5TQ                     ((uint8_t)0x04U)             /*!< 5 time quanta */
+#define CAN_BT_BS2_6TQ                     ((uint8_t)0x05U)             /*!< 6 time quanta */
+#define CAN_BT_BS2_7TQ                     ((uint8_t)0x06U)             /*!< 7 time quanta */
+#define CAN_BT_BS2_8TQ                     ((uint8_t)0x07U)             /*!< 8 time quanta */
+
+/* CAN mailbox number */
+#define CAN_MAILBOX0                       ((uint8_t)0x00U)             /*!< mailbox0 */
+#define CAN_MAILBOX1                       ((uint8_t)0x01U)             /*!< mailbox1 */
+#define CAN_MAILBOX2                       ((uint8_t)0x02U)             /*!< mailbox2 */
+#define CAN_NOMAILBOX                      ((uint8_t)0x03U)             /*!< no mailbox empty */
+
+/* CAN frame format */
+#define CAN_FF_STANDARD                    ((uint32_t)0x00000000U)      /*!< standard frame */
+#define CAN_FF_EXTENDED                    ((uint32_t)0x00000004U)      /*!< extended frame */
+
+/* CAN receive fifo */
+#define CAN_FIFO0                          ((uint8_t)0x00U)             /*!< receive FIFO0 */
+#define CAN_FIFO1                          ((uint8_t)0x01U)             /*!< receive FIFO1 */
+
+/* frame number of receive fifo */
+#define CAN_RFIFO_RFL0_MASK                ((uint32_t)0x00000003U)      /*!< mask for frame number in receive FIFO0 */
+
+#define CAN_SFID_MASK                      ((uint32_t)0x000007FFU)      /*!< mask of standard identifier */
+#define CAN_EFID_MASK                      ((uint32_t)0x1FFFFFFFU)      /*!< mask of extended identifier */
+
+/* CAN working mode */
+#define CAN_MODE_INITIALIZE                ((uint8_t)0x01U)             /*!< CAN initialize mode */
+#define CAN_MODE_NORMAL                    ((uint8_t)0x02U)             /*!< CAN normal mode */
+#define CAN_MODE_SLEEP                     ((uint8_t)0x04U)             /*!< CAN sleep mode */
+
+/* filter bits */
+#define CAN_FILTERBITS_16BIT               ((uint8_t)0x00U)             /*!< CAN filter 16 bits */
+#define CAN_FILTERBITS_32BIT               ((uint8_t)0x01U)             /*!< CAN filter 32 bits */
+
+/* filter mode */
+#define CAN_FILTERMODE_MASK                ((uint8_t)0x00U)             /*!< mask mode */
+#define CAN_FILTERMODE_LIST                ((uint8_t)0x01U)             /*!< list mode */
+
+/* filter 16 bits mask */
+#define CAN_FILTER_MASK_16BITS             ((uint32_t)0x0000FFFFU) 
+
+/* frame type */
+#define CAN_FT_DATA                        ((uint32_t)0x00000000U)      /*!< data frame */
+#define CAN_FT_REMOTE                      ((uint32_t)0x00000002U)      /*!< remote frame */
+
+/* CAN timeout */
+#define CAN_TIMEOUT                        ((uint32_t)0x0000FFFFU)      /*!< timeout value */
+
+/* function declarations */
+/* initialization functions */
+/* CAN deinit */
+void can_deinit(uint32_t can_periph);
+/* CAN init */
+ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init);
+
+/* transmit functions */
+/* CAN transmit message */
+uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message);
+/* CAN transmit state */
+can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number);
+/* CAN stop transmission */
+void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number);
+/* CAN transmit error number */
+uint8_t can_transmit_error_number(uint32_t can_periph);
+
+/* filter functions */
+/* CAN filter init */
+void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init);
+/* set can1 fliter start bank number */
+void can1_filter_start_bank(uint8_t start_bank);
+
+/* enable functions */
+/* CAN debug freeze enable */
+void can_debug_freeze_enable(uint32_t can_periph);
+/* CAN debug freeze disable */
+void can_debug_freeze_disable(uint32_t can_periph);
+/* CAN time triggle mode enable */
+void can_time_trigger_mode_enable(uint32_t can_periph);
+/* CAN time triggle mode disable */
+void can_time_trigger_mode_disable(uint32_t can_periph);
+/* CAN interrupt enable */
+void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt);
+/* CAN interrupt disable */
+void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt);
+
+/* receive functions */
+/* CAN receive message */
+void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message);
+/* CAN release fifo */
+void can_fifo_release(uint32_t can_periph, uint8_t fifo_number);
+/* CAN receive message length */
+uint8_t can_receive_message_length(uint32_t can_periph, uint8_t fifo_number);
+/* CAN receive error number */
+uint8_t can_receive_error_number(uint32_t can_periph);
+
+/* mode functions */
+/* CAN working mode */
+ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode);
+/* CAN wakeup from sleep mode */
+ErrStatus can_wakeup(uint32_t can_periph);
+
+/* flag functions */
+/* CAN get error */
+can_error_enum can_error_get(uint32_t can_periph);
+/* CAN get flag state */
+FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag);
+/* CAN clear flag state */
+void can_flag_clear(uint32_t can_periph, can_flag_enum flag);
+/* CAN get interrupt flag state */
+FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag);
+/* CAN clear interrupt flag state */
+void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag);
+
+#endif /* GD32F4XX_CAN_H */

+ 55 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h

@@ -0,0 +1,55 @@
+/*!
+    \file  gd32f4xx_crc.h
+    \brief definitions for the CRC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_CRC_H
+#define GD32F4XX_CRC_H
+
+#include "gd32f4xx.h"
+
+/* CRC definitions */
+#define CRC                            CRC_BASE
+
+/* registers definitions */
+#define CRC_DATA                       REG32(CRC + 0x00U)              /*!< CRC data register */
+#define CRC_FDATA                      REG32(CRC + 0x04U)              /*!< CRC free data register */
+#define CRC_CTL                        REG32(CRC + 0x08U)              /*!< CRC control register */
+
+/* bits definitions */
+/* CRC_DATA */
+#define CRC_DATA_DATA                  BITS(0,31)                      /*!< CRC calculation result bits */
+
+/* CRC_FDATA */
+#define CRC_FDATA_FDATA                BITS(0,7)                       /*!< CRC free data bits */
+
+/* CRC_CTL */
+#define CRC_CTL_RST                    BIT(0)                          /*!< CRC reset CRC_DATA register bit */
+
+
+/* function declarations */
+/* deinit CRC calculation unit */
+void crc_deinit(void);
+
+/* reset data register to the value of initializaiton data register */
+void crc_data_register_reset(void);
+/* read the data register */
+uint32_t crc_data_register_read(void);
+
+/* read the free data register */
+uint8_t crc_free_data_register_read(void);
+/* write the free data register */
+void crc_free_data_register_write(uint8_t free_data);
+
+/* CRC calculate a 32-bit data */
+uint32_t crc_single_data_calculate(uint32_t sdata);
+/* CRC calculate a 32-bit data array */
+uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size);
+
+#endif /* GD32F4XX_CRC_H */

+ 168 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h

@@ -0,0 +1,168 @@
+/*!
+    \file  gd32f4xx_ctc.h
+    \brief definitions for the CTC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_CTC_H
+#define GD32F4XX_CTC_H
+
+#include "gd32f4xx.h"
+
+/* CTC definitions */
+#define CTC                          CTC_BASE
+
+/* registers definitions */
+#define CTC_CTL0                     REG32((CTC) + 0x00U)      /*!< CTC control register 0 */
+#define CTC_CTL1                     REG32((CTC) + 0x04U)      /*!< CTC control register 1 */
+#define CTC_STAT                     REG32((CTC) + 0x08U)      /*!< CTC status register */
+#define CTC_INTC                     REG32((CTC) + 0x0CU)      /*!< CTC interrupt clear register */
+
+/* bits definitions */
+/* CTC_CTL0 */
+#define CTC_CTL0_CKOKIE              BIT(0)                    /*!< clock trim OK(CKOKIF) interrupt enable */ 
+#define CTC_CTL0_CKWARNIE            BIT(1)                    /*!< clock trim warning(CKWARNIF) interrupt enable */
+#define CTC_CTL0_ERRIE               BIT(2)                    /*!< error(ERRIF) interrupt enable */
+#define CTC_CTL0_EREFIE              BIT(3)                    /*!< EREFIF interrupt enable */
+#define CTC_CTL0_CNTEN               BIT(5)                    /*!< CTC counter enable */
+#define CTC_CTL0_AUTOTRIM            BIT(6)                    /*!< hardware automatically trim mode */
+#define CTC_CTL0_SWREFPUL            BIT(7)                    /*!< software reference source sync pulse */
+#define CTC_CTL0_TRIMVALUE           BITS(8,13)                /*!< IRC48M trim value */
+
+/* CTC_CTL1 */
+#define CTC_CTL1_RLVALUE             BITS(0,15)                /*!< CTC counter reload value */
+#define CTC_CTL1_CKLIM               BITS(16,23)               /*!< clock trim base limit value */
+#define CTC_CTL1_REFPSC              BITS(24,26)               /*!< reference signal source prescaler */
+#define CTC_CTL1_REFSEL              BITS(28,29)               /*!< reference signal source selection */
+#define CTC_CTL1_USBSOFSEL           BIT(30)                   /*!< USBFS or USBHS SOF signal selection */
+#define CTC_CTL1_REFPOL              BIT(31)                   /*!< reference signal source polarity */
+
+/* CTC_STAT */
+#define CTC_STAT_CKOKIF              BIT(0)                    /*!< clock trim OK interrupt flag */
+#define CTC_STAT_CKWARNIF            BIT(1)                    /*!< clock trim warning interrupt flag */
+#define CTC_STAT_ERRIF               BIT(2)                    /*!< error interrupt flag */
+#define CTC_STAT_EREFIF              BIT(3)                    /*!< expect reference interrupt flag */
+#define CTC_STAT_CKERR               BIT(8)                    /*!< clock trim error bit */
+#define CTC_STAT_REFMISS             BIT(9)                    /*!< reference sync pulse miss */
+#define CTC_STAT_TRIMERR             BIT(10)                   /*!< trim value error bit */
+#define CTC_STAT_REFDIR              BIT(15)                   /*!< CTC trim counter direction when reference sync pulse occurred */
+#define CTC_STAT_REFCAP              BITS(16,31)               /*!< CTC counter capture when reference sync pulse occurred */
+
+/* CTC_INTC */
+#define CTC_INTC_CKOKIC              BIT(0)                    /*!< CKOKIF interrupt clear bit */
+#define CTC_INTC_CKWARNIC            BIT(1)                    /*!< CKWARNIF interrupt clear bit */
+#define CTC_INTC_ERRIC               BIT(2)                    /*!< ERRIF interrupt clear bit */
+#define CTC_INTC_EREFIC              BIT(3)                    /*!< EREFIF interrupt clear bit */
+
+/* constants definitions */
+/* hardware automatically trim mode definitions */
+#define CTC_HARDWARE_TRIM_MODE_ENABLE                    CTC_CTL0_AUTOTRIM            /*!< hardware automatically trim mode enable*/
+#define CTC_HARDWARE_TRIM_MODE_DISABLE                   ((uint32_t)0x00000000U)      /*!< hardware automatically trim mode disable*/
+
+/* reference signal source polarity definitions */
+#define CTC_REFSOURCE_POLARITY_FALLING                   CTC_CTL1_REFPOL              /*!< reference signal source polarity is falling edge*/
+#define CTC_REFSOURCE_POLARITY_RISING                    ((uint32_t)0x00000000U)      /*!< reference signal source polarity is rising edge*/
+
+/* USBFS or USBHS SOF signal selection definitions */
+#define CTC_USBSOFSEL_USBHS                              CTC_CTL1_USBSOFSEL           /*!< USBHS SOF signal is selected*/
+#define CTC_USBSOFSEL_USBFS                              ((uint32_t)0x00000000U)      /*!< USBFS SOF signal is selected*/
+
+/* reference signal source selection definitions */
+#define CTL1_REFSEL(regval)                              (BITS(28,29) & ((uint32_t)(regval) << 28))
+#define CTC_REFSOURCE_GPIO                               CTL1_REFSEL(0)               /*!< GPIO is selected */
+#define CTC_REFSOURCE_LXTAL                              CTL1_REFSEL(1)               /*!< LXTAL is clock selected */
+#define CTC_REFSOURCE_USBSOF                             CTL1_REFSEL(2)               /*!< USBSOF is selected */
+
+/* reference signal source prescaler definitions */
+#define CTL1_REFPSC(regval)                              (BITS(24,26) & ((uint32_t)(regval) << 24))
+#define CTC_REFSOURCE_PSC_OFF                            CTL1_REFPSC(0)               /*!< reference signal not divided */
+#define CTC_REFSOURCE_PSC_DIV2                           CTL1_REFPSC(1)               /*!< reference signal divided by 2 */
+#define CTC_REFSOURCE_PSC_DIV4                           CTL1_REFPSC(2)               /*!< reference signal divided by 4 */
+#define CTC_REFSOURCE_PSC_DIV8                           CTL1_REFPSC(3)               /*!< reference signal divided by 8 */
+#define CTC_REFSOURCE_PSC_DIV16                          CTL1_REFPSC(4)               /*!< reference signal divided by 16 */
+#define CTC_REFSOURCE_PSC_DIV32                          CTL1_REFPSC(5)               /*!< reference signal divided by 32 */
+#define CTC_REFSOURCE_PSC_DIV64                          CTL1_REFPSC(6)               /*!< reference signal divided by 64 */
+#define CTC_REFSOURCE_PSC_DIV128                         CTL1_REFPSC(7)               /*!< reference signal divided by 128 */
+
+/* CTC interrupt enable definitions */
+#define CTC_INT_CKOKIE                                   CTC_CTL0_CKOKIE             /*!< clock trim OK interrupt enable */
+#define CTC_INT_CKWARNIE                                 CTC_CTL0_CKWARNIE           /*!< clock trim warning interrupt enable */
+#define CTC_INT_ERRIE                                    CTC_CTL0_ERRIE              /*!< error interrupt enable */
+#define CTC_INT_EREFIE                                   CTC_CTL0_EREFIE             /*!< expect reference interrupt enable */
+
+/* CTC interrupt source definitions */
+#define CTC_INT_CKOK                                     CTC_STAT_CKOKIF             /*!< clock trim OK interrupt flag */
+#define CTC_INT_CKWARN                                   CTC_STAT_CKWARNIF           /*!< clock trim warning interrupt flag */
+#define CTC_INT_ERR                                      CTC_STAT_ERRIF              /*!< error interrupt flag */
+#define CTC_INT_EREF                                     CTC_STAT_EREFIF             /*!< expect reference interrupt flag */
+#define CTC_INT_CKERR                                    CTC_STAT_CKERR              /*!< clock trim error bit */
+#define CTC_INT_REFMISS                                  CTC_STAT_REFMISS            /*!< reference sync pulse miss */
+#define CTC_INT_TRIMERR                                  CTC_STAT_TRIMERR            /*!< trim value error */
+
+/* CTC flag definitions */
+#define CTC_FLAG_CKOK                                    CTC_STAT_CKOKIF             /*!< clock trim OK flag */
+#define CTC_FLAG_CKWARN                                  CTC_STAT_CKWARNIF           /*!< clock trim warning flag */
+#define CTC_FLAG_ERR                                     CTC_STAT_ERRIF              /*!< error flag */
+#define CTC_FLAG_EREF                                    CTC_STAT_EREFIF             /*!< expect reference flag */
+#define CTC_FLAG_CKERR                                   CTC_STAT_CKERR              /*!< clock trim error bit */
+#define CTC_FLAG_REFMISS                                 CTC_STAT_REFMISS            /*!< reference sync pulse miss */
+#define CTC_FLAG_TRIMERR                                 CTC_STAT_TRIMERR            /*!< trim value error bit */
+
+/* function declarations */
+/* reset ctc clock trim controller */
+void ctc_deinit(void);
+
+/* enable the CTC interrupt */
+void ctc_interrupt_enable(uint32_t ctc_interrupt);
+/* disable the CTC interrupt */
+void ctc_interrupt_disable(uint32_t ctc_interrupt);
+/* get CTC interrupt flag */
+FlagStatus ctc_interrupt_flag_get(uint32_t ctc_interrupt); 
+/* clear CTC interrupt flag */
+void ctc_interrupt_flag_clear(uint32_t ctc_interrupt);
+
+/* get CTC flag */
+FlagStatus ctc_flag_get(uint32_t ctc_flag);
+/* clear CTC flag */
+void ctc_flag_clear(uint32_t ctc_flag);
+
+/* configure the IRC48M trim value */
+void ctc_irc48m_trim_value_config(uint8_t ctc_trim_value);
+/* generate software reference source sync pulse */
+void ctc_software_refsource_pulse_generate(void);
+/* configure hardware automatically trim mode */
+void ctc_hardware_trim_mode_config(uint32_t ctc_hardmode);
+
+/* enable CTC counter */
+void ctc_counter_enable(void);
+/* disable CTC counter */
+void ctc_counter_disable(void);
+
+/* configure reference signal source polarity */
+void ctc_refsource_polarity_config(uint32_t ctc_polarity);
+/* select USBFS or USBHS SOF signal */
+void ctc_usbsof_signal_select(uint32_t ctc_usbsof);
+/* select reference signal source */
+void ctc_refsource_signal_select(uint32_t ctc_refs);
+/* configure reference signal source prescaler */
+void ctc_refsource_prescaler_config(uint32_t ctc_prescaler);
+/* configure clock trim base limit value */
+void ctc_clock_limit_value_config(uint8_t ctc_limit_value);
+/* configure CTC counter reload value */
+void ctc_counter_reload_value_config(uint16_t ctc_reload_value);
+
+/* read CTC counter capture value when reference sync pulse occurred */
+uint16_t ctc_counter_capture_value_read(void);
+/* read CTC trim counter direction when reference sync pulse occurred */
+FlagStatus ctc_counter_direction_read(void);
+/* read CTC counter reload value */
+uint16_t ctc_counter_reload_value_read(void);
+/* read the IRC48M trim value */
+uint8_t ctc_irc48m_trim_value_read(void);
+
+#endif /* GD32F4XX_CTC_H */

+ 240 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h

@@ -0,0 +1,240 @@
+/*!
+    \file  gd32f4xx_dac.h
+    \brief definitions for the DAC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_DAC_H
+#define GD32F4XX_DAC_H
+
+#include "gd32f4xx.h"
+
+/* DACx(x=0,1) definitions */
+#define DAC                     DAC_BASE
+#define DAC0                    0U
+#define DAC1                    1U
+
+/* registers definitions */
+#define DAC_CTL                 REG32(DAC + 0x00U)   /*!< DAC control register */
+#define DAC_SWT                 REG32(DAC + 0x04U)   /*!< DAC software trigger register */
+#define DAC0_R12DH              REG32(DAC + 0x08U)   /*!< DAC0 12-bit right-aligned data holding register */
+#define DAC0_L12DH              REG32(DAC + 0x0CU)   /*!< DAC0 12-bit left-aligned data holding register */
+#define DAC0_R8DH               REG32(DAC + 0x10U)   /*!< DAC0 8-bit right-aligned data holding register */
+#define DAC1_R12DH              REG32(DAC + 0x14U)   /*!< DAC1 12-bit right-aligned data holding register */
+#define DAC1_L12DH              REG32(DAC + 0x18U)   /*!< DAC1 12-bit left-aligned data holding register */
+#define DAC1_R8DH               REG32(DAC + 0x1CU)   /*!< DAC1 8-bit right-aligned data holding register */
+#define DACC_R12DH              REG32(DAC + 0x20U)   /*!< DAC concurrent mode 12-bit right-aligned data holding register */
+#define DACC_L12DH              REG32(DAC + 0x24U)   /*!< DAC concurrent mode 12-bit left-aligned data holding register */
+#define DACC_R8DH               REG32(DAC + 0x28U)   /*!< DAC concurrent mode 8-bit right-aligned data holding register */
+#define DAC0_DO                 REG32(DAC + 0x2CU)   /*!< DAC0 data output register */
+#define DAC1_DO                 REG32(DAC + 0x30U)   /*!< DAC1 data output register */
+#define DAC_STAT                REG32(DAC + 0x34U)   /*!< DAC status register */
+
+/* bits definitions */
+/* DAC_CLT */
+#define DAC_CTL_DEN0            BIT(0)               /*!< DAC0 enable/disable bit */
+#define DAC_CTL_DBOFF0          BIT(1)               /*!< DAC0 output buffer turn on/turn off bit */
+#define DAC_CTL_DTEN0           BIT(2)               /*!< DAC0 trigger enable/disable bit */
+#define DAC_CTL_DTSEL0          BITS(3,5)            /*!< DAC0 trigger source selection enable/disable bits */
+#define DAC_CTL_DWM0            BITS(6,7)            /*!< DAC0 noise wave mode */
+#define DAC_CTL_DWBW0           BITS(8,11)           /*!< DAC0 noise wave bit width */
+#define DAC_CTL_DDMAEN0         BIT(12)              /*!< DAC0 DMA enable/disanle bit */
+#define DAC_CTL_DDUDRIE0        BIT(13)              /*!< DAC0 DMA underrun interrupt enable/disable bit */
+#define DAC_CTL_DEN1            BIT(16)              /*!< DAC1 enable/disable bit */ 
+#define DAC_CTL_DBOFF1          BIT(17)              /*!< DAC1 output buffer turn on/turn off bit */
+#define DAC_CTL_DTEN1           BIT(18)              /*!< DAC1 trigger enable/disable bit */
+#define DAC_CTL_DTSEL1          BITS(19,21)          /*!< DAC1 trigger source selection enable/disable bits */
+#define DAC_CTL_DWM1            BITS(22,23)          /*!< DAC1 noise wave mode */
+#define DAC_CTL_DWBW1           BITS(24,27)          /*!< DAC1 noise wave bit width */
+#define DAC_CTL_DDMAEN1         BIT(28)              /*!< DAC1 DMA enable/disanle bit */
+#define DAC_CTL_DDUDRIE1        BIT(29)              /*!< DAC1 DMA underrun interrupt enable/disable bit */
+
+/* DAC_SWT */
+#define DAC_SWT_SWTR0           BIT(0)               /*!< DAC0 software trigger bit, cleared by hardware */
+#define DAC_SWT_SWTR1           BIT(1)               /*!< DAC1 software trigger bit, cleared by hardware */
+
+/* DAC0_R12DH */
+#define DAC0_R12DH_DAC0_DH      BITS(0,11)           /*!< DAC0 12-bit right-aligned data bits */
+
+/* DAC0_L12DH */
+#define DAC0_L12DH_DAC0_DH      BITS(4,15)           /*!< DAC0 12-bit left-aligned data bits */
+
+/* DAC0_R8DH */
+#define DAC0_R8DH_DAC0_DH       BITS(0,7)            /*!< DAC0 8-bit right-aligned data bits */
+
+/* DAC1_R12DH */
+#define DAC1_R12DH_DAC1_DH      BITS(0,11)           /*!< DAC1 12-bit right-aligned data bits */
+
+/* DAC1_L12DH */
+#define DAC1_L12DH_DAC1_DH      BITS(4,15)           /*!< DAC1 12-bit left-aligned data bits */
+
+/* DAC1_R8DH */
+#define DAC1_R8DH_DAC1_DH       BITS(0,7)            /*!< DAC1 8-bit right-aligned data bits */
+
+/* DACC_R12DH */
+#define DACC_R12DH_DAC0_DH      BITS(0,11)           /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */
+#define DACC_R12DH_DAC1_DH      BITS(16,27)          /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */
+
+/* DACC_L12DH */
+#define DACC_L12DH_DAC0_DH      BITS(4,15)           /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */
+#define DACC_L12DH_DAC1_DH      BITS(20,31)          /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */
+
+/* DACC_R8DH */
+#define DACC_R8DH_DAC0_DH       BITS(0,7)            /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */
+#define DACC_R8DH_DAC1_DH       BITS(16,23)          /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */
+
+/* DAC0_DO */
+#define DAC0_DO_DAC0_DO         BITS(0,11)           /*!< DAC0 12-bit output data bits */
+
+/* DAC1_DO */
+#define DAC1_DO_DAC1_DO         BITS(0,11)           /*!< DAC1 12-bit output data bits */
+
+/* DAC_STAT */
+#define DAC_STAT_DDUDR0         BIT(13)              /*!< DAC0 DMA underrun flag */
+#define DAC_STAT_DDUDR1         BIT(29)              /*!< DAC1 DMA underrun flag */
+
+/* constants definitions */
+/* DAC trigger source */
+#define CTL_DTSEL(regval)       (BITS(3,5) & ((uint32_t)(regval) << 3))
+#define DAC_TRIGGER_T5_TRGO     CTL_DTSEL(0)         /*!< TIMER5 TRGO */
+#define DAC_TRIGGER_T7_TRGO     CTL_DTSEL(1)         /*!< TIMER7 TRGO */
+#define DAC_TRIGGER_T6_TRGO     CTL_DTSEL(2)         /*!< TIMER6 TRGO */
+#define DAC_TRIGGER_T4_TRGO     CTL_DTSEL(3)         /*!< TIMER4 TRGO */
+#define DAC_TRIGGER_T1_TRGO     CTL_DTSEL(4)         /*!< TIMER1 TRGO */
+#define DAC_TRIGGER_T3_TRGO     CTL_DTSEL(5)         /*!< TIMER3 TRGO */
+#define DAC_TRIGGER_EXTI_9      CTL_DTSEL(6)         /*!< EXTI interrupt line9 event */
+#define DAC_TRIGGER_SOFTWARE    CTL_DTSEL(7)         /*!< software trigger */
+
+/* DAC noise wave mode */
+#define CTL_DWM(regval)         (BITS(6,7) & ((uint32_t)(regval) << 6))
+#define DAC_WAVE_DISABLE        CTL_DWM(0)           /*!< wave disable */
+#define DAC_WAVE_MODE_LFSR      CTL_DWM(1)           /*!< LFSR noise mode */
+#define DAC_WAVE_MODE_TRIANGLE  CTL_DWM(2)           /*!< triangle noise mode */
+
+/* DAC noise wave bit width */
+#define DWBW(regval)            (BITS(8,11) & ((uint32_t)(regval) << 8))
+#define DAC_WAVE_BIT_WIDTH_1    DWBW(0)              /*!< bit width of the wave signal is 1 */
+#define DAC_WAVE_BIT_WIDTH_2    DWBW(1)              /*!< bit width of the wave signal is 2 */
+#define DAC_WAVE_BIT_WIDTH_3    DWBW(2)              /*!< bit width of the wave signal is 3 */
+#define DAC_WAVE_BIT_WIDTH_4    DWBW(3)              /*!< bit width of the wave signal is 4 */
+#define DAC_WAVE_BIT_WIDTH_5    DWBW(4)              /*!< bit width of the wave signal is 5 */
+#define DAC_WAVE_BIT_WIDTH_6    DWBW(5)              /*!< bit width of the wave signal is 6 */
+#define DAC_WAVE_BIT_WIDTH_7    DWBW(6)              /*!< bit width of the wave signal is 7 */
+#define DAC_WAVE_BIT_WIDTH_8    DWBW(7)              /*!< bit width of the wave signal is 8 */
+#define DAC_WAVE_BIT_WIDTH_9    DWBW(8)              /*!< bit width of the wave signal is 9 */
+#define DAC_WAVE_BIT_WIDTH_10   DWBW(9)              /*!< bit width of the wave signal is 10 */
+#define DAC_WAVE_BIT_WIDTH_11   DWBW(10)             /*!< bit width of the wave signal is 11 */
+#define DAC_WAVE_BIT_WIDTH_12   DWBW(11)             /*!< bit width of the wave signal is 12 */
+
+/* unmask LFSR bits in DAC LFSR noise mode */
+#define DAC_LFSR_BIT0           DAC_WAVE_BIT_WIDTH_1  /*!< unmask the LFSR bit0 */
+#define DAC_LFSR_BITS1_0        DAC_WAVE_BIT_WIDTH_2  /*!< unmask the LFSR bits[1:0] */
+#define DAC_LFSR_BITS2_0        DAC_WAVE_BIT_WIDTH_3  /*!< unmask the LFSR bits[2:0] */
+#define DAC_LFSR_BITS3_0        DAC_WAVE_BIT_WIDTH_4  /*!< unmask the LFSR bits[3:0] */
+#define DAC_LFSR_BITS4_0        DAC_WAVE_BIT_WIDTH_5  /*!< unmask the LFSR bits[4:0] */
+#define DAC_LFSR_BITS5_0        DAC_WAVE_BIT_WIDTH_6  /*!< unmask the LFSR bits[5:0] */
+#define DAC_LFSR_BITS6_0        DAC_WAVE_BIT_WIDTH_7  /*!< unmask the LFSR bits[6:0] */
+#define DAC_LFSR_BITS7_0        DAC_WAVE_BIT_WIDTH_8  /*!< unmask the LFSR bits[7:0] */
+#define DAC_LFSR_BITS8_0        DAC_WAVE_BIT_WIDTH_9  /*!< unmask the LFSR bits[8:0] */
+#define DAC_LFSR_BITS9_0        DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */
+#define DAC_LFSR_BITS10_0       DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */
+#define DAC_LFSR_BITS11_0       DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */
+
+/* triangle amplitude in DAC triangle noise mode */
+#define DAC_TRIANGLE_AMPLITUDE_1    DAC_WAVE_BIT_WIDTH_1  /*!< triangle amplitude is 1 */
+#define DAC_TRIANGLE_AMPLITUDE_3    DAC_WAVE_BIT_WIDTH_2  /*!< triangle amplitude is 3 */
+#define DAC_TRIANGLE_AMPLITUDE_7    DAC_WAVE_BIT_WIDTH_3  /*!< triangle amplitude is 7 */
+#define DAC_TRIANGLE_AMPLITUDE_15   DAC_WAVE_BIT_WIDTH_4  /*!< triangle amplitude is 15 */
+#define DAC_TRIANGLE_AMPLITUDE_31   DAC_WAVE_BIT_WIDTH_5  /*!< triangle amplitude is 31 */
+#define DAC_TRIANGLE_AMPLITUDE_63   DAC_WAVE_BIT_WIDTH_6  /*!< triangle amplitude is 63 */
+#define DAC_TRIANGLE_AMPLITUDE_127  DAC_WAVE_BIT_WIDTH_7  /*!< triangle amplitude is 127 */
+#define DAC_TRIANGLE_AMPLITUDE_255  DAC_WAVE_BIT_WIDTH_8  /*!< triangle amplitude is 255 */
+#define DAC_TRIANGLE_AMPLITUDE_511  DAC_WAVE_BIT_WIDTH_9  /*!< triangle amplitude is 511 */
+#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */
+#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */
+#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */
+
+/* DAC data alignment */
+#define DATA_ALIGN(regval)      (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define DAC_ALIGN_12B_R         DATA_ALIGN(0)        /*!< data right 12b alignment */
+#define DAC_ALIGN_12B_L         DATA_ALIGN(1)        /*!< data left 12b alignment */
+#define DAC_ALIGN_8B_R          DATA_ALIGN(2)        /*!< data right 8b alignment */
+
+/* function declarations */
+/* deinitialize DAC */
+void dac_deinit(void);
+/* enable DAC */
+void dac_enable(uint32_t dac_periph);
+/* disable DAC */
+void dac_disable(uint32_t dac_periph);
+/* enable DAC DMA */
+void dac_dma_enable(uint32_t dac_periph);
+/* disable DAC DMA */
+void dac_dma_disable(uint32_t dac_periph); 
+/* enable DAC output buffer */
+void dac_output_buffer_enable(uint32_t dac_periph);
+/* disable DAC output buffer */
+void dac_output_buffer_disable(uint32_t dac_periph);
+/* enable DAC trigger */
+void dac_trigger_enable(uint32_t dac_periph);
+/* disable DAC trigger */
+void dac_trigger_disable(uint32_t dac_periph);
+/* enable DAC software trigger */
+void dac_software_trigger_enable(uint32_t dac_periph);
+/* disable DAC software trigger */
+void dac_software_trigger_disable(uint32_t dac_periph);
+/* enable DAC interrupt(DAC0 DMA underrun interrupt) */
+void dac_interrupt_enable(uint32_t dac_periph);
+/* disable DAC interrupt(DAC0 DMA underrun interrupt) */
+void dac_interrupt_disable(uint32_t dac_periph);
+
+/* configure DAC trigger source */
+void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource);
+/* configure DAC wave mode */
+void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode);
+/* configure DAC wave bit width */
+void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width);
+/* configure DAC LFSR noise mode */
+void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits);
+/* configure DAC triangle noise mode */
+void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude);
+/* get the last data output value */
+uint16_t dac_output_value_get(uint32_t dac_periph);
+
+/* set DAC data holding register value */
+void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data);
+/* set DAC concurrent mode data holding register value */
+void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1); 
+
+/* enable DAC concurrent mode */
+void dac_concurrent_enable(void);
+/* disable DAC concurrent mode */
+void dac_concurrent_disable(void);
+/* enable DAC concurrent software trigger */
+void dac_concurrent_software_trigger_enable(void);
+/* disable DAC concurrent software trigger */
+void dac_concurrent_software_trigger_disable(void);
+/* enable DAC concurrent buffer function */
+void dac_concurrent_output_buffer_enable(void);
+/* disable DAC concurrent buffer function */
+void dac_concurrent_output_buffer_disable(void);
+/* enable DAC concurrent interrupt */
+void dac_concurrent_interrupt_enable(void);
+/* disable DAC concurrent interrupt */
+void dac_concurrent_interrupt_disable(void);
+
+/* get the specified DAC flag(DAC DMA underrun flag) */
+FlagStatus dac_flag_get(uint32_t dac_periph);
+/* clear the specified DAC flag(DAC DMA underrun flag) */
+void dac_flag_clear(uint32_t dac_periph);
+/* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */
+FlagStatus dac_interrupt_flag_get(uint32_t dac_periph);
+/* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */
+void dac_interrupt_flag_clear(uint32_t dac_periph);
+
+#endif /* GD32F4XX_DAC_H */

+ 121 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h

@@ -0,0 +1,121 @@
+/*!
+    \file  gd32f4xx_dbg.h
+    \brief definitions for the DBG
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_DBG_H
+#define GD32F4XX_DBG_H
+
+#include "gd32f4xx.h"
+
+/* DBG definitions */
+#define DBG                      DBG_BASE
+
+/* registers definitions */
+#define DBG_ID                   REG32(DBG + 0x00U)         /*!< DBG_ID code register */
+#define DBG_CTL0                 REG32(DBG + 0x04U)         /*!< DBG control register 0 */
+#define DBG_CTL1                 REG32(DBG + 0x08U)         /*!< DBG control register 1 */
+#define DBG_CTL2                 REG32(DBG + 0x0CU)         /*!< DBG control register 2 */
+
+/* bits definitions */
+/* DBG_ID */
+#define DBG_ID_ID_CODE           BITS(0,31)                 /*!< DBG ID code values */
+
+/* DBG_CTL0 */
+#define DBG_CTL0_SLP_HOLD        BIT(0)                     /*!< keep debugger connection during sleep mode */
+#define DBG_CTL0_DSLP_HOLD       BIT(1)                     /*!< keep debugger connection during deepsleep mode */
+#define DBG_CTL0_STB_HOLD        BIT(2)                     /*!< keep debugger connection during standby mode */
+#define DBG_CTL0_TRACE_IOEN      BIT(5)                     /*!< enable trace pin assignment */
+#define DBG_CTL0_TRACE_MODE      BITS(6,7)                  /*!< trace pin mode selection */
+
+/* DBG_CTL1 */
+#define DBG_CTL1_TIMER1_HOLD     BIT(0)                     /*!< hold TIMER1 counter when core is halted */
+#define DBG_CTL1_TIMER2_HOLD     BIT(1)                     /*!< hold TIMER2 counter when core is halted */
+#define DBG_CTL1_TIMER3_HOLD     BIT(2)                     /*!< hold TIMER3 counter when core is halted */
+#define DBG_CTL1_TIMER4_HOLD     BIT(3)                     /*!< hold TIMER4 counter when core is halted */
+#define DBG_CTL1_TIMER5_HOLD     BIT(4)                     /*!< hold TIMER5 counter when core is halted */
+#define DBG_CTL1_TIMER6_HOLD     BIT(5)                     /*!< hold TIMER6 counter when core is halted */
+#define DBG_CTL1_TIMER11_HOLD    BIT(6)                     /*!< hold TIMER11 counter when core is halted */
+#define DBG_CTL1_TIMER12_HOLD    BIT(7)                     /*!< hold TIMER12 counter when core is halted */
+#define DBG_CTL1_TIMER13_HOLD    BIT(8)                     /*!< hold TIMER13 counter when core is halted */
+#define DBG_CTL1_RTC_HOLD        BIT(10)                    /*!< hold RTC calendar and wakeup counter when core is halted */
+#define DBG_CTL1_WWDGT_HOLD      BIT(11)                    /*!< debug WWDGT kept when core is halted */
+#define DBG_CTL1_FWDGT_HOLD      BIT(12)                    /*!< debug FWDGT kept when core is halted */
+#define DBG_CTL1_I2C0_HOLD       BIT(21)                    /*!< hold I2C0 smbus when core is halted */
+#define DBG_CTL1_I2C1_HOLD       BIT(22)                    /*!< hold I2C1 smbus when core is halted */
+#define DBG_CTL1_I2C2_HOLD       BIT(23)                    /*!< hold I2C2 smbus when core is halted */
+#define DBG_CTL1_CAN0_HOLD       BIT(25)                    /*!< debug CAN0 kept when core is halted */
+#define DBG_CTL1_CAN1_HOLD       BIT(26)                    /*!< debug CAN1 kept when core is halted */
+
+/* DBG_CTL2 */
+#define DBG_CTL2_TIMER0_HOLD     BIT(0)                     /*!< hold TIMER0 counter when core is halted */
+#define DBG_CTL2_TIMER7_HOLD     BIT(1)                     /*!< hold TIMER7 counter when core is halted */
+#define DBG_CTL2_TIMER8_HOLD     BIT(16)                    /*!< hold TIMER8 counter when core is halted */
+#define DBG_CTL2_TIMER9_HOLD     BIT(17)                    /*!< hold TIMER9 counter when core is halted */
+#define DBG_CTL2_TIMER10_HOLD    BIT(18)                    /*!< hold TIMER10 counter when core is halted */
+
+/* constants definitions */
+#define DBG_LOW_POWER_SLEEP      DBG_CTL0_SLP_HOLD          /*!< keep debugger connection during sleep mode */
+#define DBG_LOW_POWER_DEEPSLEEP  DBG_CTL0_DSLP_HOLD         /*!< keep debugger connection during deepsleep mode */
+#define DBG_LOW_POWER_STANDBY    DBG_CTL0_STB_HOLD          /*!< keep debugger connection during standby mode */
+
+typedef enum
+{
+    DBG_TIMER1_HOLD            = BIT(0),                    /*!< hold TIMER1 counter when core is halted */
+    DBG_TIMER2_HOLD            = BIT(1),                    /*!< hold TIMER2 counter when core is halted */
+    DBG_TIMER3_HOLD            = BIT(2),                    /*!< hold TIMER3 counter when core is halted */
+    DBG_TIMER4_HOLD            = BIT(3),                    /*!< hold TIMER4 counter when core is halted */
+    DBG_TIMER5_HOLD            = BIT(4),                    /*!< hold TIMER5 counter when core is halted */
+    DBG_TIMER6_HOLD            = BIT(5),                    /*!< hold TIMER6 counter when core is halted */
+    DBG_TIMER11_HOLD           = BIT(6),                    /*!< hold TIMER11 counter when core is halted */
+    DBG_TIMER12_HOLD           = BIT(7),                    /*!< hold TIMER12 counter when core is halted */
+    DBG_TIMER13_HOLD           = BIT(8),                    /*!< hold TIMER13 counter when core is halted */
+    DBG_RTC_HOLD               = BIT(10),                   /*!< hold RTC calendar and wakeup counter when core is halted */
+    DBG_WWDGT_HOLD             = BIT(11),                   /*!< debug WWDGT kept when core is halted */
+    DBG_FWDGT_HOLD             = BIT(12),                   /*!< debug FWDGT kept when core is halted */
+    DBG_I2C0_HOLD              = BIT(21),                   /*!< hold I2C0 smbus when core is halted */
+    DBG_I2C1_HOLD              = BIT(22),                   /*!< hold I2C1 smbus when core is halted */
+    DBG_I2C2_HOLD              = BIT(23),                   /*!< hold I2C2 smbus when core is halted */
+    DBG_CAN0_HOLD              = BIT(25),                   /*!< debug CAN0 kept when core is halted */
+    DBG_CAN1_HOLD              = BIT(26),                   /*!< debug CAN1 kept when core is halted */
+    DBG_TIMER0_HOLD            = (BIT(0) | BIT(30)),        /*!< hold TIMER0 counter when core is halted */
+    DBG_TIMER7_HOLD            = (BIT(1) | BIT(30)),        /*!< hold TIMER7 counter when core is halted */
+    DBG_TIMER8_HOLD            = (BIT(16) | BIT(30)),       /*!< hold TIMER8 counter when core is halted */
+    DBG_TIMER9_HOLD            = (BIT(17) | BIT(30)),       /*!< hold TIMER9 counter when core is halted */
+    DBG_TIMER10_HOLD           = (BIT(18) | BIT(30)),       /*!< hold TIMER10 counter when core is halted */
+}dbg_periph_enum;
+
+#define CTL0_TRACE_MODE(regval)       (BITS(6,7)&((uint32_t)(regval)<<6))
+#define TRACE_MODE_ASYNC              CTL0_TRACE_MODE(0)    /*!< trace pin used for async mode */
+#define TRACE_MODE_SYNC_DATASIZE_1    CTL0_TRACE_MODE(1)    /*!< trace pin used for sync mode and data size is 1 */
+#define TRACE_MODE_SYNC_DATASIZE_2    CTL0_TRACE_MODE(2)    /*!< trace pin used for sync mode and data size is 2 */
+#define TRACE_MODE_SYNC_DATASIZE_4    CTL0_TRACE_MODE(3)    /*!< trace pin used for sync mode and data size is 4 */
+
+/* function declarations */
+/* read DBG_ID code register */
+uint32_t dbg_id_get(void);
+
+/* enable low power behavior when the MCU is in debug mode */
+void dbg_low_power_enable(uint32_t dbg_low_power);
+/* disable low power behavior when the MCU is in debug mode */
+void dbg_low_power_disable(uint32_t dbg_low_power);
+
+/* enable peripheral behavior when the MCU is in debug mode */
+void dbg_periph_enable(dbg_periph_enum dbg_periph);
+/* disable peripheral behavior when the MCU is in debug mode */
+void dbg_periph_disable(dbg_periph_enum dbg_periph);
+
+/* enable trace pin assignment */
+void dbg_trace_pin_enable(void);
+/* disable trace pin assignment */
+void dbg_trace_pin_disable(void);
+/* set trace pin mode */
+void dbg_trace_pin_mode_set(uint32_t trace_mode);
+
+#endif /* GD32F4XX_DBG_H */

+ 200 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h

@@ -0,0 +1,200 @@
+/*!
+    \file  gd32f4xx_dci.h
+    \brief definitions for the DCI
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_DCI_H
+#define GD32F4XX_DCI_H
+
+#include "gd32f4xx.h"
+
+/* DCI definitions */
+#define DCI                       DCI_BASE
+
+/* registers definitions */
+#define DCI_CTL                   REG32(DCI + 0x00U) /*!< DCI control register */
+#define DCI_STAT0                 REG32(DCI + 0x04U) /*!< DCI status register 0 */
+#define DCI_STAT1                 REG32(DCI + 0x08U) /*!< DCI status register 1 */
+#define DCI_INTEN                 REG32(DCI + 0x0CU) /*!< DCI interrupt enable register */
+#define DCI_INTF                  REG32(DCI + 0x10U) /*!< DCI interrupt flag register */
+#define DCI_INTC                  REG32(DCI + 0x14U) /*!< DCI interrupt clear register */
+#define DCI_SC                    REG32(DCI + 0x18U) /*!< DCI synchronization codes register */
+#define DCI_SCUMSK                REG32(DCI + 0x1CU) /*!< DCI synchronization codes unmask register */
+#define DCI_CWSPOS                REG32(DCI + 0x20U) /*!< DCI cropping window start position register */
+#define DCI_CWSZ                  REG32(DCI + 0x24U) /*!< DCI cropping window size register */
+#define DCI_DATA                  REG32(DCI + 0x28U) /*!< DCI data register */
+
+/* bits definitions */
+/* DCI_CTL */
+#define DCI_CTL_CAP               BIT(0)            /*!< capture enable */
+#define DCI_CTL_SNAP              BIT(1)            /*!< snapshot mode */
+#define DCI_CTL_WDEN              BIT(2)            /*!< window enable */
+#define DCI_CTL_JM                BIT(3)            /*!< jpeg mode */
+#define DCI_CTL_ESM               BIT(4)            /*!< embedded synchronous mode */
+#define DCI_CTL_CKS               BIT(5)            /*!< clock polarity selection */
+#define DCI_CTL_HPS               BIT(6)            /*!< horizontal polarity selection */
+#define DCI_CTL_VPS               BIT(7)            /*!< vertical polarity selection */
+#define DCI_CTL_FR                BITS(8,9)         /*!< frame rate */
+#define DCI_CTL_DCIF              BITS(10,11)       /*!< digital camera interface format */
+#define DCI_CTL_DCIEN             BIT(14)           /*!< dci enable */
+
+/* DCI_STAT0 */
+#define DCI_STAT0_HS              BIT(0)            /*!< HS line status */
+#define DCI_STAT0_VS              BIT(1)            /*!< VS line status */
+#define DCI_STAT0_FV              BIT(2)            /*!< FIFO valid */
+
+/* DCI_STAT1 */
+#define DCI_STAT1_EFF             BIT(0)            /*!< end of frame flag */
+#define DCI_STAT1_OVRF            BIT(1)            /*!< FIFO overrun flag */
+#define DCI_STAT1_ESEF            BIT(2)            /*!< embedded synchronous error flag */
+#define DCI_STAT1_VSF             BIT(3)            /*!< vsync flag */
+#define DCI_STAT1_ELF             BIT(4)            /*!< end of line flag */
+
+/* DCI_INTEN */
+#define DCI_INTEN_EFIE            BIT(0)            /*!< end of frame interrupt enable */
+#define DCI_INTEN_OVRIE           BIT(1)            /*!< FIFO overrun interrupt enable */
+#define DCI_INTEN_ESEIE           BIT(2)            /*!< embedded synchronous error interrupt enable */
+#define DCI_INTEN_VSIE            BIT(3)            /*!< vsync interrupt enable */
+#define DCI_INTEN_ELIE            BIT(4)            /*!< end of line interrupt enable */
+
+/* DCI_INTF */
+#define DCI_INTF_EFIF             BIT(0)            /*!< end of frame interrupt flag */
+#define DCI_INTF_OVRIF            BIT(1)            /*!< FIFO overrun interrupt flag */
+#define DCI_INTF_ESEIF            BIT(2)            /*!< embedded synchronous error interrupt flag */
+#define DCI_INTF_VSIF             BIT(3)            /*!< vsync interrupt flag  */
+#define DCI_INTF_ELIF             BIT(4)            /*!< end of line interrupt flag */
+
+/* DCI_INTC */
+#define DCI_INTC_EFFC             BIT(0)            /*!< clear end of frame flag */
+#define DCI_INTC_OVRFC            BIT(1)            /*!< clear FIFO overrun flag */
+#define DCI_INTC_ESEFC            BIT(2)            /*!< clear embedded synchronous error flag */
+#define DCI_INTC_VSFC             BIT(3)            /*!< vsync flag clear */
+#define DCI_INTC_ELFC             BIT(4)            /*!< end of line flag clear */
+
+/* DCI_SC */
+#define DCI_SC_FS                 BITS(0,7)         /*!< frame start code in embedded synchronous mode */
+#define DCI_SC_LS                 BITS(8,15)        /*!< line start code in embedded synchronous mode */
+#define DCI_SC_LE                 BITS(16,23)       /*!< line end code in embedded synchronous mode */
+#define DCI_SC_FE                 BITS(24,31)       /*!< frame end code in embedded synchronous mode */
+
+/* DCI_SCUNMSK */
+#define DCI_SCUMSK_FSM            BITS(0,7)         /*!< frame start code unmask bits in embedded synchronous mode */
+#define DCI_SCUMSK_LSM            BITS(8,15)        /*!< line start code unmask bits in embedded synchronous mode */
+#define DCI_SCUMSK_LEM            BITS(16,23)       /*!< line end code unmask bits in embedded synchronous mode */
+#define DCI_SCUMSK_FEM            BITS(24,31)       /*!< frame end code unmask bits in embedded synchronous mode */
+
+/* DCI_CWSPOS */
+#define DCI_CWSPOS_WHSP           BITS(0,13)        /*!< window horizontal start position */
+#define DCI_CWSPOS_WVSP           BITS(16,28)       /*!< window vertical start position */
+
+/* DCI_CWSZ */
+#define DCI_CWSZ_WHSZ             BITS(0,13)        /*!< window horizontal size */
+#define DCI_CWSZ_WVSZ             BITS(16,29)       /*!< window vertical size */
+
+/* constants definitions */
+/* DCI parameter struct definitions */
+typedef struct
+{   
+    uint32_t capture_mode;                                           /*!< DCI capture mode: continuous or snapshot */
+    uint32_t clock_polarity;                                         /*!< clock polarity selection */
+    uint32_t hsync_polarity;                                         /*!< horizontal polarity selection */
+    uint32_t vsync_polarity;                                         /*!< vertical polarity selection */
+    uint32_t frame_rate;                                             /*!< frame capture rate */
+    uint32_t interface_format;                                       /*!< digital camera interface format */
+}dci_parameter_struct;                                                         
+
+#define DCI_CAPTURE_MODE_CONTINUOUS   ((uint32_t)0x00000000U)        /*!< continuous capture mode */
+#define DCI_CAPTURE_MODE_SNAPSHOT     DCI_CTL_SNAP                   /*!< snapshot capture mode */
+
+#define DCI_CK_POLARITY_FALLING       ((uint32_t)0x00000000U)        /*!< capture at falling edge */
+#define DCI_CK_POLARITY_RISING        DCI_CTL_CKS                    /*!< capture at rising edge */
+
+#define DCI_HSYNC_POLARITY_LOW        ((uint32_t)0x00000000U)        /*!< low level during blanking period */
+#define DCI_HSYNC_POLARITY_HIGH       DCI_CTL_HPS                    /*!< high level during blanking period */
+
+#define DCI_VSYNC_POLARITY_LOW        ((uint32_t)0x00000000U)        /*!< low level during blanking period */
+#define DCI_VSYNC_POLARITY_HIGH       DCI_CTL_VPS                    /*!< high level during blanking period*/
+ 
+#define CTL_FR(regval)                (BITS(8,9)&((uint32_t)(regval) << 8U))    
+#define DCI_FRAME_RATE_ALL            CTL_FR(0)                      /*!< capture all frames */
+#define DCI_FRAME_RATE_1_2            CTL_FR(1)                      /*!< capture one in 2 frames */
+#define DCI_FRAME_RATE_1_4            CTL_FR(2)                      /*!< capture one in 4 frames */
+
+#define CTL_DCIF(regval)              (BITS(10,11)&((uint32_t)(regval) << 10U)) 
+#define DCI_INTERFACE_FORMAT_8BITS    CTL_DCIF(0)                    /*!< 8-bit data on every pixel clock */
+#define DCI_INTERFACE_FORMAT_10BITS   CTL_DCIF(1)                    /*!< 10-bit data on every pixel clock */
+#define DCI_INTERFACE_FORMAT_12BITS   CTL_DCIF(2)                    /*!< 12-bit data on every pixel clock */
+#define DCI_INTERFACE_FORMAT_14BITS   CTL_DCIF(3)                    /*!< 14-bit data on every pixel clock */
+
+/* DCI interrupt constants definitions */
+#define DCI_INT_EF                    ((uint32_t)0x00000001U)         /*!< end of frame interrupt */
+#define DCI_INT_OVR                   ((uint32_t)0x00000002U)         /*!< FIFO overrun interrupt */
+#define DCI_INT_ESE                   ((uint32_t)0x00000004U)         /*!< embedded synchronous error interrupt */
+#define DCI_INT_VS                    ((uint32_t)0x00000008U)         /*!< vsync interrupt */
+#define DCI_INT_EL                    ((uint32_t)0x00000010U)         /*!< end of line interrupt */
+
+/* DCI flag definitions */  
+#define DCI_FLAG_HS                   ((uint8_t)0x01U)                /*!< HS line status */
+#define DCI_FLAG_VS                   ((uint8_t)0x02U)                /*!< VS line status */
+#define DCI_FLAG_FV                   ((uint8_t)0x03U)                /*!< FIFO valid */
+#define DCI_FLAG_EFF                  ((uint8_t)0x04U)                /*!< end of frame flag */
+#define DCI_FLAG_OVRF                 ((uint8_t)0x05U)                /*!< FIFO overrun flag */
+#define DCI_FLAG_ESEF                 ((uint8_t)0x06U)                /*!< embedded synchronous error flag */
+#define DCI_FLAG_VSF                  ((uint8_t)0x07U)                /*!< vsync flag */
+#define DCI_FLAG_ELF                  ((uint8_t)0x08U)                /*!< end of line flag */
+
+/* function declarations */
+/* DCI deinit */
+void dci_deinit(void);
+/* initialize DCI registers */
+void dci_init(dci_parameter_struct* dci_struct);
+
+/* enable DCI function */
+void dci_enable(void);
+/* disble DCI function */
+void dci_disable(void);
+/* enable DCI capture */
+void dci_capture_enable(void);
+/* disble DCI capture */
+void dci_capture_disable(void);
+/* enable DCI jpeg mode */
+void dci_jpeg_enable(void);
+/* disble DCI jpeg mode */
+void dci_jpeg_disable(void);
+
+/* enable cropping window function */
+void dci_crop_window_enable(void);
+/* disble cropping window function */
+void dci_crop_window_disable(void);
+/* config DCI cropping window */
+void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height);
+
+/* enable sync codes function */
+void dci_sync_codes_enable(void);
+/* disble sync codes function */
+void dci_sync_codes_disable(void);
+/* config sync codes */
+void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end);
+/* config sync codes unmask */
+void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end);
+
+/* read DCI data register */
+uint32_t dci_data_read(void);
+
+/* enable specified DCI interrupt */
+void dci_interrupt_enable(uint32_t interrupt);
+/* disble specified DCI interrupt */
+void dci_interrupt_disable(uint32_t interrupt);
+/* clear specified interrupt */
+void dci_interrupt_clear(uint32_t interrupt);
+/* get specified flag */
+FlagStatus dci_flag_get(uint32_t flag);
+/* get specified interrupt flag */
+FlagStatus dci_interrupt_flag_get(uint32_t interrupt);
+#endif /* GD32F4XX_DCI_H */

+ 380 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h

@@ -0,0 +1,380 @@
+/*!
+    \file  gd32f4xx_dma.h
+    \brief definitions for the DMA
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_DMA_H
+#define GD32F4XX_DMA_H
+
+#include "gd32f4xx.h"
+
+/* DMA definitions */
+#define DMA0                              (DMA_BASE)                    /*!< DMA0 base address */
+#define DMA1                              (DMA_BASE + 0x0400U)          /*!< DMA1 base address */
+
+/* registers definitions */
+#define DMA_INTF0(dmax)                    REG32((dmax) + 0x00U)        /*!< DMA interrupt flag register 0 */
+#define DMA_INTF1(dmax)                    REG32((dmax) + 0x04U)        /*!< DMA interrupt flag register 1 */
+#define DMA_INTC0(dmax)                    REG32((dmax) + 0x08U)        /*!< DMA interrupt flag clear register 0 */
+#define DMA_INTC1(dmax)                    REG32((dmax) + 0x0CU)        /*!< DMA interrupt flag clear register 1 */
+
+#define DMA_CH0CTL(dmax)                   REG32((dmax) + 0x10U)        /*!< DMA channel 0 control register */
+#define DMA_CH0CNT(dmax)                   REG32((dmax) + 0x14U)        /*!< DMA channel 0 counter register */
+#define DMA_CH0PADDR(dmax)                 REG32((dmax) + 0x18U)        /*!< DMA channel 0 peripheral base address register */
+#define DMA_CH0M0ADDR(dmax)                REG32((dmax) + 0x1CU)        /*!< DMA channel 0 memory 0 base address register */
+#define DMA_CH0M1ADDR(dmax)                REG32((dmax) + 0x20U)        /*!< DMA channel 0 memory 1 base address register */
+#define DMA_CH0FCTL(dmax)                  REG32((dmax) + 0x24U)        /*!< DMA channel 0 FIFO control register */
+
+#define DMA_CH1CTL(dmax)                   REG32((dmax) + 0x28U)        /*!< DMA channel 1 control register */
+#define DMA_CH1CNT(dmax)                   REG32((dmax) + 0x2CU)        /*!< DMA channel 1 counter register */
+#define DMA_CH1PADDR(dmax)                 REG32((dmax) + 0x30U)        /*!< DMA channel 1 peripheral base address register */
+#define DMA_CH1M0ADDR(dmax)                REG32((dmax) + 0x34U)        /*!< DMA channel 1 memory 0 base address register */
+#define DMA_CH1M1ADDR(dmax)                REG32((dmax) + 0x38U)        /*!< DMA channel 1 memory 1 base address register */
+#define DMA_CH1FCTL(dmax)                  REG32((dmax) + 0x3CU)        /*!< DMA channel 1 FIFO control register */
+
+#define DMA_CH2CTL(dmax)                   REG32((dmax) + 0x40U)        /*!< DMA channel 2 control register */
+#define DMA_CH2CNT(dmax)                   REG32((dmax) + 0x44U)        /*!< DMA channel 2 counter register */
+#define DMA_CH2PADDR(dmax)                 REG32((dmax) + 0x48U)        /*!< DMA channel 2 peripheral base address register */
+#define DMA_CH2M0ADDR(dmax)                REG32((dmax) + 0x4CU)        /*!< DMA channel 2 memory 0 base address register */
+#define DMA_CH2M1ADDR(dmax)                REG32((dmax) + 0x50U)        /*!< DMA channel 2 memory 1 base address register */
+#define DMA_CH2FCTL(dmax)                  REG32((dmax) + 0x54U)        /*!< DMA channel 2 FIFO control register */
+
+#define DMA_CH3CTL(dmax)                   REG32((dmax) + 0x58U)        /*!< DMA channel 3 control register */
+#define DMA_CH3CNT(dmax)                   REG32((dmax) + 0x5CU)        /*!< DMA channel 3 counter register */
+#define DMA_CH3PADDR(dmax)                 REG32((dmax) + 0x60U)        /*!< DMA channel 3 peripheral base address register */
+#define DMA_CH3M0ADDR(dmax)                REG32((dmax) + 0x64U)        /*!< DMA channel 3 memory 0 base address register */
+#define DMA_CH3M1ADDR(dmax)                REG32((dmax) + 0x68U)        /*!< DMA channel 3 memory 1 base address register */
+#define DMA_CH3FCTL(dmax)                  REG32((dmax) + 0x6CU)        /*!< DMA channel 3 FIFO control register */
+
+#define DMA_CH4CTL(dmax)                   REG32((dmax) + 0x70U)        /*!< DMA channel 4 control register */
+#define DMA_CH4CNT(dmax)                   REG32((dmax) + 0x74U)        /*!< DMA channel 4 counter register */
+#define DMA_CH4PADDR(dmax)                 REG32((dmax) + 0x78U)        /*!< DMA channel 4 peripheral base address register */
+#define DMA_CH4M0ADDR(dmax)                REG32((dmax) + 0x7CU)        /*!< DMA channel 4 memory 0 base address register */
+#define DMA_CH4M1ADDR(dmax)                REG32((dmax) + 0x80U)        /*!< DMA channel 4 memory 1 base address register */
+#define DMA_CH4FCTL(dmax)                  REG32((dmax) + 0x84U)        /*!< DMA channel 4 FIFO control register */
+
+#define DMA_CH5CTL(dmax)                   REG32((dmax) + 0x88U)        /*!< DMA channel 5 control register */
+#define DMA_CH5CNT(dmax)                   REG32((dmax) + 0x8CU)        /*!< DMA channel 5 counter register */
+#define DMA_CH5PADDR(dmax)                 REG32((dmax) + 0x90U)        /*!< DMA channel 5 peripheral base address register */
+#define DMA_CH5M0ADDR(dmax)                REG32((dmax) + 0x94U)        /*!< DMA channel 5 memory 0 base address register */
+#define DMA_CH5M1ADDR(dmax)                REG32((dmax) + 0x98U)        /*!< DMA channel 5 memory 1 base address register */
+#define DMA_CH5FCTL(dmax)                  REG32((dmax) + 0x9CU)        /*!< DMA channel 5 FIFO control register */
+
+#define DMA_CH6CTL(dmax)                   REG32((dmax) + 0xA0U)        /*!< DMA channel 6 control register */
+#define DMA_CH6CNT(dmax)                   REG32((dmax) + 0xA4U)        /*!< DMA channel 6 counter register */
+#define DMA_CH6PADDR(dmax)                 REG32((dmax) + 0xA8U)        /*!< DMA channel 6 peripheral base address register */
+#define DMA_CH6M0ADDR(dmax)                REG32((dmax) + 0xACU)        /*!< DMA channel 6 memory 0 base address register */
+#define DMA_CH6M1ADDR(dmax)                REG32((dmax) + 0xB0U)        /*!< DMA channel 6 memory 1 base address register */
+#define DMA_CH6FCTL(dmax)                  REG32((dmax) + 0xB4U)        /*!< DMA channel 6 FIFO control register */
+
+#define DMA_CH7CTL(dmax)                   REG32((dmax) + 0xB8U)        /*!< DMA channel 7 control register */
+#define DMA_CH7CNT(dmax)                   REG32((dmax) + 0xBCU)        /*!< DMA channel 7 counter register */
+#define DMA_CH7PADDR(dmax)                 REG32((dmax) + 0xC0U)        /*!< DMA channel 7 peripheral base address register */
+#define DMA_CH7M0ADDR(dmax)                REG32((dmax) + 0xC4U)        /*!< DMA channel 7 memory 0 base address register */
+#define DMA_CH7M1ADDR(dmax)                REG32((dmax) + 0xC8U)        /*!< DMA channel 7 memory 1 base address register */
+#define DMA_CH7FCTL(dmax)                  REG32((dmax) + 0xCCU)        /*!< DMA channel 7 FIFO control register */
+
+/* bits definitions */
+/* DMA_INTF */
+#define DMA_INTF_FEEIF                    BIT(0)                        /*!< FIFO error and exception flag */
+#define DMA_INTF_SDEIF                    BIT(2)                        /*!< single data mode exception flag */
+#define DMA_INTF_TAEIF                    BIT(3)                        /*!< transfer access error flag */
+#define DMA_INTF_HTFIF                    BIT(4)                        /*!< half transfer finish flag */
+#define DMA_INTF_FTFIF                    BIT(5)                        /*!< full transger finish flag */
+
+/* DMA_INTC */
+#define DMA_INTC_FEEIFC                   BIT(0)                        /*!< clear FIFO error and exception flag */
+#define DMA_INTC_SDEIFC                   BIT(2)                        /*!< clear single data mode exception flag */
+#define DMA_INTC_TAEIFC                   BIT(3)                        /*!< clear single data mode exception flag */
+#define DMA_INTC_HTFIFC                   BIT(4)                        /*!< clear half transfer finish flag */
+#define DMA_INTC_FTFIFC                   BIT(5)                        /*!< clear full transger finish flag */
+
+/* DMA_CHxCTL,x=0..7 */
+#define DMA_CHXCTL_CHEN                   BIT(0)                        /*!< channel x enable */
+#define DMA_CHXCTL_SDEIE                  BIT(1)                        /*!< enable bit for channel x single data mode exception interrupt */
+#define DMA_CHXCTL_TAEIE                  BIT(2)                        /*!< enable bit for channel x tranfer access error interrupt */
+#define DMA_CHXCTL_HTFIE                  BIT(3)                        /*!< enable bit for channel x half transfer finish interrupt */
+#define DMA_CHXCTL_FTFIE                  BIT(4)                        /*!< enable bit for channel x full transfer finish interrupt */
+#define DMA_CHXCTL_TFCS                   BIT(5)                        /*!< transfer flow controller select */
+#define DMA_CHXCTL_TM                     BITS(6,7)                     /*!< transfer mode */
+#define DMA_CHXCTL_CMEN                   BIT(8)                        /*!< circulation mode */
+#define DMA_CHXCTL_PNAGA                  BIT(9)                        /*!< next address generation algorithm of peripheral */
+#define DMA_CHXCTL_MNAGA                  BIT(10)                       /*!< next address generation algorithm of memory */
+#define DMA_CHXCTL_PWIDTH                 BITS(11,12)                   /*!< transfer width of peipheral */
+#define DMA_CHXCTL_MWIDTH                 BITS(13,14)                   /*!< transfer width of memory */
+#define DMA_CHXCTL_PAIF                   BIT(15)                       /*!< peripheral address increment fixed */
+#define DMA_CHXCTL_PRIO                   BITS(16,17)                   /*!< priority level */
+#define DMA_CHXCTL_SBMEN                  BIT(18)                       /*!< switch-buffer mode enable */
+#define DMA_CHXCTL_MBS                    BIT(19)                       /*!< memory buffer select */
+#define DMA_CHXCTL_PBURST                 BITS(21,22)                   /*!< transfer burst type of peripheral */
+#define DMA_CHXCTL_MBURST                 BITS(23,24)                   /*!< transfer burst type of memory */
+#define DMA_CHXCTL_PERIEN                 BITS(25,27)                   /*!< peripheral enable */
+
+/* DMA_CHxCNT,x=0..7 */
+#define DMA_CHXCNT_CNT                    BITS(0,15)                    /*!< transfer counter */
+
+/* DMA_CHxPADDR,x=0..7 */
+#define DMA_CHXPADDR_PADDR                BITS(0,31)                    /*!< peripheral base address */
+
+/* DMA_CHxM0ADDR,x=0..7 */
+#define DMA_CHXM0ADDR_PADDR               BITS(0,31)                    /*!< memory 0 base address */
+
+/* DMA_CHxM1ADDR,x=0..7 */
+#define DMA_CHXM1ADDR_PADDR               BITS(0,31)                    /*!< memory 1 base address */
+
+/* DMA_CHxFCTL,x=0..7 */
+#define DMA_CHXFCTL_FCCV                  BITS(0,1)                     /*!< FIFO counter critical value */
+#define DMA_CHXFCTL_MDMEN                 BIT(2)                        /*!< multi-data mode enable */
+#define DMA_CHXFCTL_FCNT                  BITS(3,5)                     /*!< FIFO counter */
+#define DMA_CHXFCTL_FEEIE                 BIT(7)                        /*!< FIFO exception interrupt enable */
+
+/* constants definitions */
+/* DMA channel select */
+typedef enum 
+{
+    DMA_CH0 = 0,                                    /*!< DMA Channel 0 */
+    DMA_CH1,                                        /*!< DMA Channel 1 */
+    DMA_CH2,                                        /*!< DMA Channel 2 */
+    DMA_CH3,                                        /*!< DMA Channel 3 */
+    DMA_CH4,                                        /*!< DMA Channel 4 */
+    DMA_CH5,                                        /*!< DMA Channel 5 */
+    DMA_CH6,                                        /*!< DMA Channel 6 */
+    DMA_CH7                                         /*!< DMA Channel 7 */
+} dma_channel_enum;
+
+/* DMA peripheral select */
+typedef enum 
+{
+    DMA_SUBPERI0 = 0,                               /*!< DMA Peripheral 0 */
+    DMA_SUBPERI1,                                   /*!< DMA Peripheral 1 */
+    DMA_SUBPERI2,                                   /*!< DMA Peripheral 2 */
+    DMA_SUBPERI3,                                   /*!< DMA Peripheral 3 */
+    DMA_SUBPERI4,                                   /*!< DMA Peripheral 4 */
+    DMA_SUBPERI5,                                   /*!< DMA Peripheral 5 */
+    DMA_SUBPERI6,                                   /*!< DMA Peripheral 6 */
+    DMA_SUBPERI7                                    /*!< DMA Peripheral 7 */
+} dma_subperipheral_enum;
+
+/* DMA multidata mode initialize struct */
+typedef struct
+{
+    uint32_t periph_addr;                           /*!< peripheral base address */
+    uint32_t periph_width;                          /*!< transfer data size of peripheral */
+    uint32_t periph_inc;                            /*!< peripheral increasing mode */  
+
+    uint32_t memory0_addr;                          /*!< memory 0 base address */
+    uint32_t memory_width;                          /*!< transfer data size of memory */
+    uint32_t memory_inc;                            /*!< memory increasing mode */
+
+    uint32_t memory_burst_width;                    /*!< multi data mode enable */
+    uint32_t periph_burst_width;                    /*!< multi data mode enable */
+    uint32_t critical_value;                        /*!< FIFO critical */
+
+    uint32_t circular_mode;
+    uint32_t direction;                             /*!< channel data transfer direction */
+    uint32_t number;                                /*!< channel transfer number */
+    uint32_t priority;                              /*!< channel priority level */
+}dma_multi_data_parameter_struct;
+
+/* DMA singledata mode initialize struct */
+typedef struct
+{
+    uint32_t periph_addr;                           /*!< peripheral base address */
+    uint32_t periph_inc;                            /*!< peripheral increasing mode */  
+
+    uint32_t memory0_addr;                          /*!< memory 0 base address */
+    uint32_t memory_inc;                            /*!< memory increasing mode */
+
+    uint32_t periph_memory_width;                   /*!< transfer data size of peripheral */
+
+    uint32_t circular_mode;                         /*!< DMA circular mode */
+    uint32_t direction;                             /*!< channel data transfer direction */
+    uint32_t number;                                /*!< channel transfer number */
+    uint32_t priority;                              /*!< channel priority level */
+} dma_single_data_parameter_struct;
+
+#define DMA_FLAG_ADD(flag,channel)        ((uint32_t)((flag)<<((((uint32_t)(channel)*6U))+((uint32_t)(((uint32_t)(channel)) >> 1U)&0x01U)*4U)))   /*!< DMA channel flag shift */
+
+/* DMA_register address */
+#define DMA_CHCTL(dma,channel)            REG32(((dma) + 0x10U) + 0x18U*(channel))  /*!< the address of DMA channel CHXCTL register  */
+#define DMA_CHCNT(dma,channel)            REG32(((dma) + 0x14U) + 0x18U*(channel))  /*!< the address of DMA channel CHXCNT register */
+#define DMA_CHPADDR(dma,channel)          REG32(((dma) + 0x18U) + 0x18U*(channel))  /*!< the address of DMA channel CHXPADDR register */
+#define DMA_CHM0ADDR(dma,channel)         REG32(((dma) + 0x1CU) + 0x18U*(channel))  /*!< the address of DMA channel CHXM0ADDR register */
+#define DMA_CHM1ADDR(dma,channel)         REG32(((dma) + 0x20U) + 0x18U*(channel))  /*!< the address of DMA channel CHXM1ADDR register */
+#define DMA_CHFCTL(dma,channel)           REG32(((dma) + 0x24U) + 0x18U*(channel))  /*!< the address of DMA channel CHXMADDR register */
+
+/* peripheral select */
+#define CHCTL_PERIEN(regval)              (BITS(25,27) & ((uint32_t)(regval) << 25))
+#define DMA_PERIPH_0_SELECT               CHCTL_PERIEN(0)                           /*!< peripheral 0 select */
+#define DMA_PERIPH_1_SELECT               CHCTL_PERIEN(1)                           /*!< peripheral 1 select */
+#define DMA_PERIPH_2_SELECT               CHCTL_PERIEN(2)                           /*!< peripheral 2 select */
+#define DMA_PERIPH_3_SELECT               CHCTL_PERIEN(3)                           /*!< peripheral 3 select */
+#define DMA_PERIPH_4_SELECT               CHCTL_PERIEN(4)                           /*!< peripheral 4 select */
+#define DMA_PERIPH_5_SELECT               CHCTL_PERIEN(5)                           /*!< peripheral 5 select */
+#define DMA_PERIPH_6_SELECT               CHCTL_PERIEN(6)                           /*!< peripheral 6 select */
+#define DMA_PERIPH_7_SELECT               CHCTL_PERIEN(7)                           /*!< peripheral 7 select */
+
+/* burst type of memory */
+#define CHCTL_MBURST(regval)              (BITS(23,24) & ((uint32_t)(regval) << 23))
+#define DMA_MEMORY_BURST_SINGLE           CHCTL_MBURST(0)                           /*!< single burst */
+#define DMA_MEMORY_BURST_4_BEAT           CHCTL_MBURST(1)                           /*!< 4-beat burst */
+#define DMA_MEMORY_BURST_8_BEAT           CHCTL_MBURST(2)                           /*!< 8-beat burst */
+#define DMA_MEMORY_BURST_16_BEAT          CHCTL_MBURST(3)                           /*!< 16-beat burst */
+
+/* burst type of peripheral */
+#define CHCTL_PBURST(regval)              (BITS(21,22) & ((uint32_t)(regval) << 21))
+#define DMA_PERIPH_BURST_SINGLE           CHCTL_PBURST(0)                           /*!< single burst */
+#define DMA_PERIPH_BURST_4_BEAT           CHCTL_PBURST(1)                           /*!< 4-beat burst */
+#define DMA_PERIPH_BURST_8_BEAT           CHCTL_PBURST(2)                           /*!< 8-beat burst */
+#define DMA_PERIPH_BURST_16_BEAT          CHCTL_PBURST(3)                           /*!< 16-beat burst */
+
+/* channel priority level */
+#define CHCTL_PRIO(regval)                (BITS(16,17) & ((uint32_t)(regval) << 16))
+#define DMA_PRIORITY_LOW                  CHCTL_PRIO(0)                             /*!< low priority */
+#define DMA_PRIORITY_MEDIUM               CHCTL_PRIO(1)                             /*!< medium priority */
+#define DMA_PRIORITY_HIGH                 CHCTL_PRIO(2)                             /*!< high priority */
+#define DMA_PRIORITY_ULTRA_HIGH           CHCTL_PRIO(3)                             /*!< ultra high priority */
+
+/* transfer data width of memory */
+#define CHCTL_MWIDTH(regval)              (BITS(13,14) & ((uint32_t)(regval) << 13))
+#define DMA_MEMORY_WIDTH_8BIT             CHCTL_MWIDTH(0)                           /*!< transfer data width of memory is 8-bit */
+#define DMA_MEMORY_WIDTH_16BIT            CHCTL_MWIDTH(1)                           /*!< transfer data width of memory is 16-bit */
+#define DMA_MEMORY_WIDTH_32BIT            CHCTL_MWIDTH(2)                           /*!< transfer data width of memory is 32-bit */
+
+/* transfer data width of peripheral */
+#define CHCTL_PWIDTH(regval)              (BITS(11,12) & ((uint32_t)(regval) << 11))
+#define DMA_PERIPH_WIDTH_8BIT             CHCTL_PWIDTH(0)                           /*!< transfer data width of peripheral is 8-bit */
+#define DMA_PERIPH_WIDTH_16BIT            CHCTL_PWIDTH(1)                           /*!< transfer data width of peripheral is 16-bit */
+#define DMA_PERIPH_WIDTH_32BIT            CHCTL_PWIDTH(2)                           /*!< transfer data width of peripheral is 32-bit */
+
+/* channel transfer mode */
+#define CHCTL_TM(regval)                  (BITS(6,7) & ((uint32_t)(regval) << 6))
+#define DMA_PERIPH_TO_MEMORY              CHCTL_TM(0)                               /*!< read from peripheral and write to memory */
+#define DMA_MEMORY_TO_PERIPH              CHCTL_TM(1)                               /*!< read from memory and write to peripheral */
+#define DMA_MEMORY_TO_MEMORY              CHCTL_TM(2)                               /*!< read from memory and write to memory */
+
+/* FIFO counter critical value */
+#define CHFCTL_FCCV(regval)               (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define DMA_FIFO_1_WORD                   CHFCTL_FCCV(0)                            /*!< critical value 1 word */
+#define DMA_FIFO_2_WORD                   CHFCTL_FCCV(1)                            /*!< critical value 2 word */
+#define DMA_FIFO_3_WORD                   CHFCTL_FCCV(2)                            /*!< critical value 3 word */
+#define DMA_FIFO_4_WORD                   CHFCTL_FCCV(3)                            /*!< critical value 4 word */
+
+/* memory select */
+#define DMA_MEMORY_0                      ((uint32_t)0x00000000U)                   /*!< select memory 0 */
+#define DMA_MEMORY_1                      ((uint32_t)0x00000001U)                   /*!< select memory 1 */
+
+/* DMA circular mode */
+#define DMA_CIRCULAR_MODE_ENABLE          ((uint32_t)0x00000000U)                   /*!< circular mode enable */
+#define DMA_CIRCULAR_MODE_DISABLE         ((uint32_t)0x00000001U)                   /*!< circular mode disable */
+
+/* DMA flow controller select */
+#define DMA_FLOW_CONTROLLER_DMA           ((uint32_t)0x00000000U)                   /*!< DMA is the flow controler */
+#define DMA_FLOW_CONTROLLER_PERI          ((uint32_t)0x00000001U)                   /*!< peripheral is the flow controler */
+
+/* peripheral increasing mode */
+#define DMA_PERIPH_INCREASE_ENABLE        ((uint32_t)0x00000000U)                   /*!< next address of peripheral is increasing address mode */
+#define DMA_PERIPH_INCREASE_DISABLE       ((uint32_t)0x00000001U)                   /*!< next address of peripheral is fixed address mode */
+#define DMA_PERIPH_INCREASE_FIX           ((uint32_t)0x00000002U)                   /*!< next address of peripheral is increasing fixed */
+
+/* memory increasing mode */
+#define DMA_MEMORY_INCREASE_ENABLE        ((uint32_t)0x00000000U)                   /*!< next address of memory is increasing address mode */
+#define DMA_MEMORY_INCREASE_DISABLE       ((uint32_t)0x00000001U)                   /*!< next address of memory is fixed address mode */
+
+/* FIFO status */
+#define DMA_FIFO_STATUS_NODATA            ((uint32_t)0x00000000U)                   /*!< the data in the FIFO less than 1 word */
+#define DMA_FIFO_STATUS_1_WORD            ((uint32_t)0x00000001U)                   /*!< the data in the FIFO more than 1 word, less than 2 words */
+#define DMA_FIFO_STATUS_2_WORD            ((uint32_t)0x00000002U)                   /*!< the data in the FIFO more than 2 word, less than 3 words */
+#define DMA_FIFO_STATUS_3_WORD            ((uint32_t)0x00000003U)                   /*!< the data in the FIFO more than 3 word, less than 4 words */
+#define DMA_FIFO_STATUS_EMPTY             ((uint32_t)0x00000004U)                   /*!< the data in the FIFO is empty */
+#define DMA_FIFO_STATUS_FULL              ((uint32_t)0x00000005U)                   /*!< the data in the FIFO is full */
+
+/* DMA reset value */
+#define DMA_CHCTL_RESET_VALUE             ((uint32_t)0x00000000U)                   /*!< the reset value of DMA channel CHXCTL register  */
+#define DMA_CHCNT_RESET_VALUE             ((uint32_t)0x00000000U)                   /*!< the reset value of DMA channel CHXCNT register  */
+#define DMA_CHPADDR_RESET_VALUE           ((uint32_t)0x00000000U)                   /*!< the reset value of DMA channel CHXPADDR register  */
+#define DMA_CHMADDR_RESET_VALUE           ((uint32_t)0x00000000U)                   /*!< the reset value of DMA channel CHXMADDR register  */
+#define DMA_CHINTF_RESET_VALUE            ((uint32_t)0x0000003DU)                   /*!< clear DMA channel CHXINTFS register  */
+#define DMA_CHFCTL_RESET_VALUE            ((uint32_t)0x00000000U)                   /*!< the reset value of DMA channel CHXFCTL register  */
+
+/* function declarations */
+/* deinitialize DMA a channel registers */
+void dma_deinit(uint32_t dma_periph,dma_channel_enum channelx);
+/* DMA single data mode initialize */
+void dma_single_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_single_data_parameter_struct init_struct);
+/* DMA multi data mode initialize */
+void dma_multi_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_multi_data_parameter_struct init_struct);
+
+/* set DMA peripheral base address */
+void dma_periph_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t address);
+/* set DMA Memory base address */
+void dma_memory_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t memory_flag,uint32_t address);
+
+/* set the number of remaining data to be transferred by the DMA */
+void dma_transfer_number_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t number);
+/* get the number of remaining data to be transferred by the DMA */
+uint32_t dma_transfer_number_get(uint32_t dma_periph,dma_channel_enum channelx);
+
+/* configure priority level of DMA channel */
+void dma_priority_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t priority);
+
+/* configure transfer burst beats of memory */
+void dma_memory_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t mbeat);
+/* configure transfer burst beats of peripheral */
+void dma_periph_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t pbeat);
+/* configure transfer data size of memory */
+void dma_memory_width_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t msize);
+/* configure transfer data size of peripheral */
+void dma_periph_width_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t psize);
+
+/* configure next address increasement algorithm of memory */
+void dma_memory_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm);
+/* configure next address increasement algorithm of peripheral */
+void dma_peripheral_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm);
+
+/* enable DMA circulation mode */
+void dma_circulation_enable(uint32_t dma_periph,dma_channel_enum channelx);
+/* disable DMA circulation mode */
+void dma_circulation_disable(uint32_t dma_periph,dma_channel_enum channelx);
+/* enable DMA channel */
+void dma_channel_enable(uint32_t dma_periph,dma_channel_enum channelx);
+/* disable DMA channel */
+void dma_channel_disable(uint32_t dma_periph,dma_channel_enum channelx);
+
+/* configure the direction of data transfer on the channel */
+void dma_transfer_direction_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t direction);
+
+/* DMA switch buffer mode config */
+void dma_switch_buffer_mode_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t memory1_addr,uint32_t memory_select);
+/* DMA using memory get */
+uint32_t dma_using_memory_get(uint32_t dma_periph,dma_channel_enum channelx);
+
+/* DMA channel peripheral select */
+void dma_channel_subperipheral_select(uint32_t dma_periph,dma_channel_enum channelx,dma_subperipheral_enum sub_periph);
+/* DMA flow controller configure */
+void dma_flow_controller_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t controller);
+/* DMA flow controller enable */
+void dma_switch_buffer_mode_enable(uint32_t dma_periph,dma_channel_enum channelx,ControlStatus newvalue);
+/* DMA FIFO status get */
+uint32_t dma_fifo_status_get(uint32_t dma_periph,dma_channel_enum channelx);
+
+/* check DMA flag is set or not */
+FlagStatus dma_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag);
+/* clear DMA a channel flag */
+void dma_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag);
+/* check DMA flag is set or not */
+FlagStatus dma_interrupt_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt);
+/* clear DMA a channel flag */
+void dma_interrupt_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt);
+/* enable DMA interrupt */
+void dma_interrupt_enable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source);
+/* disable DMA interrupt */
+void dma_interrupt_disable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source);
+
+#endif /* GD32F4XX_DMA_H */

+ 1664 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h

@@ -0,0 +1,1664 @@
+/*!
+    \file  gd32f4xx_enet.h
+    \brief definitions for the ENET
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_ENET_H
+#define GD32F4XX_ENET_H
+
+#include "gd32f4xx.h"
+#include <stdlib.h>
+
+#define IF_USE_EXTERNPHY_LIB             0
+#if (1 == IF_USE_EXTERNPHY_LIB)
+#include "phy.h"
+#endif
+
+#ifndef ENET_RXBUF_NUM
+#define ENET_RXBUF_NUM                   5U                                     /*!< ethernet Rx DMA descriptor number */
+#endif
+
+#ifndef ENET_TXBUF_NUM
+#define ENET_TXBUF_NUM                   5U                                     /*!< ethernet Tx DMA descriptor number */
+#endif
+
+#ifndef ENET_RXBUF_SIZE
+#define ENET_RXBUF_SIZE                  ENET_MAX_FRAME_SIZE                    /*!< ethernet receive buffer size */
+#endif
+
+#ifndef ENET_TXBUF_SIZE
+#define ENET_TXBUF_SIZE                  ENET_MAX_FRAME_SIZE                    /*!< ethernet transmit buffer size */
+#endif
+
+//#define SELECT_DESCRIPTORS_ENHANCED_MODE 
+
+//#define USE_DELAY
+
+#ifndef _PHY_H_
+#define DP83848                          0
+#define LAN8700                          1
+#define PHY_TYPE                         DP83848
+
+#define PHY_ADDRESS                      ((uint16_t)1U)                         /*!< phy address determined by the hardware */
+
+/* PHY read write timeouts */ 
+#define PHY_READ_TO                      ((uint32_t)0x0004FFFFU)                /*!< PHY read timeout */
+#define PHY_WRITE_TO                     ((uint32_t)0x0004FFFFU)                /*!< PHY write timeout */
+
+/* PHY delay */
+#define PHY_RESETDELAY                   ((uint32_t)0x008FFFFFU)                /*!< PHY reset delay */
+#define PHY_CONFIGDELAY                  ((uint32_t)0x00FFFFFFU)                /*!< PHY configure delay */
+
+/* PHY register address */ 
+#define PHY_REG_BCR                      0U                                     /*!< tranceiver basic control register */
+#define PHY_REG_BSR                      1U                                     /*!< tranceiver basic status register */
+
+/* PHY basic control register */
+#define PHY_RESET                        ((uint16_t)0x8000)                     /*!< PHY reset */
+#define PHY_LOOPBACK                     ((uint16_t)0x4000)                     /*!< enable phy loop-back mode */
+#define PHY_FULLDUPLEX_100M              ((uint16_t)0x2100)                     /*!< configure speed to 100 Mbit/s and the full-duplex mode */
+#define PHY_HALFDUPLEX_100M              ((uint16_t)0x2000)                     /*!< configure speed to 100 Mbit/s and the half-duplex mode */
+#define PHY_FULLDUPLEX_10M               ((uint16_t)0x0100)                     /*!< configure speed to 10 Mbit/s and the full-duplex mode */
+#define PHY_HALFDUPLEX_10M               ((uint16_t)0x0000)                     /*!< configure speed to 10 Mbit/s and the half-duplex mode */
+#define PHY_AUTONEGOTIATION              ((uint16_t)0x1000)                     /*!< enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION      ((uint16_t)0x0200)                     /*!< restart auto-negotiation function */
+#define PHY_POWERDOWN                    ((uint16_t)0x0800)                     /*!< enable the power down mode */
+#define PHY_ISOLATE                      ((uint16_t)0x0400)                     /*!< isolate PHY from MII */
+
+/* PHY basic status register */
+#define PHY_AUTONEGO_COMPLETE            ((uint16_t)0x0020)                     /*!< auto-negotioation process completed */
+#define PHY_LINKED_STATUS                ((uint16_t)0x0004)                     /*!< valid link established */
+#define PHY_JABBER_DETECTION             ((uint16_t)0x0002)                     /*!< jabber condition detected */
+
+#if(PHY_TYPE == LAN8700) 
+#define PHY_SR                           31U                                    /*!< tranceiver status register */
+#define PHY_SPEED_STATUS                 ((uint16_t)0x0004)                     /*!< configured information of speed: 10Mbit/s */
+#define PHY_DUPLEX_STATUS                ((uint16_t)0x0010)                     /*!< configured information of duplex: full-duplex */
+#elif(PHY_TYPE == DP83848)
+#define PHY_SR                           16U                                    /*!< tranceiver status register */
+#define PHY_SPEED_STATUS                 ((uint16_t)0x0002)                     /*!< configured information of speed: 10Mbit/s */
+#define PHY_DUPLEX_STATUS                ((uint16_t)0x0004)                     /*!< configured information of duplex: full-duplex */
+#endif /* PHY_TYPE */
+
+#endif /* _PHY_H_ */
+
+
+/* ENET definitions */
+#define ENET                             ENET_BASE
+
+/* registers definitions */
+#define ENET_MAC_CFG                     REG32((ENET) + 0x00U)                  /*!< ethernet MAC configuration register */
+#define ENET_MAC_FRMF                    REG32((ENET) + 0x04U)                  /*!< ethernet MAC frame filter register */
+#define ENET_MAC_HLH                     REG32((ENET) + 0x08U)                  /*!< ethernet MAC hash list high register */
+#define ENET_MAC_HLL                     REG32((ENET) + 0x0CU)                  /*!< ethernet MAC hash list low register */
+#define ENET_MAC_PHY_CTL                 REG32((ENET) + 0x10U)                  /*!< ethernet MAC PHY control register */
+#define ENET_MAC_PHY_DATA                REG32((ENET) + 0x14U)                  /*!< ethernet MAC MII data register */
+#define ENET_MAC_FCTL                    REG32((ENET) + 0x18U)                  /*!< ethernet MAC flow control register */
+#define ENET_MAC_VLT                     REG32((ENET) + 0x1CU)                  /*!< ethernet MAC VLAN tag register */
+#define ENET_MAC_RWFF                    REG32((ENET) + 0x28U)                  /*!< ethernet MAC remote wakeup frame filter register */
+#define ENET_MAC_WUM                     REG32((ENET) + 0x2CU)                  /*!< ethernet MAC wakeup management register */
+#define ENET_MAC_DBG                     REG32((ENET) + 0x34U)                  /*!< ethernet MAC debug register */
+#define ENET_MAC_INTF                    REG32((ENET) + 0x38U)                  /*!< ethernet MAC interrupt flag register */
+#define ENET_MAC_INTMSK                  REG32((ENET) + 0x3CU)                  /*!< ethernet MAC interrupt mask register */
+#define ENET_MAC_ADDR0H                  REG32((ENET) + 0x40U)                  /*!< ethernet MAC address 0 high register */
+#define ENET_MAC_ADDR0L                  REG32((ENET) + 0x44U)                  /*!< ethernet MAC address 0 low register */
+#define ENET_MAC_ADDR1H                  REG32((ENET) + 0x48U)                  /*!< ethernet MAC address 1 high register */
+#define ENET_MAC_ADDR1L                  REG32((ENET) + 0x4CU)                  /*!< ethernet MAC address 1 low register */
+#define ENET_MAC_ADDT2H                  REG32((ENET) + 0x50U)                  /*!< ethernet MAC address 2 high register */
+#define ENET_MAC_ADDR2L                  REG32((ENET) + 0x54U)                  /*!< ethernet MAC address 2 low register */
+#define ENET_MAC_ADDR3H                  REG32((ENET) + 0x58U)                  /*!< ethernet MAC address 3 high register */
+#define ENET_MAC_ADDR3L                  REG32((ENET) + 0x5CU)                  /*!< ethernet MAC address 3 low register */
+#define ENET_MAC_FCTH                    REG32((ENET) + 0x1080U)                /*!< ethernet MAC flow control threshold register */
+
+#define ENET_MSC_CTL                     REG32((ENET) + 0x100U)                 /*!< ethernet MSC control register */
+#define ENET_MSC_RINTF                   REG32((ENET) + 0x104U)                 /*!< ethernet MSC receive interrupt flag register */
+#define ENET_MSC_TINTF                   REG32((ENET) + 0x108U)                 /*!< ethernet MSC transmit interrupt flag register */
+#define ENET_MSC_RINTMSK                 REG32((ENET) + 0x10CU)                 /*!< ethernet MSC receive interrupt mask register */
+#define ENET_MSC_TINTMSK                 REG32((ENET) + 0x110U)                 /*!< ethernet MSC transmit interrupt mask register */
+#define ENET_MSC_SCCNT                   REG32((ENET) + 0x14CU)                 /*!< ethernet MSC transmitted good frames after a single collision counter register */
+#define ENET_MSC_MSCCNT                  REG32((ENET) + 0x150U)                 /*!< ethernet MSC transmitted good frames after more than a single collision counter register */
+#define ENET_MSC_TGFCNT                  REG32((ENET) + 0x168U)                 /*!< ethernet MSC transmitted good frames counter register */
+#define ENET_MSC_RFCECNT                 REG32((ENET) + 0x194U)                 /*!< ethernet MSC received frames with CRC error counter register */
+#define ENET_MSC_RFAECNT                 REG32((ENET) + 0x198U)                 /*!< ethernet MSC received frames with alignment error counter register */
+#define ENET_MSC_RGUFCNT                 REG32((ENET) + 0x1C4U)                 /*!< ethernet MSC received good unicast frames counter register */
+
+#define ENET_PTP_TSCTL                   REG32((ENET) + 0x700U)                 /*!< ethernet PTP time stamp control register */
+#define ENET_PTP_SSINC                   REG32((ENET) + 0x704U)                 /*!< ethernet PTP subsecond increment register */ 
+#define ENET_PTP_TSH                     REG32((ENET) + 0x708U)                 /*!< ethernet PTP time stamp high register */
+#define ENET_PTP_TSL                     REG32((ENET) + 0x70CU)                 /*!< ethernet PTP time stamp low register */
+#define ENET_PTP_TSUH                    REG32((ENET) + 0x710U)                 /*!< ethernet PTP time stamp update high register */
+#define ENET_PTP_TSUL                    REG32((ENET) + 0x714U)                 /*!< ethernet PTP time stamp update low register */
+#define ENET_PTP_TSADDEND                REG32((ENET) + 0x718U)                 /*!< ethernet PTP time stamp addend register */
+#define ENET_PTP_ETH                     REG32((ENET) + 0x71CU)                 /*!< ethernet PTP expected time high register */
+#define ENET_PTP_ETL                     REG32((ENET) + 0x720U)                 /*!< ethernet PTP expected time low register */
+#define ENET_PTP_TSF                     REG32((ENET) + 0x728U)                 /*!< ethernet PTP time stamp flag register */
+#define ENET_PTP_PPSCTL                  REG32((ENET) + 0x72CU)                 /*!< ethernet PTP PPS control register */
+
+#define ENET_DMA_BCTL                    REG32((ENET) + 0x1000U)                /*!< ethernet DMA bus control register */
+#define ENET_DMA_TPEN                    REG32((ENET) + 0x1004U)                /*!< ethernet DMA transmit poll enable register */ 
+#define ENET_DMA_RPEN                    REG32((ENET) + 0x1008U)                /*!< ethernet DMA receive poll enable register */
+#define ENET_DMA_RDTADDR                 REG32((ENET) + 0x100CU)                /*!< ethernet DMA receive descriptor table address register */
+#define ENET_DMA_TDTADDR                 REG32((ENET) + 0x1010U)                /*!< ethernet DMA transmit descriptor table address register */
+#define ENET_DMA_STAT                    REG32((ENET) + 0x1014U)                /*!< ethernet DMA status register */
+#define ENET_DMA_CTL                     REG32((ENET) + 0x1018U)                /*!< ethernet DMA control register */
+#define ENET_DMA_INTEN                   REG32((ENET) + 0x101CU)                /*!< ethernet DMA interrupt enable register */
+#define ENET_DMA_MFBOCNT                 REG32((ENET) + 0x1020U)                /*!< ethernet DMA missed frame and buffer overflow counter register */
+#define ENET_DMA_RSWDC                   REG32((ENET) + 0x1024U)                /*!< ethernet DMA receive state watchdog counter register */
+#define ENET_DMA_CTDADDR                 REG32((ENET) + 0x1048U)                /*!< ethernet DMA current transmit descriptor address register */ 
+#define ENET_DMA_CRDADDR                 REG32((ENET) + 0x104CU)                /*!< ethernet DMA current receive descriptor address register */
+#define ENET_DMA_CTBADDR                 REG32((ENET) + 0x1050U)                /*!< ethernet DMA current transmit buffer address register */
+#define ENET_DMA_CRBADDR                 REG32((ENET) + 0x1054U)                /*!< ethernet DMA current receive buffer address register */
+
+/* bits definitions */
+/* ENET_MAC_CFG */
+#define ENET_MAC_CFG_REN                 BIT(2)                                 /*!< receiver enable */
+#define ENET_MAC_CFG_TEN                 BIT(3)                                 /*!< transmitter enable */
+#define ENET_MAC_CFG_DFC                 BIT(4)                                 /*!< defferal check */
+#define ENET_MAC_CFG_BOL                 BITS(5,6)                              /*!< back-off limit */
+#define ENET_MAC_CFG_APCD                BIT(7)                                 /*!< automatic pad/CRC drop */
+#define ENET_MAC_CFG_RTD                 BIT(9)                                 /*!< retry disable */
+#define ENET_MAC_CFG_IPFCO               BIT(10)                                /*!< IP frame checksum offload */
+#define ENET_MAC_CFG_DPM                 BIT(11)                                /*!< duplex mode */
+#define ENET_MAC_CFG_LBM                 BIT(12)                                /*!< loopback mode */
+#define ENET_MAC_CFG_ROD                 BIT(13)                                /*!< receive own disable */
+#define ENET_MAC_CFG_SPD                 BIT(14)                                /*!< fast eneternet speed */
+#define ENET_MAC_CFG_CSD                 BIT(16)                                /*!< carrier sense disable */
+#define ENET_MAC_CFG_IGBS                BITS(17,19)                            /*!< inter-frame gap bit selection */            
+#define ENET_MAC_CFG_JBD                 BIT(22)                                /*!< jabber disable */
+#define ENET_MAC_CFG_WDD                 BIT(23)                                /*!< watchdog disable */
+#define ENET_MAC_CFG_TFCD                BIT(25)                                /*!< type frame CRC dropping */
+
+/* ENET_MAC_FRMF */
+#define ENET_MAC_FRMF_PM                 BIT(0)                                 /*!< promiscuous mode */
+#define ENET_MAC_FRMF_HUF                BIT(1)                                 /*!< hash unicast filter */
+#define ENET_MAC_FRMF_HMF                BIT(2)                                 /*!< hash multicast filter */ 
+#define ENET_MAC_FRMF_DAIFLT             BIT(3)                                 /*!< destination address inverse filtering enable */ 
+#define ENET_MAC_FRMF_MFD                BIT(4)                                 /*!< multicast filter disable */ 
+#define ENET_MAC_FRMF_BFRMD              BIT(5)                                 /*!< broadcast frame disable */ 
+#define ENET_MAC_FRMF_PCFRM              BITS(6,7)                              /*!< pass control frames */ 
+#define ENET_MAC_FRMF_SAIFLT             BIT(8)                                 /*!< source address inverse filtering */ 
+#define ENET_MAC_FRMF_SAFLT              BIT(9)                                 /*!< source address filter */ 
+#define ENET_MAC_FRMF_HPFLT              BIT(10)                                /*!< hash or perfect filter */ 
+#define ENET_MAC_FRMF_FAR                BIT(31)                                /*!< frames all receive */ 
+  
+/* ENET_MAC_HLH */
+#define ENET_MAC_HLH_HLH                 BITS(0,31)                             /*!< hash list high */
+  
+/* ENET_MAC_HLL */
+#define ENET_MAC_HLL_HLL                 BITS(0,31)                             /*!< hash list low */
+  
+/* ENET_MAC_PHY_CTL */
+#define ENET_MAC_PHY_CTL_PB              BIT(0)                                 /*!< PHY busy */ 
+#define ENET_MAC_PHY_CTL_PW              BIT(1)                                 /*!< PHY write */ 
+#define ENET_MAC_PHY_CTL_CLR             BITS(2,4)                              /*!< clock range */ 
+#define ENET_MAC_PHY_CTL_PR              BITS(6,10)                             /*!< PHY register */ 
+#define ENET_MAC_PHY_CTL_PA              BITS(11,15)                            /*!< PHY address */ 
+    
+/* ENET_MAC_PHY_DATA */
+#define ENET_MAC_PHY_DATA_PD             BITS(0,15)                             /*!< PHY data */
+  
+/* ENET_MAC_FCTL */
+#define ENET_MAC_FCTL_FLCBBKPA           BIT(0)                                 /*!< flow control busy(in full duplex mode)/backpressure activate(in half duplex mode) */
+#define ENET_MAC_FCTL_TFCEN              BIT(1)                                 /*!< transmit flow control enable */
+#define ENET_MAC_FCTL_RFCEN              BIT(2)                                 /*!< receive flow control enable */
+#define ENET_MAC_FCTL_UPFDT              BIT(3)                                 /*!< unicast pause frame detect */
+#define ENET_MAC_FCTL_PLTS               BITS(4,5)                              /*!< pause low threshold */     
+#define ENET_MAC_FCTL_DZQP               BIT(7)                                 /*!< disable zero-quanta pause */
+#define ENET_MAC_FCTL_PTM                BITS(16,31)                            /*!< pause time */
+  
+/* ENET_MAC_VLT */
+#define ENET_MAC_VLT_VLTI                BITS(0,15)                             /*!< VLAN tag identifier(for receive frames) */
+#define ENET_MAC_VLT_VLTC                BIT(16)                                /*!< 12-bit VLAN tag comparison */
+  
+/* ENET_MAC_RWFF */
+#define ENET_MAC_RWFF_DATA               BITS(0,31)                             /*!< wakeup frame filter register data */
+  
+/* ENET_MAC_WUM */ 
+#define ENET_MAC_WUM_PWD                 BIT(0)                                 /*!< power down */
+#define ENET_MAC_WUM_MPEN                BIT(1)                                 /*!< magic packet enable */
+#define ENET_MAC_WUM_WFEN                BIT(2)                                 /*!< wakeup frame enable */
+#define ENET_MAC_WUM_MPKR                BIT(5)                                 /*!< magic packet received */
+#define ENET_MAC_WUM_WUFR                BIT(6)                                 /*!< wakeup frame received */
+#define ENET_MAC_WUM_GU                  BIT(9)                                 /*!< global unicast */
+#define ENET_MAC_WUM_WUFFRPR             BIT(31)                                /*!< wakeup frame filter register pointer reset */
+
+/* ENET_MAC_DBG */ 
+#define ENET_MAC_DBG_MRNI                BIT(0)                                 /*!< MAC receive state not idle */
+#define ENET_MAC_DBG_RXAFS               BITS(1,2)                              /*!< Rx asynchronous FIFO status */
+#define ENET_MAC_DBG_RXFW                BIT(4)                                 /*!< RxFIFO is writing */
+#define ENET_MAC_DBG_RXFRS               BITS(5,6)                              /*!< RxFIFO read operation status */
+#define ENET_MAC_DBG_RXFS                BITS(8,9)                              /*!< RxFIFO state */
+#define ENET_MAC_DBG_MTNI                BIT(16)                                /*!< MAC transmit state not idle */
+#define ENET_MAC_DBG_SOMT                BITS(17,18)                            /*!< status of mac transmitter */
+#define ENET_MAC_DBG_PCS                 BIT(19)                                /*!< pause condition status */
+#define ENET_MAC_DBG_TXFRS               BITS(20,21)                            /*!< TxFIFO read operation status */
+#define ENET_MAC_DBG_TXFW                BIT(22)                                /*!< TxFIFO is writing */
+#define ENET_MAC_DBG_TXFNE               BIT(24)                                /*!< TxFIFO not empty flag */
+#define ENET_MAC_DBG_TXFF                BIT(25)                                /*!< TxFIFO full flag */
+
+/* ENET_MAC_INTF */ 
+#define ENET_MAC_INTF_WUM                BIT(3)                                 /*!< WUM status */
+#define ENET_MAC_INTF_MSC                BIT(4)                                 /*!< MSC status */
+#define ENET_MAC_INTF_MSCR               BIT(5)                                 /*!< MSC receive status */
+#define ENET_MAC_INTF_MSCT               BIT(6)                                 /*!< MSC transmit status */
+#define ENET_MAC_INTF_TMST               BIT(9)                                 /*!< timestamp trigger status */
+
+/* ENET_MAC_INTMSK */
+#define ENET_MAC_INTMSK_WUMIM            BIT(3)                                 /*!< WUM interrupt mask */
+#define ENET_MAC_INTMSK_TMSTIM           BIT(9)                                 /*!< timestamp trigger interrupt mask */
+
+/* ENET_MAC_ADDR0H */
+#define ENET_MAC_ADDR0H_ADDR0H           BITS(0,15)                             /*!< MAC address0 high */
+#define ENET_MAC_ADDR0H_MO               BIT(31)                                /*!< always read 1 and must be kept */
+  
+/* ENET_MAC_ADDR0L */
+#define ENET_MAC_ADDR0L_ADDR0L           BITS(0,31)                             /*!< MAC address0 low */
+  
+/* ENET_MAC_ADDR1H */
+#define ENET_MAC_ADDR1H_ADDR1H           BITS(0,15)                             /*!< MAC address1 high */
+#define ENET_MAC_ADDR1H_MB               BITS(24,29)                            /*!< mask byte */ 
+#define ENET_MAC_ADDR1H_SAF              BIT(30)                                /*!< source address filter */
+#define ENET_MAC_ADDR1H_AFE              BIT(31)                                /*!< address filter enable */
+  
+/* ENET_MAC_ADDR1L */
+#define ENET_MAC_ADDR1L_ADDR1L           BITS(0,31)                             /*!< MAC address1 low */
+  
+/* ENET_MAC_ADDR2H */
+#define ENET_MAC_ADDR2H_ADDR2H           BITS(0,15)                             /*!< MAC address2 high */
+#define ENET_MAC_ADDR2H_MB               BITS(24,29)                            /*!< mask byte */
+#define ENET_MAC_ADDR2H_SAF              BIT(30)                                /*!< source address filter */
+#define ENET_MAC_ADDR2H_AFE              BIT(31)                                /*!< address filter enable */
+  
+/* ENET_MAC_ADDR2L */
+#define ENET_MAC_ADDR2L_ADDR2L           BITS(0,31)                             /*!< MAC address2 low */
+  
+/* ENET_MAC_ADDR3H */
+#define ENET_MAC_ADDR3H_ADDR3H           BITS(0,15)                             /*!< MAC address3 high */
+#define ENET_MAC_ADDR3H_MB               BITS(24,29)                            /*!< mask byte */
+#define ENET_MAC_ADDR3H_SAF              BIT(30)                                /*!< source address filter */
+#define ENET_MAC_ADDR3H_AFE              BIT(31)                                /*!< address filter enable */
+
+/* ENET_MAC_ADDR3L */
+#define ENET_MAC_ADDR3L_ADDR3L           BITS(0,31)                             /*!< MAC address3 low */
+  
+/* ENET_MAC_FCTH */
+#define ENET_MAC_FCTH_RFA                BITS(0,2)                              /*!< threshold of active flow control */
+#define ENET_MAC_FCTH_RFD                BITS(4,6)                              /*!< threshold of deactive flow control */
+ 
+/* ENET_MSC_CTL */
+#define ENET_MSC_CTL_CTR                 BIT(0)                                 /*!< counter reset */
+#define ENET_MSC_CTL_CTSR                BIT(1)                                 /*!< counter stop rollover */
+#define ENET_MSC_CTL_RTOR                BIT(2)                                 /*!< reset on read */
+#define ENET_MSC_CTL_MCFZ                BIT(3)                                 /*!< MSC counter freeze */
+#define ENET_MSC_CTL_PMC                 BIT(4)                                 /*!< preset MSC counter */
+#define ENET_MSC_CTL_AFHPM               BIT(5)                                 /*!< almost full or half preset mode */
+
+/* ENET_MSC_RINTF */
+#define ENET_MSC_RINTF_RFCE              BIT(5)                                 /*!< received frames CRC error */
+#define ENET_MSC_RINTF_RFAE              BIT(6)                                 /*!< received frames alignment error */
+#define ENET_MSC_RINTF_RGUF              BIT(17)                                /*!< receive good unicast frames */
+  
+/* ENET_MSC_TINTF */
+#define ENET_MSC_TINTF_TGFSC             BIT(14)                                /*!< transmitted good frames single collision */
+#define ENET_MSC_TINTF_TGFMSC            BIT(15)                                /*!< transmitted good frames more single collision */
+#define ENET_MSC_TINTF_TGF               BIT(21)                                /*!< transmitted good frames */
+
+/* ENET_MSC_RINTMSK */
+#define ENET_MSC_RINTMSK_RFCEIM          BIT(5)                                 /*!< received frame CRC error interrupt mask */
+#define ENET_MSC_RINTMSK_RFAEIM          BIT(6)                                 /*!< received frames alignment error interrupt mask */
+#define ENET_MSC_RINTMSK_RGUFIM          BIT(17)                                /*!< received good unicast frames interrupt mask */
+  
+/* ENET_MSC_TINTMSK */
+#define ENET_MSC_TINTMSK_TGFSCIM         BIT(14)                                /*!< transmitted good frames single collision interrupt mask */
+#define ENET_MSC_TINTMSK_TGFMSCIM        BIT(15)                                /*!< transmitted good frames more single collision interrupt mask */
+#define ENET_MSC_TINTMSK_TGFIM           BIT(21)                                /*!< transmitted good frames interrupt mask */
+  
+/* ENET_MSC_SCCNT */
+#define ENET_MSC_SCCNT_SCC               BITS(0,31)                             /*!< transmitted good frames single collision counter */
+  
+/* ENET_MSC_MSCCNT */
+#define ENET_MSC_MSCCNT_MSCC             BITS(0,31)                             /*!< transmitted good frames more one single collision counter */
+  
+/* ENET_MSC_TGFCNT */
+#define ENET_MSC_TGFCNT_TGF              BITS(0,31)                             /*!< transmitted good frames counter */
+  
+/* ENET_MSC_RFCECNT */
+#define ENET_MSC_RFCECNT_RFCER           BITS(0,31)                             /*!< received frames with CRC error counter */
+  
+/* ENET_MSC_RFAECNT */
+#define ENET_MSC_RFAECNT_RFAER           BITS(0,31)                             /*!< received frames alignment error counter */
+  
+/* ENET_MSC_RGUFCNT */
+#define ENET_MSC_RGUFCNT_RGUF            BITS(0,31)                             /*!< received good unicast frames counter */
+   
+/* ENET_PTP_TSCTL */
+#define PTP_TSCTL_CKNT(regval)           (BITS(16,17) & ((uint32_t)(regval) << 16))    /*!< write value to ENET_PTP_TSCTL_CKNT bit field */
+
+#define ENET_PTP_TSCTL_TMSEN             BIT(0)                                 /*!< timestamp enable */
+#define ENET_PTP_TSCTL_TMSFCU            BIT(1)                                 /*!< timestamp fine or coarse update */
+#define ENET_PTP_TSCTL_TMSSTI            BIT(2)                                 /*!< timestamp system time initialize */
+#define ENET_PTP_TSCTL_TMSSTU            BIT(3)                                 /*!< timestamp system time update */
+#define ENET_PTP_TSCTL_TMSITEN           BIT(4)                                 /*!< timestamp interrupt trigger enable */
+#define ENET_PTP_TSCTL_TMSARU            BIT(5)                                 /*!< timestamp addend register update */
+#define ENET_PTP_TSCTL_ARFSEN            BIT(8)                                 /*!< all received frames snapshot enable */
+#define ENET_PTP_TSCTL_SCROM             BIT(9)                                 /*!< subsecond counter rollover mode */
+#define ENET_PTP_TSCTL_PFSV              BIT(10)                                /*!< PTP frame snooping version */
+#define ENET_PTP_TSCTL_ESEN              BIT(11)                                /*!< received Ethernet snapshot enable */
+#define ENET_PTP_TSCTL_IP6SEN            BIT(12)                                /*!< received IPv6 snapshot enable */
+#define ENET_PTP_TSCTL_IP4SEN            BIT(13)                                /*!< received IPv4 snapshot enable */
+#define ENET_PTP_TSCTL_ETMSEN            BIT(14)                                /*!< received event type message snapshot enable */
+#define ENET_PTP_TSCTL_MNMSEN            BIT(15)                                /*!< received master node message snapshot enable */
+#define ENET_PTP_TSCTL_CKNT              BITS(16,17)                            /*!< clock node type for time stamp */
+#define ENET_PTP_TSCTL_MAFEN             BIT(18)                                /*!< MAC address filter enable for PTP frame */
+  
+/* ENET_PTP_SSINC */
+#define ENET_PTP_SSINC_STMSSI            BITS(0,7)                              /*!< system time subsecond increment */
+  
+/* ENET_PTP_TSH */
+#define ENET_PTP_TSH_STMS                BITS(0,31)                             /*!< system time second */
+  
+/* ENET_PTP_TSL */
+#define ENET_PTP_TSL_STMSS               BITS(0,30)                             /*!< system time subseconds */
+#define ENET_PTP_TSL_STS                 BIT(31)                                /*!< system time sign */
+  
+/* ENET_PTP_TSUH */
+#define ENET_PTP_TSUH_TMSUS              BITS(0,31)                             /*!< timestamp update seconds */
+  
+/* ENET_PTP_TSUL */
+#define ENET_PTP_TSUL_TMSUSS             BITS(0,30)                             /*!< timestamp update subseconds */
+#define ENET_PTP_TSUL_TMSUPNS            BIT(31)                                /*!< timestamp update positive or negative sign */
+
+/* ENET_PTP_TSADDAND */
+#define ENET_PTP_TSADDAND_TMSA           BITS(0,31)                             /*!< timestamp addend */
+  
+/* ENET_PTP_ETH */
+#define ENET_PTP_ETH_ETSH                BITS(0,31)                             /*!< expected time high */
+  
+/* ENET_PTP_ETL */
+#define ENET_PTP_ETL_ETSL                BITS(0,31)                             /*!< expected time low */
+  
+/* ENET_PTP_TSF */
+#define ENET_PTP_TSF_TSSCO               BIT(0)                                 /*!< timestamp second counter overflow */
+#define ENET_PTP_TSF_TTM                 BIT(1)                                 /*!< target time match */
+  
+/* ENET_PTP_PPSCTL */
+#define ENET_PTP_PPSCTL_PPSOFC           BITS(0,3)                              /*!< PPS output frequency configure */
+
+/* ENET_DMA_BCTL */
+#define ENET_DMA_BCTL_SWR                BIT(0)                                 /*!< software reset */
+#define ENET_DMA_BCTL_DAB                BIT(1)                                 /*!< DMA arbitration */
+#define ENET_DMA_BCTL_DPSL               BITS(2,6)                              /*!< descriptor skip length */
+#define ENET_DMA_BCTL_DFM                BIT(7)                                 /*!< descriptor format mode */
+#define ENET_DMA_BCTL_PGBL               BITS(8,13)                             /*!< programmable burst length */
+#define ENET_DMA_BCTL_RTPR               BITS(14,15)                            /*!< RxDMA and TxDMA transfer priority ratio */
+#define ENET_DMA_BCTL_FB                 BIT(16)                                /*!< fixed Burst */
+#define ENET_DMA_BCTL_RXDP               BITS(17,22)                            /*!< RxDMA PGBL */
+#define ENET_DMA_BCTL_UIP                BIT(23)                                /*!< use independent PGBL */
+#define ENET_DMA_BCTL_FPBL               BIT(24)                                /*!< four times PGBL mode */
+#define ENET_DMA_BCTL_AA                 BIT(25)                                /*!< address-aligned */
+#define ENET_DMA_BCTL_MB                 BIT(26)                                /*!< mixed burst */
+  
+/* ENET_DMA_TPEN */
+#define ENET_DMA_TPEN_TPE                BITS(0,31)                             /*!< transmit poll enable */
+  
+/* ENET_DMA_RPEN */
+#define ENET_DMA_RPEN_RPE                BITS(0,31)                             /*!< receive poll enable  */
+
+/* ENET_DMA_RDTADDR */
+#define ENET_DMA_RDTADDR_SRT             BITS(0,31)                             /*!< start address of receive table */
+  
+/* ENET_DMA_TDTADDR */
+#define ENET_DMA_TDTADDR_STT             BITS(0,31)                             /*!< start address of transmit table */
+  
+/* ENET_DMA_STAT */
+#define ENET_DMA_STAT_TS                 BIT(0)                                 /*!< transmit status */
+#define ENET_DMA_STAT_TPS                BIT(1)                                 /*!< transmit process stopped status */
+#define ENET_DMA_STAT_TBU                BIT(2)                                 /*!< transmit buffer unavailable status */
+#define ENET_DMA_STAT_TJT                BIT(3)                                 /*!< transmit jabber timeout status */
+#define ENET_DMA_STAT_RO                 BIT(4)                                 /*!< receive overflow status */
+#define ENET_DMA_STAT_TU                 BIT(5)                                 /*!< transmit underflow status */
+#define ENET_DMA_STAT_RS                 BIT(6)                                 /*!< receive status */
+#define ENET_DMA_STAT_RBU                BIT(7)                                 /*!< receive buffer unavailable status */
+#define ENET_DMA_STAT_RPS                BIT(8)                                 /*!< receive process stopped status */
+#define ENET_DMA_STAT_RWT                BIT(9)                                 /*!< receive watchdog timeout status */
+#define ENET_DMA_STAT_ET                 BIT(10)                                /*!< early transmit status */
+#define ENET_DMA_STAT_FBE                BIT(13)                                /*!< fatal bus error status */
+#define ENET_DMA_STAT_ER                 BIT(14)                                /*!< early receive status */
+#define ENET_DMA_STAT_AI                 BIT(15)                                /*!< abnormal interrupt summary */
+#define ENET_DMA_STAT_NI                 BIT(16)                                /*!< normal interrupt summary */
+#define ENET_DMA_STAT_RP                 BITS(17,19)                            /*!< receive process state */
+#define ENET_DMA_STAT_TP                 BITS(20,22)                            /*!< transmit process state */
+#define ENET_DMA_STAT_EB                 BITS(23,25)                            /*!< error bits status */
+#define ENET_DMA_STAT_MSC                BIT(27)                                /*!< MSC status */
+#define ENET_DMA_STAT_WUM                BIT(28)                                /*!< WUM status */
+#define ENET_DMA_STAT_TST                BIT(29)                                /*!< timestamp trigger status */
+ 
+/* ENET_DMA_CTL */
+#define ENET_DMA_CTL_SRE                 BIT(1)                                 /*!< start/stop receive enable */
+#define ENET_DMA_CTL_OSF                 BIT(2)                                 /*!< operate on second frame */
+#define ENET_DMA_CTL_RTHC                BITS(3,4)                              /*!< receive threshold control */
+#define ENET_DMA_CTL_FUF                 BIT(6)                                 /*!< forward undersized good frames */
+#define ENET_DMA_CTL_FERF                BIT(7)                                 /*!< forward error frames */
+#define ENET_DMA_CTL_STE                 BIT(13)                                /*!< start/stop transmission enable */
+#define ENET_DMA_CTL_TTHC                BITS(14,16)                            /*!< transmit threshold control */
+#define ENET_DMA_CTL_FTF                 BIT(20)                                /*!< flush transmit FIFO */
+#define ENET_DMA_CTL_TSFD                BIT(21)                                /*!< transmit store-and-forward */
+#define ENET_DMA_CTL_DAFRF               BIT(24)                                /*!< disable flushing of received frames */
+#define ENET_DMA_CTL_RSFD                BIT(25)                                /*!< receive store-and-forward */
+#define ENET_DMA_CTL_DTCERFD             BIT(26)                                /*!< dropping of TCP/IP checksum error frames disable */
+  
+/* ENET_DMA_INTEN */
+#define ENET_DMA_INTEN_TIE               BIT(0)                                 /*!< transmit interrupt enable */
+#define ENET_DMA_INTEN_TPSIE             BIT(1)                                 /*!< transmit process stopped interrupt enable */
+#define ENET_DMA_INTEN_TBUIE             BIT(2)                                 /*!< transmit buffer unavailable interrupt enable */
+#define ENET_DMA_INTEN_TJTIE             BIT(3)                                 /*!< transmit jabber timeout interrupt enable */
+#define ENET_DMA_INTEN_ROIE              BIT(4)                                 /*!< receive overflow interrupt enable */
+#define ENET_DMA_INTEN_TUIE              BIT(5)                                 /*!< transmit underflow interrupt enable */
+#define ENET_DMA_INTEN_RIE               BIT(6)                                 /*!< receive interrupt enable */
+#define ENET_DMA_INTEN_RBUIE             BIT(7)                                 /*!< receive buffer unavailable interrupt enable */
+#define ENET_DMA_INTEN_RPSIE             BIT(8)                                 /*!< receive process stopped interrupt enable */
+#define ENET_DMA_INTEN_RWTIE             BIT(9)                                 /*!< receive watchdog timeout interrupt enable */
+#define ENET_DMA_INTEN_ETIE              BIT(10)                                /*!< early transmit interrupt enable */
+#define ENET_DMA_INTEN_FBEIE             BIT(13)                                /*!< fatal bus error interrupt enable */
+#define ENET_DMA_INTEN_ERIE              BIT(14)                                /*!< early receive interrupt enable */
+#define ENET_DMA_INTEN_AIE               BIT(15)                                /*!< abnormal interrupt summary enable */
+#define ENET_DMA_INTEN_NIE               BIT(16)                                /*!< normal interrupt summary enable */
+  
+/* ENET_DMA_MFBOCNT */
+#define ENET_DMA_MFBOCNT_MSFC            BITS(0,15)                             /*!< missed frames by the controller */
+#define ENET_DMA_MFBOCNT_MSFA            BITS(17,27)                            /*!< missed frames by the application */
+
+/* ENET_DMA_RSWDC */
+#define ENET_DMA_RSWDC_WDCFRS            BITS(0,7)                              /*!< watchdog counter for receive status (RS) */
+
+/* ENET_DMA_CTDADDR */
+#define ENET_DMA_CTDADDR_TDAP            BITS(0,31)                             /*!< transmit descriptor address pointer */
+
+/* ENET_DMA_CRDADDR */
+#define ENET_DMA_CRDADDR_RDAP            BITS(0,31)                             /*!< receive descriptor address pointer */
+  
+/* ENET_DMA_CTBADDR */
+#define ENET_DMA_CTBADDR_TBAP            BITS(0,31)                             /*!< transmit buffer address pointer */
+  
+/* ENET_DMA_CRBADDR */
+#define ENET_DMA_CRBADDR_RBAP            BITS(0,31)                             /*!< receive buffer address pointer */
+
+/* ENET DMA Tx descriptor TDES0 */
+#define ENET_TDES0_DB                    BIT(0)                                 /*!< deferred */
+#define ENET_TDES0_UFE                   BIT(1)                                 /*!< underflow error */
+#define ENET_TDES0_EXD                   BIT(2)                                 /*!< excessive deferral */
+#define ENET_TDES0_COCNT                 BITS(3,6)                              /*!< collision count */
+#define ENET_TDES0_VFRM                  BIT(7)                                 /*!< VLAN frame */
+#define ENET_TDES0_ECO                   BIT(8)                                 /*!< excessive collision */
+#define ENET_TDES0_LCO                   BIT(9)                                 /*!< late collision */
+#define ENET_TDES0_NCA                   BIT(10)                                /*!< no carrier */
+#define ENET_TDES0_LCA                   BIT(11)                                /*!< loss of carrier */
+#define ENET_TDES0_IPPE                  BIT(12)                                /*!< IP payload error */
+#define ENET_TDES0_FRMF                  BIT(13)                                /*!< frame flushed */
+#define ENET_TDES0_JT                    BIT(14)                                /*!< jabber timeout */
+#define ENET_TDES0_ES                    BIT(15)                                /*!< error summary */
+#define ENET_TDES0_IPHE                  BIT(16)                                /*!< IP header error */
+#define ENET_TDES0_TTMSS                 BIT(17)                                /*!< transmit timestamp status */
+#define ENET_TDES0_TCHM                  BIT(20)                                /*!< the second address chained mode */
+#define ENET_TDES0_TERM                  BIT(21)                                /*!< transmit end of ring mode*/
+#define ENET_TDES0_CM                    BITS(22,23)                            /*!< checksum mode */
+#define ENET_TDES0_TTSEN                 BIT(25)                                /*!< transmit timestamp function enable */
+#define ENET_TDES0_DPAD                  BIT(26)                                /*!< disable adding pad */
+#define ENET_TDES0_DCRC                  BIT(27)                                /*!< disable CRC */
+#define ENET_TDES0_FSG                   BIT(28)                                /*!< first segment */
+#define ENET_TDES0_LSG                   BIT(29)                                /*!< last segment */
+#define ENET_TDES0_INTC                  BIT(30)                                /*!< interrupt on completion */
+#define ENET_TDES0_DAV                   BIT(31)                                /*!< DAV bit */
+
+/* ENET DMA Tx descriptor TDES1 */
+#define ENET_TDES1_TB1S                  BITS(0,12)                             /*!< transmit buffer 1 size */
+#define ENET_TDES1_TB2S                  BITS(16,28)                            /*!< transmit buffer 2 size */
+
+/* ENET DMA Tx descriptor TDES2 */
+#define ENET_TDES2_TB1AP                 BITS(0,31)                             /*!< transmit buffer 1 address pointer/transmit frame timestamp low 32-bit value */
+
+/* ENET DMA Tx descriptor TDES3 */
+#define ENET_TDES3_TB2AP                 BITS(0,31)                             /*!< transmit buffer 2 address pointer (or next descriptor address) / transmit frame timestamp high 32-bit value */
+
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+/* ENET DMA Tx descriptor TDES6 */
+#define ENET_TDES6_TTSL                  BITS(0,31)                             /*!< transmit frame timestamp low 32-bit value */
+
+/* ENET DMA Tx descriptor TDES7 */
+#define ENET_TDES7_TTSH                  BITS(0,31)                             /*!< transmit frame timestamp high 32-bit value */
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */
+
+/* ENET DMA Rx descriptor RDES0 */
+#define ENET_RDES0_PCERR                 BIT(0)                                 /*!< payload checksum error */
+#define ENET_RDES0_EXSV                  BIT(0)                                 /*!< extended status valid */
+#define ENET_RDES0_CERR                  BIT(1)                                 /*!< CRC error */
+#define ENET_RDES0_DBERR                 BIT(2)                                 /*!< dribble bit error */
+#define ENET_RDES0_RERR                  BIT(3)                                 /*!< receive error */
+#define ENET_RDES0_RWDT                  BIT(4)                                 /*!< receive watchdog timeout */
+#define ENET_RDES0_FRMT                  BIT(5)                                 /*!< frame type */
+#define ENET_RDES0_LCO                   BIT(6)                                 /*!< late collision */
+#define ENET_RDES0_IPHERR                BIT(7)                                 /*!< IP frame header error */
+#define ENET_RDES0_TSV                   BIT(7)                                 /*!< timestamp valid */
+#define ENET_RDES0_LDES                  BIT(8)                                 /*!< last descriptor */ 
+#define ENET_RDES0_FDES                  BIT(9)                                 /*!< first descriptor */
+#define ENET_RDES0_VTAG                  BIT(10)                                /*!< VLAN tag */
+#define ENET_RDES0_OERR                  BIT(11)                                /*!< overflow Error */
+#define ENET_RDES0_LERR                  BIT(12)                                /*!< length error */
+#define ENET_RDES0_SAFF                  BIT(13)                                /*!< SA filter fail */
+#define ENET_RDES0_DERR                  BIT(14)                                /*!< descriptor error */
+#define ENET_RDES0_ERRS                  BIT(15)                                /*!< error summary */
+#define ENET_RDES0_FRML                  BITS(16,29)                            /*!< frame length */
+#define ENET_RDES0_DAFF                  BIT(30)                                /*!< destination address filter fail */
+#define ENET_RDES0_DAV                   BIT(31)                                /*!< descriptor available */
+
+/* ENET DMA Rx descriptor RDES1 */ 
+#define ENET_RDES1_RB1S                  BITS(0,12)                             /*!< receive buffer 1 size */
+#define ENET_RDES1_RCHM                  BIT(14)                                /*!< receive chained mode for second address */
+#define ENET_RDES1_RERM                  BIT(15)                                /*!< receive end of ring mode*/
+#define ENET_RDES1_RB2S                  BITS(16,28)                            /*!< receive buffer 2 size */
+#define ENET_RDES1_DINTC                 BIT(31)                                /*!< disable interrupt on completion */
+
+/* ENET DMA Rx descriptor RDES2 */
+#define ENET_RDES2_RB1AP                 BITS(0,31)                             /*!< receive buffer 1 address pointer / receive frame timestamp low 32-bit */
+
+/* ENET DMA Rx descriptor RDES3 */
+#define ENET_RDES3_RB2AP                 BITS(0,31)                             /*!< receive buffer 2 address pointer (next descriptor address)/receive frame timestamp high 32-bit value */
+
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+/* ENET DMA Rx descriptor RDES4 */
+#define ENET_RDES4_IPPLDT                BITS(0,2)                              /*!< IP frame payload type */
+#define ENET_RDES4_IPHERR                BIT(3)                                 /*!< IP frame header error */
+#define ENET_RDES4_IPPLDERR              BIT(4)                                 /*!< IP frame payload error */
+#define ENET_RDES4_IPCKSB                BIT(5)                                 /*!< IP frame checksum bypassed */
+#define ENET_RDES4_IPF4                  BIT(6)                                 /*!< IP frame in version 4 */
+#define ENET_RDES4_IPF6                  BIT(7)                                 /*!< IP frame in version 6 */
+#define ENET_RDES4_PTPMT                 BITS(8,11)                             /*!< PTP message type */
+#define ENET_RDES4_PTPOEF                BIT(12)                                /*!< PTP on ethernet frame */
+#define ENET_RDES4_PTPVF                 BIT(13)                                /*!< PTP version format */
+
+/* ENET DMA Rx descriptor RDES6 */
+#define ENET_RDES6_RTSL                  BITS(0,31)                             /*!< receive frame timestamp low 32-bit value */
+
+/* ENET DMA Rx descriptor RDES7 */
+#define ENET_RDES7_RTSH                  BITS(0,31)                             /*!< receive frame timestamp high 32-bit value */
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */
+
+/* constants definitions */
+/* define bit position and its register index offset */
+#define ENET_REGIDX_BIT(regidx, bitpos)  (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define ENET_REG_VAL(periph)             (REG32(ENET + ((uint32_t)(periph)>>6)))
+#define ENET_BIT_POS(val)                ((uint32_t)(val) & 0x1FU)
+
+/* ENET clock range judgement */
+#define ENET_RANGE(hclk, n, m)           (((hclk) >= (n))&&((hclk) < (m)))
+
+/* define MAC address configuration and reference address */
+#define ENET_SET_MACADDRH(p)             (((uint32_t)(p)[5] << 8) | (uint32_t)(p)[4])         
+#define ENET_SET_MACADDRL(p)             (((uint32_t)(p)[3] << 24) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[1] << 8) | (uint32_t)(p)[0])
+#define ENET_ADDRH_BASE                  ((ENET) + 0x40U)
+#define ENET_ADDRL_BASE                  ((ENET) + 0x44U)
+#define ENET_GET_MACADDR(offset, n)      ((uint8_t)((REG32((ENET_ADDRL_BASE + (offset)) - (((n) / 4U) * 4U)) >> (8U * ((n) % 4U))) & 0xFFU))
+
+/* register offset */
+#define MAC_FCTL_REG_OFFSET              0x0018U                                /*!< MAC flow control register offset */
+#define MAC_WUM_REG_OFFSET               0x002CU                                /*!< MAC wakeup management register offset */
+#define MAC_INTF_REG_OFFSET              0x0038U                                /*!< MAC interrupt flag register offset */
+#define MAC_INTMSK_REG_OFFSET            0x003CU                                /*!< MAC interrupt mask register offset */
+
+#define MSC_RINTF_REG_OFFSET             0x0104U                                /*!< MSC receive interrupt flag register offset */
+#define MSC_TINTF_REG_OFFSET             0x0108U                                /*!< MSC transmit interrupt flag register offset */
+#define MSC_RINTMSK_REG_OFFSET           0x010CU                                /*!< MSC receive interrupt mask register offset */
+#define MSC_TINTMSK_REG_OFFSET           0x0110U                                /*!< MSC transmit interrupt mask register offset */
+#define MSC_SCCNT_REG_OFFSET             0x014CU                                /*!< MSC transmitted good frames after a single collision counter register offset */
+#define MSC_MSCCNT_REG_OFFSET            0x0150U                                /*!< MSC transmitted good frames after more than a single collision counter register offset */
+#define MSC_TGFCNT_REG_OFFSET            0x0168U                                /*!< MSC transmitted good frames counter register offset */
+#define MSC_RFCECNT_REG_OFFSET           0x0194U                                /*!< MSC received frames with CRC error counter register offset */
+#define MSC_RFAECNT_REG_OFFSET           0x0198U                                /*!< MSC received frames with alignment error counter register offset */
+#define MSC_RGUFCNT_REG_OFFSET           0x01C4U                                /*!< MSC received good unicast frames counter register offset */
+                                                                           
+#define PTP_TSF_REG_OFFSET               0x0728U                                /*!< PTP time stamp flag register offset */
+
+#define DMA_STAT_REG_OFFSET              0x1014U                                /*!< DMA status register offset */
+#define DMA_INTEN_REG_OFFSET             0x101CU                                /*!< DMA interrupt enable register offset */
+#define DMA_TDTADDR_REG_OFFSET           0x1010U                                /*!< DMA transmit descriptor table address register offset */
+#define DMA_CTDADDR_REG_OFFSET           0x1048U                                /*!< DMA current transmit descriptor address register */
+#define DMA_CTBADDR_REG_OFFSET           0x1050U                                /*!< DMA current transmit buffer address register */
+#define DMA_RDTADDR_REG_OFFSET           0x100CU                                /*!< DMA receive descriptor table address register */
+#define DMA_CRDADDR_REG_OFFSET           0x104CU                                /*!< DMA current receive descriptor address register */
+#define DMA_CRBADDR_REG_OFFSET           0x1054U                                /*!< DMA current receive buffer address register */
+
+/* ENET status flag get */
+typedef enum
+{
+    /* ENET_MAC_WUM register */
+    ENET_MAC_FLAG_MPKR              = ENET_REGIDX_BIT(MAC_WUM_REG_OFFSET, 5U),      /*!< magic packet received flag */
+    ENET_MAC_FLAG_WUFR              = ENET_REGIDX_BIT(MAC_WUM_REG_OFFSET, 6U),      /*!< wakeup frame received flag */ 
+    /* ENET_MAC_FCTL register */
+    ENET_MAC_FLAG_FLOWCONTROL       = ENET_REGIDX_BIT(MAC_FCTL_REG_OFFSET, 0U),     /*!< flow control status flag */
+    /* ENET_MAC_INTF register */
+    ENET_MAC_FLAG_WUM               = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 3U),     /*!< WUM status flag */
+    ENET_MAC_FLAG_MSC               = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 4U),     /*!< MSC status flag */
+    ENET_MAC_FLAG_MSCR              = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 5U),     /*!< MSC receive status flag */
+    ENET_MAC_FLAG_MSCT              = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 6U),     /*!< MSC transmit status flag */
+    ENET_MAC_FLAG_TMST              = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 9U),     /*!< timestamp trigger status flag */
+    /* ENET_PTP_TSF register */
+    ENET_PTP_FLAG_TSSCO             = ENET_REGIDX_BIT(PTP_TSF_REG_OFFSET, 0U),      /*!< timestamp second counter overflow flag */  
+    ENET_PTP_FLAG_TTM               = ENET_REGIDX_BIT(PTP_TSF_REG_OFFSET, 1U),      /*!< target time match flag */
+    /* ENET_MSC_RINTF register */
+    ENET_MSC_FLAG_RFCE              = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 5U),    /*!< received frames CRC error flag */
+    ENET_MSC_FLAG_RFAE              = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 6U),    /*!< received frames alignment error flag */
+    ENET_MSC_FLAG_RGUF              = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 17U),   /*!< received good unicast frames flag */
+    /* ENET_MSC_TINTF register */ 
+    ENET_MSC_FLAG_TGFSC             = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 14U),   /*!< transmitted good frames single collision flag */
+    ENET_MSC_FLAG_TGFMSC            = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 15U),   /*!< transmitted good frames more single collision flag */
+    ENET_MSC_FLAG_TGF               = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 21U),   /*!< transmitted good frames flag */
+    /* ENET_DMA_STAT register */
+    ENET_DMA_FLAG_TS                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U),     /*!< transmit status flag */
+    ENET_DMA_FLAG_TPS               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U),     /*!< transmit process stopped status flag */
+    ENET_DMA_FLAG_TBU               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U),     /*!< transmit buffer unavailable status flag */
+    ENET_DMA_FLAG_TJT               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U),     /*!< transmit jabber timeout status flag */
+    ENET_DMA_FLAG_RO                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U),     /*!< receive overflow status flag */
+    ENET_DMA_FLAG_TU                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U),     /*!< transmit underflow status flag */
+    ENET_DMA_FLAG_RS                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U),     /*!< receive status flag */
+    ENET_DMA_FLAG_RBU               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U),     /*!< receive buffer unavailable status flag */
+    ENET_DMA_FLAG_RPS               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U),     /*!< receive process stopped status flag */
+    ENET_DMA_FLAG_RWT               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U),     /*!< receive watchdog timeout status flag */
+    ENET_DMA_FLAG_ET                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U),    /*!< early transmit status flag */
+    ENET_DMA_FLAG_FBE               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U),    /*!< fatal bus error status flag */
+    ENET_DMA_FLAG_ER                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U),    /*!< early receive status flag */
+    ENET_DMA_FLAG_AI                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U),    /*!< abnormal interrupt summary flag */
+    ENET_DMA_FLAG_NI                = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U),    /*!< normal interrupt summary flag */
+    ENET_DMA_FLAG_EB_DMA_ERROR      = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 23U),    /*!< error during data transfer by RxDMA/TxDMA flag */
+    ENET_DMA_FLAG_EB_TRANSFER_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 24U),    /*!< error during write/read transfer flag */
+    ENET_DMA_FLAG_EB_ACCESS_ERROR   = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 25U),    /*!< error during data buffer/descriptor access flag */
+    ENET_DMA_FLAG_MSC               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 27U),    /*!< MSC status flag */
+    ENET_DMA_FLAG_WUM               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 28U),    /*!< WUM status flag */
+    ENET_DMA_FLAG_TST               = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 29U),    /*!< timestamp trigger status flag */                        
+}enet_flag_enum;
+
+/* ENET stutus flag clear */
+typedef enum
+{
+    /* ENET_DMA_STAT register */
+    ENET_DMA_FLAG_TS_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U),     /*!< transmit status flag */
+    ENET_DMA_FLAG_TPS_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U),     /*!< transmit process stopped status flag */
+    ENET_DMA_FLAG_TBU_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U),     /*!< transmit buffer unavailable status flag */
+    ENET_DMA_FLAG_TJT_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U),     /*!< transmit jabber timeout status flag */
+    ENET_DMA_FLAG_RO_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U),     /*!< receive overflow status flag */
+    ENET_DMA_FLAG_TU_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U),     /*!< transmit underflow status flag */
+    ENET_DMA_FLAG_RS_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U),     /*!< receive status flag */
+    ENET_DMA_FLAG_RBU_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U),     /*!< receive buffer unavailable status flag */
+    ENET_DMA_FLAG_RPS_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U),     /*!< receive process stopped status flag */
+    ENET_DMA_FLAG_RWT_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U),     /*!< receive watchdog timeout status flag */
+    ENET_DMA_FLAG_ET_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U),    /*!< early transmit status flag */
+    ENET_DMA_FLAG_FBE_CLR           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U),    /*!< fatal bus error status flag */
+    ENET_DMA_FLAG_ER_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U),    /*!< early receive status flag */
+    ENET_DMA_FLAG_AI_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U),    /*!< abnormal interrupt summary flag */
+    ENET_DMA_FLAG_NI_CLR            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U),    /*!< normal interrupt summary flag */                       
+}enet_flag_clear_enum;
+
+/* ENET interrupt enable/disable */
+typedef enum
+{
+    /* ENET_MAC_INTMSK register */
+    ENET_MAC_INT_WUMIM              = ENET_REGIDX_BIT(MAC_INTMSK_REG_OFFSET, 3U),   /*!< WUM interrupt mask */
+    ENET_MAC_INT_TMSTIM             = ENET_REGIDX_BIT(MAC_INTMSK_REG_OFFSET, 9U),   /*!< timestamp trigger interrupt mask */
+    /* ENET_MSC_RINTMSK register */ 
+    ENET_MSC_INT_RFCEIM             = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 5U),  /*!< received frame CRC error interrupt mask */
+    ENET_MSC_INT_RFAEIM             = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 6U),  /*!< received frames alignment error interrupt mask */
+    ENET_MSC_INT_RGUFIM             = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 17U), /*!< received good unicast frames interrupt mask */
+    /* ENET_MSC_TINTMSK register */ 
+    ENET_MSC_INT_TGFSCIM            = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 14U), /*!< transmitted good frames single collision interrupt mask */
+    ENET_MSC_INT_TGFMSCIM           = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 15U), /*!< transmitted good frames more single collision interrupt mask */
+    ENET_MSC_INT_TGFIM              = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 21U), /*!< transmitted good frames interrupt mask */
+    /* ENET_DMA_INTEN register */ 
+    ENET_DMA_INT_TIE                = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 0U),    /*!< transmit interrupt enable */
+    ENET_DMA_INT_TPSIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 1U),    /*!< transmit process stopped interrupt enable */
+    ENET_DMA_INT_TBUIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 2U),    /*!< transmit buffer unavailable interrupt enable */
+    ENET_DMA_INT_TJTIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 3U),    /*!< transmit jabber timeout interrupt enable */
+    ENET_DMA_INT_ROIE               = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 4U),    /*!< receive overflow interrupt enable */
+    ENET_DMA_INT_TUIE               = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 5U),    /*!< transmit underflow interrupt enable */
+    ENET_DMA_INT_RIE                = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 6U),    /*!< receive interrupt enable */
+    ENET_DMA_INT_RBUIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 7U),    /*!< receive buffer unavailable interrupt enable */
+    ENET_DMA_INT_RPSIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 8U),    /*!< receive process stopped interrupt enable */
+    ENET_DMA_INT_RWTIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 9U),    /*!< receive watchdog timeout interrupt enable */
+    ENET_DMA_INT_ETIE               = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 10U),   /*!< early transmit interrupt enable */
+    ENET_DMA_INT_FBEIE              = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 13U),   /*!< fatal bus error interrupt enable */
+    ENET_DMA_INT_ERIE               = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 14U),   /*!< early receive interrupt enable */
+    ENET_DMA_INT_AIE                = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 15U),   /*!< abnormal interrupt summary enable */
+    ENET_DMA_INT_NIE                = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 16U),   /*!< normal interrupt summary enable */
+}enet_int_enum;
+ 
+/* ENET interrupt flag get */
+typedef enum
+{
+    /* ENET_MAC_INTF register */
+    ENET_MAC_INT_FLAG_WUM           = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 3U),     /*!< WUM status flag */
+    ENET_MAC_INT_FLAG_MSC           = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 4U),     /*!< MSC status flag */
+    ENET_MAC_INT_FLAG_MSCR          = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 5U),     /*!< MSC receive status flag */
+    ENET_MAC_INT_FLAG_MSCT          = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 6U),     /*!< MSC transmit status flag */
+    ENET_MAC_INT_FLAG_TMST          = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 9U),     /*!< timestamp trigger status flag */
+    /* ENET_MSC_RINTF register */
+    ENET_MSC_INT_FLAG_RFCE          = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 5U),    /*!< received frames CRC error flag */
+    ENET_MSC_INT_FLAG_RFAE          = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 6U),    /*!< received frames alignment error flag */
+    ENET_MSC_INT_FLAG_RGUF          = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 17U),   /*!< received good unicast frames flag */
+    /* ENET_MSC_TINTF register */
+    ENET_MSC_INT_FLAG_TGFSC         = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 14U),   /*!< transmitted good frames single collision flag */
+    ENET_MSC_INT_FLAG_TGFMSC        = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 15U),   /*!< transmitted good frames more single collision flag */
+    ENET_MSC_INT_FLAG_TGF           = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 21U),   /*!< transmitted good frames flag */
+    /* ENET_DMA_STAT register */
+    ENET_DMA_INT_FLAG_TS            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U),     /*!< transmit status flag */
+    ENET_DMA_INT_FLAG_TPS           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U),     /*!< transmit process stopped status flag */
+    ENET_DMA_INT_FLAG_TBU           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U),     /*!< transmit buffer unavailable status flag */
+    ENET_DMA_INT_FLAG_TJT           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U),     /*!< transmit jabber timeout status flag */
+    ENET_DMA_INT_FLAG_RO            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U),     /*!< receive overflow status flag */
+    ENET_DMA_INT_FLAG_TU            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U),     /*!< transmit underflow status flag */
+    ENET_DMA_INT_FLAG_RS            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U),     /*!< receive status flag */
+    ENET_DMA_INT_FLAG_RBU           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U),     /*!< receive buffer unavailable status flag */
+    ENET_DMA_INT_FLAG_RPS           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U),     /*!< receive process stopped status flag */
+    ENET_DMA_INT_FLAG_RWT           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U),     /*!< receive watchdog timeout status flag */
+    ENET_DMA_INT_FLAG_ET            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U),    /*!< early transmit status flag */
+    ENET_DMA_INT_FLAG_FBE           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U),    /*!< fatal bus error status flag */
+    ENET_DMA_INT_FLAG_ER            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U),    /*!< early receive status flag */
+    ENET_DMA_INT_FLAG_AI            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U),    /*!< abnormal interrupt summary flag */
+    ENET_DMA_INT_FLAG_NI            = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U),    /*!< normal interrupt summary flag */
+    ENET_DMA_INT_FLAG_MSC           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 27U),    /*!< MSC status flag */
+    ENET_DMA_INT_FLAG_WUM           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 28U),    /*!< WUM status flag */
+    ENET_DMA_INT_FLAG_TST           = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 29U),    /*!< timestamp trigger status flag */ 
+}enet_int_flag_enum;
+
+/* ENET interrupt flag clear */
+typedef enum
+{
+    /* ENET_DMA_STAT register */
+    ENET_DMA_INT_FLAG_TS_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U),     /*!< transmit status flag */
+    ENET_DMA_INT_FLAG_TPS_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U),     /*!< transmit process stopped status flag */
+    ENET_DMA_INT_FLAG_TBU_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U),     /*!< transmit buffer unavailable status flag */
+    ENET_DMA_INT_FLAG_TJT_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U),     /*!< transmit jabber timeout status flag */
+    ENET_DMA_INT_FLAG_RO_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U),     /*!< receive overflow status flag */
+    ENET_DMA_INT_FLAG_TU_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U),     /*!< transmit underflow status flag */
+    ENET_DMA_INT_FLAG_RS_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U),     /*!< receive status flag */
+    ENET_DMA_INT_FLAG_RBU_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U),     /*!< receive buffer unavailable status flag */
+    ENET_DMA_INT_FLAG_RPS_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U),     /*!< receive process stopped status flag */
+    ENET_DMA_INT_FLAG_RWT_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U),     /*!< receive watchdog timeout status flag */
+    ENET_DMA_INT_FLAG_ET_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U),    /*!< early transmit status flag */
+    ENET_DMA_INT_FLAG_FBE_CLR       = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U),    /*!< fatal bus error status flag */
+    ENET_DMA_INT_FLAG_ER_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U),    /*!< early receive status flag */
+    ENET_DMA_INT_FLAG_AI_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U),    /*!< abnormal interrupt summary flag */
+    ENET_DMA_INT_FLAG_NI_CLR        = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U),    /*!< normal interrupt summary flag */
+}enet_int_flag_clear_enum;
+
+/* current RX/TX descriptor/buffer/descriptor table address get */
+typedef enum
+{
+    ENET_RX_DESC_TABLE              = DMA_RDTADDR_REG_OFFSET,                       /*!< RX descriptor table */
+    ENET_RX_CURRENT_DESC            = DMA_CRDADDR_REG_OFFSET,                       /*!< current RX descriptor */
+    ENET_RX_CURRENT_BUFFER          = DMA_CRBADDR_REG_OFFSET,                       /*!< current RX buffer */
+    ENET_TX_DESC_TABLE              = DMA_TDTADDR_REG_OFFSET,                       /*!< TX descriptor table */
+    ENET_TX_CURRENT_DESC            = DMA_CTDADDR_REG_OFFSET,                       /*!< current TX descriptor */
+    ENET_TX_CURRENT_BUFFER          = DMA_CTBADDR_REG_OFFSET                        /*!< current TX buffer */
+}enet_desc_reg_enum;
+
+/* MAC statistics counter get */
+typedef enum
+{
+    ENET_MSC_TX_SCCNT               = MSC_SCCNT_REG_OFFSET,                         /*!< MSC transmitted good frames after a single collision counter */
+    ENET_MSC_TX_MSCCNT              = MSC_MSCCNT_REG_OFFSET,                        /*!< MSC transmitted good frames after more than a single collision counter */
+    ENET_MSC_TX_TGFCNT              = MSC_TGFCNT_REG_OFFSET,                        /*!< MSC transmitted good frames counter */
+    ENET_MSC_RX_RFCECNT             = MSC_RFCECNT_REG_OFFSET,                       /*!< MSC received frames with CRC error counter */
+    ENET_MSC_RX_RFAECNT             = MSC_RFAECNT_REG_OFFSET,                       /*!< MSC received frames with alignment error counter */
+    ENET_MSC_RX_RGUFCNT             = MSC_RGUFCNT_REG_OFFSET                        /*!< MSC received good unicast frames counter */
+}enet_msc_counter_enum; 
+
+/* function option, used for ENET initialization */
+typedef enum
+{
+    FORWARD_OPTION                  = BIT(0),                                       /*!< configure the frame forward related parameters */
+    DMABUS_OPTION                   = BIT(1),                                       /*!< configure the DMA bus mode related parameters */
+    DMA_MAXBURST_OPTION             = BIT(2),                                       /*!< configure the DMA max burst related parameters */
+    DMA_ARBITRATION_OPTION          = BIT(3),                                       /*!< configure the DMA arbitration related parameters */
+    STORE_OPTION                    = BIT(4),                                       /*!< configure the store forward mode related parameters */
+    DMA_OPTION                      = BIT(5),                                       /*!< configure the DMA control related parameters */
+    VLAN_OPTION                     = BIT(6),                                       /*!< configure the VLAN tag related parameters */
+    FLOWCTL_OPTION                  = BIT(7),                                       /*!< configure the flow control related parameters */
+    HASHH_OPTION                    = BIT(8),                                       /*!< configure the hash list high 32-bit related parameters */
+    HASHL_OPTION                    = BIT(9),                                       /*!< configure the hash list low 32-bit related parameters */
+    FILTER_OPTION                   = BIT(10),                                      /*!< configure the frame filter control related parameters */
+    HALFDUPLEX_OPTION               = BIT(11),                                      /*!< configure the halfduplex related parameters */
+    TIMER_OPTION                    = BIT(12),                                      /*!< configure the frame timer related parameters */
+    INTERFRAMEGAP_OPTION            = BIT(13),                                      /*!< configure the inter frame gap related parameters */
+}enet_option_enum;
+
+/* phy mode and mac loopback configurations */
+typedef enum
+{
+    ENET_AUTO_NEGOTIATION           = 0x01u,                                        /*!< PHY auto negotiation */
+    ENET_100M_FULLDUPLEX            = (ENET_MAC_CFG_SPD | ENET_MAC_CFG_DPM),        /*!< 100Mbit/s, full-duplex */
+    ENET_100M_HALFDUPLEX            = ENET_MAC_CFG_SPD ,                            /*!< 100Mbit/s, half-duplex */
+    ENET_10M_FULLDUPLEX             = ENET_MAC_CFG_DPM,                             /*!< 10Mbit/s, full-duplex */
+    ENET_10M_HALFDUPLEX             = (uint32_t)0x00000000U,                        /*!< 10Mbit/s, half-duplex */
+    ENET_LOOPBACKMODE               = (ENET_MAC_CFG_LBM | ENET_MAC_CFG_DPM)         /*!< MAC in loopback mode at the MII */
+}enet_mediamode_enum;
+
+/* IP frame checksum function */
+typedef enum
+{
+    ENET_NO_AUTOCHECKSUM                = (uint32_t)0x00000000U,                    /*!< disable IP frame checksum function */
+    ENET_AUTOCHECKSUM_DROP_FAILFRAMES   = ENET_MAC_CFG_IPFCO,                       /*!< enable IP frame checksum function */
+    ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES = (ENET_MAC_CFG_IPFCO|ENET_DMA_CTL_DTCERFD) /*!< enable IP frame checksum function, and the received frame
+                                                                                         with only payload error but no other errors will not be dropped */
+}enet_chksumconf_enum;
+
+/* received frame filter function */
+typedef enum
+{
+    ENET_PROMISCUOUS_MODE           = ENET_MAC_FRMF_PM,                             /*!< promiscuous mode enabled */
+    ENET_RECEIVEALL                 = (int32_t)ENET_MAC_FRMF_FAR,                   /*!< all received frame are forwarded to application */
+    ENET_BROADCAST_FRAMES_PASS      = (uint32_t)0x00000000U,                        /*!< the address filters pass all received broadcast frames */
+    ENET_BROADCAST_FRAMES_DROP      = ENET_MAC_FRMF_BFRMD                           /*!< the address filters filter all incoming broadcast frames */
+}enet_frmrecept_enum;
+
+/* register group value get */
+typedef enum
+{
+    ALL_MAC_REG                     = 0,                                            /*!< MAC register group */
+    ALL_MSC_REG                     = 22,                                           /*!< MSC register group */
+    ALL_PTP_REG                     = 33,                                           /*!< PTP register group */
+    ALL_DMA_REG                     = 44,                                           /*!< DMA register group */
+}enet_registers_type_enum;
+
+/* dma direction select */
+typedef enum
+{
+    ENET_DMA_TX                     = ENET_DMA_STAT_TP,                             /*!< DMA transmit direction */
+    ENET_DMA_RX                     = ENET_DMA_STAT_RP                              /*!< DMA receive direction */
+}enet_dmadirection_enum;
+
+/* PHY operation direction select */
+typedef enum
+{
+    ENET_PHY_READ                   = (uint32_t)0x00000000,                         /*!< read PHY */
+    ENET_PHY_WRITE                  = ENET_MAC_PHY_CTL_PW                           /*!< write PHY */
+}enet_phydirection_enum;
+
+/* register operation direction select */
+typedef enum
+{
+    ENET_REG_READ,                                                                  /*!< read register */
+    ENET_REG_WRITE                                                                  /*!< write register */
+}enet_regdirection_enum;
+
+/* ENET MAC addresses */ 
+typedef enum
+{
+    ENET_MAC_ADDRESS0               = ((uint32_t)0x00000000),                       /*!< MAC address0 */
+    ENET_MAC_ADDRESS1               = ((uint32_t)0x00000008),                       /*!< MAC address1 */
+    ENET_MAC_ADDRESS2               = ((uint32_t)0x00000010),                       /*!< MAC address2 */
+    ENET_MAC_ADDRESS3               = ((uint32_t)0x00000018)                        /*!< MAC address3 */
+}enet_macaddress_enum;
+
+/* descriptor information */
+typedef enum
+{
+    TXDESC_COLLISION_COUNT,                                                         /*!< the number of collisions occurred before the frame was transmitted */
+    TXDESC_BUFFER_1_ADDR,                                                           /*!< transmit frame buffer 1 address */
+    RXDESC_FRAME_LENGTH,                                                            /*!< the byte length of the received frame that was transferred to the buffer */
+    RXDESC_BUFFER_1_SIZE,                                                           /*!< receive buffer 1 size */
+    RXDESC_BUFFER_2_SIZE,                                                           /*!< receive buffer 2 size */
+    RXDESC_BUFFER_1_ADDR                                                            /*!< receive frame buffer 1 address */
+}enet_descstate_enum;
+
+/* MSC counters preset mode */
+typedef enum
+{
+    ENET_MSC_PRESET_NONE            = 0U,                                           /*!< do not preset MSC counter */
+    ENET_MSC_PRESET_HALF            = ENET_MSC_CTL_PMC,                             /*!< preset all MSC counters to almost-half(0x7FFF FFF0) value */
+    ENET_MSC_PRESET_FULL            = ENET_MSC_CTL_PMC | ENET_MSC_CTL_AFHPM         /*!< preset all MSC counters to almost-full(0xFFFF FFF0) value */
+}enet_msc_preset_enum;
+
+typedef enum{
+    ENET_CKNT_ORDINARY                = PTP_TSCTL_CKNT(0),                          /*!< type of ordinary clock node type for timestamp */
+    ENET_CKNT_BOUNDARY                = PTP_TSCTL_CKNT(1),                          /*!< type of boundary clock node type for timestamp */
+    ENET_CKNT_END_TO_END              = PTP_TSCTL_CKNT(2),                          /*!< type of end-to-end transparent clock node type for timestamp */
+    ENET_CKNT_PEER_TO_PEER            = PTP_TSCTL_CKNT(3),                          /*!< type of peer-to-peer transparent clock node type for timestamp */
+    ENET_PTP_SYSTIME_INIT             = ENET_PTP_TSCTL_TMSSTI,                      /*!< timestamp initialize */
+    ENET_PTP_SYSTIME_UPDATE           = ENET_PTP_TSCTL_TMSSTU,                      /*!< timestamp update */ 
+    ENET_PTP_ADDEND_UPDATE            = ENET_PTP_TSCTL_TMSARU,                      /*!< addend register update */
+    ENET_PTP_FINEMODE                 = (int32_t)(ENET_PTP_TSCTL_TMSFCU| BIT(31)),  /*!< the system timestamp uses the fine method for updating */
+    ENET_PTP_COARSEMODE               = ENET_PTP_TSCTL_TMSFCU,                      /*!< the system timestamp uses the coarse method for updating */
+    ENET_SUBSECOND_DIGITAL_ROLLOVER   = (int32_t)(ENET_PTP_TSCTL_SCROM | BIT(31)),  /*!< digital rollover mode */
+    ENET_SUBSECOND_BINARY_ROLLOVER    = ENET_PTP_TSCTL_SCROM,                       /*!< binary rollover mode */
+    ENET_SNOOPING_PTP_VERSION_2       = (int32_t)(ENET_PTP_TSCTL_PFSV| BIT(31)),    /*!< version 2 */
+    ENET_SNOOPING_PTP_VERSION_1       = ENET_PTP_TSCTL_PFSV,                        /*!< version 1 */
+    ENET_EVENT_TYPE_MESSAGES_SNAPSHOT = (int32_t)(ENET_PTP_TSCTL_ETMSEN| BIT(31)),  /*!< only event type messages are taken snapshot */
+    ENET_ALL_TYPE_MESSAGES_SNAPSHOT   = ENET_PTP_TSCTL_ETMSEN,                      /*!< all type messages are taken snapshot except announce, management and signaling message */
+    ENET_MASTER_NODE_MESSAGE_SNAPSHOT = (int32_t)(ENET_PTP_TSCTL_MNMSEN| BIT(31)),  /*!< snapshot is only take for master node message */
+    ENET_SLAVE_NODE_MESSAGE_SNAPSHOT  = ENET_PTP_TSCTL_MNMSEN,                      /*!< snapshot is only taken for slave node message */
+}enet_ptp_function_enum;
+
+/* structure for initialization of the ENET  */
+typedef struct
+{
+    uint32_t option_enable;                                                         /*!< select which function to configure */
+    uint32_t forward_frame;                                                         /*!< frame forward related parameters */ 
+    uint32_t dmabus_mode;                                                           /*!< DMA bus mode related parameters */
+    uint32_t dma_maxburst;                                                          /*!< DMA max burst related parameters */
+    uint32_t dma_arbitration;                                                       /*!< DMA Tx and Rx arbitration related parameters */
+    uint32_t store_forward_mode;                                                    /*!< store forward mode related parameters */
+    uint32_t dma_function;                                                          /*!< DMA control related parameters */
+    uint32_t vlan_config;                                                           /*!< VLAN tag related parameters */   
+    uint32_t flow_control;                                                          /*!< flow control related parameters */
+    uint32_t hashtable_high;                                                        /*!< hash list high 32-bit related parameters */
+    uint32_t hashtable_low;                                                         /*!< hash list low 32-bit related parameters */
+    uint32_t framesfilter_mode;                                                     /*!< frame filter control related parameters */
+    uint32_t halfduplex_param;                                                      /*!< halfduplex related parameters */            
+    uint32_t timer_config;                                                          /*!< frame timer related parameters */
+    uint32_t interframegap;                                                         /*!< inter frame gap related parameters */
+}enet_initpara_struct;
+
+/* structure for ENET DMA desciptors */ 
+typedef struct  
+{
+    uint32_t status;                                                                /*!< status */
+    uint32_t control_buffer_size;                                                   /*!< control and buffer1, buffer2 lengths */
+    uint32_t buffer1_addr;                                                          /*!< buffer1 address pointer/timestamp low */
+    uint32_t buffer2_next_desc_addr;                                                /*!< buffer2 or next descriptor address pointer/timestamp high */
+
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+    uint32_t extended_status;                                                       /*!< extended status */
+    uint32_t reserved;                                                              /*!< reserved */
+    uint32_t timestamp_low;                                                         /*!< timestamp low */
+    uint32_t timestamp_high;                                                        /*!< timestamp high */ 
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ 
+  
+} enet_descriptors_struct;
+
+/* structure of PTP system time */ 
+typedef struct
+{
+    uint32_t second;                                                                /*!< second of system time */
+    uint32_t subsecond;                                                             /*!< subsecond of system time */
+    uint32_t sign;                                                                  /*!< sign of system time */
+}enet_ptp_systime_struct;
+
+/* mac_cfg register value */
+#define MAC_CFG_BOL(regval)                       (BITS(5,6) & ((uint32_t)(regval) << 5))       /*!< write value to ENET_MAC_CFG_BOL bit field */
+#define ENET_BACKOFFLIMIT_10                      MAC_CFG_BOL(0)                                /*!< min (n, 10) */
+#define ENET_BACKOFFLIMIT_8                       MAC_CFG_BOL(1)                                /*!< min (n, 8) */
+#define ENET_BACKOFFLIMIT_4                       MAC_CFG_BOL(2)                                /*!< min (n, 4) */
+#define ENET_BACKOFFLIMIT_1                       MAC_CFG_BOL(3)                                /*!< min (n, 1) */ 
+
+#define MAC_CFG_IGBS(regval)                      (BITS(17,19) & ((uint32_t)(regval) << 17))    /*!< write value to ENET_MAC_CFG_IGBS bit field */
+#define ENET_INTERFRAMEGAP_96BIT                  MAC_CFG_IGBS(0)                               /*!< minimum 96 bit times */ 
+#define ENET_INTERFRAMEGAP_88BIT                  MAC_CFG_IGBS(1)                               /*!< minimum 88 bit times */
+#define ENET_INTERFRAMEGAP_80BIT                  MAC_CFG_IGBS(2)                               /*!< minimum 80 bit times */
+#define ENET_INTERFRAMEGAP_72BIT                  MAC_CFG_IGBS(3)                               /*!< minimum 72 bit times */
+#define ENET_INTERFRAMEGAP_64BIT                  MAC_CFG_IGBS(4)                               /*!< minimum 64 bit times */        
+#define ENET_INTERFRAMEGAP_56BIT                  MAC_CFG_IGBS(5)                               /*!< minimum 56 bit times */
+#define ENET_INTERFRAMEGAP_48BIT                  MAC_CFG_IGBS(6)                               /*!< minimum 48 bit times */
+#define ENET_INTERFRAMEGAP_40BIT                  MAC_CFG_IGBS(7)                               /*!< minimum 40 bit times */  
+
+#define ENET_TYPEFRAME_CRC_DROP_ENABLE            ENET_MAC_CFG_TFCD                             /*!< FCS field(last 4 bytes) of frame will be dropped before forwarding */
+#define ENET_TYPEFRAME_CRC_DROP_DISABLE           ((uint32_t)0x00000000U)                       /*!< FCS field(last 4 bytes) of frame will not be dropped before forwarding */
+#define ENET_TYPEFRAME_CRC_DROP                   ENET_MAC_CFG_TFCD                             /*!< the function that FCS field(last 4 bytes) of frame will be dropped before forwarding */
+
+#define ENET_WATCHDOG_ENABLE                      ((uint32_t)0x00000000U)                       /*!< the MAC allows no more than 2048 bytes of the frame being received */
+#define ENET_WATCHDOG_DISABLE                     ENET_MAC_CFG_WDD                              /*!< the MAC disables the watchdog timer on the receiver, and can receive frames of up to 16384 bytes */
+ 
+#define ENET_JABBER_ENABLE                        ((uint32_t)0x00000000U)                       /*!< the maximum transmission byte is 2048 */
+#define ENET_JABBER_DISABLE                       ENET_MAC_CFG_JBD                              /*!< the maximum transmission byte can be 16384 */
+
+#define ENET_CARRIERSENSE_ENABLE                  ((uint32_t)0x00000000U)                       /*!< the MAC transmitter generates carrier sense error and aborts the transmission */
+#define ENET_CARRIERSENSE_DISABLE                 ENET_MAC_CFG_CSD                              /*!< the MAC transmitter ignores the MII CRS signal during frame transmission in half-duplex mode */
+ 
+#define ENET_SPEEDMODE_10M                        ((uint32_t)0x00000000U)                       /*!< 10 Mbit/s */
+#define ENET_SPEEDMODE_100M                       ENET_MAC_CFG_SPD                              /*!< 100 Mbit/s */
+
+#define ENET_RECEIVEOWN_ENABLE                    ((uint32_t)0x00000000U)                       /*!< the MAC receives all packets that are given by the PHY while transmitting */
+#define ENET_RECEIVEOWN_DISABLE                   ENET_MAC_CFG_ROD                              /*!< the MAC disables the reception of frames in half-duplex mode */
+
+#define ENET_LOOPBACKMODE_ENABLE                  ENET_MAC_CFG_LBM                              /*!< the MAC operates in loopback mode at the MII */
+#define ENET_LOOPBACKMODE_DISABLE                 ((uint32_t)0x00000000U)                       /*!< the MAC operates in normal mode */
+
+#define ENET_MODE_FULLDUPLEX                      ENET_MAC_CFG_DPM                              /*!< full-duplex mode enable */
+#define ENET_MODE_HALFDUPLEX                      ((uint32_t)0x00000000U)                       /*!< half-duplex mode enable */
+
+#define ENET_CHECKSUMOFFLOAD_ENABLE               ENET_MAC_CFG_IPFCO                            /*!< IP frame checksum offload function enabled for received IP frame */
+#define ENET_CHECKSUMOFFLOAD_DISABLE              ((uint32_t)0x00000000U)                       /*!< the checksum offload function in the receiver is disabled */
+
+#define ENET_RETRYTRANSMISSION_ENABLE             ((uint32_t)0x00000000U)                       /*!< the MAC attempts retries up to 16 times based on the settings of BOL*/
+#define ENET_RETRYTRANSMISSION_DISABLE            ENET_MAC_CFG_RTD                              /*!< the MAC attempts only 1 transmission */
+
+#define ENET_AUTO_PADCRC_DROP_ENABLE              ENET_MAC_CFG_APCD                             /*!< the MAC strips the Pad/FCS field on received frames */
+#define ENET_AUTO_PADCRC_DROP_DISABLE             ((uint32_t)0x00000000U)                       /*!< the MAC forwards all received frames without modify it */
+#define ENET_AUTO_PADCRC_DROP                     ENET_MAC_CFG_APCD                             /*!< the function of the MAC strips the Pad/FCS field on received frames */
+
+#define ENET_DEFERRALCHECK_ENABLE                 ENET_MAC_CFG_DFC                              /*!< the deferral check function is enabled in the MAC */
+#define ENET_DEFERRALCHECK_DISABLE                ((uint32_t)0x00000000U)                       /*!< the deferral check function is disabled */
+
+/* mac_frmf register value */
+#define MAC_FRMF_PCFRM(regval)                    (BITS(6,7) & ((uint32_t)(regval) << 6))       /*!< write value to ENET_MAC_FRMF_PCFRM bit field */
+#define ENET_PCFRM_PREVENT_ALL                    MAC_FRMF_PCFRM(0)                             /*!< MAC prevents all control frames from reaching the application */
+#define ENET_PCFRM_PREVENT_PAUSEFRAME             MAC_FRMF_PCFRM(1)                             /*!< MAC only forwards all other control frames except pause control frame */
+#define ENET_PCFRM_FORWARD_ALL                    MAC_FRMF_PCFRM(2)                             /*!< MAC forwards all control frames to application even if they fail the address filter */
+#define ENET_PCFRM_FORWARD_FILTERED               MAC_FRMF_PCFRM(3)                             /*!< MAC forwards control frames that only pass the address filter */
+ 
+#define ENET_RX_FILTER_DISABLE                    ENET_MAC_FRMF_FAR                             /*!< all received frame are forwarded to application */
+#define ENET_RX_FILTER_ENABLE                     ((uint32_t)0x00000000U)                       /*!< only the frame passed the filter can be forwarded to application */
+ 
+#define ENET_SRC_FILTER_NORMAL_ENABLE             ENET_MAC_FRMF_SAFLT                           /*!< filter source address */
+#define ENET_SRC_FILTER_INVERSE_ENABLE            (ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT)  /*!< inverse source address filtering result */
+#define ENET_SRC_FILTER_DISABLE                   ((uint32_t)0x00000000U)                       /*!< source address function in filter disable */
+#define ENET_SRC_FILTER                           ENET_MAC_FRMF_SAFLT                           /*!< filter source address function */
+#define ENET_SRC_FILTER_INVERSE                   ENET_MAC_FRMF_SAIFLT                          /*!< inverse source address filtering result function */
+
+#define ENET_BROADCASTFRAMES_ENABLE               ((uint32_t)0x00000000U)                       /*!< the address filters pass all received broadcast frames */
+#define ENET_BROADCASTFRAMES_DISABLE              ENET_MAC_FRMF_BFRMD                           /*!< the address filters filter all incoming broadcast frames */
+ 
+#define ENET_DEST_FILTER_INVERSE_ENABLE           ENET_MAC_FRMF_DAIFLT                          /*!< inverse DA filtering result */
+#define ENET_DEST_FILTER_INVERSE_DISABLE          ((uint32_t)0x00000000U)                       /*!< not inverse DA filtering result */
+#define ENET_DEST_FILTER_INVERSE                  ENET_MAC_FRMF_DAIFLT                          /*!< inverse DA filtering result function */
+
+#define ENET_PROMISCUOUS_ENABLE                   ENET_MAC_FRMF_PM                              /*!< promiscuous mode enabled */
+#define ENET_PROMISCUOUS_DISABLE                  ((uint32_t)0x00000000U)                       /*!< promiscuous mode disabled */
+          
+#define ENET_MULTICAST_FILTER_HASH_OR_PERFECT     (ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT)     /*!< pass multicast frames that match either the perfect or the hash filtering */
+#define ENET_MULTICAST_FILTER_HASH                ENET_MAC_FRMF_HMF                             /*!< pass multicast frames that match the hash filtering */
+#define ENET_MULTICAST_FILTER_PERFECT             ((uint32_t)0x00000000U)                       /*!< pass multicast frames that match the perfect filtering */
+#define ENET_MULTICAST_FILTER_NONE                ENET_MAC_FRMF_MFD                             /*!< all multicast frames are passed */
+#define ENET_MULTICAST_FILTER_PASS                ENET_MAC_FRMF_MFD                             /*!< pass all multicast frames function */
+#define ENET_MULTICAST_FILTER_HASH_MODE           ENET_MAC_FRMF_HMF                             /*!< HASH multicast filter function */
+#define ENET_FILTER_MODE_EITHER                   ENET_MAC_FRMF_HPFLT                           /*!< HASH or perfect filter function */
+
+#define ENET_UNICAST_FILTER_EITHER                (ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_HPFLT)     /*!< pass unicast frames that match either the perfect or the hash filtering */
+#define ENET_UNICAST_FILTER_HASH                  ENET_MAC_FRMF_HUF                             /*!< pass unicast frames that match the hash filtering */
+#define ENET_UNICAST_FILTER_PERFECT               ((uint32_t)0x00000000U)                       /*!< pass unicast frames that match the perfect filtering */
+#define ENET_UNICAST_FILTER_HASH_MODE             ENET_MAC_FRMF_HUF                             /*!< HASH unicast filter function */
+
+/* mac_phy_ctl register value */
+#define MAC_PHY_CTL_CLR(regval)                   (BITS(2,4) & ((uint32_t)(regval) << 2))       /*!< write value to ENET_MAC_PHY_CTL_CLR bit field */
+#define ENET_MDC_HCLK_DIV42                       MAC_PHY_CTL_CLR(0)                            /*!< HCLK:60-100 MHz; MDC clock= HCLK/42 */
+#define ENET_MDC_HCLK_DIV62                       MAC_PHY_CTL_CLR(1)                            /*!< HCLK:100-150 MHz; MDC clock= HCLK/62 */
+#define ENET_MDC_HCLK_DIV16                       MAC_PHY_CTL_CLR(2)                            /*!< HCLK:20-35 MHz; MDC clock= HCLK/16 */
+#define ENET_MDC_HCLK_DIV26                       MAC_PHY_CTL_CLR(3)                            /*!< HCLK:35-60 MHz; MDC clock= HCLK/26 */
+#define ENET_MDC_HCLK_DIV102                      MAC_PHY_CTL_CLR(4)                            /*!< HCLK:150-200 MHz; MDC clock= HCLK/102 */
+
+#define MAC_PHY_CTL_PR(regval)                    (BITS(6,10) & ((uint32_t)(regval) << 6))      /*!< write value to ENET_MAC_PHY_CTL_PR bit field */
+
+#define MAC_PHY_CTL_PA(regval)                    (BITS(11,15) & ((uint32_t)(regval) << 11))    /*!< write value to ENET_MAC_PHY_CTL_PA bit field */
+
+/* mac_phy_data register value */
+#define MAC_PHY_DATA_PD(regval)                   (BITS(0,15) & ((uint32_t)(regval) << 0))      /*!< write value to ENET_MAC_PHY_DATA_PD bit field */
+
+/* mac_fctl register value */
+#define MAC_FCTL_PLTS(regval)                     (BITS(4,5) & ((uint32_t)(regval) << 4))       /*!< write value to ENET_MAC_FCTL_PLTS bit field */
+#define ENET_PAUSETIME_MINUS4                     MAC_FCTL_PLTS(0)                              /*!< pause time minus 4 slot times */
+#define ENET_PAUSETIME_MINUS28                    MAC_FCTL_PLTS(1)                              /*!< pause time minus 28 slot times */
+#define ENET_PAUSETIME_MINUS144                   MAC_FCTL_PLTS(2)                              /*!< pause time minus 144 slot times */
+#define ENET_PAUSETIME_MINUS256                   MAC_FCTL_PLTS(3)                              /*!< pause time minus 256 slot times */ 
+
+#define ENET_ZERO_QUANTA_PAUSE_ENABLE             ((uint32_t)0x00000000U)                       /*!< enable the automatic zero-quanta generation function */
+#define ENET_ZERO_QUANTA_PAUSE_DISABLE            ENET_MAC_FCTL_DZQP                            /*!< disable the automatic zero-quanta generation function */
+#define ENET_ZERO_QUANTA_PAUSE                    ENET_MAC_FCTL_DZQP                            /*!< the automatic zero-quanta generation function */
+
+#define ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT  ENET_MAC_FCTL_UPFDT                           /*!< besides the unique multicast address, MAC also use the MAC0 address to detect pause frame */
+#define ENET_UNIQUE_PAUSEDETECT                   ((uint32_t)0x00000000U)                       /*!< only the unique multicast address for pause frame which is specified in IEEE802.3 can be detected */
+ 
+#define ENET_RX_FLOWCONTROL_ENABLE                ENET_MAC_FCTL_RFCEN                           /*!< enable decoding function for the received pause frame and process it */
+#define ENET_RX_FLOWCONTROL_DISABLE               ((uint32_t)0x00000000U)                       /*!< decode function for pause frame is disabled */
+#define ENET_RX_FLOWCONTROL                       ENET_MAC_FCTL_RFCEN                           /*!< decoding function for the received pause frame and process it */
+
+#define ENET_TX_FLOWCONTROL_ENABLE                ENET_MAC_FCTL_TFCEN                           /*!< enable the flow control operation in the MAC */
+#define ENET_TX_FLOWCONTROL_DISABLE               ((uint32_t)0x00000000U)                       /*!< disable the flow control operation in the MAC */
+#define ENET_TX_FLOWCONTROL                       ENET_MAC_FCTL_TFCEN                           /*!< the flow control operation in the MAC */
+
+#define ENET_BACK_PRESSURE_ENABLE                 ENET_MAC_FCTL_FLCBBKPA                        /*!< enable the back pressure operation in the MAC */
+#define ENET_BACK_PRESSURE_DISABLE                ((uint32_t)0x00000000U)                       /*!< disable the back pressure operation in the MAC */
+#define ENET_BACK_PRESSURE                        ENET_MAC_FCTL_FLCBBKPA                        /*!< the back pressure operation in the MAC */
+                                                                                      
+#define MAC_FCTL_PTM(regval)                      (BITS(16,31) & ((uint32_t)(regval) << 16))    /*!< write value to ENET_MAC_FCTL_PTM bit field */
+/* mac_vlt register value */
+#define MAC_VLT_VLTI(regval)                      (BITS(0,15) & ((uint32_t)(regval) << 0))      /*!< write value to ENET_MAC_VLT_VLTI bit field */
+ 
+#define ENET_VLANTAGCOMPARISON_12BIT              ENET_MAC_VLT_VLTC                             /*!< only low 12 bits of the VLAN tag are used for comparison */
+#define ENET_VLANTAGCOMPARISON_16BIT              ((uint32_t)0x00000000U)                       /*!< all 16 bits of the VLAN tag are used for comparison */
+
+/* mac_wum register value */ 
+#define ENET_WUM_FLAG_WUFFRPR                     ENET_MAC_WUM_WUFFRPR                          /*!< wakeup frame filter register poniter reset */
+#define ENET_WUM_FLAG_WUFR                        ENET_MAC_WUM_WUFR                             /*!< wakeup frame received */
+#define ENET_WUM_FLAG_MPKR                        ENET_MAC_WUM_MPKR                             /*!< magic packet received */
+#define ENET_WUM_POWER_DOWN                       ENET_MAC_WUM_PWD                              /*!< power down mode */    
+#define ENET_WUM_MAGIC_PACKET_FRAME               ENET_MAC_WUM_MPEN                             /*!< enable a wakeup event due to magic packet reception */   
+#define ENET_WUM_WAKE_UP_FRAME                    ENET_MAC_WUM_WFEN                             /*!< enable a wakeup event due to wakeup frame reception */     
+#define ENET_WUM_GLOBAL_UNICAST                   ENET_MAC_WUM_GU                               /*!< any received unicast frame passed filter is considered to be a wakeup frame */
+/* mac_dbg register value */
+#define ENET_MAC_RECEIVER_NOT_IDLE                ENET_MAC_DBG_MRNI                             /*!< MAC receiver is not in idle state */
+#define ENET_RX_ASYNCHRONOUS_FIFO_STATE           ENET_MAC_DBG_RXAFS                            /*!< Rx asynchronous FIFO status */
+#define ENET_RXFIFO_NOT_WRITING                   ENET_MAC_DBG_RXFW                             /*!< RxFIFO is not doing write operation */
+#define ENET_RXFIFO_READ_STATUS                   ENET_MAC_DBG_RXFRS                            /*!< RxFIFO read operation status */
+#define ENET_RXFIFO_STATE                         ENET_MAC_DBG_RXFS                             /*!< RxFIFO state */
+#define ENET_MAC_TRANSMITTER_NOT_IDLE             ENET_MAC_DBG_MTNI                             /*!< MAC transmitter is not in idle state */
+#define ENET_MAC_TRANSMITTER_STATUS               ENET_MAC_DBG_SOMT                             /*!< status of MAC transmitter */
+#define ENET_PAUSE_CONDITION_STATUS               ENET_MAC_DBG_PCS                              /*!< pause condition status */
+#define ENET_TXFIFO_READ_STATUS                   ENET_MAC_DBG_TXFRS                            /*!< TxFIFO read operation status */
+#define ENET_TXFIFO_NOT_WRITING                   ENET_MAC_DBG_TXFW                             /*!< TxFIFO is not doing write operation */
+#define ENET_TXFIFO_NOT_EMPTY                     ENET_MAC_DBG_TXFNE                            /*!< TxFIFO is not empty */
+#define ENET_TXFIFO_FULL                          ENET_MAC_DBG_TXFF                             /*!< TxFIFO is full */
+
+#define GET_MAC_DBG_RXAFS(regval)                 GET_BITS((regval),1,2)                        /*!< get value of ENET_MAC_DBG_RXAFS bit field */
+
+#define GET_MAC_DBG_RXFRS(regval)                 GET_BITS((regval),5,6)                        /*!< get value of ENET_MAC_DBG_RXFRS bit field */
+
+#define GET_MAC_DBG_RXFS(regval)                  GET_BITS((regval),8,9)                        /*!< get value of ENET_MAC_DBG_RXFS bit field */
+
+#define GET_MAC_DBG_SOMT(regval)                  GET_BITS((regval),17,18)                      /*!< get value of ENET_MAC_DBG_SOMT bit field */
+
+#define GET_MAC_DBG_TXFRS(regval)                 GET_BITS((regval),20,21)                      /*!< get value of ENET_MAC_DBG_TXFRS bit field */
+
+/* mac_addr0h register value */
+#define MAC_ADDR0H_ADDR0H(regval)                 (BITS(0,15) & ((uint32_t)(regval) << 0))      /*!< write value to ENET_MAC_ADDR0H_ADDR0H bit field */
+
+/* mac_addrxh register value, x = 1,2,3 */
+#define MAC_ADDR123H_ADDR123H(regval)             (BITS(0,15) & ((uint32_t)(regval) << 0))      /*!< write value to ENET_MAC_ADDRxH_ADDRxH(x=1,2,3) bit field */
+
+#define ENET_ADDRESS_MASK_BYTE0                   BIT(24)                                       /*!< low register bits [7:0] */
+#define ENET_ADDRESS_MASK_BYTE1                   BIT(25)                                       /*!< low register bits [15:8] */
+#define ENET_ADDRESS_MASK_BYTE2                   BIT(26)                                       /*!< low register bits [23:16] */
+#define ENET_ADDRESS_MASK_BYTE3                   BIT(27)                                       /*!< low register bits [31:24] */
+#define ENET_ADDRESS_MASK_BYTE4                   BIT(28)                                       /*!< high register bits [7:0] */
+#define ENET_ADDRESS_MASK_BYTE5                   BIT(29)                                       /*!< high register bits [15:8] */
+
+#define ENET_ADDRESS_FILTER_SA                    BIT(30)                                       /*!< use MAC address[47:0] is to compare with the SA fields of the received frame */
+#define ENET_ADDRESS_FILTER_DA                    ((uint32_t)0x00000000)                        /*!< use MAC address[47:0] is to compare with the DA fields of the received frame */
+ 
+/* mac_fcth register value */
+#define MAC_FCTH_RFA(regval)                      ((BITS(0,2) & ((uint32_t)(regval) << 0))<<8)  /*!< write value to ENET_MAC_FCTH_RFA bit field */
+#define ENET_ACTIVE_THRESHOLD_256BYTES            MAC_FCTH_RFA(0)                               /*!< threshold level is 256 bytes */
+#define ENET_ACTIVE_THRESHOLD_512BYTES            MAC_FCTH_RFA(1)                               /*!< threshold level is 512 bytes */
+#define ENET_ACTIVE_THRESHOLD_768BYTES            MAC_FCTH_RFA(2)                               /*!< threshold level is 768 bytes */
+#define ENET_ACTIVE_THRESHOLD_1024BYTES           MAC_FCTH_RFA(3)                               /*!< threshold level is 1024 bytes */
+#define ENET_ACTIVE_THRESHOLD_1280BYTES           MAC_FCTH_RFA(4)                               /*!< threshold level is 1280 bytes */
+#define ENET_ACTIVE_THRESHOLD_1536BYTES           MAC_FCTH_RFA(5)                               /*!< threshold level is 1536 bytes */
+#define ENET_ACTIVE_THRESHOLD_1792BYTES           MAC_FCTH_RFA(6)                               /*!< threshold level is 1792 bytes */
+
+#define MAC_FCTH_RFD(regval)                      ((BITS(4,6) & ((uint32_t)(regval) << 4))<<8)  /*!< write value to ENET_MAC_FCTH_RFD bit field */
+#define ENET_DEACTIVE_THRESHOLD_256BYTES          MAC_FCTH_RFD(0)                               /*!< threshold level is 256 bytes */
+#define ENET_DEACTIVE_THRESHOLD_512BYTES          MAC_FCTH_RFD(1)                               /*!< threshold level is 512 bytes */
+#define ENET_DEACTIVE_THRESHOLD_768BYTES          MAC_FCTH_RFD(2)                               /*!< threshold level is 768 bytes */
+#define ENET_DEACTIVE_THRESHOLD_1024BYTES         MAC_FCTH_RFD(3)                               /*!< threshold level is 1024 bytes */
+#define ENET_DEACTIVE_THRESHOLD_1280BYTES         MAC_FCTH_RFD(4)                               /*!< threshold level is 1280 bytes */
+#define ENET_DEACTIVE_THRESHOLD_1536BYTES         MAC_FCTH_RFD(5)                               /*!< threshold level is 1536 bytes */
+#define ENET_DEACTIVE_THRESHOLD_1792BYTES         MAC_FCTH_RFD(6)                               /*!< threshold level is 1792 bytes */
+
+/* msc_ctl register value */
+#define ENET_MSC_COUNTER_STOP_ROLLOVER            ENET_MSC_CTL_CTSR                             /*!< counter stop rollover */
+#define ENET_MSC_RESET_ON_READ                    ENET_MSC_CTL_RTOR                             /*!< reset on read */
+#define ENET_MSC_COUNTERS_FREEZE                  ENET_MSC_CTL_MCFZ                             /*!< MSC counter freeze */
+
+/* ptp_tsctl register value */
+#define ENET_RXTX_TIMESTAMP                       ENET_PTP_TSCTL_TMSEN                          /*!< enable timestamp function for transmit and receive frames */
+#define ENET_PTP_TIMESTAMP_INT                    ENET_PTP_TSCTL_TMSITEN                        /*!< timestamp interrupt trigger enable */
+#define ENET_ALL_RX_TIMESTAMP                     ENET_PTP_TSCTL_ARFSEN                         /*!< all received frames are taken snapshot */
+#define ENET_NONTYPE_FRAME_SNAPSHOT               ENET_PTP_TSCTL_ESEN                           /*!< take snapshot when received non type frame */
+#define ENET_IPV6_FRAME_SNAPSHOT                  ENET_PTP_TSCTL_IP6SEN                         /*!< take snapshot for IPv6 frame */
+#define ENET_IPV4_FRAME_SNAPSHOT                  ENET_PTP_TSCTL_IP4SEN                         /*!< take snapshot for IPv4 frame */
+#define ENET_PTP_FRAME_USE_MACADDRESS_FILTER      ENET_PTP_TSCTL_MAFEN                          /*!< enable MAC address1-3 to filter the PTP frame */
+
+/* ptp_ssinc register value */
+#define PTP_SSINC_STMSSI(regval)                  (BITS(0,7) & ((uint32_t)(regval) << 0))       /*!< write value to ENET_PTP_SSINC_STMSSI bit field */
+
+/* ptp_tsl register value */
+#define GET_PTP_TSL_STMSS(regval)                 GET_BITS((uint32_t)(regval),0,30)             /*!< get value of ENET_PTP_TSL_STMSS bit field */
+ 
+#define ENET_PTP_TIME_POSITIVE                    ((uint32_t)0x00000000)                        /*!< time value is positive */
+#define ENET_PTP_TIME_NEGATIVE                    ENET_PTP_TSL_STS                              /*!< time value is negative */
+
+#define GET_PTP_TSL_STS(regval)                   (((regval) & BIT(31)) >> (31U))               /*!< get value of ENET_PTP_TSL_STS bit field */
+
+/* ptp_tsul register value */
+#define PTP_TSUL_TMSUSS(regval)                   (BITS(0,30) & ((uint32_t)(regval) << 0))      /*!< write value to ENET_PTP_TSUL_TMSUSS bit field */
+
+#define ENET_PTP_ADD_TO_TIME                      ((uint32_t)0x00000000)                        /*!< timestamp update value is added to system time */
+#define ENET_PTP_SUBSTRACT_FROM_TIME              ENET_PTP_TSUL_TMSUPNS                         /*!< timestamp update value is subtracted from system time */
+
+/* ptp_ppsctl register value */
+#define PTP_PPSCTL_PPSOFC(regval)                 (BITS(0,3) & ((uint32_t)(regval) << 0))       /*!< write value to ENET_PTP_PPSCTL_PPSOFC bit field */
+#define ENET_PPSOFC_1HZ                           PTP_PPSCTL_PPSOFC(0)                          /*!< PPS output 1Hz frequency */
+#define ENET_PPSOFC_2HZ                           PTP_PPSCTL_PPSOFC(1)                          /*!< PPS output 2Hz frequency */
+#define ENET_PPSOFC_4HZ                           PTP_PPSCTL_PPSOFC(2)                          /*!< PPS output 4Hz frequency */
+#define ENET_PPSOFC_8HZ                           PTP_PPSCTL_PPSOFC(3)                          /*!< PPS output 8Hz frequency */
+#define ENET_PPSOFC_16HZ                          PTP_PPSCTL_PPSOFC(4)                          /*!< PPS output 16Hz frequency */
+#define ENET_PPSOFC_32HZ                          PTP_PPSCTL_PPSOFC(5)                          /*!< PPS output 32Hz frequency */
+#define ENET_PPSOFC_64HZ                          PTP_PPSCTL_PPSOFC(6)                          /*!< PPS output 64Hz frequency */
+#define ENET_PPSOFC_128HZ                         PTP_PPSCTL_PPSOFC(7)                          /*!< PPS output 128Hz frequency */
+#define ENET_PPSOFC_256HZ                         PTP_PPSCTL_PPSOFC(8)                          /*!< PPS output 256Hz frequency */
+#define ENET_PPSOFC_512HZ                         PTP_PPSCTL_PPSOFC(9)                          /*!< PPS output 512Hz frequency */
+#define ENET_PPSOFC_1024HZ                        PTP_PPSCTL_PPSOFC(10)                         /*!< PPS output 1024Hz frequency */
+#define ENET_PPSOFC_2048HZ                        PTP_PPSCTL_PPSOFC(11)                         /*!< PPS output 2048Hz frequency */
+#define ENET_PPSOFC_4096HZ                        PTP_PPSCTL_PPSOFC(12)                         /*!< PPS output 4096Hz frequency */
+#define ENET_PPSOFC_8192HZ                        PTP_PPSCTL_PPSOFC(13)                         /*!< PPS output 8192Hz frequency */
+#define ENET_PPSOFC_16384HZ                       PTP_PPSCTL_PPSOFC(14)                         /*!< PPS output 16384Hz frequency */
+#define ENET_PPSOFC_32768HZ                       PTP_PPSCTL_PPSOFC(15)                         /*!< PPS output 32768Hz frequency */
+
+/* dma_bctl register value */
+#define DMA_BCTL_DPSL(regval)                     (BITS(2,6) & ((uint32_t)(regval) << 2))       /*!< write value to ENET_DMA_BCTL_DPSL bit field */
+#define GET_DMA_BCTL_DPSL(regval)                 GET_BITS((regval),2,6)                        /*!< get value of ENET_DMA_BCTL_DPSL bit field */
+
+#define ENET_ENHANCED_DESCRIPTOR                  ENET_DMA_BCTL_DFM                             /*!< enhanced mode descriptor */
+#define ENET_NORMAL_DESCRIPTOR                    ((uint32_t)0x00000000)                        /*!< normal mode descriptor */
+
+#define DMA_BCTL_PGBL(regval)                     (BITS(8,13) & ((uint32_t)(regval) << 8))      /*!< write value to ENET_DMA_BCTL_PGBL bit field */
+#define ENET_PGBL_1BEAT                           DMA_BCTL_PGBL(1)                              /*!< maximum number of beats is 1 */
+#define ENET_PGBL_2BEAT                           DMA_BCTL_PGBL(2)                              /*!< maximum number of beats is 2 */
+#define ENET_PGBL_4BEAT                           DMA_BCTL_PGBL(4)                              /*!< maximum number of beats is 4 */
+#define ENET_PGBL_8BEAT                           DMA_BCTL_PGBL(8)                              /*!< maximum number of beats is 8 */
+#define ENET_PGBL_16BEAT                          DMA_BCTL_PGBL(16)                             /*!< maximum number of beats is 16 */
+#define ENET_PGBL_32BEAT                          DMA_BCTL_PGBL(32)                             /*!< maximum number of beats is 32 */                
+#define ENET_PGBL_4xPGBL_4BEAT                    (DMA_BCTL_PGBL(1)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats is 4 */
+#define ENET_PGBL_4xPGBL_8BEAT                    (DMA_BCTL_PGBL(2)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats is 8 */
+#define ENET_PGBL_4xPGBL_16BEAT                   (DMA_BCTL_PGBL(4)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats is 16 */
+#define ENET_PGBL_4xPGBL_32BEAT                   (DMA_BCTL_PGBL(8)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats is 32 */
+#define ENET_PGBL_4xPGBL_64BEAT                   (DMA_BCTL_PGBL(16)|ENET_DMA_BCTL_FPBL)        /*!< maximum number of beats is 64 */
+#define ENET_PGBL_4xPGBL_128BEAT                  (DMA_BCTL_PGBL(32)|ENET_DMA_BCTL_FPBL)        /*!< maximum number of beats is 128 */
+
+#define DMA_BCTL_RTPR(regval)                     (BITS(14,15) & ((uint32_t)(regval) << 14))    /*!< write value to ENET_DMA_BCTL_RTPR bit field */
+#define ENET_ARBITRATION_RXTX_1_1                 DMA_BCTL_RTPR(0)                              /*!< receive and transmit priority ratio is 1:1*/
+#define ENET_ARBITRATION_RXTX_2_1                 DMA_BCTL_RTPR(1)                              /*!< receive and transmit priority ratio is 2:1*/
+#define ENET_ARBITRATION_RXTX_3_1                 DMA_BCTL_RTPR(2)                              /*!< receive and transmit priority ratio is 3:1 */
+#define ENET_ARBITRATION_RXTX_4_1                 DMA_BCTL_RTPR(3)                              /*!< receive and transmit priority ratio is 4:1 */  
+#define ENET_ARBITRATION_RXPRIORTX                ENET_DMA_BCTL_DAB                             /*!< RxDMA has higher priority than TxDMA */
+
+#define ENET_FIXED_BURST_ENABLE                   ENET_DMA_BCTL_FB                              /*!< AHB can only use SINGLE/INCR4/INCR8/INCR16 during start of normal burst transfers */
+#define ENET_FIXED_BURST_DISABLE                  ((uint32_t)0x00000000)                        /*!< AHB can use SINGLE/INCR burst transfer operations */
+
+#define DMA_BCTL_RXDP(regval)                     (BITS(17,22) & ((uint32_t)(regval) << 17))    /*!< write value to ENET_DMA_BCTL_RXDP bit field */
+#define ENET_RXDP_1BEAT                           DMA_BCTL_RXDP(1)                              /*!< maximum number of beats 1 */
+#define ENET_RXDP_2BEAT                           DMA_BCTL_RXDP(2)                              /*!< maximum number of beats 2 */
+#define ENET_RXDP_4BEAT                           DMA_BCTL_RXDP(4)                              /*!< maximum number of beats 4 */
+#define ENET_RXDP_8BEAT                           DMA_BCTL_RXDP(8)                              /*!< maximum number of beats 8 */
+#define ENET_RXDP_16BEAT                          DMA_BCTL_RXDP(16)                             /*!< maximum number of beats 16 */
+#define ENET_RXDP_32BEAT                          DMA_BCTL_RXDP(32)                             /*!< maximum number of beats 32 */                
+#define ENET_RXDP_4xPGBL_4BEAT                    (DMA_BCTL_RXDP(1)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats 4 */
+#define ENET_RXDP_4xPGBL_8BEAT                    (DMA_BCTL_RXDP(2)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats 8 */
+#define ENET_RXDP_4xPGBL_16BEAT                   (DMA_BCTL_RXDP(4)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats 16 */
+#define ENET_RXDP_4xPGBL_32BEAT                   (DMA_BCTL_RXDP(8)|ENET_DMA_BCTL_FPBL)         /*!< maximum number of beats 32 */
+#define ENET_RXDP_4xPGBL_64BEAT                   (DMA_BCTL_RXDP(16)|ENET_DMA_BCTL_FPBL)        /*!< maximum number of beats 64 */
+#define ENET_RXDP_4xPGBL_128BEAT                  (DMA_BCTL_RXDP(32)|ENET_DMA_BCTL_FPBL)        /*!< maximum number of beats 128 */  
+
+#define ENET_RXTX_DIFFERENT_PGBL                  ENET_DMA_BCTL_UIP                             /*!< RxDMA uses the RXDP[5:0], while TxDMA uses the PGBL[5:0] */
+#define ENET_RXTX_SAME_PGBL                       ((uint32_t)0x00000000)                        /*!< RxDMA/TxDMA uses PGBL[5:0] */
+
+#define ENET_ADDRESS_ALIGN_ENABLE                 ENET_DMA_BCTL_AA                              /*!< enabled address-aligned */
+#define ENET_ADDRESS_ALIGN_DISABLE                ((uint32_t)0x00000000)                        /*!< disable address-aligned */
+
+#define ENET_MIXED_BURST_ENABLE                   ENET_DMA_BCTL_MB                              /*!< AHB master interface transfer burst length greater than 16 with INCR */
+#define ENET_MIXED_BURST_DISABLE                  ((uint32_t)0x00000000)                        /*!< AHB master interface only transfer fixed burst length with 16 and below */
+
+/* dma_stat register value */
+#define GET_DMA_STAT_RP(regval)                   GET_BITS((uint32_t)(regval),17,19)            /*!< get value of ENET_DMA_STAT_RP bit field */
+#define ENET_RX_STATE_STOPPED                     ((uint32_t)0x00000000)                        /*!< reset or stop rx command issued */
+#define ENET_RX_STATE_FETCHING                    BIT(17)                                       /*!< fetching the Rx descriptor */
+#define ENET_RX_STATE_WAITING                     (BIT(17)|BIT(18))                             /*!< waiting for receive packet */
+#define ENET_RX_STATE_SUSPENDED                   BIT(19)                                       /*!< Rx descriptor unavailable */
+#define ENET_RX_STATE_CLOSING                     (BIT(17)|BIT(19))                             /*!< closing receive descriptor */
+#define ENET_RX_STATE_QUEUING                     ENET_DMA_STAT_RP                              /*!< transferring the receive packet data from recevie buffer to host memory */
+
+#define GET_DMA_STAT_TP(regval)                   GET_BITS((uint32_t)(regval),20,22)            /*!< get value of ENET_DMA_STAT_TP bit field */
+#define ENET_TX_STATE_STOPPED                     ((uint32_t)0x00000000)                        /*!< reset or stop Tx Command issued  */
+#define ENET_TX_STATE_FETCHING                    BIT(20)                                       /*!< fetching the Tx descriptor */
+#define ENET_TX_STATE_WAITING                     BIT(21)                                       /*!< waiting for status */
+#define ENET_TX_STATE_READING                     (BIT(20)|BIT(21))                             /*!< reading the data from host memory buffer and queuing it to transmit buffer */
+#define ENET_TX_STATE_SUSPENDED                   (BIT(21)|BIT(22))                             /*!< Tx descriptor unavailabe or transmit buffer underflow */
+#define ENET_TX_STATE_CLOSING                     ENET_DMA_STAT_TP                              /*!< closing Tx descriptor */
+
+#define GET_DMA_STAT_EB(regval)                   GET_BITS((uint32_t)(regval),23,25)            /*!< get value of ENET_DMA_STAT_EB bit field */
+#define ENET_ERROR_TXDATA_TRANSFER                BIT(23)                                       /*!< error during data transfer by TxDMA or RxDMA */
+#define ENET_ERROR_READ_TRANSFER                  BIT(24)                                       /*!< error during write transfer or read transfer */
+#define ENET_ERROR_DESC_ACCESS                    BIT(25)                                       /*!< error during descriptor or buffer access */
+
+/* dma_ctl register value */
+#define DMA_CTL_RTHC(regval)                      (BITS(3,4) & ((uint32_t)(regval) << 3))       /*!< write value to ENET_DMA_CTL_RTHC bit field */
+#define ENET_RX_THRESHOLD_64BYTES                 DMA_CTL_RTHC(0)                               /*!< threshold level is 64 Bytes */
+#define ENET_RX_THRESHOLD_32BYTES                 DMA_CTL_RTHC(1)                               /*!< threshold level is 32 Bytes */
+#define ENET_RX_THRESHOLD_96BYTES                 DMA_CTL_RTHC(2)                               /*!< threshold level is 96 Bytes */
+#define ENET_RX_THRESHOLD_128BYTES                DMA_CTL_RTHC(3)                               /*!< threshold level is 128 Bytes */
+
+#define DMA_CTL_TTHC(regval)                      (BITS(14,16) & ((uint32_t)(regval) << 14))    /*!< write value to ENET_DMA_CTL_TTHC bit field */
+#define ENET_TX_THRESHOLD_64BYTES                 DMA_CTL_TTHC(0)                               /*!< threshold level is 64 Bytes */
+#define ENET_TX_THRESHOLD_128BYTES                DMA_CTL_TTHC(1)                               /*!< threshold level is 128 Bytes */
+#define ENET_TX_THRESHOLD_192BYTES                DMA_CTL_TTHC(2)                               /*!< threshold level is 192 Bytes */
+#define ENET_TX_THRESHOLD_256BYTES                DMA_CTL_TTHC(3)                               /*!< threshold level is 256 Bytes */
+#define ENET_TX_THRESHOLD_40BYTES                 DMA_CTL_TTHC(4)                               /*!< threshold level is 40 Bytes */
+#define ENET_TX_THRESHOLD_32BYTES                 DMA_CTL_TTHC(5)                               /*!< threshold level is 32 Bytes */
+#define ENET_TX_THRESHOLD_24BYTES                 DMA_CTL_TTHC(6)                               /*!< threshold level is 24 Bytes */
+#define ENET_TX_THRESHOLD_16BYTES                 DMA_CTL_TTHC(7)                               /*!< threshold level is 16 Bytes */
+
+#define ENET_TCPIP_CKSUMERROR_ACCEPT              ENET_DMA_CTL_DTCERFD                          /*!< Rx frame with only payload error but no other errors will not be dropped */
+#define ENET_TCPIP_CKSUMERROR_DROP                ((uint32_t)0x00000000)                        /*!< all error frames will be dropped when FERF = 0 */
+
+#define ENET_RX_MODE_STOREFORWARD                 ENET_DMA_CTL_RSFD                             /*!< RxFIFO operates in store-and-forward mode */
+#define ENET_RX_MODE_CUTTHROUGH                   ((uint32_t)0x00000000)                        /*!< RxFIFO operates in cut-through mode */
+
+#define ENET_FLUSH_RXFRAME_ENABLE                 ((uint32_t)0x00000000)                        /*!< RxDMA flushes all frames */
+#define ENET_FLUSH_RXFRAME_DISABLE                ENET_DMA_CTL_DAFRF                            /*!< RxDMA does not flush any frames */
+#define ENET_FLUSH_RXFRAME                        ENET_DMA_CTL_DAFRF                            /*!< RxDMA flushes frames function */
+
+#define ENET_TX_MODE_STOREFORWARD                 ENET_DMA_CTL_TSFD                             /*!< TxFIFO operates in store-and-forward mode */
+#define ENET_TX_MODE_CUTTHROUGH                   ((uint32_t)0x00000000)                        /*!< TxFIFO operates in cut-through mode */
+
+#define ENET_FORWARD_ERRFRAMES_ENABLE             (ENET_DMA_CTL_FERF<<2)                        /*!< all frame received with error except runt error are forwarded to memory */
+#define ENET_FORWARD_ERRFRAMES_DISABLE            ((uint32_t)0x00000000)                        /*!< RxFIFO drop error frame */
+#define ENET_FORWARD_ERRFRAMES                    (ENET_DMA_CTL_FERF<<2)                             /*!< the function that all frame received with error except runt error are forwarded to memory */
+
+#define ENET_FORWARD_UNDERSZ_GOODFRAMES_ENABLE    (ENET_DMA_CTL_FUF<<2)                         /*!< forward undersized good frames */
+#define ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE   ((uint32_t)0x00000000)                        /*!< RxFIFO drops all frames whose length is less than 64 bytes */  
+#define ENET_FORWARD_UNDERSZ_GOODFRAMES           (ENET_DMA_CTL_FUF<<2)                            /*!< the function that forwarding undersized good frames */
+
+#define ENET_SECONDFRAME_OPT_ENABLE               ENET_DMA_CTL_OSF                              /*!< TxDMA controller operate on second frame mode enable*/
+#define ENET_SECONDFRAME_OPT_DISABLE              ((uint32_t)0x00000000)                        /*!< TxDMA controller operate on second frame mode disable */
+#define ENET_SECONDFRAME_OPT                      ENET_DMA_CTL_OSF                              /*!< TxDMA controller operate on second frame function */
+/* dma_mfbocnt register value */
+#define GET_DMA_MFBOCNT_MSFC(regval)              GET_BITS((regval),0,15)                       /*!< get value of ENET_DMA_MFBOCNT_MSFC bit field */
+
+#define GET_DMA_MFBOCNT_MSFA(regval)              GET_BITS((regval),17,27)                      /*!< get value of ENET_DMA_MFBOCNT_MSFA bit field */
+
+/* dma_rswdc register value */
+#define DMA_RSWDC_WDCFRS(regval)                  (BITS(0,7) & ((uint32_t)(regval) << 0))       /*!< write value to ENET_DMA_RSWDC_WDCFRS bit field */
+
+/* dma tx descriptor tdes0 register value */
+#define TDES0_CONT(regval)                        (BITS(3,6) & ((uint32_t)(regval) << 3))       /*!< write value to ENET DMA TDES0 CONT bit field */
+#define GET_TDES0_COCNT(regval)                   GET_BITS((regval),3,6)                        /*!< get value of ENET DMA TDES0 CONT bit field */
+
+#define TDES0_CM(regval)                          (BITS(22,23) & ((uint32_t)(regval) << 22))    /*!< write value to ENET DMA TDES0 CM bit field */
+#define ENET_CHECKSUM_DISABLE                     TDES0_CM(0)                                   /*!< checksum insertion disabled */ 
+#define ENET_CHECKSUM_IPV4HEADER                  TDES0_CM(1)                                   /*!< only IP header checksum calculation and insertion are enabled */ 
+#define ENET_CHECKSUM_TCPUDPICMP_SEGMENT          TDES0_CM(2)                                   /*!< TCP/UDP/ICMP checksum insertion calculated but pseudo-header  */ 
+#define ENET_CHECKSUM_TCPUDPICMP_FULL             TDES0_CM(3)                                   /*!< TCP/UDP/ICMP checksum insertion fully calculated */ 
+
+/* dma tx descriptor tdes1 register value */
+#define TDES1_TB1S(regval)                        (BITS(0,12) & ((uint32_t)(regval) << 0))      /*!< write value to ENET DMA TDES1 TB1S bit field */
+
+#define TDES1_TB2S(regval)                        (BITS(16,28) & ((uint32_t)(regval) << 16))    /*!< write value to ENET DMA TDES1 TB2S bit field */
+
+/* dma rx descriptor rdes0 register value */
+#define RDES0_FRML(regval)                        (BITS(16,29) & ((uint32_t)(regval) << 16))    /*!< write value to ENET DMA RDES0 FRML bit field */
+#define GET_RDES0_FRML(regval)                    GET_BITS((regval),16,29)                      /*!< get value of ENET DMA RDES0 FRML bit field */
+
+/* dma rx descriptor rdes1 register value */
+#define ENET_RECEIVE_COMPLETE_INT_ENABLE          ((uint32_t)0x00000000U)                       /*!< RS bit immediately set after Rx completed */
+#define ENET_RECEIVE_COMPLETE_INT_DISABLE         ENET_RDES1_DINTC                              /*!< RS bit not immediately set after Rx completed */
+
+#define GET_RDES1_RB1S(regval)                    GET_BITS((regval),0,12)                       /*!< get value of ENET DMA RDES1 RB1S bit field */
+
+#define GET_RDES1_RB2S(regval)                    GET_BITS((regval),16,28)                      /*!< get value of ENET DMA RDES1 RB2S bit field */
+
+/* dma rx descriptor rdes4 register value */
+#define RDES4_IPPLDT(regval)                      (BITS(0,2) & ((uint32_t)(regval) << 0))       /*!< write value to ENET DMA RDES4 IPPLDT bit field */
+#define GET_RDES4_IPPLDT(regval)                  GET_BITS((regval),0,2)                        /*!< get value of ENET DMA RDES4 IPPLDT bit field */
+
+#define RDES4_PTPMT(regval)                       (BITS(8,11) & ((uint32_t)(regval) << 8))      /*!< write value to ENET DMA RDES4 PTPMT bit field */
+#define GET_RDES4_PTPMT(regval)                   GET_BITS((regval),8,11)                       /*!< get value of ENET DMA RDES4 PTPMT bit field */
+
+/* ENET register mask value */
+#define MAC_CFG_MASK                              ((uint32_t)0xFD30810FU)                       /*!< ENET_MAC_CFG register mask */
+#define MAC_FCTL_MASK                             ((uint32_t)0x0000FF41U)                       /*!< ENET_MAC_FCTL register mask */
+#define DMA_CTL_MASK                              ((uint32_t)0xF8DE3F23U)                       /*!< ENET_DMA_CTL register mask */
+#define DMA_BCTL_MASK                             ((uint32_t)0xF800007DU)                       /*!< ENET_DMA_BCTL register mask */
+#define ENET_MSC_PRESET_MASK                      (~(ENET_MSC_CTL_PMC | ENET_MSC_CTL_AFHPM))    /*!< ENET_MSC_CTL preset mask */
+
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+#define ETH_DMATXDESC_SIZE                        0x20U                                         /*!< TxDMA enhanced descriptor size */
+#define ETH_DMARXDESC_SIZE                        0x20U                                         /*!< RxDMA enhanced descriptor size */
+#else
+#define ETH_DMATXDESC_SIZE                        0x10U                                         /*!< TxDMA descriptor size */
+#define ETH_DMARXDESC_SIZE                        0x10U                                         /*!< RxDMA descriptor size */
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ 
+
+/* ENET remote wake-up frame register length */
+#define ETH_WAKEUP_REGISTER_LENGTH                8U                                            /*!< remote wake-up frame register length */
+
+/* ENET frame size */ 
+#define ENET_MAX_FRAME_SIZE                       1524U                                         /*!< header + frame_extra + payload + CRC */    
+
+/* ENET delay timeout */
+#define ENET_DELAY_TO                             ((uint32_t)0x0004FFFFU)                       /*!< ENET delay timeout */
+#define ENET_RESET_TO                             ((uint32_t)0x000004FFU)                       /*!< ENET reset timeout */
+
+
+
+/* function declarations */
+/* main function */
+/* deinitialize the ENET, and reset structure parameters for ENET initialization */
+void enet_deinit(void);
+/* configure the parameters which are usually less cared for initialization */
+void enet_initpara_config(enet_option_enum option, uint32_t para);
+/* initialize ENET peripheral with generally concerned parameters and the less cared parameters */
+ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept);
+/* reset all core internal registers located in CLK_TX and CLK_RX */
+ErrStatus enet_software_reset(void);
+/* check receive frame valid and return frame size */
+uint32_t enet_rxframe_size_get(void);
+/* initialize the dma tx/rx descriptors's parameters in chain mode */
+void enet_descriptors_chain_init(enet_dmadirection_enum direction);
+/* initialize the dma tx/rx descriptors's parameters in ring mode */
+void enet_descriptors_ring_init(enet_dmadirection_enum direction);
+/* handle current received frame data to application buffer */
+ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize);
+/* handle current received frame but without data copy to application buffer */
+#define ENET_NOCOPY_FRAME_RECEIVE()         enet_frame_receive(NULL, 0U)
+/* handle application buffer data to transmit it */
+ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length);
+/* handle current transmit frame but without data copy from application buffer */
+#define ENET_NOCOPY_FRAME_TRANSMIT(len)     enet_frame_transmit(NULL, (len))
+/* configure the transmit IP frame checksum offload calculation and insertion */
+void enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum);
+/* ENET Tx and Rx function enable (include MAC and DMA module) */
+void enet_enable(void);   
+/* ENET Tx and Rx function disable (include MAC and DMA module) */
+void enet_disable(void);
+/* configure MAC address */
+void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]);
+/* get MAC address */   
+void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]);
+
+/* get the ENET MAC/MSC/PTP/DMA status flag */
+FlagStatus enet_flag_get(enet_flag_enum enet_flag);
+/* clear the ENET DMA status flag */
+void enet_flag_clear(enet_flag_clear_enum enet_flag);
+/* enable ENET MAC/MSC/DMA interrupt */
+void enet_interrupt_enable(enet_int_enum enet_int);
+/* disable ENET MAC/MSC/DMA interrupt */
+void enet_interrupt_disable(enet_int_enum enet_int);
+/* get ENET MAC/MSC/DMA interrupt flag */
+FlagStatus enet_interrupt_flag_get(enet_int_flag_enum int_flag);
+/* clear ENET DMA interrupt flag */
+void enet_interrupt_flag_clear(enet_int_flag_clear_enum int_flag_clear);
+
+/* MAC function */
+/* ENET Tx function enable (include MAC and DMA module) */
+void enet_tx_enable(void);
+/* ENET Tx function disable (include MAC and DMA module) */
+void enet_tx_disable(void);
+/* ENET Rx function enable (include MAC and DMA module) */
+void enet_rx_enable(void);
+/* ENET Rx function disable (include MAC and DMA module) */
+void enet_rx_disable(void);
+/* put registers value into the application buffer */
+void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t num);
+/* get the enet debug status from the debug register */
+uint32_t enet_debug_status_get(uint32_t mac_debug);
+/* enable the MAC address filter */
+void enet_address_filter_enable(enet_macaddress_enum mac_addr);
+/* disable the MAC address filter */
+void enet_address_filter_disable(enet_macaddress_enum mac_addr);
+/* configure the MAC address filter */
+void enet_address_filter_config(enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type);
+/* PHY interface configuration (configure SMI clock and reset PHY chip) */
+ErrStatus enet_phy_config(void);
+/* write to/read from a PHY register */
+ErrStatus enet_phy_write_read(enet_phydirection_enum direction, uint16_t phy_address, uint16_t phy_reg, uint16_t *pvalue);
+/* enable the loopback function of phy chip */
+ErrStatus enet_phyloopback_enable(void);
+/* disable the loopback function of phy chip */
+ErrStatus enet_phyloopback_disable(void);
+/* enable ENET forward feature */
+void enet_forward_feature_enable(uint32_t feature);
+/* disable ENET forward feature */
+void enet_forward_feature_disable(uint32_t feature);
+/* enable ENET fliter feature */
+void enet_fliter_feature_enable(uint32_t feature);
+/* disable ENET fliter feature */
+void enet_fliter_feature_disable(uint32_t feature);
+
+/* flow control function */
+/* generate the pause frame, ENET will send pause frame after enable transmit flow control */
+ErrStatus enet_pauseframe_generate(void);
+/* configure the pause frame detect type */
+void enet_pauseframe_detect_config(uint32_t detect);
+/* configure the pause frame parameters */
+void enet_pauseframe_config(uint32_t pausetime, uint32_t pause_threshold);
+/* configure the threshold of the flow control(deactive and active threshold) */
+void enet_flowcontrol_threshold_config(uint32_t deactive, uint32_t active);
+/* enable ENET flow control feature */
+void enet_flowcontrol_feature_enable(uint32_t feature);
+/* disable ENET flow control feature */
+void enet_flowcontrol_feature_disable(uint32_t feature);
+
+/* DMA function */
+/* get the dma transmit/receive process state */
+uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction); 
+/* poll the dma transmission/reception enable */
+void enet_dmaprocess_resume(enet_dmadirection_enum direction);
+/* check and recover the Rx process */
+void enet_rxprocess_check_recovery(void);
+/* flush the ENET transmit fifo, and wait until the flush operation completes */
+ErrStatus enet_txfifo_flush(void);
+/* get the transmit/receive address of current descriptor, or current buffer, or descriptor table */
+uint32_t enet_current_desc_address_get(enet_desc_reg_enum addr_get);
+/* get the Tx or Rx descriptor information */
+uint32_t enet_desc_information_get(enet_descriptors_struct *desc, enet_descstate_enum info_get);
+/* get the number of missed frames during receiving */
+void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop);
+
+/* descriptor function */
+/* get the bit flag of ENET dma descriptor */
+FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag);
+/* set the bit flag of ENET dma tx descriptor */
+void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag);
+/* clear the bit flag of ENET dma tx descriptor */
+void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag); 
+/* when receiving the completed, set RS bit in ENET_DMA_STAT register will immediately set */
+void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct *desc);
+/* when receiving the completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time */
+void enet_rx_desc_delay_receive_complete_interrupt(enet_descriptors_struct *desc, uint32_t delay_time);
+/* drop current receive frame */
+void enet_rxframe_drop(void);
+/* enable DMA feature */
+void enet_dma_feature_enable(uint32_t feature);
+/* disable DMA feature */
+void enet_dma_feature_disable(uint32_t feature);
+
+
+/* special enhanced mode function */
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+/* get the bit of extended status flag in ENET DMA descriptor */
+uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status);
+/* configure descriptor to work in enhanced mode */
+void enet_desc_select_enhanced_mode(void);
+/* initialize the dma Tx/Rx descriptors's parameters in enhanced chain mode with ptp function */
+void enet_ptp_enhanced_descriptors_chain_init(enet_dmadirection_enum direction);
+/* initialize the dma Tx/Rx descriptors's parameters in enhanced ring mode with ptp function */
+void enet_ptp_enhanced_descriptors_ring_init(enet_dmadirection_enum direction);
+/* receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode */
+ErrStatus enet_ptpframe_receive_enhanced_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]);
+/* handle current received frame but without data copy to application buffer in PTP enhanced mode */
+#define ENET_NOCOPY_PTPFRAME_RECEIVE_ENHANCED_MODE(ptr)           enet_ptpframe_receive_enhanced_mode(NULL, 0U, (ptr))
+/* send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode */
+ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]);
+/* handle current transmit frame but without data copy from application buffer in PTP enhanced mode */
+#define ENET_NOCOPY_PTPFRAME_TRANSMIT_ENHANCED_MODE(len, ptr)     enet_ptpframe_transmit_enhanced_mode(NULL, (len), (ptr))
+
+#else
+
+/* configure descriptor to work in normal mode */
+void enet_desc_select_normal_mode(void);
+/* initialize the dma Tx/Rx descriptors's parameters in normal chain mode with ptp function */
+void enet_ptp_normal_descriptors_chain_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab);
+/* initialize the dma Tx/Rx descriptors's parameters in normal ring mode with ptp function */
+void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab);
+/* receive a packet data with timestamp values to application buffer, when the DMA is in normal mode */
+ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]);
+/* handle current received frame but without data copy to application buffer in PTP normal mode */
+#define ENET_NOCOPY_PTPFRAME_RECEIVE_NORMAL_MODE(ptr)             enet_ptpframe_receive_normal_mode(NULL, 0U, (ptr))
+/* send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode */
+ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]);
+/* handle current transmit frame but without data copy from application buffer in PTP normal mode */
+#define ENET_NOCOPY_PTPFRAME_TRANSMIT_NORMAL_MODE(len, ptr)       enet_ptpframe_transmit_normal_mode(NULL, (len), (ptr))
+
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */
+
+/* WUM function */
+/* wakeup frame filter register pointer reset */
+void enet_wum_filter_register_pointer_reset(void);
+/* set the remote wakeup frame registers */
+void enet_wum_filter_config(uint32_t pdata[]);
+/* enable wakeup management features */
+void enet_wum_feature_enable(uint32_t feature);
+/* disable wakeup management features */
+void enet_wum_feature_disable(uint32_t feature);
+
+/* MSC function */
+/* reset the MAC statistics counters */
+void enet_msc_counters_reset(void);
+/* enable the MAC statistics counter features */ 
+void enet_msc_feature_enable(uint32_t feature);
+/* disable the MAC statistics counter features */ 
+void enet_msc_feature_disable(uint32_t feature);
+/* configure MAC statistics counters preset mode */
+void enet_msc_counters_preset_config(enet_msc_preset_enum mode);
+/* get MAC statistics counter */                   
+uint32_t enet_msc_counters_get(enet_msc_counter_enum counter);
+
+/* PTP function */
+/* enable the PTP features */
+void enet_ptp_feature_enable(uint32_t feature);
+/* disable the PTP features */
+void enet_ptp_feature_disable(uint32_t feature);
+/* configure the PTP timestamp function */
+ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func);
+/* configure the PTP system time subsecond increment value */
+void enet_ptp_subsecond_increment_config(uint32_t subsecond);
+/* adjusting the PTP clock frequency only in fine update mode */
+void enet_ptp_timestamp_addend_config(uint32_t add);
+/* initializing or adding/subtracting to second of the PTP system time */
+void enet_ptp_timestamp_update_config(uint32_t sign, uint32_t second, uint32_t subsecond);
+/* configure the PTP expected target time */
+void enet_ptp_expected_time_config(uint32_t second, uint32_t nanosecond);
+/* get the PTP current system time */
+void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct);
+/* configure the PPS output frequency */
+void enet_ptp_pps_output_frequency_config(uint32_t freq);
+
+
+/* internal function */
+/* reset the ENET initpara struct, call it before using enet_initpara_config() */
+void enet_initpara_reset(void);
+/* initialize ENET peripheral with generally concerned parameters, call it by enet_init() */
+static void enet_default_init(void);
+#ifdef USE_DELAY
+/* user can provide more timing precise _ENET_DELAY_ function */
+#define _ENET_DELAY_                              delay_ms 
+#else
+/* insert a delay time */
+static void enet_delay(uint32_t ncount);
+/* default _ENET_DELAY_ function with less precise timing */
+#define _ENET_DELAY_                              enet_delay
+#endif
+
+#endif /* GD32F4XX_ENET_H */

+ 781 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h

@@ -0,0 +1,781 @@
+/*!
+    \file  gd32f4xx_exmc.h
+    \brief definitions for the EXMC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_EXMC_H
+#define GD32F4XX_EXMC_H
+
+#include "gd32f4xx.h"
+
+/* EXMC definitions */
+#define EXMC                              (EXMC_BASE)                   /*!< EXMC register base address */
+#define EXMC_NOR_PSRAM                    (EXMC_BASE - 0x40000000)      /*!< EXMC NOR/PSRAM base address */
+#define EXMC_NAND                         (EXMC_BASE - 0x30000000)      /*!< EXMC NAND base address */
+#define EXMC_PCCARD                       (EXMC_BASE - 0x10000000)      /*!< EXMC PC card base address */
+#define EXMC_SDRAM                        (EXMC_BASE + 0x20000000)      /*!< EXMC SDRAM base address */
+
+/* registers definitions */
+/* NOR/PSRAM */
+#define EXMC_SNCTL0                       REG32(EXMC + 0x00U)           /*!< EXMC SRAM/NOR flash control register */
+#define EXMC_SNTCFG0                      REG32(EXMC + 0x04U)           /*!< EXMC SRAM/NOR flash timing configuration register */
+#define EXMC_SNWTCFG0                     REG32(EXMC + 0x104U)          /*!< EXMC SRAM/NOR flash write timing configuration register */
+
+#define EXMC_SNCTL1                       REG32(EXMC + 0x08U)           /*!< EXMC SRAM/NOR flash control register */
+#define EXMC_SNTCFG1                      REG32(EXMC + 0x0CU)           /*!< EXMC SRAM/NOR flash timing configuration register */
+#define EXMC_SNWTCFG1                     REG32(EXMC + 0x10CU)          /*!< EXMC SRAM/NOR flash write timing configuration register */
+
+#define EXMC_SNCTL2                       REG32(EXMC + 0x10U)           /*!< EXMC SRAM/NOR flash control register */
+#define EXMC_SNTCFG2                      REG32(EXMC + 0x14U)           /*!< EXMC SRAM/NOR flash timing configuration register */
+#define EXMC_SNWTCFG2                     REG32(EXMC + 0x114U)          /*!< EXMC SRAM/NOR flash write timing configuration register */
+
+#define EXMC_SNCTL3                       REG32(EXMC + 0x18U)           /*!< EXMC SRAM/NOR flash control register */
+#define EXMC_SNTCFG3                      REG32(EXMC + 0x1CU)           /*!< EXMC SRAM/NOR flash timing configuration register */
+#define EXMC_SNWTCFG3                     REG32(EXMC + 0x11CU)          /*!< EXMC SRAM/NOR flash write timing configuration register */
+
+/* NAND/PC card */
+#define EXMC_NPCTL1                       REG32(EXMC + 0x40U)           /*!< EXMC NAND/PC card control register */
+#define EXMC_NPINTEN1                     REG32(EXMC + 0x44U)           /*!< EXMC NAND/PC card interrupt enable register */
+#define EXMC_NPCTCFG1                     REG32(EXMC + 0x48U)           /*!< EXMC NAND/PC card common space timing configuration register */
+#define EXMC_NPATCFG1                     REG32(EXMC + 0x4CU)           /*!< EXMC NAND/PC card attribute space timing configuration register */
+#define EXMC_NECC1                        REG32(EXMC + 0x54U)           /*!< EXMC NAND ECC register */
+
+#define EXMC_NPCTL2                       REG32(EXMC + 0x60U)           /*!< EXMC NAND/PC card control register */
+#define EXMC_NPINTEN2                     REG32(EXMC + 0x64U)           /*!< EXMC NAND/PC card interrupt enable register */
+#define EXMC_NPCTCFG2                     REG32(EXMC + 0x68U)           /*!< EXMC NAND/PC card common space timing configuration register */
+#define EXMC_NPATCFG2                     REG32(EXMC + 0x6CU)           /*!< EXMC NAND/PC card attribute space timing configuration register */
+#define EXMC_NECC2                        REG32(EXMC + 0x74U)           /*!< EXMC NAND ECC register */
+
+#define EXMC_NPCTL3                       REG32(EXMC + 0x80U)           /*!< EXMC NAND/PC card control register */
+#define EXMC_NPINTEN3                     REG32(EXMC + 0x84U)           /*!< EXMC NAND/PC card interrupt enable register */
+#define EXMC_NPCTCFG3                     REG32(EXMC + 0x88U)           /*!< EXMC NAND/PC card common space timing configuration register */
+#define EXMC_NPATCFG3                     REG32(EXMC + 0x8CU)           /*!< EXMC NAND/PC card attribute space timing configuration register */
+#define EXMC_PIOTCFG3                     REG32(EXMC + 0xB0U)           /*!< EXMC PC card I/O space timing configuration register */
+
+/* SDRAM */
+#define EXMC_SDCTL0                       REG32(EXMC + 0x140U)          /*!< EXMC SDRAM control register */
+#define EXMC_SDTCFG0                      REG32(EXMC + 0x148U)          /*!< EXMC SDRAM timing configuration register register */
+
+#define EXMC_SDCTL1                       REG32(EXMC + 0x144U)          /*!< EXMC SDRAM control register */
+#define EXMC_SDTCFG1                      REG32(EXMC + 0x14CU)          /*!< EXMC SDRAM timing configuration register register */
+
+#define EXMC_SDCMD                        REG32(EXMC + 0x150U)          /*!< EXMC SDRAM command register */
+#define EXMC_SDARI                        REG32(EXMC + 0x154U)          /*!< EXMC SDRAM auto-refresh interval register */
+#define EXMC_SDSTAT                       REG32(EXMC + 0x158U)          /*!< EXMC SDRAM status register */
+#define EXMC_SDRSCTL                      REG32(EXMC + 0x180U)          /*!< EXMC SDRAM read sample control register */
+
+/* SQPI PSRAM */
+#define EXMC_SINIT                        REG32(EXMC + 0x310U)          /*!< EXMC SPI initialization register */
+#define EXMC_SRCMD                        REG32(EXMC + 0x320U)          /*!< EXMC SPI read command register */
+#define EXMC_SWCMD                        REG32(EXMC + 0x330U)          /*!< EXMC SPI write command register */
+#define EXMC_SIDL                         REG32(EXMC + 0x340U)          /*!< EXMC SPI ID low register */
+#define EXMC_SIDH                         REG32(EXMC + 0x350U)          /*!< EXMC SPI ID high register */
+
+/* bits definitions */
+/* EXMC_SNCTLx,x=0..3 */
+#define EXMC_SNCTL_NRBKEN                 BIT(0)                        /*!< NOR bank enable */
+#define EXMC_SNCTL_NRMUX                  BIT(1)                        /*!< NOR bank memory address/data multiplexing */
+#define EXMC_SNCTL_NRTP                   BITS(2,3)                     /*!< NOR bank memory type */
+#define EXMC_SNCTL_NRW                    BITS(4,5)                     /*!< NOR bank memory data bus width */
+#define EXMC_SNCTL_NREN                   BIT(6)                        /*!< NOR flash access enable */
+#define EXMC_SNCTL_SBRSTEN                BIT(8)                        /*!< synchronous burst enable */
+#define EXMC_SNCTL_NRWTPOL                BIT(9)                        /*!< NWAIT signal polarity */
+#define EXMC_SNCTL_WRAPEN                 BIT(10)                       /*!< wrapped burst mode enable */
+#define EXMC_SNCTL_NRWTCFG                BIT(11)                       /*!< NWAIT signal configuration, only work in synchronous mode  */
+#define EXMC_SNCTL_WREN                   BIT(12)                       /*!< write enable */
+#define EXMC_SNCTL_NRWTEN                 BIT(13)                       /*!< NWAIT signal enable */
+#define EXMC_SNCTL_EXMODEN                BIT(14)                       /*!< extended mode enable */
+#define EXMC_SNCTL_ASYNCWAIT              BIT(15)                       /*!< asynchronous wait */
+#define EXMC_SNCTL_CPS                    BITS(16,18)                   /*!< CRAM page size */
+#define EXMC_SNCTL_SYNCWR                 BIT(19)                       /*!< synchronous write */
+#define EXMC_SNCTL_CCK                    BIT(20)                       /*!< consecutive clock */
+
+/* EXMC_SNTCFGx,x=0..3 */
+#define EXMC_SNTCFG_ASET                  BITS(0,3)                     /*!< address setup time */
+#define EXMC_SNTCFG_AHLD                  BITS(4,7)                     /*!< address hold time */
+#define EXMC_SNTCFG_DSET                  BITS(8,15)                    /*!< data setup time */
+#define EXMC_SNTCFG_BUSLAT                BITS(16,19)                   /*!< bus latency */
+#define EXMC_SNTCFG_CKDIV                 BITS(20,23)                   /*!< synchronous clock divide ratio */
+#define EXMC_SNTCFG_DLAT                  BITS(24,27)                   /*!< data latency for NOR flash */
+#define EXMC_SNTCFG_ASYNCMOD              BITS(28,29)                   /*!< asynchronous access mode */
+
+/* EXMC_SNWTCFGx,x=0..3 */
+#define EXMC_SNWTCFG_WASET                BITS(0,3)                     /*!< address setup time */
+#define EXMC_SNWTCFG_WAHLD                BITS(4,7)                     /*!< address hold time */
+#define EXMC_SNWTCFG_WDSET                BITS(8,15)                    /*!< data setup time */
+#define EXMC_SNWTCFG_WBUSLAT              BITS(16,19)                   /*!< bus latency */
+#define EXMC_SNWTCFG_WASYNCMOD            BITS(28,29)                   /*!< asynchronous access mode */
+
+/* EXMC_NPCTLx,x=1..3 */
+#define EXMC_NPCTL_NDWTEN                 BIT(1)                        /*!< wait feature enable */
+#define EXMC_NPCTL_NDBKEN                 BIT(2)                        /*!< NAND bank enable */
+#define EXMC_NPCTL_NDTP                   BIT(3)                        /*!< NAND bank memory type */
+#define EXMC_NPCTL_NDW                    BITS(4,5)                     /*!< NAND bank memory data bus width */
+#define EXMC_NPCTL_ECCEN                  BIT(6)                        /*!< ECC enable */
+#define EXMC_NPCTL_CTR                    BITS(9,12)                    /*!< CLE to RE delay */
+#define EXMC_NPCTL_ATR                    BITS(13,16)                   /*!< ALE to RE delay */
+#define EXMC_NPCTL_ECCSZ                  BITS(17,19)                   /*!< ECC size */
+
+/* EXMC_NPINTENx,x=1..3 */
+#define EXMC_NPINTEN_INTRS                BIT(0)                        /*!< interrupt rising edge status */
+#define EXMC_NPINTEN_INTHS                BIT(1)                        /*!< interrupt high-level status */
+#define EXMC_NPINTEN_INTFS                BIT(2)                        /*!< interrupt falling edge status */
+#define EXMC_NPINTEN_INTREN               BIT(3)                        /*!< interrupt rising edge detection enable */
+#define EXMC_NPINTEN_INTHEN               BIT(4)                        /*!< interrupt high-level detection enable */
+#define EXMC_NPINTEN_INTFEN               BIT(5)                        /*!< interrupt falling edge detection enable */
+#define EXMC_NPINTEN_INTEPT               BIT(6)                        /*!< FIFO empty flag */
+
+/* EXMC_NPCTCFGx,x=1..3 */
+#define EXMC_NPCTCFG_COMSET               BITS(0,7)                     /*!< common memory data bus HiZ time */
+#define EXMC_NPCTCFG_COMWAIT              BITS(8,15)                    /*!< common memory hold time */
+#define EXMC_NPCTCFG_COMHLD               BITS(16,23)                   /*!< common memory wait time */
+#define EXMC_NPCTCFG_COMHIZ               BITS(24,31)                   /*!< common memory setup time */
+
+/* EXMC_NPATCFGx,x=1..3 */
+#define EXMC_NPATCFG_ATTSET               BITS(0,7)                     /*!< attribute memory data bus HiZ time */
+#define EXMC_NPATCFG_ATTWAIT              BITS(8,15)                    /*!< attribute memory hold time */
+#define EXMC_NPATCFG_ATTHLD               BITS(16,23)                   /*!< attribute memory wait time */
+#define EXMC_NPATCFG_ATTHIZ               BITS(24,31)                   /*!< attribute memory setup time */
+
+/* EXMC_PIOTCFG3 */
+#define EXMC_PIOTCFG3_IOSET               BITS(0,7)                     /*!< IO space data bus HiZ time */
+#define EXMC_PIOTCFG3_IOWAIT              BITS(8,15)                    /*!< IO space hold time */
+#define EXMC_PIOTCFG3_IOHLD               BITS(16,23)                   /*!< IO space wait time */
+#define EXMC_PIOTCFG3_IOHIZ               BITS(24,31)                   /*!< IO space setup time */
+
+/* EXMC_NECCx,x=1..2 */
+#define EXMC_NECC_ECC                     BITS(0,31)                    /*!< ECC result */
+
+/* EXMC_SDCTLx,x=0..1 */
+#define EXMC_SDCTL_CAW                    BITS(0,1)                     /*!< column address bit width */
+#define EXMC_SDCTL_RAW                    BITS(2,3)                     /*!< row address bit width */
+#define EXMC_SDCTL_SDW                    BITS(4,5)                     /*!< SDRAM data bus width */
+#define EXMC_SDCTL_NBK                    BIT(6)                        /*!< number of banks */
+#define EXMC_SDCTL_CL                     BIT(7,8)                      /*!< CAS Latency */
+#define EXMC_SDCTL_WPEN                   BIT(9)                        /*!< write protection enable */
+#define EXMC_SDCTL_SDCLK                  BITS(10,11)                   /*!< SDRAM clock configuration */
+#define EXMC_SDCTL_BRSTRD                 BIT(12)                       /*!< burst read */
+#define EXMC_SDCTL_PIPED                  BITS(13,14)                   /*!< pipeline delay */
+
+/* EXMC_SDTCFGx,x=0..1 */
+#define EXMC_SDTCFG_LMRD                  BITS(0,3)                     /*!< load mode register delay */
+#define EXMC_SDTCFG_XSRD                  BITS(4,7)                     /*!< exit self-refresh delay */
+#define EXMC_SDTCFG_RASD                  BITS(8,11)                    /*!< row address select delay */
+#define EXMC_SDTCFG_ARFD                  BITS(12,15)                   /*!< auto refresh delay */
+#define EXMC_SDTCFG_WRD                   BITS(16,19)                   /*!< write recovery delay */
+#define EXMC_SDTCFG_RPD                   BITS(20,23)                   /*!< row precharge delay */
+#define EXMC_SDTCFG_RCD                   BITS(24,27)                   /*!< row to column delay */
+
+/* EXMC_SDCMD */
+#define EXMC_SDCMD_CMD                    BITS(0,2)                     /*!< command */
+#define EXMC_SDCMD_DS1                    BIT(3)                        /*!< device select 1 */
+#define EXMC_SDCMD_DS0                    BIT(4)                        /*!< device select 0 */
+#define EXMC_SDCMD_NARF                   BITS(5,8)                     /*!< number of successive auto-refresh */
+#define EXMC_SDCMD_MRC                    BITS(9,21)                    /*!< mode register content */
+
+/* EXMC_SDARI */
+#define EXMC_SDARI_REC                    BIT(0)                        /*!< refresh error flag clear */
+#define EXMC_SDARI_ARINTV                 BITS(1,13)                    /*!< auto-refresh interval */
+#define EXMC_SDARI_REIE                   BIT(14)                       /*!< interrupt refresh error enable */
+
+/* EXMC_SDSTAT */
+#define EXMC_SDSDAT_REIF                  BIT(0)                        /*!< refresh error interrupt flag */
+#define EXMC_SDSDAT_STA0                  BITS(1,2)                     /*!< device 0 status */
+#define EXMC_SDSDAT_STA1                  BITS(3,4)                     /*!< device 1 status */
+#define EXMC_SDSDAT_NRDY                  BIT(5)                        /*!< not ready status */
+
+/* EXMC_SDRSCTL */
+#define EXMC_SDRSCTL_RSEN                 BIT(0)                        /*!< read sample enable */
+#define EXMC_SDRSCTL_SSCR                 BIT(1)                        /*!< select sample cycle of read data */
+#define EXMC_SDRSCTL_SDSC                 BITS(4,7)                     /*!< select the delayed sample clock of read data */
+
+/* EXMC_SINIT */
+#define EXMC_SINIT_CMDBIT                 BITS(16,17)                   /*!< bit number of SPI PSRAM command phase */
+#define EXMC_SINIT_ARDBIT                 BITS(24,28)                   /*!< bit number of SPI PSRAM address phase */
+#define EXMC_SINIT_IDL                    BITS(29,30)                   /*!< SPI PSRAM ID length */
+#define EXMC_SINIT_POL                    BIT(31)                       /*!< read data sample polarity */
+
+/* EXMC_SRCMD */
+#define EXMC_SRCMD_RCMD                   BITS(0,15)                    /*!< SPI read command for AHB read transfer */
+#define EXMC_SRCMD_RWAITCYCLE             BITS(16,19)                   /*!< SPI read wait cycle number after address phase */
+#define EXMC_SRCMD_RMODE                  BITS(20,21)                   /*!< SPI PSRAM read command mode */
+#define EXMC_SRCMD_RDID                   BIT(31)                       /*!< send SPI read ID command */
+
+/* EXMC_SWCMD */
+#define EXMC_SWCMD_WCMD                   BITS(0,15)                    /*!< send SPI special command */
+#define EXMC_SWCMD_WWAITCYCLE             BITS(16,19)                   /*!< SPI PSRAM write command mode */
+#define EXMC_SWCMD_WMODE                  BITS(20,21)                   /*!< SPI write wait cycle number after address phase */
+#define EXMC_SWCMD_SC                     BIT(31)                       /*!< SPI write command for AHB write transfer */
+
+/* EXMC_SIDL */
+#define EXMC_SIDL_SIDL                    BITS(0,31)                    /*!< ID low data saved for SPI read ID command */
+
+/* EXMC_SIDH */
+#define EXMC_SIDL_SIDH                    BITS(0,31)                    /*!< ID high Data saved for SPI read ID command */
+
+/* constants definitions */
+/* EXMC NOR/SRAM timing initialize struct */
+typedef struct
+{
+    uint32_t asyn_access_mode;                                          /*!< asynchronous access mode */
+    uint32_t syn_data_latency;                                          /*!< configure the data latency */
+    uint32_t syn_clk_division;                                          /*!< configure the clock divide ratio */
+    uint32_t bus_latency;                                               /*!< configure the bus latency */
+    uint32_t asyn_data_setuptime;                                       /*!< configure the data setup time,asynchronous access mode valid */
+    uint32_t asyn_address_holdtime;                                     /*!< configure the address hold time,asynchronous access mode valid */
+    uint32_t asyn_address_setuptime;                                    /*!< configure the data setup time,asynchronous access mode valid */
+}exmc_norsram_timing_parameter_struct;
+
+/* EXMC NOR/SRAM initialize struct */
+typedef struct
+{
+    uint32_t norsram_region;                                            /*!< select the region of EXMC NOR/SRAM bank */
+    uint32_t write_mode;                                                /*!< the write mode, synchronous mode or asynchronous mode */
+    uint32_t extended_mode;                                             /*!< enable or disable the extended mode */
+    uint32_t asyn_wait;                                                 /*!< enable or disable the asynchronous wait function */
+    uint32_t nwait_signal;                                              /*!< enable or disable the NWAIT signal while in synchronous bust mode */
+    uint32_t memory_write;                                              /*!< enable or disable the write operation */
+    uint32_t nwait_config;                                              /*!< NWAIT signal configuration */
+    uint32_t wrap_burst_mode;                                           /*!< enable or disable the wrap burst mode */
+    uint32_t nwait_polarity;                                            /*!< specifies the polarity of NWAIT signal from memory */
+    uint32_t burst_mode;                                                /*!< enable or disable the burst mode */
+    uint32_t databus_width;                                             /*!< specifies the databus width of external memory */
+    uint32_t memory_type;                                               /*!< specifies the type of external memory */
+    uint32_t address_data_mux;                                          /*!< specifies whether the data bus and address bus are multiplexed */
+    exmc_norsram_timing_parameter_struct* read_write_timing;            /*!< timing parameters for read and write if the extendedmode is not used or the timing 
+                                                                             parameters for read if the extendedmode is used. */
+    exmc_norsram_timing_parameter_struct* write_timing;                 /*!< timing parameters for write when the extendedmode is used. */
+}exmc_norsram_parameter_struct;
+
+/* EXMC NAND/PC card timing initialize struct */
+typedef struct
+{
+    uint32_t databus_hiztime;                                           /*!< configure the dadtabus HiZ time for write operation */
+    uint32_t holdtime;                                                  /*!< configure the address hold time(or the data hold time for write operation) */
+    uint32_t waittime;                                                  /*!< configure the minimum wait time */
+    uint32_t setuptime;                                                 /*!< configure the address setup time */
+}exmc_nand_pccard_timing_parameter_struct;
+
+/* EXMC NAND initialize struct */
+typedef struct
+{
+    uint32_t nand_bank;                                                 /*!< select the bank of NAND */ 
+    uint32_t ecc_size;                                                  /*!< the page size for the ECC calculation */
+    uint32_t atr_latency;                                               /*!< configure the latency of ALE low to RB low */
+    uint32_t ctr_latency;                                               /*!< configure the latency of CLE low to RB low */
+    uint32_t ecc_logic;                                                 /*!< enable or disable the ECC calculation logic */
+    uint32_t databus_width;                                             /*!< the NAND flash databus width */
+    uint32_t wait_feature;                                              /*!< enables or disables the wait feature */
+    exmc_nand_pccard_timing_parameter_struct* common_space_timing;      /*!< the timing parameters for NAND flash Common Space */
+    exmc_nand_pccard_timing_parameter_struct* attribute_space_timing;   /*!< the timing parameters for NAND flash Attribute Space */
+}exmc_nand_parameter_struct;
+
+/* EXMC PC card initialize struct */
+typedef struct
+{
+    uint32_t atr_latency;                                               /*!< configure the latency of ALE low to RB low */
+    uint32_t ctr_latency;                                               /*!< configure the latency of CLE low to RB low */
+    uint32_t wait_feature;                                              /*!< enables or disables the Wait feature */
+    exmc_nand_pccard_timing_parameter_struct*  common_space_timing;     /*!< the timing parameters for NAND flash Common Space */
+    exmc_nand_pccard_timing_parameter_struct*  attribute_space_timing;  /*!< the timing parameters for NAND flash Attribute Space */  
+    exmc_nand_pccard_timing_parameter_struct*  io_space_timing;         /*!< the timing parameters for NAND flash IO Space */
+}exmc_pccard_parameter_struct;;
+
+/* EXMC SDRAM timing initialize struct */
+typedef struct
+{
+    uint32_t row_to_column_delay;                                       /*!< configure the row to column delay */
+    uint32_t row_precharge_delay;                                       /*!< configure the row precharge delay */
+    uint32_t write_recovery_delay;                                      /*!< configure the write recovery delay */
+    uint32_t auto_refresh_delay;                                        /*!< configure the auto refresh delay */       
+    uint32_t row_address_select_delay;                                  /*!< configure the row address select delay */
+    uint32_t exit_selfrefresh_delay;                                    /*!< configure the exit self-refresh delay */
+    uint32_t load_mode_register_delay;                                  /*!< configure the load mode register delay */
+}exmc_sdram_timing_parameter_struct;
+
+/* EXMC SDRAM initialize struct */
+typedef struct
+{
+    uint32_t sdram_device;                                              /*!< device of SDRAM */
+    uint32_t pipeline_read_delay;                                       /*!< the delay for reading data after CAS latency in HCLK clock cycles */
+    uint32_t brust_read_switch;                                         /*!< enable or disable the burst read */
+    uint32_t sdclock_config;                                            /*!< the SDCLK memory clock for both SDRAM banks */
+    uint32_t write_protection;                                          /*!< enable or disable SDRAM bank write protection function */
+    uint32_t cas_latency;                                               /*!< configure the SDRAM CAS latency */
+    uint32_t internal_bank_number;                                      /*!< the number internal banks */
+    uint32_t data_width;                                                /*!< the databus width of SDRAM memory */
+    uint32_t row_address_width;                                         /*!< the bit width of a row address */
+    uint32_t column_address_width;                                      /*!< the bit width of a column address */
+    exmc_sdram_timing_parameter_struct* timing;                         /*!< the timing parameters for write and read SDRAM */
+}exmc_sdram_parameter_struct;
+
+/* EXMC SDRAM command initialize struct */
+typedef struct
+{
+    uint32_t mode_register_content;                                     /*!< the SDRAM mode register content */
+    uint32_t auto_refresh_number;                                       /*!< the number of successive auto-refresh cycles will be send when CMD = 011 */
+    uint32_t bank_select;                                               /*!< the bank which command will be sent to */
+    uint32_t command;                                                   /*!< the commands that will be sent to SDRAM */
+}exmc_sdram_command_parameter_struct;
+
+/* EXMC SQPISRAM initialize struct */
+typedef struct{
+    uint32_t sample_polarity;                                           /*!< read data sample polarity */
+    uint32_t id_length;                                                 /*!< SPI PSRAM ID length */
+    uint32_t address_bits;                                              /*!< bit number of SPI PSRAM address phase */
+    uint32_t command_bits;                                              /*!< bit number of SPI PSRAM command phase */
+}exmc_sqpipsram_parameter_struct;
+
+/* EXMC_register address */
+#define EXMC_SNCTL(bank)                  REG32(EXMC + 0x08U*((uint32_t)(bank)))        /*!< EXMC SRAM/NOR flash control register */
+#define EXMC_SNTCFG(bank)                 REG32(EXMC + 0x04U + 0x08U*(bank))            /*!< EXMC SRAM/NOR flash timing configuration register */
+#define EXMC_SNWTCFG(bank)                REG32(EXMC + 0x104U + 0x08U*(bank))           /*!< EXMC SRAM/NOR flash write timing configuration register */
+
+#define EXMC_NPCTL(bank)                  REG32(EXMC + 0x40U + 0x20U*(bank))            /*!< EXMC NAND/PC card control register */
+#define EXMC_NPINTEN(bank)                REG32(EXMC + 0x44U + 0x20U*(bank))            /*!< EXMC NAND/PC card interrupt enable register */
+#define EXMC_NPCTCFG(bank)                REG32(EXMC + 0x48U + 0x20U*(bank))            /*!< EXMC NAND/PC card common space timing configuration register */
+#define EXMC_NPATCFG(bank)                REG32(EXMC + 0x4CU + 0x20U*(bank))            /*!< EXMC NAND/PC card attribute space timing configuration register */
+#define EXMC_NECC(bank)                   REG32(EXMC + 0x54U + 0x20U*(bank))            /*!< EXMC NAND ECC register */
+
+#define EXMC_SDCTL(bank)                  REG32(EXMC + 0x140U + 0x4U*((bank) - 0x4U))   /*!< EXMC SDRAM control register */
+#define EXMC_SDTCFG(bank)                 REG32(EXMC + 0x148U + 0x4U*((bank) - 0x4U))   /*!< EXMC SDRAM timing configuration register */
+
+/* CRAM page size */
+#define SNCTL_CPS(regval)                 (BITS(16,18) & ((uint32_t)(regval) << 16))
+#define EXMC_CRAM_AUTO_SPLIT              SNCTL_CPS(0)                  /*!< automatic burst split on page boundary crossing */
+#define EXMC_CRAM_PAGE_SIZE_128_BYTES     SNCTL_CPS(1)                  /*!< page size is 128 bytes */
+#define EXMC_CRAM_PAGE_SIZE_256_BYTES     SNCTL_CPS(2)                  /*!< page size is 256 bytes */
+#define EXMC_CRAM_PAGE_SIZE_512_BYTES     SNCTL_CPS(3)                  /*!< page size is 512 bytes */
+#define EXMC_CRAM_PAGE_SIZE_1024_BYTES    SNCTL_CPS(4)                  /*!< page size is 1024 bytes */
+
+/* NOR bank memory data bus width */
+#define SNCTL_NRW(regval)                 (BITS(4,5) & ((uint32_t)(regval) << 4))
+#define EXMC_NOR_DATABUS_WIDTH_8B         SNCTL_NRW(0)                  /*!< NOR data width 8 bits */
+#define EXMC_NOR_DATABUS_WIDTH_16B        SNCTL_NRW(1)                  /*!< NOR data width 16 bits */
+
+/* NOR bank memory type */
+#define SNCTL_NRTP(regval)                (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define EXMC_MEMORY_TYPE_SRAM             SNCTL_NRTP(0)                 /*!< SRAM,ROM */
+#define EXMC_MEMORY_TYPE_PSRAM            SNCTL_NRTP(1)                 /*!< PSRAM,CRAM */
+#define EXMC_MEMORY_TYPE_NOR              SNCTL_NRTP(2)                 /*!< NOR flash */
+
+/* asynchronous access mode */
+#define SNTCFG_ASYNCMOD(regval)           (BITS(28,29) & ((uint32_t)(regval) << 28))
+#define EXMC_ACCESS_MODE_A                SNTCFG_ASYNCMOD(0)            /*!< mode A access */
+#define EXMC_ACCESS_MODE_B                SNTCFG_ASYNCMOD(1)            /*!< mode B access */
+#define EXMC_ACCESS_MODE_C                SNTCFG_ASYNCMOD(2)            /*!< mode C access */
+#define EXMC_ACCESS_MODE_D                SNTCFG_ASYNCMOD(3)            /*!< mode D access */
+
+/* data latency for NOR flash */
+#define SNTCFG_DLAT(regval)               (BITS(24,27) & ((uint32_t)(regval) << 24))
+#define EXMC_DATALAT_2_CLK                SNTCFG_DLAT(0)                /*!< data latency 2 EXMC_CLK */
+#define EXMC_DATALAT_3_CLK                SNTCFG_DLAT(1)                /*!< data latency 3 EXMC_CLK */
+#define EXMC_DATALAT_4_CLK                SNTCFG_DLAT(2)                /*!< data latency 4 EXMC_CLK */
+#define EXMC_DATALAT_5_CLK                SNTCFG_DLAT(3)                /*!< data latency 5 EXMC_CLK */
+#define EXMC_DATALAT_6_CLK                SNTCFG_DLAT(4)                /*!< data latency 6 EXMC_CLK */
+#define EXMC_DATALAT_7_CLK                SNTCFG_DLAT(5)                /*!< data latency 7 EXMC_CLK */
+#define EXMC_DATALAT_8_CLK                SNTCFG_DLAT(6)                /*!< data latency 8 EXMC_CLK */
+#define EXMC_DATALAT_9_CLK                SNTCFG_DLAT(7)                /*!< data latency 9 EXMC_CLK */
+#define EXMC_DATALAT_10_CLK               SNTCFG_DLAT(8)                /*!< data latency 10 EXMC_CLK */
+#define EXMC_DATALAT_11_CLK               SNTCFG_DLAT(9)                /*!< data latency 11 EXMC_CLK */
+#define EXMC_DATALAT_12_CLK               SNTCFG_DLAT(10)               /*!< data latency 12 EXMC_CLK */
+#define EXMC_DATALAT_13_CLK               SNTCFG_DLAT(11)               /*!< data latency 13 EXMC_CLK */
+#define EXMC_DATALAT_14_CLK               SNTCFG_DLAT(12)               /*!< data latency 14 EXMC_CLK */
+#define EXMC_DATALAT_15_CLK               SNTCFG_DLAT(13)               /*!< data latency 15 EXMC_CLK */
+#define EXMC_DATALAT_16_CLK               SNTCFG_DLAT(14)               /*!< data latency 16 EXMC_CLK */
+#define EXMC_DATALAT_17_CLK               SNTCFG_DLAT(15)               /*!< data latency 17 EXMC_CLK */
+
+/* synchronous clock divide ratio */
+#define SNTCFG_CKDIV(regval)              (BITS(20,23) & ((uint32_t)(regval) << 20))
+#define EXMC_SYN_CLOCK_RATIO_DISABLE      SNTCFG_CKDIV(0)               /*!< EXMC_CLK disable */
+#define EXMC_SYN_CLOCK_RATIO_2_CLK        SNTCFG_CKDIV(1)               /*!< EXMC_CLK = 2*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_3_CLK        SNTCFG_CKDIV(2)               /*!< EXMC_CLK = 3*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_4_CLK        SNTCFG_CKDIV(3)               /*!< EXMC_CLK = 4*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_5_CLK        SNTCFG_CKDIV(4)               /*!< EXMC_CLK = 5*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_6_CLK        SNTCFG_CKDIV(5)               /*!< EXMC_CLK = 6*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_7_CLK        SNTCFG_CKDIV(6)               /*!< EXMC_CLK = 7*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_8_CLK        SNTCFG_CKDIV(7)               /*!< EXMC_CLK = 8*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_9_CLK        SNTCFG_CKDIV(8)               /*!< EXMC_CLK = 9*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_10_CLK       SNTCFG_CKDIV(9)               /*!< EXMC_CLK = 10*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_11_CLK       SNTCFG_CKDIV(10)              /*!< EXMC_CLK = 11*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_12_CLK       SNTCFG_CKDIV(11)              /*!< EXMC_CLK = 12*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_13_CLK       SNTCFG_CKDIV(12)              /*!< EXMC_CLK = 13*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_14_CLK       SNTCFG_CKDIV(13)              /*!< EXMC_CLK = 14*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_15_CLK       SNTCFG_CKDIV(14)              /*!< EXMC_CLK = 15*HCLK */
+#define EXMC_SYN_CLOCK_RATIO_16_CLK       SNTCFG_CKDIV(15)              /*!< EXMC_CLK = 16*HCLK */
+
+/* ECC size */
+#define NPCTL_ECCSZ(regval)               (BITS(17,19) & ((uint32_t)(regval) << 17))
+#define EXMC_ECC_SIZE_256BYTES            NPCTL_ECCSZ(0)                /* 256 bytes */
+#define EXMC_ECC_SIZE_512BYTES            NPCTL_ECCSZ(1)                /* 512 bytes */
+#define EXMC_ECC_SIZE_1024BYTES           NPCTL_ECCSZ(2)                /* 1024 bytes */
+#define EXMC_ECC_SIZE_2048BYTES           NPCTL_ECCSZ(3)                /* 2048 bytes */
+#define EXMC_ECC_SIZE_4096BYTES           NPCTL_ECCSZ(4)                /* 4096 bytes */
+#define EXMC_ECC_SIZE_8192BYTES           NPCTL_ECCSZ(5)                /* 8192 bytes */
+
+/* ALE to RE delay */
+#define NPCTL_ATR(regval)                 (BITS(13,16) & ((uint32_t)(regval) << 13))
+#define EXMC_ALE_RE_DELAY_1_HCLK          NPCTL_ATR(0)                  /* ALE to RE delay = 1*HCLK */
+#define EXMC_ALE_RE_DELAY_2_HCLK          NPCTL_ATR(1)                  /* ALE to RE delay = 2*HCLK */
+#define EXMC_ALE_RE_DELAY_3_HCLK          NPCTL_ATR(2)                  /* ALE to RE delay = 3*HCLK */
+#define EXMC_ALE_RE_DELAY_4_HCLK          NPCTL_ATR(3)                  /* ALE to RE delay = 4*HCLK */
+#define EXMC_ALE_RE_DELAY_5_HCLK          NPCTL_ATR(4)                  /* ALE to RE delay = 5*HCLK */
+#define EXMC_ALE_RE_DELAY_6_HCLK          NPCTL_ATR(5)                  /* ALE to RE delay = 6*HCLK */
+#define EXMC_ALE_RE_DELAY_7_HCLK          NPCTL_ATR(6)                  /* ALE to RE delay = 7*HCLK */
+#define EXMC_ALE_RE_DELAY_8_HCLK          NPCTL_ATR(7)                  /* ALE to RE delay = 8*HCLK */
+#define EXMC_ALE_RE_DELAY_9_HCLK          NPCTL_ATR(8)                  /* ALE to RE delay = 9*HCLK */
+#define EXMC_ALE_RE_DELAY_10_HCLK         NPCTL_ATR(9)                  /* ALE to RE delay = 10*HCLK */
+#define EXMC_ALE_RE_DELAY_11_HCLK         NPCTL_ATR(10)                 /* ALE to RE delay = 11*HCLK */
+#define EXMC_ALE_RE_DELAY_12_HCLK         NPCTL_ATR(11)                 /* ALE to RE delay = 12*HCLK */
+#define EXMC_ALE_RE_DELAY_13_HCLK         NPCTL_ATR(12)                 /* ALE to RE delay = 13*HCLK */
+#define EXMC_ALE_RE_DELAY_14_HCLK         NPCTL_ATR(13)                 /* ALE to RE delay = 14*HCLK */
+#define EXMC_ALE_RE_DELAY_15_HCLK         NPCTL_ATR(14)                 /* ALE to RE delay = 15*HCLK */
+#define EXMC_ALE_RE_DELAY_16_HCLK         NPCTL_ATR(15)                 /* ALE to RE delay = 16*HCLK */
+
+/* CLE to RE delay */
+#define NPCTL_CTR(regval)                 (BITS(9,12) & ((uint32_t)(regval) << 9))
+#define EXMC_CLE_RE_DELAY_1_HCLK          NPCTL_CTR(0)                  /* CLE to RE delay = 1*HCLK */
+#define EXMC_CLE_RE_DELAY_2_HCLK          NPCTL_CTR(1)                  /* CLE to RE delay = 2*HCLK */
+#define EXMC_CLE_RE_DELAY_3_HCLK          NPCTL_CTR(2)                  /* CLE to RE delay = 3*HCLK */
+#define EXMC_CLE_RE_DELAY_4_HCLK          NPCTL_CTR(3)                  /* CLE to RE delay = 4*HCLK */
+#define EXMC_CLE_RE_DELAY_5_HCLK          NPCTL_CTR(4)                  /* CLE to RE delay = 5*HCLK */
+#define EXMC_CLE_RE_DELAY_6_HCLK          NPCTL_CTR(5)                  /* CLE to RE delay = 6*HCLK */
+#define EXMC_CLE_RE_DELAY_7_HCLK          NPCTL_CTR(6)                  /* CLE to RE delay = 7*HCLK */
+#define EXMC_CLE_RE_DELAY_8_HCLK          NPCTL_CTR(7)                  /* CLE to RE delay = 8*HCLK */
+#define EXMC_CLE_RE_DELAY_9_HCLK          NPCTL_CTR(8)                  /* CLE to RE delay = 9*HCLK */
+#define EXMC_CLE_RE_DELAY_10_HCLK         NPCTL_CTR(9)                  /* CLE to RE delay = 10*HCLK */
+#define EXMC_CLE_RE_DELAY_11_HCLK         NPCTL_CTR(10)                 /* CLE to RE delay = 11*HCLK */
+#define EXMC_CLE_RE_DELAY_12_HCLK         NPCTL_CTR(11)                 /* CLE to RE delay = 12*HCLK */
+#define EXMC_CLE_RE_DELAY_13_HCLK         NPCTL_CTR(12)                 /* CLE to RE delay = 13*HCLK */
+#define EXMC_CLE_RE_DELAY_14_HCLK         NPCTL_CTR(13)                 /* CLE to RE delay = 14*HCLK */
+#define EXMC_CLE_RE_DELAY_15_HCLK         NPCTL_CTR(14)                 /* CLE to RE delay = 15*HCLK */
+#define EXMC_CLE_RE_DELAY_16_HCLK         NPCTL_CTR(15)                 /* CLE to RE delay = 16*HCLK */
+
+/* NAND bank memory data bus width */
+#define NPCTL_NDW(regval)                 (BITS(4,5) & ((uint32_t)(regval) << 4))
+#define EXMC_NAND_DATABUS_WIDTH_8B        NPCTL_NDW(0)                  /*!< NAND data width 8 bits */
+#define EXMC_NAND_DATABUS_WIDTH_16B       NPCTL_NDW(1)                  /*!< NAND data width 16 bits */
+
+/* SDRAM pipeline delay */
+#define SDCTL_PIPED(regval)               (BITS(13,14) & ((uint32_t)(regval) << 13))
+#define EXMC_PIPELINE_DELAY_0_HCLK        SDCTL_PIPED(0)                /*!< 0 HCLK clock cycle delay */
+#define EXMC_PIPELINE_DELAY_1_HCLK        SDCTL_PIPED(1)                /*!< 1 HCLK clock cycle delay */
+#define EXMC_PIPELINE_DELAY_2_HCLK        SDCTL_PIPED(2)                /*!< 2 HCLK clock cycle delay */
+
+/* SDRAM clock configuration */
+#define SDCTL_SDCLK(regval)               (BITS(10,11) & ((uint32_t)(regval) << 10))
+#define EXMC_SDCLK_DISABLE                SDCTL_SDCLK(0)                /*!< SDCLK memory clock disabled */
+#define EXMC_SDCLK_PERIODS_2_HCLK         SDCTL_SDCLK(2)                /*!< SDCLK memory period = 2*HCLK */
+#define EXMC_SDCLK_PERIODS_3_HCLK         SDCTL_SDCLK(3)                /*!< SDCLK memory period = 3*HCLK */
+
+/* CAS latency */
+#define SDCTL_CL(regval)                  (BITS(7,8) & ((uint32_t)(regval) << 7))
+#define EXMC_CAS_LATENCY_1_SDCLK          SDCTL_CL(1)                   /*!< CAS latency is 1 memory clock cycle */
+#define EXMC_CAS_LATENCY_2_SDCLK          SDCTL_CL(2)                   /*!< CAS latency is 2 memory clock cycle */
+#define EXMC_CAS_LATENCY_3_SDCLK          SDCTL_CL(3)                   /*!< CAS latency is 3 memory clock cycle */
+
+/* SDRAM data bus width */
+#define SDCTL_SDW(regval)                 (BITS(4,5) & ((uint32_t)(regval) << 4))
+#define EXMC_SDRAM_DATABUS_WIDTH_8B       SDCTL_SDW(0)                  /*!< SDRAM data width 8 bits */
+#define EXMC_SDRAM_DATABUS_WIDTH_16B      SDCTL_SDW(1)                  /*!< SDRAM data width 16 bits */
+#define EXMC_SDRAM_DATABUS_WIDTH_32B      SDCTL_SDW(2)                  /*!< SDRAM data width 32 bits */
+
+/* SDRAM row address bit width */
+#define SDCTL_RAW(regval)                 (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define EXMC_SDRAM_ROW_ADDRESS_11         SDCTL_RAW(0)                  /*!< row address bit width is 11 bits */
+#define EXMC_SDRAM_ROW_ADDRESS_12         SDCTL_RAW(1)                  /*!< row address bit width is 12 bits */
+#define EXMC_SDRAM_ROW_ADDRESS_13         SDCTL_RAW(2)                  /*!< row address bit width is 13 bits */
+
+/* SDRAM column address bit width */
+#define SDCTL_CAW(regval)                 (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define EXMC_SDRAM_COW_ADDRESS_8          SDCTL_CAW(0)                  /*!< column address bit width is 8 bits */
+#define EXMC_SDRAM_COW_ADDRESS_9          SDCTL_CAW(1)                  /*!< column address bit width is 9 bits */
+#define EXMC_SDRAM_COW_ADDRESS_10         SDCTL_CAW(2)                  /*!< column address bit width is 10 bits */
+#define EXMC_SDRAM_COW_ADDRESS_11         SDCTL_CAW(3)                  /*!< column address bit width is 11 bits */
+
+/* SDRAM number of successive auto-refresh */
+#define SDCMD_NARF(regval)                (BITS(5,8) & ((uint32_t)(regval) << 5))
+#define EXMC_SDRAM_AUTO_REFLESH_1_SDCLK   SDCMD_NARF(0)                 /*!< 1 auto-refresh cycle */
+#define EXMC_SDRAM_AUTO_REFLESH_2_SDCLK   SDCMD_NARF(1)                 /*!< 2 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_3_SDCLK   SDCMD_NARF(2)                 /*!< 3 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_4_SDCLK   SDCMD_NARF(3)                 /*!< 4 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_5_SDCLK   SDCMD_NARF(4)                 /*!< 5 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_6_SDCLK   SDCMD_NARF(5)                 /*!< 6 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_7_SDCLK   SDCMD_NARF(6)                 /*!< 7 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_8_SDCLK   SDCMD_NARF(7)                 /*!< 8 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_9_SDCLK   SDCMD_NARF(8)                 /*!< 9 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_10_SDCLK  SDCMD_NARF(9)                 /*!< 10 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_11_SDCLK  SDCMD_NARF(10)                /*!< 11 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_12_SDCLK  SDCMD_NARF(11)                /*!< 12 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_13_SDCLK  SDCMD_NARF(12)                /*!< 13 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_14_SDCLK  SDCMD_NARF(13)                /*!< 14 auto-refresh cycles */
+#define EXMC_SDRAM_AUTO_REFLESH_15_SDCLK  SDCMD_NARF(14)                /*!< 15 auto-refresh cycles */
+
+/* SDRAM command select */
+#define SDCMD_CMD(regval)                 (BITS(0,2) & ((uint32_t)(regval) << 0))
+#define EXMC_SDRAM_NORMAL_OPERATION       SDCMD_CMD(0)                  /*!< normal operation command */
+#define EXMC_SDRAM_CLOCK_ENABLE           SDCMD_CMD(1)                  /*!< clock enable command */
+#define EXMC_SDRAM_PRECHARGE_ALL          SDCMD_CMD(2)                  /*!< precharge all command */
+#define EXMC_SDRAM_AUTO_REFRESH           SDCMD_CMD(3)                  /*!< auto-refresh command */
+#define EXMC_SDRAM_LOAD_MODE_REGISTER     SDCMD_CMD(4)                  /*!< load mode register command */
+#define EXMC_SDRAM_SELF_REFRESH           SDCMD_CMD(5)                  /*!< self-refresh command */
+#define EXMC_SDRAM_POWERDOWN_ENTRY        SDCMD_CMD(6)                  /*!< power-down entry command */
+
+/* SDRAM the delayed sample clock of read data */
+#define SDRSCTL_SDSC(regval)              (BITS(4,7) & ((uint32_t)(regval) << 4))
+#define EXMC_SDRAM_0_DELAY_CELL           SDRSCTL_SDSC(0)               /*!< select the clock after 0 delay cell */
+#define EXMC_SDRAM_1_DELAY_CELL           SDRSCTL_SDSC(1)               /*!< select the clock after 1 delay cell */
+#define EXMC_SDRAM_2_DELAY_CELL           SDRSCTL_SDSC(2)               /*!< select the clock after 2 delay cell */
+#define EXMC_SDRAM_3_DELAY_CELL           SDRSCTL_SDSC(3)               /*!< select the clock after 3 delay cell */
+#define EXMC_SDRAM_4_DELAY_CELL           SDRSCTL_SDSC(4)               /*!< select the clock after 4 delay cell */
+#define EXMC_SDRAM_5_DELAY_CELL           SDRSCTL_SDSC(5)               /*!< select the clock after 5 delay cell */
+#define EXMC_SDRAM_6_DELAY_CELL           SDRSCTL_SDSC(6)               /*!< select the clock after 6 delay cell */
+#define EXMC_SDRAM_7_DELAY_CELL           SDRSCTL_SDSC(7)               /*!< select the clock after 7 delay cell */
+#define EXMC_SDRAM_8_DELAY_CELL           SDRSCTL_SDSC(8)               /*!< select the clock after 8 delay cell */
+#define EXMC_SDRAM_9_DELAY_CELL           SDRSCTL_SDSC(9)               /*!< select the clock after 9 delay cell */
+#define EXMC_SDRAM_10_DELAY_CELL          SDRSCTL_SDSC(10)              /*!< select the clock after 10 delay cell */
+#define EXMC_SDRAM_11_DELAY_CELL          SDRSCTL_SDSC(11)              /*!< select the clock after 11 delay cell */
+#define EXMC_SDRAM_12_DELAY_CELL          SDRSCTL_SDSC(12)              /*!< select the clock after 12 delay cell */
+#define EXMC_SDRAM_13_DELAY_CELL          SDRSCTL_SDSC(13)              /*!< select the clock after 13 delay cell */
+#define EXMC_SDRAM_14_DELAY_CELL          SDRSCTL_SDSC(14)              /*!< select the clock after 14 delay cell */
+#define EXMC_SDRAM_15_DELAY_CELL          SDRSCTL_SDSC(15)              /*!< select the clock after 15 delay cell */
+
+/* SPI PSRAM ID length */
+#define SINIT_IDL(regval)                 (BITS(29,30) & ((uint32_t)(regval) << 29))
+#define EXMC_SQPIPSRAM_ID_LENGTH_64B      SINIT_IDL(0)                  /*!< SPI PSRAM ID length is 64 bits */
+#define EXMC_SQPIPSRAM_ID_LENGTH_32B      SINIT_IDL(1)                  /*!< SPI PSRAM ID length is 32 bits */
+#define EXMC_SQPIPSRAM_ID_LENGTH_16B      SINIT_IDL(2)                  /*!< SPI PSRAM ID length is 16 bits */
+#define EXMC_SQPIPSRAM_ID_LENGTH_8B       SINIT_IDL(3)                  /*!< SPI PSRAM ID length is 8 bits */
+
+/* SPI PSRAM bit number of address phase */
+#define SINIT_ADRBIT(regval)              (BITS(24,28) & ((uint32_t)(regval) << 24))
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_1B     SINIT_ADRBIT(1)               /*!< SPI PSRAM address is 1 bit */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_2B     SINIT_ADRBIT(2)               /*!< SPI PSRAM address is 2 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_3B     SINIT_ADRBIT(3)               /*!< SPI PSRAM address is 3 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_4B     SINIT_ADRBIT(4)               /*!< SPI PSRAM address is 4 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_5B     SINIT_ADRBIT(5)               /*!< SPI PSRAM address is 5 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_6B     SINIT_ADRBIT(6)               /*!< SPI PSRAM address is 6 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_7B     SINIT_ADRBIT(7)               /*!< SPI PSRAM address is 7 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_8B     SINIT_ADRBIT(8)               /*!< SPI PSRAM address is 8 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_9B     SINIT_ADRBIT(9)               /*!< SPI PSRAM address is 9 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_10B    SINIT_ADRBIT(10)              /*!< SPI PSRAM address is 10 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_11B    SINIT_ADRBIT(11)              /*!< SPI PSRAM address is 11 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_12B    SINIT_ADRBIT(12)              /*!< SPI PSRAM address is 12 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_13B    SINIT_ADRBIT(13)              /*!< SPI PSRAM address is 13 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_14B    SINIT_ADRBIT(14)              /*!< SPI PSRAM address is 14 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_15B    SINIT_ADRBIT(15)              /*!< SPI PSRAM address is 15 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_16B    SINIT_ADRBIT(16)              /*!< SPI PSRAM address is 16 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_17B    SINIT_ADRBIT(17)              /*!< SPI PSRAM address is 17 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_18B    SINIT_ADRBIT(18)              /*!< SPI PSRAM address is 18 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_19B    SINIT_ADRBIT(19)              /*!< SPI PSRAM address is 19 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_20B    SINIT_ADRBIT(20)              /*!< SPI PSRAM address is 20 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_21B    SINIT_ADRBIT(21)              /*!< SPI PSRAM address is 21 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_22B    SINIT_ADRBIT(22)              /*!< SPI PSRAM address is 22 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_23B    SINIT_ADRBIT(23)              /*!< SPI PSRAM address is 23 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_24B    SINIT_ADRBIT(24)              /*!< SPI PSRAM address is 24 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_25B    SINIT_ADRBIT(25)              /*!< SPI PSRAM address is 25 bits */
+#define EXMC_SQPIPSRAM_ADDR_LENGTH_26B    SINIT_ADRBIT(26)              /*!< SPI PSRAM address is 26 bits */
+
+/* SPI PSRAM bit number of command phase */
+#define SINIT_CMDBIT(regval)              (BITS(16,17) & ((uint32_t)(regval) << 16))
+#define EXMC_SQPIPSRAM_COMMAND_LENGTH_4B  SINIT_CMDBIT(0)               /*!< SPI PSRAM command is 4 bits */
+#define EXMC_SQPIPSRAM_COMMAND_LENGTH_8B  SINIT_CMDBIT(1)               /*!< SPI PSRAM command is 8 bits */
+#define EXMC_SQPIPSRAM_COMMAND_LENGTH_16B SINIT_CMDBIT(2)               /*!< SPI PSRAM command is 16 bits */
+
+/* SPI PSRAM read command mode */
+#define SRCMD_RMODE(regval)               (BITS(20,21) & ((uint32_t)(regval) << 20))
+#define EXMC_SQPIPSRAM_READ_MODE_DISABLE  SRCMD_RMODE(0)                /*!< not SPI mode */
+#define EXMC_SQPIPSRAM_READ_MODE_SPI      SRCMD_RMODE(1)                /*!< SPI mode */
+#define EXMC_SQPIPSRAM_READ_MODE_SQPI     SRCMD_RMODE(2)                /*!< SQPI mode */
+#define EXMC_SQPIPSRAM_READ_MODE_QPI      SRCMD_RMODE(3)                /*!< QPI mode */
+
+/* SPI PSRAM write command mode */
+#define SRCMD_WMODE(regval)               (BITS(20,21) & ((uint32_t)(regval) << 20))
+#define EXMC_SQPIPSRAM_WRITE_MODE_DISABLE SRCMD_WMODE(0)                /*!< not SPI mode */
+#define EXMC_SQPIPSRAM_WRITE_MODE_SPI     SRCMD_WMODE(1)                /*!< SPI mode */
+#define EXMC_SQPIPSRAM_WRITE_MODE_SQPI    SRCMD_WMODE(2)                /*!< SQPI mode */
+#define EXMC_SQPIPSRAM_WRITE_MODE_QPI     SRCMD_WMODE(3)                /*!< QPI mode */
+
+/* EXMC NOR/SRAM bank region definition */
+#define EXMC_BANK0_NORSRAM_REGION0        ((uint32_t)0x00000000U)       /*!< bank0 NOR/SRAM region0 */
+#define EXMC_BANK0_NORSRAM_REGION1        ((uint32_t)0x00000001U)       /*!< bank0 NOR/SRAM region1 */
+#define EXMC_BANK0_NORSRAM_REGION2        ((uint32_t)0x00000002U)       /*!< bank0 NOR/SRAM region2 */
+#define EXMC_BANK0_NORSRAM_REGION3        ((uint32_t)0x00000003U)       /*!< bank0 NOR/SRAM region3 */
+
+/* EXMC consecutive clock */
+#define EXMC_CLOCK_SYN_MODE               ((uint32_t)0x00000000U)       /*!< EXMC_CLK is generated only during synchronous access */
+#define EXMC_CLOCK_UNCONDITIONALLY        ((uint32_t)0x00010000U)       /*!< EXMC_CLK is generated unconditionally */
+
+/* EXMC NOR/SRAM write mode */
+#define EXMC_ASYN_WRITE                   ((uint32_t)0x00000000U)       /*!< asynchronous write mode */
+#define EXMC_SYN_WRITE                    ((uint32_t)0x00008000U)       /*!< synchronous write mode */
+
+/* EXMC NWAIT signal configuration */
+#define EXMC_NWAIT_CONFIG_BEFORE          ((uint32_t)0x00000000U)       /*!< NWAIT signal is active one data cycle before wait state */
+#define EXMC_NWAIT_CONFIG_DURING          ((uint32_t)0x00000800U)       /*!< NWAIT signal is active during wait state */
+
+/* EXMC NWAIT signal polarity configuration */
+#define EXMC_NWAIT_POLARITY_LOW           ((uint32_t)0x00000000U)       /*!< low level is active of NWAIT */
+#define EXMC_NWAIT_POLARITY_HIGH          ((uint32_t)0x00000200U)       /*!< high level is active of NWAIT */
+
+/* EXMC NAND/PC card bank definition */
+#define EXMC_BANK1_NAND                   ((uint32_t)0x00000001U)       /*!< bank1 NAND flash */
+#define EXMC_BANK2_NAND                   ((uint32_t)0x00000002U)       /*!< bank2 NAND flash */
+#define EXMC_BANK3_PCCARD                 ((uint32_t)0x00000003U)       /*!< bank3 PC card */
+
+/* EXMC SDRAM bank definition */
+#define EXMC_SDRAM_DEVICE0                ((uint32_t)0x00000004U)       /*!< SDRAM device0 */
+#define EXMC_SDRAM_DEVICE1                ((uint32_t)0x00000005U)       /*!< SDRAM device1 */
+
+/* EXMC SDRAM internal banks */
+#define EXMC_SDRAM_2_INTER_BANK           ((uint32_t)0x00000000U)       /*!< 2 internal banks */
+#define EXMC_SDRAM_4_INTER_BANK           ((uint32_t)0x00000040U)       /*!< 4 internal banks */
+
+/* SDRAM device0 select */
+#define EXMC_SDRAM_DEVICE0_UNSELECT       ((uint32_t)0x00000000U)       /*!< NAND data width 8 bits */
+#define EXMC_SDRAM_DEVICE0_SELECT         ((uint32_t)0x00000010U)       /*!< NAND data width 16 bits */
+
+/* SDRAM device1 select */
+#define EXMC_SDRAM_DEVICE1_UNSELECT       ((uint32_t)0x00000000U)       /*!< NAND data width 8 bits */
+#define EXMC_SDRAM_DEVICE1_SELECT         ((uint32_t)0x00000008U)       /*!< NAND data width 16 bits */
+
+/* SDRAM device status */
+#define EXMC_SDRAM_DEVICE_NORMAL          ((uint32_t)0x00000000U)       /*!< normal status */
+#define EXMC_SDRAM_DEVICE_SELF_REFRESH    ((uint32_t)0x00000001U)       /*!< self refresh status */
+#define EXMC_SDRAM_DEVICE_POWER_DOWN      ((uint32_t)0x00000002U)       /*!< power down status */
+
+/* sample cycle of read data */
+#define EXMC_SDRAM_READSAMPLE_0_EXTRAHCLK ((uint32_t)0x00000000U)       /*!< add 0 extra HCLK cycle to the read data sample clock besides the delay chain */
+#define EXMC_SDRAM_READSAMPLE_1_EXTRAHCLK ((uint32_t)0x00000002U)       /*!< add 1 extra HCLK cycle to the read data sample clock besides the delay chain */
+
+/* read data sample polarity */
+#define EXMC_SDRAM_SAMPLE_RISING_EDGE     ((uint32_t)0x00000000U)       /*!< sample data at rising edge */
+#define EXMC_SDRAM_SAMPLE_FALLING_EDGE    ((uint32_t)0x80000000U)       /*!< sample data at falling edge */
+
+/* SQPI SRAM command flag */
+#define EXMC_SEND_COMMAND_FLAG_RDID       EXMC_SRCMD_RDID               /*!< EXMC_SRCMD_RDID flag bit */
+#define EXMC_SEND_COMMAND_FLAG_SC         EXMC_SWCMD_SC                 /*!< EXMC_SWCMD_SC flag bit */
+
+/* EXMC flag bits */
+#define EXMC_NAND_PCCARD_FLAG_RISE        EXMC_NPINTENx_INTRS           /*!< interrupt rising edge status */
+#define EXMC_NAND_PCCARD_FLAG_LEVEL       EXMC_NPINTENx_INTHS           /*!< interrupt high-level status */
+#define EXMC_NAND_PCCARD_FLAG_FALL        EXMC_NPINTENx_INTFS           /*!< interrupt falling edge status */
+#define EXMC_NAND_PCCARD_FLAG_FIFOE       EXMC_NPINTENx_INTEPT          /*!< FIFO empty flag */
+#define EXMC_SDRAM_FLAG_REFRESH           EXMC_SDSDAT_REIF              /*!< refresh error interrupt flag */
+#define EXMC_SDRAM_FLAG_NREADY            EXMC_SDSDAT_NRDY              /*!< not ready status  */
+
+/* EXMC interrupt flag bits */
+#define EXMC_NAND_PCCARD_INT_RISE         EXMC_NPINTENx_INTREN          /*!< interrupt rising edge detection enable */
+#define EXMC_NAND_PCCARD_INT_LEVEL        EXMC_NPINTENx_INTHEN          /*!< interrupt high-level detection enable */
+#define EXMC_NAND_PCCARD_INT_FALL         EXMC_NPINTENx_INTFEN          /*!< interrupt falling edge detection enable */
+#define EXMC_SDRAM_INT_REFRESH            EXMC_SDARI_REIE               /*!< interrupt refresh error enable */
+
+/* function declarations */
+/* deinitialize EXMC NOR/SRAM region */
+void exmc_norsram_deinit(uint32_t exmc_norsram_region);
+/* initialize EXMC NOR/SRAM region */
+void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct);
+/* exmc_norsram_parameter_struct parameter initialize */
+void exmc_norsram_parameter_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct);
+/* consecutive clock configure */
+void exmc_norsram_consecutive_clock_config(uint32_t clock_mode);
+/* CRAM page size configure */
+void exmc_norsram_page_size_config(uint32_t page_size);
+/* EXMC NOR/SRAM bank enable */
+void exmc_norsram_enable(uint32_t exmc_norsram_region);
+/* EXMC NOR/SRAM bank disable */
+void exmc_norsram_disable(uint32_t exmc_norsram_region);
+
+
+/* deinitialize EXMC NAND bank */
+void exmc_nand_deinit(uint32_t exmc_nand_bank);
+/* initialize EXMC NAND bank */
+void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct);
+/* exmc_norsram_parameter_struct parameter initialize */
+void exmc_nand_parameter_init(exmc_nand_parameter_struct* exmc_nand_init_struct);
+/* EXMC NAND bank enable */
+void exmc_nand_enable(uint32_t exmc_nand_bank);
+/* EXMC NAND bank disable */
+void exmc_nand_disable(uint32_t exmc_nand_bank);
+/* enable or disable the EXMC NAND ECC function */
+void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue);
+/* get the EXMC ECC value */
+uint32_t exmc_ecc_get(uint32_t exmc_nand_bank);
+
+
+/* deinitialize EXMC PC card bank */
+void exmc_pccard_deinit(void);
+/* initialize EXMC PC card bank */
+void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct);
+/* exmc_pccard_parameter_struct parameter initialize */
+void exmc_pccard_parameter_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct);
+/* EXMC PC card bank enable */
+void exmc_pccard_enable(void);
+/* EXMC PC card bank disable */
+void exmc_pccard_disable(void);
+
+
+/* deinitialize EXMC SDRAM device */
+void exmc_sdram_deinit(uint32_t exmc_sdram_device);
+/* initialize EXMC SDRAM device */
+void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct);
+/* exmc_sdram_parameter_struct parameter initialize */
+void exmc_sdram_parameter_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct);
+/* configure the SDRAM memory command */
+void exmc_sdram_command_config(exmc_sdram_command_parameter_struct* exmc_sdram_command_init_struct);
+/* set auto-refresh interval */
+void exmc_sdram_refresh_count_set(uint32_t exmc_count);
+/* set the number of successive auto-refresh command */
+void exmc_sdram_autorefresh_number_set(uint32_t exmc_number);
+/* config the write protection function */
+void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue);
+/* get the status of SDRAM device0 or device1 */
+uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device);
+/* configure the delayed sample clock of read data */
+void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk);
+/* enable or disable read sample */
+void exmc_sdram_readsample_enable(ControlStatus newvalue);
+
+
+/* deinitialize EXMC SQPIPSRAM */
+void exmc_sqpipsram_deinit(void);
+/* initialize EXMC SQPIPSRAM */
+void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct);
+/* exmc_sqpipsram_parameter_struct parameter initialize */
+void exmc_sqpipsram_parameter_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct);
+/* set the read command */
+void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle,uint32_t read_command_code);
+/* set the write command */
+void exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle,uint32_t write_command_code);
+/* send SPI read ID command */
+void exmc_sqpipsram_read_id_command_send(void);
+/* send SPI special command which does not have address and data phase */
+void exmc_sqpipsram_write_cmd_send(void);
+/* get the EXMC SPI ID low data */
+uint32_t exmc_sqpipsram_low_id_get(void);
+/* get the EXMC SPI ID high data */
+uint32_t exmc_sqpipsram_high_id_get(void);
+/* get the bit value of EXMC send write command bit or read ID command */
+FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag);
+
+
+/* check EXMC flag is set or not */
+FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag);
+/* clear EXMC flag */
+void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag);
+/* check EXMC flag is set or not */
+FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt_source);
+/* clear EXMC one channel flag */
+void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt_source);
+/* enable EXMC interrupt */
+void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt_source);
+/* disable EXMC interrupt */
+void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt_source);
+
+#endif /* GD32F4XX_EXMC_H */

+ 246 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h

@@ -0,0 +1,246 @@
+/*!
+    \file  gd32f4xx_exti.h
+    \brief definitions for the EXTI
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_EXTI_H
+#define GD32F4XX_EXTI_H
+
+#include "gd32f4xx.h"
+
+/* EXTI definitions */
+#define EXTI                         EXTI_BASE
+
+/* registers definitions */
+#define EXTI_INTEN                   REG32(EXTI + 0x00U)      /*!< interrupt enable register */
+#define EXTI_EVEN                    REG32(EXTI + 0x04U)      /*!< event enable register */
+#define EXTI_RTEN                    REG32(EXTI + 0x08U)      /*!< rising edge trigger enable register */
+#define EXTI_FTEN                    REG32(EXTI + 0x0CU)      /*!< falling trigger enable register */
+#define EXTI_SWIEV                   REG32(EXTI + 0x10U)      /*!< software interrupt event register */
+#define EXTI_PD                      REG32(EXTI + 0x14U)      /*!< pending register */
+
+/* bits definitions */
+/* EXTI_INTEN */
+#define EXTI_INTEN_INTEN0            BIT(0)                   /*!< interrupt from line 0 */
+#define EXTI_INTEN_INTEN1            BIT(1)                   /*!< interrupt from line 1 */
+#define EXTI_INTEN_INTEN2            BIT(2)                   /*!< interrupt from line 2 */
+#define EXTI_INTEN_INTEN3            BIT(3)                   /*!< interrupt from line 3 */
+#define EXTI_INTEN_INTEN4            BIT(4)                   /*!< interrupt from line 4 */
+#define EXTI_INTEN_INTEN5            BIT(5)                   /*!< interrupt from line 5 */
+#define EXTI_INTEN_INTEN6            BIT(6)                   /*!< interrupt from line 6 */
+#define EXTI_INTEN_INTEN7            BIT(7)                   /*!< interrupt from line 7 */
+#define EXTI_INTEN_INTEN8            BIT(8)                   /*!< interrupt from line 8 */
+#define EXTI_INTEN_INTEN9            BIT(9)                   /*!< interrupt from line 9 */
+#define EXTI_INTEN_INTEN10           BIT(10)                  /*!< interrupt from line 10 */
+#define EXTI_INTEN_INTEN11           BIT(11)                  /*!< interrupt from line 11 */
+#define EXTI_INTEN_INTEN12           BIT(12)                  /*!< interrupt from line 12 */
+#define EXTI_INTEN_INTEN13           BIT(13)                  /*!< interrupt from line 13 */
+#define EXTI_INTEN_INTEN14           BIT(14)                  /*!< interrupt from line 14 */
+#define EXTI_INTEN_INTEN15           BIT(15)                  /*!< interrupt from line 15 */
+#define EXTI_INTEN_INTEN16           BIT(16)                  /*!< interrupt from line 16 */
+#define EXTI_INTEN_INTEN17           BIT(17)                  /*!< interrupt from line 17 */
+#define EXTI_INTEN_INTEN18           BIT(18)                  /*!< interrupt from line 18 */
+#define EXTI_INTEN_INTEN19           BIT(19)                  /*!< interrupt from line 19 */
+#define EXTI_INTEN_INTEN20           BIT(20)                  /*!< interrupt from line 20 */
+#define EXTI_INTEN_INTEN21           BIT(21)                  /*!< interrupt from line 21 */
+#define EXTI_INTEN_INTEN22           BIT(22)                  /*!< interrupt from line 22 */
+
+/* EXTI_EVEN */
+#define EXTI_EVEN_EVEN0              BIT(0)                   /*!< event from line 0 */
+#define EXTI_EVEN_EVEN1              BIT(1)                   /*!< event from line 1 */
+#define EXTI_EVEN_EVEN2              BIT(2)                   /*!< event from line 2 */
+#define EXTI_EVEN_EVEN3              BIT(3)                   /*!< event from line 3 */
+#define EXTI_EVEN_EVEN4              BIT(4)                   /*!< event from line 4 */
+#define EXTI_EVEN_EVEN5              BIT(5)                   /*!< event from line 5 */
+#define EXTI_EVEN_EVEN6              BIT(6)                   /*!< event from line 6 */
+#define EXTI_EVEN_EVEN7              BIT(7)                   /*!< event from line 7 */
+#define EXTI_EVEN_EVEN8              BIT(8)                   /*!< event from line 8 */
+#define EXTI_EVEN_EVEN9              BIT(9)                   /*!< event from line 9 */
+#define EXTI_EVEN_EVEN10             BIT(10)                  /*!< event from line 10 */
+#define EXTI_EVEN_EVEN11             BIT(11)                  /*!< event from line 11 */
+#define EXTI_EVEN_EVEN12             BIT(12)                  /*!< event from line 12 */
+#define EXTI_EVEN_EVEN13             BIT(13)                  /*!< event from line 13 */
+#define EXTI_EVEN_EVEN14             BIT(14)                  /*!< event from line 14 */
+#define EXTI_EVEN_EVEN15             BIT(15)                  /*!< event from line 15 */
+#define EXTI_EVEN_EVEN16             BIT(16)                  /*!< event from line 16 */
+#define EXTI_EVEN_EVEN17             BIT(17)                  /*!< event from line 17 */
+#define EXTI_EVEN_EVEN18             BIT(18)                  /*!< event from line 18 */
+#define EXTI_EVEN_EVEN19             BIT(19)                  /*!< event from line 19 */
+#define EXTI_EVEN_EVEN20             BIT(20)                  /*!< event from line 20 */
+#define EXTI_EVEN_EVEN21             BIT(21)                  /*!< event from line 21 */
+#define EXTI_EVEN_EVEN22             BIT(22)                  /*!< event from line 22 */
+
+/* EXTI_RTEN */
+#define EXTI_RTEN_RTEN0              BIT(0)                   /*!< rising edge from line 0 */
+#define EXTI_RTEN_RTEN1              BIT(1)                   /*!< rising edge from line 1 */
+#define EXTI_RTEN_RTEN2              BIT(2)                   /*!< rising edge from line 2 */
+#define EXTI_RTEN_RTEN3              BIT(3)                   /*!< rising edge from line 3 */
+#define EXTI_RTEN_RTEN4              BIT(4)                   /*!< rising edge from line 4 */
+#define EXTI_RTEN_RTEN5              BIT(5)                   /*!< rising edge from line 5 */
+#define EXTI_RTEN_RTEN6              BIT(6)                   /*!< rising edge from line 6 */
+#define EXTI_RTEN_RTEN7              BIT(7)                   /*!< rising edge from line 7 */
+#define EXTI_RTEN_RTEN8              BIT(8)                   /*!< rising edge from line 8 */
+#define EXTI_RTEN_RTEN9              BIT(9)                   /*!< rising edge from line 9 */
+#define EXTI_RTEN_RTEN10             BIT(10)                  /*!< rising edge from line 10 */
+#define EXTI_RTEN_RTEN11             BIT(11)                  /*!< rising edge from line 11 */
+#define EXTI_RTEN_RTEN12             BIT(12)                  /*!< rising edge from line 12 */
+#define EXTI_RTEN_RTEN13             BIT(13)                  /*!< rising edge from line 13 */
+#define EXTI_RTEN_RTEN14             BIT(14)                  /*!< rising edge from line 14 */
+#define EXTI_RTEN_RTEN15             BIT(15)                  /*!< rising edge from line 15 */
+#define EXTI_RTEN_RTEN16             BIT(16)                  /*!< rising edge from line 16 */
+#define EXTI_RTEN_RTEN17             BIT(17)                  /*!< rising edge from line 17 */
+#define EXTI_RTEN_RTEN18             BIT(18)                  /*!< rising edge from line 18 */
+#define EXTI_RTEN_RTEN19             BIT(19)                  /*!< rising edge from line 19 */
+#define EXTI_RTEN_RTEN21             BIT(21)                  /*!< rising edge from line 21 */
+#define EXTI_RTEN_RTEN22             BIT(22)                  /*!< rising edge from line 22 */
+
+/* EXTI_FTEN */
+#define EXTI_FTEN_FTEN0              BIT(0)                   /*!< falling edge from line 0 */
+#define EXTI_FTEN_FTEN1              BIT(1)                   /*!< falling edge from line 1 */
+#define EXTI_FTEN_FTEN2              BIT(2)                   /*!< falling edge from line 2 */
+#define EXTI_FTEN_FTEN3              BIT(3)                   /*!< falling edge from line 3 */
+#define EXTI_FTEN_FTEN4              BIT(4)                   /*!< falling edge from line 4 */
+#define EXTI_FTEN_FTEN5              BIT(5)                   /*!< falling edge from line 5 */
+#define EXTI_FTEN_FTEN6              BIT(6)                   /*!< falling edge from line 6 */
+#define EXTI_FTEN_FTEN7              BIT(7)                   /*!< falling edge from line 7 */
+#define EXTI_FTEN_FTEN8              BIT(8)                   /*!< falling edge from line 8 */
+#define EXTI_FTEN_FTEN9              BIT(9)                   /*!< falling edge from line 9 */
+#define EXTI_FTEN_FTEN10             BIT(10)                  /*!< falling edge from line 10 */
+#define EXTI_FTEN_FTEN11             BIT(11)                  /*!< falling edge from line 11 */
+#define EXTI_FTEN_FTEN12             BIT(12)                  /*!< falling edge from line 12 */
+#define EXTI_FTEN_FTEN13             BIT(13)                  /*!< falling edge from line 13 */
+#define EXTI_FTEN_FTEN14             BIT(14)                  /*!< falling edge from line 14 */
+#define EXTI_FTEN_FTEN15             BIT(15)                  /*!< falling edge from line 15 */
+#define EXTI_FTEN_FTEN16             BIT(16)                  /*!< falling edge from line 16 */
+#define EXTI_FTEN_FTEN17             BIT(17)                  /*!< falling edge from line 17 */
+#define EXTI_FTEN_FTEN18             BIT(18)                  /*!< falling edge from line 18 */
+#define EXTI_FTEN_FTEN19             BIT(19)                  /*!< falling edge from line 19 */
+#define EXTI_FTEN_FTEN21             BIT(21)                  /*!< falling edge from line 21 */
+#define EXTI_FTEN_FTEN22             BIT(22)                  /*!< falling edge from line 22 */
+
+/* EXTI_SWIEV */
+#define EXTI_SWIEV_SWIEV0            BIT(0)                   /*!< software interrupt/event request from line 0 */
+#define EXTI_SWIEV_SWIEV1            BIT(1)                   /*!< software interrupt/event request from line 1 */
+#define EXTI_SWIEV_SWIEV2            BIT(2)                   /*!< software interrupt/event request from line 2 */
+#define EXTI_SWIEV_SWIEV3            BIT(3)                   /*!< software interrupt/event request from line 3 */
+#define EXTI_SWIEV_SWIEV4            BIT(4)                   /*!< software interrupt/event request from line 4 */
+#define EXTI_SWIEV_SWIEV5            BIT(5)                   /*!< software interrupt/event request from line 5 */
+#define EXTI_SWIEV_SWIEV6            BIT(6)                   /*!< software interrupt/event request from line 6 */
+#define EXTI_SWIEV_SWIEV7            BIT(7)                   /*!< software interrupt/event request from line 7 */
+#define EXTI_SWIEV_SWIEV8            BIT(8)                   /*!< software interrupt/event request from line 8 */
+#define EXTI_SWIEV_SWIEV9            BIT(9)                   /*!< software interrupt/event request from line 9 */
+#define EXTI_SWIEV_SWIEV10           BIT(10)                  /*!< software interrupt/event request from line 10 */
+#define EXTI_SWIEV_SWIEV11           BIT(11)                  /*!< software interrupt/event request from line 11 */
+#define EXTI_SWIEV_SWIEV12           BIT(12)                  /*!< software interrupt/event request from line 12 */
+#define EXTI_SWIEV_SWIEV13           BIT(13)                  /*!< software interrupt/event request from line 13 */
+#define EXTI_SWIEV_SWIEV14           BIT(14)                  /*!< software interrupt/event request from line 14 */
+#define EXTI_SWIEV_SWIEV15           BIT(15)                  /*!< software interrupt/event request from line 15 */
+#define EXTI_SWIEV_SWIEV16           BIT(16)                  /*!< software interrupt/event request from line 16 */
+#define EXTI_SWIEV_SWIEV17           BIT(17)                  /*!< software interrupt/event request from line 17 */
+#define EXTI_SWIEV_SWIEV18           BIT(18)                  /*!< software interrupt/event request from line 18 */
+#define EXTI_SWIEV_SWIEV19           BIT(19)                  /*!< software interrupt/event request from line 19 */
+#define EXTI_SWIEV_SWIEV21           BIT(21)                  /*!< software interrupt/event request from line 21 */
+#define EXTI_SWIEV_SWIEV22           BIT(22)                  /*!< software interrupt/event request from line 22 */
+
+/* EXTI_PD */
+#define EXTI_PD_PD0                  BIT(0)                   /*!< interrupt/event pending status from line 0 */
+#define EXTI_PD_PD1                  BIT(1)                   /*!< interrupt/event pending status from line 1 */
+#define EXTI_PD_PD2                  BIT(2)                   /*!< interrupt/event pending status from line 2 */
+#define EXTI_PD_PD3                  BIT(3)                   /*!< interrupt/event pending status from line 3 */
+#define EXTI_PD_PD4                  BIT(4)                   /*!< interrupt/event pending status from line 4 */
+#define EXTI_PD_PD5                  BIT(5)                   /*!< interrupt/event pending status from line 5 */
+#define EXTI_PD_PD6                  BIT(6)                   /*!< interrupt/event pending status from line 6 */
+#define EXTI_PD_PD7                  BIT(7)                   /*!< interrupt/event pending status from line 7 */
+#define EXTI_PD_PD8                  BIT(8)                   /*!< interrupt/event pending status from line 8 */
+#define EXTI_PD_PD9                  BIT(9)                   /*!< interrupt/event pending status from line 9 */
+#define EXTI_PD_PD10                 BIT(10)                  /*!< interrupt/event pending status from line 10 */
+#define EXTI_PD_PD11                 BIT(11)                  /*!< interrupt/event pending status from line 11 */
+#define EXTI_PD_PD12                 BIT(12)                  /*!< interrupt/event pending status from line 12 */
+#define EXTI_PD_PD13                 BIT(13)                  /*!< interrupt/event pending status from line 13 */
+#define EXTI_PD_PD14                 BIT(14)                  /*!< interrupt/event pending status from line 14 */
+#define EXTI_PD_PD15                 BIT(15)                  /*!< interrupt/event pending status from line 15 */
+#define EXTI_PD_PD16                 BIT(16)                  /*!< interrupt/event pending status from line 16 */
+#define EXTI_PD_PD17                 BIT(17)                  /*!< interrupt/event pending status from line 17 */
+#define EXTI_PD_PD18                 BIT(18)                  /*!< interrupt/event pending status from line 18 */
+#define EXTI_PD_PD19                 BIT(19)                  /*!< interrupt/event pending status from line 19 */
+#define EXTI_PD_PD21                 BIT(21)                  /*!< interrupt/event pending status from line 21 */
+#define EXTI_PD_PD22                 BIT(22)                  /*!< interrupt/event pending status from line 22 */
+
+/* constants definitions */
+/* EXTI line number */
+typedef enum
+{ 
+    EXTI_0      = BIT(0),                                     /*!< EXTI line 0 */
+    EXTI_1      = BIT(1),                                     /*!< EXTI line 1 */
+    EXTI_2      = BIT(2),                                     /*!< EXTI line 2 */
+    EXTI_3      = BIT(3),                                     /*!< EXTI line 3 */
+    EXTI_4      = BIT(4),                                     /*!< EXTI line 4 */
+    EXTI_5      = BIT(5),                                     /*!< EXTI line 5 */
+    EXTI_6      = BIT(6),                                     /*!< EXTI line 6 */
+    EXTI_7      = BIT(7),                                     /*!< EXTI line 7 */
+    EXTI_8      = BIT(8),                                     /*!< EXTI line 8 */
+    EXTI_9      = BIT(9),                                     /*!< EXTI line 9 */
+    EXTI_10     = BIT(10),                                    /*!< EXTI line 10 */
+    EXTI_11     = BIT(11),                                    /*!< EXTI line 11 */
+    EXTI_12     = BIT(12),                                    /*!< EXTI line 12 */
+    EXTI_13     = BIT(13),                                    /*!< EXTI line 13 */
+    EXTI_14     = BIT(14),                                    /*!< EXTI line 14 */
+    EXTI_15     = BIT(15),                                    /*!< EXTI line 15 */
+    EXTI_16     = BIT(16),                                    /*!< EXTI line 16 */
+    EXTI_17     = BIT(17),                                    /*!< EXTI line 17 */
+    EXTI_18     = BIT(18),                                    /*!< EXTI line 18 */
+    EXTI_19     = BIT(19),                                    /*!< EXTI line 19 */
+    EXTI_20     = BIT(20),                                    /*!< EXTI line 20 */    
+    EXTI_21     = BIT(21),                                    /*!< EXTI line 21 */
+    EXTI_22     = BIT(22),                                    /*!< EXTI line 22 */
+}exti_line_enum;
+
+/* external interrupt and event  */
+typedef enum
+{
+    EXTI_INTERRUPT   = 0,                                     /*!< EXTI interrupt mode */
+    EXTI_EVENT                                                /*!< EXTI event mode */
+}exti_mode_enum;
+
+/* interrupt trigger mode */
+typedef enum
+{ 
+    EXTI_TRIG_RISING = 0,                                     /*!< EXTI rising edge trigger */
+    EXTI_TRIG_FALLING,                                        /*!< EXTI falling edge trigger */
+    EXTI_TRIG_BOTH                                            /*!< EXTI rising and falling edge trigger */
+}exti_trig_type_enum;
+
+/* function declarations */
+/* deinitialize the EXTI */
+void exti_deinit(void);
+/* enable the configuration of EXTI initialize */
+void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type);
+/* enable the interrupts from EXTI line x */
+void exti_interrupt_enable(exti_line_enum linex);
+/* enable the events from EXTI line x */
+void exti_event_enable(exti_line_enum linex);
+/* disable the interrupts from EXTI line x */
+void exti_interrupt_disable(exti_line_enum linex);
+/* disable the events from EXTI line x */
+void exti_event_disable(exti_line_enum linex);
+
+/* get EXTI lines pending flag */
+FlagStatus exti_flag_get(exti_line_enum linex);
+/* clear EXTI lines pending flag */
+void exti_flag_clear(exti_line_enum linex);
+/* get EXTI lines flag when the interrupt flag is set */
+FlagStatus exti_interrupt_flag_get(exti_line_enum linex);
+/* clear EXTI lines pending flag */
+void exti_interrupt_flag_clear(exti_line_enum linex);
+/* EXTI software interrupt event enable */
+void exti_software_interrupt_enable(exti_line_enum linex);
+/* EXTI software interrupt event disable */
+void exti_software_interrupt_disable(exti_line_enum linex);
+
+#endif /* GD32F4XX_EXTI_H */

+ 371 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h

@@ -0,0 +1,371 @@
+/*!
+    \file  gd32f4xx_fmc.h
+    \brief definitions for the FMC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+#ifndef GD32F4XX_FMC_H
+#define GD32F4XX_FMC_H
+
+#include "gd32f4xx.h"
+
+/* FMC and option byte definition */
+#define FMC                        FMC_BASE                       /*!< FMC register base address */
+#define OB                         OB_BASE                        /*!< option byte base address */
+
+/* registers definitions */
+#define FMC_WS                     REG32((FMC) + 0x00U)           /*!< FMC wait state register */
+#define FMC_KEY                    REG32((FMC) + 0x04U)           /*!< FMC unlock key register */
+#define FMC_OBKEY                  REG32((FMC) + 0x08U)           /*!< FMC option byte unlock key register */
+#define FMC_STAT                   REG32((FMC) + 0x0CU)           /*!< FMC status register */
+#define FMC_CTL                    REG32((FMC) + 0x10U)           /*!< FMC control register */
+#define FMC_OBCTL0                 REG32((FMC) + 0x14U)           /*!< FMC option byte control register 0 */
+#define FMC_OBCTL1                 REG32((FMC) + 0x18U)           /*!< FMC option byte control register 1 */
+#define FMC_WSEN                   REG32((FMC) + 0xFCU)           /*!< FMC wait state enable register */
+#define FMC_PID                    REG32((FMC) + 0x100U)          /*!< FMC product ID register */
+
+#define OB_WP1                     REG32((OB) + 0x00000008U)      /*!< option byte write protection 1 */
+#define OB_USER                    REG32((OB) + 0x00010000U)      /*!< option byte user value*/
+#define OB_SPC                     REG32((OB) + 0x00010001U)      /*!< option byte security protection value */
+#define OB_WP0                     REG32((OB) + 0x00010008U)      /*!< option byte write protection 0 */
+
+/* bits definitions */
+/* FMC_WS */
+#define FMC_WC_WSCNT               BITS(0,3)                      /*!< wait state counter */
+
+/* FMC_KEY */
+#define FMC_KEY_KEY                BITS(0,31)                     /*!< FMC main flash key bits */
+
+/* FMC_OBKEY */
+#define FMC_OBKEY_OBKEY            BITS(0,31)                     /*!< option byte key bits */
+
+/* FMC_STAT */
+#define FMC_STAT_END               BIT(0)                         /*!< end of operation flag bit */
+#define FMC_STAT_OPERR             BIT(1)                         /*!< flash operation error flag bit */
+#define FMC_STAT_WPERR             BIT(4)                         /*!< erase/Program protection error flag bit */
+#define FMC_STAT_PGMERR            BIT(6)                         /*!< program size not match error flag bit */
+#define FMC_STAT_PGSERR            BIT(7)                         /*!< program sequence error flag bit */
+#define FMC_STAT_RDDERR            BIT(8)                         /*!< read D-bus protection error flag bit */
+#define FMC_STAT_BUSY              BIT(16)                        /*!< flash busy flag bit */
+
+/* FMC_CTL */
+#define FMC_CTL_PG                 BIT(0)                         /*!< main flash program command bit */
+#define FMC_CTL_SER                BIT(1)                         /*!< main flash sector erase command bit */
+#define FMC_CTL_MER0               BIT(2)                         /*!< main flash mass erase for bank0 command bit */
+#define FMC_CTL_SN                 BITS(3,7)                      /*!< select which sector number to be erased */
+#define FMC_CTL_PSZ                BITS(8,9)                      /*!< program size bit */
+#define FMC_CTL_MER1               BIT(15)                        /*!< main flash mass erase for bank1 command bit */
+#define FMC_CTL_START              BIT(16)                        /*!< send erase command to FMC bit */
+#define FMC_CTL_ENDIE              BIT(24)                        /*!< end of operation interrupt enable bit */
+#define FMC_CTL_ERRIE              BIT(25)                        /*!< error interrupt enable bit */
+#define FMC_CTL_LK                 BIT(31)                        /*!< FMC_CTL lock bit */
+
+/* FMC_OBCTL0 */
+#define FMC_OBCTL0_OB_LK           BIT(0)                         /*!< FMC_OBCTL0 lock bit */
+#define FMC_OBCTL0_OB_START        BIT(1)                         /*!< send option byte change command to FMC bit */
+#define FMC_OBCTL0_BOR_TH          BITS(2,3)                      /*!< option byte BOR threshold value */
+#define FMC_OBCTL0_BB              BIT(4)                         /*!< option byte boot bank value */
+#define FMC_OBCTL0_NWDG_HW         BIT(5)                         /*!< option byte watchdog value */
+#define FMC_OBCTL0_NRST_DPSLP      BIT(6)                         /*!< option byte deepsleep reset value */
+#define FMC_OBCTL0_NRST_STDBY      BIT(7)                         /*!< option byte standby reset value */
+#define FMC_OBCTL0_SPC             BITS(8,15)                     /*!< option byte Security Protection code */
+#define FMC_OBCTL0_WP0             BITS(16,27)                    /*!< erase/program protection of each sector when DRP is 0 */
+#define FMC_OBCTL0_DBS             BIT(30)                        /*!< double banks or single bank selection when flash size is 1M bytes */
+#define FMC_OBCTL0_DRP             BIT(31)                        /*!< D-bus read protection bit */
+
+/* FMC_OBCTL1 */
+#define FMC_OBCTL1_WP1             BITS(16,27)                    /*!< erase/program protection of each sector when DRP is 0 */
+
+/* FMC_WSEN */
+#define FMC_WSEN_WSEN              BIT(0)                         /*!< FMC wait state enable bit */
+
+/* FMC_PID */
+#define FMC_PID_PID                BITS(0,31)                     /*!< product ID bits */
+
+/* constants definitions */
+/* fmc state */
+typedef enum
+{
+    FMC_READY,                                                    /*!< the operation has been completed */
+    FMC_BUSY,                                                     /*!< the operation is in progress */
+    FMC_RDDERR,                                                   /*!< read D-bus protection error */
+    FMC_PGSERR,                                                   /*!< program sequence error */
+    FMC_PGMERR,                                                   /*!< program size not match error */
+    FMC_WPERR,                                                    /*!< erase/program protection error */
+    FMC_OPERR,                                                    /*!< operation error */
+    FMC_PGERR,                                                    /*!< program error */
+    FMC_TOERR                                                     /*!< timeout error */
+}fmc_state_enum;
+
+/* unlock key */
+#define UNLOCK_KEY0                ((uint32_t)0x45670123U)        /*!< unlock key 0 */
+#define UNLOCK_KEY1                ((uint32_t)0xCDEF89ABU)        /*!< unlock key 1 */
+
+#define OB_UNLOCK_KEY0             ((uint32_t)0x08192A3BU)        /*!< ob unlock key 0 */
+#define OB_UNLOCK_KEY1             ((uint32_t)0x4C5D6E7FU)        /*!< ob unlock key 1 */
+
+/* FMC time out */
+#define FMC_TIMEOUT_COUNT          ((uint32_t)0x000F0000)         /*!< enable FMC error timeout */
+
+/* option byte write protection */
+#define OB_LWP                     ((uint32_t)0x000000FFU)        /*!< write protection low bits */
+#define OB_HWP                     ((uint32_t)0x0000FF00U)        /*!< write protection high bits */
+
+/* FMC wait state counter */
+#define WC_WSCNT(regval)           (BITS(0,3) & ((uint32_t)(regval)))
+#define WS_WSCNT_0                 WC_WSCNT(0)                    /*!< FMC 0 wait */
+#define WS_WSCNT_1                 WC_WSCNT(1)                    /*!< FMC 1 wait */
+#define WS_WSCNT_2                 WC_WSCNT(2)                    /*!< FMC 2 wait */
+#define WS_WSCNT_3                 WC_WSCNT(3)                    /*!< FMC 3 wait */
+#define WS_WSCNT_4                 WC_WSCNT(4)                    /*!< FMC 4 wait */
+#define WS_WSCNT_5                 WC_WSCNT(5)                    /*!< FMC 5 wait */
+#define WS_WSCNT_6                 WC_WSCNT(6)                    /*!< FMC 6 wait */
+#define WS_WSCNT_7                 WC_WSCNT(7)                    /*!< FMC 7 wait */
+#define WS_WSCNT_8                 WC_WSCNT(8)                    /*!< FMC 8 wait */
+#define WS_WSCNT_9                 WC_WSCNT(9)                    /*!< FMC 9 wait */
+#define WS_WSCNT_10                WC_WSCNT(10)                   /*!< FMC 10 wait */
+#define WS_WSCNT_11                WC_WSCNT(11)                   /*!< FMC 11 wait */
+#define WS_WSCNT_12                WC_WSCNT(12)                   /*!< FMC 12 wait */
+#define WS_WSCNT_13                WC_WSCNT(13)                   /*!< FMC 13 wait */
+#define WS_WSCNT_14                WC_WSCNT(14)                   /*!< FMC 14 wait */
+#define WS_WSCNT_15                WC_WSCNT(15)                   /*!< FMC 15 wait */
+
+/* option byte BOR threshold value */
+#define OBCTL0_BOR_TH(regval)      (BITS(2,3) & ((uint32_t)(regval))<< 2)
+#define OB_BOR_TH_VALUE3           OBCTL0_BOR_TH(0)               /*!< BOR threshold value 3 */
+#define OB_BOR_TH_VALUE2           OBCTL0_BOR_TH(1)               /*!< BOR threshold value 2 */
+#define OB_BOR_TH_VALUE1           OBCTL0_BOR_TH(2)               /*!< BOR threshold value 1 */
+#define OB_BOR_TH_OFF              OBCTL0_BOR_TH(3)               /*!< no BOR function */
+
+/* option byte boot bank value */
+#define OBCTL0_BB(regval)          (BIT(4) & ((uint32_t)(regval)<<4))
+#define OB_BB_DISABLE              OBCTL0_BB(0)                   /*!< boot from bank0 */
+#define OB_BB_ENABLE               OBCTL0_BB(1)                   /*!< boot from bank1 or bank0 if bank1 is void */
+
+/* option byte software/hardware free watch dog timer */  
+#define OBCTL0_NWDG_HW(regval)     (BIT(5) & ((uint32_t)(regval))<< 5)
+#define OB_FWDGT_SW                OBCTL0_NWDG_HW(1)              /*!< software free watchdog */
+#define OB_FWDGT_HW                OBCTL0_NWDG_HW(0)              /*!< hardware free watchdog */
+
+/* option byte reset or not entering deep sleep mode */
+#define OBCTL0_NRST_DPSLP(regval)  (BIT(6) & ((uint32_t)(regval))<< 6)
+#define OB_DEEPSLEEP_NRST          OBCTL0_NRST_DPSLP(1)           /*!< no reset when entering deepsleep mode */
+#define OB_DEEPSLEEP_RST           OBCTL0_NRST_DPSLP(0)           /*!< generate a reset instead of entering deepsleep mode */
+
+/* option byte reset or not entering standby mode */
+#define OBCTL0_NRST_STDBY(regval)  (BIT(7) & ((uint32_t)(regval))<< 7)
+#define OB_STDBY_NRST              OBCTL0_NRST_STDBY(1)           /*!< no reset when entering deepsleep mode */
+#define OB_STDBY_RST               OBCTL0_NRST_STDBY(0)           /*!< generate a reset instead of entering standby mode */
+
+/* read protect configure */
+#define FMC_NSPC                   ((uint8_t)0xAAU)               /*!< no security protection */
+#define FMC_LSPC                   ((uint8_t)0xABU)               /*!< low security protection */
+#define FMC_HSPC                   ((uint8_t)0xCCU)               /*!< high security protection */
+
+/* option bytes write protection */
+#define OB_WP_0                    ((uint32_t)0x00000001U)        /*!< erase/program protection of sector 0  */
+#define OB_WP_1                    ((uint32_t)0x00000002U)        /*!< erase/program protection of sector 1  */
+#define OB_WP_2                    ((uint32_t)0x00000004U)        /*!< erase/program protection of sector 2  */
+#define OB_WP_3                    ((uint32_t)0x00000008U)        /*!< erase/program protection of sector 3  */
+#define OB_WP_4                    ((uint32_t)0x00000010U)        /*!< erase/program protection of sector 4  */
+#define OB_WP_5                    ((uint32_t)0x00000020U)        /*!< erase/program protection of sector 5  */
+#define OB_WP_6                    ((uint32_t)0x00000040U)        /*!< erase/program protection of sector 6  */
+#define OB_WP_7                    ((uint32_t)0x00000080U)        /*!< erase/program protection of sector 7  */
+#define OB_WP_8                    ((uint32_t)0x00000100U)        /*!< erase/program protection of sector 8  */
+#define OB_WP_9                    ((uint32_t)0x00000200U)        /*!< erase/program protection of sector 9  */
+#define OB_WP_10                   ((uint32_t)0x00000400U)        /*!< erase/program protection of sector 10 */
+#define OB_WP_11                   ((uint32_t)0x00000800U)        /*!< erase/program protection of sector 11 */
+#define OB_WP_12                   ((uint32_t)0x00000001U)        /*!< erase/program protection of sector 12 */
+#define OB_WP_13                   ((uint32_t)0x00000002U)        /*!< erase/program protection of sector 13 */
+#define OB_WP_14                   ((uint32_t)0x00000004U)        /*!< erase/program protection of sector 14 */
+#define OB_WP_15                   ((uint32_t)0x00000008U)        /*!< erase/program protection of sector 15 */
+#define OB_WP_16                   ((uint32_t)0x00000010U)        /*!< erase/program protection of sector 16 */
+#define OB_WP_17                   ((uint32_t)0x00000020U)        /*!< erase/program protection of sector 17 */
+#define OB_WP_18                   ((uint32_t)0x00000040U)        /*!< erase/program protection of sector 18 */
+#define OB_WP_19                   ((uint32_t)0x00000080U)        /*!< erase/program protection of sector 19 */
+#define OB_WP_20                   ((uint32_t)0x00000100U)        /*!< erase/program protection of sector 20 */
+#define OB_WP_21                   ((uint32_t)0x00000200U)        /*!< erase/program protection of sector 21 */
+#define OB_WP_22                   ((uint32_t)0x00000400U)        /*!< erase/program protection of sector 22 */
+#define OB_WP_23_30                ((uint32_t)0x00000800U)        /*!< erase/program protection of sector 23~30 */
+#define OB_WP_ALL                  ((uint32_t)0x00000FFFU)        /*!< erase/program protection of all sectors */
+
+/* option bytes D-bus read protection */
+#define OB_DRP_0                   ((uint32_t)0x00000001U)        /*!< D-bus read protection protection of sector 0  */
+#define OB_DRP_1                   ((uint32_t)0x00000002U)        /*!< D-bus read protection protection of sector 1  */
+#define OB_DRP_2                   ((uint32_t)0x00000004U)        /*!< D-bus read protection protection of sector 2  */
+#define OB_DRP_3                   ((uint32_t)0x00000008U)        /*!< D-bus read protection protection of sector 3  */
+#define OB_DRP_4                   ((uint32_t)0x00000010U)        /*!< D-bus read protection protection of sector 4  */
+#define OB_DRP_5                   ((uint32_t)0x00000020U)        /*!< D-bus read protection protection of sector 5  */
+#define OB_DRP_6                   ((uint32_t)0x00000040U)        /*!< D-bus read protection protection of sector 6  */
+#define OB_DRP_7                   ((uint32_t)0x00000080U)        /*!< D-bus read protection protection of sector 7  */
+#define OB_DRP_8                   ((uint32_t)0x00000100U)        /*!< D-bus read protection protection of sector 8  */
+#define OB_DRP_9                   ((uint32_t)0x00000200U)        /*!< D-bus read protection protection of sector 9  */
+#define OB_DRP_10                  ((uint32_t)0x00000400U)        /*!< D-bus read protection protection of sector 10 */
+#define OB_DRP_11                  ((uint32_t)0x00000800U)        /*!< D-bus read protection protection of sector 11 */
+#define OB_DRP_12                  ((uint32_t)0x00000001U)        /*!< D-bus read protection protection of sector 12 */
+#define OB_DRP_13                  ((uint32_t)0x00000002U)        /*!< D-bus read protection protection of sector 13 */
+#define OB_DRP_14                  ((uint32_t)0x00000004U)        /*!< D-bus read protection protection of sector 14 */
+#define OB_DRP_15                  ((uint32_t)0x00000008U)        /*!< D-bus read protection protection of sector 15 */
+#define OB_DRP_16                  ((uint32_t)0x00000010U)        /*!< D-bus read protection protection of sector 16 */
+#define OB_DRP_17                  ((uint32_t)0x00000020U)        /*!< D-bus read protection protection of sector 17 */
+#define OB_DRP_18                  ((uint32_t)0x00000040U)        /*!< D-bus read protection protection of sector 18 */
+#define OB_DRP_19                  ((uint32_t)0x00000080U)        /*!< D-bus read protection protection of sector 19 */
+#define OB_DRP_20                  ((uint32_t)0x00000100U)        /*!< D-bus read protection protection of sector 20 */
+#define OB_DRP_21                  ((uint32_t)0x00000200U)        /*!< D-bus read protection protection of sector 21 */
+#define OB_DRP_22                  ((uint32_t)0x00000400U)        /*!< D-bus read protection protection of sector 22 */
+#define OB_DRP_23_30               ((uint32_t)0x00000800U)        /*!< D-bus read protection protection of sector 23~30 */
+#define OB_DRP_ALL                 ((uint32_t)0x00000FFFU)        /*!< D-bus read protection protection of all sectors */
+
+/* double banks or single bank selection when flash size is 1M bytes */  
+#define OBCTL0_DBS(regval)         (BIT(30) & ((uint32_t)(regval)<<30))
+#define OB_DBS_DISABLE             OBCTL0_DBS(0)                  /*!< single bank when flash size is 1M bytes */
+#define OB_DBS_ENABLE              OBCTL0_DBS(1)                  /*!< double bank when flash size is 1M bytes */
+
+/* option bytes D-bus read protection mode */  
+#define OBCTL0_DRP(regval)         (BIT(31) & ((uint32_t)(regval)<<31))
+#define OB_DRP_DISABLE             OBCTL0_DRP(0)                  /*!< the WPx bits used as erase/program protection of each sector */
+#define OB_DRP_ENABLE              OBCTL0_DRP(1)                  /*!< the WPx bits used as erase/program protection and D-bus read protection of each sector */
+
+/* FMC sectors */
+#define CTL_SN(regval)             (BITS(3,7) & ((uint32_t)(regval))<< 3)
+#define CTL_SECTOR_NUMBER_0        CTL_SN(0)                      /*!< sector 0   */
+#define CTL_SECTOR_NUMBER_1        CTL_SN(1)                      /*!< sector 1   */
+#define CTL_SECTOR_NUMBER_2        CTL_SN(2)                      /*!< sector 2   */
+#define CTL_SECTOR_NUMBER_3        CTL_SN(3)                      /*!< sector 3   */
+#define CTL_SECTOR_NUMBER_4        CTL_SN(4)                      /*!< sector 4   */
+#define CTL_SECTOR_NUMBER_5        CTL_SN(5)                      /*!< sector 5   */
+#define CTL_SECTOR_NUMBER_6        CTL_SN(6)                      /*!< sector 6   */
+#define CTL_SECTOR_NUMBER_7        CTL_SN(7)                      /*!< sector 7   */
+#define CTL_SECTOR_NUMBER_8        CTL_SN(8)                      /*!< sector 8   */
+#define CTL_SECTOR_NUMBER_9        CTL_SN(9)                      /*!< sector 9   */
+#define CTL_SECTOR_NUMBER_10       CTL_SN(10)                     /*!< sector 10  */
+#define CTL_SECTOR_NUMBER_11       CTL_SN(11)                     /*!< sector 11  */
+#define CTL_SECTOR_NUMBER_24       CTL_SN(12)                     /*!< sector 24  */
+#define CTL_SECTOR_NUMBER_25       CTL_SN(13)                     /*!< sector 25  */
+#define CTL_SECTOR_NUMBER_26       CTL_SN(14)                     /*!< sector 26  */
+#define CTL_SECTOR_NUMBER_27       CTL_SN(15)                     /*!< sector 27  */
+#define CTL_SECTOR_NUMBER_12       CTL_SN(16)                     /*!< sector 12  */
+#define CTL_SECTOR_NUMBER_13       CTL_SN(17)                     /*!< sector 13  */
+#define CTL_SECTOR_NUMBER_14       CTL_SN(18)                     /*!< sector 14  */
+#define CTL_SECTOR_NUMBER_15       CTL_SN(19)                     /*!< sector 15  */
+#define CTL_SECTOR_NUMBER_16       CTL_SN(20)                     /*!< sector 16  */
+#define CTL_SECTOR_NUMBER_17       CTL_SN(21)                     /*!< sector 17  */
+#define CTL_SECTOR_NUMBER_18       CTL_SN(22)                     /*!< sector 18  */
+#define CTL_SECTOR_NUMBER_19       CTL_SN(23)                     /*!< sector 19  */
+#define CTL_SECTOR_NUMBER_20       CTL_SN(24)                     /*!< sector 20  */
+#define CTL_SECTOR_NUMBER_21       CTL_SN(25)                     /*!< sector 21  */
+#define CTL_SECTOR_NUMBER_22       CTL_SN(26)                     /*!< sector 22  */
+#define CTL_SECTOR_NUMBER_23       CTL_SN(27)                     /*!< sector 23  */
+#define CTL_SECTOR_NUMBER_28       CTL_SN(28)                     /*!< sector 28  */
+#define CTL_SECTOR_NUMBER_29       CTL_SN(29)                     /*!< sector 29  */
+#define CTL_SECTOR_NUMBER_30       CTL_SN(30)                     /*!< sector 30  */
+
+/* FMC program size */ 
+#define CTL_PSZ(regval)            (BITS(8,9) & ((uint32_t)(regval))<< 8)
+#define CTL_PSZ_BYTE               CTL_PSZ(0)                     /*!< FMC program by byte access */
+#define CTL_PSZ_HALF_WORD          CTL_PSZ(1)                     /*!< FMC program by half-word access */
+#define CTL_PSZ_WORD               CTL_PSZ(2)                     /*!< FMC program by word access */
+
+/* FMC interrupt enable */
+#define FMC_INTEN_END              ((uint32_t)0x01000000U)        /*!< enable FMC end of program interrupt */
+#define FMC_INTEN_ERR              ((uint32_t)0x02000000U)        /*!< enable FMC error interrupt */
+
+/* FMC flags */
+#define FMC_FLAG_END               ((uint32_t)0x00000001U)        /*!< FMC end of operation flag bit */
+#define FMC_FLAG_OPERR             ((uint32_t)0x00000002U)        /*!< FMC operation error flag bit */
+#define FMC_FLAG_WPERR             ((uint32_t)0x00000010U)        /*!< FMC erase/program protection error flag bit */
+#define FMC_FLAG_PGMERR            ((uint32_t)0x00000040U)        /*!< FMC program size not match error flag bit */
+#define FMC_FLAG_PGSERR            ((uint32_t)0x00000080U)        /*!< FMC program sequence error flag bit */
+#define FMC_FLAG_RDDERR            ((uint32_t)0x00000100U)        /*!< FMC read D-bus protection error flag bit */
+#define FMC_FLAG_BUSY              ((uint32_t)0x00010000U)        /*!< FMC busy flag */ 
+
+/* function declarations */
+/* FMC main memory programming functions */
+/* set the FMC wait state counter */
+void fmc_wscnt_set(uint32_t wscnt);
+/* unlock the main FMC operation */
+void fmc_unlock(void);
+/* lock the main FMC operation */
+void fmc_lock(void);
+/* FMC erase sector */
+fmc_state_enum fmc_sector_erase(uint32_t fmc_sector);
+/* FMC erase whole chip */
+fmc_state_enum fmc_mass_erase(void);
+/* FMC erase whole bank0 */
+fmc_state_enum fmc_bank0_erase(void);
+/* FMC erase whole bank1 */
+fmc_state_enum fmc_bank1_erase(void);
+/* FMC program a word at the corresponding address */
+fmc_state_enum fmc_word_program(uint32_t address, uint32_t data);
+/* FMC program a half word at the corresponding address */
+fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data);
+/* FMC program a byte at the corresponding address */
+fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data);
+
+/* FMC option bytes programming functions */
+/* unlock the option byte operation */
+void ob_unlock(void);
+/* lock the option byte operation */
+void ob_lock(void);
+/* send option byte change command */
+void ob_start(void);
+/* enable write protect */
+void ob_write_protection0_enable(uint32_t ob_wp);
+/* disable write protect */
+void ob_write_protection0_disable(uint32_t ob_wp);
+/* enable write protect */
+void ob_write_protection1_enable(uint32_t ob_wp);
+/* disable write protect */
+void ob_write_protection1_disable(uint32_t ob_wp);
+/* configure the erase/program protection mode */
+void ob_drp_config(uint32_t ob_drp);
+/* enable the erase/program protection mode */
+void ob_drp0_enable(uint32_t ob_drp);
+/* disable the erase/program protection mode */
+void ob_drp0_disable(uint32_t ob_drp);
+/* enable the erase/program protection mode */
+void ob_drp1_enable(uint32_t ob_drp);
+/* disable the erase/program protection mode */
+void ob_drp1_disable(uint32_t ob_drp);
+/* set the option byte security protection level  */
+void ob_security_protection_config(uint8_t ob_spc);
+/* write the FMC option byte user */
+void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby);
+/* option byte BOR threshold value */
+void ob_user_bor_threshold(uint32_t ob_bor_th);
+/* configure the boot mode */
+void ob_boot_mode_config(uint32_t boot_mode);
+/* get the FMC option byte user */
+uint8_t ob_user_get(void);
+/* get the FMC option byte write protection */
+uint16_t ob_write_protection0_get(void);
+/* get the FMC option byte write protection */
+uint16_t ob_write_protection1_get(void);
+/* get the FMC erase/program protection and D-bus read protection option bytes value */
+uint16_t ob_drp0_get(void);
+/* get the FMC erase/program protection and D-bus read protection option bytes value */
+uint16_t ob_drp1_get(void);
+/* get option byte security protection code value */
+FlagStatus ob_spc_get(void);
+/* get the FMC threshold value */
+uint8_t ob_user_bor_threshold_get(void);
+
+/* FMC interrupts and flags management functions */
+/* enable FMC interrupt */
+void fmc_interrupt_enable(uint32_t fmc_int);
+/* disable FMC interrupt */
+void fmc_interrupt_disable(uint32_t fmc_int);
+/* get flag set or reset */
+FlagStatus fmc_flag_get(uint32_t fmc_flag);
+/* clear the FMC pending flag */
+void fmc_flag_clear(uint32_t fmc_flag);
+/* return the FMC state */
+fmc_state_enum fmc_state_get(void);
+/* check FMC ready or not */
+fmc_state_enum fmc_ready_wait(uint32_t count);
+
+#endif /* GD32F4XX_FMC_H */

+ 75 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h

@@ -0,0 +1,75 @@
+/*!
+    \file  gd32f4xx_fwdgt.h
+    \brief definitions for the FWDGT
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_FWDGT_H
+#define GD32F4XX_FWDGT_H
+
+#include "gd32f4xx.h"
+
+/* FWDGT definitions */
+#define FWDGT                       FWDGT_BASE
+
+/* registers definitions */
+#define FWDGT_CTL                   REG32((FWDGT) + 0x00U)          /*!< FWDGT control register */
+#define FWDGT_PSC                   REG32((FWDGT) + 0x04U)          /*!< FWDGT prescaler register */
+#define FWDGT_RLD                   REG32((FWDGT) + 0x08U)          /*!< FWDGT reload register */
+#define FWDGT_STAT                  REG32((FWDGT) + 0x0CU)          /*!< FWDGT status register */
+
+/* bits definitions */
+/* FWDGT_CTL */
+#define FWDGT_CTL_CMD               BITS(0,15)                      /*!< FWDGT command value */
+
+/* FWDGT_PSC */
+#define FWDGT_PSC_PSC               BITS(0,2)                       /*!< FWDGT prescaler divider value */
+
+/* FWDGT_RLD */
+#define FWDGT_RLD_RLD               BITS(0,11)                      /*!< FWDGT counter reload value */
+
+/* FWDGT_STAT */
+#define FWDGT_STAT_PUD              BIT(0)                          /*!< FWDGT prescaler divider value update */
+#define FWDGT_STAT_RUD              BIT(1)                          /*!< FWDGT counter reload value update */
+
+/* constants definitions */
+/* psc register value */
+#define PSC_PSC(regval)             (BITS(0,2) & ((uint32_t)(regval) << 0))
+#define FWDGT_PSC_DIV4              ((uint8_t)PSC_PSC(0))           /*!< FWDGT prescaler set to 4 */
+#define FWDGT_PSC_DIV8              ((uint8_t)PSC_PSC(1))           /*!< FWDGT prescaler set to 8 */
+#define FWDGT_PSC_DIV16             ((uint8_t)PSC_PSC(2))           /*!< FWDGT prescaler set to 16 */
+#define FWDGT_PSC_DIV32             ((uint8_t)PSC_PSC(3))           /*!< FWDGT prescaler set to 32 */
+#define FWDGT_PSC_DIV64             ((uint8_t)PSC_PSC(4))           /*!< FWDGT prescaler set to 64 */
+#define FWDGT_PSC_DIV128            ((uint8_t)PSC_PSC(5))           /*!< FWDGT prescaler set to 128 */
+#define FWDGT_PSC_DIV256            ((uint8_t)PSC_PSC(6))           /*!< FWDGT prescaler set to 256 */
+
+/* control value */
+#define FWDGT_WRITEACCESS_ENABLE    ((uint16_t)0x5555U)             /*!< FWDGT_CTL bits write access enable value */
+#define FWDGT_WRITEACCESS_DISABLE   ((uint16_t)0x0000U)             /*!< FWDGT_CTL bits write access disable value */
+#define FWDGT_KEY_RELOAD            ((uint16_t)0xAAAAU)             /*!< FWDGT_CTL bits fwdgt counter reload value */
+#define FWDGT_KEY_ENABLE            ((uint16_t)0xCCCCU)             /*!< FWDGT_CTL bits fwdgt counter enable value */
+
+/* FWDGT timeout value */
+#define FWDGT_PSC_TIMEOUT           ((uint32_t)0x000FFFFFU)         /*!< FWDGT_PSC register write operation state flag timeout */
+#define FWDGT_RLD_TIMEOUT           ((uint32_t)0x000FFFFFU)         /*!< FWDGT_RLD register write operation state flag timeout */
+
+/* function declarations */
+/* disable write access to FWDGT_PSC and FWDGT_RLD */
+void fwdgt_write_disable(void);
+/* start the free watchdog timer counter */
+void fwdgt_enable(void);
+
+/* reload the counter of FWDGT */
+void fwdgt_counter_reload(void);
+/* configure counter reload value, and prescaler divider value */
+ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div);
+
+/* get flag state of FWDGT */
+FlagStatus fwdgt_flag_get(uint16_t flag);
+
+#endif /* GD32F4XX_FWDGT_H */

+ 383 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h

@@ -0,0 +1,383 @@
+/*!
+    \file  gd32f4xx_gpio.h
+    \brief definitions for the GPIO
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_GPIO_H
+#define GD32F4XX_GPIO_H
+
+#include "gd32f4xx.h"
+
+/* GPIOx(x=A,B,C,D,E,F,G,H,I) definitions */
+#define GPIOA                      (GPIO_BASE + 0x00000000U)
+#define GPIOB                      (GPIO_BASE + 0x00000400U)
+#define GPIOC                      (GPIO_BASE + 0x00000800U)
+#define GPIOD                      (GPIO_BASE + 0x00000C00U)
+#define GPIOE                      (GPIO_BASE + 0x00001000U)
+#define GPIOF                      (GPIO_BASE + 0x00001400U)
+#define GPIOG                      (GPIO_BASE + 0x00001800U)
+#define GPIOH                      (GPIO_BASE + 0x00001C00U)
+#define GPIOI                      (GPIO_BASE + 0x00002000U)
+
+/* registers definitions */
+#define GPIO_CTL(gpiox)            REG32((gpiox) + 0x00U)    /*!< GPIO port control register */
+#define GPIO_OMODE(gpiox)          REG32((gpiox) + 0x04U)    /*!< GPIO port output mode register */
+#define GPIO_OSPD(gpiox)           REG32((gpiox) + 0x08U)    /*!< GPIO port output speed register */
+#define GPIO_PUD(gpiox)            REG32((gpiox) + 0x0CU)    /*!< GPIO port pull-up/pull-down register */
+#define GPIO_ISTAT(gpiox)          REG32((gpiox) + 0x10U)    /*!< GPIO port input status register */
+#define GPIO_OCTL(gpiox)           REG32((gpiox) + 0x14U)    /*!< GPIO port output control register */
+#define GPIO_BOP(gpiox)            REG32((gpiox) + 0x18U)    /*!< GPIO port bit operation register */
+#define GPIO_LOCK(gpiox)           REG32((gpiox) + 0x1CU)    /*!< GPIO port configuration lock register */
+#define GPIO_AFSEL0(gpiox)         REG32((gpiox) + 0x20U)    /*!< GPIO alternate function selected register 0 */
+#define GPIO_AFSEL1(gpiox)         REG32((gpiox) + 0x24U)    /*!< GPIO alternate function selected register 1 */
+#define GPIO_BC(gpiox)             REG32((gpiox) + 0x28U)    /*!< GPIO bit clear register */
+#define GPIO_TG(gpiox)             REG32((gpiox) + 0x2CU)    /*!< GPIO port bit toggle register */
+
+/* bits definitions */
+/* GPIO_CTL */
+#define GPIO_CTL_CTL0              BITS(0,1)             /*!< pin 0 configuration bits */ 
+#define GPIO_CTL_CTL1              BITS(2,3)             /*!< pin 1 configuration bits */
+#define GPIO_CTL_CTL2              BITS(4,5)             /*!< pin 2 configuration bits */
+#define GPIO_CTL_CTL3              BITS(6,7)             /*!< pin 3 configuration bits */
+#define GPIO_CTL_CTL4              BITS(8,9)             /*!< pin 4 configuration bits */
+#define GPIO_CTL_CTL5              BITS(10,11)           /*!< pin 5 configuration bits */
+#define GPIO_CTL_CTL6              BITS(12,13)           /*!< pin 6 configuration bits */
+#define GPIO_CTL_CTL7              BITS(14,15)           /*!< pin 7 configuration bits */
+#define GPIO_CTL_CTL8              BITS(16,17)           /*!< pin 8 configuration bits */
+#define GPIO_CTL_CTL9              BITS(18,19)           /*!< pin 9 configuration bits */
+#define GPIO_CTL_CTL10             BITS(20,21)           /*!< pin 10 configuration bits */
+#define GPIO_CTL_CTL11             BITS(22,23)           /*!< pin 11 configuration bits */
+#define GPIO_CTL_CTL12             BITS(24,25)           /*!< pin 12 configuration bits */
+#define GPIO_CTL_CTL13             BITS(26,27)           /*!< pin 13 configuration bits */
+#define GPIO_CTL_CTL14             BITS(28,29)           /*!< pin 14 configuration bits */
+#define GPIO_CTL_CTL15             BITS(30,31)           /*!< pin 15 configuration bits */
+
+/* GPIO_OMODE */
+#define GPIO_OMODE_OM0             BIT(0)                /*!< pin 0 output mode bit */
+#define GPIO_OMODE_OM1             BIT(1)                /*!< pin 1 output mode bit */
+#define GPIO_OMODE_OM2             BIT(2)                /*!< pin 2 output mode bit */
+#define GPIO_OMODE_OM3             BIT(3)                /*!< pin 3 output mode bit */
+#define GPIO_OMODE_OM4             BIT(4)                /*!< pin 4 output mode bit */
+#define GPIO_OMODE_OM5             BIT(5)                /*!< pin 5 output mode bit */
+#define GPIO_OMODE_OM6             BIT(6)                /*!< pin 6 output mode bit */
+#define GPIO_OMODE_OM7             BIT(7)                /*!< pin 7 output mode bit */
+#define GPIO_OMODE_OM8             BIT(8)                /*!< pin 8 output mode bit */
+#define GPIO_OMODE_OM9             BIT(9)                /*!< pin 9 output mode bit */
+#define GPIO_OMODE_OM10            BIT(10)               /*!< pin 10 output mode bit */
+#define GPIO_OMODE_OM11            BIT(11)               /*!< pin 11 output mode bit */
+#define GPIO_OMODE_OM12            BIT(12)               /*!< pin 12 output mode bit */
+#define GPIO_OMODE_OM13            BIT(13)               /*!< pin 13 output mode bit */
+#define GPIO_OMODE_OM14            BIT(14)               /*!< pin 14 output mode bit */
+#define GPIO_OMODE_OM15            BIT(15)               /*!< pin 15 output mode bit */
+
+/* GPIO_OSPD */
+#define GPIO_OSPD_OSPD0            BITS(0,1)             /*!< pin 0 output max speed bits */
+#define GPIO_OSPD_OSPD1            BITS(2,3)             /*!< pin 1 output max speed bits */
+#define GPIO_OSPD_OSPD2            BITS(4,5)             /*!< pin 2 output max speed bits */
+#define GPIO_OSPD_OSPD3            BITS(6,7)             /*!< pin 3 output max speed bits */
+#define GPIO_OSPD_OSPD4            BITS(8,9)             /*!< pin 4 output max speed bits */
+#define GPIO_OSPD_OSPD5            BITS(10,11)           /*!< pin 5 output max speed bits */
+#define GPIO_OSPD_OSPD6            BITS(12,13)           /*!< pin 6 output max speed bits */
+#define GPIO_OSPD_OSPD7            BITS(14,15)           /*!< pin 7 output max speed bits */
+#define GPIO_OSPD_OSPD8            BITS(16,17)           /*!< pin 8 output max speed bits */
+#define GPIO_OSPD_OSPD9            BITS(18,19)           /*!< pin 9 output max speed bits */
+#define GPIO_OSPD_OSPD10           BITS(20,21)           /*!< pin 10 output max speed bits */
+#define GPIO_OSPD_OSPD11           BITS(22,23)           /*!< pin 11 output max speed bits */
+#define GPIO_OSPD_OSPD12           BITS(24,25)           /*!< pin 12 output max speed bits */
+#define GPIO_OSPD_OSPD13           BITS(26,27)           /*!< pin 13 output max speed bits */
+#define GPIO_OSPD_OSPD14           BITS(28,29)           /*!< pin 14 output max speed bits */
+#define GPIO_OSPD_OSPD15           BITS(30,31)           /*!< pin 15 output max speed bits */
+
+/* GPIO_PUD */
+#define GPIO_PUD_PUD0              BITS(0,1)             /*!< pin 0 pull-up or pull-down bits */
+#define GPIO_PUD_PUD1              BITS(2,3)             /*!< pin 1 pull-up or pull-down bits */
+#define GPIO_PUD_PUD2              BITS(4,5)             /*!< pin 2 pull-up or pull-down bits */
+#define GPIO_PUD_PUD3              BITS(6,7)             /*!< pin 3 pull-up or pull-down bits */
+#define GPIO_PUD_PUD4              BITS(8,9)             /*!< pin 4 pull-up or pull-down bits */
+#define GPIO_PUD_PUD5              BITS(10,11)           /*!< pin 5 pull-up or pull-down bits */
+#define GPIO_PUD_PUD6              BITS(12,13)           /*!< pin 6 pull-up or pull-down bits */
+#define GPIO_PUD_PUD7              BITS(14,15)           /*!< pin 7 pull-up or pull-down bits */
+#define GPIO_PUD_PUD8              BITS(16,17)           /*!< pin 8 pull-up or pull-down bits */
+#define GPIO_PUD_PUD9              BITS(18,19)           /*!< pin 9 pull-up or pull-down bits */
+#define GPIO_PUD_PUD10             BITS(20,21)           /*!< pin 10 pull-up or pull-down bits */
+#define GPIO_PUD_PUD11             BITS(22,23)           /*!< pin 11 pull-up or pull-down bits */
+#define GPIO_PUD_PUD12             BITS(24,25)           /*!< pin 12 pull-up or pull-down bits */
+#define GPIO_PUD_PUD13             BITS(26,27)           /*!< pin 13 pull-up or pull-down bits */
+#define GPIO_PUD_PUD14             BITS(28,29)           /*!< pin 14 pull-up or pull-down bits */
+#define GPIO_PUD_PUD15             BITS(30,31)           /*!< pin 15 pull-up or pull-down bits */
+
+/* GPIO_ISTAT */
+#define GPIO_ISTAT_ISTAT0          BIT(0)                /*!< pin 0 input status */
+#define GPIO_ISTAT_ISTAT1          BIT(1)                /*!< pin 1 input status */
+#define GPIO_ISTAT_ISTAT2          BIT(2)                /*!< pin 2 input status */
+#define GPIO_ISTAT_ISTAT3          BIT(3)                /*!< pin 3 input status */
+#define GPIO_ISTAT_ISTAT4          BIT(4)                /*!< pin 4 input status */
+#define GPIO_ISTAT_ISTAT5          BIT(5)                /*!< pin 5 input status */
+#define GPIO_ISTAT_ISTAT6          BIT(6)                /*!< pin 6 input status */
+#define GPIO_ISTAT_ISTAT7          BIT(7)                /*!< pin 7 input status */
+#define GPIO_ISTAT_ISTAT8          BIT(8)                /*!< pin 8 input status */
+#define GPIO_ISTAT_ISTAT9          BIT(9)                /*!< pin 9 input status */
+#define GPIO_ISTAT_ISTAT10         BIT(10)               /*!< pin 10 input status */
+#define GPIO_ISTAT_ISTAT11         BIT(11)               /*!< pin 11 input status */
+#define GPIO_ISTAT_ISTAT12         BIT(12)               /*!< pin 12 input status */
+#define GPIO_ISTAT_ISTAT13         BIT(13)               /*!< pin 13 input status */
+#define GPIO_ISTAT_ISTAT14         BIT(14)               /*!< pin 14 input status */
+#define GPIO_ISTAT_ISTAT15         BIT(15)               /*!< pin 15 input status */
+
+/* GPIO_OCTL */
+#define GPIO_OCTL_OCTL0            BIT(0)                /*!< pin 0 output bit */
+#define GPIO_OCTL_OCTL1            BIT(1)                /*!< pin 1 output bit */
+#define GPIO_OCTL_OCTL2            BIT(2)                /*!< pin 2 output bit */
+#define GPIO_OCTL_OCTL3            BIT(3)                /*!< pin 3 output bit */
+#define GPIO_OCTL_OCTL4            BIT(4)                /*!< pin 4 output bit */
+#define GPIO_OCTL_OCTL5            BIT(5)                /*!< pin 5 output bit */
+#define GPIO_OCTL_OCTL6            BIT(6)                /*!< pin 6 output bit */
+#define GPIO_OCTL_OCTL7            BIT(7)                /*!< pin 7 output bit */
+#define GPIO_OCTL_OCTL8            BIT(8)                /*!< pin 8 output bit */
+#define GPIO_OCTL_OCTL9            BIT(9)                /*!< pin 9 output bit */
+#define GPIO_OCTL_OCTL10           BIT(10)               /*!< pin 10 output bit */
+#define GPIO_OCTL_OCTL11           BIT(11)               /*!< pin 11 output bit */
+#define GPIO_OCTL_OCTL12           BIT(12)               /*!< pin 12 output bit */
+#define GPIO_OCTL_OCTL13           BIT(13)               /*!< pin 13 output bit */
+#define GPIO_OCTL_OCTL14           BIT(14)               /*!< pin 14 output bit */
+#define GPIO_OCTL_OCTL15           BIT(15)               /*!< pin 15 output bit */
+
+/* GPIO_BOP */
+#define GPIO_BOP_BOP0              BIT(0)                /*!< pin 0 set bit */
+#define GPIO_BOP_BOP1              BIT(1)                /*!< pin 1 set bit */
+#define GPIO_BOP_BOP2              BIT(2)                /*!< pin 2 set bit */
+#define GPIO_BOP_BOP3              BIT(3)                /*!< pin 3 set bit */
+#define GPIO_BOP_BOP4              BIT(4)                /*!< pin 4 set bit */
+#define GPIO_BOP_BOP5              BIT(5)                /*!< pin 5 set bit */
+#define GPIO_BOP_BOP6              BIT(6)                /*!< pin 6 set bit */
+#define GPIO_BOP_BOP7              BIT(7)                /*!< pin 7 set bit */
+#define GPIO_BOP_BOP8              BIT(8)                /*!< pin 8 set bit */
+#define GPIO_BOP_BOP9              BIT(9)                /*!< pin 9 set bit */
+#define GPIO_BOP_BOP10             BIT(10)               /*!< pin 10 set bit */
+#define GPIO_BOP_BOP11             BIT(11)               /*!< pin 11 set bit */
+#define GPIO_BOP_BOP12             BIT(12)               /*!< pin 12 set bit */
+#define GPIO_BOP_BOP13             BIT(13)               /*!< pin 13 set bit */
+#define GPIO_BOP_BOP14             BIT(14)               /*!< pin 14 set bit */
+#define GPIO_BOP_BOP15             BIT(15)               /*!< pin 15 set bit */
+#define GPIO_BOP_CR0               BIT(16)               /*!< pin 0 clear bit */
+#define GPIO_BOP_CR1               BIT(17)               /*!< pin 1 clear bit */
+#define GPIO_BOP_CR2               BIT(18)               /*!< pin 2 clear bit */
+#define GPIO_BOP_CR3               BIT(19)               /*!< pin 3 clear bit */
+#define GPIO_BOP_CR4               BIT(20)               /*!< pin 4 clear bit */
+#define GPIO_BOP_CR5               BIT(21)               /*!< pin 5 clear bit */
+#define GPIO_BOP_CR6               BIT(22)               /*!< pin 6 clear bit */
+#define GPIO_BOP_CR7               BIT(23)               /*!< pin 7 clear bit */
+#define GPIO_BOP_CR8               BIT(24)               /*!< pin 8 clear bit */
+#define GPIO_BOP_CR9               BIT(25)               /*!< pin 9 clear bit */
+#define GPIO_BOP_CR10              BIT(26)               /*!< pin 10 clear bit */
+#define GPIO_BOP_CR11              BIT(27)               /*!< pin 11 clear bit */
+#define GPIO_BOP_CR12              BIT(28)               /*!< pin 12 clear bit */
+#define GPIO_BOP_CR13              BIT(29)               /*!< pin 13 clear bit */
+#define GPIO_BOP_CR14              BIT(30)               /*!< pin 14 clear bit */
+#define GPIO_BOP_CR15              BIT(31)               /*!< pin 15 clear bit */
+
+/* GPIO_LOCK */
+#define GPIO_LOCK_LK0              BIT(0)                /*!< pin 0 lock bit */
+#define GPIO_LOCK_LK1              BIT(1)                /*!< pin 1 lock bit */
+#define GPIO_LOCK_LK2              BIT(2)                /*!< pin 2 lock bit */
+#define GPIO_LOCK_LK3              BIT(3)                /*!< pin 3 lock bit */
+#define GPIO_LOCK_LK4              BIT(4)                /*!< pin 4 lock bit */
+#define GPIO_LOCK_LK5              BIT(5)                /*!< pin 5 lock bit */
+#define GPIO_LOCK_LK6              BIT(6)                /*!< pin 6 lock bit */
+#define GPIO_LOCK_LK7              BIT(7)                /*!< pin 7 lock bit */
+#define GPIO_LOCK_LK8              BIT(8)                /*!< pin 8 lock bit */
+#define GPIO_LOCK_LK9              BIT(9)                /*!< pin 9 lock bit */
+#define GPIO_LOCK_LK10             BIT(10)               /*!< pin 10 lock bit */
+#define GPIO_LOCK_LK11             BIT(11)               /*!< pin 11 lock bit */
+#define GPIO_LOCK_LK12             BIT(12)               /*!< pin 12 lock bit */
+#define GPIO_LOCK_LK13             BIT(13)               /*!< pin 13 lock bit */
+#define GPIO_LOCK_LK14             BIT(14)               /*!< pin 14 lock bit */
+#define GPIO_LOCK_LK15             BIT(15)               /*!< pin 15 lock bit */
+#define GPIO_LOCK_LKK              BIT(16)               /*!< pin sequence lock key */
+
+/* GPIO_AFSEL0 */
+#define GPIO_AFSEL0_SEL0           BITS(0,3)             /*!< pin 0 alternate function selected */
+#define GPIO_AFSEL0_SEL1           BITS(4,7)             /*!< pin 1 alternate function selected */
+#define GPIO_AFSEL0_SEL2           BITS(8,11)            /*!< pin 2 alternate function selected */
+#define GPIO_AFSEL0_SEL3           BITS(12,15)           /*!< pin 3 alternate function selected */
+#define GPIO_AFSEL0_SEL4           BITS(16,19)           /*!< pin 4 alternate function selected */
+#define GPIO_AFSEL0_SEL5           BITS(20,23)           /*!< pin 5 alternate function selected */
+#define GPIO_AFSEL0_SEL6           BITS(24,27)           /*!< pin 6 alternate function selected */
+#define GPIO_AFSEL0_SEL7           BITS(28,31)           /*!< pin 7 alternate function selected */
+
+/* GPIO_AFSEL1 */
+#define GPIO_AFSEL1_SEL8           BITS(0,3)             /*!< pin 8 alternate function selected */
+#define GPIO_AFSEL1_SEL9           BITS(4,7)             /*!< pin 9 alternate function selected */
+#define GPIO_AFSEL1_SEL10          BITS(8,11)            /*!< pin 10 alternate function selected */
+#define GPIO_AFSEL1_SEL11          BITS(12,15)           /*!< pin 11 alternate function selected */
+#define GPIO_AFSEL1_SEL12          BITS(16,19)           /*!< pin 12 alternate function selected */
+#define GPIO_AFSEL1_SEL13          BITS(20,23)           /*!< pin 13 alternate function selected */
+#define GPIO_AFSEL1_SEL14          BITS(24,27)           /*!< pin 14 alternate function selected */
+#define GPIO_AFSEL1_SEL15          BITS(28,31)           /*!< pin 15 alternate function selected */
+
+/* GPIO_BC */
+#define GPIO_BC_CR0                BIT(0)                /*!< pin 0 clear bit */
+#define GPIO_BC_CR1                BIT(1)                /*!< pin 1 clear bit */
+#define GPIO_BC_CR2                BIT(2)                /*!< pin 2 clear bit */
+#define GPIO_BC_CR3                BIT(3)                /*!< pin 3 clear bit */
+#define GPIO_BC_CR4                BIT(4)                /*!< pin 4 clear bit */
+#define GPIO_BC_CR5                BIT(5)                /*!< pin 5 clear bit */
+#define GPIO_BC_CR6                BIT(6)                /*!< pin 6 clear bit */
+#define GPIO_BC_CR7                BIT(7)                /*!< pin 7 clear bit */
+#define GPIO_BC_CR8                BIT(8)                /*!< pin 8 clear bit */
+#define GPIO_BC_CR9                BIT(9)                /*!< pin 9 clear bit */
+#define GPIO_BC_CR10               BIT(10)               /*!< pin 10 clear bit */
+#define GPIO_BC_CR11               BIT(11)               /*!< pin 11 clear bit */
+#define GPIO_BC_CR12               BIT(12)               /*!< pin 12 clear bit */
+#define GPIO_BC_CR13               BIT(13)               /*!< pin 13 clear bit */
+#define GPIO_BC_CR14               BIT(14)               /*!< pin 14 clear bit */
+#define GPIO_BC_CR15               BIT(15)               /*!< pin 15 clear bit */
+
+/* GPIO_TG */
+#define GPIO_TG_TG0                BIT(0)                /*!< pin 0 toggle bit */
+#define GPIO_TG_TG1                BIT(1)                /*!< pin 1 toggle bit */
+#define GPIO_TG_TG2                BIT(2)                /*!< pin 2 toggle bit */
+#define GPIO_TG_TG3                BIT(3)                /*!< pin 3 toggle bit */
+#define GPIO_TG_TG4                BIT(4)                /*!< pin 4 toggle bit */
+#define GPIO_TG_TG5                BIT(5)                /*!< pin 5 toggle bit */
+#define GPIO_TG_TG6                BIT(6)                /*!< pin 6 toggle bit */
+#define GPIO_TG_TG7                BIT(7)                /*!< pin 7 toggle bit */
+#define GPIO_TG_TG8                BIT(8)                /*!< pin 8 toggle bit */
+#define GPIO_TG_TG9                BIT(9)                /*!< pin 9 toggle bit */
+#define GPIO_TG_TG10               BIT(10)               /*!< pin 10 toggle bit */
+#define GPIO_TG_TG11               BIT(11)               /*!< pin 11 toggle bit */
+#define GPIO_TG_TG12               BIT(12)               /*!< pin 12 toggle bit */
+#define GPIO_TG_TG13               BIT(13)               /*!< pin 13 toggle bit */
+#define GPIO_TG_TG14               BIT(14)               /*!< pin 14 toggle bit */
+#define GPIO_TG_TG15               BIT(15)               /*!< pin 15 toggle bit */
+
+/* constants definitions */
+typedef FlagStatus bit_status;
+
+/* output mode definitions */
+#define CTL_CLTR(regval)           (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define GPIO_MODE_INPUT            CTL_CLTR(0)           /*!< input mode */
+#define GPIO_MODE_OUTPUT           CTL_CLTR(1)           /*!< output mode */
+#define GPIO_MODE_AF               CTL_CLTR(2)           /*!< alternate function mode */
+#define GPIO_MODE_ANALOG           CTL_CLTR(3)           /*!< analog mode */
+
+/* pull up pull down definitions */
+#define PUD_PUPD(regval)           (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define GPIO_PUPD_NONE             PUD_PUPD(0)           /*!< without weak pull-up and pull-down resistors */
+#define GPIO_PUPD_PULLUP           PUD_PUPD(1)           /*!< with weak pull-up resistor */
+#define GPIO_PUPD_PULLDOWN         PUD_PUPD(2)           /*!< with weak pull-down resistor */
+
+/* gpio pin definitions */
+#define GPIO_PIN_0                 BIT(0)                /*!< GPIO pin 0 */
+#define GPIO_PIN_1                 BIT(1)                /*!< GPIO pin 1 */
+#define GPIO_PIN_2                 BIT(2)                /*!< GPIO pin 2 */
+#define GPIO_PIN_3                 BIT(3)                /*!< GPIO pin 3 */
+#define GPIO_PIN_4                 BIT(4)                /*!< GPIO pin 4 */
+#define GPIO_PIN_5                 BIT(5)                /*!< GPIO pin 5 */
+#define GPIO_PIN_6                 BIT(6)                /*!< GPIO pin 6 */
+#define GPIO_PIN_7                 BIT(7)                /*!< GPIO pin 7 */
+#define GPIO_PIN_8                 BIT(8)                /*!< GPIO pin 8 */
+#define GPIO_PIN_9                 BIT(9)                /*!< GPIO pin 9 */
+#define GPIO_PIN_10                BIT(10)               /*!< GPIO pin 10 */
+#define GPIO_PIN_11                BIT(11)               /*!< GPIO pin 11 */
+#define GPIO_PIN_12                BIT(12)               /*!< GPIO pin 12 */
+#define GPIO_PIN_13                BIT(13)               /*!< GPIO pin 13 */
+#define GPIO_PIN_14                BIT(14)               /*!< GPIO pin 14 */
+#define GPIO_PIN_15                BIT(15)               /*!< GPIO pin 15 */
+#define GPIO_PIN_ALL               ((uint32_t)(0xFFFF))  /*!< GPIO pin all */
+
+/* gpio ctlr values */
+#define GPIO_MODE_SET(n, mode)     ((uint32_t)((uint32_t)(mode) << (2U * (n))))
+#define GPIO_MODE_MASK(n)          (0x3U << (2U * (n)))
+
+/* gpio pull up pull down values */
+#define GPIO_PUPD_SET(n, pupd)     ((uint32_t)((uint32_t)(pupd) << (2U * (n))))
+#define GPIO_PUPD_MASK(n)          (0x3U << (2U * (n)))
+
+/* gpio output speed values */
+#define GPIO_OSPEED_SET(n, speed)  ((uint32_t)((uint32_t)(speed) << (2U * (n))))
+#define GPIO_OSPEED_MASK(n)        (0x3U << (2U * (n)))
+
+/* gpio output type */
+#define GPIO_OTYPE_PP              ((uint8_t)(0x00))     /*!< push pull mode */
+#define GPIO_OTYPE_OD              ((uint8_t)(0x01))     /*!< open drain mode */
+
+/* gpio output max speed level */
+#define OSPD_OSPD(regval)          (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define GPIO_OSPEED_LEVEL0         OSPD_OSPD(0)          /*!< output max speed level 0 */
+#define GPIO_OSPEED_LEVEL1         OSPD_OSPD(1)          /*!< output max speed level 1 */
+#define GPIO_OSPEED_LEVEL2         OSPD_OSPD(2)          /*!< output max speed level 2 */
+#define GPIO_OSPEED_LEVEL3         OSPD_OSPD(3)          /*!< output max speed level 3 */
+
+/* gpio output max speed value */
+#define GPIO_OSPEED_2MHZ           GPIO_OSPEED_LEVEL0    /*!< output max speed 2M */
+#define GPIO_OSPEED_25MHZ          GPIO_OSPEED_LEVEL1    /*!< output max speed 25M */
+#define GPIO_OSPEED_50MHZ          GPIO_OSPEED_LEVEL2    /*!< output max speed 50M */
+#define GPIO_OSPEED_200MHZ         GPIO_OSPEED_LEVEL3    /*!< output max speed 200M */
+
+/* gpio alternate function values */
+#define GPIO_AFR_SET(n, af)        ((uint32_t)((uint32_t)(af) << (4U * (n))))
+#define GPIO_AFR_MASK(n)           (0xFU << (4U * (n)))
+ 
+/* gpio alternate function */
+#define AF(regval)                 (BITS(0,3) & ((uint32_t)(regval) << 0)) 
+#define GPIO_AF_0                   AF(0)                /*!< alternate function selected 0 */
+#define GPIO_AF_1                   AF(1)                /*!< alternate function selected 1 */
+#define GPIO_AF_2                   AF(2)                /*!< alternate function selected 2 */
+#define GPIO_AF_3                   AF(3)                /*!< alternate function selected 3 */
+#define GPIO_AF_4                   AF(4)                /*!< alternate function selected 4 */
+#define GPIO_AF_5                   AF(5)                /*!< alternate function selected 5 */
+#define GPIO_AF_6                   AF(6)                /*!< alternate function selected 6 */
+#define GPIO_AF_7                   AF(7)                /*!< alternate function selected 7 */
+#define GPIO_AF_8                   AF(8)                /*!< alternate function selected 8 */
+#define GPIO_AF_9                   AF(9)                /*!< alternate function selected 9 */
+#define GPIO_AF_10                  AF(10)               /*!< alternate function selected 10 */
+#define GPIO_AF_11                  AF(11)               /*!< alternate function selected 11 */
+#define GPIO_AF_12                  AF(12)               /*!< alternate function selected 12 */
+#define GPIO_AF_13                  AF(13)               /*!< alternate function selected 13 */
+#define GPIO_AF_14                  AF(14)               /*!< alternate function selected 14 */
+#define GPIO_AF_15                  AF(15)               /*!< alternate function selected 15 */
+
+/* function declarations */
+/* reset gpio port */
+void gpio_deinit(uint32_t gpio_periph);
+/* set gpio mode */
+void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin);
+/* set gpio output type and speed */
+void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin);
+
+/* set gpio pin bit */
+void gpio_bit_set(uint32_t gpio_periph,uint32_t pin);
+/* reset gpio pin bit */
+void gpio_bit_reset(uint32_t gpio_periph,uint32_t pin);
+/* write data to the specified gpio pin */
+void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value);
+/* write data to the specified gpio port */
+void gpio_port_write(uint32_t gpio_periph,uint16_t data);
+
+/* get gpio pin input status */
+FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin);
+/* get gpio port input status */
+uint16_t gpio_input_port_get(uint32_t gpio_periph);
+/* get gpio pin output status */
+FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin);
+/* get gpio port output status */
+uint16_t gpio_output_port_get(uint32_t gpio_periph);
+
+/* set gpio alternate function */
+void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin);
+/* lock gpio pin bit */
+void gpio_pin_lock(uint32_t gpio_periph,uint32_t pin);
+
+/* toggle gpio pin status */
+void gpio_bit_toggle(uint32_t gpio_periph,uint32_t pin);
+/* toggle gpio port status */
+void gpio_port_toggle(uint32_t gpio_periph);
+
+#endif /* GD32F4XX_GPIO_H */

+ 331 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h

@@ -0,0 +1,331 @@
+/*!
+    \file  gd32f4xx_i2c.h
+    \brief definitions for the I2C
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_I2C_H
+#define GD32F4XX_I2C_H
+
+#include "gd32f4xx.h"
+
+/* I2Cx(x=0,1,2) definitions */
+#define I2C0                          I2C_BASE
+#define I2C1                          (I2C_BASE+0x400U)
+#define I2C2                          (I2C_BASE+0x800U)
+
+/* registers definitions */
+#define I2C_CTL0(i2cx)                REG32((i2cx) + 0x00U)      /*!< I2C control register 0 */
+#define I2C_CTL1(i2cx)                REG32((i2cx) + 0x04U)      /*!< I2C control register 1 */
+#define I2C_SADDR0(i2cx)              REG32((i2cx) + 0x08U)      /*!< I2C slave address register 0*/
+#define I2C_SADDR1(i2cx)              REG32((i2cx) + 0x0CU)      /*!< I2C slave address register */
+#define I2C_DATA(i2cx)                REG32((i2cx) + 0x10U)      /*!< I2C transfer buffer register */
+#define I2C_STAT0(i2cx)               REG32((i2cx) + 0x14U)      /*!< I2C transfer status register 0 */
+#define I2C_STAT1(i2cx)               REG32((i2cx) + 0x18U)      /*!< I2C transfer status register */
+#define I2C_CKCFG(i2cx)               REG32((i2cx) + 0x1CU)      /*!< I2C clock configure register */
+#define I2C_RT(i2cx)                  REG32((i2cx) + 0x20U)      /*!< I2C rise time register */
+#define I2C_FCTL(i2cx)                REG32((i2cx) + 0x24U)      /*!< I2C filter control register */
+#define I2C_SAMCS(i2cx)               REG32((i2cx) + 0x80U)      /*!< I2C SAM control and status register */
+
+
+/* bits definitions */
+/* I2Cx_CTL0 */
+#define I2C_CTL0_I2CEN                BIT(0)        /*!< peripheral enable */
+#define I2C_CTL0_SMBEN                BIT(1)        /*!< SMBus mode */
+#define I2C_CTL0_SMBSEL               BIT(3)        /*!< SMBus type */
+#define I2C_CTL0_ARPEN                BIT(4)        /*!< ARP enable */
+#define I2C_CTL0_PECEN                BIT(5)        /*!< PEC enable */
+#define I2C_CTL0_GCEN                 BIT(6)        /*!< general call enable */
+#define I2C_CTL0_DISSTRC              BIT(7)        /*!< clock stretching disable (slave mode) */
+#define I2C_CTL0_START                BIT(8)        /*!< start generation */
+#define I2C_CTL0_STOP                 BIT(9)        /*!< stop generation */
+#define I2C_CTL0_ACKEN                BIT(10)       /*!< acknowledge enable */
+#define I2C_CTL0_POAP                 BIT(11)       /*!< acknowledge/PEC position (for data reception) */
+#define I2C_CTL0_PECTRANS             BIT(12)       /*!< packet error checking */
+#define I2C_CTL0_SALT                 BIT(13)       /*!< SMBus alert */
+#define I2C_CTL0_SRESET               BIT(15)       /*!< software reset */
+
+/* I2Cx_CTL1 */
+#define I2C_CTL1_I2CCLK               BITS(0,5)     /*!< I2CCLK[5:0] bits (peripheral clock frequency) */
+#define I2C_CTL1_ERRIE                BIT(8)        /*!< error interrupt inable */
+#define I2C_CTL1_EVIE                 BIT(9)        /*!< event interrupt enable */
+#define I2C_CTL1_BUFIE                BIT(10)       /*!< buffer interrupt enable */
+#define I2C_CTL1_DMAON                BIT(11)       /*!< DMA requests enable */
+#define I2C_CTL1_DMALST               BIT(12)       /*!< DMA last transfer */
+
+/* I2Cx_SADDR0 */
+#define I2C_SADDR0_ADDRESS0           BIT(0)        /*!< bit 0 of a 10-bit address */
+#define I2C_SADDR0_ADDRESS            BITS(1,7)     /*!< 7-bit address or bits 7:1 of a 10-bit address */
+#define I2C_SADDR0_ADDRESS_H          BITS(8,9)     /*!< highest two bits of a 10-bit address */
+#define I2C_SADDR0_ADDFORMAT          BIT(15)       /*!< address mode for the I2C slave */
+
+/* I2Cx_SADDR1 */
+#define I2C_SADDR1_DUADEN             BIT(0)        /*!< aual-address mode switch */
+#define I2C_SADDR1_ADDRESS2           BITS(1,7)     /*!< second I2C address for the slave in dual-address mode */
+
+/* I2Cx_DATA */
+#define I2C_DATA_TRB                  BITS(0,7)     /*!< 8-bit data register */
+
+/* I2Cx_STAT0 */
+#define I2C_STAT0_SBSEND              BIT(0)        /*!< start bit (master mode) */
+#define I2C_STAT0_ADDSEND             BIT(1)        /*!< address sent (master mode)/matched (slave mode) */
+#define I2C_STAT0_BTC                 BIT(2)        /*!< byte transfer finished */
+#define I2C_STAT0_ADD10SEND           BIT(3)        /*!< 10-bit header sent (master mode) */
+#define I2C_STAT0_STPDET              BIT(4)        /*!< stop detection (slave mode) */
+#define I2C_STAT0_RBNE                BIT(6)        /*!< data register not empty (receivers) */
+#define I2C_STAT0_TBE                 BIT(7)        /*!< data register empty (transmitters) */
+#define I2C_STAT0_BERR                BIT(8)        /*!< bus error */
+#define I2C_STAT0_LOSTARB             BIT(9)        /*!< arbitration lost (master mode) */
+#define I2C_STAT0_AERR                BIT(10)       /*!< acknowledge failure */
+#define I2C_STAT0_OUERR               BIT(11)       /*!< overrun/underrun */
+#define I2C_STAT0_PECERR              BIT(12)       /*!< PEC error in reception */
+#define I2C_STAT0_SMBTO               BIT(14)       /*!< timeout signal in SMBus mode */
+#define I2C_STAT0_SMBALT              BIT(15)       /*!< SMBus alert status */
+
+/* I2Cx_STAT1 */
+#define I2C_STAT1_MASTER              BIT(0)        /*!< master/slave */
+#define I2C_STAT1_I2CBSY              BIT(1)        /*!< bus busy */
+#define I2C_STAT1_TRS                 BIT(2)        /*!< transmitter/receiver */
+#define I2C_STAT1_RXGC                BIT(4)        /*!< general call address (slave mode) */
+#define I2C_STAT1_DEFSMB              BIT(5)        /*!< SMBus device default address (slave mode) */
+#define I2C_STAT1_HSTSMB              BIT(6)        /*!< SMBus host header (slave mode) */
+#define I2C_STAT1_DUMODF              BIT(7)        /*!< dual flag (slave mode) */
+#define I2C_STAT1_ECV                 BITS(8,15)    /*!< packet error checking register */
+
+/* I2Cx_CKCFG */
+#define I2C_CKCFG_CLKC                BITS(0,11)    /*!< clock control register in fast/standard mode (master mode) */
+#define I2C_CKCFG_DTCY                BIT(14)       /*!< fast mode duty cycle */
+#define I2C_CKCFG_FAST                BIT(15)       /*!< I2C speed selection in master mode */
+
+/* I2Cx_RT */
+#define I2C_RT_RISETIME               BITS(0,5)     /*!< maximum rise time in fast/standard mode (Master mode) */
+
+/* I2Cx_FCTL */
+#define I2C_FCTL_DF                   BITS(0,3)     /*!< digital noise filter */
+#define I2C_FCTL_AFD                  BIT(4)        /*!< analog noise filter disable */
+
+/* I2Cx_SAMCS */
+#define I2C_SAMCS_SAMEN               BIT(0)        /*!< SAM_V interface enable */
+#define I2C_SAMCS_STOEN               BIT(1)        /*!< SAM_V interface timeout detect enable */
+#define I2C_SAMCS_TFFIE               BIT(4)        /*!< txframe fall interrupt enable */
+#define I2C_SAMCS_TFRIE               BIT(5)        /*!< txframe rise interrupt enable */
+#define I2C_SAMCS_RFFIE               BIT(6)        /*!< rxframe fall interrupt enable */
+#define I2C_SAMCS_RFRIE               BIT(7)        /*!< rxframe rise interrupt enable */
+#define I2C_SAMCS_TXF                 BIT(8)        /*!< level of txframe signal */
+#define I2C_SAMCS_RXF                 BIT(9)        /*!< level of rxframe signal */
+#define I2C_SAMCS_TFF                 BIT(12)       /*!< txframe fall flag, cleared by software write 0 */
+#define I2C_SAMCS_TFR                 BIT(13)       /*!< txframe rise flag, cleared by software write 0 */
+#define I2C_SAMCS_RFF                 BIT(14)       /*!< rxframe fall flag, cleared by software write 0 */
+#define I2C_SAMCS_RFR                 BIT(15)       /*!< rxframe rise flag, cleared by software write 0 */
+
+
+/* constants definitions */
+
+/* the digital noise filter can filter spikes's length */
+typedef enum {
+    I2C_DF_DISABLE,                                     /*!< disable digital noise filter */
+    I2C_DF_1PCLK,                                       /*!< enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 */
+    I2C_DF_2PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 */
+    I2C_DF_3PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 */
+    I2C_DF_4PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 */
+    I2C_DF_5PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 */
+    I2C_DF_6PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 */
+    I2C_DF_7PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 */
+    I2C_DF_8PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 */
+    I2C_DF_9PCLKS,                                      /*!< enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 */
+    I2C_DF_10PCLKS,                                     /*!< enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 */
+    I2C_DF_11PCLKS,                                     /*!< enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 */
+    I2C_DF_12PCLKS,                                     /*!< enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 */
+    I2C_DF_13PCLKS,                                     /*!< enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 */
+    I2C_DF_14PCLKS,                                     /*!< enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 */
+    I2C_DF_15PCLKS                                      /*!< enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 */
+}i2c_digital_filter_enum;
+
+/* SMBus/I2C mode switch and SMBus type selection */
+#define I2C_I2CMODE_ENABLE            ((uint32_t)0x00000000U)                  /*!< I2C mode */
+#define I2C_SMBUSMODE_ENABLE          I2C_CTL0_SMBEN                           /*!< SMBus mode */
+
+/* SMBus/I2C mode switch and SMBus type selection */
+#define I2C_SMBUS_DEVICE              ((uint32_t)0x00000000U)                  /*!< SMBus mode device type */
+#define I2C_SMBUS_HOST                I2C_CTL0_SMBSEL                          /*!< SMBus mode host type */
+/* I2C transfer direction */
+#define I2C_TRANSMITTER               (~BIT(0))                                /*!< transmitter */
+#define I2C_RECEIVER                  BIT(0)                                   /*!< receiver */
+
+/* whether or not to send an ACK */
+#define I2C_ACK_ENABLE                ((uint8_t)0x01U)                         /*!< ACK will be sent */
+#define I2C_ACK_DISABLE               ((uint8_t)0x00U)                         /*!< ACK will be not sent */
+
+/* I2C POAP position*/
+#define I2C_ACKPOS_CURRENT            ((uint8_t)0x01U)                         /*!< ACKEN bit decides whether to send ACK or not for the current */
+#define I2C_ACKPOS_NEXT               ((uint8_t)0x00U)                         /*!< ACKEN bit decides whether to send ACK or not for the next byte */
+
+/* I2C dual-address mode switch */
+#define I2C_DUADEN_DISABLE            ((uint8_t)0x00U)                         /*!< dual-address mode disabled */
+#define I2C_DUADEN_ENABLE             ((uint8_t)0x01U)                         /*!< dual-address mode enabled */
+
+/* whether or not to stretch SCL low */
+#define I2C_SCLSTRETCH_ENABLE         ((uint32_t)0x00000000U)                  /*!< SCL stretching is enabled */
+#define I2C_SCLSTRETCH_DISABLE        I2C_CTL0_DISSTRC                         /*!< SCL stretching is disabled */
+
+/* whether or not to response to a General Call */
+#define I2C_GCEN_ENABLE               I2C_CTL0_GCEN                            /*!< slave will response to a general call */
+#define I2C_GCEN_DISABLE              ((uint32_t)0x00000000U)                  /*!< slave will not response to a general call */
+
+/* software reset I2C */
+#define I2C_SRESET_SET                I2C_CTL0_SRESET                          /*!< I2C is under reset */
+#define I2C_SRESET_RESET              ((uint32_t)0x00000000U)                  /*!< I2C is not under reset */
+
+/* I2C DMA mode configure */
+/* DMA mode switch */
+#define I2C_DMA_ON                    I2C_CTL1_DMAON                           /*!< DMA mode enabled */
+#define I2C_DMA_OFF                   ((uint32_t)0x00000000U)                  /*!< DMA mode disabled */
+/* flag indicating DMA last transfer */
+#define I2C_DMALST_ON                 I2C_CTL1_DMALST                          /*!< next DMA EOT is the last transfer */
+#define I2C_DMALST_OFF                ((uint32_t)0x00000000U)                  /*!< next DMA EOT is not the last transfer */
+
+
+/* I2C PEC configure */
+/* PEC enable */
+#define I2C_PEC_ENABLE                I2C_CTL0_PECEN                           /*!< PEC calculation on */
+#define I2C_PEC_DISABLE              ((uint32_t)0x00000000U)                   /*!< PEC calculation off */
+
+/* PEC transfer */
+#define I2C_PECTRANS_ENABLE           I2C_CTL0_PECTRANS                        /*!< transfer PEC */
+#define I2C_PECTRANS_DISABLE          ((uint32_t)0x00000000U)                  /*!< not transfer PEC value */
+
+/* I2C SMBus configure */
+/* issue or not alert through SMBA pin */
+#define I2C_SALTSEND_ENABLE           I2C_CTL0_SALT                            /*!< issue alert through SMBA pin */
+#define I2C_SALTSEND_DISABLE          ((uint32_t)0x00000000U)                  /*!< not issue alert through SMBA */
+/* ARP protocol in SMBus switch */
+#define I2C_ARP_ENABLE                I2C_CTL0_ARPEN                           /*!< ARP is enabled */
+#define I2C_ARP_DISABLE               ((uint32_t)0x00000000U)                  /*!< ARP is disabled */
+
+/* I2C state */
+/* I2C bit state */
+#define I2C_SBSEND                    BIT(0)                                   /*!< start condition sent out in master mode */
+#define I2C_ADDSEND                   BIT(1)                                   /*!< address is sent in master mode or received and matches in slave mode */
+#define I2C_BTC                       BIT(2)                                   /*!< byte transmission finishes */
+#define I2C_ADD10SEND                 BIT(3)                                   /*!< header of 10-bit address is sent in master mode */
+#define I2C_STPDET                    BIT(4)                                   /*!< etop condition detected in slave mode */
+#define I2C_RBNE                      BIT(6)                                   /*!< I2C_DATA is not Empty during receiving */
+#define I2C_TBE                       BIT(7)                                   /*!< I2C_DATA is empty during transmitting */
+#define I2C_BERR                      BIT(8)                                   /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */
+#define I2C_LOSTARB                   BIT(9)                                   /*!< arbitration lost in master mode */
+#define I2C_AERR                      BIT(10)                                  /*!< acknowledge error */
+#define I2C_OUERR                     BIT(11)                                  /*!< over-run or under-run situation occurs in slave mode */
+#define I2C_PECERR                    BIT(12)                                  /*!< PEC error when receiving data */
+#define I2C_SMBTO                     BIT(14)                                  /*!< timeout signal in SMBus mode */
+#define I2C_SMBALT                    BIT(15)                                  /*!< SMBus alert status */
+#define I2C_MASTER                    (BIT(0)|BIT(31))                         /*!< a flag indicating whether I2C block is in master or slave mode */
+#define I2C_I2CBSY                    (BIT(1)|BIT(31))                         /*!< busy flag */
+#define I2C_TRS                       (BIT(2)|BIT(31))                         /*!< whether the I2C is a transmitter or a receiver */
+#define I2C_RXGC                      (BIT(4)|BIT(31))                         /*!< general call address (00h) received */
+#define I2C_DEFSMB                    (BIT(5)|BIT(31))                         /*!< default address of SMBus device */
+#define I2C_HSTSMB                    (BIT(6)|BIT(31))                         /*!< SMBus host header detected in slave mode */
+#define I2C_DUMODF                    (BIT(7)|BIT(31))                         /*!< dual flag in slave mode indicating which address is matched in dual-address mode */
+
+/* I2C duty cycle in fast mode */
+#define CKCFG_DTCY(regval)            (BIT(14) & ((uint32_t)(regval) << 14))
+#define I2C_DTCY_2                    CKCFG_DTCY(0)                            /*!< I2C fast mode Tlow/Thigh = 2 */
+#define I2C_DTCY_16_9                 CKCFG_DTCY(1)                            /*!< I2C fast mode Tlow/Thigh = 16/9 */
+
+/* address mode for the I2C slave */
+#define SADDR0_ADDFORMAT(regval)      (BIT(15) & ((regval) << 15))
+#define I2C_ADDFORMAT_7BITS           SADDR0_ADDFORMAT(0)                      /*!< address:7 bits */
+#define I2C_ADDFORMAT_10BITS          SADDR0_ADDFORMAT(1)                      /*!< address:10 bits */
+
+/* function declarations */
+/* reset I2C */
+void i2c_deinit(uint32_t i2c_periph);
+/* I2C clock configure */
+void i2c_clock_config(uint32_t i2c_periph,uint32_t clkspeed,uint32_t dutycyc);
+/* I2C address configure */
+void i2c_mode_addr_config(uint32_t i2c_periph,uint32_t i2cmod,uint32_t addformat,uint32_t addr);
+/* SMBus type selection */
+void i2c_smbus_type_config(uint32_t i2c_periph,uint32_t type);
+/* whether or not to send an ACK */
+void i2c_ack_config(uint32_t i2c_periph,uint8_t ack);
+/* I2C POAP position configure */
+void i2c_ackpos_config(uint32_t i2c_periph,uint8_t pos);
+/* master send slave address */
+void i2c_master_addressing(uint32_t i2c_periph,uint8_t addr,uint32_t trandirection);
+/* dual-address mode switch */
+void i2c_dualaddr_enable(uint32_t i2c_periph, uint8_t dualaddr);
+
+/* enable i2c */
+void i2c_enable(uint32_t i2c_periph);
+/* disable i2c */
+void i2c_disable(uint32_t i2c_periph);
+/* generate a START condition on I2C bus */
+void i2c_start_on_bus(uint32_t i2c_periph);
+/* generate a STOP condition on I2C bus */
+void i2c_stop_on_bus(uint32_t i2c_periph);
+/* i2c transmit data function */
+void i2c_transmit_data(uint32_t i2c_periph,uint8_t data);
+/* i2c receive data function */
+uint8_t i2c_receive_data(uint32_t i2c_periph);
+/* I2C DMA mode enable */
+void i2c_dma_enable(uint32_t i2c_periph,uint32_t dmastste);
+/* flag indicating DMA last transfer */
+void i2c_dma_last_transfer_enable(uint32_t i2c_periph,uint32_t dmalast);
+/* whether to stretch SCL low when data is not ready in slave mode  */
+void i2c_stretch_scl_low_config(uint32_t i2c_periph,uint32_t stretchpara );
+/* whether or not to response to a general call  */
+void i2c_slave_response_to_gcall_config(uint32_t i2c_periph,uint32_t gcallpara);
+/* software reset I2C  */
+void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset);
+
+/* check i2c state */
+FlagStatus i2c_flag_get(uint32_t i2c_periph,uint32_t state);
+/* clear i2c state */
+void i2c_flag_clear(uint32_t i2c_periph,uint32_t state);
+/* enable i2c interrupt */
+void i2c_interrupt_enable(uint32_t i2c_periph,uint32_t inttype);
+/* disable i2c interrupt */
+void i2c_interrupt_disable(uint32_t i2c_periph,uint32_t inttype);
+
+/* I2C PEC calculation on or off */
+void i2c_pec_enable(uint32_t i2c_periph,uint32_t pecstate);
+/* I2C whether to transfer PEC value */
+void i2c_pec_transfer_enable(uint32_t i2c_periph,uint32_t pecpara);
+/* packet error checking value  */
+uint8_t i2c_pec_value(uint32_t i2c_periph);
+
+/* I2C issue alert through SMBA pin */
+void i2c_smbus_alert_issue(uint32_t i2c_periph,uint32_t smbuspara);
+/* I2C ARP protocol in SMBus switch  */
+void i2c_smbus_arp_enable(uint32_t i2c_periph,uint32_t arpstate);
+
+/* I2C analog noise filter disable */
+void i2c_analog_noise_filter_disable(uint32_t i2c_periph);
+/* I2C analog noise filter enable */
+void i2c_analog_noise_filter_enable(uint32_t i2c_periph);
+/* digital noise filter */
+void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara);
+
+/* enable SAM_V interface */
+void i2c_sam_enable(uint32_t i2c_periph);
+/* disable SAM_V interface */
+void i2c_sam_disable(uint32_t i2c_periph);
+/* enable SAM_V interface timeout detect */
+void i2c_sam_timeout_enable(uint32_t i2c_periph);
+/* disable SAM_V interface timeout detect */
+void i2c_sam_timeout_disable(uint32_t i2c_periph);
+/* enable the specified I2C SAM interrupt */
+void i2c_sam_interrupt_enable(uint32_t i2c_periph,uint32_t inttype);
+/* disable the specified I2C SAM interrupt */
+void i2c_sam_interrupt_disable(uint32_t i2c_periph,uint32_t inttype);
+/* check i2c SAM state */
+FlagStatus i2c_sam_flag_get(uint32_t i2c_periph,uint32_t samstate);
+/* clear i2c SAM state */
+void i2c_sam_flag_clear(uint32_t i2c_periph,uint32_t samstate);
+
+
+#endif /* GD32F4XX_I2C_H */

+ 320 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h

@@ -0,0 +1,320 @@
+/*!
+    \file  gd32f4xx_ipa.h
+    \brief definitions for the IPA
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_IPA_H
+#define GD32F4XX_IPA_H
+
+#include "gd32f4xx.h"
+
+/* TLI definitions */
+#define IPA                               IPA_BASE               /*!< IPA base address */
+
+/* bits definitions */
+/* registers definitions */
+#define IPA_CTL                           REG32(IPA + 0x00U)     /*!< IPA control register */
+#define IPA_INTF                          REG32(IPA + 0x04U)     /*!< IPA interrupt flag register */
+#define IPA_INTC                          REG32(IPA + 0x08U)     /*!< IPA interrupt flag clear register */
+#define IPA_FMADDR                        REG32(IPA + 0x0CU)     /*!< IPA foreground memory base address register */
+#define IPA_FLOFF                         REG32(IPA + 0x10U)     /*!< IPA foreground line offset register */
+#define IPA_BMADDR                        REG32(IPA + 0x14U)     /*!< IPA background memory base address register  */
+#define IPA_BLOFF                         REG32(IPA + 0x18U)     /*!< IPA background line offset register */
+#define IPA_FPCTL                         REG32(IPA + 0x1CU)     /*!< IPA foreground pixel control register */
+#define IPA_FPV                           REG32(IPA + 0x20U)     /*!< IPA foreground pixel value register */
+#define IPA_BPCTL                         REG32(IPA + 0x24U)     /*!< IPA background pixel control register */
+#define IPA_BPV                           REG32(IPA + 0x28U)     /*!< IPA background pixel value register */
+#define IPA_FLMADDR                       REG32(IPA + 0x2CU)     /*!< IPA foreground LUT memory base address register */
+#define IPA_BLMADDR                       REG32(IPA + 0x30U)     /*!< IPA background LUT memory base address register */
+#define IPA_DPCTL                         REG32(IPA + 0x34U)     /*!< IPA destination pixel control register */
+#define IPA_DPV                           REG32(IPA + 0x38U)     /*!< IPA destination pixel value register  */
+#define IPA_DMADDR                        REG32(IPA + 0x3CU)     /*!< IPA destination memory base address register */
+#define IPA_DLOFF                         REG32(IPA + 0x40U)     /*!< IPA destination line offset register */
+#define IPA_IMS                           REG32(IPA + 0x44U)     /*!< IPA image size register */
+#define IPA_LM                            REG32(IPA + 0x48U)     /*!< IPA line mark register  */
+#define IPA_ITCTL                         REG32(IPA + 0x4CU)     /*!< IPA inter-timer control register */
+
+/* IPA_CTL */
+#define IPA_CTL_TEN                       BIT(0)           /*!< transfer enable */
+#define IPA_CTL_THU                       BIT(1)           /*!< transfer hang up */
+#define IPA_CTL_TST                       BIT(2)           /*!< transfer stop */
+#define IPA_CTL_TAEIE                     BIT(8)           /*!< enable bit for transfer access error interrupt */
+#define IPA_CTL_FTFIE                     BIT(9)           /*!< enable bit for full transfer finish interrup */
+#define IPA_CTL_TLMIE                     BIT(10)          /*!< enable bit for transfer line mark interrupt */
+#define IPA_CTL_LACIE                     BIT(11)          /*!< enable bit for LUT access conflict interrupt */
+#define IPA_CTL_LLFIE                     BIT(12)          /*!< enable bit for LUT loading finish interrupt */
+#define IPA_CTL_WCFIE                     BIT(13)          /*!< enable bit for wrong configuration interrupt */
+#define IPA_CTL_PFCM                      BITS(16,17)      /*!< pixel format convert mode */
+
+/* IPA_INTF */
+#define IPA_INTF_TAEIF                    BIT(0)           /*!< transfer access error interrupt flag */
+#define IPA_INTF_FTFIF                    BIT(1)           /*!< full transfer finish interrupt flag */
+#define IPA_INTF_TLMIF                    BIT(2)           /*!< transfer line mark interrupt flag */
+#define IPA_INTF_LACIF                    BIT(3)           /*!< LUT access conflict interrupt flag */
+#define IPA_INTF_LLFIF                    BIT(4)           /*!< LUT loading finish interrupt flag */
+#define IPA_INTF_WCFIF                    BIT(5)           /*!< wrong configuration interrupt flag */
+
+/* IPA_INTC */
+#define IPA_INTC_TAEIFC                   BIT(0)           /*!< clear bit for transfer access error interrupt flag */
+#define IPA_INTC_FTFIFC                   BIT(1)           /*!< clear bit for full transfer finish interrupt flag */
+#define IPA_INTC_TLMIFC                   BIT(2)           /*!< clear bit for transfer line mark interrupt flag */
+#define IPA_INTC_LACIFC                   BIT(3)           /*!< clear bit for LUT access conflict interrupt flag */
+#define IPA_INTC_LLFIFC                   BIT(4)           /*!< clear bit for LUT loading finish interrupt flag */
+#define IPA_INTC_WCFIFC                   BIT(5)           /*!< clear bit for wrong configuration interrupt flag */
+
+/* IPA_FMADDR */
+#define IPA_FMADDR_FMADDR                 BITS(0,31)       /*!< foreground memory base address */
+
+/* IPA_FLOFF */
+#define IPA_FLOFF_FLOFF                   BITS(0,13)       /*!< foreground line offset */
+
+/* IPA_BMADDR */
+#define IPA_BMADDR_BMADDR                 BITS(0,31)       /*!< background memory base address */
+
+/* IPA_BLOFF */
+#define IPA_BLOFF_BLOFF                   BITS(0,13)       /*!< background line offset */
+
+/* IPA_FPCTL */
+#define IPA_FPCTL_FPF                     BITS(0,3)        /*!< foreground pixel format */
+#define IPA_FPCTL_FLPF                    BIT(4)           /*!< foreground LUT pixel format */
+#define IPA_FPCTL_FLLEN                   BIT(5)           /*!< foreground LUT loading enable */
+#define IPA_FPCTL_FCNP                    BITS(8,15)       /*!< foreground LUT number of pixel */
+#define IPA_FPCTL_FAVCA                   BITS(16,17)      /*!< foreground alpha value calculation algorithm */
+#define IPA_FPCTL_FPDAV                   BITS(24,31)      /*!< foreground pre- defined alpha value */
+
+/* IPA_FPV */
+#define IPA_FPV_FPDBV                     BITS(0,7)        /*!< foreground pre-defined red value */
+#define IPA_FPV_FPDGV                     BITS(8,15)       /*!< foreground pre-defined green value */
+#define IPA_FPV_FPDRV                     BITS(16,23)      /*!< foreground pre-defined red value */
+
+/* IPA_BPCTL */
+#define IPA_BPCTL_BPF                     BITS(0,3)        /*!< background pixel format */
+#define IPA_BPCTL_BLPF                    BIT(4)           /*!< background LUT pixel format */
+#define IPA_BPCTL_BLLEN                   BIT(5)           /*!< background LUT loading enable */
+#define IPA_BPCTL_BCNP                    BITS(8,15)       /*!< background LUT number of pixel */
+#define IPA_BPCTL_BAVCA                   BITS(16,17)      /*!< background alpha value calculation algorithm */
+#define IPA_BPCTL_BPDAV                   BITS(24,31)      /*!< background pre- defined alpha value */
+
+/* IPA_BPV */
+#define IPA_BPV_BPDBV                     BITS(0,7)        /*!< background pre-defined blue value */
+#define IPA_BPV_BPDGV                     BITS(8,15)       /*!< background pre-defined green value */
+#define IPA_BPV_BPDRV                     BITS(16,23)      /*!< background pre-defined red value */
+
+/* IPA_FLMADDR */
+#define IPA_FLMADDR_FLMADDR               BITS(0,31)       /*!< foreground LUT memory base address */
+
+/* IPA_BLMADDR */
+#define IPA_BLMADDR_BLMADDR               BITS(0,31)       /*!< background LUT memory base address */
+
+/* IPA_DPCTL */
+#define IPA_DPCTL_DPF                     BITS(0,2)       /*!< destination pixel control register */
+
+/* IPA_DPV */
+/* destination pixel format ARGB8888 */
+#define IPA_DPV_DPDBV_0                   BITS(0,7)        /*!< destination pre-defined blue value */
+#define IPA_DPV_DPDGV_0                   BITS(8,15)       /*!< destination pre-defined green value */
+#define IPA_DPV_DPDRV_0                   BITS(16,23)      /*!< destination pre-defined red value */
+#define IPA_DPV_DPDAV_0                   BITS(24,31)      /*!< destination pre-defined alpha value */
+
+/* destination pixel format RGB8888 */
+#define IPA_DPV_DPDBV_1                   BITS(0,7)        /*!< destination pre-defined blue value */
+#define IPA_DPV_DPDGV_1                   BITS(8,15)       /*!< destination pre-defined green value */
+#define IPA_DPV_DPDRV_1                   BITS(16,23)      /*!< destination pre-defined red value */
+
+/* destination pixel format RGB565 */
+#define IPA_DPV_DPDBV_2                   BITS(0,4)        /*!< destination pre-defined blue value */
+#define IPA_DPV_DPDGV_2                   BITS(5,10)       /*!< destination pre-defined green value */
+#define IPA_DPV_DPDRV_2                   BITS(11,15)      /*!< destination pre-defined red value */
+
+/* destination pixel format ARGB1555 */
+#define IPA_DPV_DPDBV_3                   BITS(0,4)        /*!< destination pre-defined blue value */
+#define IPA_DPV_DPDGV_3                   BITS(5,9)        /*!< destination pre-defined green value */
+#define IPA_DPV_DPDRV_3                   BITS(10,14)      /*!< destination pre-defined red value */
+#define IPA_DPV_DPDAV_3                   BIT(15)          /*!< destination pre-defined alpha value */
+
+/* destination pixel format ARGB4444 */
+#define IPA_DPV_DPDBV_4                   BITS(0,3)        /*!< destination pre-defined blue value */
+#define IPA_DPV_DPDGV_4                   BITS(4,7)        /*!< destination pre-defined green value */
+#define IPA_DPV_DPDRV_4                   BITS(8,11)       /*!< destination pre-defined red value */
+#define IPA_DPV_DPDAV_4                   BITS(12,15)      /*!< destination pre-defined alpha value */
+
+/* IPA_DMADDR */
+#define IPA_DMADDR_DMADDR                 BITS(0,31)       /*!< destination memory base address */
+
+/* IPA_DLOFF */
+#define IPA_DLOFF_DLOFF                   BITS(0,13)       /*!< destination line offset */
+
+/* IPA_IMS */
+#define IPA_IMS_HEIGHT                    BITS(0,15)       /*!< height of the image to be processed */
+#define IPA_IMS_WIDTH                     BITS(16,29)      /*!< width of the image to be processed */
+
+/* IPA_LM */
+#define IPA_LM_LM                         BITS(0,15)       /*!< line mark */
+
+/* IPA_ITCTL */
+#define IPA_ITCTL_ITEN                    BIT(0)           /*!< inter-timer enable */
+#define IPA_ITCTL_NCCI                    BITS(8,15)       /*!< number of clock cycles interval */
+
+
+/* constants definitions */
+/* IPA foreground parameter struct definitions */
+typedef struct
+{   
+    uint32_t foreground_memaddr;                          /*!< foreground memory base address */
+    uint32_t foreground_lineoff;                          /*!< foreground line offset */
+    uint32_t foreground_prealpha;                         /*!< foreground pre-defined alpha value */
+    uint32_t foreground_alpha_algorithm;                  /*!< foreground alpha value calculation algorithm */
+    uint32_t foreground_pf;                               /*!< foreground pixel format */
+    uint32_t foreground_prered;                           /*!< foreground pre-defined red value */
+    uint32_t foreground_pregreen;                         /*!< foreground pre-defined green value */
+    uint32_t foreground_preblue;                          /*!< foreground pre-defined blue value */
+}ipa_foreground_parameter_struct; 
+
+/* IPA background parameter struct definitions */
+typedef struct
+{   
+    uint32_t background_memaddr;                          /*!< background memory base address */
+    uint32_t background_lineoff;                          /*!< background line offset */
+    uint32_t background_prealpha;                         /*!< background pre-defined alpha value */
+    uint32_t background_alpha_algorithm;                  /*!< background alpha value calculation algorithm */                                          
+    uint32_t background_pf;                               /*!< background pixel format */
+    uint32_t background_prered;                           /*!< background pre-defined red value */
+    uint32_t background_pregreen;                         /*!< background pre-defined green value */
+    uint32_t background_preblue;                          /*!< background pre-defined blue value */
+}ipa_background_parameter_struct; 
+
+/* IPA destination parameter struct definitions */
+typedef struct
+{
+    uint32_t destination_memaddr;                         /*!< destination memory base address */    
+    uint32_t destination_lineoff;                         /*!< destination line offset */
+    uint32_t destination_prealpha;                        /*!< destination pre-defined alpha value */
+    uint32_t destination_pf;                              /*!< destination pixel format */
+    uint32_t destination_prered;                          /*!< destination pre-defined red value */
+    uint32_t destination_pregreen;                        /*!< destination pre-defined green value */
+    uint32_t destination_preblue;                         /*!< destination pre-defined blue value */
+    uint32_t image_width;                                 /*!< width of the image to be processed */
+    uint32_t image_height;                                /*!< height of the image to be processed */                                          
+}ipa_destination_parameter_struct; 
+
+/* destination pixel format */
+typedef enum 
+{
+    IPA_DPF_ARGB8888,                                         /*!< destination pixel format ARGB8888 */
+    IPA_DPF_RGB888,                                           /*!< destination pixel format RGB888 */
+    IPA_DPF_RGB565,                                           /*!< destination pixel format RGB565 */
+    IPA_DPF_ARGB1555,                                         /*!< destination pixel format ARGB1555 */
+    IPA_DPF_ARGB4444                                          /*!< destination pixel format ARGB4444 */
+} ipa_dpf_enum;
+
+/* LUT pixel format */
+#define IPA_LUT_PF_ARGB8888             ((uint8_t)0x00U)                 /*!< LUT pixel format ARGB8888 */
+#define IPA_LUT_PF_RGB888               ((uint8_t)0x01U)                 /*!< LUT pixel format RGB888 */
+
+/* Inter-timer */
+#define IPA_INTER_TIMER_DISABLE         ((uint8_t)0x00U)                 /*!< Inter-timer disable */
+#define IPA_INTER_TIMER_ENABLE          ((uint8_t)0x01U)                 /*!< Inter-timer enable */
+
+/* IPA pixel format convert mode */
+#define CTL_PFCM(regval)                (BITS(16,17) & ((regval) << 16))
+#define IPA_FGTODE                      CTL_PFCM(0)                      /*!< foreground memory to destination memory without pixel format convert */
+#define IPA_FGTODE_PF_CONVERT           CTL_PFCM(1)                      /*!< foreground memory to destination memory with pixel format convert */
+#define IPA_FGBGTODE                    CTL_PFCM(2)                      /*!< blending foreground and background memory to destination memory */
+#define IPA_FILL_UP_DE                  CTL_PFCM(3)                      /*!< fill up destination memory with specific color */
+
+/* foreground alpha value calculation algorithm */
+#define FPCTL_FAVCA(regval)             (BITS(16,17) & ((regval) << 16))
+#define IPA_FG_ALPHA_MODE_0             FPCTL_FAVCA(0)                   /*!< no effect */
+#define IPA_FG_ALPHA_MODE_1             FPCTL_FAVCA(1)                   /*!< FPDAV[7:0] is selected as the foreground alpha value */
+#define IPA_FG_ALPHA_MODE_2             FPCTL_FAVCA(2)                   /*!< FPDAV[7:0] multiplied by read alpha value */
+
+/* background alpha value calculation algorithm */
+#define BPCTL_BAVCA(regval)             (BITS(16,17) & ((regval) << 16))
+#define IPA_BG_ALPHA_MODE_0             BPCTL_BAVCA(0)                   /*!< no effect */
+#define IPA_BG_ALPHA_MODE_1             BPCTL_BAVCA(1)                   /*!< BPDAV[7:0] is selected as the background alpha value */
+#define IPA_BG_ALPHA_MODE_2             BPCTL_BAVCA(2)                   /*!< BPDAV[7:0] multiplied by read alpha value */
+
+/* foreground pixel format */
+#define FPCTL_PPF(regval)               (BITS(0,3) & ((regval)))
+#define FOREGROUND_PPF_ARGB8888         FPCTL_PPF(0)                     /*!< foreground pixel format ARGB8888 */
+#define FOREGROUND_PPF_RGB888           FPCTL_PPF(1)                     /*!< foreground pixel format RGB888 */
+#define FOREGROUND_PPF_RGB565           FPCTL_PPF(2)                     /*!< foreground pixel format RGB565 */
+#define FOREGROUND_PPF_ARG1555          FPCTL_PPF(3)                     /*!< foreground pixel format ARGB1555 */
+#define FOREGROUND_PPF_ARGB4444         FPCTL_PPF(4)                     /*!< foreground pixel format ARGB4444 */
+#define FOREGROUND_PPF_L8               FPCTL_PPF(5)                     /*!< foreground pixel format L8 */
+#define FOREGROUND_PPF_AL44             FPCTL_PPF(6)                     /*!< foreground pixel format AL44 */
+#define FOREGROUND_PPF_AL88             FPCTL_PPF(7)                     /*!< foreground pixel format AL88 */
+#define FOREGROUND_PPF_L4               FPCTL_PPF(8)                     /*!< foreground pixel format L4 */
+#define FOREGROUND_PPF_A8               FPCTL_PPF(9)                     /*!< foreground pixel format A8 */
+#define FOREGROUND_PPF_A4               FPCTL_PPF(10)                    /*!< foreground pixel format A4 */
+
+/* background pixel format */
+#define BPCTL_PPF(regval)               (BITS(0,3) & ((regval)))
+#define BACKGROUND_PPF_ARGB8888         BPCTL_PPF(0)                     /*!< background pixel format ARGB8888 */
+#define BACKGROUND_PPF_RGB888           BPCTL_PPF(1)                     /*!< background pixel format RGB888 */
+#define BACKGROUND_PPF_RGB565           BPCTL_PPF(2)                     /*!< background pixel format RGB565 */
+#define BACKGROUND_PPF_ARG1555          BPCTL_PPF(3)                     /*!< background pixel format ARGB1555 */
+#define BACKGROUND_PPF_ARGB4444         BPCTL_PPF(4)                     /*!< background pixel format ARGB4444 */
+#define BACKGROUND_PPF_L8               BPCTL_PPF(5)                     /*!< background pixel format L8 */
+#define BACKGROUND_PPF_AL44             BPCTL_PPF(6)                     /*!< background pixel format AL44 */
+#define BACKGROUND_PPF_AL88             BPCTL_PPF(7)                     /*!< background pixel format AL88 */
+#define BACKGROUND_PPF_L4               BPCTL_PPF(8)                     /*!< background pixel format L4 */
+#define BACKGROUND_PPF_A8               BPCTL_PPF(9)                     /*!< background pixel format A8 */
+#define BACKGROUND_PPF_A4               BPCTL_PPF(10)                    /*!< background pixel format A4 */
+
+
+/* function declarations */
+
+/* deinitialize IPA */
+void ipa_deinit(void);
+/* IPA transfer enable */
+void ipa_transfer_enable(void);
+/* IPA transfer hang up enable */
+void ipa_transfer_hangup_enable(void);
+/* IPA transfer hang up disable */
+void ipa_transfer_hangup_disable(void);
+/* IPA transfer stop enable */
+void ipa_transfer_stop_enable(void);
+/* IPA transfer stop disable */
+void ipa_transfer_stop_disable(void);
+/* IPA foreground LUT loading enable */
+void ipa_foreground_lut_loading_enable(void);
+/* IPA background LUT loading enable */
+void ipa_background_lut_loading_enable(void);
+/* IPA transfer enable */
+void ipa_pixel_format_convert_mod(uint32_t pfcm);
+
+/* initialize foreground parameters */
+void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct);
+/* initialize background parameters */
+void ipa_background_init(ipa_background_parameter_struct* background_struct);
+/* initialize destination parameters */
+void ipa_destination_init(ipa_destination_parameter_struct* destination_struct);
+/* initialize IPA foreground LUT parameters */
+void ipa_foreground_lut_init(uint32_t fg_lut_num,uint8_t fg_lut_pf, uint32_t fg_lut_addr);
+/* initialize IPA background LUT parameters */
+void ipa_background_lut_init(uint32_t bg_lut_num,uint8_t bg_lut_pf, uint32_t bg_lut_addr);
+
+/* configure line mark */
+void ipa_line_mark_config(uint32_t linenum);
+/* Inter-timer enable or disable */
+void ipa_inter_timer_config(uint8_t timercfg);
+/* number of clock cycles interval set */
+void ipa_interval_clock_num_config(uint32_t clk_num );
+
+/* IPA interrupt enable */
+void ipa_interrupt_enable(uint32_t inttype);
+/* IPA interrupt disable */
+void ipa_interrupt_disable(uint32_t inttype);
+/* get IPA interrupt flag */
+FlagStatus ipa_interrupt_flag_get(uint32_t intflag);
+/* clear IPA interrupt flag */
+void ipa_interrupt_flag_clear(uint32_t intflag);
+
+#endif /* GD32F4XX_IPA_H */

+ 161 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h

@@ -0,0 +1,161 @@
+/*!
+    \file  gd32f4xx_iref.h
+    \brief definitions for the IREF
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_IREF_H
+#define GD32F4XX_IREF_H
+
+#include "gd32f4xx.h"
+
+/* IREF definitions */
+#define IREF                            IREF_BASE              /*!< IREF base address */
+
+/* registers definitions */
+#define IREF_CTL                        REG32(IREF + 0x300U)   /*!< IREF control register */
+
+/* bits definitions */
+/* IREF_CTL */
+#define IREF_CTL_CSDT                   BITS(0,5)              /*!< current step data */
+#define IREF_CTL_SCMOD                  BIT(7)                 /*!< sink current mode */
+#define IREF_CTL_CPT                    BITS(8,12)             /*!< current precision trim */
+#define IREF_CTL_SSEL                   BIT(14)                /*!< step selection */ 
+#define IREF_CTL_CREN                   BIT(15)                /*!< current reference enable */
+
+/* constants definitions */
+/* IREF current precision trim */
+#define CTL_CPT(regval)                 (BITS(8,12) & ((uint32_t)(regval) << 8))
+#define IREF_CUR_PRECISION_TRIM_0       CTL_CPT(0)             /*!< IREF current precision trim 0 */
+#define IREF_CUR_PRECISION_TRIM_1       CTL_CPT(1)             /*!< IREF current precision trim 1 */
+#define IREF_CUR_PRECISION_TRIM_2       CTL_CPT(2)             /*!< IREF current precision trim 2 */
+#define IREF_CUR_PRECISION_TRIM_3       CTL_CPT(3)             /*!< IREF current precision trim 3 */
+#define IREF_CUR_PRECISION_TRIM_4       CTL_CPT(4)             /*!< IREF current precision trim 4 */
+#define IREF_CUR_PRECISION_TRIM_5       CTL_CPT(5)             /*!< IREF current precision trim 5 */
+#define IREF_CUR_PRECISION_TRIM_6       CTL_CPT(6)             /*!< IREF current precision trim 6 */
+#define IREF_CUR_PRECISION_TRIM_7       CTL_CPT(7)             /*!< IREF current precision trim 7 */
+#define IREF_CUR_PRECISION_TRIM_8       CTL_CPT(8)             /*!< IREF current precision trim 8 */
+#define IREF_CUR_PRECISION_TRIM_9       CTL_CPT(9)             /*!< IREF current precision trim 9 */
+#define IREF_CUR_PRECISION_TRIM_10      CTL_CPT(10)            /*!< IREF current precision trim 10 */
+#define IREF_CUR_PRECISION_TRIM_11      CTL_CPT(11)            /*!< IREF current precision trim 11 */
+#define IREF_CUR_PRECISION_TRIM_12      CTL_CPT(12)            /*!< IREF current precision trim 12 */
+#define IREF_CUR_PRECISION_TRIM_13      CTL_CPT(13)            /*!< IREF current precision trim 13 */
+#define IREF_CUR_PRECISION_TRIM_14      CTL_CPT(14)            /*!< IREF current precision trim 14 */
+#define IREF_CUR_PRECISION_TRIM_15      CTL_CPT(15)            /*!< IREF current precision trim 15 */
+#define IREF_CUR_PRECISION_TRIM_16      CTL_CPT(16)            /*!< IREF current precision trim 16 */
+#define IREF_CUR_PRECISION_TRIM_17      CTL_CPT(17)            /*!< IREF current precision trim 17 */
+#define IREF_CUR_PRECISION_TRIM_18      CTL_CPT(18)            /*!< IREF current precision trim 18 */
+#define IREF_CUR_PRECISION_TRIM_19      CTL_CPT(19)            /*!< IREF current precision trim 19 */
+#define IREF_CUR_PRECISION_TRIM_20      CTL_CPT(20)            /*!< IREF current precision trim 20 */
+#define IREF_CUR_PRECISION_TRIM_21      CTL_CPT(21)            /*!< IREF current precision trim 21 */
+#define IREF_CUR_PRECISION_TRIM_22      CTL_CPT(22)            /*!< IREF current precision trim 22 */
+#define IREF_CUR_PRECISION_TRIM_23      CTL_CPT(23)            /*!< IREF current precision trim 23 */
+#define IREF_CUR_PRECISION_TRIM_24      CTL_CPT(24)            /*!< IREF current precision trim 24 */
+#define IREF_CUR_PRECISION_TRIM_25      CTL_CPT(25)            /*!< IREF current precision trim 25 */
+#define IREF_CUR_PRECISION_TRIM_26      CTL_CPT(26)            /*!< IREF current precision trim 26 */
+#define IREF_CUR_PRECISION_TRIM_27      CTL_CPT(27)            /*!< IREF current precision trim 27 */
+#define IREF_CUR_PRECISION_TRIM_28      CTL_CPT(28)            /*!< IREF current precision trim 28 */
+#define IREF_CUR_PRECISION_TRIM_29      CTL_CPT(29)            /*!< IREF current precision trim 29 */
+#define IREF_CUR_PRECISION_TRIM_30      CTL_CPT(30)            /*!< IREF current precision trim 30 */
+#define IREF_CUR_PRECISION_TRIM_31      CTL_CPT(31)            /*!< IREF current precision trim 31 */
+
+/* IREF current step */
+#define CTL_CSDT(regval)                (BITS(0,5) & ((uint32_t)(regval) << 0))
+#define IREF_CUR_STEP_DATA_0            CTL_CSDT(0)            /*!< IREF current step data 0 */
+#define IREF_CUR_STEP_DATA_1            CTL_CSDT(1)            /*!< IREF current step data 1 */
+#define IREF_CUR_STEP_DATA_2            CTL_CSDT(2)            /*!< IREF current step data 2 */
+#define IREF_CUR_STEP_DATA_3            CTL_CSDT(3)            /*!< IREF current step data 3 */
+#define IREF_CUR_STEP_DATA_4            CTL_CSDT(4)            /*!< IREF current step data 4 */
+#define IREF_CUR_STEP_DATA_5            CTL_CSDT(5)            /*!< IREF current step data 5 */
+#define IREF_CUR_STEP_DATA_6            CTL_CSDT(6)            /*!< IREF current step data 6 */
+#define IREF_CUR_STEP_DATA_7            CTL_CSDT(7)            /*!< IREF current step data 7 */
+#define IREF_CUR_STEP_DATA_8            CTL_CSDT(8)            /*!< IREF current step data 8 */
+#define IREF_CUR_STEP_DATA_9            CTL_CSDT(9)            /*!< IREF current step data 9 */
+#define IREF_CUR_STEP_DATA_10           CTL_CSDT(10)           /*!< IREF current step data 10 */
+#define IREF_CUR_STEP_DATA_11           CTL_CSDT(11)           /*!< IREF current step data 11 */
+#define IREF_CUR_STEP_DATA_12           CTL_CSDT(12)           /*!< IREF current step data 12 */
+#define IREF_CUR_STEP_DATA_13           CTL_CSDT(13)           /*!< IREF current step data 13 */
+#define IREF_CUR_STEP_DATA_14           CTL_CSDT(14)           /*!< IREF current step data 14 */
+#define IREF_CUR_STEP_DATA_15           CTL_CSDT(15)           /*!< IREF current step data 15 */
+#define IREF_CUR_STEP_DATA_16           CTL_CSDT(16)           /*!< IREF current step data 16 */
+#define IREF_CUR_STEP_DATA_17           CTL_CSDT(17)           /*!< IREF current step data 17 */
+#define IREF_CUR_STEP_DATA_18           CTL_CSDT(18)           /*!< IREF current step data 18 */
+#define IREF_CUR_STEP_DATA_19           CTL_CSDT(19)           /*!< IREF current step data 19 */
+#define IREF_CUR_STEP_DATA_20           CTL_CSDT(20)           /*!< IREF current step data 20 */
+#define IREF_CUR_STEP_DATA_21           CTL_CSDT(21)           /*!< IREF current step data 21 */
+#define IREF_CUR_STEP_DATA_22           CTL_CSDT(22)           /*!< IREF current step data 22 */
+#define IREF_CUR_STEP_DATA_23           CTL_CSDT(23)           /*!< IREF current step data 23 */
+#define IREF_CUR_STEP_DATA_24           CTL_CSDT(24)           /*!< IREF current step data 24 */
+#define IREF_CUR_STEP_DATA_25           CTL_CSDT(25)           /*!< IREF current step data 25 */
+#define IREF_CUR_STEP_DATA_26           CTL_CSDT(26)           /*!< IREF current step data 26 */
+#define IREF_CUR_STEP_DATA_27           CTL_CSDT(27)           /*!< IREF current step data 27 */
+#define IREF_CUR_STEP_DATA_28           CTL_CSDT(28)           /*!< IREF current step data 28 */
+#define IREF_CUR_STEP_DATA_29           CTL_CSDT(29)           /*!< IREF current step data 29 */
+#define IREF_CUR_STEP_DATA_30           CTL_CSDT(30)           /*!< IREF current step data 30 */
+#define IREF_CUR_STEP_DATA_31           CTL_CSDT(31)           /*!< IREF current step data 31 */
+#define IREF_CUR_STEP_DATA_32           CTL_CSDT(32)           /*!< IREF current step data 32 */
+#define IREF_CUR_STEP_DATA_33           CTL_CSDT(33)           /*!< IREF current step data 33 */
+#define IREF_CUR_STEP_DATA_34           CTL_CSDT(34)           /*!< IREF current step data 34 */
+#define IREF_CUR_STEP_DATA_35           CTL_CSDT(35)           /*!< IREF current step data 35 */
+#define IREF_CUR_STEP_DATA_36           CTL_CSDT(36)           /*!< IREF current step data 36 */
+#define IREF_CUR_STEP_DATA_37           CTL_CSDT(37)           /*!< IREF current step data 37 */
+#define IREF_CUR_STEP_DATA_38           CTL_CSDT(38)           /*!< IREF current step data 38 */
+#define IREF_CUR_STEP_DATA_39           CTL_CSDT(39)           /*!< IREF current step data 39 */
+#define IREF_CUR_STEP_DATA_40           CTL_CSDT(40)           /*!< IREF current step data 40 */
+#define IREF_CUR_STEP_DATA_41           CTL_CSDT(41)           /*!< IREF current step data 41 */
+#define IREF_CUR_STEP_DATA_42           CTL_CSDT(42)           /*!< IREF current step data 42 */
+#define IREF_CUR_STEP_DATA_43           CTL_CSDT(43)           /*!< IREF current step data 43 */
+#define IREF_CUR_STEP_DATA_44           CTL_CSDT(44)           /*!< IREF current step data 44 */
+#define IREF_CUR_STEP_DATA_45           CTL_CSDT(45)           /*!< IREF current step data 45 */
+#define IREF_CUR_STEP_DATA_46           CTL_CSDT(46)           /*!< IREF current step data 46 */
+#define IREF_CUR_STEP_DATA_47           CTL_CSDT(47)           /*!< IREF current step data 47 */
+#define IREF_CUR_STEP_DATA_48           CTL_CSDT(48)           /*!< IREF current step data 48 */
+#define IREF_CUR_STEP_DATA_49           CTL_CSDT(49)           /*!< IREF current step data 49 */
+#define IREF_CUR_STEP_DATA_50           CTL_CSDT(50)           /*!< IREF current step data 50 */
+#define IREF_CUR_STEP_DATA_51           CTL_CSDT(51)           /*!< IREF current step data 51 */
+#define IREF_CUR_STEP_DATA_52           CTL_CSDT(52)           /*!< IREF current step data 52 */
+#define IREF_CUR_STEP_DATA_53           CTL_CSDT(53)           /*!< IREF current step data 53 */
+#define IREF_CUR_STEP_DATA_54           CTL_CSDT(54)           /*!< IREF current step data 54 */
+#define IREF_CUR_STEP_DATA_55           CTL_CSDT(55)           /*!< IREF current step data 54 */
+#define IREF_CUR_STEP_DATA_56           CTL_CSDT(56)           /*!< IREF current step data 54 */
+#define IREF_CUR_STEP_DATA_57           CTL_CSDT(57)           /*!< IREF current step data 57 */
+#define IREF_CUR_STEP_DATA_58           CTL_CSDT(58)           /*!< IREF current step data 58 */
+#define IREF_CUR_STEP_DATA_59           CTL_CSDT(59)           /*!< IREF current step data 59 */
+#define IREF_CUR_STEP_DATA_60           CTL_CSDT(60)           /*!< IREF current step data 60 */
+#define IREF_CUR_STEP_DATA_61           CTL_CSDT(61)           /*!< IREF current step data 61 */
+#define IREF_CUR_STEP_DATA_62           CTL_CSDT(62)           /*!< IREF current step data 62 */
+#define IREF_CUR_STEP_DATA_63           CTL_CSDT(63)           /*!< IREF current step data 63 */
+ 
+/* IREF mode selection */
+#define IREF_STEP(regval)               (BIT(14) & ((uint32_t)(regval) << 14))
+#define IREF_MODE_LOW_POWER             IREF_STEP(0)           /*!< low power, 1uA step */
+#define IREF_MODE_HIGH_CURRENT          IREF_STEP(1)           /*!< high current, 8uA step */
+ 
+/* IREF sink current mode*/ 
+#define IREF_CURRENT(regval)            (BIT(7) & ((uint32_t)(regval) << 7))
+#define IREF_SOURCE_CURRENT             IREF_CURRENT(0)        /*!< IREF source current */
+#define IREF_SINK_CURRENT               IREF_CURRENT(1)        /*!< IREF sink current */
+
+/* function declarations */
+/* deinit IREF */
+void iref_deinit(void);
+/* enable IREF */
+void iref_enable(void);
+/* disable IREF */
+void iref_disable(void);
+
+/* set IREF mode*/
+void iref_mode_set(uint32_t step);
+/* set IREF sink current mode*/
+void iref_sink_set(uint32_t sinkmode);
+/* set IREF current precision trim value */
+void iref_precision_trim_value_set(uint32_t precisiontrim);
+/* set IREF step data*/
+void iref_step_data_config(uint32_t stepdata);
+
+#endif /* GD32F4XX_IREF_H */

+ 68 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h

@@ -0,0 +1,68 @@
+/*!
+    \file  gd32f4xx_misc.h
+    \brief definitions for the MISC
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_MISC_H
+#define GD32F4XX_MISC_H
+
+#include "gd32f4xx.h"
+
+/* constants definitions */
+/* set the RAM and FLASH base address */
+#define NVIC_VECTTAB_RAM            ((uint32_t)0x20000000) /*!< RAM base address */
+#define NVIC_VECTTAB_FLASH          ((uint32_t)0x08000000) /*!< Flash base address */
+
+/* set the NVIC vector table offset mask */
+#define NVIC_VECTTAB_OFFSET_MASK    ((uint32_t)0x1FFFFF80)
+
+/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */
+#define NVIC_AIRCR_VECTKEY_MASK     ((uint32_t)0x05FA0000)
+
+/* priority group - define the pre-emption priority and the subpriority */
+#define NVIC_PRIGROUP_PRE0_SUB4     ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */
+#define NVIC_PRIGROUP_PRE1_SUB3     ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */
+#define NVIC_PRIGROUP_PRE2_SUB2     ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */
+#define NVIC_PRIGROUP_PRE3_SUB1     ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */
+#define NVIC_PRIGROUP_PRE4_SUB0     ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */
+
+/* choose the method to enter or exit the lowpower mode */
+#define SCB_SCR_SLEEPONEXIT         ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */
+#define SCB_SCR_SLEEPDEEP           ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */
+#define SCB_SCR_SEVONPEND           ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */
+
+#define SCB_LPM_SLEEP_EXIT_ISR      SCB_SCR_SLEEPONEXIT
+#define SCB_LPM_DEEPSLEEP           SCB_SCR_SLEEPDEEP
+#define SCB_LPM_WAKE_BY_ALL_INT     SCB_SCR_SEVONPEND
+
+/* choose the systick clock source */
+#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */
+#define SYSTICK_CLKSOURCE_HCLK      ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */
+
+/* function declarations */
+/* set the priority group */
+void nvic_priority_group_set(uint32_t nvic_prigroup);
+
+/* enable NVIC request */
+void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority);
+/* disable NVIC request */
+void nvic_irq_disable(uint8_t nvic_irq);
+
+/* set the NVIC vector table base address */
+void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset);
+
+/* set the state of the low power mode */
+void system_lowpower_set(uint8_t lowpower_mode);
+/* reset the state of the low power mode */
+void system_lowpower_reset(uint8_t lowpower_mode);
+
+/* set the systick clock source */
+void systick_clksource_set(uint32_t systick_clksource);
+
+#endif /* GD32F4XX_MISC_H */

+ 173 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h

@@ -0,0 +1,173 @@
+/*!
+    \file  gd32f4xx_pmu.h
+    \brief definitions for the PMU
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_PMU_H
+#define GD32F4XX_PMU_H
+
+#include "gd32f4xx.h"
+
+/* PMU definitions */
+#define PMU                           PMU_BASE                 /*!< PMU base address */
+
+/* registers definitions */
+#define PMU_CTL                       REG32((PMU) + 0x00U)     /*!< PMU control register */
+#define PMU_CS                        REG32((PMU) + 0x04U)     /*!< PMU control and status register */
+
+/* bits definitions */
+/* PMU_CTL */
+#define PMU_CTL_LDOLP                 BIT(0)                   /*!< LDO low power mode */
+#define PMU_CTL_STBMOD                BIT(1)                   /*!< standby mode */
+#define PMU_CTL_WURST                 BIT(2)                   /*!< wakeup flag reset */
+#define PMU_CTL_STBRST                BIT(3)                   /*!< standby flag reset */
+#define PMU_CTL_LVDEN                 BIT(4)                   /*!< low voltage detector enable */
+#define PMU_CTL_LVDT                  BITS(5,7)                /*!< low voltage detector threshold */
+#define PMU_CTL_BKPWEN                BIT(8)                   /*!< backup domain write enable */
+#define PMU_CTL_LDLP                  BIT(10)                  /*!< low-driver mode when use low power LDO */
+#define PMU_CTL_LDNP                  BIT(11)                  /*!< low-driver mode when use normal power LDO */
+#define PMU_CTL_LDOVS                 BITS(14,15)              /*!< LDO output voltage select */
+#define PMU_CTL_HDEN                  BIT(16)                  /*!< high-driver mode enable */
+#define PMU_CTL_HDS                   BIT(17)                  /*!< high-driver mode switch */
+#define PMU_CTL_LDEN                  BITS(18,19)              /*!< low-driver mode enable in deep-sleep mode */
+
+/* PMU_CS */
+#define PMU_CS_WUF                    BIT(0)                   /*!< wakeup flag */
+#define PMU_CS_STBF                   BIT(1)                   /*!< standby flag */
+#define PMU_CS_LVDF                   BIT(2)                   /*!< low voltage detector status flag */
+#define PMU_CS_BLDORF                 BIT(3)                   /*!< backup SRAM LDO ready flag */
+#define PMU_CS_WUPEN                  BIT(8)                   /*!< wakeup pin enable */
+#define PMU_CS_BLDOON                 BIT(9)                   /*!< backup SRAM LDO on */
+#define PMU_CS_LDOVSRF                BIT(14)                  /*!< LDO voltage select ready flag */
+#define PMU_CS_HDRF                   BIT(16)                  /*!< high-driver ready flag */
+#define PMU_CS_HDSRF                  BIT(17)                  /*!< high-driver switch ready flag */
+#define PMU_CS_LDRF                   BITS(18,19)              /*!< Low-driver mode ready flag */
+
+/* constants definitions */
+/* PMU low voltage detector threshold definitions */
+#define CTL_LVDT(regval)              (BITS(5,7)&((uint32_t)(regval)<<5))
+#define PMU_LVDT_0                    CTL_LVDT(0)              /*!< voltage threshold is 2.2V */
+#define PMU_LVDT_1                    CTL_LVDT(1)              /*!< voltage threshold is 2.3V */
+#define PMU_LVDT_2                    CTL_LVDT(2)              /*!< voltage threshold is 2.4V */
+#define PMU_LVDT_3                    CTL_LVDT(3)              /*!< voltage threshold is 2.5V */
+#define PMU_LVDT_4                    CTL_LVDT(4)              /*!< voltage threshold is 2.6V */
+#define PMU_LVDT_5                    CTL_LVDT(5)              /*!< voltage threshold is 2.7V */
+#define PMU_LVDT_6                    CTL_LVDT(6)              /*!< voltage threshold is 2.8V */
+#define PMU_LVDT_7                    CTL_LVDT(7)              /*!< voltage threshold is 2.9V */
+
+/* PMU LDO output voltage select definitions */
+#define CTL_LDOVS(regval)             (BITS(14,15)&((uint32_t)(regval)<<14))
+#define PMU_LDOVS_LOW                 CTL_LDOVS(1)             /*!< LDO output voltage low mode */
+#define PMU_LDOVS_MID                 CTL_LDOVS(2)             /*!< LDO output voltage mid mode */
+#define PMU_LDOVS_HIGH                CTL_LDOVS(3)             /*!< LDO output voltage high mode */
+
+/* PMU low-driver mode enable in deep-sleep mode */
+#define CTL_LDEN(regval)              (BITS(18,19)&((uint32_t)(regval)<<18))
+#define PMU_LOWDRIVER_DISABLE         CTL_LDEN(0)              /*!< low-driver mode disable in deep-sleep mode */
+#define PMU_LOWDRIVER_ENABLE          CTL_LDEN(3)              /*!< low-driver mode enable in deep-sleep mode */
+
+/* PMU high-driver mode switch */
+#define CTL_HDS(regval)               (BIT(17)&((uint32_t)(regval)<<17))
+#define PMU_HIGHDR_SWITCH_NONE        CTL_HDS(0)               /*!< no high-driver mode switch */
+#define PMU_HIGHDR_SWITCH_EN          CTL_HDS(1)               /*!< high-driver mode switch */
+
+/* PMU low-driver mode when use low power LDO */
+#define CTL_LDLP(regval)              (BIT(10)&((uint32_t)(regval)<<10))
+#define PMU_NORMALDR_LOWPWR           CTL_LDLP(0)              /*!< normal driver when use low power LDO */
+#define PMU_LOWDR_LOWPWR              CTL_LDLP(1)              /*!< low-driver mode enabled when LDEN is 11 and use low power LDO */
+
+/* PMU low-driver mode when use normal power LDO */
+#define CTL_LDNP(regval)              (BIT(11)&((uint32_t)(regval)<<11))
+#define PMU_NORMALDR_NORMALPWR        CTL_LDNP(0)              /*!< normal driver when use normal power LDO */
+#define PMU_LOWDR_NORMALPWR           CTL_LDNP(1)              /*!< low-driver mode enabled when LDEN is 11 and use normal power LDO */
+
+/* PMU low power mode ready flag definitions */
+#define CS_LDRF(regval)               (BITS(18,19)&((uint32_t)(regval)<<18))
+#define PMU_LDRF_NORMAL               CS_LDRF(0)               /*!< normal driver in deep-sleep mode */
+#define PMU_LDRF_LOWDRIVER            CS_LDRF(3)               /*!< low-driver mode in deep-sleep mode */
+
+/* PMU backup SRAM LDO on or off */
+#define CS_BLDOON(regval)             (BIT(9)&((uint32_t)(regval)<<9))
+#define PMU_BLDOON_OFF                CS_BLDOON(0)             /*!< backup SRAM LDO off */
+#define PMU_BLDOON_ON                 CS_BLDOON(1)             /*!< the backup SRAM LDO on */
+
+/* PMU flag definitions */
+#define PMU_FLAG_WAKEUP               PMU_CS_WUF               /*!< wakeup flag status */
+#define PMU_FLAG_STANDBY              PMU_CS_STBF              /*!< standby flag status */
+#define PMU_FLAG_LVD                  PMU_CS_LVDF              /*!< lvd flag status */
+#define PMU_FLAG_BLDORF               PMU_CS_BLDORF            /*!< backup SRAM LDO ready flag */
+#define PMU_FLAG_LDOVSRF              PMU_CS_LDOVSRF           /*!< LDO voltage select ready flag */
+#define PMU_FLAG_HDRF                 PMU_CS_HDRF              /*!< high-driver ready flag */
+#define PMU_FLAG_HDSRF                PMU_CS_HDSRF             /*!< high-driver switch ready flag */
+#define PMU_FLAG_LDRF                 PMU_CS_LDRF              /*!< low-driver mode ready flag */
+
+/* PMU ldo definitions */
+#define PMU_LDO_NORMAL                ((uint32_t)0x00000000U)  /*!< LDO normal work when PMU enter deepsleep mode */
+#define PMU_LDO_LOWPOWER              PMU_CTL_LDOLP            /*!< LDO work at low power status when PMU enter deepsleep mode */
+
+/* PMU flag reset definitions */
+#define PMU_FLAG_RESET_WAKEUP         ((uint8_t)0x00U)         /*!< wakeup flag reset */
+#define PMU_FLAG_RESET_STANDBY        ((uint8_t)0x01U)         /*!< standby flag reset */
+
+/* PMU command constants definitions */
+#define WFI_CMD                       ((uint8_t)0x00U)         /*!< use WFI command */
+#define WFE_CMD                       ((uint8_t)0x01U)         /*!< use WFE command */
+
+/* function declarations */
+/* reset PMU register */
+void pmu_deinit(void);
+
+/* select low voltage detector threshold */
+void pmu_lvd_select(uint32_t pmu_lvdt_n);
+/* LDO output voltage select */
+void pmu_ldo_output_select(uint32_t ldo_output);
+/* PMU lvd disable */
+void pmu_lvd_disable(void);
+
+/* functions of low-driver mode and high-driver mode in deep-sleep mode */
+/* high-driver mode switch */
+void pmu_highdriver_switch_select(uint32_t highdr_switch);
+/* high-driver mode enable */
+void pmu_highdriver_mode_enable(void);
+/* high-driver mode disable */
+void pmu_highdriver_mode_disable(void);
+/* low-driver mode enable in deep-sleep mode */
+void pmu_low_driver_mode_enable(uint32_t lowdr_mode);
+/* in deep-sleep mode, low-driver mode when use low power LDO */
+void pmu_lowdriver_lowpower_config(uint32_t mode);
+/* in deep-sleep mode, low-driver mode when use normal power LDO */
+void pmu_lowdriver_normalpower_config(uint32_t mode);
+
+/* set PMU mode */
+/* PMU work at sleep mode */
+void pmu_to_sleepmode(uint8_t sleepmodecmd);
+/* PMU work at deepsleep mode */
+void pmu_to_deepsleepmode(uint32_t pmu_ldo, uint8_t deepsleepmodecmd);
+/* PMU work at standby mode */
+void pmu_to_standbymode(uint8_t standbymodecmd);
+/* PMU wakeup pin enable */
+void pmu_wakeup_pin_enable(void);
+/* PMU wakeup pin disable */
+void pmu_wakeup_pin_disable(void);
+
+/* backup related functions */
+/* backup SRAM LDO on */
+void pmu_backup_ldo_config(uint32_t bkp_ldo);
+/* backup domain write enable */
+void pmu_backup_write_enable(void);
+/* backup domain write disable */
+void pmu_backup_write_disable(void);
+
+/* flag functions */
+/* reset flag bit */
+void pmu_flag_reset(uint32_t flag_reset);
+/* get flag status */
+FlagStatus pmu_flag_get(uint32_t pmu_flag);
+
+#endif /* GD32F4XX_PMU_H */

+ 1152 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h

@@ -0,0 +1,1152 @@
+/*!
+    \file  gd32f4xx_rcu.h
+    \brief definitions for the RCU
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_RCU_H
+#define GD32F4XX_RCU_H
+
+#include "gd32f4xx.h"
+
+/* RCU definitions */
+#define RCU                             RCU_BASE
+
+/* registers definitions */
+#define RCU_CTL                         REG32(RCU + 0x00U)        /*!< control register */
+#define RCU_PLL                         REG32(RCU + 0x04U)        /*!< PLL register */
+#define RCU_CFG0                        REG32(RCU + 0x08U)        /*!< clock configuration register 0 */
+#define RCU_INT                         REG32(RCU + 0x0CU)        /*!< clock interrupt register */
+#define RCU_AHB1RST                     REG32(RCU + 0x10U)        /*!< AHB1 reset register */
+#define RCU_AHB2RST                     REG32(RCU + 0x14U)        /*!< AHB2 reset register */
+#define RCU_AHB3RST                     REG32(RCU + 0x18U)        /*!< AHB3 reset register */
+#define RCU_APB1RST                     REG32(RCU + 0x20U)        /*!< APB1 reset register */
+#define RCU_APB2RST                     REG32(RCU + 0x24U)        /*!< APB2 reset register */
+#define RCU_AHB1EN                      REG32(RCU + 0x30U)        /*!< AHB1 enable register */
+#define RCU_AHB2EN                      REG32(RCU + 0x34U)        /*!< AHB2 enable register */
+#define RCU_AHB3EN                      REG32(RCU + 0x38U)        /*!< AHB3 enable register */
+#define RCU_APB1EN                      REG32(RCU + 0x40U)        /*!< APB1 enable register */
+#define RCU_APB2EN                      REG32(RCU + 0x44U)        /*!< APB2 enable register */
+#define RCU_AHB1SPEN                    REG32(RCU + 0x50U)        /*!< AHB1 sleep mode enable register */
+#define RCU_AHB2SPEN                    REG32(RCU + 0x54U)        /*!< AHB2 sleep mode enable register */
+#define RCU_AHB3SPEN                    REG32(RCU + 0x58U)        /*!< AHB3 sleep mode enable register */ 
+#define RCU_APB1SPEN                    REG32(RCU + 0x60U)        /*!< APB1 sleep mode enable register */
+#define RCU_APB2SPEN                    REG32(RCU + 0x64U)        /*!< APB2 sleep mode enable register */
+#define RCU_BDCTL                       REG32(RCU + 0x70U)        /*!< backup domain control register */
+#define RCU_RSTSCK                      REG32(RCU + 0x74U)        /*!< reset source / clock register */
+#define RCU_PLLSSCTL                    REG32(RCU + 0x80U)        /*!< PLL clock spread spectrum control register */
+#define RCU_PLLI2S                      REG32(RCU + 0x84U)        /*!< PLLI2S register */ 
+#define RCU_PLLSAI                      REG32(RCU + 0x88U)        /*!< PLLSAI register */ 
+#define RCU_CFG1                        REG32(RCU + 0x8CU)        /*!< clock configuration register 1 */
+#define RCU_ADDCTL                      REG32(RCU + 0xC0U)        /*!< Additional clock control register */
+#define RCU_ADDINT                      REG32(RCU + 0xCCU)        /*!< Additional clock interrupt register */
+#define RCU_ADDAPB1RST                  REG32(RCU + 0xE0U)        /*!< APB1 additional reset register */
+#define RCU_ADDAPB1EN                   REG32(RCU + 0xE4U)        /*!< APB1 additional enable register */
+#define RCU_ADDAPB1SPEN                 REG32(RCU + 0xE8U)        /*!< APB1 additional sleep mode enable register */
+#define RCU_VKEY                        REG32(RCU + 0x100U)       /*!< voltage key register */
+#define RCU_DSV                         REG32(RCU + 0x134U)       /*!< deep-sleep mode voltage register */
+
+/* bits definitions */
+/* RCU_CTL */
+#define RCU_CTL_IRC16MEN                BIT(0)                    /*!< internal high speed oscillator enable */
+#define RCU_CTL_IRC16MSTB               BIT(1)                    /*!< IRC8M high speed internal oscillator stabilization flag */
+#define RCU_CTL_IRC16MADJ               BITS(3,7)                 /*!< high speed internal oscillator clock trim adjust value */
+#define RCU_CTL_IRC16MCALIB             BITS(8,15)                /*!< high speed internal oscillator calibration value register */
+#define RCU_CTL_HXTALEN                 BIT(16)                   /*!< external high speed oscillator enable */
+#define RCU_CTL_HXTALSTB                BIT(17)                   /*!< external crystal oscillator clock stabilization flag */
+#define RCU_CTL_HXTALBPS                BIT(18)                   /*!< external crystal oscillator clock bypass mode enable */
+#define RCU_CTL_CKMEN                   BIT(19)                   /*!< HXTAL clock monitor enable */
+#define RCU_CTL_PLLEN                   BIT(24)                   /*!< PLL enable */
+#define RCU_CTL_PLLSTB                  BIT(25)                   /*!< PLL Clock Stabilization Flag */
+#define RCU_CTL_PLLI2SEN                BIT(26)                   /*!< PLLI2S enable */
+#define RCU_CTL_PLLI2STB                BIT(27)                   /*!< PLLI2S Clock Stabilization Flag */
+#define RCU_CTL_PLLSAIEN                BIT(28)                   /*!< PLLSAI enable */
+#define RCU_CTL_PLLSAISTB               BIT(29)                   /*!< PLLSAI Clock Stabilization Flag */
+
+/* RCU_PLL */
+#define RCU_PLL_PLLPSC                  BITS(0,5)                 /*!< The PLL VCO source clock prescaler */
+#define RCU_PLL_PLLN                    BITS(6,14)                /*!< The PLL VCO clock multi factor */
+#define RCU_PLL_PLLP                    BITS(16,17)               /*!< The PLLP output frequency division factor from PLL VCO clock */
+#define RCU_PLL_PLLSEL                  BIT(22)                   /*!< PLL Clock Source Selection */
+#define RCU_PLL_PLLQ                    BITS(24,27)               /*!< The PLL Q output frequency division factor from PLL VCO clock */
+
+/* RCU_CFG0 */
+#define RCU_CFG0_SCS                    BITS(0,1)                 /*!< system clock switch */
+#define RCU_CFG0_SCSS                   BITS(2,3)                 /*!< system clock switch status */
+#define RCU_CFG0_AHBPSC                 BITS(4,7)                 /*!< AHB prescaler selection */
+#define RCU_CFG0_APB1PSC                BITS(10,12)               /*!< APB1 prescaler selection */
+#define RCU_CFG0_APB2PSC                BITS(13,15)               /*!< APB2 prescaler selection */
+#define RCU_CFG0_RTCDIV                 BITS(16,20)               /*!< RTC clock divider factor */
+#define RCU_CFG0_CKOUT0SEL              BITS(21,22)               /*!< CKOUT0 Clock Source Selection */
+#define RCU_CFG0_I2SSEL                 BIT(23)                   /*!< I2S Clock Source Selection */
+#define RCU_CFG0_CKOUT0DIV              BITS(24,26)               /*!< The CK_OUT0 divider which the CK_OUT0 frequency can be reduced */
+#define RCU_CFG0_CKOUT1DIV              BITS(27,29)               /*!< The CK_OUT1 divider which the CK_OUT1 frequency can be reduced */
+#define RCU_CFG0_CKOUT1SEL              BITS(30,31)               /*!< CKOUT1 Clock Source Selection */
+
+/* RCU_INT */
+#define RCU_INT_IRC32KSTBIF             BIT(0)                    /*!< IRC32K stabilization interrupt flag */
+#define RCU_INT_LXTALSTBIF              BIT(1)                    /*!< LXTAL stabilization interrupt flag */
+#define RCU_INT_IRC16MSTBIF             BIT(2)                    /*!< IRC16M stabilization interrupt flag */
+#define RCU_INT_HXTALSTBIF              BIT(3)                    /*!< HXTAL stabilization interrupt flag */
+#define RCU_INT_PLLSTBIF                BIT(4)                    /*!< PLL stabilization interrupt flag */
+#define RCU_INT_PLLI2SSTBIF             BIT(5)                    /*!< PLLI2S stabilization interrupt flag */
+#define RCU_INT_PLLSAISTBIF             BIT(6)                    /*!< PLLSAI stabilization interrupt flag */
+#define RCU_INT_CKMIF                   BIT(7)                    /*!< HXTAL clock stuck interrupt flag */
+#define RCU_INT_IRC32KSTBIE             BIT(8)                    /*!< IRC32K stabilization interrupt enable */
+#define RCU_INT_LXTALSTBIE              BIT(9)                    /*!< LXTAL stabilization interrupt enable */
+#define RCU_INT_IRC16MSTBIE             BIT(10)                   /*!< IRC16M stabilization interrupt enable */
+#define RCU_INT_HXTALSTBIE              BIT(11)                   /*!< HXTAL stabilization interrupt enable */
+#define RCU_INT_PLLSTBIE                BIT(12)                   /*!< PLL stabilization interrupt enable */
+#define RCU_INT_PLLI2SSTBIE             BIT(13)                   /*!< PLLI2S Stabilization Interrupt Enable */
+#define RCU_INT_PLLSAISTBIE             BIT(14)                   /*!< PLLSAI Stabilization Interrupt Enable */
+#define RCU_INT_IRC32KSTBIC             BIT(16)                   /*!< IRC32K Stabilization Interrupt Clear */
+#define RCU_INT_LXTALSTBIC              BIT(17)                   /*!< LXTAL Stabilization Interrupt Clear */
+#define RCU_INT_IRC16MSTBIC             BIT(18)                   /*!< IRC16M Stabilization Interrupt Clear */
+#define RCU_INT_HXTALSTBIC              BIT(19)                   /*!< HXTAL Stabilization Interrupt Clear */
+#define RCU_INT_PLLSTBIC                BIT(20)                   /*!< PLL stabilization Interrupt Clear */
+#define RCU_INT_PLLI2SSTBIC             BIT(21)                   /*!< PLLI2S stabilization Interrupt Clear */
+#define RCU_INT_PLLSAISTBIC             BIT(22)                   /*!< PLLSAI stabilization Interrupt Clear */
+#define RCU_INT_CKMIC                   BIT(23)                   /*!< HXTAL Clock Stuck Interrupt Clear */
+
+/* RCU_AHB1RST */
+#define RCU_AHB1RST_PARST               BIT(0)                    /*!< GPIO port A reset */
+#define RCU_AHB1RST_PBRST               BIT(1)                    /*!< GPIO port B reset */
+#define RCU_AHB1RST_PCRST               BIT(2)                    /*!< GPIO port C reset */
+#define RCU_AHB1RST_PDRST               BIT(3)                    /*!< GPIO port D reset */
+#define RCU_AHB1RST_PERST               BIT(4)                    /*!< GPIO port E reset */
+#define RCU_AHB1RST_PFRST               BIT(5)                    /*!< GPIO port F reset */
+#define RCU_AHB1RST_PGRST               BIT(6)                    /*!< GPIO port G reset */
+#define RCU_AHB1RST_PHRST               BIT(7)                    /*!< GPIO port H reset */
+#define RCU_AHB1RST_PIRST               BIT(8)                    /*!< GPIO port I reset */
+#define RCU_AHB1RST_CRCRST              BIT(12)                   /*!< CRC reset */ 
+#define RCU_AHB1RST_DMA0RST             BIT(21)                   /*!< DMA0 reset */
+#define RCU_AHB1RST_DMA1RST             BIT(22)                   /*!< DMA1 reset */
+#define RCU_AHB1RST_IPARST              BIT(23)                   /*!< IPA reset */
+#define RCU_AHB1RST_ENETRST             BIT(25)                   /*!< ENET reset */
+#define RCU_AHB1RST_USBHSRST            BIT(29)                   /*!< USBHS reset */
+
+/* RCU_AHB2RST */
+#define RCU_AHB2RST_DCIRST              BIT(0)                    /*!< DCI reset */
+#define RCU_AHB2RST_TRNGRST             BIT(6)                    /*!< TRNG reset */
+#define RCU_AHB2RST_USBFSRST            BIT(7)                    /*!< USBFS reset */
+                                    
+/* RCU_AHB3RST */
+#define RCU_AHB3RST_EXMCRST             BIT(0)                    /*!< EXMC reset */
+
+/* RCU_APB1RST */
+#define RCU_APB1RST_TIMER1RST           BIT(0)                    /*!< TIMER1 reset */
+#define RCU_APB1RST_TIMER2RST           BIT(1)                    /*!< TIMER2 reset */
+#define RCU_APB1RST_TIMER3RST           BIT(2)                    /*!< TIMER3 reset */
+#define RCU_APB1RST_TIMER4RST           BIT(3)                    /*!< TIMER4 reset */
+#define RCU_APB1RST_TIMER5RST           BIT(4)                    /*!< TIMER5 reset */
+#define RCU_APB1RST_TIMER6RST           BIT(5)                    /*!< TIMER6 reset */
+#define RCU_APB1RST_TIMER11RST          BIT(6)                    /*!< TIMER11 reset */
+#define RCU_APB1RST_TIMER12RST          BIT(7)                    /*!< TIMER12 reset */
+#define RCU_APB1RST_TIMER13RST          BIT(8)                    /*!< TIMER13 reset */
+#define RCU_APB1RST_WWDGTRST            BIT(11)                   /*!< WWDGT reset */
+#define RCU_APB1RST_SPI1RST             BIT(14)                   /*!< SPI1 reset */
+#define RCU_APB1RST_SPI2RST             BIT(15)                   /*!< SPI2 reset */
+#define RCU_APB1RST_USART1RST           BIT(17)                   /*!< USART1 reset */
+#define RCU_APB1RST_USART2RST           BIT(18)                   /*!< USART2 reset */
+#define RCU_APB1RST_UART3RST            BIT(19)                   /*!< UART3 reset */
+#define RCU_APB1RST_UART4RST            BIT(20)                   /*!< UART4 reset */
+#define RCU_APB1RST_I2C0RST             BIT(21)                   /*!< I2C0 reset */
+#define RCU_APB1RST_I2C1RST             BIT(22)                   /*!< I2C1 reset */
+#define RCU_APB1RST_I2C2RST             BIT(23)                   /*!< I2C2 reset */
+#define RCU_APB1RST_CAN0RST             BIT(25)                   /*!< CAN0 reset */
+#define RCU_APB1RST_CAN1RST             BIT(26)                   /*!< CAN1 reset */
+#define RCU_APB1RST_PMURST              BIT(28)                   /*!< PMU reset */
+#define RCU_APB1RST_DACRST              BIT(29)                   /*!< DAC reset */
+#define RCU_APB1RST_UART6RST            BIT(30)                   /*!< UART6 reset */
+#define RCU_APB1RST_UART7RST            BIT(31)                   /*!< UART7 reset */
+
+/* RCU_APB2RST */
+#define RCU_APB2RST_TIMER0RST           BIT(0)                    /*!< TIMER0 reset */
+#define RCU_APB2RST_TIMER7RST           BIT(1)                    /*!< TIMER7  reset */
+#define RCU_APB2RST_USART0RST           BIT(4)                    /*!< USART0 reset */
+#define RCU_APB2RST_USART5RST           BIT(5)                    /*!< USART5  reset */
+#define RCU_APB2RST_ADCRST              BIT(8)                    /*!< ADC reset */
+#define RCU_APB2RST_SDIORST             BIT(11)                   /*!< SDIO reset */
+#define RCU_APB2RST_SPI0RST             BIT(12)                   /*!< SPI0 reset */
+#define RCU_APB2RST_SPI3RST             BIT(13)                   /*!< SPI3 reset */
+#define RCU_APB2RST_SYSCFGRST           BIT(14)                   /*!< SYSCFG reset */
+#define RCU_APB2RST_TIMER8RST           BIT(16)                   /*!< TIMER8 reset */
+#define RCU_APB2RST_TIMER9RST           BIT(17)                   /*!< TIMER9 reset */
+#define RCU_APB2RST_TIMER10RST          BIT(18)                   /*!< TIMER10 reset */
+#define RCU_APB2RST_SPI4RST             BIT(20)                   /*!< SPI4 reset */
+#define RCU_APB2RST_SPI5RST             BIT(21)                   /*!< SPI5 reset */
+#define RCU_APB2RST_TLIRST              BIT(26)                   /*!< TLI reset */
+
+/* RCU_AHB1EN */
+#define RCU_AHB1EN_PAEN                 BIT(0)                    /*!< GPIO port A clock enable */
+#define RCU_AHB1EN_PBEN                 BIT(1)                    /*!< GPIO port B clock enable */
+#define RCU_AHB1EN_PCEN                 BIT(2)                    /*!< GPIO port C clock enable */
+#define RCU_AHB1EN_PDEN                 BIT(3)                    /*!< GPIO port D clock enable */
+#define RCU_AHB1EN_PEEN                 BIT(4)                    /*!< GPIO port E clock enable */
+#define RCU_AHB1EN_PFEN                 BIT(5)                    /*!< GPIO port F clock enable */
+#define RCU_AHB1EN_PGEN                 BIT(6)                    /*!< GPIO port G clock enable */
+#define RCU_AHB1EN_PHEN                 BIT(7)                    /*!< GPIO port H clock enable */
+#define RCU_AHB1EN_PIEN                 BIT(8)                    /*!< GPIO port I clock enable */
+#define RCU_AHB1EN_CRCEN                BIT(12)                   /*!< CRC clock enable */
+#define RCU_AHB1EN_BKPSRAMEN            BIT(18)                   /*!< BKPSRAM clock enable */
+#define RCU_AHB1EN_TCMSRAMEN            BIT(20)                   /*!< TCMSRAM clock enable */
+#define RCU_AHB1EN_DMA0EN               BIT(21)                   /*!< DMA0 clock enable */
+#define RCU_AHB1EN_DMA1EN               BIT(22)                   /*!< DMA1 clock enable */
+#define RCU_AHB1EN_IPAEN                BIT(23)                   /*!< IPA clock enable */
+#define RCU_AHB1EN_ENETEN               BIT(25)                   /*!< ENET clock enable */
+#define RCU_AHB1EN_ENETTXEN             BIT(26)                   /*!< Ethernet TX clock enable */
+#define RCU_AHB1EN_ENETRXEN             BIT(27)                   /*!< Ethernet RX clock enable */
+#define RCU_AHB1EN_ENETPTPEN            BIT(28)                   /*!< Ethernet PTP clock enable */
+#define RCU_AHB1EN_USBHSEN              BIT(29)                   /*!< USBHS clock enable */
+#define RCU_AHB1EN_USBHSULPIEN          BIT(30)                   /*!< USBHS ULPI clock enable */
+
+/* RCU_AHB2EN */
+#define RCU_AHB2EN_DCIEN                BIT(0)                    /*!< DCI clock enable */
+#define RCU_AHB2EN_TRNGEN               BIT(6)                    /*!< TRNG clock enable */
+#define RCU_AHB2EN_USBFSEN              BIT(7)                    /*!< USBFS clock enable */
+
+/* RCU_AHB3EN */
+#define RCU_AHB3EN_EXMCEN               BIT(0)                    /*!< EXMC clock enable */
+
+/* RCU_APB1EN */
+#define RCU_APB1EN_TIMER1EN             BIT(0)                    /*!< TIMER1 clock enable */
+#define RCU_APB1EN_TIMER2EN             BIT(1)                    /*!< TIMER2 clock enable */
+#define RCU_APB1EN_TIMER3EN             BIT(2)                    /*!< TIMER3 clock enable */
+#define RCU_APB1EN_TIMER4EN             BIT(3)                    /*!< TIMER4 clock enable */
+#define RCU_APB1EN_TIMER5EN             BIT(4)                    /*!< TIMER5 clock enable */
+#define RCU_APB1EN_TIMER6EN             BIT(5)                    /*!< TIMER6 clock enable */
+#define RCU_APB1EN_TIMER11EN            BIT(6)                    /*!< TIMER11 clock enable */
+#define RCU_APB1EN_TIMER12EN            BIT(7)                    /*!< TIMER12 clock enable */
+#define RCU_APB1EN_TIMER13EN            BIT(8)                    /*!< TIMER13 clock enable */
+#define RCU_APB1EN_WWDGTEN              BIT(11)                   /*!< WWDGT clock enable */
+#define RCU_APB1EN_SPI1EN               BIT(14)                   /*!< SPI1 clock enable */
+#define RCU_APB1EN_SPI2EN               BIT(15)                   /*!< SPI2 clock enable */
+#define RCU_APB1EN_USART1EN             BIT(17)                   /*!< USART1 clock enable */
+#define RCU_APB1EN_USART2EN             BIT(18)                   /*!< USART2 clock enable */
+#define RCU_APB1EN_UART3EN              BIT(19)                   /*!< UART3 clock enable */
+#define RCU_APB1EN_UART4EN              BIT(20)                   /*!< UART4 clock enable */
+#define RCU_APB1EN_I2C0EN               BIT(21)                   /*!< I2C0 clock enable */
+#define RCU_APB1EN_I2C1EN               BIT(22)                   /*!< I2C1 clock enable */
+#define RCU_APB1EN_I2C2EN               BIT(23)                   /*!< I2C2 clock enable */
+#define RCU_APB1EN_CAN0EN               BIT(25)                   /*!< CAN0 clock enable */
+#define RCU_APB1EN_CAN1EN               BIT(26)                   /*!< CAN1 clock enable */
+#define RCU_APB1EN_PMUEN                BIT(28)                   /*!< PMU clock enable */
+#define RCU_APB1EN_DACEN                BIT(29)                   /*!< DAC clock enable */
+#define RCU_APB1EN_UART6EN              BIT(30)                   /*!< UART6 clock enable */
+#define RCU_APB1EN_UART7EN              BIT(31)                   /*!< UART7 clock enable */
+
+/* RCU_APB2EN */
+#define RCU_APB2EN_TIMER0EN             BIT(0)                    /*!< TIMER0 clock enable */
+#define RCU_APB2EN_TIMER7EN             BIT(1)                    /*!< TIMER7 clock enable */
+#define RCU_APB2EN_USART0EN             BIT(4)                    /*!< USART0 clock enable */
+#define RCU_APB2EN_USART5EN             BIT(5)                    /*!< USART5 clock enable */
+#define RCU_APB2EN_ADC0EN               BIT(8)                    /*!< ADC0 clock enable */
+#define RCU_APB2EN_ADC1EN               BIT(9)                    /*!< ADC1 clock enable */
+#define RCU_APB2EN_ADC2EN               BIT(10)                   /*!< ADC2 clock enable */
+#define RCU_APB2EN_SDIOEN               BIT(11)                   /*!< SDIO clock enable */
+#define RCU_APB2EN_SPI0EN               BIT(12)                   /*!< SPI0 clock enable */
+#define RCU_APB2EN_SPI3EN               BIT(13)                   /*!< SPI3 clock enable */
+#define RCU_APB2EN_SYSCFGEN             BIT(14)                   /*!< SYSCFG clock enable */
+#define RCU_APB2EN_TIMER8EN             BIT(16)                   /*!< TIMER8 clock enable */
+#define RCU_APB2EN_TIMER9EN             BIT(17)                   /*!< TIMER9 clock enable */
+#define RCU_APB2EN_TIMER10EN            BIT(18)                   /*!< TIMER10 clock enable */
+#define RCU_APB2EN_SPI4EN               BIT(20)                   /*!< SPI4 clock enable */
+#define RCU_APB2EN_SPI5EN               BIT(21)                   /*!< SPI5 clock enable */
+#define RCU_APB2EN_TLIEN                BIT(26)                   /*!< TLI clock enable */
+
+/* RCU_AHB1SPEN */
+#define RCU_AHB1SPEN_PASPEN             BIT(0)                    /*!< GPIO port A clock enable when sleep mode */
+#define RCU_AHB1SPEN_PBSPEN             BIT(1)                    /*!< GPIO port B clock enable when sleep mode */
+#define RCU_AHB1SPEN_PCSPEN             BIT(2)                    /*!< GPIO port C clock enable when sleep mode */
+#define RCU_AHB1SPEN_PDSPEN             BIT(3)                    /*!< GPIO port D clock enable when sleep mode */
+#define RCU_AHB1SPEN_PESPEN             BIT(4)                    /*!< GPIO port E clock enable when sleep mode */
+#define RCU_AHB1SPEN_PFSPEN             BIT(5)                    /*!< GPIO port F clock enable when sleep mode */
+#define RCU_AHB1SPEN_PGSPEN             BIT(6)                    /*!< GPIO port G clock enable when sleep mode */
+#define RCU_AHB1SPEN_PHSPEN             BIT(7)                    /*!< GPIO port H clock enable when sleep mode */
+#define RCU_AHB1SPEN_PISPEN             BIT(8)                    /*!< GPIO port I clock enable when sleep mode */
+#define RCU_AHB1SPEN_CRCSPEN            BIT(12)                   /*!< CRC clock enable when sleep mode */
+#define RCU_AHB1SPEN_FMCSPEN            BIT(15)                   /*!< FMC clock enable when sleep mode */
+#define RCU_AHB1SPEN_SRAM0SPEN          BIT(16)                   /*!< SRAM0 clock enable when sleep mode */
+#define RCU_AHB1SPEN_SRAM1SPEN          BIT(17)                   /*!< SRAM1 clock enable when sleep mode */
+#define RCU_AHB1SPEN_BKPSRAMSPEN        BIT(18)                   /*!< BKPSRAM clock enable when sleep mode */
+#define RCU_AHB1SPEN_SRAM2SPEN          BIT(19)                   /*!< SRAM2 clock enable when sleep mode */
+#define RCU_AHB1SPEN_DMA0SPEN           BIT(21)                   /*!< DMA0 clock when sleep mode enable */
+#define RCU_AHB1SPEN_DMA1SPEN           BIT(22)                   /*!< DMA1 clock when sleep mode enable */
+#define RCU_AHB1SPEN_IPASPEN            BIT(23)                   /*!< IPA clock enable when sleep mode */
+#define RCU_AHB1SPEN_ENETSPEN           BIT(25)                   /*!< ENET clock enable when sleep mode */
+#define RCU_AHB1SPEN_ENETTXSPEN         BIT(26)                   /*!< Ethernet TX clock enable when sleep mode */
+#define RCU_AHB1SPEN_ENETRXSPEN         BIT(27)                   /*!< Ethernet RX clock enable when sleep mode */
+#define RCU_AHB1SPEN_ENETPTPSPEN        BIT(28)                   /*!< Ethernet PTP clock enable when sleep mode */
+#define RCU_AHB1SPEN_USBHSSPEN          BIT(29)                   /*!< USBHS clock enable when sleep mode */
+#define RCU_AHB1SPEN_USBHSULPISPEN      BIT(30)                   /*!< USBHS ULPI clock enable when sleep mode */
+
+/* RCU_AHB2SPEN */
+#define RCU_AHB2SPEN_DCISPEN            BIT(0)                    /*!< DCI clock enable when sleep mode */
+#define RCU_AHB2SPEN_TRNGSPEN           BIT(6)                    /*!< TRNG clock enable when sleep mode */
+#define RCU_AHB2SPEN_USBFSSPEN          BIT(7)                    /*!< USBFS clock enable when sleep mode */
+
+/* RCU_AHB3SPEN */
+#define RCU_AHB3SPEN_EXMCSPEN           BIT(0)                    /*!< EXMC clock enable when sleep mode */
+
+/* RCU_APB1SPEN */
+#define RCU_APB1SPEN_TIMER1SPEN         BIT(0)                    /*!< TIMER1 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER2SPEN         BIT(1)                    /*!< TIMER2 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER3SPEN         BIT(2)                    /*!< TIMER3 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER4SPEN         BIT(3)                    /*!< TIMER4 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER5SPEN         BIT(4)                    /*!< TIMER5 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER6SPEN         BIT(5)                    /*!< TIMER6 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER11SPEN        BIT(6)                    /*!< TIMER11 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER12SPEN        BIT(7)                    /*!< TIMER12 clock enable when sleep mode */
+#define RCU_APB1SPEN_TIMER13SPEN        BIT(8)                    /*!< TIMER13 clock enable when sleep mode */
+#define RCU_APB1SPEN_WWDGTSPEN          BIT(11)                   /*!< WWDGT clock enable when sleep mode */
+#define RCU_APB1SPEN_SPI1SPEN           BIT(14)                   /*!< SPI1 clock enable when sleep mode */
+#define RCU_APB1SPEN_SPI2SPEN           BIT(15)                   /*!< SPI2 clock enable when sleep mode */
+#define RCU_APB1SPEN_USART1SPEN         BIT(17)                   /*!< USART1 clock enable when sleep mode*/
+#define RCU_APB1SPEN_USART2SPEN         BIT(18)                   /*!< USART2 clock enable when sleep mode*/
+#define RCU_APB1SPEN_UART3SPEN          BIT(19)                   /*!< UART3 clock enable when sleep mode*/
+#define RCU_APB1SPEN_UART4SPEN          BIT(20)                   /*!< UART4 clock enable when sleep mode */
+#define RCU_APB1SPEN_I2C0SPEN           BIT(21)                   /*!< I2C0 clock enable when sleep mode */
+#define RCU_APB1SPEN_I2C1SPEN           BIT(22)                   /*!< I2C1 clock enable when sleep mode*/
+#define RCU_APB1SPEN_I2C2SPEN           BIT(23)                   /*!< I2C2 clock enable when sleep mode */
+#define RCU_APB1SPEN_CAN0SPEN           BIT(25)                   /*!< CAN0 clock enable when sleep mode*/
+#define RCU_APB1SPEN_CAN1SPEN           BIT(26)                   /*!< CAN1 clock enable when sleep mode */
+#define RCU_APB1SPEN_PMUSPEN            BIT(28)                   /*!< PMU clock enable when sleep mode */
+#define RCU_APB1SPEN_DACSPEN            BIT(29)                   /*!< DAC clock enable when sleep mode */
+#define RCU_APB1SPEN_UART6SPEN          BIT(30)                   /*!< UART6 clock enable when sleep mode */
+#define RCU_APB1SPEN_UART7SPEN          BIT(31)                   /*!< UART7 clock enable when sleep mode */
+
+/* RCU_APB2SPEN */
+#define RCU_APB2SPEN_TIMER0SPEN         BIT(0)                    /*!< TIMER0 clock enable when sleep mode */
+#define RCU_APB2SPEN_TIMER7SPEN         BIT(1)                    /*!< TIMER7 clock enable when sleep mode */
+#define RCU_APB2SPEN_USART0SPEN         BIT(4)                    /*!< USART0 clock enable when sleep mode */
+#define RCU_APB2SPEN_USART5SPEN         BIT(5)                    /*!< USART5 clock enable when sleep mode */
+#define RCU_APB2SPEN_ADC0SPEN           BIT(8)                    /*!< ADC0 clock enable when sleep mode */
+#define RCU_APB2SPEN_ADC1SPEN           BIT(9)                    /*!< ADC1 clock enable when sleep mode */
+#define RCU_APB2SPEN_ADC2SPEN           BIT(10)                   /*!< ADC2 clock enable when sleep mode */
+#define RCU_APB2SPEN_SDIOSPEN           BIT(11)                   /*!< SDIO clock enable when sleep mode */
+#define RCU_APB2SPEN_SPI0SPEN           BIT(12)                   /*!< SPI0 clock enable when sleep mode */
+#define RCU_APB2SPEN_SPI3SPEN           BIT(13)                   /*!< SPI3 clock enable when sleep mode */
+#define RCU_APB2SPEN_SYSCFGSPEN         BIT(14)                   /*!< SYSCFG clock enable when sleep mode */
+#define RCU_APB2SPEN_TIMER8SPEN         BIT(16)                   /*!< TIMER8 clock enable when sleep mode */
+#define RCU_APB2SPEN_TIMER9SPEN         BIT(17)                   /*!< TIMER9 clock enable when sleep mode */
+#define RCU_APB2SPEN_TIMER10SPEN        BIT(18)                   /*!< TIMER10 clock enable when sleep mode */
+#define RCU_APB2SPEN_SPI4SPEN           BIT(20)                   /*!< SPI4 clock enable when sleep mode */
+#define RCU_APB2SPEN_SPI5SPEN           BIT(21)                   /*!< SPI5 clock enable when sleep mode */
+#define RCU_APB2SPEN_TLISPEN            BIT(26)                   /*!< TLI clock enable when sleep mode*/
+
+/* RCU_BDCTL */
+#define RCU_BDCTL_LXTALEN               BIT(0)                    /*!< LXTAL enable */
+#define RCU_BDCTL_LXTALSTB              BIT(1)                    /*!< low speed crystal oscillator stabilization flag */
+#define RCU_BDCTL_LXTALBPS              BIT(2)                    /*!< LXTAL bypass mode enable */
+#define RCU_BDCTL_LXTALDRI              BIT(3)                    /*!< LXTAL drive capability */
+#define RCU_BDCTL_RTCSRC                BITS(8,9)                 /*!< RTC clock entry selection */
+#define RCU_BDCTL_RTCEN                 BIT(15)                   /*!< RTC clock enable */
+#define RCU_BDCTL_BKPRST                BIT(16)                   /*!< backup domain reset */
+
+/* RCU_RSTSCK */
+#define RCU_RSTSCK_IRC32KEN             BIT(0)                    /*!< IRC32K enable */
+#define RCU_RSTSCK_IRC32KSTB            BIT(1)                    /*!< IRC32K stabilization flag */
+#define RCU_RSTSCK_RSTFC                BIT(24)                   /*!< reset flag clear */
+#define RCU_RSTSCK_BORRSTF              BIT(25)                   /*!< BOR reset flag */
+#define RCU_RSTSCK_EPRSTF               BIT(26)                   /*!< external pin reset flag */
+#define RCU_RSTSCK_PORRSTF              BIT(27)                   /*!< power reset flag */
+#define RCU_RSTSCK_SWRSTF               BIT(28)                   /*!< software reset flag */
+#define RCU_RSTSCK_FWDGTRSTF            BIT(29)                   /*!< free watchdog timer reset flag */
+#define RCU_RSTSCK_WWDGTRSTF            BIT(30)                   /*!< window watchdog timer reset flag */
+#define RCU_RSTSCK_LPRSTF               BIT(31)                   /*!< low-power reset flag */
+
+/* RCU_PLLSSCTL */
+#define RCU_PLLSSCTL_MODCNT             BITS(0,12)                /*!< these bits configure PLL spread spectrum modulation 
+                                                                       profile amplitude and frequency. the following criteria 
+                                                                       must be met: MODSTEP*MODCNT=215-1 */
+#define RCU_PLLSSCTL_MODSTEP            BITS(13,27)               /*!< these bits configure PLL spread spectrum modulation 
+                                                                       profile amplitude and frequency. the following criteria 
+                                                                       must be met: MODSTEP*MODCNT=215-1 */
+#define RCU_PLLSSCTL_SS_TYPE            BIT(30)                   /*!< PLL spread spectrum modulation type select */
+#define RCU_PLLSSCTL_SSCGON             BIT(31)                   /*!< PLL spread spectrum modulation enable */
+
+/* RCU_PLLI2S */
+#define RCU_PLLI2S_PLLI2SN              BITS(6,14)                /*!< the PLLI2S VCO clock multi factor */
+#define RCU_PLLI2S_PLLI2SQ              BITS(24,27)               /*!< the PLLI2S Q output frequency division factor from PLLI2S VCO clock */
+#define RCU_PLLI2S_PLLI2SR              BITS(28,30)               /*!< the PLLI2S R output frequency division factor from PLLI2S VCO clock */
+
+/* RCU_PLLSAI */
+#define RCU_PLLSAI_PLLSAIN              BITS(6,14)                /*!< the PLLSAI VCO clock multi factor */
+#define RCU_PLLSAI_PLLSAIP              BITS(16,17)               /*!< the PLLSAI P output frequency division factor from PLLSAI VCO clock */
+#define RCU_PLLSAI_PLLSAIQ              BITS(24,27)               /*!< the PLLSAI Q output frequency division factor from PLLSAI VCO clock */
+#define RCU_PLLSAI_PLLSAIR              BITS(28,30)               /*!< the PLLSAI R output frequency division factor from PLLSAI VCO clock */
+
+/* RCU_CFG1 */
+#define RCU_CFG1_PLLSAIRDIV             BITS(16,17)               /*!< the divider factor from PLLSAIR clock */
+#define RCU_CFG1_TIMERSEL               BIT(24)                   /*!< TIMER clock selection */
+
+/* RCU_ADDCTL */
+#define RCU_ADDCTL_CK48MSEL             BIT(0)                    /*!< 48MHz clock selection */
+#define RCU_ADDCTL_PLL48MSEL            BIT(1)                    /*!< PLL48M clock selection */
+#define RCU_ADDCTL_IRC48MEN             BIT(16)                   /*!< internal 48MHz RC oscillator enable */
+#define RCU_ADDCTL_IRC48MSTB            BIT(17)                   /*!< internal 48MHz RC oscillator clock stabilization flag */
+#define RCU_ADDCTL_IRC48MCAL            BITS(24,31)               /*!< internal 48MHz RC oscillator calibration value register */
+
+/* RCU_ADDINT */
+#define RCU_ADDINT_IRC48MSTBIF          BIT(6)                    /*!< IRC48M stabilization interrupt flag */
+#define RCU_ADDINT_IRC48MSTBIE          BIT(14)                   /*!< internal 48 MHz RC oscillator stabilization interrupt enable */
+#define RCU_ADDINT_IRC48MSTBIC          BIT(22)                   /*!< internal 48 MHz RC oscillator stabilization interrupt clear */
+
+/* RCU_ADDAPB1RST */
+#define RCU_ADDAPB1RST_CTCRST           BIT(27)                   /*!< CTC reset */
+#define RCU_ADDAPB1RST_IREFRST          BIT(31)                   /*!< IREF reset */
+
+/* RCU_ADDAPB1EN */
+#define RCU_ADDAPB1EN_CTCEN             BIT(27)                   /*!< CTC clock enable */
+#define RCU_ADDAPB1EN_IREFEN            BIT(31)                   /*!< IREF interface clock enable */
+
+/* RCU_ADDAPB1SPEN */
+#define RCU_ADDAPB1SPEN_CTCSPEN         BIT(27)                   /*!< CTC clock enable during sleep mode */
+#define RCU_ADDAPB1SPEN_IREFSPEN        BIT(31)                   /*!< IREF interface clock enable during sleep mode */
+
+/* RCU_VKEY */
+#define RCU_VKEY_KEY                    BITS(0,31)                /*!< RCU_DSV key register */
+
+/* RCU_DSV */
+#define RCU_DSV_DSLPVS                  BITS(0,2)                 /*!< deep-sleep mode voltage select */
+
+/* constants definitions */
+/* define the peripheral clock enable bit position and its register index offset */
+#define RCU_REGIDX_BIT(regidx, bitpos)      (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define RCU_REG_VAL(periph)                 (REG32(RCU + ((uint32_t)(periph) >> 6)))
+#define RCU_BIT_POS(val)                    ((uint32_t)(val) & 0x1FU)
+/* define the voltage key unlock value */
+#define RCU_VKEY_UNLOCK                 ((uint32_t)0x1A2B3C4DU)
+
+/* register offset */
+/* peripherals enable */
+#define AHB1EN_REG_OFFSET               0x30U                     /*!< AHB1 enable register offset */
+#define AHB2EN_REG_OFFSET               0x34U                     /*!< AHB2 enable register offset */
+#define AHB3EN_REG_OFFSET               0x38U                     /*!< AHB3 enable register offset */
+#define APB1EN_REG_OFFSET               0x40U                     /*!< APB1 enable register offset */
+#define APB2EN_REG_OFFSET               0x44U                     /*!< APB2 enable register offset */
+#define AHB1SPEN_REG_OFFSET             0x50U                     /*!< AHB1 sleep mode enable register offset */
+#define AHB2SPEN_REG_OFFSET             0x54U                     /*!< AHB2 sleep mode enable register offset */
+#define AHB3SPEN_REG_OFFSET             0x58U                     /*!< AHB3 sleep mode enable register offset */
+#define APB1SPEN_REG_OFFSET             0x60U                     /*!< APB1 sleep mode enable register offset */
+#define APB2SPEN_REG_OFFSET             0x64U                     /*!< APB2 sleep mode enable register offset */
+#define ADD_APB1EN_REG_OFFSET           0xE4U                     /*!< APB1 additional enable register offset */
+#define ADD_APB1SPEN_REG_OFFSET         0xE8U                     /*!< APB1 additional sleep mode enable register offset */
+
+/* peripherals reset */                                        
+#define AHB1RST_REG_OFFSET              0x10U                     /*!< AHB1 reset register offset */
+#define AHB2RST_REG_OFFSET              0x14U                     /*!< AHB2 reset register offset */
+#define AHB3RST_REG_OFFSET              0x18U                     /*!< AHB3 reset register offset */
+#define APB1RST_REG_OFFSET              0x20U                     /*!< APB1 reset register offset */
+#define APB2RST_REG_OFFSET              0x24U                     /*!< APB2 reset register offset */
+#define ADD_APB1RST_REG_OFFSET          0xE0U                     /*!< APB1 additional reset register offset */
+#define RSTSCK_REG_OFFSET               0x74U                     /*!< reset source/clock register offset */
+
+/* clock control */
+#define CTL_REG_OFFSET                  0x00U                     /*!< control register offset */
+#define BDCTL_REG_OFFSET                0x70U                     /*!< backup domain control register offset */
+#define ADDCTL_REG_OFFSET               0xC0U                     /*!< additional clock control register offset */
+
+/* clock stabilization and stuck interrupt */
+#define INT_REG_OFFSET                  0x0CU                     /*!< clock interrupt register offset */
+#define ADDINT_REG_OFFSET               0xCCU                     /*!< additional clock interrupt register offset */
+
+/* configuration register */
+#define PLL_REG_OFFSET                  0x04U                     /*!< PLL register offset */
+#define CFG0_REG_OFFSET                 0x08U                     /*!< clock configuration register 0 offset */
+#define PLLSSCTL_REG_OFFSET             0x80U                     /*!< PLL clock spread spectrum control register offset */
+#define PLLI2S_REG_OFFSET               0x84U                     /*!< PLLI2S register offset */
+#define PLLSAI_REG_OFFSET               0x88U                     /*!< PLLSAI register offset */
+#define CFG1_REG_OFFSET                 0x8CU                     /*!< clock configuration register 1 offset */
+
+/* peripheral clock enable */
+typedef enum
+{
+    /* AHB1 peripherals */
+    RCU_GPIOA     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 0U),                  /*!< GPIOA clock */
+    RCU_GPIOB     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 1U),                  /*!< GPIOB clock */
+    RCU_GPIOC     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 2U),                  /*!< GPIOC clock */
+    RCU_GPIOD     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 3U),                  /*!< GPIOD clock */
+    RCU_GPIOE     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 4U),                  /*!< GPIOE clock */
+    RCU_GPIOF     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 5U),                  /*!< GPIOF clock */
+    RCU_GPIOG     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 6U),                  /*!< GPIOG clock */
+    RCU_GPIOH     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 7U),                  /*!< GPIOH clock */
+    RCU_GPIOI     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 8U),                  /*!< GPIOI clock */
+    RCU_CRC       = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 12U),                 /*!< CRC clock */
+    RCU_BKPSRAM   = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 18U),                 /*!< BKPSRAM clock */
+    RCU_TCMSRAM   = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 20U),                 /*!< TCMSRAM clock */
+    RCU_DMA0      = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 21U),                 /*!< DMA0 clock */
+    RCU_DMA1      = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 22U),                 /*!< DMA1 clock */
+    RCU_IPA       = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 23U),                 /*!< IPA clock */
+    RCU_ENET      = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 25U),                 /*!< ENET clock */
+    RCU_ENETTX    = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 26U),                 /*!< ENETTX clock */
+    RCU_ENETRX    = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 27U),                 /*!< ENETRX clock */
+    RCU_ENETPTP   = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 28U),                 /*!< ENETPTP clock */
+    RCU_USBHS     = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 29U),                 /*!< USBHS clock */
+    RCU_USBHSULPI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 30U),                 /*!< USBHSULPI clock */
+    /* AHB2 peripherals */
+    RCU_DCI       = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 0U),                  /*!< DCI clock */
+    RCU_TRNG      = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 6U),                  /*!< TRNG clock */
+    RCU_USBFS     = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 7U),                  /*!< USBFS clock */
+    /* AHB3 peripherals */
+    RCU_EXMC      = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 0U),                  /*!< EXMC clock */
+    /* APB1 peripherals */
+    RCU_TIMER1    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 0U),                  /*!< TIMER1 clock */
+    RCU_TIMER2    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 1U),                  /*!< TIMER2 clock */
+    RCU_TIMER3    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 2U),                  /*!< TIMER3 clock */
+    RCU_TIMER4    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 3U),                  /*!< TIMER4 clock */
+    RCU_TIMER5    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 4U),                  /*!< TIMER5 clock */
+    RCU_TIMER6    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 5U),                  /*!< TIMER6 clock */
+    RCU_TIMER11   = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 6U),                  /*!< TIMER11 clock */
+    RCU_TIMER12   = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 7U),                  /*!< TIMER12 clock */
+    RCU_TIMER13   = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 8U),                  /*!< TIMER13 clock */   
+    RCU_WWDGT     = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 11U),                 /*!< WWDGT clock */
+    RCU_SPI1      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 14U),                 /*!< SPI1 clock */
+    RCU_SPI2      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 15U),                 /*!< SPI2 clock */
+    RCU_USART1    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 17U),                 /*!< USART1 clock */
+    RCU_USART2    = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 18U),                 /*!< USART2 clock */
+    RCU_UART3     = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 19U),                 /*!< UART3 clock */
+    RCU_UART4     = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 20U),                 /*!< UART4 clock */
+    RCU_I2C0      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 21U),                 /*!< I2C0 clock */
+    RCU_I2C1      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 22U),                 /*!< I2C1 clock */
+    RCU_I2C2      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 23U),                 /*!< I2C2 clock */   
+    RCU_CAN0      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 25U),                 /*!< CAN0 clock */
+    RCU_CAN1      = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 26U),                 /*!< CAN1 clock */
+    RCU_PMU       = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U),                 /*!< PMU clock */
+    RCU_DAC       = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 29U),                 /*!< DAC clock */
+    RCU_UART6     = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 30U),                 /*!< UART6 clock */
+    RCU_UART7     = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 31U),                 /*!< UART7 clock */
+    RCU_RTC       = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U),                  /*!< RTC clock */
+    /* APB2 peripherals */
+    RCU_TIMER0    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 0U),                  /*!< TIMER0 clock */
+    RCU_TIMER7    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 1U),                  /*!< TIMER7 clock */
+    RCU_USART0    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 4U),                  /*!< USART0 clock */
+    RCU_USART5    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 5U),                  /*!< USART5 clock */
+    RCU_ADC0      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 8U),                  /*!< ADC0 clock */
+    RCU_ADC1      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 9U),                  /*!< ADC1 clock */
+    RCU_ADC2      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 10U),                 /*!< ADC2 clock */
+    RCU_SDIO      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 11U),                 /*!< SDIO clock */
+    RCU_SPI0      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U),                 /*!< SPI0 clock */
+    RCU_SPI3      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 13U),                 /*!< SPI3 clock */
+    RCU_SYSCFG    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 14U),                 /*!< SYSCFG clock */
+    RCU_TIMER8    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 16U),                 /*!< TIMER8 clock */
+    RCU_TIMER9    = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 17U),                 /*!< TIMER9 clock */
+    RCU_TIMER10   = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 18U),                 /*!< TIMER10 clock */
+    RCU_SPI4      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 20U),                 /*!< SPI4 clock */
+    RCU_SPI5      = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 21U),                 /*!< SPI5 clock */
+    RCU_TLI       = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 26U),                 /*!< TLI clock */
+    /* APB2 additional peripherals */
+    RCU_CTC       = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 27U),             /*!< CTC clock */
+    RCU_IREF      = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 31U),             /*!< IREF clock */
+}rcu_periph_enum;
+
+/* peripheral clock enable when sleep mode*/
+typedef enum
+{
+    /* AHB1 peripherals */
+    RCU_GPIOA_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 0U),            /*!< GPIOA clock */
+    RCU_GPIOB_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 1U),            /*!< GPIOB clock */
+    RCU_GPIOC_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 2U),            /*!< GPIOC clock */
+    RCU_GPIOD_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 3U),            /*!< GPIOD clock */
+    RCU_GPIOE_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 4U),            /*!< GPIOE clock */
+    RCU_GPIOF_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 5U),            /*!< GPIOF clock */
+    RCU_GPIOG_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 6U),            /*!< GPIOG clock */
+    RCU_GPIOH_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 7U),            /*!< GPIOH clock */
+    RCU_GPIOI_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 8U),            /*!< GPIOI clock */
+    RCU_CRC_SLP       = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 12U),           /*!< CRC clock */
+    RCU_FMC_SLP       = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 15U),           /*!< FMC clock */
+    RCU_SRAM0_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 16U),           /*!< SRAM0 clock */
+    RCU_SRAM1_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 17U),           /*!< SRAM1 clock */
+    RCU_BKPSRAM_SLP   = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 18U),           /*!< BKPSRAM clock */
+    RCU_SRAM2_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 19U),           /*!< SRAM2 clock */
+    RCU_DMA0_SLP      = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 21U),           /*!< DMA0 clock */
+    RCU_DMA1_SLP      = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 22U),           /*!< DMA1 clock */
+    RCU_IPA_SLP       = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 23U),           /*!< IPA clock */
+    RCU_ENET_SLP      = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 25U),           /*!< ENET clock */
+    RCU_ENETTX_SLP    = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 26U),           /*!< ENETTX clock */
+    RCU_ENETRX_SLP    = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 27U),           /*!< ENETRX clock */
+    RCU_ENETPTP_SLP   = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 28U),           /*!< ENETPTP clock */
+    RCU_USBHS_SLP     = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 29U),           /*!< USBHS clock */
+    RCU_USBHSULPI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 30U),           /*!< USBHSULPI clock */
+    /* AHB2 peripherals */
+    RCU_DCI_SLP       = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 0U),            /*!< DCI clock */
+    RCU_TRNG_SLP      = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 6U),            /*!< TRNG clock */
+    RCU_USBFS_SLP     = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 7U),            /*!< USBFS clock */
+    /* AHB3 peripherals */
+    RCU_EXMC_SLP      = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 0U),            /*!< EXMC clock */
+    /* APB1 peripherals */
+    RCU_TIMER1_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 0U),            /*!< TIMER1 clock */
+    RCU_TIMER2_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 1U),            /*!< TIMER2 clock */
+    RCU_TIMER3_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 2U),            /*!< TIMER3 clock */
+    RCU_TIMER4_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 3U),            /*!< TIMER4 clock */
+    RCU_TIMER5_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 4U),            /*!< TIMER5 clock */
+    RCU_TIMER6_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 5U),            /*!< TIMER6 clock */
+    RCU_TIMER11_SLP   = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 6U),            /*!< TIMER11 clock */
+    RCU_TIMER12_SLP   = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 7U),            /*!< TIMER12 clock */
+    RCU_TIMER13_SLP   = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 8U),            /*!< TIMER13 clock */   
+    RCU_WWDGT_SLP     = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 11U),           /*!< WWDGT clock */
+    RCU_SPI1_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 14U),           /*!< SPI1 clock */
+    RCU_SPI2_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 15U),           /*!< SPI2 clock */
+    RCU_USART1_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 17U),           /*!< USART1 clock */
+    RCU_USART2_SLP    = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 18U),           /*!< USART2 clock */
+    RCU_UART3_SLP     = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 19U),           /*!< UART3 clock */
+    RCU_UART4_SLP     = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 20U),           /*!< UART4 clock */
+    RCU_I2C0_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 21U),           /*!< I2C0 clock */
+    RCU_I2C1_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 22U),           /*!< I2C1 clock */
+    RCU_I2C2_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 23U),           /*!< I2C2 clock */   
+    RCU_CAN0_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 25U),           /*!< CAN0 clock */
+    RCU_CAN1_SLP      = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 26U),           /*!< CAN1 clock */
+    RCU_PMU_SLP       = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 28U),           /*!< PMU clock */
+    RCU_DAC_SLP       = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 29U),           /*!< DAC clock */
+    RCU_UART6_SLP     = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 30U),           /*!< UART6 clock */
+    RCU_UART7_SLP     = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 31U),           /*!< UART7 clock */
+    /* APB2 peripherals */
+    RCU_TIMER0_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 0U),            /*!< TIMER0 clock */
+    RCU_TIMER7_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 1U),            /*!< TIMER7 clock */
+    RCU_USART0_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 4U),            /*!< USART0 clock */
+    RCU_USART5_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 5U),            /*!< USART5 clock */
+    RCU_ADC0_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 8U),            /*!< ADC0 clock */
+    RCU_ADC1_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 9U),            /*!< ADC1 clock */
+    RCU_ADC2_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 10U),           /*!< ADC2 clock */
+    RCU_SDIO_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 11U),           /*!< SDIO clock */
+    RCU_SPI0_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 12U),           /*!< SPI0 clock */
+    RCU_SPI3_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 13U),           /*!< SPI3 clock */
+    RCU_SYSCFG_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 14U),           /*!< SYSCFG clock */
+    RCU_TIMER8_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 16U),           /*!< TIMER8 clock */
+    RCU_TIMER9_SLP    = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 17U),           /*!< TIMER9 clock */
+    RCU_TIMER10_SLP   = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 18U),           /*!< TIMER10 clock */
+    RCU_SPI4_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 20U),           /*!< SPI4 clock */
+    RCU_SPI5_SLP      = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 21U),           /*!< SPI5 clock */
+    RCU_TLI_SLP       = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 26U),           /*!< TLI clock */
+    /* APB1 additional peripherals */
+    RCU_CTC_SLP       = RCU_REGIDX_BIT(ADD_APB1SPEN_REG_OFFSET, 27U),       /*!< CTC clock */
+    RCU_IREF_SLP      = RCU_REGIDX_BIT(ADD_APB1SPEN_REG_OFFSET, 31U),       /*!< IREF clock */
+}rcu_periph_sleep_enum;
+
+/* peripherals reset */
+typedef enum
+{
+    /* AHB1 peripherals */
+    RCU_GPIOARST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 0U),              /*!< GPIOA clock reset */
+    RCU_GPIOBRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 1U),              /*!< GPIOB clock reset */
+    RCU_GPIOCRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 2U),              /*!< GPIOC clock reset */
+    RCU_GPIODRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 3U),              /*!< GPIOD clock reset */
+    RCU_GPIOERST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 4U),              /*!< GPIOE clock reset */
+    RCU_GPIOFRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 5U),              /*!< GPIOF clock reset */
+    RCU_GPIOGRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 6U),              /*!< GPIOG clock reset */
+    RCU_GPIOHRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 7U),              /*!< GPIOH clock reset */
+    RCU_GPIOIRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 8U),              /*!< GPIOI clock reset */
+    RCU_CRCRST       = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 12U),             /*!< CRC clock reset */
+    RCU_DMA0RST      = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 21U),             /*!< DMA0 clock reset */
+    RCU_DMA1RST      = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 22U),             /*!< DMA1 clock reset */
+    RCU_IPAENRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 23U),             /*!< IPA clock reset */
+    RCU_ENETRST      = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 25U),             /*!< ENET clock reset */   
+    RCU_USBHSRST     = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 29U),             /*!< USBHS clock reset */
+    /* AHB2 peripherals */
+    RCU_DCIRST       = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 0U),              /*!< DCI clock reset */
+    RCU_TRNGRST      = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 6U),              /*!< TRNG clock reset */
+    RCU_USBFSRST     = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 7U),              /*!< USBFS clock reset */
+    /* AHB3 peripherals */
+    RCU_EXMCRST      = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 0U),              /*!< EXMC clock reset */
+    /* APB1 peripherals */
+    RCU_TIMER1RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 0U),              /*!< TIMER1 clock reset */
+    RCU_TIMER2RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 1U),              /*!< TIMER2 clock reset */
+    RCU_TIMER3RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 2U),              /*!< TIMER3 clock reset */
+    RCU_TIMER4RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 3U),              /*!< TIMER4 clock reset */
+    RCU_TIMER5RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 4U),              /*!< TIMER5 clock reset */
+    RCU_TIMER6RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 5U),              /*!< TIMER6 clock reset */
+    RCU_TIMER11RST   = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 6U),              /*!< TIMER11 clock reset */
+    RCU_TIMER12RST   = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 7U),              /*!< TIMER12 clock reset */
+    RCU_TIMER13RST   = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 8U),              /*!< TIMER13 clock reset */   
+    RCU_WWDGTRST     = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 11U),             /*!< WWDGT clock reset */
+    RCU_SPI1RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 14U),             /*!< SPI1 clock reset */
+    RCU_SPI2RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 15U),             /*!< SPI2 clock reset */
+    RCU_USART1RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 17U),             /*!< USART1 clock reset */
+    RCU_USART2RST    = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 18U),             /*!< USART2 clock reset */
+    RCU_UART3RST     = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 19U),             /*!< UART3 clock reset */
+    RCU_UART4RST     = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 20U),             /*!< UART4 clock reset */
+    RCU_I2C0RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 21U),             /*!< I2C0 clock reset */
+    RCU_I2C1RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 22U),             /*!< I2C1 clock reset */
+    RCU_I2C2RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 23U),             /*!< I2C2 clock reset */   
+    RCU_CAN0RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 25U),             /*!< CAN0 clock reset */
+    RCU_CAN1RST      = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 26U),             /*!< CAN1 clock reset */
+    RCU_PMURST       = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 28U),             /*!< PMU clock reset */
+    RCU_DACRST       = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 29U),             /*!< DAC clock reset */
+    RCU_UART6RST     = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 30U),             /*!< UART6 clock reset */
+    RCU_UART7RST     = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 31U),             /*!< UART7 clock reset */
+    /* APB2 peripherals */
+    RCU_TIMER0RST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 0U),              /*!< TIMER0 clock reset */
+    RCU_TIMER7RST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 1U),              /*!< TIMER7 clock reset */
+    RCU_USART0RST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 4U),              /*!< USART0 clock reset */
+    RCU_USART5RST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 5U),              /*!< USART5 clock reset */
+    RCU_ADCRST       = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 8U),              /*!< ADCs all clock reset */
+    RCU_SDIORST      = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 11U),             /*!< SDIO clock reset */
+    RCU_SPI0RST      = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 12U),             /*!< SPI0 clock reset */
+    RCU_SPI3RST      = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 13U),             /*!< SPI3 clock reset */
+    RCU_SYSCFGRST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 14U),             /*!< SYSCFG clock reset */
+    RCU_TIMER8RST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 16U),             /*!< TIMER8 clock reset */
+    RCU_TIMER9RST    = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 17U),             /*!< TIMER9 clock reset */
+    RCU_TIMER10RST   = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 18U),             /*!< TIMER10 clock reset */
+    RCU_SPI4RST      = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 20U),             /*!< SPI4 clock reset */
+    RCU_SPI5RST      = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 21U),             /*!< SPI5 clock reset */
+    RCU_TLIRST       = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 26U),             /*!< TLI clock reset */
+    /* APB2 additional peripherals */
+    RCU_CTCRST       = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 27U),         /*!< CTC clock reset */
+    RCU_IREFRST      = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 31U)          /*!< IREF clock reset */
+}rcu_periph_reset_enum;
+
+/* clock stabilization and peripheral reset flags */
+typedef enum
+{
+    /* clock stabilization flags */
+    RCU_FLAG_IRC16MSTB     = RCU_REGIDX_BIT(CTL_REG_OFFSET, 1U),            /*!< IRC16M stabilization flags */
+    RCU_FLAG_HXTALSTB      = RCU_REGIDX_BIT(CTL_REG_OFFSET, 17U),           /*!< HXTAL stabilization flags */
+    RCU_FLAG_PLLSTB        = RCU_REGIDX_BIT(CTL_REG_OFFSET, 25U),           /*!< PLL stabilization flags */
+    RCU_FLAG_PLLI2SSTB     = RCU_REGIDX_BIT(CTL_REG_OFFSET, 27U),           /*!< PLLI2S stabilization flags */
+    RCU_FLAG_PLLSAISTB     = RCU_REGIDX_BIT(CTL_REG_OFFSET, 29U),           /*!< PLLSAI stabilization flags */
+    RCU_FLAG_LXTALSTB      = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 1U),          /*!< LXTAL stabilization flags */
+    RCU_FLAG_IRC32KSTB     = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U),         /*!< IRC32K stabilization flags */
+    RCU_FLAG_IRC48MSTB     = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 17U),        /*!< IRC48M stabilization flags */
+    /* reset source flags */
+    RCU_FLAG_BORRST        = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 25U),        /*!< BOR reset flags */
+    RCU_FLAG_EPRST         = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 26U),        /*!< External PIN reset flags */
+    RCU_FLAG_PORRST        = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 27U),        /*!< power reset flags */
+    RCU_FLAG_SWRST         = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 28U),        /*!< Software reset flags */
+    RCU_FLAG_FWDGTRST      = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 29U),        /*!< FWDGT reset flags */
+    RCU_FLAG_WWDGTRST      = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 30U),        /*!< WWDGT reset flags */
+    RCU_FLAG_LPRST         = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 31U),        /*!< Low-power reset flags */
+}rcu_flag_enum;
+
+/* clock stabilization and ckm interrupt flags */
+typedef enum
+{
+    RCU_INT_FLAG_IRC32KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 0U),            /*!< IRC32K stabilization interrupt flag */
+    RCU_INT_FLAG_LXTALSTB  = RCU_REGIDX_BIT(INT_REG_OFFSET, 1U),            /*!< LXTAL stabilization interrupt flag */
+    RCU_INT_FLAG_IRC8MSTB  = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U),            /*!< IRC8M stabilization interrupt flag */
+    RCU_INT_FLAG_HXTALSTB  = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U),            /*!< HXTAL stabilization interrupt flag */
+    RCU_INT_FLAG_PLLSTB    = RCU_REGIDX_BIT(INT_REG_OFFSET, 4U),            /*!< PLL stabilization interrupt flag */
+    RCU_INT_FLAG_PLLI2SSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U),            /*!< PLLI2S stabilization interrupt flag */
+    RCU_INT_FLAG_PLLSAISTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U),            /*!< PLLSAI stabilization interrupt flag */
+    RCU_INT_FLAG_CKM       = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U),            /*!< HXTAL clock stuck interrupt flag */
+    RCU_INT_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 6U),         /*!< IRC48M stabilization interrupt flag */
+}rcu_int_flag_enum;
+
+/* clock stabilization and stuck interrupt flags clear */
+typedef enum
+{
+    RCU_INT_FLAG_IRC32KSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 16U),       /*!< IRC32K stabilization interrupt flags clear */
+    RCU_INT_FLAG_LXTALSTB_CLR  = RCU_REGIDX_BIT(INT_REG_OFFSET, 17U),       /*!< LXTAL stabilization interrupt flags clear */
+    RCU_INT_FLAG_IRC16MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U),       /*!< IRC16M stabilization interrupt flags clear */
+    RCU_INT_FLAG_HXTALSTB_CLR  = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U),       /*!< HXTAL stabilization interrupt flags clear */
+    RCU_INT_FLAG_PLLSTB_CLR    = RCU_REGIDX_BIT(INT_REG_OFFSET, 20U),       /*!< PLL stabilization interrupt flags clear */
+    RCU_INT_FLAG_PLLI2SSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U),       /*!< PLLI2S stabilization interrupt flags clear */
+    RCU_INT_FLAG_PLLSAISTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U),       /*!< PLLSAI stabilization interrupt flags clear */
+    RCU_INT_FLAG_CKM_CLR       = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U),       /*!< CKM interrupt flags clear */
+    RCU_INT_FLAG_IRC48MSTB_CLR = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 22U),    /*!< internal 48 MHz RC oscillator stabilization interrupt clear */
+}rcu_int_flag_clear_enum;
+
+/* clock stabilization interrupt enable or disable */
+typedef enum
+{
+    RCU_INT_IRC32KSTB       = RCU_REGIDX_BIT(INT_REG_OFFSET, 8U),           /*!< IRC32K stabilization interrupt */
+    RCU_INT_LXTALSTB        = RCU_REGIDX_BIT(INT_REG_OFFSET, 9U),           /*!< LXTAL stabilization interrupt */
+    RCU_INT_IRC16MSTB       = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U),          /*!< IRC8M stabilization interrupt */
+    RCU_INT_HXTALSTB        = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U),          /*!< HXTAL stabilization interrupt */
+    RCU_INT_PLLSTB          = RCU_REGIDX_BIT(INT_REG_OFFSET, 12U),          /*!< PLL stabilization interrupt */
+    RCU_INT_PLLI2SSTB       = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U),          /*!< PLLI2S stabilization interrupt */
+    RCU_INT_PLLSAISTB       = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U),          /*!< PLLSAI stabilization interrupt */
+    RCU_INT_IRC48MSTB       = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 14U),       /*!< internal 48 MHz RC oscillator stabilization interrupt */
+}rcu_int_enum;
+
+/* oscillator types */
+typedef enum
+{
+    RCU_HXTAL      = RCU_REGIDX_BIT(CTL_REG_OFFSET, 16U),                   /*!< HXTAL */
+    RCU_LXTAL      = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 0U),                  /*!< LXTAL */
+    RCU_IRC16M     = RCU_REGIDX_BIT(CTL_REG_OFFSET, 0U),                    /*!< IRC16M */
+    RCU_IRC48M     = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 16U),                /*!< IRC48M */
+    RCU_IRC32K     = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U),                 /*!< IRC32K */
+    RCU_PLL_CK     = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U),                   /*!< PLL */
+    RCU_PLLI2S_CK  = RCU_REGIDX_BIT(CTL_REG_OFFSET, 26U),                   /*!< PLLI2S */
+    RCU_PLLSAI_CK  = RCU_REGIDX_BIT(CTL_REG_OFFSET, 28U),                   /*!< PLLSAI */
+}rcu_osci_type_enum;
+
+/* rcu clock frequency */
+typedef enum
+{
+    CK_SYS      = 0,                                                        /*!< system clock */
+    CK_AHB,                                                                 /*!< AHB clock */
+    CK_APB1,                                                                /*!< APB1 clock */
+    CK_APB2,                                                                /*!< APB2 clock */
+}rcu_clock_freq_enum;
+
+/* RCU_CFG0 register bit define */
+/* system clock source select */
+#define CFG0_SCS(regval)                (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define RCU_CKSYSSRC_IRC16M             CFG0_SCS(0)                        /*!< system clock source select IRC16M */
+#define RCU_CKSYSSRC_HXTAL              CFG0_SCS(1)                        /*!< system clock source select HXTAL */
+#define RCU_CKSYSSRC_PLLP               CFG0_SCS(2)                        /*!< system clock source select PLLP */
+
+/* system clock source select status */
+#define CFG0_SCSS(regval)               (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define RCU_SCSS_IRC16M                 CFG0_SCSS(0)                       /*!< system clock source select IRC16M */
+#define RCU_SCSS_HXTAL                  CFG0_SCSS(1)                       /*!< system clock source select HXTAL */
+#define RCU_SCSS_PLLP                   CFG0_SCSS(2)                       /*!< system clock source select PLLP */
+
+/* AHB prescaler selection */
+#define CFG0_AHBPSC(regval)             (BITS(4,7) & ((uint32_t)(regval) << 4))
+#define RCU_AHB_CKSYS_DIV1              CFG0_AHBPSC(0)                     /*!< AHB prescaler select CK_SYS */
+#define RCU_AHB_CKSYS_DIV2              CFG0_AHBPSC(8)                     /*!< AHB prescaler select CK_SYS/2 */
+#define RCU_AHB_CKSYS_DIV4              CFG0_AHBPSC(9)                     /*!< AHB prescaler select CK_SYS/4 */
+#define RCU_AHB_CKSYS_DIV8              CFG0_AHBPSC(10)                    /*!< AHB prescaler select CK_SYS/8 */
+#define RCU_AHB_CKSYS_DIV16             CFG0_AHBPSC(11)                    /*!< AHB prescaler select CK_SYS/16 */
+#define RCU_AHB_CKSYS_DIV64             CFG0_AHBPSC(12)                    /*!< AHB prescaler select CK_SYS/64 */
+#define RCU_AHB_CKSYS_DIV128            CFG0_AHBPSC(13)                    /*!< AHB prescaler select CK_SYS/128 */
+#define RCU_AHB_CKSYS_DIV256            CFG0_AHBPSC(14)                    /*!< AHB prescaler select CK_SYS/256 */
+#define RCU_AHB_CKSYS_DIV512            CFG0_AHBPSC(15)                    /*!< AHB prescaler select CK_SYS/512 */
+
+/* APB1 prescaler selection */
+#define CFG0_APB1PSC(regval)            (BITS(10,12) & ((uint32_t)(regval) << 10))
+#define RCU_APB1_CKAHB_DIV1             CFG0_APB1PSC(0)                    /*!< APB1 prescaler select CK_AHB */
+#define RCU_APB1_CKAHB_DIV2             CFG0_APB1PSC(4)                    /*!< APB1 prescaler select CK_AHB/2 */
+#define RCU_APB1_CKAHB_DIV4             CFG0_APB1PSC(5)                    /*!< APB1 prescaler select CK_AHB/4 */
+#define RCU_APB1_CKAHB_DIV8             CFG0_APB1PSC(6)                    /*!< APB1 prescaler select CK_AHB/8 */
+#define RCU_APB1_CKAHB_DIV16            CFG0_APB1PSC(7)                    /*!< APB1 prescaler select CK_AHB/16 */
+
+/* APB2 prescaler selection */
+#define CFG0_APB2PSC(regval)            (BITS(13,15) & ((uint32_t)(regval) << 13))
+#define RCU_APB2_CKAHB_DIV1             CFG0_APB2PSC(0)                    /*!< APB2 prescaler select CK_AHB */
+#define RCU_APB2_CKAHB_DIV2             CFG0_APB2PSC(4)                    /*!< APB2 prescaler select CK_AHB/2 */
+#define RCU_APB2_CKAHB_DIV4             CFG0_APB2PSC(5)                    /*!< APB2 prescaler select CK_AHB/4 */
+#define RCU_APB2_CKAHB_DIV8             CFG0_APB2PSC(6)                    /*!< APB2 prescaler select CK_AHB/8 */
+#define RCU_APB2_CKAHB_DIV16            CFG0_APB2PSC(7)                    /*!< APB2 prescaler select CK_AHB/16 */
+
+/* RTC clock divider factor from HXTAL clock */
+#define CFG0_RTCDIV(regval)             (BITS(16,20) & ((uint32_t)(regval) << 16))
+#define RCU_RTC_HXTAL_NONE              CFG0_RTCDIV(0)                     /*!< no clock for RTC */
+#define RCU_RTC_HXTAL_DIV2              CFG0_RTCDIV(2)                     /*!< RTCDIV clock select CK_HXTAL/2 */
+#define RCU_RTC_HXTAL_DIV3              CFG0_RTCDIV(3)                     /*!< RTCDIV clock select CK_HXTAL/3 */
+#define RCU_RTC_HXTAL_DIV4              CFG0_RTCDIV(4)                     /*!< RTCDIV clock select CK_HXTAL/4 */
+#define RCU_RTC_HXTAL_DIV5              CFG0_RTCDIV(5)                     /*!< RTCDIV clock select CK_HXTAL/5 */
+#define RCU_RTC_HXTAL_DIV6              CFG0_RTCDIV(6)                     /*!< RTCDIV clock select CK_HXTAL/6 */
+#define RCU_RTC_HXTAL_DIV7              CFG0_RTCDIV(7)                     /*!< RTCDIV clock select CK_HXTAL/7 */
+#define RCU_RTC_HXTAL_DIV8              CFG0_RTCDIV(8)                     /*!< RTCDIV clock select CK_HXTAL/8 */
+#define RCU_RTC_HXTAL_DIV9              CFG0_RTCDIV(9)                     /*!< RTCDIV clock select CK_HXTAL/9 */
+#define RCU_RTC_HXTAL_DIV10             CFG0_RTCDIV(10)                    /*!< RTCDIV clock select CK_HXTAL/10 */
+#define RCU_RTC_HXTAL_DIV11             CFG0_RTCDIV(11)                    /*!< RTCDIV clock select CK_HXTAL/11 */
+#define RCU_RTC_HXTAL_DIV12             CFG0_RTCDIV(12)                    /*!< RTCDIV clock select CK_HXTAL/12 */
+#define RCU_RTC_HXTAL_DIV13             CFG0_RTCDIV(13)                    /*!< RTCDIV clock select CK_HXTAL/13 */
+#define RCU_RTC_HXTAL_DIV14             CFG0_RTCDIV(14)                    /*!< RTCDIV clock select CK_HXTAL/14 */
+#define RCU_RTC_HXTAL_DIV15             CFG0_RTCDIV(15)                    /*!< RTCDIV clock select CK_HXTAL/15 */
+#define RCU_RTC_HXTAL_DIV16             CFG0_RTCDIV(16)                    /*!< RTCDIV clock select CK_HXTAL/16 */
+#define RCU_RTC_HXTAL_DIV17             CFG0_RTCDIV(17)                    /*!< RTCDIV clock select CK_HXTAL/17 */
+#define RCU_RTC_HXTAL_DIV18             CFG0_RTCDIV(18)                    /*!< RTCDIV clock select CK_HXTAL/18 */
+#define RCU_RTC_HXTAL_DIV19             CFG0_RTCDIV(19)                    /*!< RTCDIV clock select CK_HXTAL/19 */
+#define RCU_RTC_HXTAL_DIV20             CFG0_RTCDIV(20)                    /*!< RTCDIV clock select CK_HXTAL/20 */
+#define RCU_RTC_HXTAL_DIV21             CFG0_RTCDIV(21)                    /*!< RTCDIV clock select CK_HXTAL/21 */
+#define RCU_RTC_HXTAL_DIV22             CFG0_RTCDIV(22)                    /*!< RTCDIV clock select CK_HXTAL/22 */
+#define RCU_RTC_HXTAL_DIV23             CFG0_RTCDIV(23)                    /*!< RTCDIV clock select CK_HXTAL/23 */
+#define RCU_RTC_HXTAL_DIV24             CFG0_RTCDIV(24)                    /*!< RTCDIV clock select CK_HXTAL/24 */
+#define RCU_RTC_HXTAL_DIV25             CFG0_RTCDIV(25)                    /*!< RTCDIV clock select CK_HXTAL/25 */
+#define RCU_RTC_HXTAL_DIV26             CFG0_RTCDIV(26)                    /*!< RTCDIV clock select CK_HXTAL/26 */
+#define RCU_RTC_HXTAL_DIV27             CFG0_RTCDIV(27)                    /*!< RTCDIV clock select CK_HXTAL/27 */
+#define RCU_RTC_HXTAL_DIV28             CFG0_RTCDIV(28)                    /*!< RTCDIV clock select CK_HXTAL/28 */
+#define RCU_RTC_HXTAL_DIV29             CFG0_RTCDIV(29)                    /*!< RTCDIV clock select CK_HXTAL/29 */
+#define RCU_RTC_HXTAL_DIV30             CFG0_RTCDIV(30)                    /*!< RTCDIV clock select CK_HXTAL/30 */
+#define RCU_RTC_HXTAL_DIV31             CFG0_RTCDIV(31)                    /*!< RTCDIV clock select CK_HXTAL/31 */
+
+/* CKOUT0 Clock source selection */
+#define CFG0_CKOUT0SEL(regval)          (BITS(21,22) & ((uint32_t)(regval) << 21))
+#define RCU_CKOUT0SRC_IRC16M            CFG0_CKOUT0SEL(0)                  /*!< internal 16M RC oscillator clock selected */
+#define RCU_CKOUT0SRC_LXTAL             CFG0_CKOUT0SEL(1)                  /*!< low speed crystal oscillator clock (LXTAL) selected */
+#define RCU_CKOUT0SRC_HXTAL             CFG0_CKOUT0SEL(2)                  /*!< high speed crystal oscillator clock (HXTAL) selected */
+#define RCU_CKOUT0SRC_PLLP              CFG0_CKOUT0SEL(3)                  /*!< CK_PLLP clock selected */
+
+/* I2S Clock source selection */
+#define RCU_I2SSRC_PLLI2S               ((uint32_t)0x00000000U)             /*!< PLLI2S output clock selected as I2S source clock */
+#define RCU_I2SSRC_I2S_CKIN             RCU_CFG0_I2SSEL                    /*!< external I2S_CKIN pin selected as I2S source clock */
+
+/* The CK_OUT0 divider */
+#define CFG0_CKOUT0DIV(regval)          (BITS(24,26) & ((uint32_t)(regval) << 24))
+#define RCU_CKOUT0_DIV1                 CFG0_CKOUT0DIV(0)                  /*!< CK_OUT0 is divided by 1 */
+#define RCU_CKOUT0_DIV2                 CFG0_CKOUT0DIV(4)                  /*!< CK_OUT0 is divided by 2 */
+#define RCU_CKOUT0_DIV3                 CFG0_CKOUT0DIV(5)                  /*!< CK_OUT0 is divided by 3 */
+#define RCU_CKOUT0_DIV4                 CFG0_CKOUT0DIV(6)                  /*!< CK_OUT0 is divided by 4 */
+#define RCU_CKOUT0_DIV5                 CFG0_CKOUT0DIV(7)                  /*!< CK_OUT0 is divided by 5 */
+
+/* The CK_OUT1 divider */
+#define CFG0_CKOUT1DIV(regval)          (BITS(27,29) & ((uint32_t)(regval) << 27))
+#define RCU_CKOUT1_DIV1                 CFG0_CKOUT1DIV(0)                  /*!< CK_OUT1 is divided by 1 */
+#define RCU_CKOUT1_DIV2                 CFG0_CKOUT1DIV(4)                  /*!< CK_OUT1 is divided by 2 */
+#define RCU_CKOUT1_DIV3                 CFG0_CKOUT1DIV(5)                  /*!< CK_OUT1 is divided by 3 */
+#define RCU_CKOUT1_DIV4                 CFG0_CKOUT1DIV(6)                  /*!< CK_OUT1 is divided by 4 */
+#define RCU_CKOUT1_DIV5                 CFG0_CKOUT1DIV(7)                  /*!< CK_OUT1 is divided by 5 */
+
+/* CKOUT1 Clock source selection */
+#define CFG0_CKOUT1SEL(regval)          (BITS(30,31) & ((uint32_t)(regval) << 30))
+#define RCU_CKOUT1SRC_SYSTEMCLOCK       CFG0_CKOUT1SEL(0)                  /*!< system clock selected */
+#define RCU_CKOUT1SRC_PLLI2SR           CFG0_CKOUT1SEL(1)                  /*!< low speed crystal oscillator clock (LXTAL) selected */
+#define RCU_CKOUT1SRC_HXTAL             CFG0_CKOUT1SEL(2)                  /*!< high speed crystal oscillator clock (HXTAL) selected */
+#define RCU_CKOUT1SRC_PLLP              CFG0_CKOUT1SEL(3)                  /*!< CK_PLLP clock selected */
+
+/* RCU_CFG1 register bit define */
+/* the divider factor from PLLI2SQ clock */
+#define CFG1_PLLI2SQDIV(regval)         (BITS(0,4) & ((uint32_t)(regval) << 0))
+#define RCU_PLLI2SQ_DIV1                CFG1_PLLI2SQDIV(0)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/1 */
+#define RCU_PLLI2SQ_DIV2                CFG1_PLLI2SQDIV(1)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/2 */
+#define RCU_PLLI2SQ_DIV3                CFG1_PLLI2SQDIV(2)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/3 */
+#define RCU_PLLI2SQ_DIV4                CFG1_PLLI2SQDIV(3)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/4 */
+#define RCU_PLLI2SQ_DIV5                CFG1_PLLI2SQDIV(4)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/5 */
+#define RCU_PLLI2SQ_DIV6                CFG1_PLLI2SQDIV(5)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/6 */
+#define RCU_PLLI2SQ_DIV7                CFG1_PLLI2SQDIV(6)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/7 */
+#define RCU_PLLI2SQ_DIV8                CFG1_PLLI2SQDIV(7)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/8 */
+#define RCU_PLLI2SQ_DIV9                CFG1_PLLI2SQDIV(8)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/9 */
+#define RCU_PLLI2SQ_DIV10               CFG1_PLLI2SQDIV(9)                 /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/10 */
+#define RCU_PLLI2SQ_DIV11               CFG1_PLLI2SQDIV(10)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/11 */
+#define RCU_PLLI2SQ_DIV12               CFG1_PLLI2SQDIV(11)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/12 */
+#define RCU_PLLI2SQ_DIV13               CFG1_PLLI2SQDIV(12)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/13 */
+#define RCU_PLLI2SQ_DIV14               CFG1_PLLI2SQDIV(13)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/14 */
+#define RCU_PLLI2SQ_DIV15               CFG1_PLLI2SQDIV(14)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/15 */
+#define RCU_PLLI2SQ_DIV16               CFG1_PLLI2SQDIV(15)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/16 */
+#define RCU_PLLI2SQ_DIV17               CFG1_PLLI2SQDIV(16)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/17 */
+#define RCU_PLLI2SQ_DIV18               CFG1_PLLI2SQDIV(17)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/18 */
+#define RCU_PLLI2SQ_DIV19               CFG1_PLLI2SQDIV(18)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/19 */
+#define RCU_PLLI2SQ_DIV20               CFG1_PLLI2SQDIV(19)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/20 */
+#define RCU_PLLI2SQ_DIV21               CFG1_PLLI2SQDIV(20)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/21 */
+#define RCU_PLLI2SQ_DIV22               CFG1_PLLI2SQDIV(21)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/22 */
+#define RCU_PLLI2SQ_DIV23               CFG1_PLLI2SQDIV(22)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/23 */
+#define RCU_PLLI2SQ_DIV24               CFG1_PLLI2SQDIV(23)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/24 */
+#define RCU_PLLI2SQ_DIV25               CFG1_PLLI2SQDIV(24)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/25 */
+#define RCU_PLLI2SQ_DIV26               CFG1_PLLI2SQDIV(25)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/26 */
+#define RCU_PLLI2SQ_DIV27               CFG1_PLLI2SQDIV(26)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/27 */
+#define RCU_PLLI2SQ_DIV28               CFG1_PLLI2SQDIV(27)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/28 */
+#define RCU_PLLI2SQ_DIV29               CFG1_PLLI2SQDIV(28)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/29 */
+#define RCU_PLLI2SQ_DIV30               CFG1_PLLI2SQDIV(29)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/30 */
+#define RCU_PLLI2SQ_DIV31               CFG1_PLLI2SQDIV(30)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/31 */
+#define RCU_PLLI2SQ_DIV32               CFG1_PLLI2SQDIV(31)                /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/32 */
+
+/* the divider factor from PLLSAIR clock */
+#define CFG1_PLLSAIRDIV(regval)         (BITS(16,17) & ((uint32_t)(regval) << 16))
+#define RCU_PLLSAIR_DIV2                CFG1_PLLSAIRDIV(0)                 /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/2 */
+#define RCU_PLLSAIR_DIV4                CFG1_PLLSAIRDIV(1)                 /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/4 */
+#define RCU_PLLSAIR_DIV8                CFG1_PLLSAIRDIV(2)                 /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/8 */
+#define RCU_PLLSAIR_DIV16               CFG1_PLLSAIRDIV(3)                 /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/16 */
+
+/* TIMER clock selection */
+#define RCU_TIMER_PSC_MUL2              ~RCU_CFG1_TIMERSEL                 /*!< if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) 
+                                                                                or 0b100(CK_APBx = CK_AHB/2), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB).
+                                                                                or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; 
+                                                                                TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2) */
+#define RCU_TIMER_PSC_MUL4              RCU_CFG1_TIMERSEL                  /*!< if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), 
+                                                                                0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). 
+                                                                                or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1;  
+                                                                                TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2) */
+
+/* RCU_PLLSSCTL register bit define */
+/* PLL spread spectrum modulation type select */
+#define RCU_SS_TYPE_CENTER              ((uint32_t)0x00000000U)            /*!< center type is selected */
+#define RCU_SS_TYPE_DOWN                RCU_PLLSSCTL_SS_TYPE               /*!< down type is selected */
+
+/* RCU_PLL register bit define */
+/* The PLL VCO source clock prescaler */
+#define RCU_PLLPSC_DIV_MIN              ((uint32_t)2U)                     /*!< PLLPSC_DIV min value */
+#define RCU_PLLPSC_DIV_MAX              ((uint32_t)63U)                    /*!< PLLPSC_DIV max value */
+
+/* The PLL VCO clock multi factor */
+#define RCU_PLLN_MUL_MIN                ((uint32_t)64U)                    /*!< PLLN_MUL min value */
+#define RCU_PLLN_MUL_MAX                ((uint32_t)500U)                   /*!< PLLN_MUL max value */
+#define RCU_SS_MODULATION_CENTER_INC    ((uint32_t)5U)                     /*!< minimum factor of PLLN in center mode */
+#define RCU_SS_MODULATION_DOWN_INC      ((uint32_t)7U)                     /*!< minimum factor of PLLN in down mode */
+
+/* The PLLP output frequency division factor from PLL VCO clock */
+#define RCU_PLLP_DIV_MIN                ((uint32_t)2U)                     /*!< PLLP_DIV min value */
+#define RCU_PLLP_DIV_MAX                ((uint32_t)8U)                     /*!< PLLP_DIV max value */
+                                         
+/* PLL Clock Source Selection  */
+#define RCU_PLLSRC_IRC16M               ((uint32_t)0x00000000U)            /*!< IRC16M clock selected as source clock of PLL, PLLSAI, PLLI2S */
+#define RCU_PLLSRC_HXTAL                RCU_PLL_PLLSEL                     /*!< HXTAL clock selected as source clock of PLL, PLLSAI, PLLI2S */
+
+/* The PLL Q output frequency division factor from PLL VCO clock */
+#define RCU_PLLQ_DIV_MIN                ((uint32_t)2U)                     /*!< PLLQ_DIV min value */
+#define RCU_PLLQ_DIV_MAX                ((uint32_t)15U)                    /*!< PLLQ_DIV max value */
+
+#define CHECK_PLL_PSC_VALID(val)        (((val) >= RCU_PLLPSC_DIV_MIN)&&((val) <= RCU_PLLPSC_DIV_MAX))            
+#define CHECK_PLL_N_VALID(val, inc)     (((val) >= (RCU_PLLN_MUL_MIN + (inc)))&&((val) <= RCU_PLLN_MUL_MAX))      
+#define CHECK_PLL_P_VALID(val)          (((val) == 2U) || ((val) == 4U) || ((val) == 6U) || ((val) == 8U))         
+#define CHECK_PLL_Q_VALID(val)          (((val) >= RCU_PLLQ_DIV_MIN)&&((val) <= RCU_PLLQ_DIV_MAX))                 
+
+/* RCU_BDCTL register bit define */
+/* LXTAL drive capability */
+#define RCU_LXTALDRI_LOWER_DRIVE        ((uint32_t)0x00000000)             /*!< LXTAL drive capability is selected lower */
+#define RCU_LXTALDRI_HIGHER_DRIVE       RCU_BDCTL_LXTALDRI                 /*!< LXTAL drive capability is selected higher */
+
+/* RTC clock entry selection */
+#define BDCTL_RTCSRC(regval)            (BITS(8,9) & ((uint32_t)(regval) << 8))
+#define RCU_RTCSRC_NONE                 BDCTL_RTCSRC(0)                    /*!< no clock selected */
+#define RCU_RTCSRC_LXTAL                BDCTL_RTCSRC(1)                    /*!< RTC source clock select LXTAL  */
+#define RCU_RTCSRC_IRC32K               BDCTL_RTCSRC(2)                    /*!< RTC source clock select IRC32K */
+#define RCU_RTCSRC_HXTAL_DIV_RTCDIV     BDCTL_RTCSRC(3)                    /*!< RTC source clock select HXTAL/RTCDIV */
+
+/* RCU_PLLI2S register bit define */
+/* The PLLI2S VCO clock multi factor */
+#define RCU_PLLI2SN_MUL_MIN             50U
+#define RCU_PLLI2SN_MUL_MAX             500U
+
+/* The PLLI2S Q output frequency division factor from PLLI2S VCO clock */
+#define RCU_PLLI2SQ_DIV_MIN             2U
+#define RCU_PLLI2SQ_DIV_MAX             15U
+
+/* The PLLI2S R output frequency division factor from PLLI2S VCO clock */
+#define RCU_PLLI2SR_DIV_MIN             2U
+#define RCU_PLLI2SR_DIV_MAX             7U
+
+/* RCU_PLLSAI register bit define */
+/* The PLLSAI VCO clock multi factor */
+#define RCU_PLLSAIN_MUL_MIN             50U
+#define RCU_PLLSAIN_MUL_MAX             500U
+
+/* The PLLSAI P output frequency division factor from PLLSAI VCO clock */
+#define RCU_PLLSAIP_DIV_MIN             2U
+#define RCU_PLLSAIP_DIV_MAX             8U
+
+/* The PLLSAI Q output frequency division factor from PLLSAI VCO clock */
+#define RCU_PLLSAIQ_DIV_MIN             2U
+#define RCU_PLLSAIQ_DIV_MAX             15U
+
+/* The PLLSAI R output frequency division factor from PLLSAI VCO clock */
+#define RCU_PLLSAIR_DIV_MIN             2U
+#define RCU_PLLSAIR_DIV_MAX             7U
+
+#define CHECK_PLLI2S_PSC_VALID(val)     (((val) >= RCU_PLLI2SPSC_DIV_MIN)&&((val) <= RCU_PLLI2SPSC_DIV_MAX))
+#define CHECK_PLLI2S_N_VALID(val)       (((val) >= RCU_PLLI2SN_MUL_MIN)&&((val) <= RCU_PLLI2SN_MUL_MAX))
+#define CHECK_PLLI2S_Q_VALID(val)       (((val) >= RCU_PLLI2SQ_DIV_MIN)&&((val) <= RCU_PLLI2SQ_DIV_MAX))
+#define CHECK_PLLI2S_R_VALID(val)       (((val) >= RCU_PLLI2SR_DIV_MIN)&&((val) <= RCU_PLLI2SR_DIV_MAX))
+
+#define CHECK_PLLSAI_N_VALID(val)       (((val) >= (RCU_PLLSAIN_MUL_MIN))&&((val) <= RCU_PLLSAIN_MUL_MAX))
+#define CHECK_PLLSAI_P_VALID(val)       (((val) == 2U) || ((val) == 4U) || ((val) == 6U) || ((val) == 8U))
+#define CHECK_PLLSAI_Q_VALID(val)       (((val) >= RCU_PLLSAIQ_DIV_MIN)&&((val) <= RCU_PLLSAIQ_DIV_MAX))
+#define CHECK_PLLSAI_R_VALID(val)       (((val) >= RCU_PLLSAIR_DIV_MIN)&&((val) <= RCU_PLLSAIR_DIV_MAX))
+
+/* RCU_ADDCTL register bit define */
+/* 48MHz clock selection */ 
+#define RCU_CK48MSRC_PLL48M             ((uint32_t)0x00000000U)            /*!< CK48M source clock select PLL48M */
+#define RCU_CK48MSRC_IRC48M             RCU_ADDCTL_CK48MSEL                /*!< CK48M source clock select IRC48M */
+
+/* PLL48M clock selection */
+#define RCU_PLL48MSRC_PLLQ              ((uint32_t)0x00000000U)            /*!< PLL48M source clock select PLLQ */
+#define RCU_PLL48MSRC_PLLSAIP           RCU_ADDCTL_PLL48MSEL               /*!< PLL48M source clock select PLLSAIP */
+
+/* Deep-sleep mode voltage */
+#define DSV_DSLPVS(regval)              (BITS(0,2) & ((uint32_t)(regval) << 0))
+#define RCU_DEEPSLEEP_V_1_2             DSV_DSLPVS(0)                      /*!< core voltage is 1.2V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_1_1             DSV_DSLPVS(1)                      /*!< core voltage is 1.1V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_1_0             DSV_DSLPVS(2)                      /*!< core voltage is 1.0V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_0_9             DSV_DSLPVS(3)                      /*!< core voltage is 0.9V in deep-sleep mode */
+
+
+/* function declarations */
+/* deinitialize the RCU */
+void rcu_deinit(void);
+/* enable the peripherals clock */
+void rcu_periph_clock_enable(rcu_periph_enum periph);
+/* disable the peripherals clock */
+void rcu_periph_clock_disable(rcu_periph_enum periph);
+/* enable the peripherals clock when sleep mode */
+void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph);
+/* disable the peripherals clock when sleep mode */
+void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph);
+/* reset the peripherals */
+void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset);
+/* disable reset the peripheral */
+void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset);
+/* reset the BKP */
+void rcu_bkp_reset_enable(void);
+/* disable the BKP reset */
+void rcu_bkp_reset_disable(void);
+
+/* configure the system clock source */
+void rcu_system_clock_source_config(uint32_t ck_sys);
+/* get the system clock source */
+uint32_t rcu_system_clock_source_get(void);
+/* configure the AHB prescaler selection */
+void rcu_ahb_clock_config(uint32_t ck_ahb);
+/* configure the APB1 prescaler selection */
+void rcu_apb1_clock_config(uint32_t ck_apb1);
+/* configure the APB2 prescaler selection */
+void rcu_apb2_clock_config(uint32_t ck_apb2);
+/* configure the CK_OUT0 clock source and divider */
+void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div);
+/* configure the CK_OUT1 clock source and divider */
+void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div);
+/* configure the PLL clock source selection and PLL multiply factor */
+ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uint32_t pll_p, uint32_t pll_q);
+/* configure the PLLI2S clock */
+ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_q, uint32_t plli2s_r);
+/* configure the PLLSAI clock */
+ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_q, uint32_t pllsai_r);
+/* configure the RTC clock source selection */
+void rcu_rtc_clock_config(uint32_t rtc_clock_source);
+/* configure the I2S clock source selection */
+void rcu_i2s_clock_config(uint32_t i2s_clock_source);
+/* configure the CK48M clock selection */
+void rcu_ck48m_clock_config(uint32_t ck48m_clock_source);
+/* configure the PLL48M clock selection */
+void rcu_pll48m_clock_config(uint32_t pll48m_clock_source);
+/* configure the TIMER clock prescaler selection */
+void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler);       
+/* configure the TLI clock division selection */
+void rcu_tli_clock_div_config(uint32_t pllsai_r_div);
+
+
+/* get the clock stabilization and periphral reset flags */
+FlagStatus rcu_flag_get(rcu_flag_enum flag);
+/* clear the reset flag */
+void rcu_all_reset_flag_clear(void);
+/* get the clock stabilization interrupt and ckm flags */
+FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag);
+/* clear the interrupt flags */
+void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear);
+/* enable the stabilization interrupt */
+void rcu_interrupt_enable(rcu_int_enum stab_int);
+/* disable the stabilization interrupt */
+void rcu_interrupt_disable(rcu_int_enum stab_int);
+
+/* configure the LXTAL drive capability */
+void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap);
+/* wait for oscillator stabilization flags is SET or oscillator startup is timeout */
+ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci);
+/* turn on the oscillator */
+void rcu_osci_on(rcu_osci_type_enum osci);
+/* turn off the oscillator */
+void rcu_osci_off(rcu_osci_type_enum osci);
+/* enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */
+void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci);
+/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */
+void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci);
+/* enable the HXTAL clock monitor */
+void rcu_hxtal_clock_monitor_enable(void);
+/* disable the HXTAL clock monitor */
+void rcu_hxtal_clock_monitor_disable(void);
+
+/* set the IRC16M adjust value */
+void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval);
+/* configure the spread spectrum modulation for the main PLL clock */
+void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt);
+/* enable the spread spectrum modulation for the main PLL clock */
+void rcu_spread_spectrum_enable(void);
+/* disable the spread spectrum modulation for the main PLL clock */
+void rcu_spread_spectrum_disable(void);          
+/* unlock the voltage key */
+void rcu_voltage_key_unlock(void);
+/* set the deep sleep mode voltage */
+void rcu_deepsleep_voltage_set(uint32_t dsvol);
+
+/* get the system clock, bus and peripheral clock frequency */
+uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock);
+
+#endif /* GD32F4XX_RCU_H */

+ 597 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h

@@ -0,0 +1,597 @@
+/*!
+    \file  gd32f4xx_rtc.h
+    \brief definitions for the RTC 
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_RTC_H
+#define GD32F4XX_RTC_H
+
+#include "gd32f4xx.h"
+
+/* RTC definitions */
+#define RTC                                RTC_BASE
+
+/* registers definitions */
+#define RTC_TIME                           REG32((RTC) + 0x00U)                 /*!< RTC time of day register */
+#define RTC_DATE                           REG32((RTC) + 0x04U)                 /*!< RTC date register */
+#define RTC_CTL                            REG32((RTC) + 0x08U)                 /*!< RTC control register */
+#define RTC_STAT                           REG32((RTC) + 0x0CU)                 /*!< RTC status register */
+#define RTC_PSC                            REG32((RTC) + 0x10U)                 /*!< RTC time prescaler register */
+#define RTC_WUT                            REG32((RTC) + 0x14U)                 /*!< RTC wakeup timer regiser */
+#define RTC_COSC                           REG32((RTC) + 0x18U)                 /*!< RTC coarse calibration register */
+#define RTC_ALRM0TD                        REG32((RTC) + 0x1CU)                 /*!< RTC alarm 0 time and date register */
+#define RTC_ALRM1TD                        REG32((RTC) + 0x20U)                 /*!< RTC alarm 1 time and date register */
+#define RTC_WPK                            REG32((RTC) + 0x24U)                 /*!< RTC write protection key register */
+#define RTC_SS                             REG32((RTC) + 0x28U)                 /*!< RTC sub second register */
+#define RTC_SHIFTCTL                       REG32((RTC) + 0x2CU)                 /*!< RTC shift function control register */
+#define RTC_TTS                            REG32((RTC) + 0x30U)                 /*!< RTC time of timestamp register */
+#define RTC_DTS                            REG32((RTC) + 0x34U)                 /*!< RTC date of timestamp register */
+#define RTC_SSTS                           REG32((RTC) + 0x38U)                 /*!< RTC sub second of timestamp register */
+#define RTC_HRFC                           REG32((RTC) + 0x3CU)                 /*!< RTC high resolution frequency compensation registor */
+#define RTC_TAMP                           REG32((RTC) + 0x40U)                 /*!< RTC tamper register */
+#define RTC_ALRM0SS                        REG32((RTC) + 0x44U)                 /*!< RTC alarm 0 sub second register */
+#define RTC_ALRM1SS                        REG32((RTC) + 0x48U)                 /*!< RTC alarm 1 sub second register */
+#define RTC_BKP0                           REG32((RTC) + 0x50U)                 /*!< RTC backup register */
+#define RTC_BKP1                           REG32((RTC) + 0x54U)                 /*!< RTC backup register */
+#define RTC_BKP2                           REG32((RTC) + 0x58U)                 /*!< RTC backup register */
+#define RTC_BKP3                           REG32((RTC) + 0x5CU)                 /*!< RTC backup register */
+#define RTC_BKP4                           REG32((RTC) + 0x60U)                 /*!< RTC backup register */
+#define RTC_BKP5                           REG32((RTC) + 0x64U)                 /*!< RTC backup register */
+#define RTC_BKP6                           REG32((RTC) + 0x68U)                 /*!< RTC backup register */
+#define RTC_BKP7                           REG32((RTC) + 0x6CU)                 /*!< RTC backup register */
+#define RTC_BKP8                           REG32((RTC) + 0x70U)                 /*!< RTC backup register */
+#define RTC_BKP9                           REG32((RTC) + 0x74U)                 /*!< RTC backup register */
+#define RTC_BKP10                          REG32((RTC) + 0x78U)                 /*!< RTC backup register */
+#define RTC_BKP11                          REG32((RTC) + 0x7CU)                 /*!< RTC backup register */
+#define RTC_BKP12                          REG32((RTC) + 0x80U)                 /*!< RTC backup register */
+#define RTC_BKP13                          REG32((RTC) + 0x84U)                 /*!< RTC backup register */
+#define RTC_BKP14                          REG32((RTC) + 0x88U)                 /*!< RTC backup register */
+#define RTC_BKP15                          REG32((RTC) + 0x8CU)                 /*!< RTC backup register */
+#define RTC_BKP16                          REG32((RTC) + 0x90U)                 /*!< RTC backup register */
+#define RTC_BKP17                          REG32((RTC) + 0x94U)                 /*!< RTC backup register */
+#define RTC_BKP18                          REG32((RTC) + 0x98U)                 /*!< RTC backup register */
+#define RTC_BKP19                          REG32((RTC) + 0x9CU)                 /*!< RTC backup register */
+
+/* bits definitions */
+/* RTC_TIME */
+#define RTC_TIME_SCU                       BITS(0,3)                            /*!< second units in BCD code */
+#define RTC_TIME_SCT                       BITS(4,6)                            /*!< second tens in BCD code */
+#define RTC_TIME_MNU                       BITS(8,11)                           /*!< minute units in BCD code */
+#define RTC_TIME_MNT                       BITS(12,14)                          /*!< minute tens in BCD code */
+#define RTC_TIME_HRU                       BITS(16,19)                          /*!< hour units in BCD code */
+#define RTC_TIME_HRT                       BITS(20,21)                          /*!< hour tens in BCD code */
+#define RTC_TIME_PM                        BIT(22)                              /*!< AM/PM notation */
+
+/* RTC_DATE */
+#define RTC_DATE_DAYU                      BITS(0,3)                            /*!< date units in BCD code */
+#define RTC_DATE_DAYT                      BITS(4,5)                            /*!< date tens in BCD code */
+#define RTC_DATE_MONU                      BITS(8,11)                           /*!< month units in BCD code */
+#define RTC_DATE_MONT                      BIT(12)                              /*!< month tens in BCD code */
+#define RTC_DATE_DOW                       BITS(13,15)                          /*!< day of week units */
+#define RTC_DATE_YRU                       BITS(16,19)                          /*!< year units in BCD code */
+#define RTC_DATE_YRT                       BITS(20,23)                          /*!< year tens in BCD code */
+
+/* RTC_CTL */
+#define RTC_CTL_WTCS                       BITS(0,2)                            /*!< auto wakeup timer clock selection */
+#define RTC_CTL_TSEG                       BIT(3)                               /*!< valid event edge of time-stamp */
+#define RTC_CTL_REFEN                      BIT(4)                               /*!< reference clock detection function enable */
+#define RTC_CTL_BPSHAD                     BIT(5)                               /*!< shadow registers bypass control */
+#define RTC_CTL_CS                         BIT(6)                               /*!< display format of clock system */
+#define RTC_CTL_CCEN                       BIT(7)                               /*!< coarse calibration function enable */
+#define RTC_CTL_ALRM0EN                    BIT(8)                               /*!< alarm0 function enable */
+#define RTC_CTL_ALRM1EN                    BIT(9)                               /*!< alarm1 function enable */
+#define RTC_CTL_WTEN                       BIT(10)                              /*!< auto wakeup timer function enable */
+#define RTC_CTL_TSEN                       BIT(11)                              /*!< time-stamp function enable */
+#define RTC_CTL_ALRM0IE                    BIT(12)                              /*!< RTC alarm0 interrupt enable */
+#define RTC_CTL_ALRM1IE                    BIT(13)                              /*!< RTC alarm1 interrupt enable */
+#define RTC_CTL_WTIE                       BIT(14)                              /*!< auto wakeup timer interrupt enable */
+#define RTC_CTL_TSIE                       BIT(15)                              /*!< time-stamp interrupt enable */
+#define RTC_CTL_A1H                        BIT(16)                              /*!< add 1 hour(summer time change) */
+#define RTC_CTL_S1H                        BIT(17)                              /*!< subtract 1 hour(winter time change) */
+#define RTC_CTL_DSM                        BIT(18)                              /*!< daylight saving mark */
+#define RTC_CTL_COS                        BIT(19)                              /*!< calibration output selection */
+#define RTC_CTL_OPOL                       BIT(20)                              /*!< output polarity */
+#define RTC_CTL_OS                         BITS(21,22)                          /*!< output selection */
+#define RTC_CTL_COEN                       BIT(23)                              /*!< calibration output enable */
+
+/* RTC_STAT */
+#define RTC_STAT_ALRM0WF                   BIT(0)                               /*!< alarm0 configuration can be write flag */
+#define RTC_STAT_ALRM1WF                   BIT(1)                               /*!< alarm1 configuration can be write flag */
+#define RTC_STAT_WTWF                      BIT(2)                               /*!< wakeup timer can be write flag */
+#define RTC_STAT_SOPF                      BIT(3)                               /*!< shift function operation pending flag */
+#define RTC_STAT_YCM                       BIT(4)                               /*!< year configuration mark status flag */
+#define RTC_STAT_RSYNF                     BIT(5)                               /*!< register synchronization flag */
+#define RTC_STAT_INITF                     BIT(6)                               /*!< initialization state flag */
+#define RTC_STAT_INITM                     BIT(7)                               /*!< enter initialization mode */
+#define RTC_STAT_ALRM0F                    BIT(8)                               /*!< alarm0 occurs flag */
+#define RTC_STAT_ALRM1F                    BIT(9)                               /*!< alarm1 occurs flag */
+#define RTC_STAT_WTF                       BIT(10)                              /*!< wakeup timer occurs flag */
+#define RTC_STAT_TSF                       BIT(11)                              /*!< time-stamp flag */
+#define RTC_STAT_TSOVRF                    BIT(12)                              /*!< time-stamp overflow flag */
+#define RTC_STAT_TP0F                      BIT(13)                              /*!< RTC tamper 0 detected flag */
+#define RTC_STAT_TP1F                      BIT(14)                              /*!< RTC tamper 1 detected flag */
+#define RTC_STAT_SCPF                      BIT(16)                              /*!< smooth calibration pending flag */
+
+/* RTC_PSC */
+#define RTC_PSC_FACTOR_S                   BITS(0,14)                           /*!< synchronous prescaler factor */
+#define RTC_PSC_FACTOR_A                   BITS(16,22)                          /*!< asynchronous prescaler factor */
+
+/* RTC_WUT */
+#define RTC_WUT_WTRV                       BITS(0,15)                           /*!< auto wakeup timer reloads value */
+
+/* RTC_COSC */
+#define RTC_COSC_COSS                      BITS(0,4)                            /*!< coarse calibration step */
+#define RTC_COSC_COSD                      BIT(7)                               /*!< coarse calibration direction */
+
+/* RTC_ALRMxTD */
+#define RTC_ALRMXTD_SCU                    BITS(0,3)                            /*!< second units in BCD code */
+#define RTC_ALRMXTD_SCT                    BITS(4,6)                            /*!< second tens in BCD code */
+#define RTC_ALRMXTD_MSKS                   BIT(7)                               /*!< alarm second mask bit */
+#define RTC_ALRMXTD_MNU                    BITS(8,11)                           /*!< minutes units in BCD code */
+#define RTC_ALRMXTD_MNT                    BITS(12,14)                          /*!< minutes tens in BCD code */
+#define RTC_ALRMXTD_MSKM                   BIT(15)                              /*!< alarm minutes mask bit */
+#define RTC_ALRMXTD_HRU                    BITS(16,19)                          /*!< hour units in BCD code */
+#define RTC_ALRMXTD_HRT                    BITS(20,21)                          /*!< hour units in BCD code */
+#define RTC_ALRMXTD_PM                     BIT(22)                              /*!< AM/PM flag */
+#define RTC_ALRMXTD_MSKH                   BIT(23)                              /*!< alarm hour mask bit */
+#define RTC_ALRMXTD_DAYU                   BITS(24,27)                          /*!< date units or week day in BCD code */
+#define RTC_ALRMXTD_DAYT                   BITS(28,29)                          /*!< date tens in BCD code */
+#define RTC_ALRMXTD_DOWS                   BIT(30)                              /*!< day of week  selection */
+#define RTC_ALRMXTD_MSKD                   BIT(31)                              /*!< alarm date mask bit */
+
+/* RTC_WPK */
+#define RTC_WPK_WPK                        BITS(0,7)                            /*!< key for write protection */
+
+/* RTC_SS */
+#define RTC_SS_SSC                         BITS(0,15)                           /*!< sub second value */
+
+/* RTC_SHIFTCTL */
+#define RTC_SHIFTCTL_SFS                   BITS(0,14)                           /*!< subtract a fraction of a second */
+#define RTC_SHIFTCTL_A1S                   BIT(31)                              /*!< one second add */
+
+/* RTC_TTS */
+#define RTC_TTS_SCU                        BITS(0,3)                            /*!< second units in BCD code */
+#define RTC_TTS_SCT                        BITS(4,6)                            /*!< second units in BCD code */
+#define RTC_TTS_MNU                        BITS(8,11)                           /*!< minute units in BCD code */
+#define RTC_TTS_MNT                        BITS(12,14)                          /*!< minute tens in BCD code */
+#define RTC_TTS_HRU                        BITS(16,19)                          /*!< hour units in BCD code */
+#define RTC_TTS_HRT                        BITS(20,21)                          /*!< hour tens in BCD code */
+#define RTC_TTS_PM                         BIT(22)                              /*!< AM/PM notation */
+
+/* RTC_DTS */
+#define RTC_DTS_DAYU                       BITS(0,3)                            /*!< date units in BCD code */
+#define RTC_DTS_DAYT                       BITS(4,5)                            /*!< date tens in BCD code */
+#define RTC_DTS_MONU                       BITS(8,11)                           /*!< month units in BCD code */
+#define RTC_DTS_MONT                       BIT(12)                              /*!< month tens in BCD code */
+#define RTC_DTS_DOW                        BITS(13,15)                          /*!< day of week units */
+
+/* RTC_SSTS */
+#define RTC_SSTS_SSC                       BITS(0,15)                           /*!< timestamp sub second units */
+
+/* RTC_HRFC */
+#define RTC_HRFC_CMSK                      BITS(0,8)                            /*!< calibration mask number */
+#define RTC_HRFC_CWND16                    BIT(13)                              /*!< calibration window select 16 seconds */
+#define RTC_HRFC_CWND8                     BIT(14)                              /*!< calibration window select 16 seconds */
+#define RTC_HRFC_FREQI                     BIT(15)                              /*!< increase RTC frequency by 488.5ppm */
+
+/* RTC_TAMP */
+#define RTC_TAMP_TP0EN                     BIT(0)                               /*!< tamper 0 detection enable */
+#define RTC_TAMP_TP0EG                     BIT(1)                               /*!< tamper 0 event trigger edge for RTC tamp 0 input */
+#define RTC_TAMP_TPIE                      BIT(2)                               /*!< tamper detection interrupt enable */
+#define RTC_TAMP_TP1EN                     BIT(3)                               /*!< tamper 1 detection enable */
+#define RTC_TAMP_TP1EG                     BIT(4)                               /*!< Tamper 1 event trigger edge for RTC tamp 1 input */
+#define RTC_TAMP_TPTS                      BIT(7)                               /*!< make tamper function used for timestamp function */
+#define RTC_TAMP_FREQ                      BITS(8,10)                           /*!< sample frequency of tamper event detection */
+#define RTC_TAMP_FLT                       BITS(11,12)                          /*!< RTC tamp x filter count setting */
+#define RTC_TAMP_PRCH                      BITS(13,14)                          /*!< precharge duration time of RTC tamp x */
+#define RTC_TAMP_DISPU                     BIT(15)                              /*!< RTC tamp x pull up disable bit */
+#define RTC_TAMP_TP0SEL                    BIT(16)                              /*!< Tamper 0 function input mapping selection */
+#define RTC_TAMP_TSSEL                     BIT(17)                              /*!< Timestamp input mapping selection */
+#define RTC_TAMP_AOT                       BIT(18)                              /*!< RTC_ALARM output Type */
+
+/* RTC_ALRM0SS */
+#define RTC_ALRM0SS_SSC                    BITS(0,14)                           /*!< alarm0 sub second value */
+#define RTC_ALRM0SS_MASKSSC                BITS(24,27)                          /*!< mask control bit of SS */
+
+/* RTC_ALRM1SS */
+#define RTC_ALRM1SS_SSC                    BITS(0,14)                           /*!< alarm1 sub second value */
+#define RTC_ALRM1SS_MASKSSC                BITS(24,27)                          /*!< mask control bit of SS */
+
+/* constants definitions */
+/* structure for initialization of the RTC */
+typedef struct
+{
+    uint8_t year;                                                               /*!< RTC year value: 0x0 - 0x99(BCD format) */
+    uint8_t month;                                                              /*!< RTC month value */
+    uint8_t date;                                                               /*!< RTC date value: 0x1 - 0x31(BCD format) */
+    uint8_t day_of_week;                                                        /*!< RTC weekday value */
+    uint8_t hour;                                                               /*!< RTC hour value */
+    uint8_t minute;                                                             /*!< RTC minute value: 0x0 - 0x59(BCD format) */
+    uint8_t second;                                                             /*!< RTC second value: 0x0 - 0x59(BCD format) */
+    uint16_t factor_asyn;                                                       /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */
+    uint16_t factor_syn;                                                        /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */
+    uint32_t am_pm;                                                             /*!< RTC AM/PM value */
+    uint32_t display_format;                                                    /*!< RTC time notation */
+}rtc_parameter_struct;
+
+/* structure for RTC alarm configuration */
+typedef struct
+{
+    uint32_t alarm_mask;                                                        /*!< RTC alarm mask */
+    uint32_t weekday_or_date;                                                   /*!< specify RTC alarm is on date or weekday */
+    uint8_t alarm_day;                                                          /*!< RTC alarm date or weekday value*/
+    uint8_t alarm_hour;                                                         /*!< RTC alarm hour value */
+    uint8_t alarm_minute;                                                       /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */
+    uint8_t alarm_second;                                                       /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */
+    uint32_t am_pm;                                                             /*!< RTC alarm AM/PM value */
+}rtc_alarm_struct;
+
+/* structure for RTC time-stamp configuration */
+typedef struct
+{
+    uint8_t timestamp_month;                                                    /*!< RTC time-stamp month value */
+    uint8_t timestamp_date;                                                     /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */
+    uint8_t timestamp_day;                                                      /*!< RTC time-stamp weekday value */
+    uint8_t timestamp_hour;                                                     /*!< RTC time-stamp hour value */
+    uint8_t timestamp_minute;                                                   /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */
+    uint8_t timestamp_second;                                                   /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */
+    uint32_t am_pm;                                                             /*!< RTC time-stamp AM/PM value */
+}rtc_timestamp_struct;
+
+/* structure for RTC tamper configuration */
+typedef struct
+{
+    uint32_t tamper_source;                                                     /*!< RTC tamper source */
+    uint32_t tamper_trigger;                                                    /*!< RTC tamper trigger */
+    uint32_t tamper_filter;                                                     /*!< RTC tamper consecutive samples needed during a voltage level detection */
+    uint32_t tamper_sample_frequency;                                           /*!< RTC tamper sampling frequency during a voltage level detection */
+    ControlStatus tamper_precharge_enable;                                      /*!< RTC tamper precharge feature during a voltage level detection */
+    uint32_t tamper_precharge_time;                                             /*!< RTC tamper precharge duration if precharge feature is enabled */
+    ControlStatus tamper_with_timestamp;                                        /*!< RTC tamper time-stamp feature */
+}rtc_tamper_struct; 
+
+/* time register value */
+#define TIME_SC(regval)                    (BITS(0,6) & ((uint32_t)(regval) << 0))    /*!< write value to RTC_TIME_SC bit field */
+#define GET_TIME_SC(regval)                GET_BITS((regval),0,6)                     /*!< get value of RTC_TIME_SC bit field */
+
+#define TIME_MN(regval)                    (BITS(8,14) & ((uint32_t)(regval) << 8))   /*!< write value to RTC_TIME_MN bit field */
+#define GET_TIME_MN(regval)                GET_BITS((regval),8,14)                    /*!< get value of RTC_TIME_MN bit field */
+
+#define TIME_HR(regval)                    (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TIME_HR bit field */
+#define GET_TIME_HR(regval)                GET_BITS((regval),16,21)                   /*!< get value of RTC_TIME_HR bit field */
+
+#define RTC_AM                             ((uint32_t)0x00000000U)                    /*!< AM format */
+#define RTC_PM                             RTC_TIME_PM                                /*!< PM format */
+
+/* date register value */
+#define DATE_DAY(regval)                   (BITS(0,5) & ((uint32_t)(regval) << 0))    /*!< write value to RTC_DATE_DAY bit field */
+#define GET_DATE_DAY(regval)               GET_BITS((regval),0,5)                     /*!< get value of RTC_DATE_DAY bit field */
+
+#define DATE_MON(regval)                   (BITS(8,12) & ((uint32_t)(regval) << 8))   /*!< write value to RTC_DATE_MON bit field */
+#define GET_DATE_MON(regval)               GET_BITS((regval),8,12)                    /*!< get value of RTC_DATE_MON bit field */
+#define RTC_JAN                            ((uint8_t)0x01U)                           /*!< janurary */
+#define RTC_FEB                            ((uint8_t)0x02U)                           /*!< february */
+#define RTC_MAR                            ((uint8_t)0x03U)                           /*!< march */
+#define RTC_APR                            ((uint8_t)0x04U)                           /*!< april */
+#define RTC_MAY                            ((uint8_t)0x05U)                           /*!< may */
+#define RTC_JUN                            ((uint8_t)0x06U)                           /*!< june */
+#define RTC_JUL                            ((uint8_t)0x07U)                           /*!< july */
+#define RTC_AUG                            ((uint8_t)0x08U)                           /*!< august */
+#define RTC_SEP                            ((uint8_t)0x09U)                           /*!< september */
+#define RTC_OCT                            ((uint8_t)0x10U)                           /*!< october */
+#define RTC_NOV                            ((uint8_t)0x11U)                           /*!< november */
+#define RTC_DEC                            ((uint8_t)0x12U)                           /*!< december */
+
+#define DATE_DOW(regval)                   (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DATE_DOW bit field */
+#define GET_DATE_DOW(regval)               GET_BITS((uint32_t)(regval),13,15)         /*!< get value of RTC_DATE_DOW bit field */
+#define RTC_MONDAY                         ((uint8_t)0x01)                            /*!< monday */
+#define RTC_TUESDAY                        ((uint8_t)0x02)                            /*!< tuesday */
+#define RTC_WEDSDAY                        ((uint8_t)0x03)                            /*!< wednesday */
+#define RTC_THURSDAY                       ((uint8_t)0x04)                            /*!< thursday */
+#define RTC_FRIDAY                         ((uint8_t)0x05)                            /*!< friday */
+#define RTC_SATURDAY                       ((uint8_t)0x06)                            /*!< saturday */
+#define RTC_SUNDAY                         ((uint8_t)0x07)                            /*!< sunday */
+
+#define DATE_YR(regval)                    (BITS(16,23) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_DATE_YR bit field */
+#define GET_DATE_YR(regval)                GET_BITS((regval),16,23)                   /*!< get value of RTC_DATE_YR bit field */
+
+/* ctl register value */
+#define CTL_OS(regval)                     (BITS(21,22) & ((uint32_t)(regval) << 21)) /*!< write value to RTC_CTL_OS bit field */
+#define RTC_OS_DISABLE                     CTL_OS(0)                                  /*!< disable output RTC_ALARM */
+#define RTC_OS_ALARM0                      CTL_OS(1)                                  /*!< enable alarm0 flag output */
+#define RTC_OS_ALARM1                      CTL_OS(2)                                  /*!< enable alarm1 flag output */
+#define RTC_OS_WAKEUP                      CTL_OS(3)                                  /*!< enable wakeup flag output */
+
+#define RTC_CALIBRATION_512HZ              RTC_CTL_COEN                               /*!< calibration output of 512Hz is enable */
+#define RTC_CALIBRATION_1HZ                (RTC_CTL_COEN | RTC_CTL_COS)               /*!< calibration output of 1Hz is enable */
+#define RTC_ALARM0_HIGH                    RTC_OS_ALARM0                              /*!< enable alarm0 flag output with high level */
+#define RTC_ALARM0_LOW                     (RTC_OS_ALARM0 | RTC_CTL_OPOL)             /*!< enable alarm0 flag output with low level*/
+#define RTC_ALARM1_HIGH                    RTC_OS_ALARM1                              /*!< enable alarm1 flag output with high level */
+#define RTC_ALARM1_LOW                     (RTC_OS_ALARM1 | RTC_CTL_OPOL)             /*!< enable alarm1 flag output with low level*/
+#define RTC_WAKEUP_HIGH                    RTC_OS_WAKEUP                              /*!< enable wakeup flag output with high level */
+#define RTC_WAKEUP_LOW                     (RTC_OS_WAKEUP | RTC_CTL_OPOL)             /*!< enable wakeup flag output with low level*/
+
+#define RTC_24HOUR                         ((uint32_t)0x00000000U)                    /*!< 24-hour format */
+#define RTC_12HOUR                         RTC_CTL_CS                                 /*!< 12-hour format */
+
+#define RTC_TIMESTAMP_RISING_EDGE          ((uint32_t)0x00000000U)                    /*!< rising edge is valid event edge for time-stamp event */
+#define RTC_TIMESTAMP_FALLING_EDGE         RTC_CTL_TSEG                               /*!< falling edge is valid event edge for time-stamp event */
+
+/* psc register value */
+#define PSC_FACTOR_S(regval)               (BITS(0,14) & ((uint32_t)(regval) << 0))   /*!< write value to RTC_PSC_FACTOR_S bit field */
+#define GET_PSC_FACTOR_S(regval)           GET_BITS((regval),0,14)                    /*!< get value of RTC_PSC_FACTOR_S bit field */
+
+#define PSC_FACTOR_A(regval)               (BITS(16,22) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_PSC_FACTOR_A bit field */
+#define GET_PSC_FACTOR_A(regval)           GET_BITS((regval),16,22)                   /*!< get value of RTC_PSC_FACTOR_A bit field */
+
+/* alrmtd register value */
+#define ALRMTD_SC(regval)                  (BITS(0,6) & ((uint32_t)(regval)<< 0))     /*!< write value to RTC_ALRMTD_SC bit field */
+#define GET_ALRMTD_SC(regval)              GET_BITS((regval),0,6)                     /*!< get value of RTC_ALRMTD_SC bit field */
+
+#define ALRMTD_MN(regval)                  (BITS(8,14) & ((uint32_t)(regval) << 8))   /*!< write value to RTC_ALRMTD_MN bit field */
+#define GET_ALRMTD_MN(regval)              GET_BITS((regval),8,14)                    /*!< get value of RTC_ALRMTD_MN bit field */
+
+#define ALRMTD_HR(regval)                  (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_ALRMTD_HR bit field */
+#define GET_ALRMTD_HR(regval)              GET_BITS((regval),16,21)                   /*!< get value of RTC_ALRMTD_HR bit field */
+
+#define ALRMTD_DAY(regval)                 (BITS(24,29) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMTD_DAY bit field */
+#define GET_ALRMTD_DAY(regval)             GET_BITS((regval),24,29)                   /*!< get value of RTC_ALRMTD_DAY bit field */
+
+#define RTC_ALARM_NONE_MASK                ((uint32_t)0x00000000U)                    /*!< alarm none mask */
+#define RTC_ALARM_DATE_MASK                RTC_ALRMXTD_MSKD                           /*!< alarm date mask */
+#define RTC_ALARM_HOUR_MASK                RTC_ALRMXTD_MSKH                           /*!< alarm hour mask */
+#define RTC_ALARM_MINUTE_MASK              RTC_ALRMXTD_MSKM                           /*!< alarm minute mask */
+#define RTC_ALARM_SECOND_MASK              RTC_ALRMXTD_MSKS                           /*!< alarm second mask */
+#define RTC_ALARM_ALL_MASK                 (RTC_ALRMXTD_MSKD|RTC_ALRMXTD_MSKH|RTC_ALRMXTD_MSKM|RTC_ALRMXTD_MSKS)   /*!< alarm all mask */
+
+#define RTC_ALARM_DATE_SELECTED            ((uint32_t)0x00000000U)                    /*!< alarm date format selected */
+#define RTC_ALARM_WEEKDAY_SELECTED         RTC_ALRMXTD_DOWS                           /*!< alarm weekday format selected */
+
+/* wpk register value */
+#define WPK_WPK(regval)                    (BITS(0,7) & ((uint32_t)(regval) << 0))    /*!< write value to RTC_WPK_WPK bit field */
+
+/* ss register value */
+#define SS_SSC(regval)                     (BITS(0,15) & ((uint32_t)(regval) << 0))   /*!< write value to RTC_SS_SSC bit field */
+
+/* shiftctl register value */
+#define SHIFTCTL_SFS(regval)               (BITS(0,14) & ((uint32_t)(regval) << 0))   /*!< write value to RTC_SHIFTCTL_SFS bit field */
+
+#define RTC_SHIFT_ADD1S_RESET              ((uint32_t)0x00000000U)                    /*!< not add 1 second */
+#define RTC_SHIFT_ADD1S_SET                RTC_SHIFTCTL_A1S                           /*!< add one second to the clock */
+
+/* tts register value */
+#define TTS_SC(regval)                     (BITS(0,6) & ((uint32_t)(regval) << 0))    /*!< write value to RTC_TTS_SC bit field */
+#define GET_TTS_SC(regval)                 GET_BITS((regval),0,6)                     /*!< get value of RTC_TTS_SC bit field */
+
+#define TTS_MN(regval)                     (BITS(8,14) & ((uint32_t)(regval) << 8))   /*!< write value to RTC_TTS_MN bit field */
+#define GET_TTS_MN(regval)                 GET_BITS((regval),8,14)                    /*!< get value of RTC_TTS_MN bit field */
+
+#define TTS_HR(regval)                     (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TTS_HR bit field */
+#define GET_TTS_HR(regval)                 GET_BITS((regval),16,21)                   /*!< get value of RTC_TTS_HR bit field */
+
+/* dts register value */
+#define DTS_DAY(regval)                    (BITS(0,5) & ((uint32_t)(regval) << 0))    /*!< write value to RTC_DTS_DAY bit field */
+#define GET_DTS_DAY(regval)                GET_BITS((regval),0,5)                     /*!< get value of RTC_DTS_DAY bit field */
+
+#define DTS_MON(regval)                    (BITS(8,12) & ((uint32_t)(regval) << 8))   /*!< write value to RTC_DTS_MON bit field */
+#define GET_DTS_MON(regval)                GET_BITS((regval),8,11)                    /*!< get value of RTC_DTS_MON bit field */
+
+#define DTS_DOW(regval)                    (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DTS_DOW bit field */
+#define GET_DTS_DOW(regval)                GET_BITS((regval),13,15)                   /*!< get value of RTC_DTS_DOW bit field */
+
+/* ssts register value */
+#define SSTS_SSC(regval)                   (BITS(0,15) & ((uint32_t)(regval) << 0))   /*!< write value to RTC_SSTS_SSC bit field */
+
+/* hrfc register value */
+#define HRFC_CMSK(regval)                  (BITS(0,8) & ((uint32_t)(regval) << 0))    /*!< write value to RTC_HRFC_CMSK bit field */
+
+#define RTC_CALIBRATION_WINDOW_32S         ((uint32_t)0x00000000U)                    /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */
+#define RTC_CALIBRATION_WINDOW_16S         RTC_HRFC_CWND16                            /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */
+#define RTC_CALIBRATION_WINDOW_8S          RTC_HRFC_CWND8                             /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */
+
+#define RTC_CALIBRATION_PLUS_SET           RTC_HRFC_FREQI                             /*!< increase RTC frequency by 488.5ppm */
+#define RTC_CALIBRATION_PLUS_RESET         ((uint32_t)0x00000000U)                    /*!< no effect */
+
+/* tamp register value */
+#define TAMP_FREQ(regval)                  (BITS(8,10) & ((uint32_t)(regval) << 10))  /*!< write value to RTC_TAMP_FREQ bit field */
+#define RTC_FREQ_DIV32768                  TAMP_FREQ(0)                               /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV16384                  TAMP_FREQ(1)                               /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV8192                   TAMP_FREQ(2)                               /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV4096                   TAMP_FREQ(3)                               /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV2048                   TAMP_FREQ(4)                               /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV1024                   TAMP_FREQ(5)                               /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV512                    TAMP_FREQ(6)                               /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV256                    TAMP_FREQ(7)                               /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */
+
+#define TAMP_FLT(regval)                   (BITS(11,12) & ((uint32_t)(regval) << 11)) /*!< write value to RTC_TAMP_FLT bit field */
+#define RTC_FLT_EDGE                       TAMP_FLT(0)                                /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */
+#define RTC_FLT_2S                         TAMP_FLT(1)                                /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event  */
+#define RTC_FLT_4S                         TAMP_FLT(2)                                /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */
+#define RTC_FLT_8S                         TAMP_FLT(3)                                /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event  */
+
+#define TAMP_PRCH(regval)                  (BITS(13,14) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_TAMP_PRCH bit field */
+#define RTC_PRCH_1C                        TAMP_PRCH(0)                               /*!< 1 RTC clock prechagre time before each sampling */
+#define RTC_PRCH_2C                        TAMP_PRCH(1)                               /*!< 2 RTC clock prechagre time before each sampling  */
+#define RTC_PRCH_4C                        TAMP_PRCH(2)                               /*!< 4 RTC clock prechagre time before each sampling */
+#define RTC_PRCH_8C                        TAMP_PRCH(3)                               /*!< 8 RTC clock prechagre time before each sampling */
+
+#define RTC_TAMPER0                        RTC_TAMP_TP0EN                             /*!< tamper 0 detection enable */
+#define RTC_TAMPER1                        RTC_TAMP_TP1EN                             /*!< tamper 1 detection enable */
+
+#define RTC_TAMPER_TRIGGER_EDGE_RISING     ((uint32_t)0x00000000U)                    /*!< tamper detection is in rising edge mode */
+#define RTC_TAMPER_TRIGGER_EDGE_FALLING    RTC_TAMP_TP0EG                             /*!< tamper detection is in falling edge mode */
+#define RTC_TAMPER_TRIGGER_LEVEL_LOW       ((uint32_t)0x00000000U)                    /*!< tamper detection is in low level mode */
+#define RTC_TAMPER_TRIGGER_LEVEL_HIGH      RTC_TAMP_TP0EG                             /*!< tamper detection is in high level mode */
+
+#define RTC_TAMPER_TRIGGER_POS             ((uint32_t)0x00000001U)                    /* shift position of trigger relative to source */
+
+#define RTC_ALARM_OUTPUT_OD                ((uint32_t)0x00000000U)                    /*!< RTC alarm output open-drain mode */
+#define RTC_ALARM_OUTPUT_PP                RTC_TAMP_AOT                               /*!< RTC alarm output push-pull mode */
+
+/* ALRMXSS register value */
+#define ALRMXSS_SSC(regval)                (BITS(0,14) & ((uint32_t)(regval)<< 0))    /*!< write value to RTC_ALRMXSS_SSC bit field */
+
+#define ALRMXSS_MASKSSC(regval)            (BITS(24,27) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMXSS_MASKSSC bit field */
+#define RTC_MASKSSC_0_14                   ALRMXSS_MASKSSC(0)                         /*!< mask alarm subsecond configuration */
+#define RTC_MASKSSC_1_14                   ALRMXSS_MASKSSC(1)                         /*!< mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared */
+#define RTC_MASKSSC_2_14                   ALRMXSS_MASKSSC(2)                         /*!< mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared */
+#define RTC_MASKSSC_3_14                   ALRMXSS_MASKSSC(3)                         /*!< mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared */
+#define RTC_MASKSSC_4_14                   ALRMXSS_MASKSSC(4)                         /*!< mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared */
+#define RTC_MASKSSC_5_14                   ALRMXSS_MASKSSC(5)                         /*!< mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared */
+#define RTC_MASKSSC_6_14                   ALRMXSS_MASKSSC(6)                         /*!< mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared */
+#define RTC_MASKSSC_7_14                   ALRMXSS_MASKSSC(7)                         /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */
+#define RTC_MASKSSC_8_14                   ALRMXSS_MASKSSC(8)                         /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */
+#define RTC_MASKSSC_9_14                   ALRMXSS_MASKSSC(9)                         /*!< mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared */
+#define RTC_MASKSSC_10_14                  ALRMXSS_MASKSSC(10)                        /*!< mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared */
+#define RTC_MASKSSC_11_14                  ALRMXSS_MASKSSC(11)                        /*!< mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared */
+#define RTC_MASKSSC_12_14                  ALRMXSS_MASKSSC(12)                        /*!< mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared */
+#define RTC_MASKSSC_13_14                  ALRMXSS_MASKSSC(13)                        /*!< mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared */
+#define RTC_MASKSSC_14                     ALRMXSS_MASKSSC(14)                        /*!< mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared */
+#define RTC_MASKSSC_NONE                   ALRMXSS_MASKSSC(15)                        /*!< mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared */
+
+/* RTC interrupt source */
+#define RTC_INT_TIMESTAMP                  RTC_CTL_TSIE                               /*!< time-stamp interrupt enable */
+#define RTC_INT_ALARM0                     RTC_CTL_ALRM0IE                            /*!< RTC alarm0 interrupt enable */
+#define RTC_INT_ALARM1                     RTC_CTL_ALRM1IE                            /*!< RTC alarm1 interrupt enable */
+#define RTC_INT_TAMP                       RTC_TAMP_TPIE                              /*!< tamper detection interrupt enable */
+#define RTC_INT_WAKEUP                     RTC_CTL_WTIE                               /*!< RTC wakeup timer interrupt enable */
+
+/* write protect key */
+#define RTC_UNLOCK_KEY1                    ((uint8_t)0xCAU)                           /*!< RTC unlock key1 */
+#define RTC_UNLOCK_KEY2                    ((uint8_t)0x53U)                           /*!< RTC unlock key2 */
+#define RTC_LOCK_KEY                       ((uint8_t)0xFFU)                           /*!< RTC lock key */
+
+/* registers reset value */
+#define RTC_REGISTER_RESET                 ((uint32_t)0x00000000U)                    /*!< RTC common register reset value */
+#define RTC_DATE_RESET                     ((uint32_t)0x00002101U)                    /*!< RTC_DATE register reset value */
+#define RTC_STAT_RESET                     ((uint32_t)0x00000000U)                    /*!< RTC_STAT register reset value */
+#define RTC_PSC_RESET                      ((uint32_t)0x007F00FFU)                    /*!< RTC_PSC register reset value */
+#define RTC_WUT_RESET                      ((uint32_t)0x0000FFFFU)                    /*!< RTC_WUT register reset value */
+
+/* RTC alarm */
+#define RTC_ALARM0                         ((uint8_t)0x01U)                           /*!< RTC alarm 0 */              
+#define RTC_ALARM1                         ((uint8_t)0x02U)                           /*!< RTC alarm 1 */   
+
+/* RTC coarse calibration direction */
+#define CALIB_INCREASE                     ((uint8_t)0x01U)                           /*!< RTC coarse calibration increase */  
+#define CALIB_DECREASE                     ((uint8_t)0x02U)                           /*!< RTC coarse calibration decrease */  
+
+/* RTC wakeup timer clock */
+#define CTL_WTCS(regval)                   (BITS(0,2) & ((regval)<< 0))
+#define WAKEUP_RTCCK_DIV16                 CTL_WTCS(0)                                /*!< wakeup timer clock is RTC clock divided by 16 */
+#define WAKEUP_RTCCK_DIV8                  CTL_WTCS(1)                                /*!< wakeup timer clock is RTC clock divided by 8 */
+#define WAKEUP_RTCCK_DIV4                  CTL_WTCS(2)                                /*!< wakeup timer clock is RTC clock divided by 4 */
+#define WAKEUP_RTCCK_DIV2                  CTL_WTCS(3)                                /*!< wakeup timer clock is RTC clock divided by 2 */
+#define WAKEUP_CKSPRE                      CTL_WTCS(4)                                /*!< wakeup timer clock is ckapre */
+#define WAKEUP_CKSPRE_2EXP16               CTL_WTCS(6)                                /*!< wakeup timer clock is ckapre and wakeup timer add 2exp16 */
+ 
+/* RTC_AF pin */
+#define RTC_AF0_TIMESTAMP                  ((uint32_t)0x00000000)                     /*!< RTC_AF0 use for timestamp */
+#define RTC_AF1_TIMESTAMP                  RTC_TAMP_TSSEL                             /*!< RTC_AF1 use for timestamp */
+#define RTC_AF0_TAMPER0                    ((uint32_t)0x00000000)                     /*!< RTC_AF0 use for tamper0 */
+#define RTC_AF1_TAMPER0                    RTC_TAMP_TP0SEL                            /*!< RTC_AF1 use for tamper0 */
+
+/* function declarations */
+/* reset most of the RTC registers */
+ErrStatus rtc_deinit(void);
+/* initialize RTC registers */
+ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct);
+/* enter RTC init mode */
+ErrStatus rtc_init_mode_enter(void);
+/* exit RTC init mode */
+void rtc_init_mode_exit(void);
+/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */
+ErrStatus rtc_register_sync_wait(void);
+
+/* get current time and date */
+void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct);
+/* get current subsecond value */
+uint32_t rtc_subsecond_get(void);
+
+/* configure RTC alarm */
+void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time);
+/* configure subsecond of RTC alarm */
+void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond);
+/* get RTC alarm */
+void rtc_alarm_get(uint8_t rtc_alarm,rtc_alarm_struct* rtc_alarm_time);
+/* get RTC alarm subsecond */
+uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm);
+/* enable RTC alarm */
+void rtc_alarm_enable(uint8_t rtc_alarm);
+/* disable RTC alarm */
+ErrStatus rtc_alarm_disable(uint8_t rtc_alarm);
+
+/* enable RTC time-stamp */
+void rtc_timestamp_enable(uint32_t edge);
+/* disable RTC time-stamp */
+void rtc_timestamp_disable(void);
+/* get RTC timestamp time and date */
+void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp);
+/* get RTC time-stamp subsecond */
+uint32_t rtc_timestamp_subsecond_get(void);
+/* RTC time-stamp pin map */
+void rtc_timestamp_pin_map(uint32_t rtc_af);
+
+/* enable RTC tamper */
+void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper);
+/* disable RTC tamper */
+void rtc_tamper_disable(uint32_t source);
+/* RTC tamper0 pin map */
+void rtc_tamper0_pin_map(uint32_t rtc_af);
+
+/* enable specified RTC interrupt */
+void rtc_interrupt_enable(uint32_t interrupt);
+/* disble specified RTC interrupt */
+void rtc_interrupt_disable(uint32_t interrupt);
+/* check specified flag */
+FlagStatus rtc_flag_get(uint32_t flag);
+/* clear specified flag */
+void rtc_flag_clear(uint32_t flag);
+
+/* configure RTC alarm output source */
+void rtc_alarm_output_config(uint32_t source, uint32_t mode);
+/* configure RTC calibration output source */
+void rtc_calibration_output_config(uint32_t source);
+
+/* adjust the daylight saving time by adding or substracting one hour from the current time */
+void rtc_hour_adjust(uint32_t operation);
+/* adjust RTC second or subsecond value of current time */
+ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus);
+
+/* enable RTC bypass shadow registers function */
+void rtc_bypass_shadow_enable(void);
+/* disable RTC bypass shadow registers function */
+void rtc_bypass_shadow_disable(void);
+
+/* enable RTC reference clock detection function */
+ErrStatus rtc_refclock_detection_enable(void);
+/* disable RTC reference clock detection function */
+ErrStatus rtc_refclock_detection_disable(void);
+
+/* enable RTC wakeup timer */
+void rtc_wakeup_enable(void);
+/* disable RTC wakeup timer */
+ErrStatus rtc_wakeup_disable(void);
+/* set auto wakeup timer clock */
+ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock);
+/* set auto wakeup timer value */
+ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer);
+/* get auto wakeup timer value */
+uint16_t rtc_wakeup_timer_get(void);
+
+/* configure RTC smooth calibration */
+ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus);
+/* enable RTC coarse calibration */
+ErrStatus rtc_coarse_calibration_enable(void);
+/* disable RTC coarse calibration */
+ErrStatus rtc_coarse_calibration_disable(void);
+/* configure RTC coarse calibration direction and step */
+ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step);
+
+#endif /* GD32F4XX_RTC_H */

+ 378 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h

@@ -0,0 +1,378 @@
+/*!
+    \file  gd32f4xx_sdio.h
+    \brief definitions for the SDIO
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_SDIO_H
+#define GD32F4XX_SDIO_H
+
+#include "gd32f4xx.h"
+
+/* SDIO definitions */
+#define SDIO                            SDIO_BASE
+
+/* registers definitions */
+#define SDIO_PWRCTL                     REG32(SDIO + 0x00U)    /*!< SDIO power control register */
+#define SDIO_CLKCTL                     REG32(SDIO + 0x04U)    /*!< SDIO clock control register */
+#define SDIO_CMDAGMT                    REG32(SDIO + 0x08U)    /*!< SDIO command argument register */
+#define SDIO_CMDCTL                     REG32(SDIO + 0x0CU)    /*!< SDIO command control register */
+#define SDIO_RSPCMDIDX                  REG32(SDIO + 0x10U)    /*!< SDIO command index response register */
+#define SDIO_RESP0                      REG32(SDIO + 0x14U)    /*!< SDIO response register 0 */
+#define SDIO_RESP1                      REG32(SDIO + 0x18U)    /*!< SDIO response register 1 */
+#define SDIO_RESP2                      REG32(SDIO + 0x1CU)    /*!< SDIO response register 2 */
+#define SDIO_RESP3                      REG32(SDIO + 0x20U)    /*!< SDIO response register 3 */
+#define SDIO_DATATO                     REG32(SDIO + 0x24U)    /*!< SDIO data timeout register */
+#define SDIO_DATALEN                    REG32(SDIO + 0x28U)    /*!< SDIO data length register */
+#define SDIO_DATACTL                    REG32(SDIO + 0x2CU)    /*!< SDIO data control register */
+#define SDIO_DATACNT                    REG32(SDIO + 0x30U)    /*!< SDIO data counter register */
+#define SDIO_STAT                       REG32(SDIO + 0x34U)    /*!< SDIO status register */
+#define SDIO_INTC                       REG32(SDIO + 0x38U)    /*!< SDIO interrupt clear register */
+#define SDIO_INTEN                      REG32(SDIO + 0x3CU)    /*!< SDIO interrupt enable register */
+#define SDIO_FIFOCNT                    REG32(SDIO + 0x48U)    /*!< SDIO FIFO counter register */
+#define SDIO_FIFO                       REG32(SDIO + 0x80U)    /*!< SDIO FIFO data register */
+
+/* bits definitions */
+/* SDIO_PWRCTL */
+#define SDIO_PWRCTL_PWRCTL              BITS(0,1)              /*!< SDIO power control bits */
+
+/* SDIO_CLKCTL */
+#define SDIO_CLKCTL_DIV                 BITS(0,7)              /*!< clock division */
+#define SDIO_CLKCTL_CLKEN               BIT(8)                 /*!< SDIO_CLK clock output enable bit */
+#define SDIO_CLKCTL_CLKPWRSAV           BIT(9)                 /*!< SDIO_CLK clock dynamic switch on/off for power saving */
+#define SDIO_CLKCTL_CLKBYP              BIT(10)                /*!< clock bypass enable bit */
+#define SDIO_CLKCTL_BUSMODE             BITS(11,12)            /*!< SDIO card bus mode control bit */
+#define SDIO_CLKCTL_CLKEDGE             BIT(13)                /*!< SDIO_CLK clock edge selection bit */
+#define SDIO_CLKCTL_HWCLKEN             BIT(14)                /*!< hardware clock control enable bit */
+#define SDIO_CLKCTL_DIV8                BIT(31)                /*!< MSB of clock division */
+
+/* SDIO_CMDAGMT */
+#define SDIO_CMDAGMT_CMDAGMT            BITS(0,31)             /*!< SDIO card command argument */
+
+/* SDIO_CMDCTL */
+#define SDIO_CMDCTL_CMDIDX              BITS(0,5)              /*!< command index */
+#define SDIO_CMDCTL_CMDRESP             BITS(6,7)              /*!< command response type bits */
+#define SDIO_CMDCTL_INTWAIT             BIT(8)                 /*!< interrupt wait instead of timeout */
+#define SDIO_CMDCTL_WAITDEND            BIT(9)                 /*!< wait for ends of data transfer */
+#define SDIO_CMDCTL_CSMEN               BIT(10)                /*!< command state machine(CSM) enable bit */
+#define SDIO_CMDCTL_SUSPEND             BIT(11)                /*!< SD I/O suspend command(SD I/O only) */
+#define SDIO_CMDCTL_ENCMDC              BIT(12)                /*!< CMD completion signal enabled (CE-ATA only) */
+#define SDIO_CMDCTL_NINTEN              BIT(13)                /*!< no CE-ATA interrupt (CE-ATA only) */
+#define SDIO_CMDCTL_ATAEN               BIT(14)                /*!< CE-ATA command enable(CE-ATA only) */
+
+/* SDIO_DATATO */
+#define SDIO_DATATO_DATATO              BITS(0,31)             /*!< data timeout period */
+
+/* SDIO_DATALEN */
+#define SDIO_DATALEN_DATALEN            BITS(0,24)             /*!< data transfer length */
+
+/* SDIO_DATACTL */
+#define SDIO_DATACTL_DATAEN             BIT(0)                 /*!< data transfer enabled bit */
+#define SDIO_DATACTL_DATADIR            BIT(1)                 /*!< data transfer direction */
+#define SDIO_DATACTL_TRANSMOD           BIT(2)                 /*!< data transfer mode */
+#define SDIO_DATACTL_DMAEN              BIT(3)                 /*!< DMA enable bit */
+#define SDIO_DATACTL_BLKSZ              BITS(4,7)              /*!< data block size */
+#define SDIO_DATACTL_RWEN               BIT(8)                 /*!< read wait mode enabled(SD I/O only) */
+#define SDIO_DATACTL_RWSTOP             BIT(9)                 /*!< read wait stop(SD I/O only) */
+#define SDIO_DATACTL_RWTYPE             BIT(10)                /*!< read wait type(SD I/O only) */
+#define SDIO_DATACTL_IOEN               BIT(11)                /*!< SD I/O specific function enable(SD I/O only) */
+
+/* SDIO_STAT */
+#define SDIO_STAT_CCRCERR               BIT(0)                 /*!< command response received (CRC check failed) */
+#define SDIO_STAT_DTCRCERR              BIT(1)                 /*!< data block sent/received (CRC check failed) */
+#define SDIO_STAT_CMDTMOUT              BIT(2)                 /*!< command response timeout */
+#define SDIO_STAT_DTTMOUT               BIT(3)                 /*!< data timeout */
+#define SDIO_STAT_TXURE                 BIT(4)                 /*!< transmit FIFO underrun error occurs */
+#define SDIO_STAT_RXORE                 BIT(5)                 /*!< received FIFO overrun error occurs */
+#define SDIO_STAT_CMDRECV               BIT(6)                 /*!< command response received (CRC check passed) */
+#define SDIO_STAT_CMDSEND               BIT(7)                 /*!< command sent (no response required) */
+#define SDIO_STAT_DTEND                 BIT(8)                 /*!< data end (data counter, SDIO_DATACNT, is zero) */
+#define SDIO_STAT_STBITE                BIT(9)                 /*!< start bit error in the bus */
+#define SDIO_STAT_DTBLKEND              BIT(10)                /*!< data block sent/received (CRC check passed) */
+#define SDIO_STAT_CMDRUN                BIT(11)                /*!< command transmission in progress */
+#define SDIO_STAT_TXRUN                 BIT(12)                /*!< data transmission in progress */
+#define SDIO_STAT_RXRUN                 BIT(13)                /*!< data reception in progress */
+#define SDIO_STAT_TFH                   BIT(14)                /*!< transmit FIFO is half empty: at least 8 words can be written into the FIFO */
+#define SDIO_STAT_RFH                   BIT(15)                /*!< receive FIFO is half full: at least 8 words can be read in the FIFO */
+#define SDIO_STAT_TFF                   BIT(16)                /*!< transmit FIFO is full */
+#define SDIO_STAT_RFF                   BIT(17)                /*!< receive FIFO is full */
+#define SDIO_STAT_TFE                   BIT(18)                /*!< transmit FIFO is empty */
+#define SDIO_STAT_RFE                   BIT(19)                /*!< receive FIFO is empty */
+#define SDIO_STAT_TXDTVAL               BIT(20)                /*!< data is valid in transmit FIFO */
+#define SDIO_STAT_RXDTVAL               BIT(21)                /*!< data is valid in receive FIFO */
+#define SDIO_STAT_SDIOINT               BIT(22)                /*!< SD I/O interrupt received */
+#define SDIO_STAT_ATAEND                BIT(23)                /*!< CE-ATA command completion signal received (only for CMD61) */
+
+/* SDIO_INTC */
+#define SDIO_INTC_CCRCERRC              BIT(0)                 /*!< CCRCERR flag clear bit */
+#define SDIO_INTC_DTCRCERRC             BIT(1)                 /*!< DTCRCERR flag clear bit */
+#define SDIO_INTC_CMDTMOUTC             BIT(2)                 /*!< CMDTMOUT flag clear bit */
+#define SDIO_INTC_DTTMOUTC              BIT(3)                 /*!< DTTMOUT flag clear bit */
+#define SDIO_INTC_TXUREC                BIT(4)                 /*!< TXURE flag clear bit */
+#define SDIO_INTC_RXOREC                BIT(5)                 /*!< RXORE flag clear bit */
+#define SDIO_INTC_CMDRECVC              BIT(6)                 /*!< CMDRECV flag clear bit */
+#define SDIO_INTC_CMDSENDC              BIT(7)                 /*!< CMDSEND flag clear bit */
+#define SDIO_INTC_DTENDC                BIT(8)                 /*!< DTEND flag clear bit */
+#define SDIO_INTC_STBITEC               BIT(9)                 /*!< STBITE flag clear bit */
+#define SDIO_INTC_DTBLKENDC             BIT(10)                /*!< DTBLKEND flag clear bit */
+#define SDIO_INTC_SDIOINTC              BIT(22)                /*!< SDIOINT flag clear bit */
+#define SDIO_INTC_ATAENDC               BIT(23)                /*!< ATAEND flag clear bit */
+
+/* SDIO_INTEN */
+#define SDIO_INTEN_CCRCERRIE            BIT(0)                 /*!< command response CRC fail interrupt enable */
+#define SDIO_INTEN_DTCRCERRIE           BIT(1)                 /*!< data CRC fail interrupt enable */
+#define SDIO_INTEN_CMDTMOUTIE           BIT(2)                 /*!< command response timeout interrupt enable */
+#define SDIO_INTEN_DTTMOUTIE            BIT(3)                 /*!< data timeout interrupt enable */
+#define SDIO_INTEN_TXUREIE              BIT(4)                 /*!< transmit FIFO underrun error interrupt enable */
+#define SDIO_INTEN_RXOREIE              BIT(5)                 /*!< received FIFO overrun error interrupt enable */
+#define SDIO_INTEN_CMDRECVIE            BIT(6)                 /*!< command response received interrupt enable */
+#define SDIO_INTEN_CMDSENDIE            BIT(7)                 /*!< command sent interrupt enable */
+#define SDIO_INTEN_DTENDIE              BIT(8)                 /*!< data end interrupt enable */
+#define SDIO_INTEN_STBITEIE             BIT(9)                 /*!< start bit error interrupt enable */
+#define SDIO_INTEN_DTBLKENDIE           BIT(10)                /*!< data block end interrupt enable */
+#define SDIO_INTEN_CMDRUNIE             BIT(11)                /*!< command transmission interrupt enable */
+#define SDIO_INTEN_TXRUNIE              BIT(12)                /*!< data transmission interrupt enable */
+#define SDIO_INTEN_RXRUNIE              BIT(13)                /*!< data reception interrupt enable */
+#define SDIO_INTEN_TFHIE                BIT(14)                /*!< transmit FIFO half empty interrupt enable */
+#define SDIO_INTEN_RFHIE                BIT(15)                /*!< receive FIFO half full interrupt enable */
+#define SDIO_INTEN_TFFIE                BIT(16)                /*!< transmit FIFO full interrupt enable */
+#define SDIO_INTEN_RFFIE                BIT(17)                /*!< receive FIFO full interrupt enable */
+#define SDIO_INTEN_TFEIE                BIT(18)                /*!< transmit FIFO empty interrupt enable */
+#define SDIO_INTEN_RFEIE                BIT(19)                /*!< receive FIFO empty interrupt enable */
+#define SDIO_INTEN_TXDTVALIE            BIT(20)                /*!< data valid in transmit FIFO interrupt enable */
+#define SDIO_INTEN_RXDTVALIE            BIT(21)                /*!< data valid in receive FIFO interrupt enable */
+#define SDIO_INTEN_SDIOINTIE            BIT(22)                /*!< SD I/O interrupt received interrupt enable */
+#define SDIO_INTEN_ATAENDIE             BIT(23)                /*!< CE-ATA command completion signal received interrupt enable */
+
+/* SDIO_FIFO */
+#define SDIO_FIFO_FIFODT                BITS(0,31)             /*!< receive FIFO data or transmit FIFO data */
+
+/* constants definitions */
+/* SDIO flags */
+#define SDIO_FLAG_CCRCERR               BIT(0)                 /*!< command response received (CRC check failed) flag */
+#define SDIO_FLAG_DTCRCERR              BIT(1)                 /*!< data block sent/received (CRC check failed) flag */
+#define SDIO_FLAG_CMDTMOUT              BIT(2)                 /*!< command response timeout flag */
+#define SDIO_FLAG_DTTMOUT               BIT(3)                 /*!< data timeout flag */
+#define SDIO_FLAG_TXURE                 BIT(4)                 /*!< transmit FIFO underrun error occurs flag */
+#define SDIO_FLAG_RXORE                 BIT(5)                 /*!< received FIFO overrun error occurs flag */
+#define SDIO_FLAG_CMDRECV               BIT(6)                 /*!< command response received (CRC check passed) flag */
+#define SDIO_FLAG_CMDSEND               BIT(7)                 /*!< command sent (no response required) flag */
+#define SDIO_FLAG_DTEND                 BIT(8)                 /*!< data end (data counter, SDIO_DATACNT, is zero) flag */
+#define SDIO_FLAG_STBITE                BIT(9)                 /*!< start bit error in the bus flag */
+#define SDIO_FLAG_DTBLKEND              BIT(10)                /*!< data block sent/received (CRC check passed) flag */
+#define SDIO_FLAG_CMDRUN                BIT(11)                /*!< command transmission in progress flag */
+#define SDIO_FLAG_TXRUN                 BIT(12)                /*!< data transmission in progress flag */
+#define SDIO_FLAG_RXRUN                 BIT(13)                /*!< data reception in progress flag */
+#define SDIO_FLAG_TFH                   BIT(14)                /*!< transmit FIFO is half empty flag: at least 8 words can be written into the FIFO */
+#define SDIO_FLAG_RFH                   BIT(15)                /*!< receive FIFO is half full flag: at least 8 words can be read in the FIFO */
+#define SDIO_FLAG_TFF                   BIT(16)                /*!< transmit FIFO is full flag */
+#define SDIO_FLAG_RFF                   BIT(17)                /*!< receive FIFO is full flag */
+#define SDIO_FLAG_TFE                   BIT(18)                /*!< transmit FIFO is empty flag */
+#define SDIO_FLAG_RFE                   BIT(19)                /*!< receive FIFO is empty flag */
+#define SDIO_FLAG_TXDTVAL               BIT(20)                /*!< data is valid in transmit FIFO flag */
+#define SDIO_FLAG_RXDTVAL               BIT(21)                /*!< data is valid in receive FIFO flag */
+#define SDIO_FLAG_SDIOINT               BIT(22)                /*!< SD I/O interrupt received flag */
+#define SDIO_FLAG_ATAEND                BIT(23)                /*!< CE-ATA command completion signal received (only for CMD61) flag */
+
+/* SDIO interrupt flags */
+#define SDIO_INT_CCRCERR                BIT(0)                 /*!< SDIO CCRCERR interrupt */
+#define SDIO_INT_DTCRCERR               BIT(1)                 /*!< SDIO DTCRCERR interrupt */
+#define SDIO_INT_CMDTMOUT               BIT(2)                 /*!< SDIO CMDTMOUT interrupt */
+#define SDIO_INT_DTTMOUT                BIT(3)                 /*!< SDIO DTTMOUT interrupt */
+#define SDIO_INT_TXURE                  BIT(4)                 /*!< SDIO TXURE interrupt */
+#define SDIO_INT_RXORE                  BIT(5)                 /*!< SDIO RXORE interrupt */
+#define SDIO_INT_CMDRECV                BIT(6)                 /*!< SDIO CMDRECV interrupt */
+#define SDIO_INT_CMDSEND                BIT(7)                 /*!< SDIO CMDSEND interrupt */
+#define SDIO_INT_DTEND                  BIT(8)                 /*!< SDIO DTEND interrupt */
+#define SDIO_INT_STBITE                 BIT(9)                 /*!< SDIO STBITE interrupt */
+#define SDIO_INT_DTBLKEND               BIT(10)                /*!< SDIO DTBLKEND interrupt */
+#define SDIO_INT_CMDRUN                 BIT(11)                /*!< SDIO CMDRUN interrupt */
+#define SDIO_INT_TXRUN                  BIT(12)                /*!< SDIO TXRUN interrupt */
+#define SDIO_INT_RXRUN                  BIT(13)                /*!< SDIO RXRUN interrupt */
+#define SDIO_INT_TFH                    BIT(14)                /*!< SDIO TFH interrupt */
+#define SDIO_INT_RFH                    BIT(15)                /*!< SDIO RFH interrupt */
+#define SDIO_INT_TFF                    BIT(16)                /*!< SDIO TFF interrupt */
+#define SDIO_INT_RFF                    BIT(17)                /*!< SDIO RFF interrupt */
+#define SDIO_INT_TFE                    BIT(18)                /*!< SDIO TFE interrupt */
+#define SDIO_INT_RFE                    BIT(19)                /*!< SDIO RFE interrupt */
+#define SDIO_INT_TXDTVAL                BIT(20)                /*!< SDIO TXDTVAL interrupt */
+#define SDIO_INT_RXDTVAL                BIT(21)                /*!< SDIO RXDTVAL interrupt */
+#define SDIO_INT_SDIOINT                BIT(22)                /*!< SDIO SDIOINT interrupt */
+#define SDIO_INT_ATAEND                 BIT(23)                /*!< SDIO ATAEND interrupt */
+
+/* SDIO power control */
+#define PWRCTL_PWRCTL(regval)           (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define SDIO_POWER_OFF                  PWRCTL_PWRCTL(0)       /*!< SDIO power off */
+#define SDIO_POWER_ON                   PWRCTL_PWRCTL(3)       /*!< SDIO power on */
+
+/* SDIO card bus mode control */
+#define CLKCTL_BUSMODE(regval)          (BITS(11,12) & ((uint32_t)(regval) << 11))
+#define SDIO_BUSMODE_1BIT               CLKCTL_BUSMODE(0)      /*!< 1-bit SDIO card bus mode */
+#define SDIO_BUSMODE_4BIT               CLKCTL_BUSMODE(1)      /*!< 4-bit SDIO card bus mode */
+#define SDIO_BUSMODE_8BIT               CLKCTL_BUSMODE(2)      /*!< 8-bit SDIO card bus mode */
+
+/* SDIO_CLK clock edge selection */
+#define SDIO_SDIOCLKEDGE_RISING         (uint32_t)0x00000000U  /*!< select the rising edge of the SDIOCLK to generate SDIO_CLK */
+#define SDIO_SDIOCLKEDGE_FALLING        SDIO_CLKCTL_CLKEDGE    /*!< select the falling edge of the SDIOCLK to generate SDIO_CLK */
+
+/* clock bypass enable or disable */
+#define SDIO_CLOCKBYPASS_DISABLE        (uint32_t)0x00000000U  /*!< no bypass */
+#define SDIO_CLOCKBYPASS_ENABLE         SDIO_CLKCTL_CLKBYP     /*!< clock bypass */
+
+/* SDIO_CLK clock dynamic switch on/off for power saving */
+#define SDIO_CLOCKPWRSAVE_DISABLE       (uint32_t)0x00000000U  /*!< SDIO_CLK clock is always on */
+#define SDIO_CLOCKPWRSAVE_ENABLE        SDIO_CLKCTL_CLKPWRSAV  /*!< SDIO_CLK closed when bus is idle */
+
+/* SDIO command response type */
+#define CMDCTL_CMDRESP(regval)          (BITS(6,7) & ((uint32_t)(regval) << 6))
+#define SDIO_RESPONSETYPE_NO            CMDCTL_CMDRESP(0)      /*!< no response */
+#define SDIO_RESPONSETYPE_SHORT         CMDCTL_CMDRESP(1)      /*!< short response */
+#define SDIO_RESPONSETYPE_LONG          CMDCTL_CMDRESP(3)      /*!< long response */
+
+/* command state machine wait type */
+#define SDIO_WAITTYPE_NO                (uint32_t)0x00000000U  /*!< not wait interrupt */
+#define SDIO_WAITTYPE_INTERRUPT         SDIO_CMDCTL_INTWAIT    /*!< wait interrupt */
+#define SDIO_WAITTYPE_DATAEND           SDIO_CMDCTL_WAITDEND   /*!< wait the end of data transfer */
+
+#define SDIO_RESPONSE0                  (uint32_t)0x00000000U  /*!< card response[31:0]/card response[127:96] */
+#define SDIO_RESPONSE1                  (uint32_t)0x00000001U  /*!< card response[95:64] */
+#define SDIO_RESPONSE2                  (uint32_t)0x00000002U  /*!< card response[63:32] */
+#define SDIO_RESPONSE3                  (uint32_t)0x00000003U  /*!< card response[31:1], plus bit 0 */
+
+/* SDIO data block size */
+#define DATACTL_BLKSZ(regval)           (BITS(4,7) & ((uint32_t)(regval) << 4))
+#define SDIO_DATABLOCKSIZE_1BYTE        DATACTL_BLKSZ(0)       /*!< block size = 1 byte */
+#define SDIO_DATABLOCKSIZE_2BYTES       DATACTL_BLKSZ(1)       /*!< block size = 2 bytes */
+#define SDIO_DATABLOCKSIZE_4BYTES       DATACTL_BLKSZ(2)       /*!< block size = 4 bytes */
+#define SDIO_DATABLOCKSIZE_8BYTES       DATACTL_BLKSZ(3)       /*!< block size = 8 bytes */
+#define SDIO_DATABLOCKSIZE_16BYTES      DATACTL_BLKSZ(4)       /*!< block size = 16 bytes */
+#define SDIO_DATABLOCKSIZE_32BYTES      DATACTL_BLKSZ(5)       /*!< block size = 32 bytes */
+#define SDIO_DATABLOCKSIZE_64BYTES      DATACTL_BLKSZ(6)       /*!< block size = 64 bytes */
+#define SDIO_DATABLOCKSIZE_128BYTES     DATACTL_BLKSZ(7)       /*!< block size = 128 bytes */
+#define SDIO_DATABLOCKSIZE_256BYTES     DATACTL_BLKSZ(8)       /*!< block size = 256 bytes */
+#define SDIO_DATABLOCKSIZE_512BYTES     DATACTL_BLKSZ(9)       /*!< block size = 512 bytes */
+#define SDIO_DATABLOCKSIZE_1024BYTES    DATACTL_BLKSZ(10)      /*!< block size = 1024 bytes */
+#define SDIO_DATABLOCKSIZE_2048BYTES    DATACTL_BLKSZ(11)      /*!< block size = 2048 bytes */
+#define SDIO_DATABLOCKSIZE_4096BYTES    DATACTL_BLKSZ(12)      /*!< block size = 4096 bytes */
+#define SDIO_DATABLOCKSIZE_8192BYTES    DATACTL_BLKSZ(13)      /*!< block size = 8192 bytes */
+#define SDIO_DATABLOCKSIZE_16384BYTES   DATACTL_BLKSZ(14)      /*!< block size = 16384 bytes */
+
+/* SDIO data transfer mode */
+#define SDIO_TRANSMODE_BLOCK            (uint32_t)0x00000000U  /*!< block transfer */
+#define SDIO_TRANSMODE_STREAM           SDIO_DATACTL_TRANSMOD  /*!< stream transfer or SDIO multibyte transfer */
+
+/* SDIO data transfer direction */
+#define SDIO_TRANSDIRECTION_TOCARD      (uint32_t)0x00000000U  /*!< write data to card */
+#define SDIO_TRANSDIRECTION_TOSDIO      SDIO_DATACTL_DATADIR   /*!< read data from card */
+
+/* SDIO read wait type */
+#define SDIO_READWAITTYPE_DAT2          (uint32_t)0x00000000U  /*!< read wait control using SDIO_DAT[2] */
+#define SDIO_READWAITTYPE_CLK           SDIO_DATACTL_RWTYPE    /*!< read wait control by stopping SDIO_CLK */
+
+/* function declarations */
+/* deinitialize the SDIO */
+void sdio_deinit(void);
+/* configure the SDIO clock */
+void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division);
+/* enable hardware clock control */
+void sdio_hardware_clock_enable(void);
+/* disable hardware clock control */
+void sdio_hardware_clock_disable(void);
+/* set different SDIO card bus mode */
+void sdio_bus_mode_set(uint32_t bus_mode);
+/* set the SDIO power state */
+void sdio_power_state_set(uint32_t power_state);
+/* get the SDIO power state */
+uint32_t sdio_power_state_get(void);
+/* enable SDIO_CLK clock output */
+void sdio_clock_enable(void);
+/* disable SDIO_CLK clock output */
+void sdio_clock_disable(void);
+
+/* configure the command index, argument, response type, wait type and CSM to send command */
+/* configure the command and response */
+void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type);
+/* set the command state machine wait type */
+void sdio_wait_type_set(uint32_t wait_type);
+/* enable the CSM(command state machine) */
+void sdio_csm_enable(void);
+/* disable the CSM(command state machine) */
+void sdio_csm_disable(void);
+/* get the last response command index */
+uint8_t sdio_command_index_get(void);
+/* get the response for the last received command */
+uint32_t sdio_response_get(uint32_t sdio_responsex);
+
+/* configure the data timeout, length, block size, transfer mode, direction and DSM for data transfer */
+/* configure the data timeout, data length and data block size */
+void sdio_data_config(uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize);
+/* configure the data transfer mode and direction */
+void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction);
+/* enable the DSM(data state machine) for data transfer */
+void sdio_dsm_enable(void);
+/* disable the DSM(data state machine) */
+void sdio_dsm_disable(void);
+/* write data(one word) to the transmit FIFO */
+void sdio_data_write(uint32_t data);
+/* read data(one word) from the receive FIFO */
+uint32_t sdio_data_read(void);
+/* get the number of remaining data bytes to be transferred to card */
+uint32_t sdio_data_counter_get(void);
+/* get the number of words remaining to be written or read from FIFO */
+uint32_t sdio_fifo_counter_get(void);
+/* enable the DMA request for SDIO */
+void sdio_dma_enable(void);
+/* disable the DMA request for SDIO */
+void sdio_dma_disable(void);
+
+/* get the flags state of SDIO */
+FlagStatus sdio_flag_get(uint32_t flag);
+/* clear the pending flags of SDIO */
+void sdio_flag_clear(uint32_t flag);
+/* enable the SDIO interrupt */
+void sdio_interrupt_enable(uint32_t int_flag);
+/* disable the SDIO interrupt */
+void sdio_interrupt_disable(uint32_t int_flag);
+/* get the interrupt flags state of SDIO */
+FlagStatus sdio_interrupt_flag_get(uint32_t int_flag);
+/* clear the interrupt pending flags of SDIO */
+void sdio_interrupt_flag_clear(uint32_t int_flag);
+
+/* enable the read wait mode(SD I/O only) */
+void sdio_readwait_enable(void);
+/* disable the read wait mode(SD I/O only) */
+void sdio_readwait_disable(void);
+/* enable the function that stop the read wait process(SD I/O only) */
+void sdio_stop_readwait_enable(void);
+/* disable the function that stop the read wait process(SD I/O only) */
+void sdio_stop_readwait_disable(void);
+/* set the read wait type(SD I/O only) */
+void sdio_readwait_type_set(uint32_t readwait_type);
+/* enable the SD I/O mode specific operation(SD I/O only) */
+void sdio_operation_enable(void);
+/* disable the SD I/O mode specific operation(SD I/O only) */
+void sdio_operation_disable(void);
+/* enable the SD I/O suspend operation(SD I/O only) */
+void sdio_suspend_enable(void);
+/* disable the SD I/O suspend operation(SD I/O only) */
+void sdio_suspend_disable(void);
+
+/* enable the CE-ATA command(CE-ATA only) */
+void sdio_ceata_command_enable(void);
+/* disable the CE-ATA command(CE-ATA only) */
+void sdio_ceata_command_disable(void);
+/* enable the CE-ATA interrupt(CE-ATA only) */
+void sdio_ceata_interrupt_enable(void);
+/* disable the CE-ATA interrupt(CE-ATA only) */
+void sdio_ceata_interrupt_disable(void);
+/* enable the CE-ATA command completion signal(CE-ATA only) */
+void sdio_ceata_command_completion_enable(void);
+/* disable the CE-ATA command completion signal(CE-ATA only) */
+void sdio_ceata_command_completion_disable(void);
+
+#endif /* GD32F4XX_SDIO_H */

+ 327 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h

@@ -0,0 +1,327 @@
+/*!
+    \file  gd32f4xx_spi.h
+    \brief definitions for the SPI
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_SPI_H
+#define GD32F4XX_SPI_H
+
+#include "gd32f4xx.h"
+
+/* SPIx(x=0,1,2,3,4,5) definitions */
+#define SPI0                            (SPI_BASE + 0x0000F800U)
+#define SPI1                            SPI_BASE
+#define SPI2                            (SPI_BASE + 0x00000400U)
+#define SPI3                            (SPI_BASE + 0x0000FC00U)
+#define SPI4                            (SPI_BASE + 0x00011800U)
+#define SPI5                            (SPI_BASE + 0x00011C00U)
+
+/* I2Sx_ADD(x=1,2) definitions */
+#define I2S1_ADD                        I2S_ADD_BASE
+#define I2S2_ADD                        (I2S_ADD_BASE + 0x00000C00U)
+
+/* SPI registers definitions */
+#define SPI_CTL0(spix)                  REG32((spix) + 0x00U)                   /*!< SPI control register 0 */
+#define SPI_CTL1(spix)                  REG32((spix) + 0x04U)                   /*!< SPI control register 1*/
+#define SPI_STAT(spix)                  REG32((spix) + 0x08U)                   /*!< SPI status register */
+#define SPI_DATA(spix)                  REG32((spix) + 0x0CU)                   /*!< SPI data register */
+#define SPI_CRCPOLY(spix)               REG32((spix) + 0x10U)                   /*!< SPI CRC polynomial register */
+#define SPI_RCRC(spix)                  REG32((spix) + 0x14U)                   /*!< SPI receive CRC register */
+#define SPI_TCRC(spix)                  REG32((spix) + 0x18U)                   /*!< SPI transmit CRC register */
+#define SPI_I2SCTL(spix)                REG32((spix) + 0x1CU)                   /*!< SPI I2S control register */
+#define SPI_I2SPSC(spix)                REG32((spix) + 0x20U)                   /*!< SPI I2S clock prescaler register */
+#define SPI_QCTL(spix)                  REG32((spix) + 0x80U)                   /*!< SPI quad mode control register */
+
+/* I2S_ADD registers definitions */
+#define I2S_ADD_CTL0(i2sx_add)          REG32((i2sx_add) + 0x00U)               /*!< I2S_ADD control register 0 */
+#define I2S_ADD_CTL1(i2sx_add)          REG32((i2sx_add) + 0x04U)               /*!< I2S_ADD control register 1*/
+#define I2S_ADD_STAT(i2sx_add)          REG32((i2sx_add) + 0x08U)               /*!< I2S_ADD status register */
+#define I2S_ADD_DATA(i2sx_add)          REG32((i2sx_add) + 0x0CU)               /*!< I2S_ADD data register */
+#define I2S_ADD_CRCPOLY(i2sx_add)       REG32((i2sx_add) + 0x10U)               /*!< I2S_ADD CRC polynomial register */
+#define I2S_ADD_RCRC(i2sx_add)          REG32((i2sx_add) + 0x14U)               /*!< I2S_ADD receive CRC register */
+#define I2S_ADD_TCRC(i2sx_add)          REG32((i2sx_add) + 0x18U)               /*!< I2S_ADD transmit CRC register */
+#define I2S_ADD_I2SCTL(i2sx_add)        REG32((i2sx_add) + 0x1CU)               /*!< I2S_ADD I2S control register */
+#define I2S_ADD_I2SPSC(i2sx_add)        REG32((i2sx_add) + 0x20U)               /*!< I2S_ADD I2S clock prescaler register */
+
+/* bits definitions */
+/* SPIx_CTL0 */
+#define SPI_CTL0_CKPH                   BIT(0)                                  /*!< clock phase selection*/
+#define SPI_CTL0_CKPL                   BIT(1)                                  /*!< clock polarity selection */
+#define SPI_CTL0_MSTMOD                 BIT(2)                                  /*!< master mode enable */
+#define SPI_CTL0_PSC                    BITS(3,5)                               /*!< master clock prescaler selection */
+#define SPI_CTL0_SPIEN                  BIT(6)                                  /*!< SPI enable*/
+#define SPI_CTL0_LF                     BIT(7)                                  /*!< lsb first mode */
+#define SPI_CTL0_SWNSS                  BIT(8)                                  /*!< nss pin selection in nss software mode */
+#define SPI_CTL0_SWNSSEN                BIT(9)                                  /*!< nss software mode selection */
+#define SPI_CTL0_RO                     BIT(10)                                 /*!< receive only */
+#define SPI_CTL0_FF16                   BIT(11)                                 /*!< data frame size */
+#define SPI_CTL0_CRCNT                  BIT(12)                                 /*!< CRC next transfer */
+#define SPI_CTL0_CRCEN                  BIT(13)                                 /*!< CRC calculation enable */
+#define SPI_CTL0_BDOEN                  BIT(14)                                 /*!< bidirectional transmit output enable*/
+#define SPI_CTL0_BDEN                   BIT(15)                                 /*!< bidirectional enable */
+
+/* SPIx_CTL1 */
+#define SPI_CTL1_DMAREN                 BIT(0)                                  /*!< receive buffer dma enable */
+#define SPI_CTL1_DMATEN                 BIT(1)                                  /*!< transmit buffer dma enable */
+#define SPI_CTL1_NSSDRV                 BIT(2)                                  /*!< drive nss output */
+#define SPI_CTL1_TMOD                   BIT(4)                                  /*!< SPI TI mode enable */
+#define SPI_CTL1_ERRIE                  BIT(5)                                  /*!< errors interrupt enable */
+#define SPI_CTL1_RBNEIE                 BIT(6)                                  /*!< receive buffer not empty interrupt enable */
+#define SPI_CTL1_TBEIE                  BIT(7)                                  /*!< transmit buffer empty interrupt enable */
+
+/* SPIx_STAT */
+#define SPI_STAT_RBNE                   BIT(0)                                  /*!< receive buffer not empty */
+#define SPI_STAT_TBE                    BIT(1)                                  /*!< transmit buffer empty */
+#define SPI_STAT_I2SCH                  BIT(2)                                  /*!< I2S channel side */
+#define SPI_STAT_TXURERR                BIT(3)                                  /*!< I2S transmission underrun error bit */
+#define SPI_STAT_CRCERR                 BIT(4)                                  /*!< SPI CRC error bit */
+#define SPI_STAT_CONFERR                BIT(5)                                  /*!< SPI configuration error */
+#define SPI_STAT_RXORERR                BIT(6)                                  /*!< SPI reception overrun error Bit */
+#define SPI_STAT_TRANS                  BIT(7)                                  /*!< transmitting on-going Bit */
+#define SPI_STAT_FERR                   BIT(8)                                  /*!< format error */
+
+/* SPI_DATA */
+#define SPI_DATA_DATA                   BITS(0,15)                              /*!< data transfer register */
+
+/* SPI_CRCPOLY */
+#define SPI_CRCPOLY_CPR                 BITS(0,15)                              /*!< CRC polynomial register */
+
+/* SPI_RCRC */
+#define SPI_RCRC_RCR                    BITS(0,15)                              /*!< RX CRC register */
+
+/* SPI_TCRC */
+#define SPI_TCRC_TCR                    BITS(0,15)                              /*!< RX CRC register */
+
+/* SPIx_I2SCTL */
+#define SPI_I2SCTL_CHLEN                BIT(0)                                  /*!< channel length */
+#define SPI_I2SCTL_DTLEN                BITS(1,2)                               /*!< data length */
+#define SPI_I2SCTL_CKPL                 BIT(3)                                  /*!< idle state clock polarity */
+#define SPI_I2SCTL_I2SSTD               BITS(4,5)                               /*!< I2S standard selection */
+#define SPI_I2SCTL_PCMSMOD              BIT(7)                                  /*!< PCM frame synchronization mode */
+#define SPI_I2SCTL_I2SOPMOD             BITS(8,9)                               /*!< I2S operation mode */
+#define SPI_I2SCTL_I2SEN                BIT(10)                                 /*!< I2S enable */
+#define SPI_I2SCTL_I2SSEL               BIT(11)                                 /*!< I2S mode selection */
+
+/* SPIx_I2S_PSC */
+#define SPI_I2SPSC_DIV                  BITS(0,7)                               /*!< dividing factor for the prescaler */
+#define SPI_I2SPSC_OF                   BIT(8)                                  /*!< odd factor for the prescaler */
+#define SPI_I2SPSC_MCKOEN               BIT(9)                                  /*!< I2S MCK output enable */
+
+/* SPIx_SPI_QCTL(only SPI5) */
+#define SPI_QCTL_QMOD                   BIT(0)                                  /*!< quad-SPI mode enable */
+#define SPI_QCTL_QRD                    BIT(1)                                  /*!< quad-SPI mode read select */
+#define SPI_QCTL_IO23_DRV               BIT(2)                                  /*!< drive SPI_IO2 and SPI_IO3 enable */
+
+/* constants definitions */
+/* SPI and I2S parameter struct definitions */
+typedef struct
+{   
+    uint32_t device_mode;                                                       /*!< SPI master or slave */
+    uint32_t trans_mode;                                                        /*!< SPI transtype */
+    uint32_t frame_size;                                                        /*!< SPI frame size */
+    uint32_t nss;                                                               /*!< SPI nss control by handware or software */
+    uint32_t endian;                                                            /*!< SPI big endian or little endian */
+    uint32_t clock_polarity_phase;                                              /*!< SPI clock phase and polarity */
+    uint32_t prescale;                                                          /*!< SPI prescale factor */
+}spi_parameter_struct;
+
+/* SPI struct parameter options */
+#define SPI_MASTER                      (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS)      /*!< SPI as master */
+#define SPI_SLAVE                       ((uint32_t)0x00000000U)                 /*!< SPI as slave */
+
+#define SPI_BIDIRECTIONAL_TEANSMIT      SPI_CTL0_BDOEN                          /*!< SPI work in transmit-only mode */
+#define SPI_BIDIRECTIONAL_RECEIVE       ~SPI_CTL0_BDOEN                         /*!< SPI work in receive-only mode */
+
+#define SPI_TRANSMODE_FULLDUPLEX        ((uint32_t)0x00000000U)                 /*!< SPI receive and send data at fullduplex communication */
+#define SPI_TRANSMODE_RECEIVEONLY       SPI_CTL0_RO                             /*!< SPI only receive data */
+#define SPI_TRANSMODE_BDRECEIVE         SPI_CTL0_BDEN                           /*!< bidirectional receive data */
+#define SPI_TRANSMODE_BDTRANSMIT        (SPI_CTL0_BDEN | SPI_CTL0_BDOEN)        /*!< bidirectional transmit data*/
+
+#define SPI_FRAMESIZE_16BIT             SPI_CTL0_FF16                           /*!< SPI frame size is 16 bits */
+#define SPI_FRAMESIZE_8BIT              ((uint32_t)0x00000000U)                 /*!< SPI frame size is 8 bits */
+
+#define SPI_NSS_SOFT                    SPI_CTL0_SWNSSEN                        /*!< SPI nss control by sofrware */
+#define SPI_NSS_HARD                    ((uint32_t)0x00000000U)                 /*!< SPI nss control by hardware */
+
+#define SPI_ENDIAN_MSB                  ((uint32_t)0x00000000U)                 /*!< SPI transmit way is big endian:transmit MSB first */
+#define SPI_ENDIAN_LSB                  SPI_CTL0_LF                             /*!< SPI transmit way is little endian:transmit LSB first */
+
+#define SPI_CK_PL_LOW_PH_1EDGE          ((uint32_t)0x00000000U)                 /*!< SPI clock polarity is low level and phase is first edge */
+#define SPI_CK_PL_HIGH_PH_1EDGE         SPI_CTL0_CKPL                           /*!< SPI clock polarity is high level and phase is first edge */
+#define SPI_CK_PL_LOW_PH_2EDGE          SPI_CTL0_CKPH                           /*!< SPI clock polarity is low level and phase is second edge */
+#define SPI_CK_PL_HIGH_PH_2EDGE         (SPI_CTL0_CKPL|SPI_CTL0_CKPH)           /*!< SPI clock polarity is high level and phase is second edge */
+
+#define CTL0_PSC(regval)                (BITS(3,5)&((uint32_t)(regval)<<3))
+#define SPI_PSC_2                       CTL0_PSC(0)                             /*!< SPI clock prescale factor is 2 */
+#define SPI_PSC_4                       CTL0_PSC(1)                             /*!< SPI clock prescale factor is 4 */
+#define SPI_PSC_8                       CTL0_PSC(2)                             /*!< SPI clock prescale factor is 8 */
+#define SPI_PSC_16                      CTL0_PSC(3)                             /*!< SPI clock prescale factor is 16 */
+#define SPI_PSC_32                      CTL0_PSC(4)                             /*!< SPI clock prescale factor is 32 */
+#define SPI_PSC_64                      CTL0_PSC(5)                             /*!< SPI clock prescale factor is 64 */
+#define SPI_PSC_128                     CTL0_PSC(6)                             /*!< SPI clock prescale factor is 128 */
+#define SPI_PSC_256                     CTL0_PSC(7)                             /*!< SPI clock prescale factor is 256 */
+
+/* I2S parameter options */
+#define I2S_AUDIOSAMPLE_8K              ((uint32_t)8000U)                       /*!< I2S audio sample rate is 8khz */
+#define I2S_AUDIOSAMPLE_11K             ((uint32_t)11025U)                      /*!< I2S audio sample rate is 11khz */
+#define I2S_AUDIOSAMPLE_16K             ((uint32_t)16000U)                      /*!< I2S audio sample rate is 16khz */
+#define I2S_AUDIOSAMPLE_22K             ((uint32_t)22050U)                      /*!< I2S audio sample rate is 22khz */
+#define I2S_AUDIOSAMPLE_32K             ((uint32_t)32000U)                      /*!< I2S audio sample rate is 32khz */
+#define I2S_AUDIOSAMPLE_44K             ((uint32_t)44100U)                      /*!< I2S audio sample rate is 44khz */
+#define I2S_AUDIOSAMPLE_48K             ((uint32_t)48000U)                      /*!< I2S audio sample rate is 48khz */
+#define I2S_AUDIOSAMPLE_96K             ((uint32_t)96000U)                      /*!< I2S audio sample rate is 96khz */
+#define I2S_AUDIOSAMPLE_192K            ((uint32_t)192000U)                     /*!< I2S audio sample rate is 192khz */
+
+#define I2SCTL_DTLEN(regval)            (BITS(1,2)&((uint32_t)(regval)<<1))
+#define I2S_FRAMEFORMAT_DT16B_CH16B     I2SCTL_DTLEN(0)                         /*!< I2S data length is 16 bit and channel length is 16 bit */
+#define I2S_FRAMEFORMAT_DT16B_CH32B     (I2SCTL_DTLEN(0)|SPI_I2SCTL_CHLEN)      /*!< I2S data length is 16 bit and channel length is 32 bit */
+#define I2S_FRAMEFORMAT_DT24B_CH32B     (I2SCTL_DTLEN(1)|SPI_I2SCTL_CHLEN)      /*!< I2S data length is 24 bit and channel length is 32 bit */
+#define I2S_FRAMEFORMAT_DT32B_CH32B     (I2SCTL_DTLEN(2)|SPI_I2SCTL_CHLEN)      /*!< I2S data length is 32 bit and channel length is 32 bit */
+                                                                               
+#define I2S_MCKOUT_DISABLE              ((uint32_t)0x00000000U)                 /*!< I2S master clock output disable */
+#define I2S_MCKOUT_ENABLE               SPI_I2SPSC_MCKOEN                       /*!< I2S master clock output enable */
+                                                                           
+#define I2SCTL_I2SOPMOD(regval)         (BITS(8,9)&((uint32_t)(regval)<<8))
+#define I2S_MODE_SLAVETX                I2SCTL_I2SOPMOD(0)                      /*!< I2S slave transmit mode */
+#define I2S_MODE_SLAVERX                I2SCTL_I2SOPMOD(1)                      /*!< I2S slave receive mode */
+#define I2S_MODE_MASTERTX               I2SCTL_I2SOPMOD(2)                      /*!< I2S master transmit mode */
+#define I2S_MODE_MASTERRX               I2SCTL_I2SOPMOD(3)                      /*!< I2S master receive mode */
+
+#define I2SCTL_I2SSTD(regval)           (BITS(4,5)&((uint32_t)(regval)<<4))
+#define I2S_STD_PHILLIPS                I2SCTL_I2SSTD(0)                        /*!< I2S phillips standard */
+#define I2S_STD_MSB                     I2SCTL_I2SSTD(1)                        /*!< I2S MSB standard */
+#define I2S_STD_LSB                     I2SCTL_I2SSTD(2)                        /*!< I2S LSB standard */
+#define I2S_STD_PCMSHORT                I2SCTL_I2SSTD(3)                        /*!< I2S PCM short standard */
+#define I2S_STD_PCMLONG                 (I2SCTL_I2SSTD(3)|SPI_I2SCTL_PCMSMOD)   /*!< I2S PCM long standard */
+
+#define I2S_CKPL_LOW                    ((uint32_t)0x00000000U)                 /*!< I2S clock polarity low level */
+#define I2S_CKPL_HIGH                   SPI_I2SCTL_CKPL                         /*!< I2S clock polarity high level */
+
+/* SPI dma constants definitions */                                    
+#define SPI_DMA_TRANSMIT                ((uint8_t)0x00U)                        /*!< SPI transmit data DMA */
+#define SPI_DMA_RECEIVE                 ((uint8_t)0x01U)                        /*!< SPI receive data DMA */
+
+/* SPI CRC constants definitions */
+#define SPI_CRC_TX                      ((uint8_t)0x00U)                        /*!< SPI transmit CRC value */
+#define SPI_CRC_RX                      ((uint8_t)0x01U)                        /*!< SPI receive CRC value */
+
+/* SPI interrupt constants definitions */
+#define SPI_I2S_INT_TBE                 ((uint8_t)0x00U)                        /*!< transmit buffer empty interrupt */
+#define SPI_I2S_INT_RBNE                ((uint8_t)0x01U)                        /*!< receive buffer not empty interrupt */
+#define SPI_I2S_INT_RXORERR             ((uint8_t)0x02U)                        /*!< overrun interrupt */
+#define SPI_INT_CONFERR                 ((uint8_t)0x03U)                        /*!< config error interrupt */
+#define SPI_INT_CRCERR                  ((uint8_t)0x04U)                        /*!< CRC error interrupt */
+#define I2S_INT_TXURERR                 ((uint8_t)0x05U)                        /*!< underrun error interrupt */
+#define SPI_I2S_INT_ERR                 ((uint8_t)0x06U)                        /*!< error interrupt */
+#define SPI_I2S_INT_FERR                ((uint8_t)0x07U)                        /*!< format error interrupt */
+
+/* SPI flag definitions */                                                  
+#define SPI_FLAG_RBNE                   SPI_STAT_RBNE                           /*!< receive buffer not empty flag */
+#define SPI_FLAG_TBE                    SPI_STAT_TBE                            /*!< transmit buffer empty flag */
+#define SPI_FLAG_CRCERR                 SPI_STAT_CRCERR                         /*!< CRC error flag */
+#define SPI_FLAG_CONFERR                SPI_STAT_CONFERR                        /*!< mode config error flag */
+#define SPI_FLAG_RXORERR                SPI_STAT_RXORERR                        /*!< receive overrun flag */
+#define SPI_FLAG_TRANS                  SPI_STAT_TRANS                          /*!< transmit on-going flag */
+#define SPI_FLAG_FERR                   SPI_STAT_FERR                           /*!< format error interrupt flag */
+#define I2S_FLAG_RBNE                   SPI_STAT_RBNE                           /*!< receive buffer not empty flag */
+#define I2S_FLAG_TBE                    SPI_STAT_TBE                            /*!< transmit buffer empty flag */
+#define I2S_FLAG_CH                     SPI_STAT_I2SCH                          /*!< transmit buffer empty interrupt */
+#define I2S_FLAG_TXURERR                SPI_STAT_TXURERR                        /*!< underrun error flag */
+#define I2S_FLAG_RXORERR                SPI_STAT_RXORERR                        /*!< overrun flag */
+#define I2S_FLAG_TRANS                  SPI_STAT_TRANS                          /*!< transmit on-going flag */
+#define I2S_FLAG_FERR                   SPI_STAT_FERR                           /*!< format error interrupt flag */
+
+/* function declarations */
+/* SPI and I2S reset */
+void spi_i2s_deinit(uint32_t spi_periph);
+/* SPI parameter initialization */
+void spi_init(uint32_t spi_periph,spi_parameter_struct* spi_struct);
+/* SPI enable */
+void spi_enable(uint32_t spi_periph);
+/* SPI disable */
+void spi_disable(uint32_t spi_periph);
+
+/* I2S parameter initialization */
+void i2s_init(uint32_t spi_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl);
+/* I2S prescale configuration */
+void i2s_psc_config(uint32_t spi_periph,uint32_t i2s_audiosample,uint32_t i2s_frameformat,uint32_t i2s_mckout);
+/* I2S enable */
+void i2s_enable(uint32_t spi_periph);
+/* I2S disable */
+void i2s_disable(uint32_t spi_periph);
+
+/* SPI nss output enable */
+void spi_nss_output_enable(uint32_t spi_periph);
+/* SPI nss output disable */
+void spi_nss_output_disable(uint32_t spi_periph);
+/* SPI nss pin high level in software mode */
+void spi_nss_internal_high(uint32_t spi_periph);
+/* SPI nss pin low level in software mode */
+void spi_nss_internal_low(uint32_t spi_periph);
+
+/* SPI dma enable */
+void spi_dma_enable(uint32_t spi_periph,uint8_t spi_dma);
+/* SPI dma disable */
+void spi_dma_disable(uint32_t spi_periph,uint8_t spi_dma);
+
+/* configure SPI/I2S data frame format */
+void spi_i2s_data_frame_format_config(uint32_t spi_periph,uint16_t frame_format);
+/* transmit data */
+void spi_i2s_data_transmit(uint32_t spi_periph,uint16_t data);
+/* receive data */
+uint16_t spi_i2s_data_receive(uint32_t spi_periph);
+/* configure SPI bidirectional transfer direction  */
+void spi_bidirectional_transfer_config(uint32_t spi_periph,uint32_t transfer_direction);
+
+/* enable SPI interrupt */
+void spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t spi_i2s_int);
+/* disable SPI interrupt */
+void spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t spi_i2s_int);
+/* get SPI and I2S interrupt status*/
+FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph,uint8_t spi_i2s_int);
+/* get SPI and I2S flag status */
+FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t spi_i2s_flag);
+/* clear SPI CRC error flag status */
+void spi_crc_error_clear(uint32_t spi_periph);
+
+/* SPI CRC polynomial set */
+void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly);
+/* SPI CRC polynomial get */
+uint16_t spi_crc_polynomial_get(uint32_t spi_periph);
+/* SPI CRC function turn on */
+void spi_crc_on(uint32_t spi_periph);
+/* SPI CRC function turn off */
+void spi_crc_off(uint32_t spi_periph);
+/* SPI next data is CRC value */
+void spi_crc_next(uint32_t spi_periph);
+/* get SPI CRC send value or receive value */
+uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc);
+
+/* SPI TI mode enable */
+void spi_ti_mode_enable(uint32_t spi_periph);
+/* SPI TI mode disable */
+void spi_ti_mode_disable(uint32_t spi_periph);
+
+/* configure i2s full duplex mode */
+void i2s_full_duplex_mode_config(uint32_t i2s_add_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl,uint32_t i2s_frameformat);
+
+/* quad wire SPI enable */
+void qspi_enable(uint32_t spi_periph);
+/* quad wire SPI disable */
+void qspi_disable(uint32_t spi_periph);
+/* quad wire SPI write enable */
+void qspi_write_enable(uint32_t spi_periph);
+/* quad wire SPI read enable */
+void qspi_read_enable(uint32_t spi_periph);
+/* quad wire SPI_IO2 and SPI_IO3 pin output enable */
+void qspi_io23_output_enable(uint32_t spi_periph);
+/* quad wire SPI_IO2 and SPI_IO3 pin output disable */
+void qspi_io23_output_disable(uint32_t spi_periph);
+
+#endif /* GD32F4XX_SPI_H */

+ 158 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h

@@ -0,0 +1,158 @@
+/*!
+    \file  gd32f4xx_syscfg.h
+    \brief definitions for the SYSCFG
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_SYSCFG_H
+#define GD32F4XX_SYSCFG_H
+
+#include "gd32f4xx.h"
+
+/* SYSCFG definitions */
+#define SYSCFG                              SYSCFG_BASE
+
+/* registers definitions */
+#define SYSCFG_CFG0                         REG32(SYSCFG + 0x00U)    /*!< system configuration register 0 */
+#define SYSCFG_CFG1                         REG32(SYSCFG + 0x04U)    /*!< system configuration register 1 */
+#define SYSCFG_EXTISS0                      REG32(SYSCFG + 0x08U)    /*!< EXTI sources selection register 0 */
+#define SYSCFG_EXTISS1                      REG32(SYSCFG + 0x0CU)    /*!< EXTI sources selection register 1 */
+#define SYSCFG_EXTISS2                      REG32(SYSCFG + 0x10U)    /*!< EXTI sources selection register 2 */
+#define SYSCFG_EXTISS3                      REG32(SYSCFG + 0x14U)    /*!< EXTI sources selection register 3 */
+#define SYSCFG_CPSCTL                       REG32(SYSCFG + 0x20U)    /*!< system I/O compensation control register */
+
+/* SYSCFG_CFG0 bits definitions */
+#define SYSCFG_CFG0_BOOT_MODE               BITS(0,2)                /*!< SYSCFG memory remap config */
+#define SYSCFG_CFG0_FMC_SWP                 BIT(8)                   /*!< FMC memory swap config */
+#define SYSCFG_CFG0_EXMC_SWP                BITS(10,11)              /*!< EXMC memory swap config */
+
+/* SYSCFG_CFG1 bits definitions */
+#define SYSCFG_CFG1_ENET_PHY_SEL            BIT(23)                  /*!< Ethernet PHY selection config */
+
+/* SYSCFG_EXTISS0 bits definitions */
+#define SYSCFG_EXTISS0_EXTI0_SS             BITS(0,3)                /*!< EXTI 0 configuration */
+#define SYSCFG_EXTISS0_EXTI1_SS             BITS(4,7)                /*!< EXTI 1 configuration */
+#define SYSCFG_EXTISS0_EXTI2_SS             BITS(8,11)               /*!< EXTI 2 configuration */
+#define SYSCFG_EXTISS0_EXTI3_SS             BITS(12,15)              /*!< EXTI 3 configuration */
+
+/* SYSCFG_EXTISS1 bits definitions */
+#define SYSCFG_EXTISS1_EXTI4_SS             BITS(0,3)                /*!< EXTI 4 configuration */
+#define SYSCFG_EXTISS1_EXTI5_SS             BITS(4,7)                /*!< EXTI 5 configuration */
+#define SYSCFG_EXTISS1_EXTI6_SS             BITS(8,11)               /*!< EXTI 6 configuration */
+#define SYSCFG_EXTISS1_EXTI7_SS             BITS(12,15)              /*!< EXTI 7 configuration */
+
+/* SYSCFG_EXTISS2 bits definitions */
+#define SYSCFG_EXTISS2_EXTI8_SS             BITS(0,3)                /*!< EXTI 8 configuration */
+#define SYSCFG_EXTISS2_EXTI9_SS             BITS(4,7)                /*!< EXTI 9 configuration */
+#define SYSCFG_EXTISS2_EXTI10_SS            BITS(8,11)               /*!< EXTI 10 configuration */
+#define SYSCFG_EXTISS2_EXTI11_SS            BITS(12,15)              /*!< EXTI 11 configuration */
+
+/* SYSCFG_EXTISS3 bits definitions */
+#define SYSCFG_EXTISS3_EXTI12_SS            BITS(0,3)                /*!< EXTI 12 configuration */
+#define SYSCFG_EXTISS3_EXTI13_SS            BITS(4,7)                /*!< EXTI 13 configuration */
+#define SYSCFG_EXTISS3_EXTI14_SS            BITS(8,11)               /*!< EXTI 14 configuration */
+#define SYSCFG_EXTISS3_EXTI15_SS            BITS(12,15)              /*!< EXTI 15 configuration */
+
+/* SYSCFG_CPSCTL bits definitions */
+#define SYSCFG_CPSCTL_CPS_EN                BIT(0)                   /*!< I/O compensation cell enable */
+#define SYSCFG_CPSCTL_CPS_RDY               BIT(8)                   /*!< I/O compensation cell is ready or not */
+
+/* constants definitions */
+/* boot mode definitions */
+#define SYSCFG_BOOTMODE_FLASH               ((uint8_t)0x00U)          /*!< main flash memory remap */
+#define SYSCFG_BOOTMODE_BOOTLOADER          ((uint8_t)0x01U)          /*!< boot loader remap */
+#define SYSCFG_BOOTMODE_EXMC_SRAM           ((uint8_t)0x02U)          /*!< SRAM/NOR 0 and 1 of EXMC remap */
+#define SYSCFG_BOOTMODE_SRAM                ((uint8_t)0x03U)          /*!< SRAM0 of on-chip SRAM remap */
+#define SYSCFG_BOOTMODE_EXMC_SDRAM          ((uint8_t)0x04U)          /*!< SDRAM bank0 of EXMC remap */
+
+/* FMC swap definitions */
+#define SYSCFG_FMC_SWP_BANK0                ((uint32_t)0x00000000U)   /*!< main flash Bank 0 is mapped at address 0x08000000 */
+#define SYSCFG_FMC_SWP_BANK1                ((uint32_t)0x00000100U)   /*!< main flash Bank 1 is mapped at address 0x08000000 */
+
+/* EXMC swap enable/disable */
+#define SYSCFG_EXMC_SWP_ENABLE              ((uint32_t)0x00000400U)   /*!< SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card */
+#define SYSCFG_EXMC_SWP_DISABLE             ((uint32_t)0x00000000U)   /*!< no memory mapping swap */
+
+/* EXTI source select definition */
+#define EXTISS0                             ((uint8_t)0x00U)          /*!< EXTI source select GPIOx pin 0~3 */
+#define EXTISS1                             ((uint8_t)0x01U)          /*!< EXTI source select GPIOx pin 4~7 */
+#define EXTISS2                             ((uint8_t)0x02U)          /*!< EXTI source select GPIOx pin 8~11 */
+#define EXTISS3                             ((uint8_t)0x03U)          /*!< EXTI source select GPIOx pin 12~15 */
+
+/* EXTI source select mask bits definition */
+#define EXTI_SS_MASK                        BITS(0,3)
+
+/* EXTI source select jumping step definition */
+#define EXTI_SS_JSTEP                       ((uint8_t)(0x04U))
+
+/* EXTI source select moving step definition */
+#define EXTI_SS_MSTEP(pin)                  (EXTI_SS_JSTEP*((pin)%EXTI_SS_JSTEP))
+
+/* EXTI source port definitions */
+#define EXTI_SOURCE_GPIOA                   ((uint8_t)0x00U)          /*!< EXTI GPIOA configuration */
+#define EXTI_SOURCE_GPIOB                   ((uint8_t)0x01U)          /*!< EXTI GPIOB configuration */
+#define EXTI_SOURCE_GPIOC                   ((uint8_t)0x02U)          /*!< EXTI GPIOC configuration */
+#define EXTI_SOURCE_GPIOD                   ((uint8_t)0x03U)          /*!< EXTI GPIOD configuration */
+#define EXTI_SOURCE_GPIOE                   ((uint8_t)0x04U)          /*!< EXTI GPIOE configuration */
+#define EXTI_SOURCE_GPIOF                   ((uint8_t)0x05U)          /*!< EXTI GPIOF configuration */
+#define EXTI_SOURCE_GPIOG                   ((uint8_t)0x06U)          /*!< EXTI GPIOG configuration */
+#define EXTI_SOURCE_GPIOH                   ((uint8_t)0x07U)          /*!< EXTI GPIOH configuration */
+#define EXTI_SOURCE_GPIOI                   ((uint8_t)0x08U)          /*!< EXTI GPIOI configuration */
+
+/* EXTI source pin definitions */
+#define EXTI_SOURCE_PIN0                    ((uint8_t)0x00U)          /*!< EXTI GPIO pin0 configuration */
+#define EXTI_SOURCE_PIN1                    ((uint8_t)0x01U)          /*!< EXTI GPIO pin1 configuration */
+#define EXTI_SOURCE_PIN2                    ((uint8_t)0x02U)          /*!< EXTI GPIO pin2 configuration */
+#define EXTI_SOURCE_PIN3                    ((uint8_t)0x03U)          /*!< EXTI GPIO pin3 configuration */
+#define EXTI_SOURCE_PIN4                    ((uint8_t)0x04U)          /*!< EXTI GPIO pin4 configuration */
+#define EXTI_SOURCE_PIN5                    ((uint8_t)0x05U)          /*!< EXTI GPIO pin5 configuration */
+#define EXTI_SOURCE_PIN6                    ((uint8_t)0x06U)          /*!< EXTI GPIO pin6 configuration */
+#define EXTI_SOURCE_PIN7                    ((uint8_t)0x07U)          /*!< EXTI GPIO pin7 configuration */
+#define EXTI_SOURCE_PIN8                    ((uint8_t)0x08U)          /*!< EXTI GPIO pin8 configuration */
+#define EXTI_SOURCE_PIN9                    ((uint8_t)0x09U)          /*!< EXTI GPIO pin9 configuration */
+#define EXTI_SOURCE_PIN10                   ((uint8_t)0x0AU)          /*!< EXTI GPIO pin10 configuration */
+#define EXTI_SOURCE_PIN11                   ((uint8_t)0x0BU)          /*!< EXTI GPIO pin11 configuration */
+#define EXTI_SOURCE_PIN12                   ((uint8_t)0x0CU)          /*!< EXTI GPIO pin12 configuration */
+#define EXTI_SOURCE_PIN13                   ((uint8_t)0x0DU)          /*!< EXTI GPIO pin13 configuration */
+#define EXTI_SOURCE_PIN14                   ((uint8_t)0x0EU)          /*!< EXTI GPIO pin14 configuration */
+#define EXTI_SOURCE_PIN15                   ((uint8_t)0x0FU)          /*!< EXTI GPIO pin15 configuration */
+
+/* ethernet PHY selection */
+#define SYSCFG_ENET_PHY_MII                 ((uint32_t)0x00000000U)
+#define SYSCFG_ENET_PHY_RMII                ((uint32_t)0x00800000U)
+
+/* I/O compensation cell enable/disable */
+#define SYSCFG_COMPENSATION_ENABLE          ((uint32_t)0x00000001U)
+#define SYSCFG_COMPENSATION_DISABLE         ((uint32_t)0x00000000U)
+
+/* function declarations */
+/* deinit syscfg module */
+void syscfg_deinit(void);
+
+/* configure the boot mode */
+void syscfg_bootmode_config(uint8_t syscfg_bootmode);
+
+/* FMC memory mapping swap */
+void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap);
+
+/* configure the EXMC swap */
+void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap); 
+
+/* configure the GPIO pin as EXTI Line */
+void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin);
+
+/* configure the PHY interface for the ethernet MAC */
+void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface);
+
+/* configure the I/O compensation cell */
+void syscfg_compensation_config(uint32_t syscfg_compensation); 
+
+/* check the I/O compensation cell is ready or not */
+FlagStatus syscfg_flag_get(void);
+
+#endif /* GD32F4XX_SYSCFG_H */

+ 735 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h

@@ -0,0 +1,735 @@
+/*!
+    \file  gd32f4xx_timer.h
+    \brief definitions for the TIMER
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_TIMER_H
+#define GD32F4XX_TIMER_H
+
+#include "gd32f4xx.h"
+
+/* TIMERx(x=0..13) definitions */
+#define TIMER0                           (TIMER_BASE + 0x00010000U)
+#define TIMER1                           (TIMER_BASE + 0x00000000U)
+#define TIMER2                           (TIMER_BASE + 0x00000400U)
+#define TIMER3                           (TIMER_BASE + 0x00000800U)
+#define TIMER4                           (TIMER_BASE + 0x00000C00U)
+#define TIMER5                           (TIMER_BASE + 0x00001000U)
+#define TIMER6                           (TIMER_BASE + 0x00001400U)
+#define TIMER7                           (TIMER_BASE + 0x00010400U)
+#define TIMER8                           (TIMER_BASE + 0x00014000U)
+#define TIMER9                           (TIMER_BASE + 0x00014400U)
+#define TIMER10                          (TIMER_BASE + 0x00014800U)
+#define TIMER11                          (TIMER_BASE + 0x00001800U)
+#define TIMER12                          (TIMER_BASE + 0x00001C00U)
+#define TIMER13                          (TIMER_BASE + 0x00002000U)
+
+/* registers definitions */
+#define TIMER_CTL0(timerx)               REG32((timerx) + 0x00U)           /*!< TIMER control register 0 */
+#define TIMER_CTL1(timerx)               REG32((timerx) + 0x04U)           /*!< TIMER control register 1 */
+#define TIMER_SMCFG(timerx)              REG32((timerx) + 0x08U)           /*!< TIMER slave mode configuration register */
+#define TIMER_DMAINTEN(timerx)           REG32((timerx) + 0x0CU)           /*!< TIMER DMA and interrupt enable register */
+#define TIMER_INTF(timerx)               REG32((timerx) + 0x10U)           /*!< TIMER interrupt flag register */
+#define TIMER_SWEVG(timerx)              REG32((timerx) + 0x14U)           /*!< TIMER software event generation register */
+#define TIMER_CHCTL0(timerx)             REG32((timerx) + 0x18U)           /*!< TIMER channel control register 0 */
+#define TIMER_CHCTL1(timerx)             REG32((timerx) + 0x1CU)           /*!< TIMER channel control register 1 */
+#define TIMER_CHCTL2(timerx)             REG32((timerx) + 0x20U)           /*!< TIMER channel control register 2 */
+#define TIMER_CNT(timerx)                REG32((timerx) + 0x24U)           /*!< TIMER counter register */
+#define TIMER_PSC(timerx)                REG32((timerx) + 0x28U)           /*!< TIMER prescaler register */
+#define TIMER_CAR(timerx)                REG32((timerx) + 0x2CU)           /*!< TIMER counter auto reload register */
+#define TIMER_CREP(timerx)               REG32((timerx) + 0x30U)           /*!< TIMER counter repetition register */
+#define TIMER_CH0CV(timerx)              REG32((timerx) + 0x34U)           /*!< TIMER channel 0 capture/compare value register */
+#define TIMER_CH1CV(timerx)              REG32((timerx) + 0x38U)           /*!< TIMER channel 1 capture/compare value register */
+#define TIMER_CH2CV(timerx)              REG32((timerx) + 0x3CU)           /*!< TIMER channel 2 capture/compare value register */
+#define TIMER_CH3CV(timerx)              REG32((timerx) + 0x40U)           /*!< TIMER channel 3 capture/compare value register */
+#define TIMER_CCHP(timerx)               REG32((timerx) + 0x44U)           /*!< TIMER complementary channel protection register */
+#define TIMER_DMACFG(timerx)             REG32((timerx) + 0x48U)           /*!< TIMER DMA configuration register */
+#define TIMER_DMATB(timerx)              REG32((timerx) + 0x4CU)           /*!< TIMER DMA transfer buffer register */
+#define TIMER_IRMP(timerx)               REG32((timerx) + 0x50U)           /*!< TIMER channel input remap register */
+#define TIMER_CFG(timerx)                REG32((timerx) + 0xFCU)           /*!< TIMER configuration register */
+
+/* bits definitions */
+/* TIMER_CTL0 */
+#define TIMER_CTL0_CEN                   BIT(0)              /*!< TIMER counter enable */
+#define TIMER_CTL0_UPDIS                 BIT(1)              /*!< update disable */
+#define TIMER_CTL0_UPS                   BIT(2)              /*!< update source */
+#define TIMER_CTL0_SPM                   BIT(3)              /*!< single pulse mode */
+#define TIMER_CTL0_DIR                   BIT(4)              /*!< timer counter direction */
+#define TIMER_CTL0_CAM                   BITS(5,6)           /*!< center-aligned mode selection */
+#define TIMER_CTL0_ARSE                  BIT(7)              /*!< auto-reload shadow enable */
+#define TIMER_CTL0_CKDIV                 BITS(8,9)           /*!< clock division */
+
+/* TIMER_CTL1 */
+#define TIMER_CTL1_CCSE                  BIT(0)              /*!< capture/compare control shadow register enable */
+#define TIMER_CTL1_CCUC                  BIT(2)              /*!< capture/compare control shadow register update control */
+#define TIMER_CTL1_DMAS                  BIT(3)              /*!< DMA request source selection */
+#define TIMER_CTL1_MMC                   BITS(4,6)           /*!< master mode control */
+#define TIMER_CTL1_TI0S                  BIT(7)              /*!< channel 0 trigger input selection(hall mode selection) */
+#define TIMER_CTL1_ISO0                  BIT(8)              /*!< idle state of channel 0 output */
+#define TIMER_CTL1_ISO0N                 BIT(9)              /*!< idle state of channel 0 complementary output */
+#define TIMER_CTL1_ISO1                  BIT(10)             /*!< idle state of channel 1 output */
+#define TIMER_CTL1_ISO1N                 BIT(11)             /*!< idle state of channel 1 complementary output */
+#define TIMER_CTL1_ISO2                  BIT(12)             /*!< idle state of channel 2 output */
+#define TIMER_CTL1_ISO2N                 BIT(13)             /*!< idle state of channel 2 complementary output */
+#define TIMER_CTL1_ISO3                  BIT(14)             /*!< idle state of channel 3 output */
+
+/* TIMER_SMCFG */
+#define TIMER_SMCFG_SMC                  BITS(0,2)           /*!< slave mode control */
+#define TIMER_SMCFG_TRGS                 BITS(4,6)           /*!< trigger selection */
+#define TIMER_SMCFG_MSM                  BIT(7)              /*!< master-slave mode */
+#define TIMER_SMCFG_ETFC                 BITS(8,11)          /*!< external trigger filter control */
+#define TIMER_SMCFG_ETPSC                BITS(12,13)         /*!< external trigger prescaler */
+#define TIMER_SMCFG_SMC1                 BIT(14)             /*!< part of SMC for enable external clock mode 1 */
+#define TIMER_SMCFG_ETP                  BIT(15)             /*!< external trigger polarity */
+ 
+/* TIMER_DMAINTEN */
+#define TIMER_DMAINTEN_UPIE              BIT(0)              /*!< update interrupt enable */
+#define TIMER_DMAINTEN_CH0IE             BIT(1)              /*!< channel 0 interrupt enable */
+#define TIMER_DMAINTEN_CH1IE             BIT(2)              /*!< channel 1 interrupt enable */
+#define TIMER_DMAINTEN_CH2IE             BIT(3)              /*!< channel 2 interrupt enable */
+#define TIMER_DMAINTEN_CH3IE             BIT(4)              /*!< channel 3 interrupt enable */
+#define TIMER_DMAINTEN_CMTIE             BIT(5)              /*!< commutation DMA request enable */
+#define TIMER_DMAINTEN_TRGIE             BIT(6)              /*!< trigger interrupt enable */
+#define TIMER_DMAINTEN_BRKIE             BIT(7)              /*!< break interrupt enable */
+#define TIMER_DMAINTEN_UPDEN             BIT(8)              /*!< update DMA request enable */
+#define TIMER_DMAINTEN_CH0DEN            BIT(8)              /*!< channel 0 DMA request enable */
+#define TIMER_DMAINTEN_CH1DEN            BIT(10)             /*!< channel 1 DMA request enable */
+#define TIMER_DMAINTEN_CH2DEN            BIT(11)             /*!< channel 2 DMA request enable */
+#define TIMER_DMAINTEN_CH3DEN            BIT(12)             /*!< channel 3 DMA request enable */
+#define TIMER_DMAINTEN_CMTDEN            BIT(13)             /*!< channel control update DMA request enable */
+#define TIMER_DMAINTEN_TRGDEN            BIT(14)             /*!< trigger DMA request enable */
+
+/* TIMER_INTF */
+#define TIMER_INTF_UPIF                  BIT(0)              /*!< update interrupt flag */
+#define TIMER_INTF_CH0IF                 BIT(1)              /*!< channel 0 interrupt flag */
+#define TIMER_INTF_CH1IF                 BIT(2)              /*!< channel 1 interrupt flag */
+#define TIMER_INTF_CH2IF                 BIT(3)              /*!< channel 2 interrupt flag */
+#define TIMER_INTF_CH3IF                 BIT(4)              /*!< channel 3 interrupt flag */
+#define TIMER_INTF_CMTIF                 BIT(5)              /*!< channel commutation interrupt flag */
+#define TIMER_INTF_TRGIF                 BIT(6)              /*!< trigger interrupt flag */
+#define TIMER_INTF_BRKIF                 BIT(7)              /*!< break interrupt flag */
+#define TIMER_INTF_CH0OF                 BIT(9)              /*!< channel 0 overcapture flag */
+#define TIMER_INTF_CH1OF                 BIT(10)             /*!< channel 1 overcapture flag */
+#define TIMER_INTF_CH2OF                 BIT(11)             /*!< channel 2 overcapture flag */
+#define TIMER_INTF_CH3OF                 BIT(12)             /*!< channel 3 overcapture flag */
+
+/* TIMER_SWEVG */
+#define TIMER_SWEVG_UPG                  BIT(0)              /*!< update event generate */
+#define TIMER_SWEVG_CH0G                 BIT(1)              /*!< channel 0 capture or compare event generation */
+#define TIMER_SWEVG_CH1G                 BIT(2)              /*!< channel 1 capture or compare event generation */
+#define TIMER_SWEVG_CH2G                 BIT(3)              /*!< channel 2 capture or compare event generation */
+#define TIMER_SWEVG_CH3G                 BIT(4)              /*!< channel 3 capture or compare event generation */
+#define TIMER_SWEVG_CMTG                 BIT(5)              /*!< channel commutation event generation */
+#define TIMER_SWEVG_TRGG                 BIT(6)              /*!< trigger event generation */
+#define TIMER_SWEVG_BRKG                 BIT(7)              /*!< break event generation */
+
+/* TIMER_CHCTL0 */
+/* output compare mode */
+#define TIMER_CHCTL0_CH0MS               BITS(0,1)           /*!< channel 0 mode selection */
+#define TIMER_CHCTL0_CH0COMFEN           BIT(2)              /*!< channel 0 output compare fast enable */
+#define TIMER_CHCTL0_CH0COMSEN           BIT(3)              /*!< channel 0 output compare shadow enable */
+#define TIMER_CHCTL0_CH0COMCTL           BITS(4,6)           /*!< channel 0 output compare mode */
+#define TIMER_CHCTL0_CH0COMCEN           BIT(7)              /*!< channel 0 output compare clear enable */
+#define TIMER_CHCTL0_CH1MS               BITS(8,9)           /*!< channel 1 mode selection */
+#define TIMER_CHCTL0_CH1COMFEN           BIT(10)             /*!< channel 1 output compare fast enable */
+#define TIMER_CHCTL0_CH1COMSEN           BIT(11)             /*!< channel 1 output compare shadow enable */
+#define TIMER_CHCTL0_CH1COMCTL           BITS(12,14)         /*!< channel 1 output compare mode */
+#define TIMER_CHCTL0_CH1COMCEN           BIT(15)             /*!< channel 1 output compare clear enable */
+/* input capture mode */
+#define TIMER_CHCTL0_CH0CAPPSC           BITS(2,3)           /*!< channel 0 input capture prescaler */
+#define TIMER_CHCTL0_CH0CAPFLT           BITS(4,7)           /*!< channel 0 input capture filter control */
+#define TIMER_CHCTL0_CH1CAPPSC           BITS(10,11)         /*!< channel 1 input capture prescaler */
+#define TIMER_CHCTL0_CH1CAPFLT           BITS(12,15)         /*!< channel 1 input capture filter control */
+
+/* TIMER_CHCTL1 */
+/* output compare mode */
+#define TIMER_CHCTL1_CH2MS               BITS(0,1)           /*!< channel 2 mode selection */
+#define TIMER_CHCTL1_CH2COMFEN           BIT(2)              /*!< channel 2 output compare fast enable */
+#define TIMER_CHCTL1_CH2COMSEN           BIT(3)              /*!< channel 2 output compare shadow enable */
+#define TIMER_CHCTL1_CH2COMCTL           BITS(4,6)           /*!< channel 2 output compare mode */
+#define TIMER_CHCTL1_CH2COMCEN           BIT(7)              /*!< channel 2 output compare clear enable */
+#define TIMER_CHCTL1_CH3MS               BITS(8,9)           /*!< channel 3 mode selection */
+#define TIMER_CHCTL1_CH3COMFEN           BIT(10)             /*!< channel 3 output compare fast enable */
+#define TIMER_CHCTL1_CH3COMSEN           BIT(11)             /*!< channel 3 output compare shadow enable */
+#define TIMER_CHCTL1_CH3COMCTL           BITS(12,14)         /*!< channel 3 output compare mode */
+#define TIMER_CHCTL1_CH3COMCEN           BIT(15)             /*!< channel 3 output compare clear enable */
+/* input capture mode */
+#define TIMER_CHCTL1_CH2CAPPSC           BITS(2,3)           /*!< channel 2 input capture prescaler */
+#define TIMER_CHCTL1_CH2CAPFLT           BITS(4,7)           /*!< channel 2 input capture filter control */
+#define TIMER_CHCTL1_CH3CAPPSC           BITS(10,11)         /*!< channel 3 input capture prescaler */
+#define TIMER_CHCTL1_CH3CAPFLT           BITS(12,15)         /*!< channel 3 input capture filter control */
+
+/* TIMER_CHCTL2 */
+#define TIMER_CHCTL2_CH0EN               BIT(0)              /*!< channel 0 enable */
+#define TIMER_CHCTL2_CH0P                BIT(1)              /*!< channel 0 polarity */
+#define TIMER_CHCTL2_CH0NEN              BIT(2)              /*!< channel 0 complementary output enable */
+#define TIMER_CHCTL2_CH0NP               BIT(3)              /*!< channel 0 complementary output polarity */
+#define TIMER_CHCTL2_CH1EN               BIT(4)              /*!< channel 1 enable  */
+#define TIMER_CHCTL2_CH1P                BIT(5)              /*!< channel 1 polarity */
+#define TIMER_CHCTL2_CH1NEN              BIT(6)              /*!< channel 1 complementary output enable */
+#define TIMER_CHCTL2_CH1NP               BIT(7)              /*!< channel 1 complementary output polarity */
+#define TIMER_CHCTL2_CH2EN               BIT(8)              /*!< channel 2 enable  */
+#define TIMER_CHCTL2_CH2P                BIT(9)              /*!< channel 2 polarity */
+#define TIMER_CHCTL2_CH2NEN              BIT(10)             /*!< channel 2 complementary output enable */
+#define TIMER_CHCTL2_CH2NP               BIT(11)             /*!< channel 2 complementary output polarity */
+#define TIMER_CHCTL2_CH3EN               BIT(12)             /*!< channel 3 enable  */
+#define TIMER_CHCTL2_CH3P                BIT(13)             /*!< channel 3 polarity */
+
+/* TIMER_CNT */
+#define TIMER_CNT_CNT16                  BITS(0,15)          /*!< 16 bit timer counter */
+#define TIMER_CNT_CNT32                  BITS(0,31)          /*!< 32 bit(TIMER1,TIMER4) timer counter */
+
+/* TIMER_PSC */
+#define TIMER_PSC_PSC                    BITS(0,15)          /*!< prescaler value of the counter clock */
+
+/* TIMER_CAR */
+#define TIMER_CAR_CARL16                 BITS(0,15)          /*!< 16 bit counter auto reload value */
+#define TIMER_CAR_CARL32                 BITS(0,31)          /*!< 32 bit(TIMER1,TIMER4) counter auto reload value */
+
+/* TIMER_CREP */
+#define TIMER_CREP_CREP                  BITS(0,7)           /*!< counter repetition value */
+
+/* TIMER_CH0CV */
+#define TIMER_CH0CV_CH0VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 0 */
+#define TIMER_CH0CV_CH0VAL32             BITS(0,31)          /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 0 */
+
+/* TIMER_CH1CV */
+#define TIMER_CH1CV_CH0VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 1 */
+#define TIMER_CH1CV_CH0VAL32             BITS(0,31)          /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 1 */
+
+/* TIMER_CH2CV */
+#define TIMER_CH2CV_CH0VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 2 */
+#define TIMER_CH2CV_CH0VAL32             BITS(0,31)          /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 2 */
+
+/* TIMER_CH3CV */
+#define TIMER_CH3CV_CH0VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 3 */
+#define TIMER_CH3CV_CH0VAL32             BITS(0,31)          /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 3 */
+
+/* TIMER_CCHP */
+#define TIMER_CCHP_DTCFG                 BITS(0,7)           /*!< dead time configure */
+#define TIMER_CCHP_PROT                  BITS(8,9)           /*!< complementary register protect control */
+#define TIMER_CCHP_IOS                   BIT(10)             /*!< idle mode off-state configure */
+#define TIMER_CCHP_ROS                   BIT(11)             /*!< run mode off-state configure */
+#define TIMER_CCHP_BRKEN                 BIT(12)             /*!< break enable */
+#define TIMER_CCHP_BRKP                  BIT(13)             /*!< break polarity */
+#define TIMER_CCHP_OAEN                  BIT(14)             /*!< output automatic enable */
+#define TIMER_CCHP_POEN                  BIT(15)             /*!< primary output enable */
+
+/* TIMER_DMACFG */
+#define TIMER_DMACFG_DMATA               BITS(0,4)           /*!< DMA transfer access start address */
+#define TIMER_DMACFG_DMATC               BITS(8,12)          /*!< DMA transfer count */
+
+/* TIMER_DMATB */
+#define TIMER_DMATB_DMATB                BITS(0,15)          /*!< DMA transfer buffer address */
+
+/* TIMER_IRMP */
+#define TIMER1_IRMP_ITI1_RMP             BITS(10,11)         /*!< TIMER1 internal trigger input 1 remap */
+#define TIMER4_IRMP_CI3_RMP              BITS(6,7)           /*!< TIMER4 channel 3 input remap */
+#define TIMER10_IRMP_ITI1_RMP            BITS(0,1)           /*!< TIMER10 internal trigger input 1 remap */
+
+/* TIMER_CFG */
+#define TIMER_CFG_OUTSEL                 BIT(0)              /*!< the output value selection */
+#define TIMER_CFG_CHVSEL                 BIT(1)              /*!< write CHxVAL register selection */
+
+/* constants definitions */
+/* TIMER init parameter struct definitions*/
+typedef struct
+{ 
+    uint16_t prescaler;                         /*!< prescaler value */
+    uint16_t alignedmode;                       /*!< aligned mode */
+    uint16_t counterdirection;                  /*!< counter direction */
+    uint32_t period;                            /*!< period value */
+    uint16_t clockdivision;                     /*!< clock division value */
+    uint8_t  repetitioncounter;                 /*!< the counter repetition value */
+}timer_parameter_struct;
+
+/* break parameter struct definitions*/
+typedef struct
+{ 
+    uint16_t runoffstate;                          /*!< run mode off-state */
+    uint32_t ideloffstate;                          /*!< idle mode off-state */
+    uint16_t deadtime;                          /*!< delay time between the switching off and on of the outputs */
+    uint16_t breakpolarity;                     /*!< break polarity */
+    uint16_t outputautostate;                           /*!< output automatic enable */
+    uint16_t protectmode;                          /*!< complementary register protect control */
+    uint16_t breakstate;                             /*!< break enable */
+}timer_break_parameter_struct;
+
+/* channel output parameter struct definitions */
+typedef struct
+{ 
+    uint32_t outputstate;                       /*!< channel output state */
+    uint16_t outputnstate;                      /*!< channel complementary output state */
+    uint16_t ocpolarity;                        /*!< channel output polarity */
+    uint16_t ocnpolarity;                       /*!< channel complementary output polarity */
+    uint16_t ocidlestate;                       /*!< idle state of channel output */
+    uint16_t ocnidlestate;                      /*!< idle state of channel complementary output */
+}timer_oc_parameter_struct;
+
+/* channel input parameter struct definitions */
+typedef struct
+{ 
+    uint16_t icpolarity;                        /*!< channel input polarity */
+    uint16_t icselection;                       /*!< channel input mode selection */
+    uint16_t icprescaler;                       /*!< channel input capture prescaler */
+    uint16_t icfilter;                          /*!< channel input capture filter control */
+}timer_ic_parameter_struct;
+
+/* TIMER interrupt source */
+#define TIMER_INT_UP                        ((uint32_t)0x00000001U)                 /*!< update interrupt */
+#define TIMER_INT_CH0                       ((uint32_t)0x00000002U)                 /*!< channel 0 interrupt */
+#define TIMER_INT_CH1                       ((uint32_t)0x00000004U)                 /*!< channel 1 interrupt */
+#define TIMER_INT_CH2                       ((uint32_t)0x00000008U)                 /*!< channel 2 interrupt */
+#define TIMER_INT_CH3                       ((uint32_t)0x00000010U)                 /*!< channel 3 interrupt */
+#define TIMER_INT_CMT                       ((uint32_t)0x00000020U)                 /*!< channel commutation interrupt flag */
+#define TIMER_INT_TRG                       ((uint32_t)0x00000040U)                 /*!< trigger interrupt */
+#define TIMER_INT_BRK                       ((uint32_t)0x00000080U)                 /*!< break interrupt */
+
+/* TIMER flag */
+#define TIMER_FLAG_UP                       ((uint32_t)0x00000001U)                 /*!< update flag */
+#define TIMER_FLAG_CH0                      ((uint32_t)0x00000002U)                 /*!< channel 0 flag */
+#define TIMER_FLAG_CH1                      ((uint32_t)0x00000004U)                 /*!< channel 1 flag */
+#define TIMER_FLAG_CH2                      ((uint32_t)0x00000008U)                 /*!< channel 2 flag */
+#define TIMER_FLAG_CH3                      ((uint32_t)0x00000010U)                 /*!< channel 3 flag */
+#define TIMER_FLAG_CMT                      ((uint32_t)0x00000020U)                 /*!< channel control update flag */
+#define TIMER_FLAG_TRG                      ((uint32_t)0x00000040U)                 /*!< trigger flag */
+#define TIMER_FLAG_BRK                      ((uint32_t)0x00000080U)                 /*!< break flag */
+#define TIMER_FLAG_CH0OF                    ((uint32_t)0x00000200U)                 /*!< channel 0 overcapture flag */
+#define TIMER_FLAG_CH1OF                    ((uint32_t)0x00000400U)                 /*!< channel 1 overcapture flag */
+#define TIMER_FLAG_CH2OF                    ((uint32_t)0x00000800U)                 /*!< channel 2 overcapture flag */
+#define TIMER_FLAG_CH3OF                    ((uint32_t)0x00001000U)                 /*!< channel 3 overcapture flag */
+
+/* TIMER DMA source enable */
+#define TIMER_DMA_UPD                       ((uint16_t)0x0100U)                     /*!< update DMA enable */
+#define TIMER_DMA_CH0D                      ((uint16_t)0x0200U)                     /*!< channel 0 DMA enable */
+#define TIMER_DMA_CH1D                      ((uint16_t)0x0400U)                     /*!< channel 1 DMA enable */
+#define TIMER_DMA_CH2D                      ((uint16_t)0x0800U)                     /*!< channel 2 DMA enable */
+#define TIMER_DMA_CH3D                      ((uint16_t)0x1000U)                     /*!< channel 3 DMA enable */
+#define TIMER_DMA_CMTD                      ((uint16_t)0x2000U)                     /*!< commutation DMA request enable */
+#define TIMER_DMA_TRGD                      ((uint16_t)0x4000U)                     /*!< trigger DMA enable */
+
+/* channel DMA request source selection */ 
+#define TIMER_DMAREQUEST_UPDATEEVENT        ((uint8_t)0x00U)                        /*!< DMA request of channel y is sent when update event occurs */
+#define TIMER_DMAREQUEST_CHANNELEVENT       ((uint8_t)0x01U)                        /*!< DMA request of channel y is sent when channel y event occurs */
+
+/* DMA access base address */
+#define DMACFG_DMATA(regval)                (BITS(0, 4) & ((uint32_t)(regval) << 0U))
+#define TIMER_DMACFG_DMATA_CTL0             DMACFG_DMATA(0)                         /*!< DMA transfer address is TIMER_CTL0 */
+#define TIMER_DMACFG_DMATA_CTL1             DMACFG_DMATA(1)                         /*!< DMA transfer address is TIMER_CTL1 */
+#define TIMER_DMACFG_DMATA_SMCFG            DMACFG_DMATA(2)                         /*!< DMA transfer address is TIMER_SMCFG */
+#define TIMER_DMACFG_DMATA_DMAINTEN         DMACFG_DMATA(3)                         /*!< DMA transfer address is TIMER_DMAINTEN */
+#define TIMER_DMACFG_DMATA_INTF             DMACFG_DMATA(4)                         /*!< DMA transfer address is TIMER_INTF */
+#define TIMER_DMACFG_DMATA_SWEVG            DMACFG_DMATA(5)                         /*!< DMA transfer address is TIMER_SWEVG */
+#define TIMER_DMACFG_DMATA_CHCTL0           DMACFG_DMATA(6)                         /*!< DMA transfer address is TIMER_CHCTL0 */
+#define TIMER_DMACFG_DMATA_CHCTL1           DMACFG_DMATA(7)                         /*!< DMA transfer address is TIMER_CHCTL1 */
+#define TIMER_DMACFG_DMATA_CHCTL2           DMACFG_DMATA(8)                         /*!< DMA transfer address is TIMER_CHCTL2 */
+#define TIMER_DMACFG_DMATA_CNT              DMACFG_DMATA(9)                         /*!< DMA transfer address is TIMER_CNT */
+#define TIMER_DMACFG_DMATA_PSC              DMACFG_DMATA(10)                        /*!< DMA transfer address is TIMER_PSC */
+#define TIMER_DMACFG_DMATA_CAR              DMACFG_DMATA(11)                        /*!< DMA transfer address is TIMER_CAR */
+#define TIMER_DMACFG_DMATA_CREP             DMACFG_DMATA(12)                        /*!< DMA transfer address is TIMER_CREP */
+#define TIMER_DMACFG_DMATA_CH0CV            DMACFG_DMATA(13)                        /*!< DMA transfer address is TIMER_CH0CV */
+#define TIMER_DMACFG_DMATA_CH1CV            DMACFG_DMATA(14)                        /*!< DMA transfer address is TIMER_CH1CV */
+#define TIMER_DMACFG_DMATA_CH2CV            DMACFG_DMATA(15)                        /*!< DMA transfer address is TIMER_CH2CV */
+#define TIMER_DMACFG_DMATA_CH3CV            DMACFG_DMATA(16)                        /*!< DMA transfer address is TIMER_CH3CV */
+#define TIMER_DMACFG_DMATA_CCHP             DMACFG_DMATA(17)                        /*!< DMA transfer address is TIMER_CCHP */
+#define TIMER_DMACFG_DMATA_DMACFG           DMACFG_DMATA(18)                        /*!< DMA transfer address is TIMER_DMACFG */
+#define TIMER_DMACFG_DMATA_DMATB            DMACFG_DMATA(19)                        /*!< DMA transfer address is TIMER_DMATB */
+
+/* DMA access burst length */
+#define DMACFG_DMATC(regval)                (BITS(8, 12) & ((uint32_t)(regval) << 8U))
+#define TIMER_DMACFG_DMATC_1TRANSFER        DMACFG_DMATC(0)                         /*!< DMA transfer 1 time */
+#define TIMER_DMACFG_DMATC_2TRANSFER        DMACFG_DMATC(1)                         /*!< DMA transfer 2 times */
+#define TIMER_DMACFG_DMATC_3TRANSFER        DMACFG_DMATC(2)                         /*!< DMA transfer 3 times */
+#define TIMER_DMACFG_DMATC_4TRANSFER        DMACFG_DMATC(3)                         /*!< DMA transfer 4 times */
+#define TIMER_DMACFG_DMATC_5TRANSFER        DMACFG_DMATC(4)                         /*!< DMA transfer 5 times */
+#define TIMER_DMACFG_DMATC_6TRANSFER        DMACFG_DMATC(5)                         /*!< DMA transfer 6 times */
+#define TIMER_DMACFG_DMATC_7TRANSFER        DMACFG_DMATC(6)                         /*!< DMA transfer 7 times */
+#define TIMER_DMACFG_DMATC_8TRANSFER        DMACFG_DMATC(7)                         /*!< DMA transfer 8 times */
+#define TIMER_DMACFG_DMATC_9TRANSFER        DMACFG_DMATC(8)                         /*!< DMA transfer 9 times */
+#define TIMER_DMACFG_DMATC_10TRANSFER       DMACFG_DMATC(9)                         /*!< DMA transfer 10 times */
+#define TIMER_DMACFG_DMATC_11TRANSFER       DMACFG_DMATC(10)                        /*!< DMA transfer 11 times */
+#define TIMER_DMACFG_DMATC_12TRANSFER       DMACFG_DMATC(11)                        /*!< DMA transfer 12 times */
+#define TIMER_DMACFG_DMATC_13TRANSFER       DMACFG_DMATC(12)                        /*!< DMA transfer 13 times */
+#define TIMER_DMACFG_DMATC_14TRANSFER       DMACFG_DMATC(13)                        /*!< DMA transfer 14 times */
+#define TIMER_DMACFG_DMATC_15TRANSFER       DMACFG_DMATC(14)                        /*!< DMA transfer 15 times */
+#define TIMER_DMACFG_DMATC_16TRANSFER       DMACFG_DMATC(15)                        /*!< DMA transfer 16 times */
+#define TIMER_DMACFG_DMATC_17TRANSFER       DMACFG_DMATC(16)                        /*!< DMA transfer 17 times */
+#define TIMER_DMACFG_DMATC_18TRANSFER       DMACFG_DMATC(17)                        /*!< DMA transfer 18 times */
+
+/* TIMER software event generation source */
+#define TIMER_EVENT_SRC_UPG                 ((uint16_t)0x0001U)                     /*!< update event generation */
+#define TIMER_EVENT_SRC_CH0G                ((uint16_t)0x0002U)                     /*!< channel 0 capture or compare event generation */
+#define TIMER_EVENT_SRC_CH1G                ((uint16_t)0x0004U)                     /*!< channel 1 capture or compare event generation */
+#define TIMER_EVENT_SRC_CH2G                ((uint16_t)0x0008U)                     /*!< channel 2 capture or compare event generation */
+#define TIMER_EVENT_SRC_CH3G                ((uint16_t)0x0010U)                     /*!< channel 3 capture or compare event generation */
+#define TIMER_EVENT_SRC_CMTG                ((uint16_t)0x0020U)                     /*!< channel commutation event generation */
+#define TIMER_EVENT_SRC_TRGG                ((uint16_t)0x0040U)                     /*!< trigger event generation */
+#define TIMER_EVENT_SRC_BRKG                ((uint16_t)0x0080U)                     /*!< break event generation */
+
+/* center-aligned mode selection */
+#define CTL0_CAM(regval)                    ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U)))
+#define TIMER_COUNTER_EDGE                  CTL0_CAM(0)                             /*!< edge-aligned mode */
+#define TIMER_COUNTER_CENTER_DOWN           CTL0_CAM(1)                             /*!< center-aligned and counting down assert mode */
+#define TIMER_COUNTER_CENTER_UP             CTL0_CAM(2)                             /*!< center-aligned and counting up assert mode */
+#define TIMER_COUNTER_CENTER_BOTH           CTL0_CAM(3)                             /*!< center-aligned and counting up/down assert mode */
+
+/* TIMER prescaler reload mode */
+#define TIMER_PSC_RELOAD_NOW                ((uint8_t)0x00U)                        /*!< the prescaler is loaded right now */
+#define TIMER_PSC_RELOAD_UPDATE             ((uint8_t)0x01U)                        /*!< the prescaler is loaded at the next update event */
+
+/* count direction */
+#define TIMER_COUNTER_UP                    ((uint16_t)0x0000U)                     /*!< counter up direction */
+#define TIMER_COUNTER_DOWN                  ((uint16_t)0x0010U)                     /*!< counter down direction */
+
+/* specify division ratio between TIMER clock and dead-time and sampling clock */
+#define CTL0_CKDIV(regval)                  ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U)))
+#define TIMER_CKDIV_DIV1                    CTL0_CKDIV(0)                           /*!< clock division value is 1,fDTS=fTIMER_CK */
+#define TIMER_CKDIV_DIV2                    CTL0_CKDIV(1)                           /*!< clock division value is 2,fDTS= fTIMER_CK/2 */
+#define TIMER_CKDIV_DIV4                    CTL0_CKDIV(2)                           /*!< clock division value is 4, fDTS= fTIMER_CK/4 */
+
+/* single pulse mode */
+#define TIMER_SP_MODE_SINGLE                ((uint8_t)0x00U)                        /*!< single pulse mode */
+#define TIMER_SP_MODE_REPETITIVE            ((uint8_t)0x01U)                        /*!< repetitive pulse mode */
+
+/* update source */
+#define TIMER_UPDATE_SRC_REGULAR            ((uint8_t)0x00U)                        /*!< update generate only by counter overflow/underflow */
+#define TIMER_UPDATE_SRC_GLOBAL             ((uint8_t)0x01U)                        /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */
+
+/* run mode off-state configure */
+#define TIMER_ROS_STATE_ENABLE              ((uint32_t)0x00000800U)                 /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */
+#define TIMER_ROS_STATE_DISABLE             ((uint32_t)0x00000000U)                 /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are disabled */
+
+/* idle mode off-state configure */                                                 
+#define TIMER_IOS_STATE_ENABLE              ((uint16_t)0x0400U)                     /*!< when POEN bit is reset, he channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */
+#define TIMER_IOS_STATE_DISABLE             ((uint16_t)0x0000U)                     /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are disabled */
+
+/* break input polarity */
+#define TIMER_BREAK_POLARITY_LOW            ((uint16_t)0x0000U)                     /*!< break input polarity is low */
+#define TIMER_BREAK_POLARITY_HIGH           ((uint16_t)0x2000U)                     /*!< break input polarity is high */
+
+/* output automatic enable */
+#define TIMER_OUTAUTO_ENABLE                ((uint16_t)0x4000U)                     /*!< output automatic enable */
+#define TIMER_OUTAUTO_DISABLE               ((uint16_t)0x0000U)                     /*!< output automatic disable */
+
+/* complementary register protect control */
+#define CCHP_PROT(regval)                   ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U)))
+#define TIMER_CCHP_PROT_OFF                 CCHP_PROT(0)                            /*!< protect disable */
+#define TIMER_CCHP_PROT_0                   CCHP_PROT(1)                            /*!< PROT mode 0 */
+#define TIMER_CCHP_PROT_1                   CCHP_PROT(2)                            /*!< PROT mode 1 */
+#define TIMER_CCHP_PROT_2                   CCHP_PROT(3)                            /*!< PROT mode 2 */
+
+/* break input enable */
+#define TIMER_BREAK_ENABLE                  ((uint16_t)0x1000U)                     /*!< break input enable */
+#define TIMER_BREAK_DISABLE                 ((uint16_t)0x0000U)                     /*!< break input disable */
+
+/* TIMER channel y(y=0,1,2,3) */
+#define TIMER_CH_0                          ((uint16_t)0x0000U)                     /*!< TIMER channel 0(TIMERx(x=0..4,7..13)) */
+#define TIMER_CH_1                          ((uint16_t)0x0001U)                     /*!< TIMER channel 1(TIMERx(x=0..4,7,8,11)) */
+#define TIMER_CH_2                          ((uint16_t)0x0002U)                     /*!< TIMER channel 2(TIMERx(x=0..4,7)) */
+#define TIMER_CH_3                          ((uint16_t)0x0003U)                     /*!< TIMER channel 3(TIMERx(x=0..4,7)) */
+
+/* channel enable state*/
+#define TIMER_CCX_ENABLE                    ((uint32_t)0x00000001U)                 /*!< channel enable */
+#define TIMER_CCX_DISABLE                   ((uint32_t)0x00000000U)                 /*!< channel disable */
+
+/* channel complementary output enable state*/
+#define TIMER_CCXN_ENABLE                   ((uint16_t)0x0004U)                     /*!< channel complementary enable */
+#define TIMER_CCXN_DISABLE                  ((uint16_t)0x0000U)                     /*!< channel complementary disable */
+
+/* channel output polarity */
+#define TIMER_OC_POLARITY_HIGH              ((uint16_t)0x0000U)                     /*!< channel output polarity is high */
+#define TIMER_OC_POLARITY_LOW               ((uint16_t)0x0002U)                     /*!< channel output polarity is low */
+
+/* channel complementary output polarity */
+#define TIMER_OCN_POLARITY_HIGH             ((uint16_t)0x0000U)                     /*!< channel complementary output polarity is high */
+#define TIMER_OCN_POLARITY_LOW              ((uint16_t)0x0008U)                     /*!< channel complementary output polarity is low */
+
+/* idle state of channel output */ 
+#define TIMER_OC_IDLE_STATE_HIGH            ((uint16_t)0x0100)                      /*!< idle state of channel output is high */
+#define TIMER_OC_IDLE_STATE_LOW             ((uint16_t)0x0000)                      /*!< idle state of channel output is low */
+
+/* idle state of channel complementary output */ 
+#define TIMER_OCN_IDLE_STATE_HIGH           ((uint16_t)0x0200U)                     /*!< idle state of channel complementary output is high */
+#define TIMER_OCN_IDLE_STATE_LOW            ((uint16_t)0x0000U)                     /*!< idle state of channel complementary output is low */
+
+/* channel output compare mode */
+#define TIMER_OC_MODE_TIMING                ((uint16_t)0x0000U)                     /*!< timing mode */
+#define TIMER_OC_MODE_ACTIVE                ((uint16_t)0x0010U)                     /*!< active mode */
+#define TIMER_OC_MODE_INACTIVE              ((uint16_t)0x0020U)                     /*!< inactive mode */
+#define TIMER_OC_MODE_TOGGLE                ((uint16_t)0x0030U)                     /*!< toggle mode */
+#define TIMER_OC_MODE_LOW                   ((uint16_t)0x0040U)                     /*!< force low mode */
+#define TIMER_OC_MODE_HIGH                  ((uint16_t)0x0050U)                     /*!< force high mode */
+#define TIMER_OC_MODE_PWM0                  ((uint16_t)0x0060U)                     /*!< PWM0 mode */
+#define TIMER_OC_MODE_PWM1                  ((uint16_t)0x0070U)                     /*!< PWM1 mode*/
+
+/* channel output compare shadow enable */
+#define TIMER_OC_SHADOW_ENABLE              ((uint16_t)0x0008U)                     /*!< channel output shadow state enable */
+#define TIMER_OC_SHADOW_DISABLE             ((uint16_t)0x0000U)                     /*!< channel output shadow state disable */
+
+/* channel output compare fast enable */
+#define TIMER_OC_FAST_ENABLE                ((uint16_t)0x0004)                      /*!< channel output fast function enable */
+#define TIMER_OC_FAST_DISABLE               ((uint16_t)0x0000)                      /*!< channel output fast function disable */
+
+/* channel output compare clear enable. */
+#define TIMER_OC_CLEAR_ENABLE               ((uint16_t)0x0080U)                     /*!< channel output clear function enable */
+#define TIMER_OC_CLEAR_DISABLE              ((uint16_t)0x0000U)                     /*!< channel output clear function disable */
+
+/* channel control shadow register update control */ 
+#define TIMER_UPDATECTL_CCU                 ((uint8_t)0x00U)                        /*!< the shadow registers update by when CMTG bit is set */
+#define TIMER_UPDATECTL_CCUTRI              ((uint8_t)0x01U)                        /*!< the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs */
+
+/* channel input capture polarity */
+#define TIMER_IC_POLARITY_RISING            ((uint16_t)0x0000U)                     /*!< input capture rising edge */
+#define TIMER_IC_POLARITY_FALLING           ((uint16_t)0x0002U)                     /*!< input capture falling edge */
+#define TIMER_IC_POLARITY_BOTH_EDGE         ((uint16_t)0x000AU)                     /*!< input capture both edge */
+
+/* timer input capture selection */
+#define TIMER_IC_SELECTION_DIRECTTI         ((uint16_t)0x0001U)                     /*!< channel y is configured as input and icy is mapped on CIy */
+#define TIMER_IC_SELECTION_INDIRECTTI       ((uint16_t)0x0002U)                     /*!< channel y is configured as input and icy is mapped on opposite input */
+#define TIMER_IC_SELECTION_ITS              ((uint16_t)0x0003U)                     /*!< channel y is configured as input and icy is mapped on ITS */
+
+/* channel input capture prescaler */
+#define TIMER_IC_PSC_DIV1                   ((uint16_t)0x0000U)                     /*!< no prescaler */
+#define TIMER_IC_PSC_DIV2                   ((uint16_t)0x0004U)                     /*!< divided by 2 */
+#define TIMER_IC_PSC_DIV4                   ((uint16_t)0x0008U)                     /*!< divided by 4*/
+#define TIMER_IC_PSC_DIV8                   ((uint16_t)0x000CU)                     /*!< divided by 8 */
+
+/* trigger selection */
+#define SMCFG_TRGSEL(regval)                (BITS(4, 6) & ((uint32_t)(regval) << 4U))
+#define TIMER_SMCFG_TRGSEL_ITI0               SMCFG_TRGSEL(0)                         /*!< internal trigger 0 */
+#define TIMER_SMCFG_TRGSEL_ITI1               SMCFG_TRGSEL(1)                         /*!< internal trigger 1 */
+#define TIMER_SMCFG_TRGSEL_ITI2               SMCFG_TRGSEL(2)                         /*!< internal trigger 2 */
+#define TIMER_SMCFG_TRGSEL_ITI3               SMCFG_TRGSEL(3)                         /*!< internal trigger 3 */
+#define TIMER_SMCFG_TRGSEL_CI0F_ED            SMCFG_TRGSEL(4)                         /*!< TI0 Edge Detector */
+#define TIMER_SMCFG_TRGSEL_CI0FE0             SMCFG_TRGSEL(5)                         /*!< filtered TIMER input 0 */
+#define TIMER_SMCFG_TRGSEL_CI1FE1             SMCFG_TRGSEL(6)                         /*!< filtered TIMER input 1 */
+#define TIMER_SMCFG_TRGSEL_ETIFP              SMCFG_TRGSEL(7)                         /*!< external trigger */
+
+/* master mode control */
+#define CTL1_MMC(regval)                    (BITS(4, 6) & ((uint32_t)(regval) << 4U))
+#define TIMER_TRI_OUT_SRC_RESET             CTL1_MMC(0)                             /*!< the UPG bit as trigger output */
+#define TIMER_TRI_OUT_SRC_ENABLE            CTL1_MMC(1)                             /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */
+#define TIMER_TRI_OUT_SRC_UPDATE            CTL1_MMC(2)                             /*!< update event as trigger output */
+#define TIMER_TRI_OUT_SRC_CC0               CTL1_MMC(3)                             /*!< a capture or a compare match occurred in channal0 as trigger output TRGO */
+#define TIMER_TRI_OUT_SRC_O0CPRE            CTL1_MMC(4)                             /*!< O0CPRE as trigger output */
+#define TIMER_TRI_OUT_SRC_O1CPRE            CTL1_MMC(5)                             /*!< O1CPRE as trigger output */
+#define TIMER_TRI_OUT_SRC_O2CPRE            CTL1_MMC(6)                             /*!< O2CPRE as trigger output */
+#define TIMER_TRI_OUT_SRC_O3CPRE            CTL1_MMC(7)                             /*!< O3CPRE as trigger output */
+
+/* slave mode control */
+#define SMCFG_SMC(regval)                   (BITS(0, 2) & ((uint32_t)(regval) << 0U)) 
+#define TIMER_SLAVE_MODE_DISABLE            SMCFG_SMC(0)                            /*!< slave mode disable */
+#define TIMER_ENCODER_MODE0                 SMCFG_SMC(1)                            /*!< encoder mode 0 */
+#define TIMER_ENCODER_MODE1                 SMCFG_SMC(2)                            /*!< encoder mode 1 */
+#define TIMER_ENCODER_MODE2                 SMCFG_SMC(3)                            /*!< encoder mode 2 */
+#define TIMER_SLAVE_MODE_RESTART            SMCFG_SMC(4)                            /*!< restart mode */
+#define TIMER_SLAVE_MODE_PAUSE              SMCFG_SMC(5)                            /*!< pause mode */
+#define TIMER_SLAVE_MODE_EVENT              SMCFG_SMC(6)                            /*!< event mode */
+#define TIMER_SLAVE_MODE_EXTERNAL0          SMCFG_SMC(7)                            /*!< external clock mode 0 */
+
+/* master slave mode selection */ 
+#define TIMER_MASTER_SLAVE_MODE_ENABLE      ((uint8_t)0x00U)                         /*!< master slave mode enable */
+#define TIMER_MASTER_SLAVE_MODE_DISABLE     ((uint8_t)0x01U)                         /*!< master slave mode disable */
+
+/* external trigger prescaler */
+#define SMCFG_ETPSC(regval)                 (BITS(12, 13) & ((uint32_t)(regval) << 12U))
+#define TIMER_EXT_TRI_PSC_OFF               SMCFG_ETPSC(0)                          /*!< no divided */
+#define TIMER_EXT_TRI_PSC_DIV2              SMCFG_ETPSC(1)                          /*!< divided by 2 */
+#define TIMER_EXT_TRI_PSC_DIV4              SMCFG_ETPSC(2)                          /*!< divided by 4 */
+#define TIMER_EXT_TRI_PSC_DIV8              SMCFG_ETPSC(3)                          /*!< divided by 8 */
+
+/* external trigger polarity */
+#define TIMER_ETP_FALLING                   TIMER_SMCFG_ETP                         /*!< active low or falling edge active */
+#define TIMER_ETP_RISING                    ((uint32_t)0x00000000U)                 /*!< active high or rising edge active */
+
+/* channel 0 trigger input selection */ 
+#define TIMER_HALLINTERFACE_ENABLE          ((uint8_t)0x00U)                        /*!< TIMER hall sensor mode enable */
+#define TIMER_HALLINTERFACE_DISABLE         ((uint8_t)0x01U)                        /*!< TIMER hall sensor mode disable */
+
+/* timer1 internal trigger input1 remap */
+#define TIMER1_IRMP(regval)                 (BITS(10, 11) & ((uint32_t)(regval) << 10U))       
+#define TIMER1_ITI1_RMP_TIMER7_TRGO         TIMER1_IRMP(0)                          /*!< timer1 internal trigger input 1 remap to TIMER7_TRGO */
+#define TIMER1_ITI1_RMP_ETHERNET_PTP        TIMER1_IRMP(1)                          /*!< timer1 internal trigger input 1 remap to ethernet PTP */
+#define TIMER1_ITI1_RMP_USB_FS_SOF          TIMER1_IRMP(2)                          /*!< timer1 internal trigger input 1 remap to USB FS SOF */
+#define TIMER1_ITI1_RMP_USB_HS_SOF          TIMER1_IRMP(3)                          /*!< timer1 internal trigger input 1 remap to USB HS SOF */
+
+/* timer4 channel 3 input remap */
+#define TIMER4_IRMP(regval)                 (BITS(6, 7) & ((uint32_t)(regval) << 6U))          
+#define TIMER4_CI3_RMP_GPIO                 TIMER4_IRMP(0)                          /*!< timer4 channel 3 input remap to GPIO pin */
+#define TIMER4_CI3_RMP_IRC32K               TIMER4_IRMP(1)                          /*!< timer4 channel 3 input remap to IRC32K */
+#define TIMER4_CI3_RMP_LXTAL                TIMER4_IRMP(2)                          /*!< timer4 channel 3 input remap to  LXTAL */
+#define TIMER4_CI3_RMP_RTC_WAKEUP_INT       TIMER4_IRMP(3)                          /*!< timer4 channel 3 input remap to RTC wakeup interrupt */
+
+/* timer10 internal trigger input1 remap */
+#define TIMER10_IRMP(regval)                (BITS(0, 1) & ((uint32_t)(regval) << 0U))
+#define TIMER10_ITI1_RMP_GPIO               TIMER10_IRMP(0)                         /*!< timer10 internal trigger input1 remap based on GPIO setting */
+#define TIMER10_ITI1_RMP_RTC_HXTAL_DIV      TIMER10_IRMP(2)                         /*!< timer10 internal trigger input1 remap  HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) */
+
+/* timerx(x=0,1,2,13,14,15,16) write cc register selection */
+#define TIMER_CCSEL_DISABLE                 ((uint16_t)0x0000U)                     /*!< write CC register selection disable */
+#define TIMER_CCSEL_ENABLE                  ((uint16_t)0x0002U)                     /*!< write CC register selection enable */
+
+/* the output value selection */
+#define TIMER_OUTSEL_DISABLE                ((uint16_t)0x0000U)                     /*!< output value selection disable */
+#define TIMER_OUTSEL_ENABLE                 ((uint16_t)0x0001U)                     /*!< output value selection enable */
+
+/* function declarations */
+/* TIMER timebase*/
+/* deinit a TIMER */
+void timer_deinit(uint32_t timer_periph);
+/* initialize TIMER counter */
+void timer_init(uint32_t timer_periph, timer_parameter_struct* timer_initpara);
+/* enable a TIMER */
+void timer_enable(uint32_t timer_periph);
+/* disable a TIMER */
+void timer_disable(uint32_t timer_periph);
+/* enable the auto reload shadow function */
+void timer_auto_reload_shadow_enable(uint32_t timer_periph);
+/* disable the auto reload shadow function */
+void timer_auto_reload_shadow_disable(uint32_t timer_periph);
+/* enable the update event */
+void timer_update_event_enable(uint32_t timer_periph);
+/* disable the update event */
+void timer_update_event_disable(uint32_t timer_periph);
+/* set TIMER counter alignment mode */
+void timer_counter_alignment(uint32_t timer_periph,uint16_t timer_aligned);
+/* set TIMER counter up direction */
+void timer_counter_up_direction(uint32_t timer_periph);
+/* set TIMER counter down direction */
+void timer_counter_down_direction(uint32_t timer_periph);
+/* configure TIMER prescaler */
+void timer_prescaler_config(uint32_t timer_periph,uint16_t timer_prescaler,uint8_t timer_pscreload);
+/* configure TIMER repetition register value */
+void timer_repetition_value_config(uint32_t timer_periph,uint16_t timer_repetition);
+/* configure TIMER autoreload register value */
+void timer_autoreload_value_config(uint32_t timer_periph,uint32_t timer_autoreload);
+/* configure TIMER counter register value */
+void timer_counter_value_config(uint32_t timer_periph , uint32_t timer_counter);
+/* read TIMER counter value */
+uint32_t timer_counter_read(uint32_t timer_periph);
+/* read TIMER prescaler value */
+uint16_t timer_prescaler_read(uint32_t timer_periph);
+/* configure TIMER single pulse mode */
+void timer_single_pulse_mode_config(uint32_t timer_periph,uint8_t timer_spmode);
+/* configure TIMER update source */
+void timer_update_source_config(uint32_t timer_periph,uint8_t timer_update);
+
+/* TIMER interrupt and flag*/
+/* enable the TIMER interrupt */
+void timer_interrupt_enable(uint32_t timer_periph,uint32_t timer_interrupt);
+/* disable the TIMER interrupt */
+void timer_interrupt_disable(uint32_t timer_periph,uint32_t timer_interrupt);
+/* get timer interrupt flag */
+FlagStatus timer_interrupt_flag_get(uint32_t timer_periph,uint32_t timer_interrupt);
+/* clear TIMER interrupt flag */
+void timer_interrupt_flag_clear(uint32_t timer_periph,uint32_t timer_interrupt);
+/* get TIMER flags */
+FlagStatus timer_flag_get(uint32_t timer_periph , uint32_t timer_flag);
+/* clear TIMER flags */
+void timer_flag_clear(uint32_t timer_periph , uint32_t timer_flag);
+
+/* timer DMA and event*/
+/* enable the TIMER DMA */
+void timer_dma_enable(uint32_t timer_periph,uint16_t timer_dma);
+/* disable the TIMER DMA */
+void timer_dma_disable(uint32_t timer_periph,uint16_t timer_dma);
+/* channel DMA request source selection */
+void timer_channel_dma_request_source_select(uint32_t timer_periph,uint8_t dma_request);
+/* configure the TIMER DMA transfer */
+void timer_dma_transfer_config(uint32_t timer_periph,uint32_t dma_baseaddr,uint32_t dma_lenth);
+/* software generate events */
+void timer_event_software_generate(uint32_t timer_periph,uint16_t timer_event);
+
+/* timer channel complementary protection */
+/* configure TIMER break function */
+void timer_break_config(uint32_t timer_periph,timer_break_parameter_struct* timer_bkdtpara);
+/* enable TIMER break function */
+void timer_break_enable(uint32_t timer_periph);
+/* disable TIMER break function */
+void timer_break_disable(uint32_t timer_periph);
+/* enable TIMER output automatic function */
+void timer_automatic_output_enable(uint32_t timer_periph);
+/* disable TIMER output automatic function */
+void timer_automatic_output_disable(uint32_t timer_periph);
+/* configure TIMER primary output function */
+void timer_primary_output_config(uint32_t timer_periph,ControlStatus newvalue);
+/* channel capture/compare control shadow register enable */
+void timer_channel_control_shadow_config(uint32_t timer_periph,ControlStatus newvalue);
+/* configure TIMER channel control shadow register update control */
+void timer_channel_control_shadow_update_config(uint32_t timer_periph,uint8_t timer_ccuctl);
+
+/* TIMER channel output */
+/* configure TIMER channel output function */
+void timer_channel_output_config(uint32_t timer_periph,uint16_t timer_channel,timer_oc_parameter_struct* timer_ocpara);
+/* configure TIMER channel output compare mode */
+void timer_channel_output_mode_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocmode);
+/* configure TIMER channel output pulse value */
+void timer_channel_output_pulse_value_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_pluse);
+/* configure TIMER channel output shadow function */
+void timer_channel_output_shadow_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocshadow);
+/* configure TIMER channel output fast function */
+void timer_channel_output_fast_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocfast);
+/* configure TIMER channel output clear function */
+void timer_channel_output_clear_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_occlear);
+/* configure TIMER channel output polarity */
+void timer_channel_output_polarity_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocpolarity);
+/* configure TIMER channel complementary output polarity */
+void timer_channel_complementary_output_polarity_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocnpolarity);
+/* configure TIMER channel enable state */
+void timer_channel_output_state_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_state);
+/* configure TIMER channel complementary output enable state */
+void timer_channel_complementary_output_state_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocnstate);
+
+/* TIMER channel input */
+/* configure TIMER input capture parameter */
+void timer_input_capture_config(uint32_t timer_periph,uint16_t timer_channel,timer_ic_parameter_struct* timer_icpara);
+/* configure TIMER channel input capture prescaler value */
+void timer_channel_input_capture_prescaler_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_prescaler);
+/* read TIMER channel capture compare register value */
+uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph,uint16_t timer_channel);
+/* configure TIMER input pwm capture function */
+void timer_input_pwm_capture_config(uint32_t timer_periph,uint16_t timer_channel,timer_ic_parameter_struct* timer_icpwm);
+/* configure TIMER hall sensor mode */
+void timer_hall_mode_config(uint32_t timer_periph,uint8_t timer_hallmode);
+
+/* TIMER master and slave */
+/* select TIMER input trigger source */
+void timer_input_trigger_source_select(uint32_t timer_periph,uint32_t timer_intrigger);
+/* select TIMER master mode output trigger source */
+void timer_master_output_trigger_source_select(uint32_t timer_periph,uint32_t timer_outrigger);
+/* select TIMER slave mode */
+void timer_slave_mode_select(uint32_t timer_periph,uint32_t timer_slavemode);
+/* configure TIMER master slave mode */
+void timer_master_slave_mode_config(uint32_t timer_periph,uint8_t timer_masterslave);
+/* configure TIMER external trigger input */
+void timer_external_trigger_config(uint32_t timer_periph,uint32_t timer_extprescaler,uint32_t timer_expolarity,uint32_t timer_extfilter);
+/* configure TIMER quadrature decoder mode */
+void timer_quadrature_decoder_mode_config(uint32_t timer_periph,uint32_t timer_decomode,uint16_t timer_ic0polarity,uint16_t timer_ic1polarity);
+/* configure TIMER internal clock mode */
+void timer_internal_clock_config(uint32_t timer_periph);
+/* configure TIMER the internal trigger as external clock input */
+void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t timer_intrigger);
+/* configure TIMER the external trigger as external clock input */
+void timer_external_trigger_as_external_clock_config(uint32_t timer_periph,uint32_t timer_extrigger,uint16_t timer_expolarity,uint32_t timer_extfilter);
+/* configure TIMER the external clock mode 0 */
+void timer_external_clock_mode0_config(uint32_t timer_periph,uint32_t timer_extprescaler,uint32_t timer_expolarity,uint32_t timer_extfilter);
+/* configure TIMER the external clock mode 1 */
+void timer_external_clock_mode1_config(uint32_t timer_periph,uint32_t timer_extprescaler,uint32_t timer_expolarity,uint32_t timer_extfilter);
+/* disable TIMER the external clock mode 1 */
+void timer_external_clock_mode1_disable(uint32_t timer_periph);
+/* configure TIMER1 channel 0 remap function */
+void timer_channel_remap_config(uint32_t timer_periph,uint32_t timer_remap);
+
+/* TIMER configure */
+/* configure TIMER write CHxVAL register selection */
+void timer_write_cc_register_config(uint32_t timer_periph, uint16_t timer_ccsel);
+/* configure TIMER output value selection */
+void timer_output_value_selection_config(uint32_t timer_periph, uint16_t timer_outsel);
+
+#endif /* GD32F4XX_TIMER_H */

+ 326 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h

@@ -0,0 +1,326 @@
+/*!
+    \file  gd32f4xx_tli.h
+    \brief definitions for the TLI
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_TLI_H
+#define GD32F4XX_TLI_H
+
+#include "gd32f4xx.h"
+
+/* TLI definitions */
+#define TLI                               TLI_BASE               /*!< TLI base address */
+/* TLI layer definitions */
+#define LAYER0                            TLI_BASE               /*!< Layer0 base address */
+#define LAYER1                            (TLI_BASE+0x80)        /*!< Layer1 base address */
+
+/* registers definitions */
+#define TLI_SPSZ                          REG32(TLI + 0x08U)          /*!< TLI synchronous pulse size register */
+#define TLI_BPSZ                          REG32(TLI + 0x0CU)          /*!< TLI back-porch size register */
+#define TLI_ASZ                           REG32(TLI + 0x10U)          /*!< TLI active size register */
+#define TLI_TSZ                           REG32(TLI + 0x14U)          /*!< TLI total size register */
+#define TLI_CTL                           REG32(TLI + 0x18U)          /*!< TLI control register */
+#define TLI_RL                            REG32(TLI + 0x24U)          /*!< TLI reload Layer register */
+#define TLI_BGC                           REG32(TLI + 0x2CU)          /*!< TLI background color register */
+#define TLI_INTEN                         REG32(TLI + 0x34U)          /*!< TLI interrupt enable register */
+#define TLI_INTF                          REG32(TLI + 0x38U)          /*!< TLI interrupt flag register */
+#define TLI_INTC                          REG32(TLI + 0x3CU)          /*!< TLI interrupt flag clear register */
+#define TLI_LM                            REG32(TLI + 0x40U)          /*!< TLI line mark register */
+#define TLI_CPPOS                         REG32(TLI + 0x44U)          /*!< TLI current pixel position register */
+#define TLI_STAT                          REG32(TLI + 0x48U)          /*!< TLI status register */
+#define TLI_LxCTL(layerx)                 REG32((layerx) + 0x84U)     /*!< TLI layer x control register */
+#define TLI_LxHPOS(layerx)                REG32((layerx) + 0x88U)     /*!< TLI layer x horizontal position parameters register */
+#define TLI_LxVPOS(layerx)                REG32((layerx) + 0x8CU)     /*!< TLI layer x vertical position parameters register */
+#define TLI_LxCKEY(layerx)                REG32((layerx) + 0x90U)     /*!< TLI layer x color key register */
+#define TLI_LxPPF(layerx)                 REG32((layerx) + 0x94U)     /*!< TLI layer x packeted pixel format register */
+#define TLI_LxSA(layerx)                  REG32((layerx) + 0x98U)     /*!< TLI layer x specified alpha register */
+#define TLI_LxDC(layerx)                  REG32((layerx) + 0x9CU)     /*!< TLI layer x default color register */
+#define TLI_LxBLEND(layerx)               REG32((layerx) + 0xA0U)     /*!< TLI layer x blending register */
+#define TLI_LxFBADDR(layerx)              REG32((layerx) + 0xACU)     /*!< TLI layer x frame base address register */
+#define TLI_LxFLLEN(layerx)               REG32((layerx) + 0xB0U)     /*!< TLI layer x frame line length register */
+#define TLI_LxFTLN(layerx)                REG32((layerx) + 0xB4U)     /*!< TLI layer x frame total line number register */
+#define TLI_LxLUT(layerx)                 REG32((layerx) + 0xC4U)     /*!< TLI ayer x Look Up Table register */
+
+
+/* bits definitions */
+/* TLI_SPSZ */
+#define TLI_SPSZ_VPSZ                     BITS(0,11)       /*!< size of the vertical synchronous pulse */
+#define TLI_SPSZ_HPSZ                     BITS(16,27)      /*!< size of the horizontal synchronous pulse */
+
+/* TLI_BPSZ */
+#define TLI_BPSZ_VBPSZ                    BITS(0,11)       /*!< size of the vertical back porch plus synchronous pulse */
+#define TLI_BPSZ_HBPSZ                    BITS(16,27)      /*!< size of the horizontal back porch plus synchronous pulse */
+
+/* TLI_ASZ */
+#define TLI_ASZ_VASZ                      BITS(0,11)       /*!< size of the vertical active area width plus back porch and synchronous pulse */
+#define TLI_ASZ_HASZ                      BITS(16,27)      /*!< size of the horizontal active area width plus back porch and synchronous pulse */
+
+/* TLI_SPSZ */
+#define TLI_TSZ_VTSZ                      BITS(0,11)       /*!< vertical total size of the display, including active area, back porch, synchronous pulse and front porch */
+#define TLI_TSZ_HTSZ                      BITS(16,27)      /*!< horizontal total size of the display, including active area, back porch, synchronous pulse and front porch */
+
+/* TLI_CTL */
+#define TLI_CTL_TLIEN                     BIT(0)           /*!< TLI enable bit */
+#define TLI_CTL_BDB                       BITS(4,6)        /*!< blue channel dither bits number */
+#define TLI_CTL_GDB                       BITS(8,10)       /*!< green channel dither bits number */
+#define TLI_CTL_RDB                       BITS(12,14)      /*!< red channel dither bits number */
+#define TLI_CTL_DFEN                      BIT(16)          /*!< dither function enable */
+#define TLI_CTL_CLKPS                     BIT(28)          /*!< pixel clock polarity selection */
+#define TLI_CTL_DEPS                      BIT(29)          /*!< data enable polarity selection */
+#define TLI_CTL_VPPS                      BIT(30)          /*!< vertical pulse polarity selection */
+#define TLI_CTL_HPPS                      BIT(31)          /*!< horizontal pulse polarity selection */
+
+/* TLI_RL */
+#define TLI_RL_RQR                        BIT(0)           /*!< request reload */
+#define TLI_RL_FBR                        BIT(1)           /*!< frame blank reload */
+
+/* TLI_BGC */
+#define TLI_BGC_BVB                       BITS(0,7)        /*!< background value blue */
+#define TLI_BGC_BVG                       BITS(8,15)       /*!< background value green */
+#define TLI_BGC_BVR                       BITS(16,23)      /*!< background value red */
+
+/* TLI_INTEN */
+#define TLI_INTEN_LMIE                    BIT(0)           /*!< line mark interrupt enable */
+#define TLI_INTEN_FEIE                    BIT(1)           /*!< FIFO error interrupt enable */
+#define TLI_INTEN_TEIE                    BIT(2)           /*!< transaction error interrupt enable */
+#define TLI_INTEN_LCRIE                   BIT(3)           /*!< layer configuration reloaded interrupt enable */
+
+/* TLI_INTF */
+#define TLI_INTF_LMF                      BIT(0)           /*!< line mark flag */
+#define TLI_INTF_FEF                      BIT(1)           /*!< FIFO error flag */
+#define TLI_INTF_TEF                      BIT(2)           /*!< transaction error flag */
+#define TLI_INTF_LCRF                     BIT(3)           /*!< layer configuration reloaded flag */
+
+/* TLI_INTC */
+#define TLI_INTC_LMC                      BIT(0)           /*!< line mark flag clear */
+#define TLI_INTC_FEC                      BIT(1)           /*!< FIFO error flag clear */
+#define TLI_INTC_TEC                      BIT(2)           /*!< transaction error flag clear */
+#define TLI_INTC_LCRC                     BIT(3)           /*!< layer configuration reloaded flag clear */
+
+/* TLI_LM */
+#define TLI_LM_LM                         BITS(0,10)       /*!< line mark value */
+
+/* TLI_CPPOS */
+#define TLI_CPPOS_VPOS                    BITS(0,15)       /*!< vertical position */
+#define TLI_CPPOS_HPOS                    BITS(16,31)      /*!< horizontal position */
+
+/* TLI_STAT */
+#define TLI_STAT_VDE                      BIT(0)           /*!< current VDE status */
+#define TLI_STAT_HDE                      BIT(1)           /*!< current HDE status */
+#define TLI_STAT_VS                       BIT(2)           /*!< current VS status of the TLI */
+#define TLI_STAT_HS                       BIT(3)           /*!< current HS status of the TLI  */
+
+/* TLI_LxCTL */
+#define TLI_LxCTL_LEN                     BIT(0)           /*!< layer enable */
+#define TLI_LxCTL_CKEYEN                  BIT(1)           /*!< color keying enable */
+#define TLI_LxCTL_LUTEN                   BIT(4)           /*!< LUT enable */
+
+/* TLI_LxHPOS */
+#define TLI_LxHPOS_WLP                    BITS(0,11)       /*!< window left position */
+#define TLI_LxHPOS_WRP                    BITS(16,27)      /*!< window right position */
+
+/* TLI_LxVPOS */
+#define TLI_LxVPOS_WTP                    BITS(0,11)       /*!< window top position */
+#define TLI_LxVPOS_WBP                    BITS(16,27)      /*!< window bottom position */
+
+/* TLI_LxCKEY */
+#define TLI_LxCKEY_CKEYB                  BITS(0,7)        /*!< color key blue */
+#define TLI_LxCKEY_CKEYG                  BITS(8,15)       /*!< color key green */
+#define TLI_LxCKEY_CKEYR                  BITS(16,23)      /*!< color key red */
+
+/* TLI_LxPPF */
+#define TLI_LxPPF_PPF                     BITS(0,2)        /*!< packeted pixel format */
+
+/* TLI_LxSA */
+#define TLI_LxSA_SA                       BITS(0,7)        /*!< specified alpha */
+
+/* TLI_LxDC */
+#define TLI_LxDC_DCB                      BITS(0,7)        /*!< the default color blue */
+#define TLI_LxDC_DCG                      BITS(8,15)       /*!< the default color green */
+#define TLI_LxDC_DCR                      BITS(16,23)      /*!< the default color red */
+#define TLI_LxDC_DCA                      BITS(24,31)      /*!< the default color alpha */
+
+/* TLI_LxBLEND */
+#define TLI_LxBLEND_ACF2                  BITS(0,2)        /*!< alpha calculation factor 2 of blending method */
+#define TLI_LxBLEND_ACF1                  BITS(8,10)       /*!< alpha calculation factor 1 of blending method */
+
+/* TLI_LxFBADDR */
+#define TLI_LxFBADDR_FBADD                BITS(0,31)       /*!< frame buffer base address */
+
+/* TLI_LxFLLEN */
+#define TLI_LxFLLEN_FLL                   BITS(0,12)       /*!< frame line length */
+#define TLI_LxFLLEN_STDOFF                BITS(16,28)      /*!< frame buffer stride offset */
+
+/* TLI_LxFTLN */
+#define TLI_LxFTLN_FTLN                   BITS(0,10)       /*!< frame total line number */
+
+/* TLI_LxLUT */
+#define TLI_LxLUT_TB                      BITS(0,7)        /*!< blue channel of a LUT entry */
+#define TLI_LxLUT_TG                      BITS(8,15)       /*!< green channel of a LUT entry */
+#define TLI_LxLUT_TR                      BITS(16,23)      /*!< red channel of a LUT entry */
+#define TLI_LxLUT_TADD                    BITS(24,31)      /*!< look up table write address */
+
+/* constants definitions */
+
+/* TLI parameter struct definitions */
+typedef struct
+{   
+    uint32_t synpsz_vpsz;                     /*!< size of the vertical synchronous pulse */
+    uint32_t synpsz_hpsz;                     /*!< size of the horizontal synchronous pulse */
+    uint32_t backpsz_vbpsz;                   /*!< size of the vertical back porch plus synchronous pulse */
+    uint32_t backpsz_hbpsz;                   /*!< size of the horizontal back porch plus synchronous pulse */
+    uint32_t activesz_vasz;                   /*!< size of the vertical active area width plus back porch and synchronous pulse */
+    uint32_t activesz_hasz;                   /*!< size of the horizontal active area width plus back porch and synchronous pulse */
+    uint32_t totalsz_vtsz;                    /*!< vertical total size of the display */
+    uint32_t totalsz_htsz;                    /*!< horizontal total size of the display */
+    uint32_t backcolor_red;                   /*!< background value red */
+    uint32_t backcolor_green;                 /*!< background value green */
+    uint32_t backcolor_blue;                  /*!< background value blue */
+    uint32_t signalpolarity_hs;               /*!< horizontal pulse polarity selection */
+    uint32_t signalpolarity_vs;               /*!< vertical pulse polarity selection */
+    uint32_t signalpolarity_de;               /*!< data enable polarity selection */
+    uint32_t signalpolarity_pixelck;          /*!< pixel clock polarity selection */
+}tli_parameter_struct; 
+
+/* TLI Layer parameter struct definitions */
+typedef struct
+{   
+    uint32_t layer_window_rightpos;           /*!< window right position */
+    uint32_t layer_window_leftpos;            /*!< window left position */
+    uint32_t layer_window_bottompos;          /*!< window bottom position */
+    uint32_t layer_window_toppos;             /*!< window top position */
+    uint32_t layer_ppf;                       /*!< packeted pixel format */
+    uint32_t layer_sa;                        /*!< specified alpha */
+    uint32_t layer_default_alpha;             /*!< the default color alpha */
+    uint32_t layer_default_red;               /*!< the default color red */
+    uint32_t layer_default_green;             /*!< the default color green */
+    uint32_t layer_default_blue;              /*!< the default color blue */
+    uint32_t layer_acf1;                      /*!< alpha calculation factor 1 of blending method */
+    uint32_t layer_acf2;                      /*!< alpha calculation factor 2 of blending method */
+    uint32_t layer_frame_bufaddr;             /*!< frame buffer base address */
+    uint32_t layer_frame_buf_stride_offset;   /*!< frame buffer stride offset */
+    uint32_t layer_frame_line_length;         /*!< frame line length */
+    uint32_t layer_frame_total_line_number;   /*!< frame total line number */
+}tli_layer_parameter_struct; 
+
+/* TLI layer LUT parameter struct definitions */
+typedef struct
+{                                                       
+    uint32_t layer_table_addr;                /*!< look up table write address */
+    uint32_t layer_lut_channel_red;           /*!< red channel of a LUT entry */
+    uint32_t layer_lut_channel_green;         /*!< green channel of a LUT entry */
+    uint32_t layer_lut_channel_blue;          /*!< blue channel of a LUT entry */                                                       
+}tli_layer_lut_parameter_struct; 
+
+/* packeted pixel format */
+typedef enum 
+{
+     LAYER_PPF_ARGB8888,                          /*!< layerx pixel format ARGB8888 */
+     LAYER_PPF_RGB888,                            /*!< layerx pixel format RGB888 */
+     LAYER_PPF_RGB565,                            /*!< layerx pixel format RGB565 */
+     LAYER_PPF_ARGB1555,                          /*!< layerx pixel format ARGB1555 */
+     LAYER_PPF_ARGB4444,                          /*!< layerx pixel format ARGB4444 */
+     LAYER_PPF_L8,                                /*!< layerx pixel format L8 */
+     LAYER_PPF_AL44,                              /*!< layerx pixel format AL44 */
+     LAYER_PPF_AL88                               /*!< layerx pixel format AL88 */
+} tli_layer_ppf_enum;
+
+/* layer reload configure */
+#define TLI_FRAME_BLANK_RELOAD_EN     ((uint8_t)0x00U)                 /*!< the layer configuration will be reloaded at frame blank */
+#define TLI_REQUEST_RELOAD_EN         ((uint8_t)0x01U)                 /*!< the layer configuration will be reloaded after this bit sets */
+
+/* dither Function */
+#define TLI_DITHER_DISABLE            ((uint8_t)0x00U)                 /*!< dither function disable */
+#define TLI_DITHER_ENABLE             ((uint8_t)0x01U)                 /*!< dither function enable */
+
+/* horizontal pulse polarity selection */
+
+#define TLI_HSYN_ACTLIVE_LOW          ((uint32_t)0x00000000U)          /*!< horizontal synchronous pulse active low */
+#define TLI_HSYN_ACTLIVE_HIGHT        TLI_CTL_HPPS                     /*!< horizontal synchronous pulse active high */
+
+
+/* vertical pulse polarity selection */
+
+#define TLI_VSYN_ACTLIVE_LOW          ((uint32_t)0x00000000U)          /*!< vertical synchronous pulse active low */
+#define TLI_VSYN_ACTLIVE_HIGHT        TLI_CTL_VPPS                     /*!< vertical synchronous pulse active high */
+
+
+/* pixel Clock Polarity Selection */
+
+#define TLI_PIXEL_CLOCK_TLI           ((uint32_t)0x00000000U)          /*!< pixel clock is TLI clock */
+#define TLI_PIXEL_CLOCK_INVERTEDTLI   TLI_CTL_CLKPS                    /*!< pixel clock is inverted TLI clock */
+
+
+/* data Enable Polarity Selection */
+
+#define TLI_DE_ACTLIVE_LOW            ((uint32_t)0x00000000U)          /*!< data enable active low */
+#define TLI_DE_ACTLIVE_HIGHT          TLI_CTL_DEPS                     /*!< data enable active high */
+
+/* alpha calculation factor 1 of blending method */
+#define LxBLEND_ACF1(regval)          (BITS(8,10) & ((regval)<<8))
+#define LAYER_ACF1_SA                 LxBLEND_ACF1(4)                  /*!< normalization specified alpha */
+#define LAYER_ACF1_PASA               LxBLEND_ACF1(6)                  /*!< normalization pixel alpha * normalization specified alpha */
+
+/* alpha calculation factor 2 of blending method*/
+#define LxBLEND_ACF2(regval)          (BITS(0,2) & ((regval)))
+#define LAYER_ACF2_SA                 LxBLEND_ACF2(5)                  /*!< normalization specified alpha */
+#define LAYER_ACF2_PASA               LxBLEND_ACF2(7)                  /*!< normalization pixel alpha x normalization specified alpha */
+/* function declarations */
+
+/* deinitialize TLI */
+void tli_deinit(void);
+/* initialize TLI */
+void tli_init(tli_parameter_struct *tli_struct);
+/* TLI dither function enable */
+void tli_dither_config(uint8_t ditherstat);
+/* enable TLI */
+void tli_enable(void);
+/* disable TLI */
+void tli_disable(void);
+/* TLI reload mode config*/
+void tli_reload_config(uint8_t reloadmod);
+
+/* TLI interrupt enable */
+void tli_interrupt_enable(uint32_t inttype);
+/* TLI interrupt disable */
+void tli_interrupt_disable(uint32_t inttype);
+/* get TLI interrupt flag */
+FlagStatus tli_interrupt_flag_get(uint32_t intflag);
+/* clear TLI interrupt flag */
+void tli_interrupt_flag_clear(uint32_t intflag);
+
+/* set line mark value */
+void tli_line_mark_set(uint32_t linenum);
+/* get current displayed position */
+uint32_t tli_current_pos_get(void);
+/* get TLI state */
+FlagStatus tli_flag_get(uint32_t state);
+
+/* TLI layer enable */
+void tli_layer_enable(uint32_t layerx);
+/* TLI layer disable */
+void tli_layer_disable(uint32_t layerx);
+/* TLI layer color keying enable */
+void tli_color_key_enable(uint32_t layerx);
+/* TLI layer color keying disable */
+void tli_color_key_disable(uint32_t layerx);
+/* TLI layer LUT enable */
+void tli_lut_enable(uint32_t layerx);
+/* TLI layer LUT disable */
+void tli_lut_disable(uint32_t layerx);
+/* TLI layer initialize */
+void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct);
+/* TLI layer initialize */
+void tli_layer_window_offset_modify(uint32_t layerx,uint32_t offset_x,uint32_t offset_y);
+/* TLI layer lut initialize */
+void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct);
+/* TLI layer key initialize */
+void tli_ckey_init(uint32_t layerx,uint32_t redkey,uint32_t greenkey,uint32_t bluekey);
+
+#endif /* GD32F4XX_TLI_H */

+ 78 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h

@@ -0,0 +1,78 @@
+/*!
+    \file  gd32f4xx_trng.h
+    \brief definitions for the TRNG
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_TRNG_H
+#define GD32F4XX_TRNG_H
+
+#include "gd32f4xx.h"
+
+/* EXTI definitions */
+#define TRNG                        TRNG_BASE
+
+/* registers definitions */
+#define TRNG_CTL                    REG32(TRNG + 0x00U)        /*!< interrupt enable register */
+#define TRNG_STAT                   REG32(TRNG + 0x04U)        /*!< event enable register */
+#define TRNG_DATA                   REG32(TRNG + 0x08U)        /*!< rising edge trigger enable register */
+
+/* bits definitions */
+/* TRNG_CTL */
+#define TRNG_CTL_TRNGEN             BIT(2)                     /*!< TRNG enable bit */
+#define TRNG_CTL_IE                 BIT(3)                     /*!< interrupt enable bit */
+
+/* TRNG_STAT */
+#define TRNG_STAT_DRDY              BIT(0)                     /*!< random data ready status bit */
+#define TRNG_STAT_CECS              BIT(1)                     /*!< clock error current status */
+#define TRNG_STAT_SECS              BIT(2)                     /*!< seed error current status */
+#define TRNG_STAT_CEIF              BIT(5)                     /*!< clock error interrupt flag */
+#define TRNG_STAT_SEIF              BIT(6)                     /*!< seed error interrupt flag */
+
+/* TRNG_DATA */
+#define TRNG_DATA_TRNDATA           BITS(0,31)                 /*!< 32-Bit Random data */
+
+/* constants definitions */
+/* trng status flag */
+typedef enum
+{ 
+    TRNG_FLAG_DRDY = TRNG_STAT_DRDY,                           /*!< random Data ready status */
+    TRNG_FLAG_CECS = TRNG_STAT_CECS,                           /*!< clock error current status */
+    TRNG_FLAG_SECS = TRNG_STAT_SECS                            /*!< seed error current status */
+}trng_flag_enum;
+
+/* trng inerrupt flag */
+typedef enum
+{
+    TRNG_INT_FLAG_CEIF = TRNG_STAT_CEIF,                       /*!< clock error interrupt flag */
+    TRNG_INT_FLAG_SEIF = TRNG_STAT_SEIF                        /*!< seed error interrupt flag */
+}trng_int_flag_enum;
+
+/* function declarations */
+/* deinitialize the TRNG */
+void trng_deinit(void);
+/* enable the TRNG interface */
+void trng_enable(void);
+/* disable the TRNG interface */
+void trng_disable(void);
+/* get the true random data */
+uint32_t trng_get_true_random_data(void);
+/* get the trng status flags */
+FlagStatus trng_flag_get(trng_flag_enum flag);
+/* clear the trng status flags */
+void trng_flag_clear(trng_flag_enum flag);
+/* the trng interrupt enable */
+void trng_interrupt_enable(void);
+/* the trng interrupt disable */
+void trng_interrupt_disable(void);
+/* get the trng interrupt flags */
+FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag);
+/* clear the trng interrupt flags */
+void trng_interrupt_flag_clear(trng_int_flag_enum int_flag);
+
+#endif /* GD32F4XX_TRNG_H */

+ 467 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h

@@ -0,0 +1,467 @@
+/*!
+    \file  gd32f4xx_usart.h
+    \brief definitions for the USART
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_USART_H
+#define GD32F4XX_USART_H
+
+#include "gd32f4xx.h"
+
+/* USARTx(x=0,1) definitions */
+#define USART1                        USART_BASE
+#define USART2                        (USART_BASE+0x00000400U)       /*!< USART2 base address */
+#define UART3                         (USART_BASE+0x00000800U)       /*!< UART3 base address */
+#define UART4                         (USART_BASE+0x00000C00U)       /*!< UART4 base address */
+#define UART6                         (USART_BASE+0x00003400U)       /*!< UART6 base address */
+#define UART7                         (USART_BASE+0x00003800U)       /*!< UART7 base address */
+#define USART0                        (USART_BASE+0x0000CC00U)       /*!< USART0 base address */
+#define USART5                        (USART_BASE+0x0000D000U)       /*!< USART5 base address */
+
+/* registers definitions */
+#define USART_STAT0(usartx)           REG32((usartx) + 0x00U)        /*!< USART status register 0 */
+#define USART_DATA(usartx)            REG32((usartx) + 0x04U)        /*!< USART data register */
+#define USART_BAUD(usartx)            REG32((usartx) + 0x08U)        /*!< USART baud rate register */
+#define USART_CTL0(usartx)            REG32((usartx) + 0x0CU)        /*!< USART control register 0 */
+#define USART_CTL1(usartx)            REG32((usartx) + 0x10U)        /*!< USART control register 1 */
+#define USART_CTL2(usartx)            REG32((usartx) + 0x14U)        /*!< USART control register 2 */
+#define USART_GP(usartx)              REG32((usartx) + 0x18U)        /*!< USART guard time and prescaler register */
+#define USART_CTL3(usartx)            REG32((usartx) + 0x80U)        /*!< USART control register 3 */
+#define USART_RT(usartx)              REG32((usartx) + 0x84U)        /*!< USART receiver timeout register */
+#define USART_STAT1(usartx)           REG32((usartx) + 0x88U)        /*!< USART status register 1 */
+#define USART_CHC(usartx)             REG32((usartx) + 0xC0U)        /*!< USART coherence control register */
+
+/* bits definitions */
+/* USARTx_STAT0 */
+#define USART_STAT0_PERR              BIT(0)       /*!< parity error flag */
+#define USART_STAT0_FERR              BIT(1)       /*!< frame error flag */
+#define USART_STAT0_NERR              BIT(2)       /*!< noise error flag */
+#define USART_STAT0_ORERR             BIT(3)       /*!< overrun error */
+#define USART_STAT0_IDLEF             BIT(4)       /*!< IDLE frame detected flag */
+#define USART_STAT0_RBNE              BIT(5)       /*!< read data buffer not empty */
+#define USART_STAT0_TC                BIT(6)       /*!< transmission complete */
+#define USART_STAT0_TBE               BIT(7)       /*!< transmit data buffer empty */
+#define USART_STAT0_LBDF              BIT(8)       /*!< LIN break detected flag */
+#define USART_STAT0_CTSF              BIT(9)       /*!< CTS change flag */
+
+/* USARTx_DATA */
+#define USART_DATA_DATA               BITS(0,8)    /*!< transmit or read data value */
+
+/* USARTx_BAUD */
+#define USART_BAUD_FRADIV             BITS(0,3)    /*!< fraction part of baud-rate divider */
+#define USART_BAUD_INTDIV             BITS(4,15)   /*!< integer part of baud-rate divider */
+
+/* USARTx_CTL0 */
+#define USART_CTL0_SBKCMD             BIT(0)       /*!< send break command */
+#define USART_CTL0_RWU                BIT(1)       /*!< receiver wakeup from mute mode */
+#define USART_CTL0_REN                BIT(2)       /*!< receiver enable */
+#define USART_CTL0_TEN                BIT(3)       /*!< transmitter enable */
+#define USART_CTL0_IDLEIE             BIT(4)       /*!< idle line detected interrupt enable */
+#define USART_CTL0_RBNEIE             BIT(5)       /*!< read data buffer not empty interrupt and overrun error interrupt enable */
+#define USART_CTL0_TCIE               BIT(6)       /*!< transmission complete interrupt enable */
+#define USART_CTL0_TBEIE              BIT(7)       /*!< transmitter buffer empty interrupt enable */
+#define USART_CTL0_PERRIE             BIT(8)       /*!< parity error interrupt enable */
+#define USART_CTL0_PM                 BIT(9)       /*!< parity mode */
+#define USART_CTL0_PCEN               BIT(10)      /*!< parity check function enable */
+#define USART_CTL0_WM                 BIT(11)      /*!< wakeup method in mute mode */
+#define USART_CTL0_WL                 BIT(12)      /*!< word length */
+#define USART_CTL0_UEN                BIT(13)      /*!< USART enable */
+#define USART_CTL0_OVSMOD             BIT(15)      /*!< oversample mode */
+
+/* USARTx_CTL1 */
+#define USART_CTL1_ADDR               BITS(0,3)    /*!< address of USART */
+#define USART_CTL1_LBLEN              BIT(5)       /*!< LIN break frame length */
+#define USART_CTL1_LBDIE              BIT(6)       /*!< LIN break detected interrupt eanble */
+#define USART_CTL1_CLEN               BIT(8)       /*!< CK length */
+#define USART_CTL1_CPH                BIT(9)       /*!< CK phase */
+#define USART_CTL1_CPL                BIT(10)      /*!< CK polarity */
+#define USART_CTL1_CKEN               BIT(11)      /*!< CK pin enable */
+#define USART_CTL1_STB                BITS(12,13)  /*!< STOP bits length */
+#define USART_CTL1_LMEN               BIT(14)      /*!< LIN mode enable */
+
+/* USARTx_CTL2 */
+#define USART_CTL2_ERRIE              BIT(0)       /*!< error interrupt enable */
+#define USART_CTL2_IREN               BIT(1)       /*!< IrDA mode enable */
+#define USART_CTL2_IRLP               BIT(2)       /*!< IrDA low-power */
+#define USART_CTL2_HDEN               BIT(3)       /*!< half-duplex enable */
+#define USART_CTL2_NKEN               BIT(4)       /*!< NACK enable in smartcard mode */
+#define USART_CTL2_SCEN               BIT(5)       /*!< smartcard mode enable */
+#define USART_CTL2_DENR               BIT(6)       /*!< DMA request enable for reception */
+#define USART_CTL2_DENT               BIT(7)       /*!< DMA request enable for transmission */
+#define USART_CTL2_RTSEN              BIT(8)       /*!< RTS enable */
+#define USART_CTL2_CTSEN              BIT(9)       /*!< CTS enable */
+#define USART_CTL2_CTSIE              BIT(10)      /*!< CTS interrupt enable */
+#define USART_CTL2_OSB                BIT(11)      /*!< one sample bit method */
+
+/* USARTx_GP */
+#define USART_GP_PSC                  BITS(0,7)    /*!< prescaler value for dividing the system clock */
+#define USART_GP_GUAT                 BITS(8,15)   /*!< guard time value in smartcard mode */
+ 
+/* USARTx_CTL3 */
+#define USART_CTL3_RTEN               BIT(0)       /*!< receiver timeout enable */
+#define USART_CTL3_SCRTNUM            BITS(1,3)    /*!< smartcard auto-retry number */
+#define USART_CTL3_RTIE               BIT(4)       /*!< interrupt enable bit of receive timeout event */
+#define USART_CTL3_EBIE               BIT(5)       /*!< interrupt enable bit of end of block event */
+#define USART_CTL3_RINV               BIT(8)       /*!< RX pin level inversion */
+#define USART_CTL3_TINV               BIT(9)       /*!< TX pin level inversion */
+#define USART_CTL3_DINV               BIT(10)      /*!< data bit level inversion */
+#define USART_CTL3_MSBF               BIT(11)      /*!< most significant bit first */
+
+/* USARTx_RT */
+#define USART_RT_RT                   BITS(0,23)   /*!< receiver timeout threshold */
+#define USART_RT_BL                   BITS(24,31)  /*!< block length */
+
+/* USARTx_STAT1 */
+#define USART_STAT1_RTF               BIT(11)      /*!< receiver timeout flag */
+#define USART_STAT1_EBF               BIT(12)      /*!< end of block flag */
+#define USART_STAT1_BSY               BIT(16)      /*!< busy flag */
+
+/* USARTx_CHC */
+#define USART_CHC_HCM                 BIT(0)       /*!< hardware flow control coherence mode */
+#define USART_CHC_PCM                 BIT(1)       /*!< parity check coherence mode */
+#define USART_CHC_BCM                 BIT(2)       /*!< break frame coherence mode */
+#define USART_CHC_EPERR               BIT(8)       /*!< early parity error flag */
+
+/* constants definitions */
+/* define the USART bit position and its register index offset */
+#define USART_REGIDX_BIT(regidx, bitpos)    (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define USART_REG_VAL(usartx, offset)       (REG32((usartx) + ((uint32_t)(offset) >> 6)))
+#define USART_BIT_POS(val)                  ((uint32_t)(val) & 0x1FU)
+
+/* register offset */
+#define STAT0_REG_OFFSET              0x00U        /*!< STAT0 register offset */
+#define STAT1_REG_OFFSET              0x88U        /*!< STAT1 register offset */
+#define CHC_REG_OFFSET                0xC0U        /*!< CHC register offset */
+#define CTL0_REG_OFFSET               0x0CU        /*!< CTL0 register offset */
+#define CTL1_REG_OFFSET               0x10U        /*!< CTL1 register offset */
+#define CTL2_REG_OFFSET               0x14U        /*!< CTL2 register offset */
+#define CTL3_REG_OFFSET               0x80U        /*!< CTL2 register offset */
+
+/* USART flags */
+typedef enum
+{
+    /* flags in STAT0 register */
+    USART_FLAG_CTSF = USART_REGIDX_BIT(STAT0_REG_OFFSET, 9U),      /*!< CTS change flag */
+    USART_FLAG_LBDF = USART_REGIDX_BIT(STAT0_REG_OFFSET, 8U),      /*!< LIN break detected flag */
+    USART_FLAG_TBE = USART_REGIDX_BIT(STAT0_REG_OFFSET, 7U),       /*!< transmit data buffer empty */
+    USART_FLAG_TC = USART_REGIDX_BIT(STAT0_REG_OFFSET, 6U),        /*!< transmission complete */
+    USART_FLAG_RBNE = USART_REGIDX_BIT(STAT0_REG_OFFSET, 5U),      /*!< read data buffer not empty */
+    USART_FLAG_IDLEF = USART_REGIDX_BIT(STAT0_REG_OFFSET, 4U),     /*!< IDLE frame detected flag */
+    USART_FLAG_ORERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 3U),     /*!< overrun error */
+    USART_FLAG_NERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 2U),      /*!< noise error flag */
+    USART_FLAG_FERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 1U),      /*!< frame error flag */
+    USART_FLAG_PERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 0U),      /*!< parity error flag */
+    /* flags in STAT1 register */
+    USART_FLAG_BSY = USART_REGIDX_BIT(STAT1_REG_OFFSET, 16U),      /*!< busy flag */
+    USART_FLAG_EBF = USART_REGIDX_BIT(STAT1_REG_OFFSET, 12U),      /*!< end of block flag */
+    USART_FLAG_RTF = USART_REGIDX_BIT(STAT1_REG_OFFSET, 11U),      /*!< receiver timeout flag */
+    /* flags in CHC register */
+    USART_FLAG_EPERR = USART_REGIDX_BIT(CHC_REG_OFFSET, 8U),       /*!< early parity error flag */
+}usart_flag_enum;
+
+/* USART interrupt flags */
+typedef enum
+{
+    /* interrupt flags in CTL0 register */
+    USART_INT_PERRIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 8U),      /*!< parity error interrupt */
+    USART_INT_TBEIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 7U),       /*!< transmitter buffer empty interrupt */
+    USART_INT_TCIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 6U),        /*!< transmission complete interrupt */
+    USART_INT_RBNEIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 5U),      /*!< read data buffer not empty interrupt and overrun error interrupt */
+    USART_INT_IDLEIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 4U),      /*!< IDLE line detected interrupt */
+    /* interrupt flags in CTL1 register */
+    USART_INT_LBDIE = USART_REGIDX_BIT(CTL1_REG_OFFSET, 6U),       /*!< LIN break detected interrupt */
+    /* interrupt flags in CTL2 register */
+    USART_INT_CTSIE = USART_REGIDX_BIT(CTL2_REG_OFFSET, 10U),      /*!< CTS interrupt */
+    USART_INT_ERRIE = USART_REGIDX_BIT(CTL2_REG_OFFSET, 0U),       /*!< error interrupt */
+    /* interrupt flags in CTL3 register */
+    USART_INT_EBIE = USART_REGIDX_BIT(CTL3_REG_OFFSET, 5U),        /*!< interrupt enable bit of end of block event */
+    USART_INT_RTIE = USART_REGIDX_BIT(CTL3_REG_OFFSET, 4U),        /*!< interrupt enable bit of receive timeout event */
+}usart_interrupt_flag_enum;
+
+/* USART invert configure */
+typedef enum
+{
+    /* data bit level inversion */
+    USART_DINV_ENABLE,                             /*!< data bit level inversion */
+    USART_DINV_DISABLE,                            /*!< data bit level not inversion */
+    /* TX pin level inversion */
+    USART_TXPIN_ENABLE,                            /*!< TX pin level inversion */
+    USART_TXPIN_DISABLE,                           /*!< TX pin level not inversion */
+    /* RX pin level inversion */
+    USART_RXPIN_ENABLE,                            /*!< RX pin level inversion */
+    USART_RXPIN_DISABLE,                           /*!< RX pin level not inversion */
+}usart_invert_enum;
+
+/* USART receiver configure */
+#define CTL0_REN(regval)              (BIT(2) & ((uint32_t)(regval) << 2))
+#define USART_RECEIVE_ENABLE          CTL0_REN(1)                      /*!< enable receiver */
+#define USART_RECEIVE_DISABLE         CTL0_REN(0)                      /*!< disable receiver */
+
+/* USART transmitter configure */
+#define CTL0_TEN(regval)              (BIT(3) & ((uint32_t)(regval) << 3))
+#define USART_TRANSMIT_ENABLE         CTL0_TEN(1)                      /*!< enable transmitter */
+#define USART_TRANSMIT_DISABLE        CTL0_TEN(0)                      /*!< disable transmitter */
+
+/* USART parity bits definitions */
+#define CTL0_PM(regval)               (BITS(9,10) & ((uint32_t)(regval) << 9))
+#define USART_PM_NONE                 CTL0_PM(0)                       /*!< no parity */
+#define USART_PM_ODD                  CTL0_PM(2)                       /*!< odd parity */
+#define USART_PM_EVEN                 CTL0_PM(3)                       /*!< even parity */
+
+/* USART wakeup method in mute mode */
+#define CTL0_WM(regval)               (BIT(11) & ((uint32_t)(regval) << 11))
+#define USART_WM_IDLE                 CTL0_WM(0)                       /*!< idle Line */
+#define USART_WM_ADDR                 CTL0_WM(1)                       /*!< address mask */
+
+/* USART word length definitions */
+#define CTL0_WL(regval)               (BIT(12) & ((uint32_t)(regval) << 12))
+#define USART_WL_8BIT                 CTL0_WL(0)                       /*!< 8 bits */
+#define USART_WL_9BIT                 CTL0_WL(1)                       /*!< 9 bits */
+
+/* USART oversampling mode definitions */
+#define CTL0_OVSMOD(regval)           (BIT(15) & ((uint32_t)(regval) << 15))
+#define USART_OVSMOD_16               CTL0_OVSMOD(0)                   /*!< 16 bits */
+#define USART_OVSMOD_8                CTL0_OVSMOD(1)                   /*!< 8 bits */
+
+/* USART stop bits definitions */
+#define CTL1_STB(regval)              (BITS(12,13) & ((uint32_t)(regval) << 12))
+#define USART_STB_1BIT                CTL1_STB(0)                      /*!< 1 bit */
+#define USART_STB_0_5BIT              CTL1_STB(1)                      /*!< 0.5 bit */
+#define USART_STB_2BIT                CTL1_STB(2)                      /*!< 2 bits */
+#define USART_STB_1_5BIT              CTL1_STB(3)                      /*!< 1.5 bits */
+
+/* USART LIN break frame length */
+#define CTL1_LBLEN(regval)            (BIT(5) & ((uint32_t)(regval) << 5))
+#define USART_LBLEN_10B               CTL1_LBLEN(0)                    /*!< 10 bits */
+#define USART_LBLEN_11B               CTL1_LBLEN(1)                    /*!< 11 bits */
+
+/* USART CK length */
+#define CTL1_CLEN(regval)             (BIT(8) & ((uint32_t)(regval) << 8))
+#define USART_CLEN_NONE               CTL1_CLEN(0)                     /*!< there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame */
+#define USART_CLEN_EN                 CTL1_CLEN(1)                     /*!< there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame */
+
+/* USART clock phase */
+#define CTL1_CPH(regval)              (BIT(9) & ((uint32_t)(regval) << 9))
+#define USART_CPH_1CK                 CTL1_CPH(0)                      /*!< first clock transition is the first data capture edge */
+#define USART_CPH_2CK                 CTL1_CPH(1)                      /*!< second clock transition is the first data capture edge */
+
+/* USART clock polarity */
+#define CTL1_CPL(regval)              (BIT(10) & ((uint32_t)(regval) << 10))
+#define USART_CPL_LOW                 CTL1_CPL(0)                      /*!< steady low value on CK pin */
+#define USART_CPL_HIGH                CTL1_CPL(1)                      /*!< steady high value on CK pin */
+
+/* USART DMA request for receive configure */
+#define CLT2_DENR(regval)             (BIT(6) & ((uint32_t)(regval) << 6))
+#define USART_DENR_ENABLE             CLT2_DENR(1)                     /*!< DMA request enable for reception */
+#define USART_DENR_DISABLE            CLT2_DENR(0)                     /*!< DMA request disable for reception */
+
+/* USART DMA request for transmission configure */
+#define CLT2_DENT(regval)             (BIT(7) & ((uint32_t)(regval) << 7))
+#define USART_DENT_ENABLE             CLT2_DENT(1)                     /*!< DMA request enable for transmission */
+#define USART_DENT_DISABLE            CLT2_DENT(0)                     /*!< DMA request disable for transmission */
+
+/* USART RTS configure */
+#define CLT2_RTSEN(regval)            (BIT(8) & ((uint32_t)(regval) << 8))
+#define USART_RTS_ENABLE              CLT2_RTSEN(1)                    /*!< RTS enable */
+#define USART_RTS_DISABLE             CLT2_RTSEN(0)                    /*!< RTS disable */
+
+/* USART CTS configure */
+#define CLT2_CTSEN(regval)            (BIT(9) & ((uint32_t)(regval) << 9))
+#define USART_CTS_ENABLE              CLT2_CTSEN(1)                    /*!< CTS enable */
+#define USART_CTS_DISABLE             CLT2_CTSEN(0)                    /*!< CTS disable */
+
+/* USART one sample bit method configure */
+#define CTL2_OSB(regval)              (BIT(11) & ((uint32_t)(regval) << 11))
+#define USART_OSB_1bit                CTL2_OSB(1)                      /*!< 1 bit */
+#define USART_OSB_3bit                CTL2_OSB(0)                      /*!< 3 bits */
+
+/* USART IrDA low-power enable */
+#define CTL2_IRLP(regval)             (BIT(2) & ((uint32_t)(regval) << 2))
+#define USART_IRLP_LOW                CTL2_IRLP(1)                     /*!< low-power */
+#define USART_IRLP_NORMAL             CTL2_IRLP(0)                     /*!< normal */
+
+/* USART data is transmitted/received with the LSB/MSB first */
+#define CTL3_MSBF(regval)             (BIT(11) & ((uint32_t)(regval) << 11))
+#define USART_MSBF_LSB                CTL3_MSBF(0)                     /*!< LSB first */
+#define USART_MSBF_MSB                CTL3_MSBF(1)                     /*!< MSB first */
+
+/* break frame coherence mode */
+#define CHC_BCM(regval)               (BIT(2) & ((uint32_t)(regval) << 2))
+#define USART_BCM_NONE                CHC_BCM(0)                       /*!< no parity error is detected */
+#define USART_BCM_EN                  CHC_BCM(1)                       /*!< parity error is detected */
+
+/* USART parity check coherence mode */
+#define CHC_PCM(regval)               (BIT(1) & ((uint32_t)(regval) << 1))
+#define USART_PCM_NONE                CHC_PCM(0)                       /*!< not check parity */
+#define USART_PCM_EN                  CHC_PCM(1)                       /*!< check the parity */
+
+/* USART hardware flow control coherence mode */
+#define CHC_HCM(regval)               (BIT(0) & ((uint32_t)(regval) << 0))
+#define USART_HCM_NONE                CHC_HCM(0)                       /*!< nRTS signal equals to the rxne status register */
+#define USART_HCM_EN                  CHC_HCM(1)                       /*!< nRTS signal is set when the last data bit has been sampled */
+
+/* interrupt enable in USART_CTL0 */
+#define USART_INTEN_PERRIE            ((uint32_t)0x10000100U)          /*!< parity error interrupt */
+#define USART_INTEN_TBEIE             ((uint32_t)0x10000080U)          /*!< transmitter buffer empty interrupt */
+#define USART_INTEN_TCIE              ((uint32_t)0x10000040U)          /*!< transmission complete interrupt */
+#define USART_INTEN_RBNEIE            ((uint32_t)0x10000020U)          /*!< read data buffer not empty interrupt and overrun error interrupt */
+#define USART_INTEN_IDLEIE            ((uint32_t)0x10000010U)          /*!< IDLE line detected interrupt */
+
+/* interrupt enable flag in USART_CTL1 */
+#define USART_INTEN_LBDIE             ((uint32_t)0x20000040U)          /*!< LIN break detected interrupt */
+
+/* interrupt enable flag in USART_CTL2 */
+#define USART_INTEN_ERRIE             ((uint32_t)0x40000001U)          /*!< error interrupt */
+#define USART_INTEN_CTSIE             ((uint32_t)0x40000400U)          /*!< CTS interrupt*/
+
+/* interrupt enable flag in USART_CTL3 */
+#define USART_INTEN_RTIE              ((uint32_t)0x80000010U)          /*!< interrupt enable bit of receive timeout event */
+#define USART_INTEN_EBIE              ((uint32_t)0x80000020U)          /*!< interrupt enable bit of end of block event */
+
+#define USART_INTEN_MASK              ((uint32_t)0x00000FFFU)          /*!< USART interrupt mask */
+#define USART_INTS_CTL0               ((uint32_t)0x10000000U)          /*!< interrupt in USART_CTL0 */
+#define USART_INTS_CTL1               ((uint32_t)0x20000000U)          /*!< interrupt in USART_CTL1 */
+#define USART_INTS_CTL2               ((uint32_t)0x40000000U)          /*!< interrupt in USART_CTL2 */
+#define USART_INTS_CTL3               ((uint32_t)0x80000000U)          /*!< interrupt in USART_CTL3 */
+
+/* function declarations */
+/* initialization functions */
+/* reset USART */
+void usart_deinit(uint32_t usart_periph);
+/* configure usart baud rate value */
+void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval);
+/* configure usart parity function */
+void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg);
+/* configure usart word length */
+void usart_word_length_set(uint32_t usart_periph, uint32_t wlen);
+/* configure usart stop bit length */
+void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen);
+
+/* USART normal mode communication */
+/* enable usart */
+void usart_enable(uint32_t usart_periph);
+/* disable usart */
+void usart_disable(uint32_t usart_periph);
+/* configure USART transmitter */
+void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig);
+/* configure USART receiver */
+void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig);
+/* data is transmitted/received with the LSB/MSB first */
+void usart_data_first_config(uint32_t usart_periph, uint32_t msbf);
+/* configure USART inverted */
+void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara);
+/* configure the USART oversample mode */
+void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp);
+/* configure sample bit method */
+void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm);
+/* enable receiver timeout */
+void usart_receiver_timeout_enable(uint32_t usart_periph);
+/* disable receiver timeout */
+void usart_receiver_timeout_disable(uint32_t usart_periph);
+/* configure receiver timeout threshold */
+void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout);
+/* USART transmit data function */
+void usart_data_transmit(uint32_t usart_periph, uint32_t data);
+/* USART receive data function */
+uint16_t usart_data_receive(uint32_t usart_periph);
+
+/* multi-processor communication */
+/* configure address of the USART */
+void usart_address_config(uint32_t usart_periph, uint8_t addr);
+/* enable mute mode */
+void usart_mute_mode_enable(uint32_t usart_periph);
+/* disable mute mode */
+void usart_mute_mode_disable(uint32_t usart_periph);
+/* configure wakeup method in mute mode */
+void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod);
+
+/* LIN mode communication */
+/* LIN mode enable */
+void usart_lin_mode_enable(uint32_t usart_periph);
+/* LIN mode disable */
+void usart_lin_mode_disable(uint32_t usart_periph);
+/* LIN break detection length */
+void usart_lin_break_dection_length_config(uint32_t usart_periph, uint32_t lblen);
+/* send break frame */
+void usart_send_break(uint32_t usart_periph);
+
+/* half-duplex communication */
+/* half-duplex enable */
+void usart_halfduplex_enable(uint32_t usart_periph);
+/* half-duplex disable */
+void usart_halfduplex_disable(uint32_t usart_periph);
+
+/* synchronous communication */
+/* clock enable */
+void usart_synchronous_clock_enable(uint32_t usart_periph);
+/* clock disable */
+void usart_synchronous_clock_disable(uint32_t usart_periph);
+/* configure usart synchronous mode parameters */
+void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl);
+
+/* smartcard communication */
+/* guard time value configure in smartcard mode */
+void usart_guard_time_config(uint32_t usart_periph,uint32_t gaut);
+/* smartcard mode enable */
+void usart_smartcard_mode_enable(uint32_t usart_periph);
+/* smartcard mode disable */
+void usart_smartcard_mode_disable(uint32_t usart_periph);
+/* NACK enable in smartcard mode */
+void usart_smartcard_mode_nack_enable(uint32_t usart_periph);
+/* NACK disable in smartcard mode */
+void usart_smartcard_mode_nack_disable(uint32_t usart_periph);
+/* smartcard auto-retry number configure */
+void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum);
+/* block length configure */
+void usart_block_length_config(uint32_t usart_periph, uint32_t bl);
+
+/* IrDA communication */
+/* enable IrDA mode */
+void usart_irda_mode_enable(uint32_t usart_periph);
+/* disable IrDA mode */
+void usart_irda_mode_disable(uint32_t usart_periph);
+/* configure the peripheral clock prescaler */
+void usart_prescaler_config(uint32_t usart_periph, uint32_t psc);
+/* configure IrDA low-power */
+void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp);
+
+/* hardware flow communication */
+/* configure hardware flow control RTS */
+void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig);
+/* configure hardware flow control CTS */
+void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig);
+
+/* coherence control */
+/* configure break frame coherence mode */
+void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm);
+/* configure parity check coherence mode */
+void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm);
+/* configure hardware flow control coherence mode */
+void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm);
+
+/* configure USART DMA for reception */
+void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd);
+/* configure USART DMA for transmission */
+void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd);
+
+/* flag functions */
+/* get flag in STAT0/STAT1/CHC register */
+FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag);
+/* clear flag in STAT0/STAT1/CHC register */
+void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag);
+
+/* interrupt functions */
+/* enable USART interrupt */
+void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag);
+/* disable USART interrupt */
+void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag);
+/* get USART interrupt enable flag */
+FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag);
+
+#endif /* GD32F4XX_USART_H */ 

+ 63 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h

@@ -0,0 +1,63 @@
+/*!
+    \file  gd32f4xx_wwdgt.h
+    \brief definitions for the WWDGT 
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_WWDGT_H
+#define GD32F4XX_WWDGT_H
+
+#include "gd32f4xx.h"
+
+/* WWDGT definitions */
+#define WWDGT                       WWDGT_BASE
+
+/* registers definitions */
+#define WWDGT_CTL                   REG32((WWDGT) + 0x00U)          /*!< WWDGT control register */
+#define WWDGT_CFG                   REG32((WWDGT) + 0x04U)          /*!< WWDGT configuration register */
+#define WWDGT_STAT                  REG32((WWDGT) + 0x08U)          /*!< WWDGT status register */
+
+/* bits definitions */
+/* WWDGT_CTL */
+#define WWDGT_CTL_CNT               BITS(0,6)                       /*!< WWDGT counter value */
+#define WWDGT_CTL_WDGTEN            BIT(7)                          /*!< WWDGT counter enable */
+
+/* WWDGT_CFG */
+#define WWDGT_CFG_WIN               BITS(0,6)                       /*!< WWDGT counter window value */
+#define WWDGT_CFG_PSC               BITS(7,8)                       /*!< WWDGT prescaler divider value */
+#define WWDGT_CFG_EWIE              BIT(9)                          /*!< early wakeup interrupt enable */
+
+/* WWDGT_STAT */
+#define WWDGT_STAT_EWIF             BIT(0)                          /*!< early wakeup interrupt flag */
+
+/* constants definitions */
+#define CFG_PSC(regval)             (BITS(7,8) & ((uint32_t)(regval) << 7))   /*!< write value to WWDGT_CFG_PSC bit field */
+#define WWDGT_CFG_PSC_DIV1          CFG_PSC(0)                      /*!< the time base of WWDGT = (PCLK1/4096)/1 */
+#define WWDGT_CFG_PSC_DIV2          CFG_PSC(1)                      /*!< the time base of WWDGT = (PCLK1/4096)/2 */
+#define WWDGT_CFG_PSC_DIV4          CFG_PSC(2)                      /*!< the time base of WWDGT = (PCLK1/4096)/4 */
+#define WWDGT_CFG_PSC_DIV8          CFG_PSC(3)                      /*!< the time base of WWDGT = (PCLK1/4096)/8 */
+
+/* function declarations */
+/* reset the window watchdog timer configuration */
+void wwdgt_deinit(void);
+/* start the window watchdog timer counter */
+void wwdgt_enable(void);
+
+/* configure the window watchdog timer counter value */
+void wwdgt_counter_update(uint16_t counter_value);
+/* configure counter value, window value, and prescaler divider value */
+void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler);
+
+/* enable early wakeup interrupt of WWDGT */
+void wwdgt_interrupt_enable(void);
+/* check early wakeup interrupt state of WWDGT */
+FlagStatus wwdgt_flag_get(void);
+/* clear early wakeup interrupt state of WWDGT */
+void wwdgt_flag_clear(void);
+
+#endif /* GD32F4XX_WWDGT_H */

+ 1042 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c

@@ -0,0 +1,1042 @@
+/*!
+    \file  gd32f4xx_adc.c
+    \brief ADC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_adc.h"
+
+#define REGULAR_CHANNEL_LENGTH_OFFSET             ((uint32_t)20U)
+#define INSERTED_CHANNEL_LENGTH_OFFSET            ((uint32_t)20U)
+#define REGULAR_DISCONTINUOUS_NUMBER              ((uint32_t)13U)
+#define REGULAR_TRIGGER_MODE                      ((uint32_t)28U)
+#define INSERTED_TRIGGER_MODE                     ((uint32_t)20U)
+
+/*!
+    \brief      ADC reset
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_ADCRST);
+    rcu_periph_reset_disable(RCU_ADCRST);
+}
+
+/*!
+    \brief      enable ADC interface
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_enable(uint32_t adc_periph)
+{
+  if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)){
+      ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON;
+  }       
+}
+
+/*!
+    \brief      disable ADC interface
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_disable(uint32_t adc_periph)
+{
+    ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON);
+}
+
+/*!
+    \brief      ADC data alignment config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  inserted_channel : insert channel select
+      \arg        ADC_DATAALIGN_RIGHT: LSB alignment
+      \arg        ADC_DATAALIGN_LEFT: MSB alignment
+    \param[out] none
+    \retval     none
+*/
+void adc_data_alignment_config(uint32_t adc_periph , uint8_t data_alignment)
+{
+    if(data_alignment){
+        ADC_CTL1(adc_periph) |= ADC_CTL1_DAL;
+    }else{
+        ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL);
+    }
+}
+
+/*!
+    \brief      ADC resolution config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  resolution: ADC resolution
+      \arg        ADC_RESOLUTION_12B: 12-bit ADC resolution
+      \arg        ADC_RESOLUTION_10B: 10-bit ADC resolution
+      \arg        ADC_RESOLUTION_8B: 8-bit ADC resolution
+      \arg        ADC_RESOLUTION_6B: 6-bit ADC resolution
+    \param[out] none
+    \retval     none
+*/
+void adc_resolution_config(uint32_t adc_periph , uint32_t resolution)
+{
+    ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DRES);
+    ADC_CTL0(adc_periph) |= (uint32_t)resolution;
+}
+
+/*!
+    \brief      ADC calibration and reset calibration
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_calibration_enable(uint32_t adc_periph)
+{
+    /* reset the selected ADC1 calibration registers */
+    ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB;
+    /* check the RSTCLB bit state */
+    while((ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)){
+    }
+    /* enable ADC calibration process */
+    ADC_CTL1(adc_periph) |= ADC_CTL1_CLB;
+    /* check the CLB bit state */
+    while((ADC_CTL1(adc_periph) & ADC_CTL1_CLB)){
+    }
+}
+
+/*!
+    \brief      ADC discontinuous mode config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: select the channel group
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  length: number of conversions in discontinuous mode,the number can be 1..8
+                        for regular channel ,the number is no effect for inserted channel
+    \param[out] none
+    \retval     none
+*/
+void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length)
+{
+    ADC_CTL0(adc_periph) &= ~((uint32_t)( ADC_CTL0_DISRC | ADC_CTL0_DISIC ));
+    switch(adc_channel_group){
+    case ADC_REGULAR_CHANNEL:
+        /* config the number of conversions in discontinuous mode  */
+        ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM);
+        if((length <= 8U) && (length >= 1U)){
+            ADC_CTL0(adc_periph) |= ((uint32_t)length - 1U) << REGULAR_DISCONTINUOUS_NUMBER;
+        }
+        ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      config end of conversion mode
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  end_selection: end of conversion mode
+      \arg        ADC_EOC_SET_SEQUENCE: only at the end of a sequence of regular conversions, the EOC bit is set
+      \arg        ADC_EOC_SET_CONVERSION: at the end of each regular conversion, the EOC bit is set.
+    \param[out] none
+    \retval     none
+*/
+void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection)
+{
+    switch(end_selection){
+        case ADC_EOC_SET_SEQUENCE:
+            ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM);
+            break;
+        case ADC_EOC_SET_CONVERSION:
+            ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_EOCM);
+            break;
+        default:
+            break;
+    }
+}
+
+/*!
+    \brief      ADC special function enable or disable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  function: select the function to config
+      \arg        ADC_SCAN_MODE: scan mode select
+      \arg        ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
+      \arg        ADC_CONTINUOUS_MODE: continuous mode select
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void adc_special_function_config(uint32_t adc_periph , uint8_t function , ControlStatus newvalue)
+{
+    if(newvalue){
+        switch(function){
+        case ADC_SCAN_MODE:
+            ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_SM;
+            break;
+        case ADC_INSERTED_CHANNEL_AUTO:
+            ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_ICA;
+            break;
+        case ADC_CONTINUOUS_MODE:
+            ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_CTN;
+            break;
+        default:
+            break;
+        }
+    }else{
+        switch(function){
+        case ADC_SCAN_MODE:
+            ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_SM);
+            break;
+        case ADC_INSERTED_CHANNEL_AUTO:
+            ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_ICA);
+            break;
+        case ADC_CONTINUOUS_MODE:
+            ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_CTN);
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+/*!
+    \brief      configure the ADC clock for all the ADCs
+    \param[in]  prescaler: configure ADCs prescaler ratio
+      \arg        ADC_ADCCK_PCLK2_DIV2: PCLK2 div2
+      \arg        ADC_ADCCK_PCLK2_DIV4: PCLK2 div4
+      \arg        ADC_ADCCK_PCLK2_DIV6: PCLK2 div6
+      \arg        ADC_ADCCK_PCLK2_DIV8: PCLK2 div8
+      \arg        ADC_ADCCK_HCLK_DIV5: HCLK div5
+      \arg        ADC_ADCCK_HCLK_DIV6: HCLK div6
+      \arg        ADC_ADCCK_HCLK_DIV10: HCLK div10
+      \arg        ADC_ADCCK_HCLK_DIV20: HCLK div20
+    \param[out] none
+    \retval     none
+*/
+void adc_clock_config(uint32_t prescaler)
+{
+    ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_ADCCK);
+    ADC_SYNCCTL |= (uint32_t) prescaler;
+}
+
+/*!
+    \brief      configure the ADC clock for all the ADCs
+    \param[in]  function: temperature sensor and internal reference voltage channel or VBAT channel 
+      \arg        ADC_VBAT_CHANNEL_SWITCH: channel 18 (1/4 voltate of external battery) switch of ADC0
+      \arg        ADC_TEMP_VREF_CHANNEL_SWITCH: channel 16 (temperature sensor) and 17 (internal reference voltage) switch of ADC0
+    \param[in]  newvalue: ENABLE or DISABLE
+\param[out] none
+    \retval     none
+*/
+void adc_channel_16_to_18(uint8_t function,ControlStatus newvalue)
+{
+    if(newvalue){
+        switch(function){
+        case ADC_VBAT_CHANNEL_SWITCH:
+            ADC_SYNCCTL |= (uint32_t)ADC_SYNCCTL_VBATEN;
+            break;
+        case ADC_TEMP_VREF_CHANNEL_SWITCH:
+            ADC_SYNCCTL |= (uint32_t)ADC_SYNCCTL_TSVREN;
+            break;
+        default:
+            break;
+        }
+    }else{
+        switch(function){
+        case ADC_VBAT_CHANNEL_SWITCH:
+            ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_VBATEN);
+            break;
+        case ADC_TEMP_VREF_CHANNEL_SWITCH:
+            ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_TSVREN);
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+/*!
+    \brief      config the length of regular channel group or inserted channel group
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: select the channel group
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  length: the length of the channel
+                        regular channel 1-16
+                        inserted channel 1-4
+    \param[out] none
+    \retval     none
+*/
+void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length)
+{
+    switch(adc_channel_group){
+    case ADC_REGULAR_CHANNEL:
+        if((length >= 1U) && (length <= 16U)){
+            ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL);
+            ADC_RSQ0(adc_periph) |= (uint32_t)((length-1U) << REGULAR_CHANNEL_LENGTH_OFFSET);
+        }
+        break;
+    case ADC_INSERTED_CHANNEL:
+        if((length >= 1U) && (length <= 4U)){
+            ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL);
+            ADC_ISQ(adc_periph) |= (uint32_t)((length-1U) << INSERTED_CHANNEL_LENGTH_OFFSET);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      ADC external trigger enable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: select the channel group
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  trigger_mode: external trigger mode
+      \arg        EXTERNAL_TRIGGER_DISABLE: external trigger disable
+      \arg        EXTERNAL_TRIGGER_RISING: rising edge of external trigger
+      \arg        EXTERNAL_TRIGGER_FALLING: falling edge of external trigger
+      \arg        EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger
+    \param[out] none
+    \retval     none
+*/
+void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode)
+{
+        switch(adc_channel_group){
+        case ADC_REGULAR_CHANNEL:
+            ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC);
+            ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << REGULAR_TRIGGER_MODE);
+            break;
+        case ADC_INSERTED_CHANNEL:
+            ADC_CTL1(adc_periph) &=  ~((uint32_t)ADC_CTL1_ETMIC);
+            ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << INSERTED_TRIGGER_MODE);
+            break;
+        default:
+            break;
+        }
+}
+
+/*!
+    \brief      ADC external trigger source config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: select the channel group
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  external_trigger_source: regular or inserted group trigger source
+                for regular channel:
+      \arg        ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CC0 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CC1 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CC2 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CC1 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T1_CH2: external trigger timer 1 CC2 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T1_CH3: external trigger timer 1 CC3 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T1_TRGO: external trigger timer 1 TRGO event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T2_CH0 : external trigger timer 2 CC0 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T2_TRGO : external trigger timer 2 TRGO event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T3_CH3: external trigger timer 3 CC3 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T4_CH0: external trigger timer 4 CC0 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T4_CH1: external trigger timer 4 CC1 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T4_CH2: external trigger timer 4 CC2 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T7_CH0: external trigger timer 7 CC0 event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_T7_TRGO: external trigger timer 7 TRGO event select for regular channel 
+      \arg        ADC_EXTTRIG_REGULAR_EXTI_11: external trigger extiline 11 select for regular channel 
+                for inserted channel:
+      \arg        ADC_EXTTRIG_INSERTED_T0_CH3: timer0 capture compare 3 
+      \arg        ADC_EXTTRIG_INSERTED_T0_TRGO: timer0 TRGO event 
+      \arg        ADC_EXTTRIG_INSERTED_T1_CH0: timer1 capture compare 0 
+      \arg        ADC_EXTTRIG_INSERTED_T1_TRGO: timer1 TRGO event 
+      \arg        ADC_EXTTRIG_INSERTED_T2_CH1: timer2 capture compare 1 
+      \arg        ADC_EXTTRIG_INSERTED_T2_CH3: timer2 capture compare 3 
+      \arg        ADC_EXTTRIG_INSERTED_T3_CH0: timer3 capture compare 0 
+      \arg        ADC_EXTTRIG_INSERTED_T3_CH1: timer3 capture compare 1 
+      \arg        ADC_EXTTRIG_INSERTED_T3_CH2: timer3 capture compare 2 
+      \arg        ADC_EXTTRIG_INSERTED_T3_TRGO: timer3 capture compare TRGO 
+      \arg        ADC_EXTTRIG_INSERTED_T4_CH3: timer4 capture compare 3 
+      \arg        ADC_EXTTRIG_INSERTED_T4_TRGO: timer4 capture compare TRGO 
+      \arg        ADC_EXTTRIG_INSERTED_T7_CH1: timer7 capture compare 1 
+      \arg        ADC_EXTTRIG_INSERTED_T7_CH2: timer7 capture compare 2 
+      \arg        ADC_EXTTRIG_INSERTED_T7_CH3: timer7 capture compare 3 
+      \arg        ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 
+    \param[out] none
+    \retval     none
+*/
+void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source)
+{   
+    switch(adc_channel_group){
+    case ADC_REGULAR_CHANNEL:
+        ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC);
+        ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC);
+        ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      ADC software trigger enable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: select the channel group
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[out] none
+    \retval     none
+*/
+void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group)
+{
+    switch(adc_channel_group){
+    case ADC_REGULAR_CHANNEL:
+        ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      get the ADC flag bits
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_flag: the adc flag bits
+      \arg        ADC_FLAG_WDE: analog watchdog event flag
+      \arg        ADC_FLAG_EOC: end of group conversion flag
+      \arg        ADC_FLAG_EOIC: end of inserted group conversion flag
+      \arg        ADC_FLAG_STIC: start flag of inserted channel group
+      \arg        ADC_FLAG_STRC: start flag of regular channel group
+      \arg        ADC_FLAG_ROVF: regular data register overflow flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag)
+{
+  if(ADC_STAT(adc_periph) & adc_flag){
+    return SET;
+  }
+  return RESET;
+
+}
+
+/*!
+    \brief      clear the ADC flag bits
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_flag: the adc flag bits
+      \arg        ADC_FLAG_WDE: analog watchdog event flag
+      \arg        ADC_FLAG_EOC: end of group conversion flag
+      \arg        ADC_FLAG_EOIC: end of inserted group conversion flag
+      \arg        ADC_FLAG_STIC: start flag of inserted channel group
+      \arg        ADC_FLAG_STRC: start flag of regular channel group
+      \arg        ADC_FLAG_ROVF: regular data register overflow flag
+    \param[out] none
+    \retval     none
+*/
+void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag)
+{
+    ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag);
+}
+
+/*!
+    \brief      get the ADC interrupt bits
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_interrupt: the adc interrupt bits
+      \arg        ADC_INT_WDE: analog watchdog interrupt
+      \arg        ADC_INT_EOC: end of group conversion interrupt
+      \arg        ADC_INT_EOIC: end of inserted group conversion interrupt
+      \arg        ADC_INT_ROVF: regular data register overflow interrupt
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt)
+{
+    FlagStatus interrupt_flag = RESET;
+    uint32_t state;
+    /* check the interrupt bits */
+    switch(adc_interrupt){
+    case ADC_INT_WDE:
+        state = ADC_STAT(adc_periph) & ADC_STAT_WDE;
+        if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state){
+          interrupt_flag = SET;
+        }
+        break;
+    case ADC_INT_EOC:
+        state = ADC_STAT(adc_periph) & ADC_STAT_EOC;
+          if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state){
+            interrupt_flag = SET;
+          }
+        break;
+    case ADC_INT_EOIC:
+        state = ADC_STAT(adc_periph) & ADC_STAT_EOIC;
+        if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state){
+            interrupt_flag = SET;
+        }
+        break;
+    case ADC_INT_ROVF:
+        state = ADC_STAT(adc_periph) & ADC_STAT_ROVF;
+        if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state){
+          interrupt_flag = SET;
+        }
+        break;
+    default:
+        break;
+    }
+    return interrupt_flag;
+}
+
+/*!
+    \brief      clear the ADC flag
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_flag: the adc status flag
+      \arg        ADC_INT_WDE: analog watchdog interrupt
+      \arg        ADC_INT_EOC: end of group conversion interrupt
+      \arg        ADC_INT_EOIC: end of inserted group conversion interrupt
+      \arg        ADC_INT_ROVF: regular data register overflow interrupt
+    \param[out] none
+    \retval     none
+*/
+void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt)
+{
+    ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt);
+}
+
+/*!
+    \brief      ADC interrupt enable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_flag: the adc interrupt flag
+      \arg        ADC_INT_WDE: analog watchdog interrupt flag
+      \arg        ADC_INT_EOC: end of group conversion interrupt flag
+      \arg        ADC_INT_EOIC: end of inserted group conversion interrupt flag
+      \arg        ADC_INT_ROVF: regular data register overflow interrupt flag
+    \param[out] none
+    \retval     none
+*/
+void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt)
+{
+    switch(adc_interrupt){
+    case ADC_INT_WDE:
+        ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE;
+        break;
+    case ADC_INT_EOC:
+        ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE;
+        break;
+    case ADC_INT_EOIC:
+        ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE;
+        break;
+    case ADC_INT_ROVF:
+        ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_ROVFIE;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      ADC interrupt disable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_flag: the adc interrupt flag
+      \arg        ADC_INT_WDE: analog watchdog interrupt flag
+      \arg        ADC_INT_EOC: end of group conversion interrupt flag
+      \arg        ADC_INT_EOIC: end of inserted group conversion interrupt flag
+      \arg        ADC_INT_ROVF: regular data register overflow interrupt flag
+    \param[out] none
+    \retval     none
+*/
+void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt)
+{
+    switch(adc_interrupt){
+    /* select the interrupt source */
+    case ADC_INT_WDE:
+        ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDEIE);
+        break;
+    case ADC_INT_EOC:
+        ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOCIE);
+        break;
+    case ADC_INT_EOIC:
+        ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOICIE);
+        break;
+    case ADC_INT_ROVF:
+        ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_ROVFIE);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      ADC analog watchdog single channel disable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_single_channel_disable(uint32_t adc_periph )
+{
+    ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDSC);
+}
+
+/*!
+    \brief      ADC analog watchdog single channel enable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel: the selected ADC channel
+      \arg        ADC_CHANNEL_x: ADC Channelx(x=0..18)
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channel)
+{
+    ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDCHSEL);
+
+    ADC_CTL0(adc_periph) |= (uint32_t)adc_channel;
+    ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDSC;
+}
+
+/*!
+    \brief      adc analog watchdog group channel config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: the channel group use analog watchdog 
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+      \arg        ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_enable(uint32_t adc_periph , uint8_t adc_channel_group)
+{
+    ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC));
+    /* select the group */
+    switch(adc_channel_group){
+    case ADC_REGULAR_CHANNEL:
+        ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN;
+        break;
+    case ADC_REGULAR_INSERTED_CHANNEL:
+        ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      ADC analog watchdog disable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  adc_channel_group: the channel group use analog watchdog 
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+      \arg        ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group)
+{
+    /* select the group */
+    switch(adc_channel_group){
+    case ADC_REGULAR_CHANNEL:
+        ADC_CTL0(adc_periph) &=  ~((uint32_t)ADC_CTL0_RWDEN);
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL0(adc_periph) &=  ~((uint32_t)ADC_CTL0_IWDEN);
+        break;
+    case ADC_REGULAR_INSERTED_CHANNEL:
+        ADC_CTL0(adc_periph) &=  ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN));
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      ADC analog watchdog threshold config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  low_threshold: analog watchdog low threshold,0..4095
+    \param[in]  high_threshold: analog watchdog high threshold,0..4095
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold)
+{
+    ADC_WDLT(adc_periph) = (uint32_t)low_threshold;
+    ADC_WDHT(adc_periph) = (uint32_t)high_threshold;
+}
+
+/*!
+    \brief      ADC regular channel config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  rank: the regular group sequencer rank,this parameter must be between 0 to 15
+    \param[in]  adc_channel: the selected ADC channel
+      \arg        ADC_CHANNEL_x(x=0..18): ADC Channelx
+    \param[in]  sample_time: the sample time value
+      \arg        ADC_SAMPLETIME_3: 3 cycles
+      \arg        ADC_SAMPLETIME_15: 15 cycles
+      \arg        ADC_SAMPLETIME_28: 28 cycles
+      \arg        ADC_SAMPLETIME_56: 56 cycles
+      \arg        ADC_SAMPLETIME_84: 84 cycles
+      \arg        ADC_SAMPLETIME_112: 112 cycles
+      \arg        ADC_SAMPLETIME_144: 144 cycles
+      \arg        ADC_SAMPLETIME_480: 480 cycles
+    \param[out] none
+    \retval     none
+*/
+void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time)
+{
+    uint32_t rsq,sampt;
+    
+    /* ADC regular sequence config */
+    if(rank < 6U){
+        rsq = ADC_RSQ2(adc_periph);
+        rsq &=  ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank)));
+        rsq |= ((uint32_t)adc_channel << (5U*rank));
+        ADC_RSQ2(adc_periph) = rsq;
+    }else if(rank < 12U){
+        rsq = ADC_RSQ1(adc_periph);
+        rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U))));
+        rsq |= ((uint32_t)adc_channel << (5U*(rank-6U)));
+        ADC_RSQ1(adc_periph) = rsq;
+    }else if(rank < 16U){
+        rsq = ADC_RSQ0(adc_periph);
+        rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U))));
+        rsq |= ((uint32_t)adc_channel << (5U*(rank-12U)));
+        ADC_RSQ0(adc_periph) = rsq;
+    }else{
+    }
+    
+    /* ADC sampling time config */
+    if(adc_channel < 10U){
+        sampt = ADC_SAMPT1(adc_periph);
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel)));
+        sampt |= (uint32_t)(sample_time << (3U*adc_channel));
+        ADC_SAMPT1(adc_periph) = sampt;
+    }else if(adc_channel < 19U){
+        sampt = ADC_SAMPT0(adc_periph);
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U))));
+        sampt |= (uint32_t)(sample_time << (3U*(adc_channel-10U)));
+        ADC_SAMPT0(adc_periph) = sampt;
+    }else{
+    }
+}
+
+/*!
+    \brief      ADC regular group data register read
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  none
+    \param[out] none
+    \retval     the conversion value
+*/
+uint16_t adc_regular_data_read(uint32_t adc_periph)
+{
+    return (uint16_t)(ADC_RDATA(adc_periph));
+}
+
+/*!
+    \brief      ADC inserted channel config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  rank: the inserted group sequencer rank,this parameter must be between 0 to 3
+    \param[in]  adc_channel: the selected ADC channel
+      \arg        ADC_CHANNEL_x(x=0..18): ADC Channelx
+    \param[in]  sample_time: The sample time value
+      \arg        ADC_SAMPLETIME_3: 3 cycles
+      \arg        ADC_SAMPLETIME_15: 15 cycles
+      \arg        ADC_SAMPLETIME_28: 28 cycles
+      \arg        ADC_SAMPLETIME_56: 56 cycles
+      \arg        ADC_SAMPLETIME_84: 84 cycles
+      \arg        ADC_SAMPLETIME_112: 112 cycles
+      \arg        ADC_SAMPLETIME_144: 144 cycles
+      \arg        ADC_SAMPLETIME_480: 480 cycles
+    \param[out] none
+    \retval     none
+*/
+void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint8_t sample_time)
+{
+    uint8_t inserted_length;
+    uint32_t isq,sampt;
+
+    inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U);
+    if(rank < 4U){
+        isq = ADC_ISQ(adc_periph);
+        isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U-(inserted_length-rank)*5U)));
+        isq |= ((uint32_t)adc_channel << (15U-(inserted_length-rank)*5U));
+        ADC_ISQ(adc_periph) = isq;
+    }
+
+    if(adc_channel < 10U){
+        sampt = ADC_SAMPT1(adc_periph);
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel)));
+        sampt |= (uint32_t) sample_time << (3U*adc_channel);
+        ADC_SAMPT1(adc_periph) = sampt;
+    }else if(adc_channel < 19U){
+        sampt = ADC_SAMPT0(adc_periph);
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U))));
+        sampt |= ((uint32_t)sample_time << (3U*(adc_channel-10U)));
+        ADC_SAMPT0(adc_periph) = sampt;
+    }else{
+    }
+}
+
+/*!
+    \brief      ADC inserted channel offset config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  inserted_channel : insert channel select
+      \arg        ADC_INSERTED_CHANNEL_0: inserted channel0
+      \arg        ADC_INSERTED_CHANNEL_1: inserted channel1
+      \arg        ADC_INSERTED_CHANNEL_2: inserted channel2
+      \arg        ADC_INSERTED_CHANNEL_3: inserted channel3
+    \param[in]  offset : the offset data
+    \param[out] none
+    \retval     the conversion value
+*/
+void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset)
+{
+    /* config the offset of the selected channels */
+  if(ADC_INSERTED_CHANNEL_0 == inserted_channel){
+      ADC_IOFF0(adc_periph) = (uint32_t)offset;
+  }else if(ADC_INSERTED_CHANNEL_1 == inserted_channel){
+      ADC_IOFF1(adc_periph) = (uint32_t)offset;
+  }else if(ADC_INSERTED_CHANNEL_2 == inserted_channel){
+      ADC_IOFF2(adc_periph) = (uint32_t)offset;
+  }else if(ADC_INSERTED_CHANNEL_3 == inserted_channel){
+      ADC_IOFF3(adc_periph) = (uint32_t)offset;
+  }else{
+  }
+}
+
+/*!
+    \brief      ADC inserted group data register read
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  inserted_channel : insert channel select
+      \arg        ADC_INSERTED_CHANNEL_0: inserted Channel0
+      \arg        ADC_INSERTED_CHANNEL_1: inserted channel1
+      \arg        ADC_INSERTED_CHANNEL_2: inserted Channel2
+      \arg        ADC_INSERTED_CHANNEL_3: inserted Channel3
+    \param[out] none
+    \retval     the conversion value
+*/
+uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel)
+{
+    uint32_t idata;
+    /* read the data of the selected channel */
+    switch(inserted_channel){
+    case ADC_INSERTED_CHANNEL_0:
+        idata = ADC_IDATA0(adc_periph);
+        break;
+    case ADC_INSERTED_CHANNEL_1:
+        idata = ADC_IDATA1(adc_periph);
+        break;
+    case ADC_INSERTED_CHANNEL_2:
+        idata = ADC_IDATA2(adc_periph);
+        break;
+    case ADC_INSERTED_CHANNEL_3:
+        idata = ADC_IDATA3(adc_periph);
+        break;
+    default:
+        idata = 0U;
+        break;
+    }
+    return (uint16_t)idata;
+}
+
+/*!
+    \brief      DMA request enable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_dma_mode_enable(uint32_t adc_periph)
+{
+    ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA);
+}
+
+/*!
+    \brief      DMA request disable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_dma_mode_disable(uint32_t adc_periph)
+{
+    ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA);
+}
+
+/*!
+    \brief      when DMA=1, the DMA engine issues a request at end of each regular conversion
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_dma_request_after_last_enable(uint32_t adc_periph)
+{
+    ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DDM);
+}
+
+/*!
+    \brief      the DMA engine is disabled after the end of transfer signal from DMA controller is detected
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_dma_request_after_last_disable(uint32_t adc_periph)
+{
+    ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DDM);
+}
+
+/*!
+    \brief      ADC oversample mode config
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[in]  mode: ADC oversampling mode
+      \arg        ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger
+      \arg        ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger
+    \param[in]  shift: ADC oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
+    \param[in]  ratio: ADC oversampling ratio
+      \arg        ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2
+      \arg        ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4
+      \arg        ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8
+      \arg        ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16
+      \arg        ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32
+      \arg        ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64
+      \arg        ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128
+      \arg        ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256
+    \param[out] none
+    \retval     none
+*/
+void adc_oversample_mode_config(uint32_t adc_periph , uint8_t mode , uint16_t shift , uint8_t ratio)
+{
+    if(ADC_OVERSAMPLING_ONE_CONVERT == mode){
+        ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS;
+    }else{
+        ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS);
+    }
+    /* config the shift and ratio */
+    ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS));
+    ADC_OVSAMPCTL(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio);
+}
+
+/*!
+    \brief      ADC oversample mode enable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_oversample_mode_enable(uint32_t adc_periph)
+{
+    ADC_OVSAMPCTL(adc_periph) |= ADC_OVSAMPCTL_OVSEN;
+}
+
+/*!
+    \brief      ADC oversample mode disable
+    \param[in]  adc_periph: ADCx,x=0,1,2
+    \param[out] none
+    \retval     none
+*/
+void adc_oversample_mode_disable(uint32_t adc_periph)
+{
+    ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
+}
+
+/*!
+    \brief      configure the ADC sync mode
+    \param[in]  sync_mode: ADC sync mode 
+      \arg        ADC_SYNC_MODE_INDEPENDENT: all the ADCs work independently
+      \arg        ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel & inserted parallel mode
+      \arg        ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel & trigger rotation mode
+      \arg        ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode
+      \arg        ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode
+      \arg        ADC_DAUL_REGULAL_FOLLOW_UP: ADC0 and ADC1 work in follow-up mode
+      \arg        ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode
+      \arg        ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined regular parallel & inserted parallel mode
+      \arg        ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION: all ADCs work in combined regular parallel & trigger rotation mode
+      \arg        ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode
+      \arg        ADC_ALL_REGULAL_PARALLEL: all ADCs work in regular parallel mode
+      \arg        ADC_ALL_REGULAL_FOLLOW_UP: all ADCs work in follow-up mode
+      \arg        ADC_ALL_INSERTED_TRRIGGER_ROTATION: all ADCs work in trigger rotation mode
+    \param[out] none
+    \retval     none
+*/
+void adc_sync_mode_config(uint32_t sync_mode)
+{
+    ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCM);
+    ADC_SYNCCTL |= sync_mode;
+}
+
+/*!
+    \brief      configure the delay between 2 sampling phases in ADC sync modes
+    \param[in]  sample_delay:  the delay between 2 sampling phases in ADC sync modes 
+      \arg        ADC_SYNC_DELAY_xCYCLE: x=5..20,the delay between 2 sampling phases in ADC sync modes is x ADC clock cycles
+    \param[out] none
+    \retval     none
+*/
+void adc_sync_delay_config(uint32_t sample_delay)
+{
+    ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDLY);
+    ADC_SYNCCTL |= sample_delay;
+}
+
+/*!
+    \brief      configure ADC sync DMA mode selection
+    \param[in]  dma_mode:  ADC sync DMA mode
+      \arg        ADC_SYNC_DMA_DISABLE: ADC sync DMA disabled
+      \arg        ADC_SYNC_DMA_MODE0: ADC sync DMA disabled
+      \arg        ADC_SYNC_DMA_MODE1: ADC sync DMA disabled
+    \param[out] none
+    \retval     none
+*/
+void adc_sync_dma_config(uint32_t dma_mode )
+{
+    ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDMA);
+    ADC_SYNCCTL |= dma_mode;
+}
+
+/*!
+    \brief      configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_sync_dma_request_after_last_enable(void)
+{
+    ADC_SYNCCTL |= ADC_SYNCCTL_SYNCDDM;
+}
+
+/*!
+    \brief      configure ADC sync DMA engine issues requests according to the SYNCDMA bits
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_sync_dma_request_after_last_disable(void)
+{
+    ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDDM);
+}
+
+/*!
+    \brief      ADC sync regular data register read
+    \param[in]  none
+    \param[out] none
+    \retval     sync regular data
+*/
+uint32_t adc_sync_regular_data_read(void)
+{
+    return (uint32_t)ADC_SYNCDATA;
+}

+ 863 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c

@@ -0,0 +1,863 @@
+/*!
+    \file  gd32f4xx_can.c
+    \brief CAN driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_can.h"
+
+/*!
+    \brief      deinitialize CAN 
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void can_deinit(uint32_t can_periph)
+{
+    if(CAN0 == can_periph){
+        rcu_periph_reset_enable(RCU_CAN0RST);
+        rcu_periph_reset_disable(RCU_CAN0RST);
+    }else{
+        rcu_periph_reset_enable(RCU_CAN1RST);
+        rcu_periph_reset_disable(RCU_CAN1RST);
+    }
+}
+
+/*!
+    \brief      initialize CAN
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  can_parameter_struct: parameters for CAN initializtion
+                  can_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
+                  can_sjw: CAN_BT_SJW_xTQ(x=1, 2, 3, 4)
+                  can_bs1: CAN_BT_BS1_xTQ(1..16)
+                  can_bs2: CAN_BT_BS2_xTQ(1..8)
+                  can_ttc: ENABLE or DISABLE
+                  can_abor: ENABLE or DISABLE
+                  can_awu: ENABLE or DISABLE
+                  can_ard: ENABLE or DISABLE
+                  can_rfod: ENABLE or DISABLE
+                  can_tfo: ENABLE or DISABLE
+                  can_psc: 0x0001 - 0x03FF
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
+{
+    uint32_t timeout = CAN_TIMEOUT;
+    ErrStatus flag = ERROR;
+    
+    /* disable sleep mode */
+    CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
+    /* enable initialize mode */
+    CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
+    /* wait ACK */
+    while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){
+        timeout--;
+    }
+    /* check initialize working success */
+    if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
+        flag = ERROR;
+    } else {
+        /* set the bit timing register */
+        CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
+                              BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
+                              BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
+                              BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
+                              BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
+        /* time trigger communication mode */
+        if(ENABLE == can_parameter_init->time_triggered){
+            CAN_CTL(can_periph) |= CAN_CTL_TTC;
+        }else{
+            CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
+        }
+        /* automatic bus-off managment */
+        if(ENABLE == can_parameter_init->auto_bus_off_recovery){
+            CAN_CTL(can_periph) |= CAN_CTL_ABOR;
+        }else{
+            CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
+        }
+        /* automatic wakeup mode */
+        if(ENABLE == can_parameter_init->auto_wake_up){
+            CAN_CTL(can_periph) |= CAN_CTL_AWU;
+        }else{
+            CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
+        }
+        /* automatic retransmission mode */
+        if(ENABLE == can_parameter_init->auto_retrans){
+            CAN_CTL(can_periph) |= CAN_CTL_ARD;
+        }else{
+            CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
+        }
+        /* receive fifo overwrite mode */        
+        if(ENABLE == can_parameter_init->rec_fifo_overwrite){
+            CAN_CTL(can_periph) |= CAN_CTL_RFOD;
+        }else{
+            CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
+        } 
+        /* transmit fifo order */
+        if(ENABLE == can_parameter_init->trans_fifo_order){
+            CAN_CTL(can_periph) |= CAN_CTL_TFO;
+        }else{
+            CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
+        }  
+        /* disable initialize mode */
+        CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
+        timeout = CAN_TIMEOUT;
+        /* wait the ACK */
+        while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){
+            timeout--;
+        }
+        /* check exit initialize mode */
+        if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){
+            flag = SUCCESS;
+        }
+    }  
+    return flag;
+}
+
+/*!
+    \brief      initialize CAN filter 
+    \param[in]  can_filter_parameter_struct: struct for CAN filter initialization
+                  can_filter_list_high: 0x0000 - 0xFFFF
+                  can_filter_list_low: 0x0000 - 0xFFFF
+                  can_filter_mask_high: 0x0000 - 0xFFFF
+                  can_filter_mask_low: 0x0000 - 0xFFFF
+                  can_filter_fifo_number: CAN_FIFO0, CAN_FIFO1 
+                  can_filter_number: 0 - 27
+                  can_filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
+                  can_filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT 
+                  can_filter_enable: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init)
+{
+    uint32_t val = 0U;
+    
+    val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
+    /* filter lock disable */
+    CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
+    /* disable filter */
+    CAN_FW(CAN0) &= ~(uint32_t)val;
+    
+    /* filter 16 bits */
+    if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){
+        /* set filter 16 bits */
+        CAN_FSCFG(CAN0) &= ~(uint32_t)val;
+        /* first 16 bits list and  first 16 bits mask or first 16 bits list and  second 16 bits list */
+        CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
+                                FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \
+                                FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
+        /* second 16 bits list and  second 16 bits mask or third 16 bits list and  fourth 16 bits list */
+        CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
+                                FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \
+                                FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
+    }
+    /* filter 32 bits */
+    if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){
+        /* set filter 32 bits */
+        CAN_FSCFG(CAN0) |= (uint32_t)val;
+        /* 32 bits list or first 32 bits list */
+        CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
+                                FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) |
+                                FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
+        /* 32 bits mask or second 32 bits list */
+        CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
+                                FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) |
+                                FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
+    }
+    
+    /* filter mode */
+    if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){
+        /* mask mode */
+        CAN_FMCFG(CAN0) &= ~(uint32_t)val;
+    }else{
+        /* list mode */
+        CAN_FMCFG(CAN0) |= (uint32_t)val;
+    }
+    
+    /* filter FIFO */
+    if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){
+        /* FIFO0 */
+        CAN_FAFIFO(CAN0) &= ~(uint32_t)val;
+    }
+    
+    if(CAN_FIFO1 == can_filter_parameter_init->filter_fifo_number){
+        /* FIFO1 */
+        CAN_FAFIFO(CAN0) |= (uint32_t)val;
+    }
+    
+    /* filter working */
+    if(ENABLE == can_filter_parameter_init->filter_enable){
+        
+        CAN_FW(CAN0) |= (uint32_t)val;
+    }
+    
+    /* filter lock enable */
+    CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
+}
+
+/*!
+    \brief      set CAN1 fliter start bank number
+    \param[in]  can1_start_bank_number
+      \arg        (1..27)
+    \param[out] none
+    \retval     none
+*/
+void can1_filter_start_bank(uint8_t start_bank)
+{
+    /* filter lock disable */
+    CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
+    /* set CAN1 filter start number */
+    CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
+    CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
+    /* filter lock enaable */
+    CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
+}
+
+/*!
+    \brief      enable CAN debug freeze
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void can_debug_freeze_enable(uint32_t can_periph)
+{
+    CAN_CTL(can_periph) |= CAN_CTL_DFZ;
+    if(CAN0 == can_periph){
+        dbg_periph_enable(DBG_CAN0_HOLD);
+    }else{
+        dbg_periph_enable(DBG_CAN1_HOLD);
+    }
+}
+
+/*!
+    \brief      disable CAN debug freeze
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void can_debug_freeze_disable(uint32_t can_periph)
+{
+    CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
+    if(CAN0 == can_periph){
+        dbg_periph_disable(DBG_CAN0_HOLD);
+    }else{
+        dbg_periph_disable(DBG_CAN0_HOLD);
+    }
+}
+
+/*!
+    \brief      enable CAN time trigger mode
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void can_time_trigger_mode_enable(uint32_t can_periph)
+{
+    uint8_t mailbox_number;
+    
+    /* enable the tcc mode */
+    CAN_CTL(can_periph) |= CAN_CTL_TTC;
+    /* enable time stamp */
+    for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){
+        CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
+    }
+}
+
+/*!
+    \brief      disable CAN time trigger mode
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void can_time_trigger_mode_disable(uint32_t can_periph)
+{
+    uint8_t mailbox_number; 
+    
+    /* disable the TCC mode */
+    CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
+    /* reset TSEN bits */
+    for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){
+        CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
+    }
+}
+
+/*!
+    \brief      CAN transmit message
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  can_trasnmit_message_struct: struct for CAN transmit message
+                  can_rx_sfid: 0x00000000 - 0x000007FF
+                  can_rx_efid: 0x00000000 - 0x1FFFFFFF
+                  can_rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
+                  can_rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
+                  can_rx_dlenc: 1 - 7
+                  can_rx_data[]: 0x00 - 0xFF
+    \param[out] none
+    \retval     none
+*/
+uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
+{
+    uint8_t mailbox_number = CAN_MAILBOX0;
+
+    /* select one empty mailbox */
+    if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
+        mailbox_number = CAN_MAILBOX0;
+    }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
+        mailbox_number = CAN_MAILBOX1;
+    }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
+        mailbox_number = CAN_MAILBOX2;
+    }else{
+        mailbox_number = CAN_NOMAILBOX;
+    }
+    if(CAN_NOMAILBOX == mailbox_number){
+        return CAN_NOMAILBOX;
+    }
+    
+    CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
+    if(CAN_FF_STANDARD == transmit_message->tx_ff){
+        /* set transmit mailbox standard identifier */
+        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
+                                                transmit_message->tx_ft);
+    }else{
+        /* set transmit mailbox extended identifier */
+        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
+                                                transmit_message->tx_ff | \
+                                                transmit_message->tx_ft);
+    }
+    /* set the data length */
+    transmit_message->tx_dlen &= (uint8_t)(CAN_TMP_DLENC);
+    CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC);
+    CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
+    /* set the data */
+    CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
+                                              TMDATA0_DB2(transmit_message->tx_data[2]) | \
+                                              TMDATA0_DB1(transmit_message->tx_data[1]) | \
+                                              TMDATA0_DB0(transmit_message->tx_data[0]);
+    CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
+                                              TMDATA1_DB6(transmit_message->tx_data[6]) | \
+                                              TMDATA1_DB5(transmit_message->tx_data[5]) | \
+                                              TMDATA1_DB4(transmit_message->tx_data[4]);
+    /* enable transmission */
+    CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
+
+    return mailbox_number;
+}
+
+/*!
+    \brief      CAN transmit state 
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  mailbox_number
+      \arg        CAN_MAILBOX(x=0,1,2)
+    \param[out] none
+    \retval     can_transmit_state_enum
+*/
+can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number)
+{
+    can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
+    uint32_t val = 0U;
+     
+    switch(mailbox_number){
+    case CAN_MAILBOX0:
+        val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
+        break;
+    case CAN_MAILBOX1:
+        val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
+        break;
+    case CAN_MAILBOX2:
+        val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
+        break;
+    default:
+        val = CAN_TRANSMIT_FAILED;
+        break;
+    }
+    switch(val){
+        /* transmit pending  */
+    case (CAN_STATE_PENDING): 
+        state = CAN_TRANSMIT_PENDING;
+        break;
+        /* transmit failed  */
+    case (CAN_TSTAT_MTF0 | CAN_TSTAT_TME0): 
+        state = CAN_TRANSMIT_FAILED;
+        break;
+    case (CAN_TSTAT_MTF1 | CAN_TSTAT_TME1): 
+        state = CAN_TRANSMIT_FAILED;
+        break;
+    case (CAN_TSTAT_MTF2 | CAN_TSTAT_TME2): 
+        state = CAN_TRANSMIT_FAILED;
+        break;
+        /* transmit succeeded  */
+    case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
+        state = CAN_TRANSMIT_OK;
+        break;
+    case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
+        state = CAN_TRANSMIT_OK;
+        break;
+    case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
+        state = CAN_TRANSMIT_OK;
+        break;
+    default: 
+        state = CAN_TRANSMIT_FAILED;
+        break;
+    }
+    return state;
+}
+
+/*!
+    \brief      CAN stop transmission
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  mailbox_number
+      \arg        CAN_MAILBOXx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
+{
+    if(CAN_MAILBOX0 == mailbox_number){
+        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
+    }else if(CAN_MAILBOX1 == mailbox_number){
+        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
+    }else if(CAN_MAILBOX2 == mailbox_number){
+        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
+    }else{
+        /* illegal parameter*/
+    }
+}
+
+/*!
+    \brief      CAN receive message
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  fifo_number
+      \arg        CAN_FIFO0x(x=0,1)
+    \param[out]  can_receive_message_struct: struct for CAN receive message
+                  can_rx_sfid: 0x00000000 - 0x000007FF
+                  can_rx_efid: 0x00000000 - 0x1FFFFFFF
+                  can_rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
+                  can_rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
+                  can_rx_dlenc: 1 - 7
+                  can_rx_data[]: 0x00 - 0xFF
+                  can_rx_fi: 0 - 27
+    \retval     none
+*/
+void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
+{
+    /* get the frame format */
+    receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
+    if(CAN_FF_STANDARD == receive_message->rx_ff){
+        /* get standard identifier */
+        receive_message -> rx_sfid = (uint32_t)(RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
+    }else{
+        /* get extended identifier */
+        receive_message -> rx_efid = (uint32_t)(RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
+    }
+    
+    /* get frame type */
+    receive_message -> rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
+    /* get recevie data length */
+    receive_message -> rx_dlen = (uint8_t)(RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));        
+    /* filtering index */
+    receive_message -> rx_fi = (uint8_t)(RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));     
+    
+    /* receive data */
+    receive_message -> rx_data[0] = (uint8_t)(RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+    receive_message -> rx_data[1] = (uint8_t)(RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+    receive_message -> rx_data[2] = (uint8_t)(RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+    receive_message -> rx_data[3] = (uint8_t)(RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+    receive_message -> rx_data[4] = (uint8_t)(RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+    receive_message -> rx_data[5] = (uint8_t)(RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+    receive_message -> rx_data[6] = (uint8_t)(RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+    receive_message -> rx_data[7] = (uint8_t)(RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+    
+    /* release FIFO */
+    if(CAN_FIFO0 == fifo_number){
+        CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
+    }else{
+        CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
+    }
+}
+
+/*!
+    \brief      release FIFO0
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+      \arg        CAN_FIFO0x(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void can_fifo_release(uint32_t can_periph, uint8_t fifo_number)
+{
+    if(CAN_FIFO0 == fifo_number){
+        CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
+    }else if(CAN_FIFO1 == fifo_number){
+        CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
+    }else{
+        /* illegal parameter */
+    }
+}
+
+/*!
+    \brief      CAN receive message length
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+      \arg        CAN_FIFO0x(x=0,1) 
+    \param[out] none
+    \retval     message length
+*/
+uint8_t can_receive_message_length(uint32_t can_periph, uint8_t fifo_number)
+{
+    uint8_t val = 0U;
+    
+    if(CAN_FIFO0 == fifo_number){
+        val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIFO_RFL0_MASK);
+    }else if(CAN_FIFO0 == fifo_number){
+        val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIFO_RFL0_MASK);
+    }else{
+        /* illegal parameter */
+    }
+    return val;
+}
+
+/*!
+    \brief      set CAN working mode
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  can_working_mode
+      \arg        CAN_INITIALIZE_MODE
+      \arg        CAN_NORMAL_MODE
+      \arg        CAN_SLEEP_MODE
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode)
+{
+    ErrStatus flag = ERROR;
+    /* timeout for IWS or also for SLPWS bits*/
+    uint32_t timeout = CAN_TIMEOUT; 
+    
+    if(CAN_MODE_INITIALIZE == working_mode){
+        /* disable sleep mode */
+        CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
+        /* set initialize mode */
+        CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
+        /* wait the acknowledge */
+        while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout != 0U)){
+            timeout--;
+        }
+        if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
+            flag = ERROR;
+        }else{
+            flag = SUCCESS;
+        }
+    }else if(CAN_MODE_NORMAL == working_mode){
+        /* enter normal mode */
+        CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
+        /* wait the acknowledge */
+        while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (timeout != 0U)){
+            timeout--;
+        }
+        if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
+            flag = ERROR;
+        }else{
+            flag = SUCCESS;
+        }
+    }else if(CAN_MODE_SLEEP == working_mode){
+        /* disable initialize mode */
+        CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
+        /* set sleep mode */
+        CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
+        /* wait the acknowledge */
+        while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (timeout != 0U)){
+            timeout--;
+        }
+        if (CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
+            flag = ERROR;
+        }else{
+            flag = SUCCESS;
+        }
+    }else{
+        flag = ERROR;
+    }
+    return  flag;
+}
+
+/*!
+    \brief      wake up CAN
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_wakeup(uint32_t can_periph)
+{
+    ErrStatus flag = ERROR;
+    uint32_t timeout = CAN_TIMEOUT;
+    
+    /* wakeup */
+    CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
+    
+    while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (timeout != 0x00U)){
+        timeout--;
+    }
+    if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
+        flag = ERROR;
+    }else{
+        flag = SUCCESS;
+    }
+    return flag;
+}
+
+/*!
+    \brief      get CAN error type
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     can_error_enum
+*/
+can_error_enum can_error_get(uint32_t can_periph)
+{
+    can_error_enum error;
+    error = CAN_ERROR_NONE;
+    
+    /* get error type */
+    error = (can_error_enum)((CAN_ERR(can_periph) & CAN_ERR_ERRN) >> 4U);
+    return error;
+}
+
+/*!
+    \brief      CAN receive error number
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     error number
+*/
+uint8_t can_receive_error_number(uint32_t can_periph)
+{
+    uint8_t val;
+    
+    val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_RECNT) >> 24U);
+    return val;
+}
+
+/*!
+    \brief      CAN transmit error number
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[out] none
+    \retval     error number
+*/
+uint8_t can_transmit_error_number(uint32_t can_periph)
+{
+    uint8_t val;
+    
+    val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_TECNT) >> 16U);
+    return val;
+}
+
+/*!
+    \brief      enable CAN interrupt 
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  interrupt 
+      \arg        CAN_INTEN_TMEIE
+      \arg        CAN_INTEN_RFNEIE0
+      \arg        CAN_INTEN_RFFIE0
+      \arg        CAN_INTEN_RFOIE0
+      \arg        CAN_INTEN_RFNEIE1
+      \arg        CAN_INTEN_RFFIE1
+      \arg        CAN_INTEN_RFOIE1
+      \arg        CAN_INTEN_WERRIE
+      \arg        CAN_INTEN_PERRIE
+      \arg        CAN_INTEN_BOIE
+      \arg        CAN_INTEN_ERRNIE
+      \arg        CAN_INTEN_ERRIE
+      \arg        CAN_INTEN_WUIE
+      \arg        CAN_INTEN_SLPWIE
+    \param[out] none
+    \retval     none
+*/
+void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt)
+{
+    CAN_INTEN(can_periph) |= interrupt;
+}
+
+/*!
+    \brief      disable CAN interrupt 
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  interrupt
+      \arg        CAN_INTEN_TMEIE
+      \arg        CAN_INTEN_RFNEIE0
+      \arg        CAN_INTEN_RFFIE0
+      \arg        CAN_INTEN_RFOIE0
+      \arg        CAN_INTEN_RFNEIE1
+      \arg        CAN_INTEN_RFFIE1
+      \arg        CAN_INTEN_RFOIE1
+      \arg        CAN_INTEN_WERRIE
+      \arg        CAN_INTEN_PERRIE
+      \arg        CAN_INTEN_BOIE
+      \arg        CAN_INTEN_ERRNIE
+      \arg        CAN_INTEN_ERRIE
+      \arg        CAN_INTEN_WUIE
+      \arg        CAN_INTEN_SLPWIE
+    \param[out] none
+    \retval     none
+*/
+void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt)
+{
+    CAN_INTEN(can_periph) &= ~interrupt;
+}
+
+/*!
+    \brief      get CAN flag state
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  flag: CAN flags, refer to can_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        CAN_FLAG_MTE2
+      \arg        CAN_FLAG_MTE1
+      \arg        CAN_FLAG_MTE0
+      \arg        CAN_FLAG_MTF2
+      \arg        CAN_FLAG_MTF1
+      \arg        CAN_FLAG_MTF0
+      \arg        CAN_FLAG_RFO0
+      \arg        CAN_FLAG_RFF0
+      \arg        CAN_FLAG_RFO1
+      \arg        CAN_FLAG_RFF1
+      \arg        CAN_FLAG_BOERR
+      \arg        CAN_FLAG_PERR
+      \arg        CAN_FLAG_WERR
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
+{  
+    if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear CAN flag state
+     \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  flag: CAN flags, refer to can_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        CAN_FLAG_MTE2
+      \arg        CAN_FLAG_MTE1
+      \arg        CAN_FLAG_MTE0
+      \arg        CAN_FLAG_MTF2
+      \arg        CAN_FLAG_MTF1
+      \arg        CAN_FLAG_MTF0
+      \arg        CAN_FLAG_RFO0
+      \arg        CAN_FLAG_RFF0
+      \arg        CAN_FLAG_RFO1
+      \arg        CAN_FLAG_RFF1
+    \param[out] none
+    \retval     none
+*/
+void can_flag_clear(uint32_t can_periph, can_flag_enum flag)
+{
+    CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag));
+}
+
+/*!
+    \brief      get CAN interrupt flag state
+    \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  flag: CAN interrupt flags, refer to can_interrupt_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        CAN_INT_SLPIF
+      \arg        CAN_INT_WUIF
+      \arg        CAN_INT_ERRIF
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
+{  
+    FlagStatus inten = RESET;
+    FlagStatus temp = RESET;
+    FlagStatus status1 = RESET;
+    FlagStatus status2 = RESET;
+    
+    switch(flag){
+    /* get the status of sleep working interrupt enable bit */
+    case CAN_INT_SLPIF:
+        inten = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_SLPWIE);
+        break;
+    /* get the status of wakeup interrupt enable bit */
+    case CAN_INT_WUIF:
+        inten = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_WUIE);
+        break;
+    /* get the status of error falgs and its enable bit */
+    case CAN_INT_ERRIF:
+        /* check if the BOERR bit in CAN_ERR register and BOIE bit in CAN_INTEN register are set */
+        status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_BOIE);
+        status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_BOERR);
+        if((RESET != status1) && (RESET != status2)){
+            inten = SET;
+        }
+        /* check if the WERR bit in CAN_ERR register and WERRIE bit in CAN_INTEN register are set */
+        status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_WERRIE);
+        status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_WERR);
+        if((RESET != status1) && (RESET != status2)){
+            inten = SET;
+        }
+        /* check if the PERR bit in CAN_ERR register and PERRIE bit in CAN_INTEN register are set */
+        status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_PERRIE);
+        status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_PERR);
+        if((RESET != status1) && (RESET != status2)){
+            inten = SET;
+        }
+        /* check if the ERRN bit in CAN_ERR register and ERRNIE bit in CAN_INTEN register are set */
+        status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_ERRNIE);
+        status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_ERRN);
+        if((RESET != status1) && (RESET != status2)){
+            inten = SET;
+        }
+        break;
+    default:
+        break;
+    }
+    /* get the interrupt flag */
+    temp = (FlagStatus)(CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)));
+    /* check the interrupt enable bit and corresponding flag bit are set */
+    if((RESET != inten) && (RESET != temp)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear CAN interrupt flag state
+     \param[in]  can_periph
+      \arg        CANx(x=0,1)
+    \param[in]  flag: CAN interrupt flags, refer to can_interrupt_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        CAN_INT_SLPIF
+      \arg        CAN_INT_WUIF
+      \arg        CAN_INT_ERRIF
+    \param[out] none
+    \retval     none
+*/
+void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag)
+{
+    CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag));
+}

+ 101 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c

@@ -0,0 +1,101 @@
+/*!
+    \file  gd32f4xx_crc.c
+    \brief CRC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_crc.h"
+
+/*!
+    \brief      deinit CRC calculation unit
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void crc_deinit(void)
+{
+    CRC_DATA  = (uint32_t)0xFFFFFFFFU;
+    CRC_FDATA = (uint32_t)0x00000000U;
+    CRC_CTL   = CRC_CTL_RST;
+}
+
+/*!
+    \brief      reset data register to the value of initializaiton data register
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void crc_data_register_reset(void)
+{
+    CRC_CTL |= (uint32_t)CRC_CTL_RST;
+}
+
+/*!
+    \brief      read the data register 
+    \param[in]  none
+    \param[out] none
+    \retval     32-bit value of the data register
+*/
+uint32_t crc_data_register_read(void)
+{
+    uint32_t data;
+    data = CRC_DATA;
+    return (data);
+}
+
+/*!
+    \brief      read the free data register
+    \param[in]  none
+    \param[out] none
+    \retval     8-bit value of the free data register
+*/
+uint8_t crc_free_data_register_read(void)
+{
+    uint8_t fdata;
+    fdata = (uint8_t)CRC_FDATA;
+    return (fdata);
+}
+
+/*!
+    \brief      write the free data register
+    \param[in]  free_data: specify 8-bit data
+    \param[out] none
+    \retval     none
+*/
+void crc_free_data_register_write(uint8_t free_data)
+{
+    CRC_FDATA = (uint32_t)free_data;
+}
+
+/*!
+    \brief      CRC calculate a 32-bit data
+    \param[in]  sdata: specify 32-bit data
+    \param[out] none
+    \retval     32-bit CRC calculate value
+*/
+uint32_t crc_single_data_calculate(uint32_t sdata)
+{
+    CRC_DATA = sdata;
+    return (CRC_DATA);
+}
+
+/*!
+    \brief      CRC calculate a 32-bit data array
+    \param[in]  array: pointer to an array of 32 bit data words
+    \param[in]  size: size of the array
+    \param[out] none
+    \retval     32-bit CRC calculate value
+*/
+uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size)
+{
+    uint32_t index;
+    for(index = 0U; index < size; index++){
+        CRC_DATA = array[index];
+    }
+    return (CRC_DATA);
+}

+ 358 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c

@@ -0,0 +1,358 @@
+/*!
+    \file  gd32f4xx_ctc.c
+    \brief CTC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_ctc.h"
+
+#define CTC_FLAG_MASK            ((uint32_t)0x00000700U)
+
+/*!
+    \brief      reset CTC clock trim controller
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ctc_deinit(void)
+{
+    /* reset CTC */
+    rcu_periph_reset_enable(RCU_CTCRST);
+    rcu_periph_reset_disable(RCU_CTCRST);
+}
+
+/*!
+    \brief      configure the IRC48M trim value
+    \param[in]  ctc_trim_value: 8-bit IRC48M trim value
+    \param[out] none
+    \retval     none
+*/
+void ctc_irc48m_trim_value_config(uint8_t ctc_trim_value)
+{
+    /* clear TRIMVALUE bits */
+    CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE);
+    /* set TRIMVALUE bits */
+    CTC_CTL0 |= ((uint32_t)ctc_trim_value << 8);
+}
+
+/*!
+    \brief      generate software reference source sync pulse
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ctc_software_refsource_pulse_generate(void)
+{
+    CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL;
+}
+
+/*!
+    \brief      configure hardware automatically trim mode
+    \param[in]  ctc_hardmode:
+      \arg        CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable
+      \arg        CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable
+    \param[out] none
+    \retval     none
+*/
+void ctc_hardware_trim_mode_config(uint32_t ctc_hardmode)
+{
+    CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM);
+    CTC_CTL0 |= (uint32_t)ctc_hardmode;
+}
+
+/*!
+    \brief      enable CTC counter
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ctc_counter_enable(void)
+{
+    CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN;
+}
+
+/*!
+    \brief      disable CTC counter
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ctc_counter_disable(void)
+{
+    CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN);
+}
+
+/*!
+    \brief      configure reference signal source polarity
+    \param[in]  ctc_polarity:
+      \arg        CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge
+      \arg        CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge
+    \param[out] none
+    \retval     none
+*/
+void ctc_refsource_polarity_config(uint32_t ctc_polarity)
+{
+    CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL);
+    CTC_CTL1 |= (uint32_t)ctc_polarity;
+}
+
+/*!
+    \brief      select USBFS or USBHS SOF signal
+    \param[in]  ctc_usbsof:
+      \arg        CTC_USBSOFSEL_USBHS: USBHS SOF signal is selected
+      \arg        CTC_USBSOFSEL_USBFS: USBFS SOF signal is selected
+    \param[out] none
+    \retval     none
+*/
+void ctc_usbsof_signal_select(uint32_t ctc_usbsof)
+{
+    CTC_CTL1 &= (uint32_t)(~CTC_CTL1_USBSOFSEL);
+    CTC_CTL1 |= (uint32_t)ctc_usbsof;
+}
+
+/*!
+    \brief      select reference signal source
+    \param[in]  ctc_refs:
+      \arg        CTC_REFSOURCE_GPIO: GPIO is selected
+      \arg        CTC_REFSOURCE_LXTAL: LXTAL is clock selected
+      \arg        CTC_REFSOURCE_USBSOF: USBSOF is selected
+    \param[out] none
+    \retval     none
+*/
+void ctc_refsource_signal_select(uint32_t ctc_refs)
+{
+    CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
+    CTC_CTL1 |= (uint32_t)ctc_refs;
+}
+
+/*!
+    \brief      configure reference signal source prescaler
+    \param[in]  ctc_prescaler:
+      \arg        CTC_REFSOURCE_PSC_OFF: reference signal not divided
+      \arg        CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2
+      \arg        CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4
+      \arg        CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8
+      \arg        CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16
+      \arg        CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32
+      \arg        CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64
+      \arg        CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128
+    \param[out] none
+    \retval     none
+*/
+void ctc_refsource_prescaler_config(uint32_t ctc_prescaler)
+{
+    CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
+    CTC_CTL1 |= (uint32_t)ctc_prescaler;
+}
+
+/*!
+    \brief      configure clock trim base limit value
+    \param[in]  ctc_limit_value: 8-bit clock trim base limit value
+    \param[out] none
+    \retval     none
+*/
+void ctc_clock_limit_value_config(uint8_t ctc_limit_value)
+{
+    CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
+    CTC_CTL1 |= (uint32_t)((uint32_t)ctc_limit_value << 16);
+}
+
+/*!
+    \brief      configure CTC counter reload value
+    \param[in]  ctc_reload_value: 16-bit CTC counter reload value
+    \param[out] none
+    \retval     none
+*/
+void ctc_counter_reload_value_config(uint16_t ctc_reload_value)
+{
+    CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
+    CTC_CTL1 |= (uint32_t)ctc_reload_value;
+}
+
+/*!
+    \brief      read CTC counter capture value when reference sync pulse occurred
+    \param[in]  none
+    \param[out] none
+    \retval     the 16-bit CTC counter capture value
+*/
+uint16_t ctc_counter_capture_value_read(void)
+{
+    uint16_t capture_value = 0U;
+    capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> 16);
+    return (capture_value);
+}
+
+/*!
+    \brief      read CTC trim counter direction when reference sync pulse occurred
+    \param[in]  none
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+      \arg        SET: CTC trim counter direction is down-counting
+      \arg        RESET: CTC trim counter direction is up-counting
+*/
+FlagStatus ctc_counter_direction_read(void)
+{
+    if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      read CTC counter reload value
+    \param[in]  none
+    \param[out] none
+    \retval     the 16-bit CTC counter reload value
+*/
+uint16_t ctc_counter_reload_value_read(void)
+{
+    uint16_t reload_value = 0U;
+    reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE);
+    return (reload_value);
+}
+
+/*!
+    \brief      read the IRC48M trim value
+    \param[in]  none
+    \param[out] none
+    \retval     the 8-bit IRC48M trim value
+*/
+uint8_t ctc_irc48m_trim_value_read(void)
+{
+    uint8_t trim_value = 0U;
+    trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> 8);
+    return (trim_value);
+}
+
+/*!
+    \brief      enable the CTC interrupt
+    \param[in]  ctc_interrupt: CTC interrupt enable
+      \arg        CTC_INT_CKOKIE: clock trim OK interrupt enable
+      \arg        CTC_INT_CKWARNIE: clock trim warning interrupt enable
+      \arg        CTC_INT_ERRIE: error interrupt enable
+      \arg        CTC_INT_EREFIE: expect reference interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void ctc_interrupt_enable(uint32_t ctc_interrupt)
+{
+    CTC_CTL0 |= (uint32_t)ctc_interrupt; 
+}
+
+/*!
+    \brief      disable the CTC interrupt
+    \param[in]  ctc_interrupt: CTC interrupt enable source
+      \arg        CTC_INT_CKOKIE: clock trim OK interrupt enable
+      \arg        CTC_INT_CKWARNIE: clock trim warning interrupt enable
+      \arg        CTC_INT_ERRIE: error interrupt enable
+      \arg        CTC_INT_EREFIE: expect reference interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void ctc_interrupt_disable(uint32_t ctc_interrupt)
+{
+    CTC_CTL0 &= (uint32_t)(~ctc_interrupt); 
+}
+
+/*!
+    \brief      get CTC interrupt flag
+    \param[in]  ctc_interrupt: the CTC interrupt flag
+      \arg        CTC_INT_CKOK: clock trim OK interrupt
+      \arg        CTC_INT_CKWARN: clock trim warning interrupt 
+      \arg        CTC_INT_ERR: error interrupt 
+      \arg        CTC_INT_EREF: expect reference interrupt
+      \arg        CTC_INT_CKERR: clock trim error bit interrupt
+      \arg        CTC_INT_REFMISS: reference sync pulse miss interrupt 
+      \arg        CTC_INT_TRIMERR: trim value error interrupt
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus ctc_interrupt_flag_get(uint32_t ctc_interrupt)
+{
+    uint32_t interrupt = 0U, intenable = 0U;
+
+    if(ctc_interrupt & CTC_FLAG_MASK){
+        intenable = CTC_CTL0 & CTC_INT_ERRIE;
+    }else{
+        intenable = CTC_CTL0 & ctc_interrupt;
+    }
+    interrupt = CTC_STAT & ctc_interrupt;
+
+    if(interrupt && intenable){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear CTC interrupt flag
+    \param[in]  ctc_interrupt: the CTC interrupt flag
+      \arg        CTC_INT_CKOK: clock trim OK interrupt
+      \arg        CTC_INT_CKWARN: clock trim warning interrupt 
+      \arg        CTC_INT_ERR: error interrupt 
+      \arg        CTC_INT_EREF: expect reference interrupt 
+      \arg        CTC_INT_CKERR: clock trim error bit interrupt
+      \arg        CTC_INT_REFMISS: reference sync pulse miss interrupt 
+      \arg        CTC_INT_TRIMERR: trim value error interrupt
+    \param[out] none
+    \retval     none
+*/ 
+void ctc_interrupt_flag_clear(uint32_t ctc_interrupt)
+{
+    if(ctc_interrupt & CTC_FLAG_MASK){
+        CTC_INTC |= CTC_INTC_ERRIC;
+    }else{
+        CTC_INTC |= ctc_interrupt;
+    }
+}
+
+/*!
+    \brief      get CTC flag
+    \param[in]  ctc_flag: the CTC flag
+      \arg        CTC_FLAG_CKOK: clock trim OK flag
+      \arg        CTC_FLAG_CKWARN: clock trim warning flag 
+      \arg        CTC_FLAG_ERR: error flag 
+      \arg        CTC_FLAG_EREF: expect reference flag
+      \arg        CTC_FLAG_CKERR: clock trim error bit
+      \arg        CTC_FLAG_REFMISS: reference sync pulse miss
+      \arg        CTC_FLAG_TRIMERR: trim value error bit
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus ctc_flag_get(uint32_t ctc_flag)
+{
+    if(RESET != (CTC_STAT & ctc_flag)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear CTC flag
+    \param[in]  ctc_flag: the CTC flag
+      \arg        CTC_FLAG_CKOK: clock trim OK flag
+      \arg        CTC_FLAG_CKWARN: clock trim warning flag 
+      \arg        CTC_FLAG_ERR: error flag 
+      \arg        CTC_FLAG_EREF: expect reference flag
+      \arg        CTC_FLAG_CKERR: clock trim error bit
+      \arg        CTC_FLAG_REFMISS: reference sync pulse miss
+      \arg        CTC_FLAG_TRIMERR: trim value error bit
+    \param[out] none
+    \retval     none
+*/
+void ctc_flag_clear(uint32_t ctc_flag)
+{
+    if(ctc_flag & CTC_FLAG_MASK){
+        CTC_INTC |= CTC_INTC_ERRIC;
+    }else{
+        CTC_INTC |= ctc_flag;
+    }
+}

+ 650 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c

@@ -0,0 +1,650 @@
+/*!
+    \file  gd32f4xx_dac.c
+    \brief DAC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_dac.h"
+
+/*!
+    \brief      deinitialize DAC
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_DACRST);
+    rcu_periph_reset_disable(RCU_DACRST);
+}
+
+/*!
+    \brief      enable DAC
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_enable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL |= DAC_CTL_DEN0;
+    }else{
+        DAC_CTL |= DAC_CTL_DEN1;
+    }
+} 
+
+/*!
+    \brief      disable DAC
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_disable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DEN0;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DEN1;
+    }
+}
+
+/*!
+    \brief      enable DAC DMA function
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_dma_enable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL |= DAC_CTL_DDMAEN0;
+    }else{
+        DAC_CTL |= DAC_CTL_DDMAEN1;
+    }
+}
+
+/*!
+    \brief      disable DAC DMA function
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_dma_disable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DDMAEN0;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DDMAEN1;
+    }
+}
+
+/*!
+    \brief      enable DAC output buffer
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_output_buffer_enable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DBOFF0;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DBOFF1;
+    }
+}
+
+/*!
+    \brief      disable DAC output buffer
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_output_buffer_disable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL |= DAC_CTL_DBOFF0;
+    }else{
+        DAC_CTL |= DAC_CTL_DBOFF1;
+    }
+}
+
+/*!
+    \brief      enable DAC trigger
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_trigger_enable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL |= DAC_CTL_DTEN0;
+    }else{
+        DAC_CTL |= DAC_CTL_DTEN1;
+    }
+}
+
+/*!
+    \brief      disable DAC trigger
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_trigger_disable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DTEN0;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DTEN1;
+    }
+}
+
+/*!
+    \brief      enable DAC software trigger
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \retval     none
+*/
+void dac_software_trigger_enable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_SWT |= DAC_SWT_SWTR0;
+    }else{
+        DAC_SWT |= DAC_SWT_SWTR1;
+    }
+}
+
+/*!
+    \brief      disable DAC software trigger
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_software_trigger_disable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_SWT &= ~DAC_SWT_SWTR0;
+    }else{
+        DAC_SWT &= ~DAC_SWT_SWTR1;
+    }
+}
+
+/*!
+    \brief      enable DAC interrupt(DAC0 DMA underrun interrupt)
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_interrupt_enable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL |= DAC_CTL_DDUDRIE0;
+    }else{
+        DAC_CTL |= DAC_CTL_DDUDRIE1;
+    }
+}
+
+/*!
+    \brief      disable DAC interrupt(DAC0 DMA underrun interrupt)
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_interrupt_disable(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DDUDRIE0;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DDUDRIE1;
+    }
+}
+
+/*!
+    \brief      set DAC trigger source
+    \param[in]  dac_periph
+      \arg        DACx(x =0,1)
+    \param[in]  triggersource: external triggers of DAC
+      \arg        DAC_TRIGGER_T1_TRGO: TIMER1 TRGO
+      \arg        DAC_TRIGGER_T3_TRGO: TIMER3 TRGO
+      \arg        DAC_TRIGGER_T4_TRGO: TIMER4 TRGO
+      \arg        DAC_TRIGGER_T5_TRGO: TIMER5 TRGO
+      \arg        DAC_TRIGGER_T6_TRGO: TIMER6 TRGO
+      \arg        DAC_TRIGGER_T7_TRGO: TIMER7 TRGO
+      \arg        DAC_TRIGGER_EXTI_9: EXTI interrupt line9 event
+      \arg        DAC_TRIGGER_SOFTWARE: software trigger
+    \param[out] none
+    \retval     none
+*/
+void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DTSEL0;
+        DAC_CTL |= triggersource;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DTSEL1;
+        DAC_CTL |= (triggersource << 16);
+    }
+}
+
+/*!
+    \brief      configure DAC wave mode
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[in]  wave_mode
+      \arg        DAC_WAVE_DISABLE: wave disable
+      \arg        DAC_WAVE_MODE_LFSR: LFSR noise mode
+      \arg        DAC_WAVE_MODE_TRIANGLE: triangle noise mode
+    \param[out] none
+    \retval     none
+*/
+void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DWM0;
+        DAC_CTL |= wave_mode;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DWM1;
+        DAC_CTL |= wave_mode << 16;
+    }
+}
+
+/*!
+    \brief      configure DAC wave bit width
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[in]  bit_width
+      \arg        DAC_WAVE_BIT_WIDTH_1: bit width of the wave signal is 1
+      \arg        DAC_WAVE_BIT_WIDTH_2: bit width of the wave signal is 2
+      \arg        DAC_WAVE_BIT_WIDTH_3: bit width of the wave signal is 3
+      \arg        DAC_WAVE_BIT_WIDTH_4: bit width of the wave signal is 4
+      \arg        DAC_WAVE_BIT_WIDTH_5: bit width of the wave signal is 5
+      \arg        DAC_WAVE_BIT_WIDTH_6: bit width of the wave signal is 6
+      \arg        DAC_WAVE_BIT_WIDTH_7: bit width of the wave signal is 7
+      \arg        DAC_WAVE_BIT_WIDTH_8: bit width of the wave signal is 8
+      \arg        DAC_WAVE_BIT_WIDTH_9: bit width of the wave signal is 9
+      \arg        DAC_WAVE_BIT_WIDTH_10: bit width of the wave signal is 10
+      \arg        DAC_WAVE_BIT_WIDTH_11: bit width of the wave signal is 11
+      \arg        DAC_WAVE_BIT_WIDTH_12: bit width of the wave signal is 12
+    \param[out] none
+    \retval     none
+*/
+void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DWBW0;
+        DAC_CTL |= bit_width;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DWBW1;
+        DAC_CTL |= bit_width << 16;
+    }
+}
+
+/*!
+    \brief      configure DAC LFSR noise mode
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[in]  unmask_bits
+      \arg        DAC_LFSR_BIT0: unmask the LFSR bit0
+      \arg        DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0]
+      \arg        DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0]
+      \arg        DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0]
+      \arg        DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0]
+      \arg        DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0]
+      \arg        DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0]
+      \arg        DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0]
+      \arg        DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0]
+      \arg        DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0]
+      \arg        DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0]
+      \arg        DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0]
+    \param[out] none
+    \retval     none
+*/
+void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DWBW0;
+        DAC_CTL |= unmask_bits;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DWBW1;
+        DAC_CTL |= unmask_bits << 16;
+    }
+}
+
+/*!
+    \brief      configure DAC triangle noise mode
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[in]  amplitude
+      \arg        DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1
+      \arg        DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3
+      \arg        DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7
+      \arg        DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15
+      \arg        DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31
+      \arg        DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63
+      \arg        DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127
+      \arg        DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255
+      \arg        DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511
+      \arg        DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023
+      \arg        DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047
+      \arg        DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095
+    \param[out] none
+    \retval     none
+*/
+void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude)
+{
+    if(DAC0 == dac_periph){
+        DAC_CTL &= ~DAC_CTL_DWBW0;
+        DAC_CTL |= amplitude;
+    }else{
+        DAC_CTL &= ~DAC_CTL_DWBW1;
+        DAC_CTL |= amplitude << 16;
+    }
+}
+
+/*!
+    \brief      get DAC output value
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     DAC output data
+*/
+uint16_t dac_output_value_get(uint32_t dac_periph)
+{
+    uint16_t data = 0U;
+    if(DAC0 == dac_periph){
+        data = (uint16_t)DAC0_DO;
+    }else{
+        data = (uint16_t)DAC1_DO;
+    }
+    return data;
+}
+
+/*!
+    \brief      enable DAC concurrent mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_enable(void)
+{
+    uint32_t ctl = 0U;
+    ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1;
+    DAC_CTL |= (ctl);
+}
+
+/*!
+    \brief      disable DAC concurrent mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_disable(void)
+{
+    uint32_t ctl = 0U;
+    ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1;
+    DAC_CTL &= (~ctl);
+}
+
+/*!
+    \brief      enable DAC concurrent software trigger function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_software_trigger_enable(void)
+{
+    uint32_t swt = 0U;
+    swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1;
+    DAC_SWT |= (swt); 
+}
+
+/*!
+    \brief      disable DAC concurrent software trigger function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_software_trigger_disable(void)
+{
+    uint32_t swt = 0U;
+    swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1;
+    DAC_SWT &= (~swt);
+}
+
+/*!
+    \brief      enable DAC concurrent buffer function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_output_buffer_enable(void)
+{
+    uint32_t ctl = 0U;
+    ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1;
+    DAC_CTL &= (~ctl);
+}
+
+/*!
+    \brief      disable DAC concurrent buffer function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_output_buffer_disable(void)
+{
+    uint32_t ctl = 0U;
+    ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1;
+    DAC_CTL |= (ctl);
+}
+
+/*!
+    \brief      enable DAC concurrent interrupt funcution
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_interrupt_enable(void)
+{
+    uint32_t ctl = 0U;
+    ctl = DAC_CTL_DDUDRIE0 | DAC_CTL_DDUDRIE1;
+    DAC_CTL |= (ctl);
+}
+
+/*!
+    \brief      disable DAC concurrent interrupt funcution
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_interrupt_disable(void)
+{
+    uint32_t ctl = 0U;
+    ctl = DAC_CTL_DDUDRIE0 | DAC_CTL_DDUDRIE1;
+    DAC_CTL &= (~ctl);
+}
+
+/*!
+    \brief      set the DAC specified data holding register value
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[in]  dac_align
+      \arg        DAC_ALIGN_8B_R: data right 8b alignment
+      \arg        DAC_ALIGN_12B_R: data right 12b alignment
+      \arg        DAC_ALIGN_12B_L: data left 12b alignment
+    \param[in]  data: data to be loaded
+    \param[out] none
+    \retval     none
+*/
+void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data)
+{
+    if(DAC0 == dac_periph){
+        switch(dac_align){
+        /* data right 12b alignment */
+        case DAC_ALIGN_12B_R:
+            DAC0_R12DH = data;
+            break;
+        /* data left 12b alignment */
+        case DAC_ALIGN_12B_L:
+            DAC0_L12DH = data;
+            break;
+        /* data right 8b alignment */
+        case DAC_ALIGN_8B_R:
+            DAC0_R8DH = data;
+            break;
+        default:
+            break;
+        }
+    }else{
+        switch(dac_align){
+        /* data right 12b alignment */
+        case DAC_ALIGN_12B_R:
+            DAC1_R12DH = data;
+            break;
+        /* data left 12b alignment */
+        case DAC_ALIGN_12B_L:
+            DAC1_L12DH = data;
+            break;
+        /* data right 8b alignment */
+        case DAC_ALIGN_8B_R:
+            DAC1_R8DH = data;
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+/*!
+    \brief      set DAC concurrent mode data holding register value
+    \param[in]  dac_align
+      \arg        DAC_ALIGN_8B_R: data right 8b alignment
+      \arg        DAC_ALIGN_12B_R: data right 12b alignment
+      \arg        DAC_ALIGN_12B_L: data left 12b alignment
+    \param[in]  data0: data to be loaded
+    \param[in]  data1: data to be loaded
+    \param[out] none
+    \retval     none
+*/
+void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1)
+{
+    uint32_t data = 0U;
+    switch(dac_align){
+    /* data right 12b alignment */
+    case DAC_ALIGN_12B_R:
+        data = ((uint32_t)data1 << 16) | data0;
+        DACC_R12DH = data;
+        break;
+    /* data left 12b alignment */
+    case DAC_ALIGN_12B_L:
+        data = ((uint32_t)data1 << 16) | data0;
+        DACC_L12DH = data;
+        break;
+    /* data right 8b alignment */
+    case DAC_ALIGN_8B_R:
+        data = ((uint32_t)data1 << 8) | data0;
+        DACC_R8DH = data;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      get the specified DAC flag(DAC DMA underrun flag)
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     the state of dac bit(SET or RESET)
+*/
+FlagStatus dac_flag_get(uint32_t dac_periph)
+{
+    FlagStatus temp_flag = RESET;
+    if(DAC0 == dac_periph){
+        /* check the DMA underrun flag */
+        if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)){
+            temp_flag = SET;
+        }
+    }else{
+        /* check the DMA underrun flag */
+        if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)){
+            temp_flag = SET;
+        }
+    }
+    return temp_flag;
+}
+
+/*!
+    \brief      clear the specified DAC flag(DAC DMA underrun flag)
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_flag_clear(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_STAT |= DAC_STAT_DDUDR0;
+    }else{
+        DAC_STAT |= DAC_STAT_DDUDR1;
+    }
+}
+
+/*!
+    \brief      get the specified DAC interrupt flag(DAC DMA underrun interrupt flag)
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     the state of DAC interrupt flag(SET or RESET)
+*/
+FlagStatus dac_interrupt_flag_get(uint32_t dac_periph)
+{
+    FlagStatus temp_flag = RESET;
+    uint32_t ddudr_flag = 0U, ddudrie_flag = 0U;
+    if(DAC0 == dac_periph){
+        /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */
+        ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0;
+        ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0;
+        if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){
+            temp_flag = SET;
+        }
+    }else{
+        /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */
+        ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1;
+        ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1;
+        if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){
+            temp_flag = SET;
+        }
+    }
+    return temp_flag;
+}
+
+/*!
+    \brief      clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag)
+    \param[in]  dac_periph
+      \arg        DACx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void dac_interrupt_flag_clear(uint32_t dac_periph)
+{
+    if(DAC0 == dac_periph){
+        DAC_STAT |= DAC_STAT_DDUDR0;
+    }else{
+        DAC_STAT |= DAC_STAT_DDUDR1;
+    }
+}

+ 122 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c

@@ -0,0 +1,122 @@
+/*!
+    \file  gd32f4xx_dbg.c
+    \brief DBG driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_dbg.h"
+
+/*!
+    \brief      read DBG_ID code register
+    \param[in]  none
+    \param[out] none
+    \retval     DBG_ID code
+*/
+uint32_t dbg_id_get(void)
+{
+    return DBG_ID;
+}
+
+/*!
+    \brief      enable low power behavior when the mcu is in debug mode
+    \param[in]  dbg_low_power:
+                this parameter can be any combination of the following values:
+      \arg        DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode
+      \arg        DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode
+      \arg        DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode
+    \param[out] none
+    \retval     none
+*/
+void dbg_low_power_enable(uint32_t dbg_low_power)
+{
+    DBG_CTL0 |= dbg_low_power;
+}
+
+/*!
+    \brief      disable low power behavior when the mcu is in debug mode
+    \param[in]  dbg_low_power:
+                this parameter can be any combination of the following values:
+      \arg        DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode
+      \arg        DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode
+      \arg        DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode
+    \param[out] none
+    \retval     none
+*/
+void dbg_low_power_disable(uint32_t dbg_low_power)
+{
+    DBG_CTL0 &= ~dbg_low_power;
+}
+
+/*!
+    \brief      enable peripheral behavior when the mcu is in debug mode
+    \param[in]  dbg_periph: dbg_periph_enum
+    \param[out] none
+    \retval     none
+*/
+void dbg_periph_enable(dbg_periph_enum dbg_periph)
+{
+    if(RESET == ((uint32_t)dbg_periph & BIT(30))){
+        DBG_CTL1 |= (uint32_t)dbg_periph;
+    }else{
+        DBG_CTL2 |= ((uint32_t)dbg_periph & (~BIT(30)));
+    }        
+
+}
+
+/*!
+    \brief      disable peripheral behavior when the mcu is in debug mode
+    \param[in]  dbg_periph: dbg_periph_enum
+    \param[out] none
+    \retval     none
+*/
+void dbg_periph_disable(dbg_periph_enum dbg_periph)
+{
+    if(RESET == ((uint32_t)dbg_periph & BIT(30))){
+        DBG_CTL1 &= ~(uint32_t)dbg_periph;
+    }else{
+        DBG_CTL2 &= ~((uint32_t)dbg_periph & (~BIT(30)));
+    }  
+}
+
+/*!
+    \brief      enable trace pin assignment
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dbg_trace_pin_enable(void)
+{
+    DBG_CTL0 |= DBG_CTL0_TRACE_IOEN;
+}
+
+/*!
+    \brief      disable trace pin assignment
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dbg_trace_pin_disable(void)
+{
+    DBG_CTL0 &= ~DBG_CTL0_TRACE_IOEN;
+}
+
+/*!
+    \brief      trace pin mode selection 
+    \param[in]  trace_mode:
+      \arg        TRACE_MODE_ASYNC: trace pin used for async mode 
+      \arg        TRACE_MODE_SYNC_DATASIZE_1: trace pin used for sync mode and data size is 1
+      \arg        TRACE_MODE_SYNC_DATASIZE_2: trace pin used for sync mode and data size is 2
+      \arg        TRACE_MODE_SYNC_DATASIZE_4: trace pin used for sync mode and data size is 4
+    \param[out] none
+    \retval     none
+*/
+void dbg_trace_pin_mode_set(uint32_t trace_mode)
+{
+    DBG_CTL0 &= ~DBG_CTL0_TRACE_MODE;
+    DBG_CTL0 |= trace_mode;
+}

+ 341 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c

@@ -0,0 +1,341 @@
+/*!
+    \file  gd32f4xx_dci.c
+    \brief DCI driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_dci.h"
+
+/*!
+    \brief      DCI deinit
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_DCIRST);
+    rcu_periph_reset_disable(RCU_DCIRST);
+}
+
+/*!
+    \brief      initialize DCI registers
+    \param[in]  dci_struct: DCI parameter initialization stuct
+                members of the structure and the member values are shown as below:
+                capture_mode    : DCI_CAPTURE_MODE_CONTINUOUS, DCI_CAPTURE_MODE_SNAPSHOT
+                colck_polarity  : DCI_CK_POLARITY_FALLING, DCI_CK_POLARITY_RISING
+                hsync_polarity  : DCI_HSYNC_POLARITY_LOW, DCI_HSYNC_POLARITY_HIGH                                      
+                vsync_polarity  : DCI_VSYNC_POLARITY_LOW, DCI_VSYNC_POLARITY_HIGH
+                frame_rate      : DCI_FRAME_RATE_ALL, DCI_FRAME_RATE_1_2, DCI_FRAME_RATE_1_4
+                interface_format: DCI_INTERFACE_FORMAT_8BITS, DCI_INTERFACE_FORMAT_10BITS,
+                                      DCI_INTERFACE_FORMAT_12BITS, DCI_INTERFACE_FORMAT_14BITS
+    \param[out] none
+    \retval     none
+*/
+void dci_init(dci_parameter_struct* dci_struct)
+{
+    uint32_t reg =0U;
+    /* disable capture function and DCI */
+    DCI_CTL &= ~(DCI_CTL_CAP | DCI_CTL_DCIEN);
+    /* config DCI parameter */
+    reg |= dci_struct->capture_mode;
+    reg |= dci_struct->clock_polarity;
+    reg |= dci_struct->hsync_polarity;
+    reg |= dci_struct->vsync_polarity;
+    reg |= dci_struct->frame_rate;
+    reg |= dci_struct->interface_format;
+
+    DCI_CTL = reg;
+}
+
+/*!
+    \brief      enable DCI function 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_enable(void)
+{
+    DCI_CTL |= DCI_CTL_DCIEN;    
+}
+
+/*!
+    \brief      disable DCI function 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_disable(void)
+{
+    DCI_CTL &= ~DCI_CTL_DCIEN;
+}
+
+/*!
+    \brief      enable DCI capture 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_capture_enable(void)
+{
+    DCI_CTL |= DCI_CTL_CAP;
+}
+
+/*!
+    \brief      disable DCI capture 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_capture_disable(void)
+{
+    DCI_CTL &= ~DCI_CTL_CAP;
+}
+
+/*!
+    \brief      enable DCI jpeg mode 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_jpeg_enable(void)
+{
+    DCI_CTL |= DCI_CTL_JM;
+}
+
+/*!
+    \brief      disable DCI jpeg mode 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_jpeg_disable(void)
+{
+    DCI_CTL &= ~DCI_CTL_JM;
+}
+
+/*!
+    \brief      enable cropping window function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_crop_window_enable(void)
+{
+    DCI_CTL |= DCI_CTL_WDEN;
+}
+
+/*!
+    \brief      disable cropping window function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_crop_window_disable(void)
+{
+    DCI_CTL &= ~DCI_CTL_WDEN;
+}
+
+/*!
+    \brief      config DCI cropping window 
+    \param[in]  start_x: window horizontal start position
+    \param[in]  start_y: window vertical start position
+    \param[in]  size_height: window horizontal size
+    \param[in]  size_width: window vertical size
+    \param[out] none
+    \retval     none
+*/
+void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height)
+{
+    DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y<<16));
+    DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height<<16));
+}
+
+/*!
+    \brief      enable sync codes function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_sync_codes_enable(void)
+{
+    DCI_CTL |= DCI_CTL_ESM;
+}
+
+/*!
+    \brief      disable sync codes function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dci_sync_codes_disable(void)
+{
+    DCI_CTL &= ~DCI_CTL_ESM;
+}
+/*!
+    \brief      config sync codes 
+    \param[in]  frame_start: frame start code in embedded synchronous mode
+    \param[in]  line_start: line start code in embedded synchronous mode
+    \param[in]  line_end: line end code in embedded synchronous mode
+    \param[in]  frame_end: frame end code in embedded synchronous mode
+    \param[out] none
+    \retval     none
+*/
+void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end)
+{
+    DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start<<8) | ((uint32_t)line_end<<16) | ((uint32_t)frame_end<<24));
+}
+
+/*!
+    \brief      config sync codes unmask
+    \param[in]  frame_start: frame start code unmask bits in embedded synchronous mode
+    \param[in]  line_start: line start code unmask bits in embedded synchronous mode
+    \param[in]  line_end: line end code unmask bits in embedded synchronous mode
+    \param[in]  frame_end: frame end code unmask bits in embedded synchronous mode
+    \param[out] none
+    \retval     none
+*/
+void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end)
+{
+    DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start<<8) | ((uint32_t)line_end<<16) | ((uint32_t)frame_end<<24));	
+}
+
+/*!
+    \brief      read DCI data register
+    \param[in]  none
+    \param[out] none
+    \retval     data
+*/
+uint32_t dci_data_read(void)
+{
+    return DCI_DATA;
+}
+
+/*!
+    \brief      enable specified DCI interrupt
+    \param[in]  interrupt:
+      \arg         DCI_INT_EF: end of frame interrupt
+      \arg         DCI_INT_OVR: FIFO overrun interrupt
+      \arg         DCI_INT_ESE: embedded synchronous error interrupt 
+      \arg         DCI_INT_VS: vsync interrupt
+      \arg         DCI_INT_EL: end of line interrupt
+    \param[out] none
+    \retval     none
+*/
+void dci_interrupt_enable(uint32_t interrupt)
+{
+    DCI_INTEN |= interrupt;
+}
+
+/*!
+    \brief      disable specified DCI interrupt
+    \param[in]  interrupt:
+      \arg         DCI_INT_EF: end of frame interrupt
+      \arg         DCI_INT_OVR: FIFO overrun interrupt
+      \arg         DCI_INT_ESE: embedded synchronous error interrupt 
+      \arg         DCI_INT_VS: vsync interrupt
+      \arg         DCI_INT_EL: end of line interrupt
+    \param[out] none
+    \retval     none
+*/
+void dci_interrupt_disable(uint32_t interrupt)
+{
+    DCI_INTEN &= ~interrupt;
+}
+
+/*!
+    \brief      clear specified interrupt
+    \param[in]  interrupt:
+      \arg         DCI_INT_EF: end of frame interrupt
+      \arg         DCI_INT_OVR: FIFO overrun interrupt
+      \arg         DCI_INT_ESE: embedded synchronous error interrupt 
+      \arg         DCI_INT_VS: vsync interrupt
+      \arg         DCI_INT_EL: end of line interrupt
+    \param[out] none
+    \retval     none
+*/
+void dci_interrupt_clear(uint32_t interrupt)
+{
+    DCI_INTC |= interrupt;
+}
+
+/*!
+    \brief      get specified flag
+    \param[in]  flag:
+      \arg         DCI_FLAG_HS: HS line status
+      \arg         DCI_FLAG_VS: VS line status
+      \arg         DCI_FLAG_FV:FIFO valid
+      \arg         DCI_FLAG_EFF: end of frame flag
+      \arg         DCI_FLAG_OVRF: FIFO overrun flag
+      \arg         DCI_FLAG_ESEF: embedded synchronous error flag
+      \arg         DCI_FLAG_VSF: vsync flag
+      \arg         DCI_FLAG_ELF: end of line flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus dci_flag_get(uint32_t flag)
+{
+    uint32_t ret = 0U;
+    
+    switch(flag){
+    /* get flag status from DCI_STAT0 register */
+    case DCI_FLAG_HS:
+        ret = (DCI_STAT0 & DCI_STAT0_HS);
+        break;
+    case DCI_FLAG_VS:
+        ret = (DCI_STAT0 & DCI_STAT0_VS);
+        break;
+    case DCI_FLAG_FV:
+        ret = (DCI_STAT0 & DCI_STAT0_FV);
+        break;
+    /* get flag status from DCI_STAT1 register */
+    case DCI_FLAG_EFF:
+        ret = (DCI_STAT1 & DCI_STAT1_EFF);
+        break;
+    case DCI_FLAG_OVRF:
+        ret = (DCI_STAT1 & DCI_STAT1_OVRF);
+        break;
+    case DCI_FLAG_ESEF:
+        ret = (DCI_STAT1 & DCI_STAT1_ESEF);
+        break;
+    case DCI_FLAG_VSF:
+        ret = (DCI_STAT1 & DCI_STAT1_VSF);
+        break;
+    case DCI_FLAG_ELF:
+        ret = (DCI_STAT1 & DCI_STAT1_ELF);
+        break;
+    default :
+        break;
+    }
+    
+    if(RESET == ret){
+        return RESET;
+    }else{
+        return SET;
+    }
+}
+
+/*!
+    \brief      get specified interrupt flag
+    \param[in]  interrupt:
+      \arg         DCI_INT_EF: end of frame interrupt
+      \arg         DCI_INT_OVR: FIFO overrun interrupt
+      \arg         DCI_INT_ESE: embedded synchronous error interrupt 
+      \arg         DCI_INT_VS: vsync interrupt
+      \arg         DCI_INT_EL: end of line interrupt
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus dci_interrupt_flag_get(uint32_t interrupt)
+{
+    if(RESET == (DCI_INTF & interrupt)){
+        return RESET;
+    }else{
+        return SET;
+    }
+}

+ 820 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c

@@ -0,0 +1,820 @@
+/*!
+    \file  gd32f4xx_dma.c
+    \brief DMA driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx		
+*/
+
+#include "gd32f4xx_dma.h"
+
+/*  DMA register bit offset */
+#define CHXCTL_PERIEN_OFFSET            ((uint32_t)25U)
+
+/*!
+    \brief      deinitialize DMA a channel registers
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel is deinitialized
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     none
+*/
+void dma_deinit(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    /* disable DMA a channel */
+    DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CHEN;
+    /* reset DMA channel registers */
+    DMA_CHCTL(dma_periph,channelx) = DMA_CHCTL_RESET_VALUE;
+    DMA_CHCNT(dma_periph,channelx) = DMA_CHCNT_RESET_VALUE;
+    DMA_CHPADDR(dma_periph,channelx) = DMA_CHPADDR_RESET_VALUE;
+    DMA_CHM0ADDR(dma_periph,channelx) = DMA_CHMADDR_RESET_VALUE;
+    DMA_CHM1ADDR(dma_periph,channelx) = DMA_CHMADDR_RESET_VALUE;
+    DMA_CHFCTL(dma_periph,channelx) = DMA_CHFCTL_RESET_VALUE;
+    if(channelx < DMA_CH4){
+        DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx);
+    }else{
+        DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx);
+    }
+}
+
+/*!
+    \brief      initialize DMA single data mode
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel is initialized
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  init_struct: the data needed to initialize DMA single data mode
+                  periph_addr: peripheral base address
+                  periph_memory_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT
+                  periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX 
+                  memory0_addr: memory base address
+                  memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE
+                  direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY
+                  number: the number of remaining data to be transferred by the DMA
+                  priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH
+                  circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE
+    \param[out] none
+    \retval     none
+*/
+void dma_single_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_single_data_parameter_struct init_struct)
+{
+    uint32_t ctl;
+    
+    /* select single data mode */
+    DMA_CHFCTL(dma_periph,channelx) &= ~DMA_CHXFCTL_MDMEN;
+    
+    /* configure peripheral base address */
+    DMA_CHPADDR(dma_periph,channelx) = init_struct.periph_addr;
+    
+    /* configure memory base address */
+    DMA_CHM0ADDR(dma_periph,channelx) = init_struct.memory0_addr;
+    
+    /* configure the number of remaining data to be transferred */
+    DMA_CHCNT(dma_periph,channelx) = init_struct.number;
+    
+    /* configure peripheral and memory transfer width,channel priotity,transfer mode */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM);
+    ctl |= (init_struct.periph_memory_width | (init_struct.periph_memory_width << 2) | init_struct.priority | init_struct.direction);
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+
+    /* configure peripheral increasing mode */
+    if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA;
+    }else if(DMA_PERIPH_INCREASE_DISABLE == init_struct.periph_inc){
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF;
+    }
+
+    /* configure memory increasing mode */
+    if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA;
+    }
+
+    /* configure DMA circular mode */
+    if(DMA_CIRCULAR_MODE_ENABLE == init_struct.circular_mode){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN;
+    }
+}
+
+/*!
+    \brief      initialize DMA multi data mode
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel is initialized
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  dma_multi_data_parameter_struct: the data needed to initialize DMA multi data mode
+                  periph_addr: peripheral base address
+                  periph_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT
+                  periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX 
+                  memory0_addr: memory0 base address
+                  memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT
+                  memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE
+                  direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY
+                  number: the number of remaining data to be transferred by the DMA
+                  priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH
+                  circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE
+                  memory_burst_width: DMA_MEMORY_BURST_SINGLE,DMA_MEMORY_BURST_4_BEAT,DMA_MEMORY_BURST_8_BEAT,DMA_MEMORY_BURST_16_BEAT
+                  periph_burst_width: DMA_PERIPH_BURST_SINGLE,DMA_PERIPH_BURST_4_BEAT,DMA_PERIPH_BURST_8_BEAT,DMA_PERIPH_BURST_16_BEAT
+                  critical_value: DMA_FIFO_1_WORD,DMA_FIFO_2_WORD,DMA_FIFO_3_WORD,DMA_FIFO_4_WORD
+    \param[out] none
+    \retval     none
+*/
+void dma_multi_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_multi_data_parameter_struct init_struct)
+{
+    uint32_t ctl;
+    
+    /* select multi data mode and configure FIFO critical value */
+    DMA_CHFCTL(dma_periph,channelx) |= (DMA_CHXFCTL_MDMEN | init_struct.critical_value);
+    
+    /* configure peripheral base address */
+    DMA_CHPADDR(dma_periph,channelx) = init_struct.periph_addr;
+    
+    /* configure memory base address */
+    DMA_CHM0ADDR(dma_periph,channelx) = init_struct.memory0_addr;
+    
+    /* configure the number of remaining data to be transferred */
+    DMA_CHCNT(dma_periph,channelx) = init_struct.number;
+    
+    /* configure peripheral and memory transfer width,channel priotity,transfer mode,peripheral and memory burst transfer width */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM | DMA_CHXCTL_PBURST | DMA_CHXCTL_MBURST);
+    ctl |= (init_struct.periph_width | (init_struct.memory_width ) | init_struct.priority | init_struct.direction | init_struct.memory_burst_width | init_struct.periph_burst_width);
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+
+    /* configure peripheral increasing mode */
+    if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA;
+    }else if(DMA_PERIPH_INCREASE_DISABLE == init_struct.periph_inc){
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF;
+    }
+
+    /* configure memory increasing mode */
+    if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA;
+    }
+
+    /* configure DMA circular mode */
+    if(DMA_CIRCULAR_MODE_ENABLE == init_struct.circular_mode){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN;
+    }
+}
+
+/*!
+    \brief      get DMA flag is set or not 
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to get flag
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  flag: specify get which flag
+      \arg        DMA_INTF_FEEIF: FIFO error and exception flag
+      \arg        DMA_INTF_SDEIF: single data mode exception flag
+      \arg        DMA_INTF_TAEIF: transfer access error flag
+      \arg        DMA_INTF_HTFIF: half transfer finish flag
+      \arg        DMA_INTF_FTFIF: full transger finish flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus dma_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag)
+{
+    if(channelx < DMA_CH4){
+        if(DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag,channelx)){
+            return SET;
+        }else{
+            return RESET;
+        }
+    }else{
+        channelx -= (dma_channel_enum)4;
+        if(DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag,channelx)){
+            return SET;
+        }else{
+            return RESET;
+        }
+    }
+}
+
+/*!
+    \brief      clear DMA a channel flag
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to get flag
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  flag: specify get which flag
+      \arg        DMA_INTF_FEEIF: FIFO error and exception flag
+      \arg        DMA_INTF_SDEIF: single data mode exception flag
+      \arg        DMA_INTF_TAEIF: transfer access error flag
+      \arg        DMA_INTF_HTFIF: half transfer finish flag
+      \arg        DMA_INTF_FTFIF: full transger finish flag
+    \param[out] none
+    \retval     none
+*/
+void dma_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag)
+{
+    if(channelx < DMA_CH4){
+        DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(flag,channelx);
+    }else{
+        channelx -= (dma_channel_enum)4;
+        DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(flag,channelx);
+    }
+}
+
+/*!
+    \brief      get DMA interrupt flag is set or not 
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to get interrupt flag
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  interrupt: specify get which flag
+      \arg        DMA_INTF_FEEIF: FIFO error and exception flag
+      \arg        DMA_INTF_SDEIF: single data mode exception flag
+      \arg        DMA_INTF_TAEIF: transfer access error flag
+      \arg        DMA_INTF_HTFIF: half transfer finish flag
+      \arg        DMA_INTF_FTFIF: full transger finish flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus dma_interrupt_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt)
+{
+    uint32_t interrupt_enable = 0U,interrupt_flag = 0U;
+    dma_channel_enum channel_flag_offset = channelx;
+    if(channelx < DMA_CH4){
+        switch(interrupt){
+        case DMA_INTF_FEEIF:
+            interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx);
+            interrupt_enable = DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FEEIE;
+            break;
+        case DMA_INTF_SDEIF:
+            interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_SDEIE;
+            break;
+        case DMA_INTF_TAEIF:
+            interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_TAEIE;
+            break;
+        case DMA_INTF_HTFIF:
+            interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_HTFIE;
+            break;
+        case DMA_INTF_FTFIF:
+            interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx));
+            interrupt_enable = (DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_FTFIE);
+            break;
+        default:
+            break;
+        }
+    }else{
+        channel_flag_offset -= (dma_channel_enum)4;
+        switch(interrupt){
+        case DMA_INTF_FEEIF:
+            interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset);
+            interrupt_enable = DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FEEIE;
+            break;
+        case DMA_INTF_SDEIF:
+            interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_SDEIE;
+            break;
+        case DMA_INTF_TAEIF:
+            interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_TAEIE;
+            break;
+        case DMA_INTF_HTFIF:
+            interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_HTFIE;
+            break;
+        case DMA_INTF_FTFIF:
+            interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset);
+            interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_FTFIE;
+            break;
+        default:
+            break;
+        }
+    }
+    
+    if(interrupt_flag && interrupt_enable){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear DMA a channel interrupt flag
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to clear interrupt flag
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  interrupt: specify get which flag
+      \arg        DMA_INTC_FEEIFC: clear FIFO error and exception flag
+      \arg        DMA_INTC_SDEIFC: clear single data mode exception flag
+      \arg        DMA_INTC_TAEIFC: clear transfer access error flag
+      \arg        DMA_INTC_HTFIFC: clear half transfer finish flag
+      \arg        DMA_INTC_FTFIFC: clear full transger finish flag
+    \param[out] none
+    \retval     none
+*/
+void dma_interrupt_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt)
+{
+    if(channelx < DMA_CH4){
+        DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(interrupt,channelx);
+    }else{
+        channelx -= (dma_channel_enum)4;
+        DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(interrupt,channelx);
+    }
+}
+
+/*!
+    \brief      enable DMA interrupt
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  source: specify which interrupt to enbale
+      \arg        DMA_CHXCTL_SDEIE: single data mode exception interrupt enable
+      \arg        DMA_CHXCTL_TAEIE: tranfer access error interrupt enable
+      \arg        DMA_CHXCTL_HTFIE: half transfer finish interrupt enable
+      \arg        DMA_CHXCTL_FTFIE: full transfer finish interrupt enable
+      \arg        DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void dma_interrupt_enable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source)
+{
+    if(DMA_CHXFCTL_FEEIE != source){
+        DMA_CHCTL(dma_periph,channelx) |= source;
+    }else{
+        DMA_CHFCTL(dma_periph,channelx) |= source;
+    }
+}
+
+/*!
+    \brief      disable DMA interrupt
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  source: specify which interrupt to disbale
+      \arg        DMA_CHXCTL_SDEIE: single data mode exception interrupt enable
+      \arg        DMA_CHXCTL_TAEIE: tranfer access error interrupt enable
+      \arg        DMA_CHXCTL_HTFIE: half transfer finish interrupt enable
+      \arg        DMA_CHXCTL_FTFIE: full transfer finish interrupt enable
+      \arg        DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void dma_interrupt_disable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source)
+{
+    if(DMA_CHXFCTL_FEEIE != source){
+        DMA_CHCTL(dma_periph,channelx) &= ~source;
+    }else{
+        DMA_CHFCTL(dma_periph,channelx) &= ~source;
+    }
+}
+
+/*!
+    \brief      set DMA peripheral base address
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to set peripheral base address
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  address: peripheral base address
+    \param[out] none
+    \retval     none
+*/
+void dma_periph_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t address)
+{
+    DMA_CHPADDR(dma_periph,channelx) = address;
+}
+
+/*!
+    \brief      set DMA Memory0 base address
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to set Memory base address 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  memory_flag: DMA_MEMORY_x(x=0,1)
+    \param[in]  address: Memory base address
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t memory_flag,uint32_t address)
+{
+    if(memory_flag){
+        DMA_CHM1ADDR(dma_periph,channelx) = address;
+    }else{
+        DMA_CHM0ADDR(dma_periph,channelx) = address;
+    }
+}
+
+/*!
+    \brief      set the number of remaining data to be transferred by the DMA
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to set number
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  number: the number of remaining data to be transferred by the DMA
+    \param[out] none
+    \retval     none
+*/
+void dma_transfer_number_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t number)
+{
+    DMA_CHCNT(dma_periph,channelx) = number;
+}
+
+/*!
+    \brief      get the number of remaining data to be transferred by the DMA
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel to set number 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     uint32_t: the number of remaining data to be transferred by the DMA 
+*/
+uint32_t dma_transfer_number_get(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    return (uint32_t)DMA_CHCNT(dma_periph,channelx);
+}
+
+/*!
+    \brief      configure priority level of DMA channel
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  priority: priority Level of this channel
+      \arg        DMA_PRIORITY_LOW: low priority
+      \arg        DMA_PRIORITY_MEDIUM: medium priority
+      \arg        DMA_PRIORITY_HIGH: high priority
+      \arg        DMA_PRIORITY_ULTRA_HIGH: ultra high priority
+    \param[out] none
+    \retval     none 
+*/
+void dma_priority_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t priority)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_PRIO;
+    ctl |= priority;
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      configure transfer burst beats of memory
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  mbeat: transfer burst beats
+      \arg        DMA_MEMORY_BURST_SINGLE: memory transfer single burst
+      \arg        DMA_MEMORY_BURST_4_BEAT: memory transfer 4-beat burst
+      \arg        DMA_MEMORY_BURST_8_BEAT: memory transfer 8-beat burst
+      \arg        DMA_MEMORY_BURST_16_BEAT: memory transfer 16-beat burst
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t mbeat)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_MBURST;
+    ctl |= mbeat;
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      configure transfer burst beats of peripheral
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  pbeat: transfer burst beats
+      \arg        DMA_PERIPH_BURST_SINGLE: peripheral transfer single burst
+      \arg        DMA_PERIPH_BURST_4_BEAT: peripheral transfer 4-beat burst
+      \arg        DMA_PERIPH_BURST_8_BEAT: peripheral transfer 8-beat burst
+      \arg        DMA_PERIPH_BURST_16_BEAT: peripheral transfer 16-beat burst
+    \param[out] none
+    \retval     none
+*/
+void dma_periph_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t pbeat)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_PBURST;
+    ctl |= pbeat;
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      configure transfer data size of memory
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  msize: transfer data size of memory
+      \arg        DMA_MEMORY_WIDTH_8BIT: transfer data size of memory is 8-bit
+      \arg        DMA_MEMORY_WIDTH_16BIT: transfer data size of memory is 16-bit
+      \arg        DMA_MEMORY_WIDTH_32BIT: transfer data size of memory is 32-bit
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_width_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t msize)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_MWIDTH;
+    ctl |= msize;
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      configure transfer data size of peripheral 
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  msize: transfer data size of peripheral
+      \arg        DMA_PERIPHERAL_WIDTH_8BIT: transfer data size of peripheral is 8-bit
+      \arg        DMA_PERIPHERAL_WIDTH_16BIT: transfer data size of peripheral is 16-bit
+      \arg        DMA_PERIPHERAL_WIDTH_32BIT: transfer data size of peripheral is 32-bit
+    \param[out] none
+    \retval     none
+*/
+void dma_periph_width_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t psize)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_PWIDTH;
+    ctl |= psize;
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      configure memory address generation generation_algorithm
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  generation_algorithm: the address generation algorithm
+      \arg        DMA_MEMORY_INCREASE_ENABLE: next address of memory is increasing address mode
+      \arg        DMA_MEMORY_INCREASE_DISABLE: next address of memory is fixed address mode
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm)
+{
+    if(DMA_MEMORY_INCREASE_ENABLE == generation_algorithm){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA;
+    }
+}
+
+/*!
+    \brief      configure peripheral address generation generation_algorithm
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  generation_algorithm: the address generation algorithm
+      \arg        DMA_PERIPH_INCREASE_ENABLE: next address of peripheral is increasing address mode
+      \arg        DMA_PERIPH_INCREASE_DISABLE: next address of peripheral is fixed address mode
+      \arg        DMA_PERIPH_INCREASE_FIX: increasing steps of peripheral address is fixed
+    \param[out] none
+    \retval     none
+*/
+void dma_peripheral_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm)
+{
+    if(DMA_PERIPH_INCREASE_ENABLE == generation_algorithm){
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA;
+    }else if(DMA_PERIPH_INCREASE_DISABLE == generation_algorithm){
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA;
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF;
+    }
+}
+
+/*!
+    \brief      enable DMA circulation mode
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     none 
+*/
+void dma_circulation_enable(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN;
+}
+
+/*!
+    \brief      disable DMA circulation mode
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     none 
+*/
+void dma_circulation_disable(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN;
+}
+
+/*!
+    \brief      configure the direction of  data transfer on the channel
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  direction: specify the direction of  data transfer
+      \arg        DMA_PERIPH_TO_MEMORY: read from peripheral and write to memory
+      \arg        DMA_MEMORY_TO_PERIPH: read from memory and write to peripheral
+      \arg        DMA_MEMORY_TO_MEMORY: read from memory and write to memory
+    \param[out] none
+    \retval     none
+*/
+void dma_transfer_direction_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t direction)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_TM;
+    ctl |= direction;
+    
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      enable DMA channel
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     none 
+*/
+void dma_channel_enable(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CHEN;
+}
+
+/*!
+    \brief      disable DMA channel
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     none 
+*/
+void dma_channel_disable(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CHEN;
+}
+
+/*!
+    \brief      DMA channel peripheral select
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  sub_periph: specify DMA channel peripheral
+      \arg        DMA_SUBPERIx(x=0..7)
+    \param[out] none
+    \retval     none 
+*/
+void dma_channel_subperipheral_select(uint32_t dma_periph,dma_channel_enum channelx,dma_subperipheral_enum sub_periph)
+{
+    uint32_t ctl;
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(dma_periph,channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_PERIEN;
+    ctl |= ((uint32_t)sub_periph << CHXCTL_PERIEN_OFFSET);
+    
+    DMA_CHCTL(dma_periph,channelx) = ctl;
+}
+
+/*!
+    \brief      DMA switch buffer mode config
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  memory1_addr: memory1 base address
+    \param[in]  memory_select: DMA_MEMORY_0 or DMA_MEMORY_1
+    \param[out] none
+    \retval     none 
+*/
+void dma_switch_buffer_mode_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t memory1_addr,uint32_t memory_select)
+{
+    /* configure memory1 base address */
+    DMA_CHM1ADDR(dma_periph,channelx) = memory1_addr;
+
+    if(DMA_MEMORY_0 == memory_select){
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MBS;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MBS;
+    }
+}
+
+/*!
+    \brief      DMA switch buffer mode enable
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none 
+*/
+void dma_switch_buffer_mode_enable(uint32_t dma_periph,dma_channel_enum channelx,ControlStatus newvalue)
+{
+    if(ENABLE == newvalue){
+        /* switch buffer mode enable */
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_SBMEN;
+    }else{
+        /* switch buffer mode disable */
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_SBMEN;
+    }
+}
+
+/*!
+    \brief      DMA using memory get
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     the using memory 
+*/
+uint32_t dma_using_memory_get(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    if((DMA_CHCTL(dma_periph,channelx)) & DMA_CHXCTL_MBS){
+        return DMA_MEMORY_1;
+    }else{
+        return DMA_MEMORY_0;
+    }
+}
+
+/*!
+    \brief      DMA flow controller configure
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[in]  controller: specify DMA flow controler 
+      \arg        DMA_FLOW_CONTROLLER_DMA: DMA is the flow controller
+      \arg        DMA_FLOW_CONTROLLER_PERI: peripheral is the flow controller
+    \param[out] none
+    \retval     none
+*/
+void dma_flow_controller_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t controller)
+{
+    if(DMA_FLOW_CONTROLLER_DMA == controller){
+        DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_TFCS;
+    }else{
+        DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_TFCS;
+    }
+}
+
+/*!
+    \brief      DMA FIFO status get
+    \param[in]  dma_periph: DMAx(x=0,1)
+      \arg        DMAx(x=0,1)
+    \param[in]  channelx: specify which DMA channel 
+      \arg        DMA_CHx(x=0..7)
+    \param[out] none
+    \retval     the using memory 
+*/
+uint32_t dma_fifo_status_get(uint32_t dma_periph,dma_channel_enum channelx)
+{
+    return (DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FCNT);
+}

+ 3449 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c

@@ -0,0 +1,3449 @@
+/*!
+    \file  gd32f4xx_enet.c
+    \brief ENET driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_enet.h"
+
+#if defined   (__CC_ARM)                                    /*!< ARM compiler */
+__align(4) 
+enet_descriptors_struct  rxdesc_tab[ENET_RXBUF_NUM];        /*!< ENET RxDMA descriptor */
+__align(4) 
+enet_descriptors_struct  txdesc_tab[ENET_TXBUF_NUM];        /*!< ENET TxDMA descriptor */
+__align(4) 
+uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE];           /*!< ENET receive buffer */
+__align(4) 
+uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE];           /*!< ENET transmit buffer */
+
+#elif defined ( __ICCARM__ )                                /*!< IAR compiler */
+#pragma data_alignment=4
+enet_descriptors_struct  rxdesc_tab[ENET_RXBUF_NUM];        /*!< ENET RxDMA descriptor */
+#pragma data_alignment=4
+enet_descriptors_struct  txdesc_tab[ENET_TXBUF_NUM];        /*!< ENET TxDMA descriptor */
+#pragma data_alignment=4
+uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE];           /*!< ENET receive buffer */
+#pragma data_alignment=4
+uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE];           /*!< ENET transmit buffer */
+
+#endif /* __CC_ARM */
+
+/* global transmit and receive descriptors pointers */
+enet_descriptors_struct  *dma_current_txdesc;
+enet_descriptors_struct  *dma_current_rxdesc;
+
+/* structure pointer of ptp descriptor for normal mode */
+enet_descriptors_struct  *dma_current_ptp_txdesc = NULL;
+enet_descriptors_struct  *dma_current_ptp_rxdesc = NULL;
+
+/* init structure parameters for ENET initialization */
+static enet_initpara_struct enet_initpara ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/* array of register offset for debug information get */
+static const uint16_t enet_reg_tab[] = {
+0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0028, 0x002C, 0x0034,
+0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x1080,
+  
+0x0100, 0x0104, 0x0108, 0x010C, 0x0110, 0x014C, 0x0150, 0x0168, 0x0194, 0x0198, 0x01C4, 
+ 
+0x0700, 0x0704,0x0708, 0x070C, 0x0710, 0x0714, 0x0718, 0x071C, 0x0720, 0x0728, 0x072C, 
+  
+0x1000, 0x1004, 0x1008, 0x100C, 0x1010, 0x1014, 0x1018, 0x101C, 0x1020, 0x1024, 0x1048,
+0x104C, 0x1050, 0x1054};
+
+
+/*!
+    \brief      deinitialize the ENET, and reset structure parameters for ENET initialization
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_ENETRST);
+    rcu_periph_reset_disable(RCU_ENETRST);
+    enet_initpara_reset();
+}
+
+/*!
+    \brief      configure the parameters which are usually less cared for initialization
+                note -- this function must be called before enet_init(), otherwise 
+                configuration will be no effect
+    \param[in]  option: different function option, which is related to several parameters, 
+                only one parameter can be selected which is shown as below, refer to enet_option_enum
+      \arg        FORWARD_OPTION: choose to configure the frame forward related parameters
+      \arg        DMABUS_OPTION: choose to configure the DMA bus mode related parameters
+      \arg        DMA_MAXBURST_OPTION: choose to configure the DMA max burst related parameters
+      \arg        DMA_ARBITRATION_OPTION: choose to configure the DMA arbitration related parameters
+      \arg        STORE_OPTION: choose to configure the store forward mode related parameters
+      \arg        DMA_OPTION: choose to configure the DMA descriptor related parameters 
+      \arg        VLAN_OPTION: choose to configure vlan related parameters
+      \arg        FLOWCTL_OPTION: choose to configure flow control related parameters
+      \arg        HASHH_OPTION: choose to configure hash high
+      \arg        HASHL_OPTION: choose to configure hash low
+      \arg        FILTER_OPTION: choose to configure frame filter related parameters
+      \arg        HALFDUPLEX_OPTION: choose to configure halfduplex mode related parameters
+      \arg        TIMER_OPTION: choose to configure time counter related parameters
+      \arg        INTERFRAMEGAP_OPTION: choose to configure the inter frame gap related parameters
+    \param[in]  para: the related parameters according to the option 
+                      all the related parameters should be configured which are shown as below
+                      FORWARD_OPTION related parameters:
+                      -  ENET_AUTO_PADCRC_DROP_ENABLE/ ENET_AUTO_PADCRC_DROP_DISABLE ;
+                      -  ENET_TYPEFRAME_CRC_DROP_ENABLE/ ENET_TYPEFRAME_CRC_DROP_DISABLE ;
+                      -  ENET_FORWARD_ERRFRAMES_ENABLE/ ENET_FORWARD_ERRFRAMES_DISABLE ;
+                      -  ENET_FORWARD_UNDERSZ_GOODFRAMES_ENABLE/ ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE .
+                      DMABUS_OPTION related parameters:
+                      -  ENET_ADDRESS_ALIGN_ENABLE/ ENET_ADDRESS_ALIGN_DISABLE ;
+                      -  ENET_FIXED_BURST_ENABLE/ ENET_FIXED_BURST_DISABLE ;
+                      -  ENET_MIXED_BURST_ENABLE/ ENET_MIXED_BURST_DISABLE ;       
+                      DMA_MAXBURST_OPTION related parameters:
+                      -  ENET_RXDP_1BEAT/ ENET_RXDP_2BEAT/ ENET_RXDP_4BEAT/
+                         ENET_RXDP_8BEAT/ ENET_RXDP_16BEAT/ ENET_RXDP_32BEAT/
+                         ENET_RXDP_4xPGBL_4BEAT/ ENET_RXDP_4xPGBL_8BEAT/
+                         ENET_RXDP_4xPGBL_16BEAT/ ENET_RXDP_4xPGBL_32BEAT/
+                         ENET_RXDP_4xPGBL_64BEAT/ ENET_RXDP_4xPGBL_128BEAT ;
+                      -  ENET_PGBL_1BEAT/ ENET_PGBL_2BEAT/ ENET_PGBL_4BEAT/
+                         ENET_PGBL_8BEAT/ ENET_PGBL_16BEAT/ ENET_PGBL_32BEAT/
+                         ENET_PGBL_4xPGBL_4BEAT/ ENET_PGBL_4xPGBL_8BEAT/
+                         ENET_PGBL_4xPGBL_16BEAT/ ENET_PGBL_4xPGBL_32BEAT/
+                         ENET_PGBL_4xPGBL_64BEAT/ ENET_PGBL_4xPGBL_128BEAT ;
+                      -  ENET_RXTX_DIFFERENT_PGBL/ ENET_RXTX_SAME_PGBL ;
+                      DMA_ARBITRATION_OPTION related parameters:
+                      -  ENET_ARBITRATION_RXPRIORTX
+                      -  ENET_ARBITRATION_RXTX_1_1/ ENET_ARBITRATION_RXTX_2_1/
+                         ENET_ARBITRATION_RXTX_3_1/ ENET_ARBITRATION_RXTX_4_1/.
+                      STORE_OPTION related parameters:
+                      -  ENET_RX_MODE_STOREFORWARD/ ENET_RX_MODE_CUTTHROUGH ;
+                      -  ENET_TX_MODE_STOREFORWARD/ ENET_TX_MODE_CUTTHROUGH ;
+                      -  ENET_RX_THRESHOLD_64BYTES/ ENET_RX_THRESHOLD_32BYTES/
+                         ENET_RX_THRESHOLD_96BYTES/ ENET_RX_THRESHOLD_128BYTES ;
+                      -  ENET_TX_THRESHOLD_64BYTES/ ENET_TX_THRESHOLD_128BYTES/
+                         ENET_TX_THRESHOLD_192BYTES/ ENET_TX_THRESHOLD_256BYTES/
+                         ENET_TX_THRESHOLD_40BYTES/ ENET_TX_THRESHOLD_32BYTES/
+                         ENET_TX_THRESHOLD_24BYTES/ ENET_TX_THRESHOLD_16BYTES .
+                      DMA_OPTION related parameters:
+                      -  ENET_FLUSH_RXFRAME_ENABLE/ ENET_FLUSH_RXFRAME_DISABLE ;
+                      -  ENET_SECONDFRAME_OPT_ENABLE/ ENET_SECONDFRAME_OPT_DISABLE ;
+                      -  ENET_ENHANCED_DESCRIPTOR/ ENET_NORMAL_DESCRIPTOR .
+                      VLAN_OPTION related parameters:
+                      -  ENET_VLANTAGCOMPARISON_12BIT/ ENET_VLANTAGCOMPARISON_16BIT ;
+                      -  MAC_VLT_VLTI(regval) .
+                      FLOWCTL_OPTION related parameters:
+                      -  MAC_FCTL_PTM(regval) ;
+                      -  ENET_ZERO_QUANTA_PAUSE_ENABLE/ ENET_ZERO_QUANTA_PAUSE_DISABLE ;
+                      -  ENET_PAUSETIME_MINUS4/ ENET_PAUSETIME_MINUS28/ 
+                         ENET_PAUSETIME_MINUS144/ENET_PAUSETIME_MINUS256 ;
+                      -  ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT/ ENET_UNIQUE_PAUSEDETECT ;
+                      -  ENET_RX_FLOWCONTROL_ENABLE/ ENET_RX_FLOWCONTROL_DISABLE ;
+                      -  ENET_TX_FLOWCONTROL_ENABLE/ ENET_TX_FLOWCONTROL_DISABLE .
+                      HASHH_OPTION related parameters:
+                      -  0x0~0xFFFF FFFFU
+                      HASHL_OPTION related parameters:
+                      -  0x0~0xFFFF FFFFU
+                      FILTER_OPTION related parameters:
+                      -  ENET_SRC_FILTER_NORMAL_ENABLE/ ENET_SRC_FILTER_INVERSE_ENABLE/
+                         ENET_SRC_FILTER_DISABLE ;
+                      -  ENET_DEST_FILTER_INVERSE_ENABLE/ ENET_DEST_FILTER_INVERSE_DISABLE ;
+                      -  ENET_MULTICAST_FILTER_HASH_OR_PERFECT/ ENET_MULTICAST_FILTER_HASH/
+                         ENET_MULTICAST_FILTER_PERFECT/ ENET_MULTICAST_FILTER_NONE ;
+                      -  ENET_UNICAST_FILTER_EITHER/ ENET_UNICAST_FILTER_HASH/
+                         ENET_UNICAST_FILTER_PERFECT ;
+                      -  ENET_PCFRM_PREVENT_ALL/ ENET_PCFRM_PREVENT_PAUSEFRAME/
+                         ENET_PCFRM_FORWARD_ALL/ ENET_PCFRM_FORWARD_FILTERED .
+                      HALFDUPLEX_OPTION related parameters:
+                      -  ENET_CARRIERSENSE_ENABLE/ ENET_CARRIERSENSE_DISABLE ;
+                      -  ENET_RECEIVEOWN_ENABLE/ ENET_RECEIVEOWN_DISABLE ;
+                      -  ENET_RETRYTRANSMISSION_ENABLE/ ENET_RETRYTRANSMISSION_DISABLE ;
+                      -  ENET_BACKOFFLIMIT_10/ ENET_BACKOFFLIMIT_8/
+                         ENET_BACKOFFLIMIT_4/ ENET_BACKOFFLIMIT_1 ;
+                      -  ENET_DEFERRALCHECK_ENABLE/ ENET_DEFERRALCHECK_DISABLE .
+                      TIMER_OPTION related parameters:
+                      -  ENET_WATCHDOG_ENABLE/ ENET_WATCHDOG_DISABLE ;
+                      -  ENET_JABBER_ENABLE/ ENET_JABBER_DISABLE ;
+                      INTERFRAMEGAP_OPTION related parameters:
+                      -  ENET_INTERFRAMEGAP_96BIT/ ENET_INTERFRAMEGAP_88BIT/
+                         ENET_INTERFRAMEGAP_80BIT/ ENET_INTERFRAMEGAP_72BIT/
+                         ENET_INTERFRAMEGAP_64BIT/ ENET_INTERFRAMEGAP_56BIT/
+                         ENET_INTERFRAMEGAP_48BIT/ ENET_INTERFRAMEGAP_40BIT .
+    \param[out] none    
+    \retval     none
+*/
+void enet_initpara_config(enet_option_enum option, uint32_t para)
+{
+    switch(option){
+    case FORWARD_OPTION:
+        /* choose to configure forward_frame, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)FORWARD_OPTION;
+        enet_initpara.forward_frame = para;
+        break;
+    case DMABUS_OPTION:
+        /* choose to configure dmabus_mode, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)DMABUS_OPTION;
+        enet_initpara.dmabus_mode = para;
+        break;
+    case DMA_MAXBURST_OPTION:
+        /* choose to configure dma_maxburst, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)DMA_MAXBURST_OPTION;
+        enet_initpara.dma_maxburst = para;
+        break;
+    case DMA_ARBITRATION_OPTION:
+        /* choose to configure dma_arbitration, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)DMA_ARBITRATION_OPTION;
+        enet_initpara.dma_arbitration = para;
+        break;
+    case STORE_OPTION:
+        /* choose to configure store_forward_mode, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)STORE_OPTION;
+        enet_initpara.store_forward_mode = para;
+        break;
+    case DMA_OPTION:
+        /* choose to configure dma_function, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)DMA_OPTION;
+    
+#ifndef SELECT_DESCRIPTORS_ENHANCED_MODE
+        para &= ~ENET_ENHANCED_DESCRIPTOR;
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */  
+    
+        enet_initpara.dma_function = para;
+        break;
+    case VLAN_OPTION:
+        /* choose to configure vlan_config, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)VLAN_OPTION;
+        enet_initpara.vlan_config = para;
+        break;
+    case FLOWCTL_OPTION:
+        /* choose to configure flow_control, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)FLOWCTL_OPTION;
+        enet_initpara.flow_control = para;
+        break;
+    case HASHH_OPTION:
+        /* choose to configure hashtable_high, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)HASHH_OPTION;
+        enet_initpara.hashtable_high = para;
+        break;
+    case HASHL_OPTION:
+        /* choose to configure hashtable_low, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)HASHL_OPTION;
+        enet_initpara.hashtable_low = para;
+        break;
+    case FILTER_OPTION:
+        /* choose to configure framesfilter_mode, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)FILTER_OPTION;
+        enet_initpara.framesfilter_mode = para;
+        break;
+    case HALFDUPLEX_OPTION:
+        /* choose to configure halfduplex_param, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)HALFDUPLEX_OPTION;
+        enet_initpara.halfduplex_param = para;
+        break;
+    case TIMER_OPTION:
+        /* choose to configure timer_config, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)TIMER_OPTION;
+        enet_initpara.timer_config = para; 
+        break;
+    case INTERFRAMEGAP_OPTION:
+        /* choose to configure interframegap, and save the configuration parameters */
+        enet_initpara.option_enable |= (uint32_t)INTERFRAMEGAP_OPTION;
+        enet_initpara.interframegap = para;
+        break;
+    default:
+        break;    
+    }      
+} 
+
+/*!
+    \brief      initialize ENET peripheral with generally concerned parameters and the less cared 
+                parameters
+    \param[in]  mediamode: PHY mode and mac loopback configurations, only one parameter can be selected
+                           which is shown as below, refer to enet_mediamode_enum 
+      \arg        ENET_AUTO_NEGOTIATION: PHY auto negotiation
+      \arg        ENET_100M_FULLDUPLEX: 100Mbit/s, full-duplex
+      \arg        ENET_100M_HALFDUPLEX: 100Mbit/s, half-duplex
+      \arg        ENET_10M_FULLDUPLEX: 10Mbit/s, full-duplex
+      \arg        ENET_10M_HALFDUPLEX: 10Mbit/s, half-duplex
+      \arg        ENET_LOOPBACKMODE: MAC in loopback mode at the MII
+    \param[in]  checksum: IP frame checksum offload function, only one parameter can be selected
+                          which is shown as below, refer to enet_mediamode_enum 
+      \arg        ENET_NO_AUTOCHECKSUM: disable IP frame checksum function
+      \arg        ENET_AUTOCHECKSUM_DROP_FAILFRAMES: enable IP frame checksum function
+      \arg        ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES: enable IP frame checksum function, and the received frame
+                                                       with only payload error but no other errors will not be dropped
+    \param[in]  recept: frame filter function, only one parameter can be selected
+                          which is shown as below, refer to enet_frmrecept_enum 
+      \arg        ENET_PROMISCUOUS_MODE: promiscuous mode enabled
+      \arg        ENET_RECEIVEALL: all received frame are forwarded to application
+      \arg        ENET_BROADCAST_FRAMES_PASS: the address filters pass all received broadcast frames
+      \arg        ENET_BROADCAST_FRAMES_DROP: the address filters filter all incoming broadcast frames
+    \param[out] none    
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept)
+{
+    uint32_t reg_value=0U, reg_temp = 0U, temp = 0U;
+    uint32_t media_temp = 0U;
+    uint32_t timeout = 0U;
+    uint16_t phy_value = 0U;  
+    ErrStatus phy_state= ERROR, enet_state = ERROR;
+  
+    /* PHY interface configuration, configure SMI clock and reset PHY chip */
+    if(ERROR == enet_phy_config()){
+        _ENET_DELAY_(PHY_RESETDELAY);
+        if(ERROR == enet_phy_config()){
+            return enet_state;
+        }  
+    }
+    /* initialize ENET peripheral with generally concerned parameters */
+    enet_default_init();
+  
+    /* 1st, configure mediamode */
+    media_temp = (uint32_t)mediamode;
+    /* if is PHY auto negotiation */
+    if((uint32_t)ENET_AUTO_NEGOTIATION == media_temp){
+        /* wait for PHY_LINKED_STATUS bit be set */
+        do{
+            enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value);
+            phy_value &= PHY_LINKED_STATUS;  
+            timeout++;
+        }while((RESET == phy_value) && (timeout < PHY_READ_TO));
+        /* return ERROR due to timeout */
+        if(PHY_READ_TO == timeout){
+            return enet_state;
+        }
+        /* reset timeout counter */
+        timeout = 0U;
+        
+        /* enable auto-negotiation */
+        phy_value = PHY_AUTONEGOTIATION;
+        phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value);
+        if(!phy_state){
+            /* return ERROR due to write timeout */
+            return enet_state;
+        }
+    
+        /* wait for the PHY_AUTONEGO_COMPLETE bit be set */
+        do{
+            enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value);
+            phy_value &= PHY_AUTONEGO_COMPLETE;
+            timeout++;
+        }while((RESET == phy_value) && (timeout < (uint32_t)PHY_READ_TO));  
+        /* return ERROR due to timeout */
+        if(PHY_READ_TO == timeout){
+            return enet_state;
+        }
+        /* reset timeout counter */
+        timeout = 0U;
+    
+        /* read the result of the auto-negotiation */
+        enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_SR, &phy_value);  
+        /* configure the duplex mode of MAC following the auto-negotiation result */
+        if((uint16_t)RESET != (phy_value & PHY_DUPLEX_STATUS)){
+            media_temp = ENET_MODE_FULLDUPLEX;
+        }else{
+            media_temp = ENET_MODE_HALFDUPLEX;
+        }
+        /* configure the communication speed of MAC following the auto-negotiation result */
+        if((uint16_t)RESET !=(phy_value & PHY_SPEED_STATUS)){
+            media_temp |= ENET_SPEEDMODE_10M;
+        }else{
+            media_temp |= ENET_SPEEDMODE_100M;
+        }    
+    }else{
+        phy_value = (uint16_t)((media_temp & ENET_MAC_CFG_DPM) >> 3);
+        phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1);
+        phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value);
+        if(!phy_state){
+            /* return ERROR due to write timeout */
+            return enet_state;
+        }
+        /* PHY configuration need some time */
+        _ENET_DELAY_(PHY_CONFIGDELAY);      
+    }
+    /* after configuring the PHY, use mediamode to configure registers */
+    reg_value = ENET_MAC_CFG;
+    /* configure ENET_MAC_CFG register */
+    reg_value &= (~(ENET_MAC_CFG_SPD |ENET_MAC_CFG_DPM |ENET_MAC_CFG_LBM));
+    reg_value |= media_temp;
+    ENET_MAC_CFG = reg_value;
+    
+    
+    /* 2st, configure checksum */
+    if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)){
+        ENET_MAC_CFG |= ENET_CHECKSUMOFFLOAD_ENABLE;
+      
+        reg_value = ENET_DMA_CTL;
+        /* configure ENET_DMA_CTL register */
+        reg_value &= ~ENET_DMA_CTL_DTCERFD;
+        reg_value |= ((uint32_t)checksum & ENET_DMA_CTL_DTCERFD);
+        ENET_DMA_CTL = reg_value;
+    }
+    
+    /* 3rd, configure recept */
+    ENET_MAC_FRMF |= (uint32_t)recept;
+    
+    /* 4th, configure different function options */
+    /* configure forward_frame related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)FORWARD_OPTION)){
+        reg_temp = enet_initpara.forward_frame;
+              
+        reg_value = ENET_MAC_CFG;
+        temp = reg_temp;
+        /* configure ENET_MAC_CFG register */
+        reg_value &= (~(ENET_MAC_CFG_TFCD |ENET_MAC_CFG_APCD));
+        temp &= (ENET_MAC_CFG_TFCD | ENET_MAC_CFG_APCD);
+        reg_value |= temp;
+        ENET_MAC_CFG = reg_value;
+      
+        reg_value = ENET_DMA_CTL;
+        temp = reg_temp;
+        /* configure ENET_DMA_CTL register */
+        reg_value &= (~(ENET_DMA_CTL_FERF |ENET_DMA_CTL_FUF));
+        temp &= ((ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF)<<2);
+        reg_value |= (temp >> 2);
+        ENET_DMA_CTL = reg_value;
+    }
+
+    /* configure dmabus_mode related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)DMABUS_OPTION)){
+        temp = enet_initpara.dmabus_mode;
+      
+        reg_value = ENET_DMA_BCTL;
+        /* configure ENET_DMA_BCTL register */
+        reg_value &= ~(ENET_DMA_BCTL_AA | ENET_DMA_BCTL_FB \
+                      |ENET_DMA_BCTL_FPBL | ENET_DMA_BCTL_MB);
+        reg_value |= temp;
+        ENET_DMA_BCTL = reg_value;
+    }
+
+    /* configure dma_maxburst related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_MAXBURST_OPTION)){   
+        temp = enet_initpara.dma_maxburst;
+      
+        reg_value = ENET_DMA_BCTL;
+        /* configure ENET_DMA_BCTL register */
+        reg_value &= ~(ENET_DMA_BCTL_RXDP| ENET_DMA_BCTL_PGBL | ENET_DMA_BCTL_UIP);    
+        reg_value |= temp;
+        ENET_DMA_BCTL = reg_value;
+    }
+
+    /* configure dma_arbitration related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_ARBITRATION_OPTION)){   
+        temp = enet_initpara.dma_arbitration;
+      
+        reg_value = ENET_DMA_BCTL;
+        /* configure ENET_DMA_BCTL register */
+        reg_value &= ~(ENET_DMA_BCTL_RTPR | ENET_DMA_BCTL_DAB);
+        reg_value |= temp;
+        ENET_DMA_BCTL = reg_value;
+    }
+    
+    /* configure store_forward_mode related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)STORE_OPTION)){   
+        temp = enet_initpara.store_forward_mode;
+      
+        reg_value = ENET_DMA_CTL;
+        /* configure ENET_DMA_CTL register */
+        reg_value &= ~(ENET_DMA_CTL_RSFD | ENET_DMA_CTL_TSFD| ENET_DMA_CTL_RTHC| ENET_DMA_CTL_TTHC);
+        reg_value |= temp;
+        ENET_DMA_CTL = reg_value;
+    }
+
+    /* configure dma_function related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_OPTION)){   
+        reg_temp = enet_initpara.dma_function;
+              
+        reg_value = ENET_DMA_CTL;
+        temp = reg_temp;
+        /* configure ENET_DMA_CTL register */
+        reg_value &= (~(ENET_DMA_CTL_DAFRF |ENET_DMA_CTL_OSF));
+        temp &= (ENET_DMA_CTL_DAFRF | ENET_DMA_CTL_OSF);
+        reg_value |= temp;
+        ENET_DMA_CTL = reg_value;
+      
+        reg_value = ENET_DMA_BCTL;
+        temp = reg_temp;
+        /* configure ENET_DMA_BCTL register */
+        reg_value &= (~ENET_DMA_BCTL_DFM);
+        temp &= ENET_DMA_BCTL_DFM;
+        reg_value |= temp;
+        ENET_DMA_BCTL = reg_value;
+    }
+
+    /* configure vlan_config related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)VLAN_OPTION)){   
+        reg_temp = enet_initpara.vlan_config;
+              
+        reg_value = ENET_MAC_VLT;
+        /* configure ENET_MAC_VLT register */
+        reg_value &= ~(ENET_MAC_VLT_VLTI | ENET_MAC_VLT_VLTC);
+        reg_value |= reg_temp;
+        ENET_MAC_VLT = reg_value;
+    }
+
+    /* configure flow_control related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)FLOWCTL_OPTION)){   
+        reg_temp = enet_initpara.flow_control;
+              
+        reg_value = ENET_MAC_FCTL;
+        temp = reg_temp;
+        /* configure ENET_MAC_FCTL register */
+        reg_value &= ~(ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \
+                      | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN);
+        temp &= (ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \
+                 | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN);
+        reg_value |= temp;
+        ENET_MAC_FCTL = reg_value;
+      
+        reg_value = ENET_MAC_FCTH;
+        temp = reg_temp;
+        /* configure ENET_MAC_FCTH register */
+        reg_value &= ~(ENET_MAC_FCTH_RFA |ENET_MAC_FCTH_RFD);
+        temp &= ((ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD )<<8);
+        reg_value |= (temp >> 8);
+        ENET_MAC_FCTH = reg_value;
+    }    
+    
+    /* configure hashtable_high related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)){   
+        ENET_MAC_HLH = enet_initpara.hashtable_high;
+    } 
+
+    /* configure hashtable_low related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)){   
+        ENET_MAC_HLL = enet_initpara.hashtable_low;
+    }    
+
+    /* configure framesfilter_mode related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)FILTER_OPTION)){   
+        reg_temp = enet_initpara.framesfilter_mode;
+              
+        reg_value = ENET_MAC_FRMF;
+        /* configure ENET_MAC_FRMF register */
+        reg_value &= ~(ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT | ENET_MAC_FRMF_DAIFLT \
+                      | ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT | ENET_MAC_FRMF_MFD \
+                      | ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_PCFRM);
+        reg_value |= reg_temp;
+        ENET_MAC_FRMF = reg_value;
+    }  
+
+    /* configure halfduplex_param related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)HALFDUPLEX_OPTION)){   
+        reg_temp = enet_initpara.halfduplex_param;
+              
+        reg_value = ENET_MAC_CFG;
+        /* configure ENET_MAC_CFG register */
+        reg_value &= ~(ENET_MAC_CFG_CSD | ENET_MAC_CFG_ROD | ENET_MAC_CFG_RTD \
+                      | ENET_MAC_CFG_BOL | ENET_MAC_CFG_DFC);
+        reg_value |= reg_temp;
+        ENET_MAC_CFG = reg_value;
+    } 
+
+    /* configure timer_config related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)TIMER_OPTION)){   
+        reg_temp = enet_initpara.timer_config;
+              
+        reg_value = ENET_MAC_CFG;
+        /* configure ENET_MAC_CFG register */
+        reg_value &= ~(ENET_MAC_CFG_WDD | ENET_MAC_CFG_JBD);
+        reg_value |= reg_temp;
+        ENET_MAC_CFG = reg_value;
+    } 
+    
+    /* configure interframegap related registers */
+    if(RESET != (enet_initpara.option_enable & (uint32_t)INTERFRAMEGAP_OPTION)){   
+        reg_temp = enet_initpara.interframegap;
+              
+        reg_value = ENET_MAC_CFG;
+        /* configure ENET_MAC_CFG register */
+        reg_value &= ~ENET_MAC_CFG_IGBS;
+        reg_value |= reg_temp;
+        ENET_MAC_CFG = reg_value;
+    }    
+
+    enet_state = SUCCESS;
+    return enet_state;
+}
+
+/*!
+    \brief      reset all core internal registers located in CLK_TX and CLK_RX
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_software_reset(void)
+{
+    uint32_t timeout = 0U;
+    ErrStatus enet_state = ERROR;
+    uint32_t dma_flag;
+    
+    /* reset all core internal registers located in CLK_TX and CLK_RX */
+    ENET_DMA_BCTL |= ENET_DMA_BCTL_SWR;
+    
+    /* wait for reset operation complete */
+    do{
+        dma_flag = (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR);
+        timeout++;
+    }while((RESET != dma_flag) && (ENET_DELAY_TO != timeout));
+
+    /* reset operation complete */    
+    if(RESET == (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR)){
+        enet_state = SUCCESS;
+    }
+    
+    return enet_state;
+}
+
+/*!
+    \brief      check receive frame valid and return frame size
+    \param[in]  none
+    \param[out] none
+    \retval     size of received frame: 0x0 - 0x3FFF
+*/
+uint32_t enet_rxframe_size_get(void)
+{
+    uint32_t size = 0U;
+    uint32_t status;
+    
+    /* get rdes0 information of current RxDMA descriptor */
+    status = dma_current_rxdesc->status;
+    
+    /* if the desciptor is owned by DMA */
+    if((uint32_t)RESET != (status & ENET_RDES0_DAV)){
+        return 0U;
+    }
+    
+    /* if has any error, or the frame uses two or more descriptors */
+    if((((uint32_t)RESET) != (status & ENET_RDES0_ERRS)) ||
+       (((uint32_t)RESET) == (status & ENET_RDES0_LDES)) ||
+       (((uint32_t)RESET) == (status & ENET_RDES0_FDES))){
+        /* drop current receive frame */
+        enet_rxframe_drop();
+
+        return 0U;
+    }
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+    /* if is an ethernet-type frame, and IP frame payload error occurred */
+    if(((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FRMT) &&
+       ((uint32_t)RESET) != (dma_current_rxdesc->extended_status & ENET_RDES4_IPPLDERR)){
+         /* drop current receive frame */
+         enet_rxframe_drop();
+
+        return 0U;
+    }
+#else 
+    /* if is an ethernet-type frame, and IP frame payload error occurred */
+    if((((uint32_t)RESET) != (status & ENET_RDES0_FRMT)) &&
+       (((uint32_t)RESET) != (status & ENET_RDES0_PCERR))){
+         /* drop current receive frame */
+         enet_rxframe_drop();
+
+        return 0U;
+    }  
+#endif 
+    /* if CPU owns current descriptor, no error occured, the frame uses only one descriptor */
+    if((((uint32_t)RESET) == (status & ENET_RDES0_DAV)) &&
+       (((uint32_t)RESET) == (status & ENET_RDES0_ERRS)) &&
+       (((uint32_t)RESET) != (status & ENET_RDES0_LDES)) &&
+       (((uint32_t)RESET) != (status & ENET_RDES0_FDES))){
+        /* get the size of the received data including CRC */
+        size = GET_RDES0_FRML(status);
+        /* substract the CRC size */ 
+        size = size - 4U;
+        
+        /* if is a type frame, and CRC is not included in forwarding frame */ 
+        if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (status & ENET_RDES0_FRMT))){
+            size = size + 4U;
+        }
+    }
+ 
+    /* return packet size */ 
+    return size;
+}
+
+/*!
+    \brief      initialize the DMA Tx/Rx descriptors's parameters in chain mode
+    \param[in]  direction: the descriptors which users want to init, refer to enet_dmadirection_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA Tx descriptors
+      \arg        ENET_DMA_RX: DMA Rx descriptors
+    \param[out] none
+    \retval     none
+*/
+void enet_descriptors_chain_init(enet_dmadirection_enum direction)
+{
+    uint32_t num = 0U, count = 0U, maxsize = 0U;
+    uint32_t desc_status = 0U, desc_bufsize = 0U;
+    enet_descriptors_struct *desc, *desc_tab;
+    uint8_t *buf;  
+
+    /* if want to initialize DMA Tx descriptors */
+    if (ENET_DMA_TX == direction){
+        /* save a copy of the DMA Tx descriptors */
+        desc_tab = txdesc_tab;
+        buf = &tx_buff[0][0];
+        count = ENET_TXBUF_NUM;
+        maxsize = ENET_TXBUF_SIZE;
+      
+        /* select chain mode */
+        desc_status = ENET_TDES0_TCHM;
+      
+        /* configure DMA Tx descriptor table address register */
+        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
+        dma_current_txdesc = desc_tab;
+    }else{ 
+        /* if want to initialize DMA Rx descriptors */
+        /* save a copy of the DMA Rx descriptors */
+        desc_tab = rxdesc_tab;
+        buf = &rx_buff[0][0];
+        count = ENET_RXBUF_NUM;
+        maxsize = ENET_RXBUF_SIZE;
+      
+        /* enable receiving */
+        desc_status = ENET_RDES0_DAV;
+        /* select receive chained mode and set buffer1 size */
+        desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE;
+      
+        /* configure DMA Rx descriptor table address register */
+        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
+        dma_current_rxdesc = desc_tab; 
+    }
+    dma_current_ptp_rxdesc = NULL;
+    dma_current_ptp_txdesc = NULL;
+    
+    /* configure each descriptor */   
+    for(num=0U; num < count; num++){
+        /* get the pointer to the next descriptor of the descriptor table */
+        desc = desc_tab + num;
+
+        /* configure descriptors */
+        desc->status = desc_status;         
+        desc->control_buffer_size = desc_bufsize;
+        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);
+    
+        /* if is not the last descriptor */
+        if(num < (count - 1U)){
+            /* configure the next descriptor address */
+            desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U);
+        }else{
+            /* when it is the last descriptor, the next descriptor address 
+            equals to first descriptor address in descriptor table */ 
+            desc->buffer2_next_desc_addr = (uint32_t) desc_tab;  
+        }
+    }  
+}
+
+/*!
+    \brief      initialize the DMA Tx/Rx descriptors's parameters in ring mode
+    \param[in]  direction: the descriptors which users want to init, refer to enet_dmadirection_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA Tx descriptors
+      \arg        ENET_DMA_RX: DMA Rx descriptors
+    \param[out] none
+    \retval     none
+*/
+void enet_descriptors_ring_init(enet_dmadirection_enum direction)
+{
+    uint32_t num = 0U, count = 0U, maxsize = 0U;
+    uint32_t desc_status = 0U, desc_bufsize = 0U;
+    enet_descriptors_struct *desc;
+    enet_descriptors_struct *desc_tab;
+    uint8_t *buf; 
+  
+    /* configure descriptor skip length */
+    ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL;
+    ENET_DMA_BCTL |= DMA_BCTL_DPSL(0);
+  
+    /* if want to initialize DMA Tx descriptors */
+    if (ENET_DMA_TX == direction){
+        /* save a copy of the DMA Tx descriptors */
+        desc_tab = txdesc_tab;
+        buf = &tx_buff[0][0];
+        count = ENET_TXBUF_NUM;
+        maxsize = ENET_TXBUF_SIZE;      
+      
+        /* configure DMA Tx descriptor table address register */
+        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
+        dma_current_txdesc = desc_tab;
+    }else{
+        /* if want to initialize DMA Rx descriptors */
+        /* save a copy of the DMA Rx descriptors */
+        desc_tab = rxdesc_tab;
+        buf = &rx_buff[0][0];
+        count = ENET_RXBUF_NUM;
+        maxsize = ENET_RXBUF_SIZE;      
+      
+        /* enable receiving */
+        desc_status = ENET_RDES0_DAV;
+        /* set buffer1 size */
+        desc_bufsize = ENET_RXBUF_SIZE;
+      
+         /* configure DMA Rx descriptor table address register */
+        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
+        dma_current_rxdesc = desc_tab; 
+    }
+    dma_current_ptp_rxdesc = NULL;
+    dma_current_ptp_txdesc = NULL;
+    
+    /* configure each descriptor */   
+    for(num=0U; num < count; num++){
+        /* get the pointer to the next descriptor of the descriptor table */
+        desc = desc_tab + num;
+
+        /* configure descriptors */
+        desc->status = desc_status; 
+        desc->control_buffer_size = desc_bufsize;      
+        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);    
+    
+        /* when it is the last descriptor */
+        if(num == (count - 1U)){
+            if (ENET_DMA_TX == direction){
+                /* configure transmit end of ring mode */  
+                desc->status |= ENET_TDES0_TERM;
+            }else{
+                /* configure receive end of ring mode */
+                desc->control_buffer_size |= ENET_RDES1_RERM;
+            }
+        }
+    }   
+}
+
+/*!
+    \brief      handle current received frame data to application buffer
+    \param[in]  bufsize: the size of buffer which is the parameter in function
+    \param[out] buffer: pointer to the received frame data
+                note -- if the input is NULL, user should copy data in application by himself
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize)
+{
+    uint32_t offset = 0U, size = 0U;
+    
+    /* the descriptor is busy due to own by the DMA */
+    if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){
+        return ERROR; 
+    }
+    
+
+    /* if buffer pointer is null, indicates that users has copied data in application */
+    if(NULL != buffer){
+        /* if no error occurs, and the frame uses only one descriptor */
+        if((((uint32_t)RESET) == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && 
+           (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_LDES)) &&  
+           (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FDES))){      
+            /* get the frame length except CRC */
+            size = GET_RDES0_FRML(dma_current_rxdesc->status);
+            size = size - 4U;
+            
+            /* if is a type frame, and CRC is not included in forwarding frame */ 
+            if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){
+                size = size + 4U;
+            }
+            
+            /* to avoid situation that the frame size exceeds the buffer length */
+            if(size > bufsize){
+                return ERROR;
+            }
+            
+            /* copy data from Rx buffer to application buffer */
+            for(offset = 0U; offset<size; offset++){
+                (*(buffer + offset)) = (*(__IO uint8_t *) (uint32_t)((dma_current_rxdesc->buffer1_addr) + offset));
+            }
+            
+        }else{
+            /* return ERROR */
+            return ERROR;
+        }
+    }
+    /* enable reception, descriptor is owned by DMA */
+    dma_current_rxdesc->status = ENET_RDES0_DAV; 
+ 
+    /* check Rx buffer unavailable flag status */
+    if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){
+        /* clear RBU flag */
+        ENET_DMA_STAT = ENET_DMA_STAT_RBU;
+        /* resume DMA reception by writing to the RPEN register*/
+        ENET_DMA_RPEN = 0U;
+    }
+  
+    /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */      
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){      
+        dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr);    
+    }else{    
+        /* ring mode */
+        if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR);      
+        }else{ 
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)));      
+        }
+    }
+  
+    return SUCCESS;
+}
+
+/*!
+    \brief      handle application buffer data to transmit it
+    \param[in]  buffer: pointer to the frame data to be transmitted,
+                note -- if the input is NULL, user should handle the data in application by himself
+    \param[in]  length: the length of frame data to be transmitted
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length)
+{
+    uint32_t offset = 0U;
+    uint32_t dma_tbu_flag, dma_tu_flag;
+    
+    /* the descriptor is busy due to own by the DMA */
+    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){
+        return ERROR;
+    }
+    
+    /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */
+    if(length > ENET_MAX_FRAME_SIZE){
+        return ERROR;
+    } 
+    
+    /* if buffer pointer is null, indicates that users has handled data in application */
+    if(NULL != buffer){    
+        /* copy frame data from application buffer to Tx buffer */
+        for(offset = 0U; offset < length; offset++){
+            (*(__IO uint8_t *) (uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset));
+        }
+    }
+    
+    /* set the frame length */
+    dma_current_txdesc->control_buffer_size = length;
+    /* set the segment of frame, frame is transmitted in one descriptor */    
+    dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG;
+    /* enable the DMA transmission */
+    dma_current_txdesc->status |= ENET_TDES0_DAV;
+    
+    /* check Tx buffer unavailable flag status */
+    dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); 
+    dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU);
+    
+    if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){
+        /* clear TBU and TU flag */
+        ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag);
+        /* resume DMA transmission by writing to the TPEN register*/
+        ENET_DMA_TPEN = 0U;
+    }
+  
+    /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/  
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){     
+        dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr);    
+    }else{   
+        /* ring mode */
+        if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR);      
+        }else{
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)));
+        }
+    }
+
+    return SUCCESS;
+}
+
+/*!
+    \brief      configure the transmit IP frame checksum offload calculation and insertion
+    \param[in]  desc: the descriptor pointer which users want to configure
+    \param[in]  checksum: IP frame checksum configuration
+                only one parameter can be selected which is shown as below
+      \arg        ENET_CHECKSUM_DISABLE: checksum insertion disabled
+      \arg        ENET_CHECKSUM_IPV4HEADER: only IP header checksum calculation and insertion are enabled
+      \arg        ENET_CHECKSUM_TCPUDPICMP_SEGMENT: TCP/UDP/ICMP checksum insertion calculated but pseudo-header
+      \arg        ENET_CHECKSUM_TCPUDPICMP_FULL: TCP/UDP/ICMP checksum insertion fully calculated
+    \param[out] none
+    \retval     none
+*/
+void enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum)
+{
+    desc->status &= ~ENET_TDES0_CM;
+    desc->status |= checksum;
+}
+
+/*!
+    \brief      ENET Tx and Rx function enable (include MAC and DMA module)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_enable(void)
+{
+    enet_tx_enable();
+    enet_rx_enable();
+}
+
+/*!
+    \brief      ENET Tx and Rx function disable (include MAC and DMA module)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_disable(void)
+{
+    enet_tx_disable();
+    enet_rx_disable();
+}
+
+/*!
+    \brief      configure MAC address 
+    \param[in]  mac_addr: select which MAC address will be set, 
+                only one parameter can be selected which is shown as below  
+      \arg        ENET_MAC_ADDRESS0: set MAC address 0 filter
+      \arg        ENET_MAC_ADDRESS1: set MAC address 1 filter
+      \arg        ENET_MAC_ADDRESS2: set MAC address 2 filter
+      \arg        ENET_MAC_ADDRESS3: set MAC address 3 filter
+    \param[in]  paddr: the buffer pointer which stores the MAC address
+                  (little-ending store, such as MAC address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) 
+    \param[out] none
+    \retval     none
+*/ 
+void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[])
+{
+    REG32(ENET_ADDRH_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRH(paddr);
+    REG32(ENET_ADDRL_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRL(paddr);
+}
+
+/*!
+    \brief      get MAC address 
+    \param[in]  mac_addr: select which MAC address will be get,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_ADDRESS0: get MAC address 0 filter
+      \arg        ENET_MAC_ADDRESS1: get MAC address 1 filter
+      \arg        ENET_MAC_ADDRESS2: get MAC address 2 filter
+      \arg        ENET_MAC_ADDRESS3: get MAC address 3 filter
+    \param[out] paddr: the buffer pointer which is stored the MAC address
+                  (little-ending store, such as mac address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) 
+    \retval     none
+*/                                   
+void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[])
+{
+    paddr[0] = ENET_GET_MACADDR(mac_addr, 0U);
+    paddr[1] = ENET_GET_MACADDR(mac_addr, 1U);
+    paddr[2] = ENET_GET_MACADDR(mac_addr, 2U);
+    paddr[3] = ENET_GET_MACADDR(mac_addr, 3U);
+    paddr[4] = ENET_GET_MACADDR(mac_addr, 4U);
+    paddr[5] = ENET_GET_MACADDR(mac_addr, 5U);
+}
+
+/*!
+    \brief      get the ENET MAC/MSC/PTP/DMA status flag 
+    \param[in]  enet_flag: ENET status flag, refer to enet_flag_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_FLAG_MPKR: magic packet received flag 
+      \arg        ENET_MAC_FLAG_WUFR: wakeup frame received flag
+      \arg        ENET_MAC_FLAG_FLOWCONTROL: flow control status flag 
+      \arg        ENET_MAC_FLAG_WUM: WUM status flag
+      \arg        ENET_MAC_FLAG_MSC: MSC status flag
+      \arg        ENET_MAC_FLAG_MSCR: MSC receive status flag
+      \arg        ENET_MAC_FLAG_MSCT: MSC transmit status flag
+      \arg        ENET_MAC_FLAG_TMST: time stamp trigger status flag
+      \arg        ENET_PTP_FLAG_TSSCO: timestamp second counter overflow flag
+      \arg        ENET_PTP_FLAG_TTM: target time match flag
+      \arg        ENET_MSC_FLAG_RFCE: received frames CRC error flag
+      \arg        ENET_MSC_FLAG_RFAE: received frames alignment error flag
+      \arg        ENET_MSC_FLAG_RGUF: received good unicast frames flag
+      \arg        ENET_MSC_FLAG_TGFSC: transmitted good frames single collision flag
+      \arg        ENET_MSC_FLAG_TGFMSC: transmitted good frames more single collision flag
+      \arg        ENET_MSC_FLAG_TGF: transmitted good frames flag
+      \arg        ENET_DMA_FLAG_TS: transmit status flag
+      \arg        ENET_DMA_FLAG_TPS: transmit process stopped status flag
+      \arg        ENET_DMA_FLAG_TBU: transmit buffer unavailable status flag
+      \arg        ENET_DMA_FLAG_TJT: transmit jabber timeout status flag
+      \arg        ENET_DMA_FLAG_RO: receive overflow status flag
+      \arg        ENET_DMA_FLAG_TU: transmit underflow status flag
+      \arg        ENET_DMA_FLAG_RS: receive status flag
+      \arg        ENET_DMA_FLAG_RBU: receive buffer unavailable status flag
+      \arg        ENET_DMA_FLAG_RPS: receive process stopped status flag
+      \arg        ENET_DMA_FLAG_RWT: receive watchdog timeout status flag
+      \arg        ENET_DMA_FLAG_ET: early transmit status flag
+      \arg        ENET_DMA_FLAG_FBE: fatal bus error status flag
+      \arg        ENET_DMA_FLAG_ER: early receive status flag
+      \arg        ENET_DMA_FLAG_AI: abnormal interrupt summary flag
+      \arg        ENET_DMA_FLAG_NI: normal interrupt summary flag
+      \arg        ENET_DMA_FLAG_EB_DMA_ERROR: DMA error flag
+      \arg        ENET_DMA_FLAG_EB_TRANSFER_ERROR: transfer error flag
+      \arg        ENET_DMA_FLAG_EB_ACCESS_ERROR: access error flag
+      \arg        ENET_DMA_FLAG_MSC: MSC status flag
+      \arg        ENET_DMA_FLAG_WUM: WUM status flag
+      \arg        ENET_DMA_FLAG_TST: timestamp trigger status flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus enet_flag_get(enet_flag_enum enet_flag)
+{
+    if(RESET != (ENET_REG_VAL(enet_flag) & BIT(ENET_BIT_POS(enet_flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the ENET DMA status flag 
+    \param[in]  enet_flag: ENET DMA flag clear, refer to enet_flag_clear_enum
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_FLAG_TS_CLR: transmit status flag clear
+      \arg        ENET_DMA_FLAG_TPS_CLR: transmit process stopped status flag clear
+      \arg        ENET_DMA_FLAG_TBU_CLR: transmit buffer unavailable status flag clear
+      \arg        ENET_DMA_FLAG_TJT_CLR: transmit jabber timeout status flag clear
+      \arg        ENET_DMA_FLAG_RO_CLR: receive overflow status flag clear
+      \arg        ENET_DMA_FLAG_TU_CLR: transmit underflow status flag clear
+      \arg        ENET_DMA_FLAG_RS_CLR: receive status flag clear
+      \arg        ENET_DMA_FLAG_RBU_CLR: receive buffer unavailable status flag clear
+      \arg        ENET_DMA_FLAG_RPS_CLR: receive process stopped status flag clear
+      \arg        ENET_DMA_FLAG_RWT_CLR: receive watchdog timeout status flag clear
+      \arg        ENET_DMA_FLAG_ET_CLR: early transmit status flag clear
+      \arg        ENET_DMA_FLAG_FBE_CLR: fatal bus error status flag clear
+      \arg        ENET_DMA_FLAG_ER_CLR: early receive status flag clear
+      \arg        ENET_DMA_FLAG_AI_CLR: abnormal interrupt summary flag clear
+      \arg        ENET_DMA_FLAG_NI_CLR: normal interrupt summary flag clear
+    \param[out] none
+    \retval     none
+*/
+void enet_flag_clear(enet_flag_clear_enum enet_flag)
+{
+    /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */
+    ENET_REG_VAL(enet_flag) = BIT(ENET_BIT_POS(enet_flag));
+}
+
+/*!
+    \brief      enable ENET MAC/MSC/DMA interrupt 
+    \param[in]  enet_int: ENET interrupt,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_INT_WUMIM: WUM interrupt mask
+      \arg        ENET_MAC_INT_TMSTIM: timestamp trigger interrupt mask
+      \arg        ENET_MSC_INT_RFCEIM: received frame CRC error interrupt mask
+      \arg        ENET_MSC_INT_RFAEIM: received frames alignment error interrupt mask
+      \arg        ENET_MSC_INT_RGUFIM: received good unicast frames interrupt mask
+      \arg        ENET_MSC_INT_TGFSCIM: transmitted good frames single collision interrupt mask
+      \arg        ENET_MSC_INT_TGFMSCIM: transmitted good frames more single collision interrupt mask
+      \arg        ENET_MSC_INT_TGFIM: transmitted good frames interrupt mask
+      \arg        ENET_DMA_INT_TIE: transmit interrupt enable
+      \arg        ENET_DMA_INT_TPSIE: transmit process stopped interrupt enable
+      \arg        ENET_DMA_INT_TBUIE: transmit buffer unavailable interrupt enable
+      \arg        ENET_DMA_INT_TJTIE: transmit jabber timeout interrupt enable
+      \arg        ENET_DMA_INT_ROIE: receive overflow interrupt enable
+      \arg        ENET_DMA_INT_TUIE: transmit underflow interrupt enable
+      \arg        ENET_DMA_INT_RIE: receive interrupt enable
+      \arg        ENET_DMA_INT_RBUIE: receive buffer unavailable interrupt enable
+      \arg        ENET_DMA_INT_RPSIE: receive process stopped interrupt enable
+      \arg        ENET_DMA_INT_RWTIE: receive watchdog timeout interrupt enable
+      \arg        ENET_DMA_INT_ETIE: early transmit interrupt enable
+      \arg        ENET_DMA_INT_FBEIE: fatal bus error interrupt enable
+      \arg        ENET_DMA_INT_ERIE: early receive interrupt enable
+      \arg        ENET_DMA_INT_AIE: abnormal interrupt summary enable
+      \arg        ENET_DMA_INT_NIE: normal interrupt summary enable
+    \param[out] none
+    \retval     none
+*/
+void enet_interrupt_enable(enet_int_enum enet_int)
+{
+    if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)){
+        /* ENET_DMA_INTEN register interrupt */
+        ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int));
+    }else{
+        /* other INTMSK register interrupt */
+        ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int));
+    }
+}
+
+/*!
+    \brief      disable ENET MAC/MSC/DMA interrupt 
+    \param[in]  enet_int: ENET interrupt,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_INT_WUMIM: WUM interrupt mask
+      \arg        ENET_MAC_INT_TMSTIM: timestamp trigger interrupt mask
+      \arg        ENET_MSC_INT_RFCEIM: received frame CRC error interrupt mask
+      \arg        ENET_MSC_INT_RFAEIM: received frames alignment error interrupt mask
+      \arg        ENET_MSC_INT_RGUFIM: received good unicast frames interrupt mask
+      \arg        ENET_MSC_INT_TGFSCIM: transmitted good frames single collision interrupt mask
+      \arg        ENET_MSC_INT_TGFMSCIM: transmitted good frames more single collision interrupt mask
+      \arg        ENET_MSC_INT_TGFIM: transmitted good frames interrupt mask
+      \arg        ENET_DMA_INT_TIE: transmit interrupt enable
+      \arg        ENET_DMA_INT_TPSIE: transmit process stopped interrupt enable
+      \arg        ENET_DMA_INT_TBUIE: transmit buffer unavailable interrupt enable
+      \arg        ENET_DMA_INT_TJTIE: transmit jabber timeout interrupt enable
+      \arg        ENET_DMA_INT_ROIE: receive overflow interrupt enable
+      \arg        ENET_DMA_INT_TUIE: transmit underflow interrupt enable
+      \arg        ENET_DMA_INT_RIE: receive interrupt enable
+      \arg        ENET_DMA_INT_RBUIE: receive buffer unavailable interrupt enable
+      \arg        ENET_DMA_INT_RPSIE: receive process stopped interrupt enable
+      \arg        ENET_DMA_INT_RWTIE: receive watchdog timeout interrupt enable
+      \arg        ENET_DMA_INT_ETIE: early transmit interrupt enable
+      \arg        ENET_DMA_INT_FBEIE: fatal bus error interrupt enable
+      \arg        ENET_DMA_INT_ERIE: early receive interrupt enable
+      \arg        ENET_DMA_INT_AIE: abnormal interrupt summary enable
+      \arg        ENET_DMA_INT_NIE: normal interrupt summary enable
+    \param[out] none
+    \retval     none
+*/
+void enet_interrupt_disable(enet_int_enum enet_int)
+{
+    if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)){
+        /* ENET_DMA_INTEN register interrupt */
+        ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int));
+    }else{
+        /* other INTMSK register interrupt */
+        ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int));
+    }
+}
+
+/*!
+    \brief      get ENET MAC/MSC/DMA interrupt flag 
+    \param[in]  int_flag: ENET interrupt flag,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_INT_FLAG_WUM: WUM status flag
+      \arg        ENET_MAC_INT_FLAG_MSC: MSC status flag
+      \arg        ENET_MAC_INT_FLAG_MSCR: MSC receive status flag
+      \arg        ENET_MAC_INT_FLAG_MSCT: MSC transmit status flag
+      \arg        ENET_MAC_INT_FLAG_TMST: time stamp trigger status flag
+      \arg        ENET_MSC_INT_FLAG_RFCE: received frames CRC error flag
+      \arg        ENET_MSC_INT_FLAG_RFAE: received frames alignment error flag
+      \arg        ENET_MSC_INT_FLAG_RGUF: received good unicast frames flag
+      \arg        ENET_MSC_INT_FLAG_TGFSC: transmitted good frames single collision flag
+      \arg        ENET_MSC_INT_FLAG_TGFMSC: transmitted good frames more single collision flag
+      \arg        ENET_MSC_INT_FLAG_TGF: transmitted good frames flag
+      \arg        ENET_DMA_INT_FLAG_TS: transmit status flag
+      \arg        ENET_DMA_INT_FLAG_TPS: transmit process stopped status flag
+      \arg        ENET_DMA_INT_FLAG_TBU: transmit buffer unavailable status flag
+      \arg        ENET_DMA_INT_FLAG_TJT: transmit jabber timeout status flag
+      \arg        ENET_DMA_INT_FLAG_RO: receive overflow status flag
+      \arg        ENET_DMA_INT_FLAG_TU: transmit underflow status flag
+      \arg        ENET_DMA_INT_FLAG_RS: receive status flag
+      \arg        ENET_DMA_INT_FLAG_RBU: receive buffer unavailable status flag
+      \arg        ENET_DMA_INT_FLAG_RPS: receive process stopped status flag
+      \arg        ENET_DMA_INT_FLAG_RWT: receive watchdog timeout status flag
+      \arg        ENET_DMA_INT_FLAG_ET: early transmit status flag
+      \arg        ENET_DMA_INT_FLAG_FBE: fatal bus error status flag
+      \arg        ENET_DMA_INT_FLAG_ER: early receive status flag
+      \arg        ENET_DMA_INT_FLAG_AI: abnormal interrupt summary flag
+      \arg        ENET_DMA_INT_FLAG_NI: normal interrupt summary flag
+      \arg        ENET_DMA_INT_FLAG_MSC: MSC status flag
+      \arg        ENET_DMA_INT_FLAG_WUM: WUM status flag
+      \arg        ENET_DMA_INT_FLAG_TST: timestamp trigger status flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus enet_interrupt_flag_get(enet_int_flag_enum int_flag)
+{
+    if(RESET != (ENET_REG_VAL(int_flag) & BIT(ENET_BIT_POS(int_flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear ENET DMA interrupt flag 
+    \param[in]  int_flag_clear: clear ENET interrupt flag,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_INT_FLAG_TS_CLR: transmit status flag
+      \arg        ENET_DMA_INT_FLAG_TPS_CLR: transmit process stopped status flag
+      \arg        ENET_DMA_INT_FLAG_TBU_CLR: transmit buffer unavailable status flag
+      \arg        ENET_DMA_INT_FLAG_TJT_CLR: transmit jabber timeout status flag
+      \arg        ENET_DMA_INT_FLAG_RO_CLR: receive overflow status flag
+      \arg        ENET_DMA_INT_FLAG_TU_CLR: transmit underflow status flag
+      \arg        ENET_DMA_INT_FLAG_RS_CLR: receive status flag
+      \arg        ENET_DMA_INT_FLAG_RBU_CLR: receive buffer unavailable status flag
+      \arg        ENET_DMA_INT_FLAG_RPS_CLR: receive process stopped status flag
+      \arg        ENET_DMA_INT_FLAG_RWT_CLR: receive watchdog timeout status flag
+      \arg        ENET_DMA_INT_FLAG_ET_CLR: early transmit status flag
+      \arg        ENET_DMA_INT_FLAG_FBE_CLR: fatal bus error status flag
+      \arg        ENET_DMA_INT_FLAG_ER_CLR: early receive status flag
+      \arg        ENET_DMA_INT_FLAG_AI_CLR: abnormal interrupt summary flag
+      \arg        ENET_DMA_INT_FLAG_NI_CLR: normal interrupt summary flag
+    \param[out] none
+    \retval     none
+*/
+void enet_interrupt_flag_clear(enet_int_flag_clear_enum int_flag_clear)
+{
+    /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */
+    ENET_REG_VAL(int_flag_clear) = BIT(ENET_BIT_POS(int_flag_clear));
+}
+
+/*!
+    \brief      ENET Tx function enable (include MAC and DMA module)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_tx_enable(void)
+{
+    ENET_MAC_CFG |= ENET_MAC_CFG_TEN;
+    enet_txfifo_flush();
+    ENET_DMA_CTL |= ENET_DMA_CTL_STE;
+}
+
+/*!
+    \brief      ENET Tx function disable (include MAC and DMA module)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_tx_disable(void)
+{    
+    ENET_DMA_CTL &= ~ENET_DMA_CTL_STE;
+    enet_txfifo_flush();
+    ENET_MAC_CFG &= ~ENET_MAC_CFG_TEN;
+}
+
+/*!
+    \brief      ENET Rx function enable (include MAC and DMA module)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_rx_enable(void)
+{
+    ENET_MAC_CFG |= ENET_MAC_CFG_REN;
+    ENET_DMA_CTL |= ENET_DMA_CTL_SRE;
+}
+
+/*!
+    \brief      ENET Rx function disable (include MAC and DMA module)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_rx_disable(void)
+{
+    ENET_DMA_CTL &= ~ENET_DMA_CTL_SRE;
+    ENET_MAC_CFG &= ~ENET_MAC_CFG_REN;
+}
+
+/*!
+    \brief      put registers value into the application buffer 
+    \param[in]  type: register type which will be get, refer to enet_registers_type_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ALL_MAC_REG: get the registers within the offset scope between ENET_MAC_CFG and ENET_MAC_FCTH 
+      \arg        ALL_MSC_REG: get the registers within the offset scope between ENET_MSC_CTL and ENET_MSC_RGUFCNT
+      \arg        ALL_PTP_REG: get the registers within the offset scope between ENET_PTP_TSCTL and ENET_PTP_PPSCTL
+      \arg        ALL_DMA_REG: get the registers within the offset scope between ENET_DMA_BCTL and ENET_DMA_CRBADDR
+    \param[in]  num: the number of registers that the user want to get
+    \param[out] preg: the application buffer pointer for storing the register value
+    \retval     none
+*/
+void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t num)
+{
+    uint32_t offset = 0U, max = 0U, limit = 0U;
+    
+    offset = (uint32_t)type;
+    max = (uint32_t)type + num;
+    limit = sizeof(enet_reg_tab)/sizeof(uint16_t);
+    
+    /* prevent element in this array is out of range */
+    if(max > limit){ 
+        max = limit;
+    }
+    
+    for(; offset < max; offset++){
+        /* get value of the corresponding register */
+        *preg = REG32((ENET) + enet_reg_tab[offset]); 
+        preg++;
+    }
+} 
+
+/*!
+    \brief      get the enet debug status from the debug register
+    \param[in]  mac_debug: enet debug status,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_RECEIVER_NOT_IDLE: MAC receiver is not in idle state
+      \arg        ENET_RX_ASYNCHRONOUS_FIFO_STATE: Rx asynchronous FIFO status
+      \arg        ENET_RXFIFO_NOT_WRITING: RxFIFO is not doing write operation
+      \arg        ENET_RXFIFO_READ_STATUS: RxFIFO read operation status
+      \arg        ENET_RXFIFO_STATE: RxFIFO state
+      \arg        ENET_MAC_TRANSMITTER_NOT_IDLE: MAC transmitter is not in idle state
+      \arg        ENET_MAC_TRANSMITTER_STATUS: status of MAC transmitter
+      \arg        ENET_PAUSE_CONDITION_STATUS: pause condition status
+      \arg        ENET_TXFIFO_READ_STATUS: TxFIFO read operation status
+      \arg        ENET_TXFIFO_NOT_WRITING: TxFIFO is not doing write operation
+      \arg        ENET_TXFIFO_NOT_EMPTY: TxFIFO is not empty
+      \arg        ENET_TXFIFO_FULL: TxFIFO is full
+    \param[out] none
+    \retval     value of the status users want to get
+*/
+uint32_t enet_debug_status_get(uint32_t mac_debug)
+{
+    uint32_t temp_state = 0U;
+  
+    switch(mac_debug){
+    case ENET_RX_ASYNCHRONOUS_FIFO_STATE:
+        temp_state = GET_MAC_DBG_RXAFS(ENET_MAC_DBG);
+        break;
+    case ENET_RXFIFO_READ_STATUS:
+        temp_state = GET_MAC_DBG_RXFRS(ENET_MAC_DBG);
+        break;
+    case ENET_RXFIFO_STATE:
+        temp_state = GET_MAC_DBG_RXFS(ENET_MAC_DBG);
+        break;
+    case ENET_MAC_TRANSMITTER_STATUS:
+        temp_state = GET_MAC_DBG_SOMT(ENET_MAC_DBG);
+        break;
+    case ENET_TXFIFO_READ_STATUS:
+        temp_state = GET_MAC_DBG_TXFRS(ENET_MAC_DBG);
+        break;
+    default:
+        if(RESET != (ENET_MAC_DBG & mac_debug)){
+            temp_state = 0x1U;
+        }
+        break;        
+    }
+    return temp_state;
+}
+
+/*!
+    \brief      enable the MAC address filter 
+    \param[in]  mac_addr: select which MAC address will be enable  
+      \arg        ENET_MAC_ADDRESS1: enable MAC address 1 filter
+      \arg        ENET_MAC_ADDRESS2: enable MAC address 2 filter
+      \arg        ENET_MAC_ADDRESS3: enable MAC address 3 filter
+    \param[out] none
+    \retval     none
+*/
+void enet_address_filter_enable(enet_macaddress_enum mac_addr)
+{
+    REG32(ENET_ADDRH_BASE + mac_addr) |= ENET_MAC_ADDR1H_AFE;
+}
+
+/*!
+    \brief      disable the MAC address filter 
+    \param[in]  mac_addr: select which MAC address will be disable,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_ADDRESS1: disable MAC address 1 filter
+      \arg        ENET_MAC_ADDRESS2: disable MAC address 2 filter
+      \arg        ENET_MAC_ADDRESS3: disable MAC address 3 filter
+    \param[out] none
+    \retval     none
+*/
+void enet_address_filter_disable(enet_macaddress_enum mac_addr)
+{
+    REG32(ENET_ADDRH_BASE + mac_addr) &= ~ENET_MAC_ADDR1H_AFE;
+}
+
+/*!
+    \brief      configure the MAC address filter 
+    \param[in]  mac_addr: select which MAC address will be configured,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC_ADDRESS1: configure MAC address 1 filter
+      \arg        ENET_MAC_ADDRESS2: configure MAC address 2 filter
+      \arg        ENET_MAC_ADDRESS3: configure MAC address 3 filter
+    \param[in]  addr_mask: select which MAC address bytes will be mask,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_ADDRESS_MASK_BYTE0: mask ENET_MAC_ADDR1L[7:0] bits
+      \arg        ENET_ADDRESS_MASK_BYTE1: mask ENET_MAC_ADDR1L[15:8] bits 
+      \arg        ENET_ADDRESS_MASK_BYTE2: mask ENET_MAC_ADDR1L[23:16] bits
+      \arg        ENET_ADDRESS_MASK_BYTE3: mask ENET_MAC_ADDR1L [31:24] bits
+      \arg        ENET_ADDRESS_MASK_BYTE4: mask ENET_MAC_ADDR1H [7:0] bits
+      \arg        ENET_ADDRESS_MASK_BYTE5: mask ENET_MAC_ADDR1H [15:8] bits
+    \param[in]  filter_type: select which MAC address filter type will be selected,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_ADDRESS_FILTER_SA: The MAC address is used to compared with the SA field of the received frame
+      \arg        ENET_ADDRESS_FILTER_DA: The MAC address is used to compared with the DA field of the received frame
+    \param[out] none
+    \retval     none
+*/
+void enet_address_filter_config(enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type)
+{
+    uint32_t reg;
+    
+    /* get the address filter register value which is to be configured */
+    reg = REG32(ENET_ADDRH_BASE + mac_addr);
+
+    /* clear and configure the address filter register */
+    reg &= ~(ENET_MAC_ADDR1H_MB | ENET_MAC_ADDR1H_SAF);
+    reg |= (addr_mask | filter_type);
+    REG32(ENET_ADDRH_BASE + mac_addr) = reg;
+}
+
+/*!
+    \brief      PHY interface configuration (configure SMI clock and reset PHY chip)
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/ 
+ErrStatus enet_phy_config(void)
+{
+    uint32_t ahbclk;
+    uint32_t reg;
+    uint16_t phy_value;
+    ErrStatus enet_state = ERROR;
+  
+    /* clear the previous MDC clock */
+    reg = ENET_MAC_PHY_CTL;
+    reg &= ~ENET_MAC_PHY_CTL_CLR;
+
+    /* get the HCLK frequency */
+    ahbclk = rcu_clock_freq_get(CK_AHB);
+  
+    /* configure MDC clock according to HCLK frequency range */
+    if(ENET_RANGE(ahbclk, 20000000U, 35000000U)){
+        reg |= ENET_MDC_HCLK_DIV16;
+    }else if(ENET_RANGE(ahbclk, 35000000U, 60000000U)){
+        reg |= ENET_MDC_HCLK_DIV26;
+    }else if(ENET_RANGE(ahbclk, 60000000U, 100000000U)){
+        reg |= ENET_MDC_HCLK_DIV42;
+    }else if(ENET_RANGE(ahbclk, 100000000U, 150000000U)){
+        reg |= ENET_MDC_HCLK_DIV62;
+    }else if((ENET_RANGE(ahbclk, 150000000U, 200000000U))||(200000000U == ahbclk)){
+        reg |= ENET_MDC_HCLK_DIV102;    
+    }else{
+        return enet_state;
+    }
+    ENET_MAC_PHY_CTL = reg;
+
+    /* reset PHY */
+    phy_value = PHY_RESET;
+    if(ERROR == (enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){
+        return enet_state;
+    }
+    /* PHY reset need some time */    
+    _ENET_DELAY_(ENET_DELAY_TO);
+    
+    /* check whether PHY reset is complete */
+    if(ERROR == (enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){
+        return enet_state;
+    }
+
+    /* PHY reset complete */
+    if(RESET == (phy_value & PHY_RESET)){
+        enet_state = SUCCESS;
+    }
+    
+    return enet_state;
+}
+
+/*!
+    \brief      write to / read from a PHY register
+    \param[in]  direction: only one parameter can be selected which is shown as below
+      \arg        ENET_PHY_WRITE: write data to phy register
+      \arg        ENET_PHY_READ:  read data from phy register
+    \param[in]  phy_address: 0x0 - 0x1F
+    \param[in]  phy_reg: 0x0 - 0x1F
+    \param[in]  pvalue: the value will be written to the PHY register in ENET_PHY_WRITE direction 
+    \param[out] pvalue: the value will be read from the PHY register in ENET_PHY_READ direction
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_phy_write_read(enet_phydirection_enum direction, uint16_t phy_address, uint16_t phy_reg, uint16_t *pvalue)
+{
+    uint32_t reg, phy_flag;
+    uint32_t timeout = 0U;
+    ErrStatus enet_state = ERROR;
+
+    /* configure ENET_MAC_PHY_CTL with write/read operation */  
+    reg = ENET_MAC_PHY_CTL;
+    reg &= ~(ENET_MAC_PHY_CTL_PB | ENET_MAC_PHY_CTL_PW | ENET_MAC_PHY_CTL_PR | ENET_MAC_PHY_CTL_PA);
+    reg |= (direction | MAC_PHY_CTL_PR(phy_reg) | MAC_PHY_CTL_PA(phy_address) | ENET_MAC_PHY_CTL_PB); 
+
+    /* if do the write operation, write value to the register */
+    if(ENET_PHY_WRITE == direction){
+        ENET_MAC_PHY_DATA = *pvalue;        
+    }
+    
+    /* do PHY write/read operation, and wait the operation complete  */
+    ENET_MAC_PHY_CTL = reg;
+    do{
+        phy_flag = (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB);
+        timeout++;
+    }
+    while((RESET != phy_flag) && (ENET_DELAY_TO != timeout));
+
+    /* write/read operation complete */    
+    if(RESET == (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB)){
+        enet_state = SUCCESS;
+    }
+
+    /* if do the read operation, get value from the register */    
+    if(ENET_PHY_READ == direction){
+        *pvalue = (uint16_t)ENET_MAC_PHY_DATA;        
+    }
+    
+    return enet_state;
+}
+
+/*!
+    \brief      enable the loopback function of PHY chip
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus enet_phyloopback_enable(void)
+{
+    uint16_t temp_phy = 0U;
+    ErrStatus phy_state = ERROR;
+
+    /* get the PHY configuration to update it */
+    enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); 
+
+    /* enable the PHY loopback mode */
+    temp_phy |= PHY_LOOPBACK;
+
+    /* update the PHY control register with the new configuration */
+    phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy);
+
+    return phy_state;
+}
+
+/*!
+    \brief      disable the loopback function of PHY chip
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus enet_phyloopback_disable(void)
+{
+    uint16_t temp_phy = 0U;
+    ErrStatus phy_state = ERROR;
+
+    /* get the PHY configuration to update it */
+    enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); 
+
+    /* disable the PHY loopback mode */
+    temp_phy &= (uint16_t)~PHY_LOOPBACK;
+
+    /* update the PHY control register with the new configuration */
+    phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy);
+
+    return phy_state;
+}
+
+/*!
+    \brief      enable ENET forward feature
+    \param[in]  feature: the feature of ENET forward mode,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_AUTO_PADCRC_DROP: the function of the MAC strips the Pad/FCS field on received frames
+      \arg        ENET_TYPEFRAME_CRC_DROP: the function that FCS field(last 4 bytes) of frame will be dropped before forwarding
+      \arg        ENET_FORWARD_ERRFRAMES: the function that all frame received with error except runt error are forwarded to memory
+      \arg        ENET_FORWARD_UNDERSZ_GOODFRAMES: the function that forwarding undersized good frames
+    \param[out] none
+    \retval     none
+*/
+void enet_forward_feature_enable(uint32_t feature)
+{
+    uint32_t mask;
+    
+    mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES)));
+    ENET_MAC_CFG |= mask;
+    
+    mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP)));
+    ENET_DMA_CTL |= (mask >> 2);
+}
+
+/*!
+    \brief      disable ENET forward feature
+    \param[in]  feature: the feature of ENET forward mode,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_AUTO_PADCRC_DROP: the automatic zero-quanta generation function
+      \arg        ENET_TYPEFRAME_CRC_DROP: the flow control operation in the MAC
+      \arg        ENET_FORWARD_ERRFRAMES: decoding function for the received pause frame and process it
+      \arg        ENET_FORWARD_UNDERSZ_GOODFRAMES: back pressure operation in the MAC(only use in half-dulex mode)
+    \param[out] none
+    \retval     none
+*/
+void enet_forward_feature_disable(uint32_t feature)
+{
+    uint32_t mask;
+    
+    mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES)));
+    ENET_MAC_CFG &= ~mask;
+    
+    mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP)));
+    ENET_DMA_CTL &= ~(mask >> 2);
+}
+                            
+/*!                    
+    \brief      enable ENET fliter feature
+    \param[in]  feature: the feature of ENET fliter mode,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_SRC_FILTER: filter source address function
+      \arg        ENET_SRC_FILTER_INVERSE: inverse source address filtering result function
+      \arg        ENET_DEST_FILTER_INVERSE: inverse DA filtering result function
+      \arg        ENET_MULTICAST_FILTER_PASS: pass all multicast frames function
+      \arg        ENET_MULTICAST_FILTER_HASH_MODE: HASH multicast filter function
+      \arg        ENET_UNICAST_FILTER_HASH_MODE: HASH unicast filter function
+      \arg        ENET_FILTER_MODE_EITHER: HASH or perfect filter function
+    \param[out] none
+    \retval     none
+*/
+void enet_fliter_feature_enable(uint32_t feature)
+{
+    ENET_MAC_FRMF |= feature;
+}
+
+/*!
+    \brief      disable ENET fliter feature
+    \param[in]  feature: the feature of ENET fliter mode,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_SRC_FILTER: filter source address function
+      \arg        ENET_SRC_FILTER_INVERSE: inverse source address filtering result function
+      \arg        ENET_DEST_FILTER_INVERSE: inverse DA filtering result function
+      \arg        ENET_MULTICAST_FILTER_PASS: pass all multicast frames function
+      \arg        ENET_MULTICAST_FILTER_HASH_MODE: HASH multicast filter function
+      \arg        ENET_UNICAST_FILTER_HASH_MODE: HASH unicast filter function
+      \arg        ENET_FILTER_MODE_EITHER: HASH or perfect filter function
+    \param[out] none
+    \retval     none
+*/
+void enet_fliter_feature_disable(uint32_t feature)
+{
+    ENET_MAC_FRMF &= ~feature;
+}
+
+/*!
+    \brief      generate the pause frame, ENET will send pause frame after enable transmit flow control
+                this function only use in full-dulex mode
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus enet_pauseframe_generate(void)  
+{ 
+    ErrStatus enet_state =ERROR;
+    uint32_t temp = 0U;
+
+    /* in full-duplex mode, must make sure this bit is 0 before writing register */
+    temp = ENET_MAC_FCTL & ENET_MAC_FCTL_FLCBBKPA;
+    if(RESET == temp){
+        ENET_MAC_FCTL |= ENET_MAC_FCTL_FLCBBKPA;
+        enet_state = SUCCESS;
+    }
+    return enet_state;    
+}
+
+/*!
+    \brief      configure the pause frame detect type
+    \param[in]  detect: pause frame detect type,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT: besides the unique multicast address, MAC can also
+                                                            use the MAC0 address to detecting pause frame
+      \arg        ENET_UNIQUE_PAUSEDETECT: only the unique multicast address for pause frame which is specified 
+                                           in IEEE802.3 can be detected
+    \param[out] none
+    \retval     none
+*/
+void enet_pauseframe_detect_config(uint32_t detect)
+{
+    ENET_MAC_FCTL &= ~ENET_MAC_FCTL_UPFDT;
+    ENET_MAC_FCTL |= detect;
+}
+
+/*!
+    \brief      configure the pause frame parameters
+    \param[in]  pausetime: pause time in transmit pause control frame
+    \param[in]  pause_threshold: the threshold of the pause timer for retransmitting frames automatically,
+                this value must make sure to be less than configured pause time, only one parameter can be
+                selected which is shown as below
+      \arg        ENET_PAUSETIME_MINUS4: pause time minus 4 slot times
+      \arg        ENET_PAUSETIME_MINUS28: pause time minus 28 slot times
+      \arg        ENET_PAUSETIME_MINUS144: pause time minus 144 slot times
+      \arg        ENET_PAUSETIME_MINUS256: pause time minus 256 slot times
+    \param[out] none
+    \retval     none
+*/
+void enet_pauseframe_config(uint32_t pausetime, uint32_t pause_threshold)
+{
+    ENET_MAC_FCTL &= ~(ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_PLTS);
+    ENET_MAC_FCTL |= (MAC_FCTL_PTM(pausetime) | pause_threshold);
+}
+
+/*!
+    \brief      configure the threshold of the flow control(deactive and active threshold)
+    \param[in]  deactive: the threshold of the deactive flow control, this value
+                should always be less than active flow control value, only one 
+                parameter can be selected which is shown as below
+      \arg        ENET_DEACTIVE_THRESHOLD_256BYTES: threshold level is 256 bytes
+      \arg        ENET_DEACTIVE_THRESHOLD_512BYTES: threshold level is 512 bytes
+      \arg        ENET_DEACTIVE_THRESHOLD_768BYTES: threshold level is 768 bytes
+      \arg        ENET_DEACTIVE_THRESHOLD_1024BYTES: threshold level is 1024 bytes
+      \arg        ENET_DEACTIVE_THRESHOLD_1280BYTES: threshold level is 1280 bytes
+      \arg        ENET_DEACTIVE_THRESHOLD_1536BYTES: threshold level is 1536 bytes
+      \arg        ENET_DEACTIVE_THRESHOLD_1792BYTES: threshold level is 1792 bytes
+    \param[in]  active: the threshold of the active flow control, only one parameter
+                can be selected which is shown as below
+      \arg        ENET_ACTIVE_THRESHOLD_256BYTES: threshold level is 256 bytes
+      \arg        ENET_ACTIVE_THRESHOLD_512BYTES: threshold level is 512 bytes
+      \arg        ENET_ACTIVE_THRESHOLD_768BYTES: threshold level is 768 bytes
+      \arg        ENET_ACTIVE_THRESHOLD_1024BYTES: threshold level is 1024 bytes
+      \arg        ENET_ACTIVE_THRESHOLD_1280BYTES: threshold level is 1280 bytes
+      \arg        ENET_ACTIVE_THRESHOLD_1536BYTES: threshold level is 1536 bytes
+      \arg        ENET_ACTIVE_THRESHOLD_1792BYTES: threshold level is 1792 bytes
+    \param[out] none
+    \retval     none
+*/
+void enet_flowcontrol_threshold_config(uint32_t deactive, uint32_t active)
+{
+    ENET_MAC_FCTH = ((deactive | active) >> 8); 
+}
+
+/*!
+    \brief      enable ENET flow control feature
+    \param[in]  feature: the feature of ENET flow control mode
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_ZERO_QUANTA_PAUSE: the automatic zero-quanta generation function
+      \arg        ENET_TX_FLOWCONTROL: the flow control operation in the MAC
+      \arg        ENET_RX_FLOWCONTROL: decoding function for the received pause frame and process it
+      \arg        ENET_BACK_PRESSURE: back pressure operation in the MAC(only use in half-dulex mode)
+    \param[out] none
+    \retval     none
+*/
+void enet_flowcontrol_feature_enable(uint32_t feature)
+{
+    if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)){
+        ENET_MAC_FCTL &= ~ENET_ZERO_QUANTA_PAUSE;
+    }
+    feature &= ~ENET_ZERO_QUANTA_PAUSE;
+    ENET_MAC_FCTL |= feature;
+}
+
+/*!
+    \brief      disable ENET flow control feature
+    \param[in]  feature: the feature of ENET flow control mode
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_ZERO_QUANTA_PAUSE: the automatic zero-quanta generation function
+      \arg        ENET_TX_FLOWCONTROL: the flow control operation in the MAC
+      \arg        ENET_RX_FLOWCONTROL: decoding function for the received pause frame and process it
+      \arg        ENET_BACK_PRESSURE: back pressure operation in the MAC(only use in half-dulex mode)
+    \param[out] none
+    \retval     none
+*/
+void enet_flowcontrol_feature_disable(uint32_t feature)
+{
+    if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)){
+        ENET_MAC_FCTL |= ENET_ZERO_QUANTA_PAUSE;
+    }
+    feature &= ~ENET_ZERO_QUANTA_PAUSE;
+    ENET_MAC_FCTL &= ~feature;
+}
+
+/*!
+    \brief      get the dma transmit/receive process state
+    \param[in]  direction: choose the direction of dma process which users want to check, 
+                refer to enet_dmadirection_enum, only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: dma transmit process
+      \arg        ENET_DMA_RX: dma receive process
+    \param[out] none
+    \retval     state of dma process, the value range shows below:
+                  ENET_RX_STATE_STOPPED, ENET_RX_STATE_FETCHING, ENET_RX_STATE_WAITING,
+                  ENET_RX_STATE_SUSPENDED, ENET_RX_STATE_CLOSING, ENET_RX_STATE_QUEUING,
+                  ENET_TX_STATE_STOPPED, ENET_TX_STATE_FETCHING, ENET_TX_STATE_WAITING,
+                  ENET_TX_STATE_READING, ENET_TX_STATE_SUSPENDED, ENET_TX_STATE_CLOSING
+*/
+uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction)
+{
+    uint32_t reval;
+    reval = (uint32_t)(ENET_DMA_STAT & (uint32_t)direction);
+    return reval;
+}
+
+/*!
+    \brief      poll the DMA transmission/reception enable by writing any value to the 
+                ENET_DMA_TPEN/ENET_DMA_RPEN register, this will make the DMA to resume transmission/reception
+    \param[in]  direction: choose the direction of DMA process which users want to resume, 
+                refer to enet_dmadirection_enum, only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA transmit process
+      \arg        ENET_DMA_RX: DMA receive process
+    \param[out] none
+    \retval     none
+*/
+void enet_dmaprocess_resume(enet_dmadirection_enum direction)
+{
+    if(ENET_DMA_TX == direction){
+        ENET_DMA_TPEN = 0U;
+    }else{
+        ENET_DMA_RPEN = 0U;
+    }
+}
+
+/*!
+    \brief      check and recover the Rx process 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_rxprocess_check_recovery(void)
+{
+    uint32_t status;
+
+    /* get DAV information of current RxDMA descriptor */  
+    status = dma_current_rxdesc->status;
+    status &= ENET_RDES0_DAV;
+    
+    /* if current descriptor is owned by DMA, but the descriptor address mismatches with 
+    receive descriptor address pointer updated by RxDMA controller */
+    if((ENET_DMA_CRDADDR != ((uint32_t)dma_current_rxdesc)) &&
+       (ENET_RDES0_DAV == status)){
+        dma_current_rxdesc = (enet_descriptors_struct*)ENET_DMA_CRDADDR;
+    }
+}
+
+/*!
+    \brief      flush the ENET transmit FIFO, and wait until the flush operation completes
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus enet_txfifo_flush(void)
+{
+    uint32_t flush_state;
+    uint32_t timeout = 0U;
+    ErrStatus enet_state = ERROR;
+ 
+    /* set the FTF bit for flushing transmit FIFO */
+    ENET_DMA_CTL |= ENET_DMA_CTL_FTF;   
+    /* wait until the flush operation completes */
+    do{
+        flush_state = ENET_DMA_CTL & ENET_DMA_CTL_FTF; 
+        timeout++;
+    }while((RESET != flush_state) && (timeout < ENET_DELAY_TO));
+    /* return ERROR due to timeout */
+    if(RESET == flush_state){
+        enet_state = SUCCESS;
+    }
+    
+    return  enet_state;
+}
+
+/*!
+    \brief      get the transmit/receive address of current descriptor, or current buffer, or descriptor table
+    \param[in]  addr_get: choose the address which users want to get, refer to enet_desc_reg_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_RX_DESC_TABLE: the start address of the receive descriptor table
+      \arg        ENET_RX_CURRENT_DESC: the start descriptor address of the current receive descriptor read by
+                                        the RxDMA controller
+      \arg        ENET_RX_CURRENT_BUFFER: the current receive buffer address being read by the RxDMA controller
+      \arg        ENET_TX_DESC_TABLE: the start address of the transmit descriptor table
+      \arg        ENET_TX_CURRENT_DESC: the start descriptor address of the current transmit descriptor read by
+                                        the TxDMA controller
+      \arg        ENET_TX_CURRENT_BUFFER: the current transmit buffer address being read by the TxDMA controller
+    \param[out] none    
+    \retval     address value
+*/
+uint32_t enet_current_desc_address_get(enet_desc_reg_enum addr_get)
+{
+    uint32_t reval = 0U;
+
+    reval = REG32((ENET) +(uint32_t)addr_get);
+    return reval;
+}
+
+/*!
+    \brief      get the Tx or Rx descriptor information
+    \param[in]  desc: the descriptor pointer which users want to get information
+    \param[in]  info_get: the descriptor information type which is selected,
+                only one parameter can be selected which is shown as below
+      \arg        RXDESC_BUFFER_1_SIZE: receive buffer 1 size
+      \arg        RXDESC_BUFFER_2_SIZE: receive buffer 2 size
+      \arg        RXDESC_FRAME_LENGTH: the byte length of the received frame that was transferred to the buffer
+      \arg        TXDESC_COLLISION_COUNT: the number of collisions occurred before the frame was transmitted
+      \arg        RXDESC_BUFFER_1_ADDR: the buffer1 address of the Rx frame
+      \arg        TXDESC_BUFFER_1_ADDR: the buffer1 address of the Tx frame
+    \param[out] none
+    \retval     descriptor information, if value is 0xFFFFFFFFU, means the false input parameter
+*/
+uint32_t enet_desc_information_get(enet_descriptors_struct *desc, enet_descstate_enum info_get)
+{
+    uint32_t reval = 0xFFFFFFFFU;
+
+    switch(info_get){
+    case RXDESC_BUFFER_1_SIZE:
+        reval = GET_RDES1_RB1S(desc->control_buffer_size);
+        break;
+    case RXDESC_BUFFER_2_SIZE:
+        reval = GET_RDES1_RB2S(desc->control_buffer_size);
+        break; 
+    case RXDESC_FRAME_LENGTH:    
+        reval = GET_RDES0_FRML(desc->status);
+        reval = reval - 4U;
+        
+        /* if is a type frame, and CRC is not included in forwarding frame */ 
+        if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (desc->status & ENET_RDES0_FRMT))){
+            reval = reval + 4U;
+        }    
+        break;
+    case RXDESC_BUFFER_1_ADDR:    
+        reval = desc->buffer1_addr;    
+        break;
+    case TXDESC_BUFFER_1_ADDR:    
+        reval = desc->buffer1_addr;  
+        break;
+    case TXDESC_COLLISION_COUNT:    
+        reval = GET_TDES0_COCNT(desc->status);
+        break;    
+    default:
+        break;
+    }
+    return reval;
+}
+
+/*!
+    \brief      get the number of missed frames during receiving
+    \param[in]  none
+    \param[out] rxfifo_drop: pointer to the number of frames dropped by RxFIFO
+    \param[out] rxdma_drop: pointer to the number of frames missed by the RxDMA controller
+    \retval     none
+*/
+void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop)
+{
+    uint32_t temp_counter = 0U;
+  
+    temp_counter = ENET_DMA_MFBOCNT;
+    *rxfifo_drop = GET_DMA_MFBOCNT_MSFA(temp_counter);
+    *rxdma_drop = GET_DMA_MFBOCNT_MSFC(temp_counter);
+}
+
+/*!
+    \brief      get the bit flag of ENET DMA descriptor
+    \param[in]  desc: the descriptor pointer which users want to get flag
+    \param[in]  desc_flag: the bit flag of ENET DMA descriptor,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_TDES0_DB: deferred 
+      \arg        ENET_TDES0_UFE: underflow error
+      \arg        ENET_TDES0_EXD: excessive deferral
+      \arg        ENET_TDES0_VFRM: VLAN frame
+      \arg        ENET_TDES0_ECO: excessive collision
+      \arg        ENET_TDES0_LCO: late collision
+      \arg        ENET_TDES0_NCA: no carrier
+      \arg        ENET_TDES0_LCA: loss of carrier
+      \arg        ENET_TDES0_IPPE: IP payload error
+      \arg        ENET_TDES0_FRMF: frame flushed
+      \arg        ENET_TDES0_JT: jabber timeout
+      \arg        ENET_TDES0_ES: error summary
+      \arg        ENET_TDES0_IPHE: IP header error
+      \arg        ENET_TDES0_TTMSS: transmit timestamp status 
+      \arg        ENET_TDES0_TCHM: the second address chained mode
+      \arg        ENET_TDES0_TERM: transmit end of ring mode
+      \arg        ENET_TDES0_TTSEN: transmit timestamp function enable
+      \arg        ENET_TDES0_DPAD: disable adding pad      
+      \arg        ENET_TDES0_DCRC: disable CRC
+      \arg        ENET_TDES0_FSG: first segment
+      \arg        ENET_TDES0_LSG: last segment
+      \arg        ENET_TDES0_INTC: interrupt on completion
+      \arg        ENET_TDES0_DAV: DAV bit
+      
+      \arg        ENET_RDES0_PCERR: payload checksum error 
+      \arg        ENET_RDES0_EXSV: extended status valid
+      \arg        ENET_RDES0_CERR: CRC error
+      \arg        ENET_RDES0_DBERR: dribble bit error
+      \arg        ENET_RDES0_RERR: receive error
+      \arg        ENET_RDES0_RWDT: receive watchdog timeout
+      \arg        ENET_RDES0_FRMT: frame type
+      \arg        ENET_RDES0_LCO: late collision
+      \arg        ENET_RDES0_IPHERR: IP frame header error
+      \arg        ENET_RDES0_TSV: timestamp valid
+      \arg        ENET_RDES0_LDES: last descriptor
+      \arg        ENET_RDES0_FDES: first descriptor
+      \arg        ENET_RDES0_VTAG: VLAN tag
+      \arg        ENET_RDES0_OERR: overflow error 
+      \arg        ENET_RDES0_LERR: length error
+      \arg        ENET_RDES0_SAFF: SA filter fail
+      \arg        ENET_RDES0_DERR: descriptor error
+      \arg        ENET_RDES0_ERRS: error summary      
+      \arg        ENET_RDES0_DAFF: destination address filter fail
+      \arg        ENET_RDES0_DAV: descriptor available
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag)
+{
+    FlagStatus enet_flag = RESET;
+  
+    if ((uint32_t)RESET != (desc->status & desc_flag)){
+        enet_flag = SET;
+    }
+
+    return enet_flag;
+}
+
+/*!
+    \brief      set the bit flag of ENET DMA descriptor
+    \param[in]  desc: the descriptor pointer which users want to set flag
+    \param[in]  desc_flag: the bit flag of ENET DMA descriptor,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_TDES0_VFRM: VLAN frame
+      \arg        ENET_TDES0_FRMF: frame flushed
+      \arg        ENET_TDES0_TCHM: the second address chained mode
+      \arg        ENET_TDES0_TERM: transmit end of ring mode
+      \arg        ENET_TDES0_TTSEN: transmit timestamp function enable
+      \arg        ENET_TDES0_DPAD: disable adding pad      
+      \arg        ENET_TDES0_DCRC: disable CRC
+      \arg        ENET_TDES0_FSG: first segment
+      \arg        ENET_TDES0_LSG: last segment
+      \arg        ENET_TDES0_INTC: interrupt on completion
+      \arg        ENET_TDES0_DAV: DAV bit
+      \arg        ENET_RDES0_DAV: descriptor available 
+    \param[out] none
+    \retval     none
+*/
+void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag)
+{
+    desc->status |= desc_flag;
+}
+
+/*!
+    \brief      clear the bit flag of ENET DMA descriptor
+    \param[in]  desc: the descriptor pointer which users want to clear flag
+    \param[in]  desc_flag: the bit flag of ENET DMA descriptor,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_TDES0_VFRM: VLAN frame
+      \arg        ENET_TDES0_FRMF: frame flushed
+      \arg        ENET_TDES0_TCHM: the second address chained mode
+      \arg        ENET_TDES0_TERM: transmit end of ring mode
+      \arg        ENET_TDES0_TTSEN: transmit timestamp function enable
+      \arg        ENET_TDES0_DPAD: disable adding pad      
+      \arg        ENET_TDES0_DCRC: disable CRC
+      \arg        ENET_TDES0_FSG: first segment
+      \arg        ENET_TDES0_LSG: last segment
+      \arg        ENET_TDES0_INTC: interrupt on completion
+      \arg        ENET_TDES0_DAV: DAV bit
+      \arg        ENET_RDES0_DAV: descriptor available 
+    \param[out] none
+    \retval     none
+*/
+void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag)
+{
+    desc->status &= ~desc_flag;
+}
+
+/*!
+    \brief      when receiving completed, set RS bit in ENET_DMA_STAT register will immediately set 
+    \param[in]  desc: the descriptor pointer which users want to configure
+    \param[out] none
+    \retval     none
+*/
+void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct *desc)
+{
+    desc->control_buffer_size &= ~ENET_RDES1_DINTC;
+}
+
+/*!
+    \brief      when receiving completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time 
+    \param[in]  desc: the descriptor pointer which users want to configure
+    \param[in]  delay_time: delay a time of 256*delay_time HCLK, this value must be between 0 and 0xFF
+    \param[out] none
+    \retval     none
+*/
+void enet_rx_desc_delay_receive_complete_interrupt(enet_descriptors_struct *desc, uint32_t delay_time)
+{
+    desc->control_buffer_size |= ENET_RDES1_DINTC;
+    ENET_DMA_RSWDC = DMA_RSWDC_WDCFRS(delay_time);
+}
+
+/*!
+    \brief      drop current receive frame
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_rxframe_drop(void)
+{
+    /* enable reception, descriptor is owned by DMA */
+    dma_current_rxdesc->status = ENET_RDES0_DAV;  
+    
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){     
+        if(NULL != dma_current_ptp_rxdesc){
+            dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->buffer2_next_desc_addr);
+            /* if it is the last ptp descriptor */
+            if(0U != dma_current_ptp_rxdesc->status){
+                /* pointer back to the first ptp descriptor address in the desc_ptptab list address */
+                dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status);
+            }else{
+                /* ponter to the next ptp descriptor */
+                dma_current_ptp_rxdesc++;
+            }
+        }else{
+            dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr);
+        }
+            
+    }else{
+        /* ring mode */    
+        if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR);
+            if(NULL != dma_current_ptp_rxdesc){
+                dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status);
+            }
+        }else{
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL));
+            if(NULL != dma_current_ptp_rxdesc){
+                dma_current_ptp_rxdesc++;
+            }
+        }
+    }
+}
+
+/*!
+    \brief      enable DMA feature
+    \param[in]  feature: the feature of DMA mode,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_FLUSH_RXFRAME: RxDMA flushes frames function
+      \arg        ENET_SECONDFRAME_OPT: TxDMA controller operate on second frame function
+    \param[out] none
+    \retval     none
+*/
+void enet_dma_feature_enable(uint32_t feature)
+{
+    ENET_DMA_CTL |= feature;
+}
+
+/*!
+    \brief      disable DMA feature
+    \param[in]  feature: the feature of DMA mode,
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_FLUSH_RXFRAME: RxDMA flushes frames function
+      \arg        ENET_SECONDFRAME_OPT: TxDMA controller operate on second frame function
+    \param[out] none
+    \retval     none
+*/
+void enet_dma_feature_disable(uint32_t feature)
+{
+    ENET_DMA_CTL &= ~feature;
+}
+
+#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
+/*!
+    \brief      get the bit of extended status flag in ENET DMA descriptor
+    \param[in]  desc: the descriptor pointer which users want to get the extended status flag
+    \param[in]  desc_status: the extended status want to get,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_RDES4_IPPLDT: IP frame payload type
+      \arg        ENET_RDES4_IPHERR: IP frame header error
+      \arg        ENET_RDES4_IPPLDERR: IP frame payload error
+      \arg        ENET_RDES4_IPCKSB: IP frame checksum bypassed
+      \arg        ENET_RDES4_IPF4: IP frame in version 4
+      \arg        ENET_RDES4_IPF6: IP frame in version 6
+      \arg        ENET_RDES4_PTPMT: PTP message type
+      \arg        ENET_RDES4_PTPOEF: PTP on ethernet frame
+      \arg        ENET_RDES4_PTPVF: PTP version format
+    \param[out] none
+    \retval     value of extended status
+*/
+uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status)
+{
+    uint32_t reval = 0xFFFFFFFFU;
+  
+    switch (desc_status){
+    case ENET_RDES4_IPPLDT:
+        reval = GET_RDES4_IPPLDT(desc->extended_status);
+        break;
+    case ENET_RDES4_PTPMT:
+        reval = GET_RDES4_PTPMT(desc->extended_status);
+        break;
+    default:
+        if ((uint32_t)RESET != (desc->extended_status & desc_status)){
+            reval = 1U;
+        }else{
+            reval = 0U;
+        } 
+    }
+    
+    return reval;
+}
+
+/*!
+    \brief      configure descriptor to work in enhanced mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_desc_select_enhanced_mode(void)
+{
+    ENET_DMA_BCTL |= ENET_DMA_BCTL_DFM;
+}
+
+/*!
+    \brief      initialize the DMA Tx/Rx descriptors's parameters in enhanced chain mode with ptp function
+    \param[in]  direction: the descriptors which users want to init, refer to enet_dmadirection_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA Tx descriptors
+      \arg        ENET_DMA_RX: DMA Rx descriptors
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_enhanced_descriptors_chain_init(enet_dmadirection_enum direction)
+{
+    uint32_t num = 0U, count = 0U, maxsize = 0U;
+    uint32_t desc_status = 0U, desc_bufsize = 0U;
+    enet_descriptors_struct *desc, *desc_tab;
+    uint8_t *buf;
+  
+    /* if want to initialize DMA Tx descriptors */
+    if (ENET_DMA_TX == direction){
+        /* save a copy of the DMA Tx descriptors */
+        desc_tab = txdesc_tab;
+        buf = &tx_buff[0][0];
+        count = ENET_TXBUF_NUM;
+        maxsize = ENET_TXBUF_SIZE;        
+      
+        /* select chain mode, and enable transmit timestamp function */
+        desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN;
+      
+        /* configure DMA Tx descriptor table address register */
+        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
+        dma_current_txdesc = desc_tab;
+    }else{
+        /* if want to initialize DMA Rx descriptors */
+        /* save a copy of the DMA Rx descriptors */
+        desc_tab = rxdesc_tab;
+        buf = &rx_buff[0][0];
+        count = ENET_RXBUF_NUM;
+        maxsize = ENET_RXBUF_SIZE;       
+  
+        /* enable receiving */
+        desc_status = ENET_RDES0_DAV;
+        /* select receive chained mode and set buffer1 size */
+        desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE;
+      
+        /* configure DMA Rx descriptor table address register */
+        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
+        dma_current_rxdesc = desc_tab;   
+    }
+      
+    /* configuration each descriptor */   
+    for(num = 0U; num < count; num++){
+        /* get the pointer to the next descriptor of the descriptor table */
+        desc = desc_tab + num;
+
+        /* configure descriptors */
+        desc->status = desc_status;         
+        desc->control_buffer_size = desc_bufsize;
+        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);
+    
+        /* if is not the last descriptor */
+        if(num < (count - 1U)){
+            /* configure the next descriptor address */
+            desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U);
+        }else{
+            /* when it is the last descriptor, the next descriptor address 
+            equals to first descriptor address in descriptor table */ 
+            desc->buffer2_next_desc_addr = (uint32_t)desc_tab;  
+        }
+    } 
+}
+
+/*!
+    \brief      initialize the DMA Tx/Rx descriptors's parameters in enhanced ring mode with ptp function
+    \param[in]  direction: the descriptors which users want to init, refer to enet_dmadirection_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA Tx descriptors
+      \arg        ENET_DMA_RX: DMA Rx descriptors
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_enhanced_descriptors_ring_init(enet_dmadirection_enum direction)
+{
+    uint32_t num = 0U, count = 0U, maxsize = 0U;
+    uint32_t desc_status = 0U, desc_bufsize = 0U;
+    enet_descriptors_struct *desc;
+    enet_descriptors_struct *desc_tab;
+    uint8_t *buf; 
+  
+    /* configure descriptor skip length */
+    ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL;
+    ENET_DMA_BCTL |= DMA_BCTL_DPSL(0);
+  
+    /* if want to initialize DMA Tx descriptors */
+    if (ENET_DMA_TX == direction){
+        /* save a copy of the DMA Tx descriptors */
+        desc_tab = txdesc_tab;
+        buf = &tx_buff[0][0];
+        count = ENET_TXBUF_NUM;
+        maxsize = ENET_TXBUF_SIZE;      
+
+        /* select ring mode, and enable transmit timestamp function */
+        desc_status = ENET_TDES0_TTSEN;
+      
+        /* configure DMA Tx descriptor table address register */
+        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
+        dma_current_txdesc = desc_tab;
+    }else{
+        /* if want to initialize DMA Rx descriptors */
+        /* save a copy of the DMA Rx descriptors */
+        desc_tab = rxdesc_tab;
+        buf = &rx_buff[0][0];
+        count = ENET_RXBUF_NUM;
+        maxsize = ENET_RXBUF_SIZE;      
+      
+        /* enable receiving */
+        desc_status = ENET_RDES0_DAV;
+        /* set buffer1 size */
+        desc_bufsize = ENET_RXBUF_SIZE;
+      
+         /* configure DMA Rx descriptor table address register */
+        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
+        dma_current_rxdesc = desc_tab; 
+    }
+    
+    /* configure each descriptor */   
+    for(num=0U; num < count; num++){
+        /* get the pointer to the next descriptor of the descriptor table */
+        desc = desc_tab + num;
+
+        /* configure descriptors */
+        desc->status = desc_status; 
+        desc->control_buffer_size = desc_bufsize;      
+        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);    
+    
+        /* when it is the last descriptor */
+        if(num == (count - 1U)){
+            if (ENET_DMA_TX == direction){
+                /* configure transmit end of ring mode */  
+                desc->status |= ENET_TDES0_TERM;
+            }else{
+                /* configure receive end of ring mode */
+                desc->control_buffer_size |= ENET_RDES1_RERM;
+            }
+        }
+    } 
+}
+
+/*!
+    \brief      receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode 
+    \param[in]  bufsize: the size of buffer which is the parameter in function
+    \param[out] buffer: pointer to the application buffer
+                note -- if the input is NULL, user should copy data in application by himself
+    \param[out] timestamp: pointer to the table which stores the timestamp high and low
+                note -- if the input is NULL, timestamp is ignored
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_ptpframe_receive_enhanced_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[])
+{
+    uint32_t offset = 0U, size = 0U;
+    uint32_t timeout = 0U;
+    uint32_t rdes0_tsv_flag;
+    
+    /* the descriptor is busy due to own by the DMA */
+    if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){
+        return ERROR; 
+    }
+    
+    /* if buffer pointer is null, indicates that users has copied data in application */
+    if(NULL != buffer){
+        /* if no error occurs, and the frame uses only one descriptor */    
+        if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && 
+           ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) &&  
+           ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))){      
+            /* get the frame length except CRC */
+            size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U;
+
+            /* if is a type frame, and CRC is not included in forwarding frame */  
+            if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){
+                size = size + 4U;
+            }
+            
+            /* to avoid situation that the frame size exceeds the buffer length */
+            if(size > bufsize){
+                return ERROR;
+            }
+
+            /* copy data from Rx buffer to application buffer */
+            for(offset = 0; offset < size; offset++){
+                (*(buffer + offset)) = (*(__IO uint8_t *)((dma_current_rxdesc->buffer1_addr) + offset));
+            }
+        }else{
+            return ERROR;
+        }
+    }  
+    
+    /* if timestamp pointer is null, indicates that users don't care timestamp in application */
+    if(NULL != timestamp){
+        /* wait for ENET_RDES0_TSV flag to be set, the timestamp value is taken and
+        write to the RDES6 and RDES7 */
+        do{   
+            rdes0_tsv_flag = (dma_current_rxdesc->status & ENET_RDES0_TSV);
+            timeout++;
+        }while ((RESET == rdes0_tsv_flag) && (timeout < ENET_DELAY_TO));
+        
+        /* return ERROR due to timeout */
+        if(ENET_DELAY_TO == timeout){
+            return ERROR;
+        }
+        
+        /* clear the ENET_RDES0_TSV flag */
+        dma_current_rxdesc->status &= ~ENET_RDES0_TSV;
+        /* get the timestamp value of the received frame */
+        timestamp[0] = dma_current_rxdesc->timestamp_low;
+        timestamp[1] = dma_current_rxdesc->timestamp_high;
+    }
+
+    /* enable reception, descriptor is owned by DMA */
+    dma_current_rxdesc->status = ENET_RDES0_DAV;
+    
+    /* check Rx buffer unavailable flag status */
+    if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){
+        /* Clear RBU flag */
+        ENET_DMA_STAT = ENET_DMA_STAT_RBU;
+        /* resume DMA reception by writing to the RPEN register*/
+        ENET_DMA_RPEN = 0;
+    }
+  
+    /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */      
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){      
+        dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr);    
+    }else{   
+        /* ring mode */    
+        if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR);      
+        }else{ 
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_rxdesc = (enet_descriptors_struct*) ((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL));      
+        }
+    }
+  
+    return SUCCESS;
+}
+
+/*!
+    \brief      send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode 
+    \param[in]  buffer: pointer on the application buffer
+                note -- if the input is NULL, user should copy data in application by himself
+    \param[in]  length: the length of frame data to be transmitted
+    \param[out] timestamp: pointer to the table which stores the timestamp high and low
+                note -- if the input is NULL, timestamp is ignored
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[])
+{
+    uint32_t offset = 0;
+    uint32_t dma_tbu_flag, dma_tu_flag;
+    uint32_t tdes0_ttmss_flag;
+    uint32_t timeout = 0; 
+    
+    /* the descriptor is busy due to own by the DMA */
+    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){
+        return ERROR;
+    }
+    
+    /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */
+    if(length > ENET_MAX_FRAME_SIZE){
+        return ERROR;
+    }  
+
+    /* if buffer pointer is null, indicates that users has handled data in application */
+    if(NULL != buffer){
+        /* copy frame data from application buffer to Tx buffer */
+        for(offset = 0; offset < length; offset++){
+            (*(__IO uint8_t *)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset));
+        }
+    }
+    /* set the frame length */
+    dma_current_txdesc->control_buffer_size = length;
+    /* set the segment of frame, frame is transmitted in one descriptor */   
+    dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG;
+    /* enable the DMA transmission */
+    dma_current_txdesc->status |= ENET_TDES0_DAV;
+
+    /* check Tx buffer unavailable flag status */
+    dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); 
+    dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU);
+    
+    if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){
+        /* Clear TBU and TU flag */
+        ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag);
+        /* resume DMA transmission by writing to the TPEN register*/
+        ENET_DMA_TPEN = 0;
+    }
+    
+    /* if timestamp pointer is null, indicates that users don't care timestamp in application */
+    if(NULL != timestamp){
+        /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */
+        do{
+            tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS);
+            timeout++;
+        }while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO));
+        
+        /* return ERROR due to timeout */
+        if(ENET_DELAY_TO == timeout){
+            return ERROR;
+        }
+     
+        /* clear the ENET_TDES0_TTMSS flag */
+        dma_current_txdesc->status &= ~ENET_TDES0_TTMSS;
+        /* get the timestamp value of the transmit frame */
+        timestamp[0] = dma_current_txdesc->timestamp_low;
+        timestamp[1] = dma_current_txdesc->timestamp_high;
+    }
+
+    /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/  
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){     
+        dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr);    
+    }else{
+        /* ring mode */        
+        if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR);      
+        }else{ 
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_txdesc = (enet_descriptors_struct*) ((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL));
+        }
+    }
+
+    return SUCCESS;
+}
+
+#else
+
+/*!
+    \brief      configure descriptor to work in normal mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_desc_select_normal_mode(void)
+{
+    ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DFM;
+}
+
+/*!
+    \brief      initialize the DMA Tx/Rx descriptors's parameters in normal chain mode with PTP function
+    \param[in]  direction: the descriptors which users want to init, refer to enet_dmadirection_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA Tx descriptors
+      \arg        ENET_DMA_RX: DMA Rx descriptors
+    \param[in]  desc_ptptab: pointer to the first descriptor address of PTP Rx descriptor table
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_normal_descriptors_chain_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab)
+{
+    uint32_t num = 0U, count = 0U, maxsize = 0U;
+    uint32_t desc_status = 0U, desc_bufsize = 0U;
+    enet_descriptors_struct *desc, *desc_tab;
+    uint8_t *buf;
+  
+    /* if want to initialize DMA Tx descriptors */
+    if (ENET_DMA_TX == direction){
+        /* save a copy of the DMA Tx descriptors */
+        desc_tab = txdesc_tab;
+        buf = &tx_buff[0][0];
+        count = ENET_TXBUF_NUM;
+        maxsize = ENET_TXBUF_SIZE;        
+      
+        /* select chain mode, and enable transmit timestamp function */
+        desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN;
+      
+        /* configure DMA Tx descriptor table address register */
+        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
+        dma_current_txdesc = desc_tab;
+        dma_current_ptp_txdesc = desc_ptptab;
+    }else{
+        /* if want to initialize DMA Rx descriptors */
+        /* save a copy of the DMA Rx descriptors */
+        desc_tab = rxdesc_tab;
+        buf = &rx_buff[0][0];
+        count = ENET_RXBUF_NUM;
+        maxsize = ENET_RXBUF_SIZE;       
+  
+        /* enable receiving */
+        desc_status = ENET_RDES0_DAV;
+        /* select receive chained mode and set buffer1 size */
+        desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE;
+      
+        /* configure DMA Rx descriptor table address register */
+        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
+        dma_current_rxdesc = desc_tab;
+        dma_current_ptp_rxdesc = desc_ptptab;      
+    }
+      
+    /* configure each descriptor */   
+    for(num = 0U; num < count; num++){
+        /* get the pointer to the next descriptor of the descriptor table */
+        desc = desc_tab + num;
+
+        /* configure descriptors */
+        desc->status = desc_status;         
+        desc->control_buffer_size = desc_bufsize;
+        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);
+    
+        /* if is not the last descriptor */
+        if(num < (count - 1U)){
+            /* configure the next descriptor address */
+            desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U);
+        }else{
+            /* when it is the last descriptor, the next descriptor address 
+            equals to first descriptor address in descriptor table */ 
+            desc->buffer2_next_desc_addr = (uint32_t)desc_tab;  
+        }
+        /* set desc_ptptab equal to desc_tab */
+        (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr;
+        (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr;
+    } 
+    /* when it is the last ptp descriptor, preserve the first descriptor 
+    address of desc_ptptab in ptp descriptor status */
+    (&desc_ptptab[num-1U])->status = (uint32_t)desc_ptptab;
+}
+
+/*!
+    \brief      initialize the DMA Tx/Rx descriptors's parameters in normal ring mode with PTP function
+    \param[in]  direction: the descriptors which users want to init, refer to enet_dmadirection_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_DMA_TX: DMA Tx descriptors
+      \arg        ENET_DMA_RX: DMA Rx descriptors
+    \param[in]  desc_ptptab: pointer to the first descriptor address of PTP Rx descriptor table
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab)
+{
+    uint32_t num = 0U, count = 0U, maxsize = 0U;
+    uint32_t desc_status = 0U, desc_bufsize = 0U;
+    enet_descriptors_struct *desc, *desc_tab;
+    uint8_t *buf;
+
+    /* configure descriptor skip length */
+    ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL;
+    ENET_DMA_BCTL |= DMA_BCTL_DPSL(0);
+    
+    /* if want to initialize DMA Tx descriptors */
+    if (ENET_DMA_TX == direction){
+        /* save a copy of the DMA Tx descriptors */
+        desc_tab = txdesc_tab;
+        buf = &tx_buff[0][0];
+        count = ENET_TXBUF_NUM;
+        maxsize = ENET_TXBUF_SIZE;        
+      
+        /* select ring mode, and enable transmit timestamp function */
+        desc_status = ENET_TDES0_TTSEN;
+      
+        /* configure DMA Tx descriptor table address register */
+        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
+        dma_current_txdesc = desc_tab;
+        dma_current_ptp_txdesc = desc_ptptab;
+    }else{
+        /* if want to initialize DMA Rx descriptors */
+        /* save a copy of the DMA Rx descriptors */
+        desc_tab = rxdesc_tab;
+        buf = &rx_buff[0][0];
+        count = ENET_RXBUF_NUM;
+        maxsize = ENET_RXBUF_SIZE;       
+  
+        /* enable receiving */
+        desc_status = ENET_RDES0_DAV;
+        /* select receive ring mode and set buffer1 size */
+        desc_bufsize = (uint32_t)ENET_RXBUF_SIZE;
+      
+        /* configure DMA Rx descriptor table address register */
+        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
+        dma_current_rxdesc = desc_tab;
+        dma_current_ptp_rxdesc = desc_ptptab;      
+    }
+      
+    /* configure each descriptor */   
+    for(num = 0U; num < count; num++){
+        /* get the pointer to the next descriptor of the descriptor table */
+        desc = desc_tab + num;
+
+        /* configure descriptors */
+        desc->status = desc_status;         
+        desc->control_buffer_size = desc_bufsize;
+        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);
+    
+        /* when it is the last descriptor */
+        if(num == (count - 1U)){
+            if (ENET_DMA_TX == direction){
+                /* configure transmit end of ring mode */  
+                desc->status |= ENET_TDES0_TERM;
+            }else{
+                /* configure receive end of ring mode */
+                desc->control_buffer_size |= ENET_RDES1_RERM;
+            }
+        }
+        /* set desc_ptptab equal to desc_tab */
+        (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr;
+        (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr;
+    } 
+    /* when it is the last ptp descriptor, preserve the first descriptor 
+    address of desc_ptptab in ptp descriptor status */
+    (&desc_ptptab[num-1U])->status = (uint32_t)desc_ptptab;
+}
+
+/*!
+    \brief      receive a packet data with timestamp values to application buffer, when the DMA is in normal mode   
+    \param[in]  bufsize: the size of buffer which is the parameter in function
+    \param[out] timestamp: pointer to the table which stores the timestamp high and low
+    \param[out] buffer: pointer to the application buffer
+                note -- if the input is NULL, user should copy data in application by himself
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[])
+{
+    uint32_t offset = 0U, size = 0U;
+    
+    /* the descriptor is busy due to own by the DMA */
+    if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){
+        return ERROR;
+    }
+    
+    /* if buffer pointer is null, indicates that users has copied data in application */
+    if(NULL != buffer){
+        /* if no error occurs, and the frame uses only one descriptor */
+        if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) &&
+           ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) &&
+           ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))){
+            
+            /* get the frame length except CRC */
+            size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U;
+            /* if is a type frame, and CRC is not included in forwarding frame */
+            if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){
+                size = size + 4U;
+            }
+            
+            /* to avoid situation that the frame size exceeds the buffer length */
+            if(size > bufsize){
+                return ERROR;
+            }
+
+            /* copy data from Rx buffer to application buffer */
+            for(offset = 0U; offset < size; offset++){
+                (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_rxdesc->buffer1_addr) + offset));
+            }
+            
+        }else{
+            return ERROR;
+        }
+    }
+    /* copy timestamp value from Rx descriptor to application array */
+    timestamp[0] = dma_current_rxdesc->buffer1_addr;
+    timestamp[1] = dma_current_rxdesc->buffer2_next_desc_addr;
+
+    dma_current_rxdesc->buffer1_addr = dma_current_ptp_rxdesc ->buffer1_addr ;
+    dma_current_rxdesc->buffer2_next_desc_addr = dma_current_ptp_rxdesc ->buffer2_next_desc_addr;
+    
+    /* enable reception, descriptor is owned by DMA */
+    dma_current_rxdesc->status = ENET_RDES0_DAV;
+    
+    /* check Rx buffer unavailable flag status */
+    if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){
+        /* clear RBU flag */
+        ENET_DMA_STAT = ENET_DMA_STAT_RBU;
+        /* resume DMA reception by writing to the RPEN register*/
+        ENET_DMA_RPEN = 0U;
+    }
+    
+
+    /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */      
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){
+        dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->buffer2_next_desc_addr);
+        /* if it is the last ptp descriptor */
+        if(0U != dma_current_ptp_rxdesc->status){
+            /* pointer back to the first ptp descriptor address in the desc_ptptab list address */
+            dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status);
+        }else{
+            /* ponter to the next ptp descriptor */
+            dma_current_ptp_rxdesc++;
+        }
+    }else{
+        /* ring mode */   
+        if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR);
+            /* RDES2 and RDES3 will not be covered by buffer address, so do not need to preserve a new table,
+            use the same table with RxDMA descriptor */
+            dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status);          
+        }else{
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL));      
+            dma_current_ptp_rxdesc ++;
+        }
+    }
+
+    return SUCCESS;
+}
+
+/*!
+    \brief      send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode 
+    \param[in]  buffer: pointer on the application buffer
+                note -- if the input is NULL, user should copy data in application by himself
+    \param[in]  length: the length of frame data to be transmitted
+    \param[out] timestamp: pointer to the table which stores the timestamp high and low
+                note -- if the input is NULL, timestamp is ignored
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[])
+{
+    uint32_t offset = 0U, timeout = 0U;
+    uint32_t dma_tbu_flag, dma_tu_flag, tdes0_ttmss_flag; 
+    
+    /* the descriptor is busy due to own by the DMA */
+    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){
+        return ERROR;
+    }
+
+    /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */
+    if(length > ENET_MAX_FRAME_SIZE){
+        return ERROR;
+    }
+    
+    /* if buffer pointer is null, indicates that users has handled data in application */
+    if(NULL != buffer){
+        /* copy frame data from application buffer to Tx buffer */
+        for(offset = 0U; offset < length; offset++){
+            (*(__IO uint8_t *) (uint32_t)((dma_current_ptp_txdesc->buffer1_addr) + offset)) = (*(buffer + offset));
+        }
+    }
+    /* set the frame length */
+    dma_current_txdesc->control_buffer_size = (length & (uint32_t)0x1FFF);
+    /* set the segment of frame, frame is transmitted in one descriptor */
+    dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG;
+    /* enable the DMA transmission */
+    dma_current_txdesc->status |= ENET_TDES0_DAV;
+    
+    /* check Tx buffer unavailable flag status */
+    dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); 
+    dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU);
+    
+    if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){
+        /* clear TBU and TU flag */
+        ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag);
+        /* resume DMA transmission by writing to the TPEN register*/
+        ENET_DMA_TPEN = 0U;
+    }
+    
+    /* if timestamp pointer is null, indicates that users don't care timestamp in application */
+    if(NULL != timestamp){
+        /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */
+        do{   
+            tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS);
+            timeout++;
+        }while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO));
+       
+        /* return ERROR due to timeout */
+        if(ENET_DELAY_TO == timeout){
+            return ERROR;
+        } 
+    
+        /* clear the ENET_TDES0_TTMSS flag */
+        dma_current_txdesc->status &= ~ENET_TDES0_TTMSS;
+        /* get the timestamp value of the transmit frame */
+        timestamp[0] = dma_current_txdesc->buffer1_addr;
+        timestamp[1] = dma_current_txdesc->buffer2_next_desc_addr;
+    }
+    dma_current_txdesc->buffer1_addr = dma_current_ptp_txdesc ->buffer1_addr ;
+    dma_current_txdesc->buffer2_next_desc_addr = dma_current_ptp_txdesc ->buffer2_next_desc_addr;
+
+    /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table */   
+    /* chained mode */
+    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){   
+        dma_current_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->buffer2_next_desc_addr);
+        /* if it is the last ptp descriptor */
+        if(0U != dma_current_ptp_txdesc->status){ 
+            /* pointer back to the first ptp descriptor address in the desc_ptptab list address */
+            dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status);
+        }else{
+            /* ponter to the next ptp descriptor */
+            dma_current_ptp_txdesc++;
+        }
+    }else{
+        /* ring mode */   
+        if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){
+            /* if is the last descriptor in table, the next descriptor is the table header */
+            dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); 
+            /* TDES2 and TDES3 will not be covered by buffer address, so do not need to preserve a new table,
+            use the same table with TxDMA descriptor */
+            dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status);
+        }else{
+            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
+            dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL));      
+            dma_current_ptp_txdesc ++;      
+        }
+    }
+    return SUCCESS;
+}
+
+#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */
+
+/*!
+    \brief      wakeup frame filter register pointer reset 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_wum_filter_register_pointer_reset(void)
+{
+    ENET_MAC_WUM |= ENET_MAC_WUM_WUFFRPR;
+}
+
+/*!
+    \brief      set the remote wakeup frame registers 
+    \param[in]  pdata: pointer to buffer data which is written to remote wakeup frame registers (8 words total)
+    \param[out] none
+    \retval     none
+*/
+void enet_wum_filter_config(uint32_t pdata[])
+{
+    uint32_t num = 0U;
+  
+    /* configure ENET_MAC_RWFF register */
+    for(num = 0U; num < ETH_WAKEUP_REGISTER_LENGTH; num++){
+        ENET_MAC_RWFF = pdata[num];
+    }
+}
+
+/*!
+    \brief      enable wakeup management features  
+    \param[in]  feature: one or more parameters can be selected which are shown as below
+      \arg        ENET_WUM_POWER_DOWN: power down mode
+      \arg        ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception
+      \arg        ENET_WUM_WAKE_UP_FRAME: enable a wakeup event due to wakeup frame reception
+      \arg        ENET_WUM_GLOBAL_UNICAST: any received unicast frame passed filter is considered to be a wakeup frame
+    \param[out] none
+    \retval     none
+*/
+void enet_wum_feature_enable(uint32_t feature)
+{
+    ENET_MAC_WUM |= feature;
+}
+
+/*!
+    \brief      disable wakeup management features  
+    \param[in]  feature: one or more parameters can be selected which are shown as below
+      \arg        ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception
+      \arg        ENET_WUM_WAKE_UP_FRAME: enable a wakeup event due to wakeup frame reception
+      \arg        ENET_WUM_GLOBAL_UNICAST: any received unicast frame passed filter is considered to be a wakeup frame
+    \param[out] none
+    \retval     none
+*/
+void enet_wum_feature_disable(uint32_t feature)
+{
+    ENET_MAC_WUM &= (~feature);
+}
+
+/*!
+    \brief      reset the MAC statistics counters  
+    \param[in]  none 
+    \param[out] none
+    \retval     none
+*/
+void enet_msc_counters_reset(void)
+{
+    /* reset all counters */
+    ENET_MSC_CTL |= ENET_MSC_CTL_CTR;
+}
+
+/*!
+    \brief      enable the MAC statistics counter features
+    \param[in]  feature: one or more parameters can be selected which are shown as below
+      \arg        ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover
+      \arg        ENET_MSC_RESET_ON_READ: reset on read
+      \arg        ENET_MSC_COUNTERS_FREEZE: MSC counter freeze
+    \param[out] none
+    \retval     none
+*/
+void enet_msc_feature_enable(uint32_t feature)
+{
+    ENET_MSC_CTL |= feature;
+}
+
+/*!
+    \brief      disable the MAC statistics counter features
+    \param[in]  feature: one or more parameters can be selected which are shown as below 
+      \arg        ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover
+      \arg        ENET_MSC_RESET_ON_READ: reset on read
+      \arg        ENET_MSC_COUNTERS_FREEZE: MSC counter freeze
+    \param[out] none
+    \retval     none
+*/
+void enet_msc_feature_disable(uint32_t feature)
+{
+     ENET_MSC_CTL &= (~feature);
+}
+
+/*!
+    \brief      configure MAC statistics counters preset mode   
+    \param[in]  mode: MSC counters preset mode, refer to enet_msc_preset_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MSC_PRESET_NONE: do not preset MSC counter
+      \arg        ENET_MSC_PRESET_HALF: preset all MSC counters to almost-half(0x7FFF FFF0) value
+      \arg        ENET_MSC_PRESET_FULL: preset all MSC counters to almost-full(0xFFFF FFF0) value
+    \param[out] none
+    \retval     none
+*/
+void enet_msc_counters_preset_config(enet_msc_preset_enum mode)
+{
+    ENET_MSC_CTL &= ENET_MSC_PRESET_MASK;
+    ENET_MSC_CTL |= (uint32_t)mode;
+}
+
+/*!
+    \brief      get MAC statistics counter  
+    \param[in]  counter: MSC counters which is selected, refer to enet_msc_counter_enum,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_MSC_TX_SCCNT: MSC transmitted good frames after a single collision counter
+      \arg        ENET_MSC_TX_MSCCNT: MSC transmitted good frames after more than a single collision counter
+      \arg        ENET_MSC_TX_TGFCNT: MSC transmitted good frames counter
+      \arg        ENET_MSC_RX_RFCECNT: MSC received frames with CRC error counter
+      \arg        ENET_MSC_RX_RFAECNT: MSC received frames with alignment error counter
+      \arg        ENET_MSC_RX_RGUFCNT: MSC received good unicast frames counter
+    \param[out] none
+    \retval     the MSC counter value
+*/
+uint32_t enet_msc_counters_get(enet_msc_counter_enum counter)
+{
+    uint32_t reval;
+    
+    reval = REG32((ENET + (uint32_t)counter));
+    
+    return reval;
+}
+
+/*!
+    \brief      enable the PTP features
+    \param[in]  feature: the feature of ENET PTP mode
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_RXTX_TIMESTAMP: timestamp function for transmit and receive frames
+      \arg        ENET_PTP_TIMESTAMP_INT: timestamp interrupt trigger
+      \arg        ENET_ALL_RX_TIMESTAMP: all received frames are taken snapshot
+      \arg        ENET_NONTYPE_FRAME_SNAPSHOT: take snapshot when received non type frame
+      \arg        ENET_IPV6_FRAME_SNAPSHOT: take snapshot for IPv6 frame
+      \arg        ENET_IPV4_FRAME_SNAPSHOT: take snapshot for IPv4 frame
+      \arg        ENET_PTP_FRAME_USE_MACADDRESS_FILTER: use MAC address1-3 to filter the PTP frame
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_feature_enable(uint32_t feature)
+{
+    ENET_PTP_TSCTL |= feature;
+}
+
+/*!
+    \brief      disable the PTP features
+    \param[in]  feature: the feature of ENET PTP mode
+                one or more parameters can be selected which are shown as below
+      \arg        ENET_RXTX_TIMESTAMP: timestamp function for transmit and receive frames
+      \arg        ENET_PTP_TIMESTAMP_INT: timestamp interrupt trigger
+      \arg        ENET_ALL_RX_TIMESTAMP: all received frames are taken snapshot
+      \arg        ENET_NONTYPE_FRAME_SNAPSHOT: take snapshot when received non type frame
+      \arg        ENET_IPV6_FRAME_SNAPSHOT: take snapshot for IPv6 frame
+      \arg        ENET_IPV4_FRAME_SNAPSHOT: take snapshot for IPv4 frame
+      \arg        ENET_PTP_FRAME_USE_MACADDRESS_FILTER: use MAC address1-3 to filter the PTP frame
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_feature_disable(uint32_t feature)
+{
+    ENET_PTP_TSCTL &= ~feature;
+}
+
+/*!
+    \brief      configure the PTP timestamp function
+    \param[in]  func: only one parameter can be selected which is shown as below
+      \arg        ENET_CKNT_ORDINARY: type of ordinary clock node type for timestamp
+      \arg        ENET_CKNT_BOUNDARY: type of boundary clock node type for timestamp
+      \arg        ENET_CKNT_END_TO_END: type of end-to-end transparent clock node type for timestamp
+      \arg        ENET_CKNT_PEER_TO_PEER: type of peer-to-peer transparent clock node type for timestamp
+      \arg        ENET_PTP_ADDEND_UPDATE: addend register update
+      \arg        ENET_PTP_SYSTIME_UPDATE: timestamp update
+      \arg        ENET_PTP_SYSTIME_INIT: timestamp initialize
+      \arg        ENET_PTP_FINEMODE: the system timestamp uses the fine method for updating
+      \arg        ENET_PTP_COARSEMODE: the system timestamp uses the coarse method for updating
+      \arg        ENET_SUBSECOND_DIGITAL_ROLLOVER: digital rollover mode
+      \arg        ENET_SUBSECOND_BINARY_ROLLOVER: binary rollover mode
+      \arg        ENET_SNOOPING_PTP_VERSION_2: version 2
+      \arg        ENET_SNOOPING_PTP_VERSION_1: version 1
+      \arg        ENET_EVENT_TYPE_MESSAGES_SNAPSHOT: only event type messages are taken snapshot
+      \arg        ENET_ALL_TYPE_MESSAGES_SNAPSHOT: all type messages are taken snapshot except announce, 
+                                                   management and signaling message
+      \arg        ENET_MASTER_NODE_MESSAGE_SNAPSHOT: snapshot is only take for master node message
+      \arg        ENET_SLAVE_NODE_MESSAGE_SNAPSHOT: snapshot is only taken for slave node message
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func)
+{
+    uint32_t temp_config = 0U, temp_state = 0U;
+    uint32_t timeout = 0U;
+    ErrStatus enet_state = SUCCESS;
+
+    switch(func){
+    case ENET_CKNT_ORDINARY:
+    case ENET_CKNT_BOUNDARY:
+    case ENET_CKNT_END_TO_END:
+    case ENET_CKNT_PEER_TO_PEER:
+        ENET_PTP_TSCTL &= ~ENET_PTP_TSCTL_CKNT;
+        ENET_PTP_TSCTL |= (uint32_t)func;
+        break;
+    case ENET_PTP_ADDEND_UPDATE: 
+        /* this bit must be read as zero before application set it */
+        do{
+            temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSARU; 
+            timeout++;
+        }while((RESET != temp_state) && (timeout < ENET_DELAY_TO));
+        /* return ERROR due to timeout */
+        if(ENET_DELAY_TO == timeout){
+            enet_state = ERROR;
+        }else{
+            ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSARU;
+        }    
+        break;
+    case ENET_PTP_SYSTIME_UPDATE:
+        /* both the TMSSTU and TMSSTI bits must be read as zero before application set this bit */
+        do{
+            temp_state = ENET_PTP_TSCTL & (ENET_PTP_TSCTL_TMSSTU | ENET_PTP_TSCTL_TMSSTI); 
+            timeout++;
+        }while((RESET != temp_state) && (timeout < ENET_DELAY_TO));
+        /* return ERROR due to timeout */
+        if(ENET_DELAY_TO == timeout){
+            enet_state = ERROR;
+        }else{
+            ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTU;
+        }    
+        break; 
+    case ENET_PTP_SYSTIME_INIT:
+        /* this bit must be read as zero before application set it */
+        do{
+            temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSSTI; 
+            timeout++;
+        }while((RESET != temp_state) && (timeout < ENET_DELAY_TO));
+        /* return ERROR due to timeout */
+        if(ENET_DELAY_TO == timeout){
+            enet_state = ERROR;
+        }else{
+            ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTI;
+        }    
+        break;        
+    default:
+        temp_config = (uint32_t)func & (~BIT(31)); 
+        if(RESET != ((uint32_t)func & BIT(31))){
+            ENET_PTP_TSCTL |= temp_config;    
+        }else{
+            ENET_PTP_TSCTL &= ~temp_config;     
+        }
+        break; 
+    }
+
+    return enet_state;
+}
+
+/*!
+    \brief      configure system time subsecond increment value
+    \param[in]  subsecond: the value will be added to the subsecond value of system time, 
+                this value must be between 0 and 0xFF
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_subsecond_increment_config(uint32_t subsecond)
+{
+    ENET_PTP_SSINC = PTP_SSINC_STMSSI(subsecond);
+}
+
+/*!
+    \brief      adjusting the clock frequency only in fine update mode
+    \param[in]  add: the value will be added to the accumulator register to achieve time synchronization
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_timestamp_addend_config(uint32_t add)
+{
+    ENET_PTP_TSADDEND = add;
+}
+
+/*!
+    \brief      initialize or add/subtract to second of the system time
+    \param[in]  sign: timestamp update positive or negative sign,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_PTP_ADD_TO_TIME: timestamp update value is added to system time
+      \arg        ENET_PTP_SUBSTRACT_FROM_TIME: timestamp update value is subtracted from system time
+    \param[in]  second: initializing or adding/subtracting to second of the system time
+    \param[in]  subsecond: the current subsecond of the system time 
+                with 0.46 ns accuracy if required accuracy is 20 ns
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_timestamp_update_config(uint32_t sign, uint32_t second, uint32_t subsecond)
+{
+    ENET_PTP_TSUH = second;
+    ENET_PTP_TSUL = sign | PTP_TSUL_TMSUSS(subsecond); 
+}
+
+/*!
+    \brief      configure the expected target time
+    \param[in]  second: the expected target second time
+    \param[in]  nanosecond: the expected target nanosecond time (signed)
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_expected_time_config(uint32_t second, uint32_t nanosecond)
+{
+    ENET_PTP_ETH = second;
+    ENET_PTP_ETL = nanosecond;
+}
+
+/*!
+    \brief      get the current system time
+    \param[in]  none
+    \param[out] systime_struct: pointer to a enet_ptp_systime_struct structure which contains 
+                parameters of PTP system time
+                members of the structure and the member values are shown as below:
+                  second: 0x0 - 0xFFFF FFFF
+                  subsecond: 0x0 - 0x7FFF FFFF
+                  sign: ENET_PTP_TIME_POSITIVE, ENET_PTP_TIME_NEGATIVE
+    \retval     none
+*/
+void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct)
+{
+    uint32_t temp_sec = 0U, temp_subs = 0U;
+
+    /* get the value of sysytem time registers */
+    temp_sec = (uint32_t)ENET_PTP_TSH;   
+    temp_subs = (uint32_t)ENET_PTP_TSL;
+   
+    /* get sysytem time and construct the enet_ptp_systime_struct structure */
+    systime_struct->second = temp_sec;
+    systime_struct->subsecond = GET_PTP_TSL_STMSS(temp_subs);
+    systime_struct->sign = GET_PTP_TSL_STS(temp_subs);
+}
+
+/*!
+    \brief      configure the PPS output frequency
+    \param[in]  freq: PPS output frequency,
+                only one parameter can be selected which is shown as below
+      \arg        ENET_PPSOFC_1HZ: PPS output 1Hz frequency
+      \arg        ENET_PPSOFC_2HZ: PPS output 2Hz frequency 
+      \arg        ENET_PPSOFC_4HZ: PPS output 4Hz frequency 
+      \arg        ENET_PPSOFC_8HZ: PPS output 8Hz frequency 
+      \arg        ENET_PPSOFC_16HZ: PPS output 16Hz frequency 
+      \arg        ENET_PPSOFC_32HZ: PPS output 32Hz frequency 
+      \arg        ENET_PPSOFC_64HZ: PPS output 64Hz frequency
+      \arg        ENET_PPSOFC_128HZ: PPS output 128Hz frequency
+      \arg        ENET_PPSOFC_256HZ: PPS output 256Hz frequency
+      \arg        ENET_PPSOFC_512HZ: PPS output 512Hz frequency 
+      \arg        ENET_PPSOFC_1024HZ: PPS output 1024Hz frequency
+      \arg        ENET_PPSOFC_2048HZ: PPS output 2048Hz frequency
+      \arg        ENET_PPSOFC_4096HZ: PPS output 4096Hz frequency
+      \arg        ENET_PPSOFC_8192HZ: PPS output 8192Hz frequency
+      \arg        ENET_PPSOFC_16384HZ: PPS output 16384Hz frequency
+      \arg        ENET_PPSOFC_32768HZ: PPS output 32768Hz frequency
+    \param[out] none
+    \retval     none
+*/
+void enet_ptp_pps_output_frequency_config(uint32_t freq)
+{
+    ENET_PTP_PPSCTL = freq;
+}
+
+/*!
+    \brief      reset the ENET initpara struct, call it before using enet_initpara_config()
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void enet_initpara_reset(void)
+{
+    enet_initpara.option_enable = 0U;
+    enet_initpara.forward_frame = 0U;
+    enet_initpara.dmabus_mode = 0U;
+    enet_initpara.dma_maxburst = 0U;
+    enet_initpara.dma_arbitration = 0U;
+    enet_initpara.store_forward_mode = 0U;
+    enet_initpara.dma_function = 0U; 
+    enet_initpara.vlan_config = 0U;
+    enet_initpara.flow_control = 0U;
+    enet_initpara.hashtable_high = 0U;
+    enet_initpara.hashtable_low = 0U;
+    enet_initpara.framesfilter_mode = 0U;
+    enet_initpara.halfduplex_param = 0U;
+    enet_initpara.timer_config = 0U;
+    enet_initpara.interframegap = 0U;
+} 
+
+/*!
+    \brief      initialize ENET peripheral with generally concerned parameters, call it by enet_init() 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void enet_default_init(void)
+{
+    uint32_t reg_value = 0U;
+
+    /* MAC */
+    /* configure ENET_MAC_CFG register */
+    reg_value = ENET_MAC_CFG;
+    reg_value &= MAC_CFG_MASK;
+    reg_value |= ENET_WATCHDOG_ENABLE | ENET_JABBER_ENABLE | ENET_INTERFRAMEGAP_96BIT \
+                | ENET_SPEEDMODE_10M |ENET_MODE_HALFDUPLEX | ENET_LOOPBACKMODE_DISABLE \
+                | ENET_CARRIERSENSE_ENABLE | ENET_RECEIVEOWN_ENABLE \
+                | ENET_RETRYTRANSMISSION_ENABLE | ENET_BACKOFFLIMIT_10 \
+                | ENET_DEFERRALCHECK_DISABLE \
+                | ENET_TYPEFRAME_CRC_DROP_DISABLE \
+                | ENET_AUTO_PADCRC_DROP_DISABLE \
+                | ENET_CHECKSUMOFFLOAD_DISABLE;
+    ENET_MAC_CFG = reg_value;
+  
+    /* configure ENET_MAC_FRMF register */
+    ENET_MAC_FRMF = ENET_SRC_FILTER_DISABLE |ENET_DEST_FILTER_INVERSE_DISABLE \
+                   |ENET_MULTICAST_FILTER_PERFECT |ENET_UNICAST_FILTER_PERFECT \
+                   |ENET_PCFRM_PREVENT_ALL |ENET_BROADCASTFRAMES_ENABLE \
+                   |ENET_PROMISCUOUS_DISABLE |ENET_RX_FILTER_ENABLE;
+
+    /* configure ENET_MAC_HLH, ENET_MAC_HLL register */
+    ENET_MAC_HLH = 0x0U;
+    
+    ENET_MAC_HLL = 0x0U;
+
+    /* configure ENET_MAC_FCTL, ENET_MAC_FCTH register */
+    reg_value = ENET_MAC_FCTL;
+    reg_value &= MAC_FCTL_MASK;
+    reg_value |= MAC_FCTL_PTM(0) |ENET_ZERO_QUANTA_PAUSE_DISABLE \
+                |ENET_PAUSETIME_MINUS4 |ENET_UNIQUE_PAUSEDETECT \
+                |ENET_RX_FLOWCONTROL_DISABLE |ENET_TX_FLOWCONTROL_DISABLE;
+    ENET_MAC_FCTL = reg_value;                                         
+                                        
+    ENET_MAC_FCTH = ENET_DEACTIVE_THRESHOLD_512BYTES |ENET_ACTIVE_THRESHOLD_1536BYTES;
+   
+    /* configure ENET_MAC_VLT register */
+    ENET_MAC_VLT = ENET_VLANTAGCOMPARISON_16BIT |MAC_VLT_VLTI(0);
+                                                          
+    /* DMA */
+    /* configure ENET_DMA_CTL register */
+    reg_value = ENET_DMA_CTL;
+    reg_value &= DMA_CTL_MASK;
+    reg_value |= ENET_TCPIP_CKSUMERROR_DROP |ENET_RX_MODE_STOREFORWARD \
+                |ENET_FLUSH_RXFRAME_ENABLE |ENET_TX_MODE_STOREFORWARD \
+                |ENET_TX_THRESHOLD_64BYTES |ENET_RX_THRESHOLD_64BYTES \
+                |ENET_FORWARD_ERRFRAMES_DISABLE |ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE \
+                |ENET_SECONDFRAME_OPT_DISABLE; 
+    ENET_DMA_CTL = reg_value;    
+
+    /* configure ENET_DMA_BCTL register */
+    reg_value = ENET_DMA_BCTL;
+    reg_value &= DMA_BCTL_MASK;
+    reg_value = ENET_ADDRESS_ALIGN_ENABLE |ENET_ARBITRATION_RXTX_2_1 \
+               |ENET_RXDP_32BEAT |ENET_PGBL_32BEAT |ENET_RXTX_DIFFERENT_PGBL \
+               |ENET_FIXED_BURST_ENABLE |ENET_MIXED_BURST_DISABLE \
+               |ENET_NORMAL_DESCRIPTOR;
+    ENET_DMA_BCTL = reg_value; 
+}
+
+#ifndef USE_DELAY
+/*!
+    \brief      insert a delay time
+    \param[in]  ncount: specifies the delay time length
+    \param[out] none
+    \param[out] none
+*/
+static void enet_delay(uint32_t ncount)
+{
+    uint32_t delay_time = 0U; 
+    
+    for(delay_time = ncount; delay_time != 0U; delay_time--){
+    }
+}
+#endif /* USE_DELAY */

+ 1138 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c

@@ -0,0 +1,1138 @@
+/*!
+    \file  gd32f4xx_exmc.c
+    \brief EXMC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_exmc.h"
+
+/* EXMC bank0 register reset value */
+#define BANK0_SNCTL_REGION_RESET          ((uint32_t)0x000030DAU)
+#define BANK0_SNTCFG_RESET                ((uint32_t)0x0FFFFFFFU)
+#define BANK0_SNWTCFG_RESET               ((uint32_t)0x0FFFFFFFU)
+
+/* EXMC bank1/2 register reset mask*/
+#define BANK1_2_NPCTL_RESET               ((uint32_t)0x00000018U)
+#define BANK1_2_NPINTEN_RESET             ((uint32_t)0x00000040U)
+#define BANK1_2_NPCTCFG_RESET             ((uint32_t)0xFCFCFCFCU)
+#define BANK1_2_NPATCFG_RESET             ((uint32_t)0xFCFCFCFCU)
+
+/* EXMC bank3 register reset mask*/
+#define BANK3_NPCTL_RESET                 ((uint32_t)0x00000018U)
+#define BANK3_NPINTEN_RESET               ((uint32_t)0x00000000U)
+#define BANK3_NPCTCFG_RESET               ((uint32_t)0xFCFCFCFCU)
+#define BANK3_NPATCFG_RESET               ((uint32_t)0xFCFCFCFCU)
+#define BANK3_PIOTCFG3_RESET              ((uint32_t)0xFCFCFCFCU)
+
+/* EXMC SDRAM device register reset mask */
+#define SDRAM_DEVICE_SDCTL_RESET          ((uint32_t)0x000002D0U)
+#define SDRAM_DEVICE_SDTCFG_RESET         ((uint32_t)0x0FFFFFFFU)
+#define SDRAM_DEVICE_SDCMD_RESET          ((uint32_t)0x00000000U)
+#define SDRAM_DEVICE_SDARI_RESET          ((uint32_t)0x00000000U)
+#define SDRAM_DEVICE_SDSTAT_RESET         ((uint32_t)0x00000000U)
+#define SDRAM_DEVICE_SDRSCTL_RESET        ((uint32_t)0x00000000U)
+
+/* EXMC bank0 SQPI-PSRAM register reset mask */
+#define BANK0_SQPI_SINIT_RESET            ((uint32_t)0x18010000U)
+#define BANK0_SQPI_SRCMD_RESET            ((uint32_t)0x00000000U)
+#define BANK0_SQPI_SWCMD_RESET            ((uint32_t)0x00000000U)
+#define BANK0_SQPI_SIDL_RESET             ((uint32_t)0x00000000U)
+#define BANK0_SQPI_SIDH_RESET             ((uint32_t)0x00000000U)
+
+/* EXMC register bit offset */
+#define SNCTL_NRMUX_OFFSET                ((uint32_t)1U)
+#define SNCTL_SBRSTEN_OFFSET              ((uint32_t)8U)
+#define SNCTL_WRAPEN_OFFSET               ((uint32_t)10U)
+#define SNCTL_WREN_OFFSET                 ((uint32_t)12U)
+#define SNCTL_NRWTEN_OFFSET               ((uint32_t)13U)
+#define SNCTL_EXMODEN_OFFSET              ((uint32_t)14U)
+#define SNCTL_ASYNCWAIT_OFFSET            ((uint32_t)15U)
+
+#define SNTCFG_AHLD_OFFSET                ((uint32_t)4U)
+#define SNTCFG_DSET_OFFSET                ((uint32_t)8U)
+#define SNTCFG_BUSLAT_OFFSET              ((uint32_t)16U)
+
+#define NPCTL_NDWTEN_OFFSET               ((uint32_t)1U)
+#define NPCTL_ECCEN_OFFSET                ((uint32_t)6U)
+
+#define NPCTCFG_COMWAIT_OFFSET            ((uint32_t)8U)
+#define NPCTCFG_COMHLD_OFFSET             ((uint32_t)16U)
+#define NPCTCFG_COMHIZ_OFFSET             ((uint32_t)24U)
+
+#define NPATCFG_COMWAIT_OFFSET            ((uint32_t)8U)
+#define NPATCFG_COMHLD_OFFSET             ((uint32_t)16U)
+#define NPATCFG_COMHIZ_OFFSET             ((uint32_t)24U)
+
+#define PIOTCFG_COMWAIT_OFFSET            ((uint32_t)8U)
+#define PIOTCFG_COMHLD_OFFSET             ((uint32_t)16U)
+#define PIOTCFG_COMHIZ_OFFSET             ((uint32_t)24U)
+
+#define SDCTL_WPEN_OFFSET                 ((uint32_t)9U)
+#define SDCTL_BRSTRD_OFFSET               ((uint32_t)12U)
+
+#define SDTCFG_XSRD_OFFSET                ((uint32_t)4U)
+#define SDTCFG_RASD_OFFSET                ((uint32_t)8U)
+#define SDTCFG_ARFD_OFFSET                ((uint32_t)12U)
+#define SDTCFG_WRD_OFFSET                 ((uint32_t)16U)
+#define SDTCFG_RPD_OFFSET                 ((uint32_t)20U)
+#define SDTCFG_RCD_OFFSET                 ((uint32_t)24U)
+
+#define SDCMD_NARF_OFFSET                 ((uint32_t)5U)
+#define SDCMD_MRC_OFFSET                  ((uint32_t)9U)
+
+#define SDARI_ARINTV_OFFSET               ((uint32_t)1U)
+
+#define SDRSCTL_SSCR_OFFSET               ((uint32_t)1U)
+#define SDRSCTL_SDSC_OFFSET               ((uint32_t)4U)
+
+#define SDSTAT_STA0_OFFSET                ((uint32_t)1U)
+#define SDSTAT_STA1_OFFSET                ((uint32_t)3U)
+
+#define SRCMD_RWAITCYCLE_OFFSET           ((uint32_t)16U)
+#define SWCMD_WWAITCYCLE_OFFSET           ((uint32_t)16U)
+
+#define INTEN_INTEN_OFFSET                ((uint32_t)3U)
+
+/*!
+    \brief      deinitialize EXMC NOR/SRAM region
+    \param[in]  exmc_norsram_region: select the region of bank0
+      \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
+    \param[out] none
+    \retval     none
+*/
+void exmc_norsram_deinit(uint32_t exmc_norsram_region)
+{
+    /* reset the registers */
+    EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_REGION_RESET;
+    EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET;
+    EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET;
+}
+
+/*!
+    \brief      initialize EXMC NOR/SRAM region
+    \param[in]  exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
+                  norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0..3
+                  write_mode: EXMC_ASYN_WRITE,EXMC_SYN_WRITE
+                  extended_mode: ENABLE or DISABLE 
+                  asyn_wait: ENABLE or DISABLE
+                  nwait_signal: ENABLE or DISABLE
+                  memory_write: ENABLE or DISABLE
+                  nwait_config: EXMC_NWAIT_CONFIG_BEFORE,EXMC_NWAIT_CONFIG_DURING
+                  wrap_burst_mode: ENABLE or DISABLE
+                  nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH
+                  burst_mode: ENABLE or DISABLE
+                  databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B
+                  memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR
+                  address_data_mux: ENABLE or DISABLE
+                  read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
+                  write_timing: struct exmc_norsram_timing_parameter_struct set the time
+    \param[out] none
+    \retval     none
+*/
+void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
+{
+    uint32_t snctl = 0x00000000U,sntcfg = 0x00000000U,snwtcfg = 0x00000000U;
+
+    /* get the register value */
+    snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
+
+    /* clear relative bits */
+    snctl &= ((uint32_t)~(EXMC_SNCTL_EXMODEN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN | 
+                          EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WREN | 
+                          EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_SYNCWR | 
+                          EXMC_SNCTL_NRBKEN));
+
+    snctl = (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
+                       exmc_norsram_init_struct->memory_type |
+                       exmc_norsram_init_struct->databus_width |
+                      (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
+                       exmc_norsram_init_struct->nwait_polarity |
+                      (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
+                       exmc_norsram_init_struct->nwait_config |
+                      (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
+                      (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
+                      (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
+                      (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
+                       exmc_norsram_init_struct->write_mode;
+
+    sntcfg = (uint32_t)exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime |
+                      (exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) |
+                      (exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) |
+                      (exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) |
+                       exmc_norsram_init_struct->read_write_timing->syn_clk_division |
+                       exmc_norsram_init_struct->read_write_timing->syn_data_latency |
+                       exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
+
+    /* nor flash access enable */
+    if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type)
+    {
+        snctl |= (uint32_t)EXMC_SNCTL_NREN;
+    }
+
+    /* extended mode configure */
+    if(ENABLE == exmc_norsram_init_struct->extended_mode)
+    {
+        snwtcfg = (uint32_t)exmc_norsram_init_struct->write_timing->asyn_address_setuptime |
+                           (exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET )|
+                           (exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) |
+                           (exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) |
+                            exmc_norsram_init_struct->write_timing->asyn_access_mode;
+    }
+    else
+    {
+        snwtcfg = BANK0_SNWTCFG_RESET;
+    }
+
+    /* configure the registers */
+    EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
+    EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
+    EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg;
+}
+
+/*!
+    \brief      initialize the struct exmc_norsram_parameter_struct
+    \param[in]  none
+    \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer
+    \retval     none
+*/
+void exmc_norsram_parameter_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
+{
+    /* configure the structure with default value */
+    exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0;
+    exmc_norsram_init_struct->address_data_mux = ENABLE;
+    exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM;
+    exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B;
+    exmc_norsram_init_struct->burst_mode = DISABLE;
+    exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
+    exmc_norsram_init_struct->wrap_burst_mode = DISABLE;
+    exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
+    exmc_norsram_init_struct->memory_write = ENABLE;
+    exmc_norsram_init_struct->nwait_signal = ENABLE;
+    exmc_norsram_init_struct->extended_mode = DISABLE;
+    exmc_norsram_init_struct->asyn_wait = DISABLE;
+    exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
+
+    /* read/write timing configure */
+    exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
+    exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
+    exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
+    exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
+    exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
+    exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK;
+    exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
+
+    /* write timing configure, when extended mode is used */
+    exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU;
+    exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU;
+    exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU;
+    exmc_norsram_init_struct->write_timing->bus_latency = 0xFU;
+    exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
+}
+
+/*!
+    \brief      consecutive clock configure
+    \param[in]  clock_mode: specifie when the clock is generated
+      \arg        EXMC_CLOCK_SYN_MODE: the clock is generated only during synchronous access
+      \arg        EXMC_CLOCK_UNCONDITIONALLY: the clock is generated unconditionally
+    \param[out] none
+    \retval     none
+*/
+void exmc_norsram_consecutive_clock_config(uint32_t clock_mode)
+{
+    if (EXMC_CLOCK_UNCONDITIONALLY == clock_mode){
+        EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_CLOCK_UNCONDITIONALLY;
+    }else{
+        EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_CLOCK_UNCONDITIONALLY;
+    }
+}
+
+/*!
+    \brief      CRAM page size configure
+    \param[in]  page_size: CRAM page size
+      \arg        EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
+      \arg        EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
+      \arg        EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
+      \arg        EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
+      \arg        EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
+    \param[out] none
+    \retval     none
+*/
+void exmc_norsram_page_size_config(uint32_t page_size)
+{
+    /* reset the bits */
+    EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_SNCTL_CPS;
+
+    /* set the CPS bits */
+    EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= page_size;
+}
+
+/*!
+    \brief      enable EXMC NOR/PSRAM bank region
+    \param[in]  exmc_norsram_region: specifie the region of NOR/PSRAM bank
+      \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
+    \param[out] none
+    \retval     none
+*/
+void exmc_norsram_enable(uint32_t exmc_norsram_region)
+{
+    EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
+}
+
+/*!
+    \brief      disable EXMC NOR/PSRAM bank region
+    \param[in]  exmc_norsram_region: specifie the region of NOR/PSRAM Bank
+      \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
+    \param[out] none
+    \retval     none
+*/
+void exmc_norsram_disable(uint32_t exmc_norsram_region)
+{
+    EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
+}
+
+/*!
+    \brief      deinitialize EXMC NAND bank
+    \param[in]  exmc_nand_bank: select the bank of NAND
+      \arg        EXMC_BANKx_NAND(x=1..2)
+    \param[out] none
+    \retval     none
+*/
+void exmc_nand_deinit(uint32_t exmc_nand_bank)
+{
+    /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */
+    EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET;
+    EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET;
+    EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET;
+    EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET;
+}
+
+/*!
+    \brief      initialize EXMC NAND bank
+    \param[in]  exmc_nand_parameter_struct: configure the EXMC NAND parameter
+                  nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND
+                  ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
+                  atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
+                  ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
+                  ecc_logic: ENABLE or DISABLE
+                  databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
+                  wait_feature: ENABLE or DISABLE
+                  common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
+                  attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
+    \param[out] none
+    \retval     none
+*/
+void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
+{
+    uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U;
+    
+    npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)|
+                       EXMC_NPCTL_NDTP |
+                       exmc_nand_init_struct->databus_width |
+                      (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)|
+                       exmc_nand_init_struct->ecc_size |
+                       exmc_nand_init_struct->ctr_latency |
+                       exmc_nand_init_struct->atr_latency;
+
+    npctcfg = (uint32_t)(exmc_nand_init_struct->common_space_timing->setuptime - 1U) |
+                ((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) |
+                (exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET)|
+                ((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET);
+
+    npatcfg = (uint32_t)(exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) |
+                ((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_COMWAIT_OFFSET) |
+                (exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_COMHLD_OFFSET)|
+                (exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_COMHIZ_OFFSET);
+
+    /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */
+    EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl;
+    EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg;
+    EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg;
+}
+
+/*!
+    \brief      initialize the struct exmc_norsram_parameter_struct
+    \param[in]  none
+    \param[out] the initialized struct exmc_norsram_parameter_struct pointer
+    \retval     none
+*/
+void exmc_nand_parameter_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
+{
+    /* configure the structure with default value */
+    exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND;
+    exmc_nand_init_struct->wait_feature = DISABLE;
+    exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
+    exmc_nand_init_struct->ecc_logic = DISABLE;
+    exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES;
+    exmc_nand_init_struct->ctr_latency = 0x0U;
+    exmc_nand_init_struct->atr_latency = 0x0U;
+    exmc_nand_init_struct->common_space_timing->setuptime = 0xfcU;
+    exmc_nand_init_struct->common_space_timing->waittime = 0xfcU;
+    exmc_nand_init_struct->common_space_timing->holdtime = 0xfcU;
+    exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xfcU;
+    exmc_nand_init_struct->attribute_space_timing->setuptime = 0xfcU;
+    exmc_nand_init_struct->attribute_space_timing->waittime = 0xfcU;
+    exmc_nand_init_struct->attribute_space_timing->holdtime = 0xfcU;
+    exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xfcU;
+}
+
+/*!
+    \brief      enable NAND bank
+    \param[in]  exmc_nand_bank: specifie the NAND bank
+      \arg        EXMC_BANKx_NAND(x=1,2)
+    \param[out] none
+    \retval     none
+*/
+void exmc_nand_enable(uint32_t exmc_nand_bank)
+{
+    EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN;
+}
+
+/*!
+    \brief      disable NAND bank
+    \param[in]  exmc_nand_bank: specifie the NAND bank
+      \arg        EXMC_BANKx_NAND(x=1,2)
+    \param[out] none
+    \retval     none
+*/
+void exmc_nand_disable(uint32_t exmc_nand_bank)
+{
+    EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_NDBKEN;
+}
+
+/*!
+    \brief      enable or disable the EXMC NAND ECC function
+    \param[in]  exmc_nand_bank: specifie the NAND bank
+      \arg        EXMC_BANKx_NAND(x=1,2)
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue)
+{
+    if (ENABLE == newvalue)
+    {
+        /* enable the selected NAND bank ECC function */
+        EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN;
+    }
+    else
+    {
+        /* disable the selected NAND bank ECC function */
+        EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_ECCEN;
+    }
+}
+
+/*!
+    \brief      get the EXMC ECC value
+    \param[in]  exmc_nand_bank: specifie the NAND bank
+      \arg        EXMC_BANKx_NAND(x=1,2)
+    \param[out] none
+    \retval     the error correction code(ECC) value
+*/
+uint32_t exmc_ecc_get(uint32_t exmc_nand_bank)
+{
+    return(EXMC_NECC(exmc_nand_bank));
+}
+
+/*!
+    \brief      deinitialize EXMC PC card bank
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_pccard_deinit(void)
+{
+    /* EXMC_BANK3_PCCARD */
+    EXMC_NPCTL3 = BANK3_NPCTL_RESET;
+    EXMC_NPINTEN3 = BANK3_NPINTEN_RESET;
+    EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET;
+    EXMC_NPATCFG3 = BANK3_NPATCFG_RESET;
+    EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET;
+}
+
+/*!
+    \brief      initialize EXMC PC card bank
+    \param[in]  exmc_pccard_parameter_struct: configure the EXMC NAND parameter
+                  atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
+                  ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
+                  wait_feature: ENABLE or DISABLE
+                  common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
+                  attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
+                  io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time
+    \param[out] none
+    \retval     none
+*/
+void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
+{
+    /* configure the EXMC bank3 PC card control register */
+    EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
+                                            EXMC_NAND_DATABUS_WIDTH_16B |  
+                                            exmc_pccard_init_struct->ctr_latency |
+                                            exmc_pccard_init_struct->atr_latency ;
+            
+    /* configure the EXMC bank3 PC card common space timing configuration register */
+    EXMC_NPCTCFG3 = (uint32_t)(exmc_pccard_init_struct->common_space_timing->setuptime - 1U) |
+                                            ((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) |
+                                            (exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET)|
+                                            ((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET);
+
+    /* configure the EXMC bank3 PC card attribute space timing configuration register */
+    EXMC_NPATCFG3 = (uint32_t)(exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) |
+                                            ((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_COMWAIT_OFFSET) |
+                                            (exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_COMHLD_OFFSET)|
+                                            (exmc_pccard_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_COMHIZ_OFFSET);
+
+    /* configure the EXMC bank3 PC card io space timing configuration register */
+    EXMC_PIOTCFG3 = (uint32_t)(exmc_pccard_init_struct->io_space_timing->setuptime - 1U) |
+                                            ((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_COMWAIT_OFFSET) |
+                                            (exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_COMHLD_OFFSET)|
+                                            (exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_COMHIZ_OFFSET);
+}
+
+/*!
+    \brief      initialize the struct exmc_pccard_parameter_struct
+    \param[in]  none
+    \param[out] the initialized struct exmc_pccard_parameter_struct pointer
+    \retval     none
+*/
+void exmc_pccard_parameter_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
+{
+    /* configure the structure with default value */
+    exmc_pccard_init_struct->wait_feature = DISABLE;
+    exmc_pccard_init_struct->ctr_latency = 0x0U;
+    exmc_pccard_init_struct->atr_latency = 0x0U;
+    exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU;
+    exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU;
+    exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU;
+    exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU;
+    exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU;
+    exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU;
+    exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU;
+    exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
+    exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU;
+    exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU;
+    exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU;
+    exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU;
+}
+
+/*!
+    \brief      enable PC Card Bank
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_pccard_enable(void)
+{
+    EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN;
+}
+
+/*!
+    \brief      disable PC Card Bank
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_pccard_disable(void)
+{
+   EXMC_NPCTL3 &= ~EXMC_NPCTL_NDBKEN;
+}
+
+/*!
+    \brief      deinitialize EXMC SDRAM device
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_deinit(uint32_t exmc_sdram_device)
+{
+    /* reset SDRAM registers */
+    EXMC_SDCTL(exmc_sdram_device) = SDRAM_DEVICE_SDCTL_RESET;
+    EXMC_SDTCFG(exmc_sdram_device) = SDRAM_DEVICE_SDTCFG_RESET;
+    EXMC_SDCMD = SDRAM_DEVICE_SDCMD_RESET;
+    EXMC_SDARI = SDRAM_DEVICE_SDARI_RESET;
+    EXMC_SDRSCTL = SDRAM_DEVICE_SDRSCTL_RESET;
+}
+
+/*!
+    \brief      initialize EXMC SDRAM device
+    \param[in]  exmc_sdram_parameter_struct: configure the EXMC SDRAM parameter
+                  sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1
+                  pipeline_read_delay: EXMC_PIPELINE_DELAY_x_HCLK,x=0..2
+                  brust_read_switch: ENABLE or DISABLE
+                  sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_HCLK,EXMC_SDCLK_PERIODS_3_HCLK
+                  write_protection: ENABLE or DISABLE
+                  cas_latency: EXMC_CAS_LATENCY_x_SDCLK,x=1..3
+                  internal_bank_number: EXMC_SDRAM_2_INTER_BANK,EXMC_SDRAM_4_INTER_BANK
+                  data_width: EXMC_SDRAM_DATABUS_WIDTH_8B,EXMC_SDRAM_DATABUS_WIDTH_16B,EXMC_SDRAM_DATABUS_WIDTH_32B
+                  row_address_width: EXMC_SDRAM_ROW_ADDRESS_x,x=11..13
+                  column_address_width: EXMC_SDRAM_COW_ADDRESS_x,x=8..11
+                  timing: exmc_sdram_timing_parameter_struct set the time
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct)
+{
+    uint32_t sdctl0, sdctl1, sdtcfg0, sdtcfg1;
+
+    /* configuration EXMC_SDCTL0 or EXMC_SDCTL1 */ 
+    if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device){
+        /* configuration EXMC_SDCTL0 */
+        EXMC_SDCTL(EXMC_SDRAM_DEVICE0)  = (uint32_t)exmc_sdram_init_struct->column_address_width |
+                                                    exmc_sdram_init_struct->row_address_width |
+                                                    exmc_sdram_init_struct->data_width |
+                                                    exmc_sdram_init_struct->internal_bank_number |
+                                                    exmc_sdram_init_struct->cas_latency |
+                                                   (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET)|
+                                                    exmc_sdram_init_struct->sdclock_config |
+                                                   (exmc_sdram_init_struct->brust_read_switch << SDCTL_BRSTRD_OFFSET)| 
+                                                    exmc_sdram_init_struct->pipeline_read_delay;
+        
+        /* configuration EXMC_SDTCFG0 */
+        EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay)-1U) |
+                                                   (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay)-1U) << SDTCFG_XSRD_OFFSET) |
+                                                   (((exmc_sdram_init_struct->timing->row_address_select_delay)-1U) << SDTCFG_RASD_OFFSET) |
+                                                   (((exmc_sdram_init_struct->timing->auto_refresh_delay)-1U) << SDTCFG_ARFD_OFFSET) |
+                                                   (((exmc_sdram_init_struct->timing->write_recovery_delay)-1U) << SDTCFG_WRD_OFFSET) |
+                                                   (((exmc_sdram_init_struct->timing->row_precharge_delay)-1U) << SDTCFG_RPD_OFFSET) |
+                                                   (((exmc_sdram_init_struct->timing->row_to_column_delay)-1U) << SDTCFG_RCD_OFFSET);
+    }else{
+        /* configuration EXMC_SDCTL0 and EXMC_SDCTL1 */
+        /* some bits in the EXMC_SDCTL1 register are reserved */
+        sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~( EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK ));
+        
+        sdctl0 |= (uint32_t)exmc_sdram_init_struct->sdclock_config |
+                            exmc_sdram_init_struct->brust_read_switch | 
+                            exmc_sdram_init_struct->pipeline_read_delay;
+        
+        sdctl1 = (uint32_t)exmc_sdram_init_struct->column_address_width |
+                           exmc_sdram_init_struct->row_address_width |
+                           exmc_sdram_init_struct->data_width |
+                           exmc_sdram_init_struct->internal_bank_number |
+                           exmc_sdram_init_struct->cas_latency |
+                           exmc_sdram_init_struct->write_protection ;
+
+        EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0;
+        EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1;
+        
+        /* configuration EXMC_SDTCFG0 and EXMC_SDTCFG1 */
+        /* some bits in the EXMC_SDTCFG1 register are reserved */
+        sdtcfg0 = EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDTCFG_RPD | EXMC_SDTCFG_WRD | EXMC_SDTCFG_ARFD));
+
+        sdtcfg0 |= (uint32_t)(((exmc_sdram_init_struct->timing->auto_refresh_delay)-1U) << SDTCFG_ARFD_OFFSET) |
+                             (((exmc_sdram_init_struct->timing->row_precharge_delay)-1U) << SDTCFG_RPD_OFFSET) |
+                             (((exmc_sdram_init_struct->timing->write_recovery_delay)-1U) << SDTCFG_WRD_OFFSET);
+
+        sdtcfg1 = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay)-1U) |
+                           (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay)-1U) << SDTCFG_XSRD_OFFSET) |
+                           (((exmc_sdram_init_struct->timing->row_address_select_delay)-1U) << SDTCFG_RASD_OFFSET) |
+                           (((exmc_sdram_init_struct->timing->row_to_column_delay)-1U) << SDTCFG_RCD_OFFSET);    
+
+        EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = sdtcfg0;
+        EXMC_SDTCFG(EXMC_SDRAM_DEVICE1) = sdtcfg1;
+    }
+}
+
+/*!
+    \brief      initialize the struct exmc_pccard_parameter_struct
+    \param[in]  none
+    \param[out] the initialized struct exmc_pccard_parameter_struct pointer
+    \retval     none
+*/
+void exmc_sdram_parameter_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct)
+{
+    /* configure the structure with default value */
+    exmc_sdram_init_struct->sdram_device = EXMC_SDRAM_DEVICE0;
+    exmc_sdram_init_struct->column_address_width = EXMC_SDRAM_COW_ADDRESS_8;
+    exmc_sdram_init_struct->row_address_width = EXMC_SDRAM_ROW_ADDRESS_11;
+    exmc_sdram_init_struct->data_width = EXMC_SDRAM_DATABUS_WIDTH_16B;
+    exmc_sdram_init_struct->internal_bank_number = EXMC_SDRAM_4_INTER_BANK;
+    exmc_sdram_init_struct->cas_latency = EXMC_CAS_LATENCY_1_SDCLK;
+    exmc_sdram_init_struct->write_protection = ENABLE;
+    exmc_sdram_init_struct->sdclock_config = EXMC_SDCLK_DISABLE;
+    exmc_sdram_init_struct->brust_read_switch = DISABLE;
+    exmc_sdram_init_struct->pipeline_read_delay = EXMC_PIPELINE_DELAY_0_HCLK;
+
+    exmc_sdram_init_struct->timing->load_mode_register_delay = 16U;
+    exmc_sdram_init_struct->timing->exit_selfrefresh_delay = 16U;
+    exmc_sdram_init_struct->timing->row_address_select_delay = 16U;
+    exmc_sdram_init_struct->timing->auto_refresh_delay = 16U;
+    exmc_sdram_init_struct->timing->write_recovery_delay = 16U;
+    exmc_sdram_init_struct->timing->row_precharge_delay = 16U;
+    exmc_sdram_init_struct->timing->row_to_column_delay = 16U;
+}
+
+/*!
+    \brief      configure the SDRAM memory command
+    \param[in]  the struct exmc_sdram_command_parameter_struct pointer
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_command_config(exmc_sdram_command_parameter_struct* exmc_sdram_command_init_struct)
+{
+    /* configure command register */
+    EXMC_SDCMD = (uint32_t)((exmc_sdram_command_init_struct->command) |
+                           (exmc_sdram_command_init_struct->bank_select) |
+                           ((exmc_sdram_command_init_struct->auto_refresh_number)) |
+                           ((exmc_sdram_command_init_struct->mode_register_content)<<SDCMD_MRC_OFFSET) );
+}
+
+/*!
+    \brief      set auto-refresh interval
+    \param[in]  exmc_count: the number SDRAM clock cycles unit between two successive auto-refresh commands
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_refresh_count_set(uint32_t exmc_count)
+{
+    uint32_t sdari;
+    sdari = EXMC_SDARI & (~EXMC_SDARI_ARINTV);
+    EXMC_SDARI = sdari | (uint32_t)((exmc_count << SDARI_ARINTV_OFFSET) & EXMC_SDARI_ARINTV);
+}
+
+/*!
+    \brief      set the number of successive auto-refresh command
+    \param[in]  exmc_number: the number SDRAM clock cycles unit between two successive auto-refresh commands
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_autorefresh_number_set(uint32_t exmc_number)
+{
+    uint32_t sdcmd;
+    sdcmd = EXMC_SDCMD & (~EXMC_SDCMD_NARF);
+    EXMC_SDCMD = sdcmd | (uint32_t)((exmc_number << SDCMD_NARF_OFFSET) & EXMC_SDCMD_NARF) ;
+}
+
+/*!
+    \brief      config the write protection function
+    \param[in]  exmc_sdram_device: specifie the SDRAM device
+      \arg        EXMC_SDRAM_DEVICEx(x=0,1)
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue)
+{
+    if (ENABLE == newvalue){
+        EXMC_SDCTL(exmc_sdram_device) |= (uint32_t)EXMC_SDCTL_WPEN;
+    }else{
+        EXMC_SDCTL(exmc_sdram_device) &= ~((uint32_t)EXMC_SDCTL_WPEN);
+    }
+
+}
+
+/*!
+    \brief      get the status of SDRAM device0 or device1
+    \param[in]  exmc_sdram_device: specifie the SDRAM device
+      \arg        EXMC_SDRAM_DEVICEx(x=0,1)
+    \param[out] none
+    \retval     the status of SDRAM device
+*/
+uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device)
+{
+    uint32_t sdstat = 0U;
+
+    if(EXMC_SDRAM_DEVICE0 == exmc_sdram_device)
+    {
+        sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA0) >> SDSTAT_STA0_OFFSET);
+    }
+    else
+    {
+        sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA1) >> SDSTAT_STA1_OFFSET);
+    }
+
+    return sdstat;
+}
+
+/*!
+    \brief      configure the delayed sample clock of read data
+    \param[in]  delay_cell: SDRAM the delayed sample clock of read data
+      \arg        EXMC_SDRAM_x_DELAY_CELL(x=0..15)
+    \param[in]  extra_hclk: sample cycle of read data
+      \arg        EXMC_SDRAM_READSAMPLE_x_EXTRAHCLK(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk)
+{
+    uint32_t sdrsctl = 0U;
+    
+    sdrsctl = EXMC_SDRSCTL & (~(EXMC_SDRSCTL_SDSC | EXMC_SDRSCTL_SSCR));
+    sdrsctl |= (uint32_t)(delay_cell  & EXMC_SDRSCTL_SDSC) |
+                        ((extra_hclk << SDRSCTL_SSCR_OFFSET) & EXMC_SDRSCTL_SSCR);
+    EXMC_SDRSCTL = sdrsctl;
+}
+
+/*!
+    \brief      enable or disable read sample
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void exmc_sdram_readsample_enable(ControlStatus newvalue)
+{
+    if (ENABLE == newvalue){
+        EXMC_SDRSCTL |=  EXMC_SDRSCTL_RSEN;
+    }else{
+        EXMC_SDRSCTL &= (uint32_t)(~EXMC_SDRSCTL_RSEN);
+    }
+}
+
+/*!
+    \brief      deinitialize exmc SQPIPSRAM
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_deinit(void)
+{
+    /* reset the registers */
+    EXMC_SINIT = BANK0_SQPI_SINIT_RESET;
+    EXMC_SRCMD = BANK0_SQPI_SRCMD_RESET;
+    EXMC_SWCMD = BANK0_SQPI_SWCMD_RESET;
+    EXMC_SIDL = BANK0_SQPI_SIDL_RESET;
+    EXMC_SIDH = BANK0_SQPI_SIDH_RESET;
+}
+
+/*!
+    \brief      initialize EXMC SQPIPSRAM
+    \param[in]  exmc_sqpipsram_parameter_struct: configure the EXMC SQPIPSRAM parameter
+                  sample_polarity: EXMC_SDRAM_SAMPLE_RISING_EDGE,EXMC_SDRAM_SAMPLE_FALLING_EDGE
+                  id_length: EXMC_SQPIPSRAM_ID_LENGTH_xB,x=8,16,32,64
+                  address_bits: EXMC_SQPIPSRAM_ADDR_LENGTH_xB,x=1..26
+                  command_bits: EXMC_SQPIPSRAM_COMMAND_LENGTH_xB,x=4,8,16
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct)
+{
+    /* initialize SQPI controller */
+    EXMC_SINIT = (uint32_t)exmc_sqpipsram_init_struct->sample_polarity |
+                           exmc_sqpipsram_init_struct->id_length |
+                           exmc_sqpipsram_init_struct->address_bits |
+                           exmc_sqpipsram_init_struct->command_bits;
+}
+
+/*!
+    \brief      initialize the struct exmc_sqpipsram_parameter_struct
+    \param[in]  the struct exmc_sqpipsram_parameter_struct pointer
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_parameter_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct)
+{
+    /* configure the structure with default value */
+    exmc_sqpipsram_init_struct->sample_polarity = EXMC_SDRAM_SAMPLE_RISING_EDGE;
+    exmc_sqpipsram_init_struct->id_length = EXMC_SQPIPSRAM_ID_LENGTH_64B;
+    exmc_sqpipsram_init_struct->address_bits = EXMC_SQPIPSRAM_ADDR_LENGTH_24B;
+    exmc_sqpipsram_init_struct->command_bits = EXMC_SQPIPSRAM_COMMAND_LENGTH_8B;
+}
+
+/*!
+    \brief      set the read command
+    \param[in]  read_command_mode: configure SPI PSRAM read command mode
+      \arg        EXMC_SQPIPSRAM_READ_MODE_DISABLE: not SPI mode
+      \arg        EXMC_SQPIPSRAM_READ_MODE_SPI: SPI mode
+      \arg        EXMC_SQPIPSRAM_READ_MODE_SQPI: SQPI mode
+      \arg        EXMC_SQPIPSRAM_READ_MODE_QPI: QPI mode
+    \param[in]  read_wait_cycle: wait cycle number after address phase,0..15
+    \param[in]  read_command_code: read command for AHB read transfer
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle,uint32_t read_command_code)
+{
+    uint32_t srcmd;
+    
+    srcmd = (uint32_t) read_command_mode |
+                     ((read_wait_cycle << SRCMD_RWAITCYCLE_OFFSET) & EXMC_SRCMD_RWAITCYCLE) |
+                     ((read_command_code & EXMC_SRCMD_RCMD));
+    EXMC_SRCMD = srcmd;
+}
+
+/*!
+    \brief      set the write command
+    \param[in]  write_command_mode: configure SPI PSRAM write command mode
+      \arg        EXMC_SQPIPSRAM_WRITE_MODE_DISABLE: not SPI mode
+      \arg        EXMC_SQPIPSRAM_WRITE_MODE_SPI: SPI mode
+      \arg        EXMC_SQPIPSRAM_WRITE_MODE_SQPI: SQPI mode
+      \arg        EXMC_SQPIPSRAM_WRITE_MODE_QPI: QPI mode
+    \param[in]  write_wait_cycle: wait cycle number after address phase,0..15
+    \param[in]  write_command_code: read command for AHB read transfer
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle,uint32_t write_command_code)
+{
+    uint32_t swcmd;
+    
+    swcmd = (uint32_t) write_command_mode |
+                     ((write_wait_cycle << SWCMD_WWAITCYCLE_OFFSET) & EXMC_SWCMD_WWAITCYCLE) |
+                     ((write_command_code & EXMC_SWCMD_WCMD));
+    EXMC_SWCMD = swcmd;
+}
+
+/*!
+    \brief      send SPI read ID command
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_read_id_command_send(void)
+{
+    EXMC_SRCMD |= EXMC_SRCMD_RDID;
+}
+
+/*!
+    \brief      send SPI special command which does not have address and data phase
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exmc_sqpipsram_write_cmd_send(void)
+{
+    EXMC_SWCMD |= EXMC_SWCMD_SC;
+}
+
+/*!
+    \brief      get the EXMC SPI ID low data
+    \param[in]  none
+    \param[out] none
+    \retval     the ID low data
+*/
+uint32_t exmc_sqpipsram_low_id_get(void)
+{
+    return (EXMC_SIDL);
+}
+
+/*!
+    \brief      get the EXMC SPI ID high data
+    \param[in]  none
+    \param[out] none
+    \retval     the ID high data
+*/
+uint32_t exmc_sqpipsram_high_id_get(void)
+{
+    return (EXMC_SIDH);
+}
+
+/*!
+    \brief      get the bit value of EXMC send write command bit or read ID command
+    \param[in]  send_command_flag: the send command flag
+      \arg        EXMC_SEND_COMMAND_FLAG_RDID: EXMC_SRCMD_RDID flag bit
+      \arg        EXMC_SEND_COMMAND_FLAG_SC: EXMC_SWCMD_SC flag bit
+    \param[out] none
+    \retval     the new value of send command flag
+*/
+FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag)
+{
+    uint32_t flag = 0x00000000U;
+    
+    if(EXMC_SEND_COMMAND_FLAG_RDID == send_command_flag){
+        flag = EXMC_SRCMD;
+    }else if(EXMC_SEND_COMMAND_FLAG_SC == send_command_flag){
+        flag = EXMC_SWCMD;
+    }else{
+    }
+    
+    if (flag & send_command_flag){
+        /* flag is set */
+        return SET;
+    }else{
+        /* flag is reset */
+        return RESET;
+    }
+}
+
+/*!
+    \brief      check EXMC flag is set or not
+    \param[in]  exmc_bank: specifies the NAND bank , PC card bank or SDRAM device
+      \arg        EXMC_BANK1_NAND: the NAND bank1
+      \arg        EXMC_BANK2_NAND: the NAND bank2
+      \arg        EXMC_BANK3_PCCARD: the PC Card bank
+      \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
+      \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
+    \param[in]  flag: specify get which flag
+      \arg        EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
+      \arg        EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
+      \arg        EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
+      \arg        EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
+      \arg        EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag
+      \arg        EXMC_SDRAM_FLAG_NREADY: not ready status
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag)
+{
+    uint32_t status = 0x00000000U;
+
+    if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){
+        /* NAND bank1,bank2 or PC card bank3 */
+        status = EXMC_NPINTEN(exmc_bank);
+    }else{
+         /* SDRAM device0 or device1 */
+        status = EXMC_SDSTAT;
+    }
+    
+    if ((status & flag) != (uint32_t)flag ){
+        /* flag is reset */
+        return RESET;
+    }else{
+        /* flag is set */
+        return SET;
+    }
+}
+
+/*!
+    \brief      clear EXMC a channel flag
+    \param[in]  exmc_bank: specifie the NAND bank , PCCARD bank or SDRAM device
+      \arg        EXMC_BANK1_NAND: the NAND bank1
+      \arg        EXMC_BANK2_NAND: the NAND bank2
+      \arg        EXMC_BANK3_PCCARD: the PC card bank
+      \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
+      \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
+    \param[in]  flag: specify get which flag
+      \arg        EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
+      \arg        EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
+      \arg        EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
+      \arg        EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
+      \arg        EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag
+      \arg        EXMC_SDRAM_FLAG_NREADY: not ready status
+    \param[out] none
+    \retval     none
+*/
+void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)
+{
+    if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){
+        /* NAND bank1,bank2 or PC card bank3 */
+        EXMC_NPINTEN(exmc_bank) &= ~flag;
+    }else{
+        /* SDRAM device0 or device1 */
+        EXMC_SDSTAT &= ~flag;
+    } 
+}
+
+/*!
+    \brief      check EXMC interrupt flag is set or not
+    \param[in]  exmc_bank: specifies the NAND bank , PC card bank or SDRAM device
+      \arg        EXMC_BANK1_NAND: the NAND bank1
+      \arg        EXMC_BANK2_NAND: the NAND bank2
+      \arg        EXMC_BANK3_PCCARD: the PC card bank
+      \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
+      \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
+    \param[in]  interrupt_source: specify get which interrupt flag
+      \arg        EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
+      \arg        EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
+      \arg        EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
+      \arg        EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt_source)
+{
+    uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U;
+
+    if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){
+        /* NAND bank1,bank2 or PC card bank3 */
+        status = EXMC_NPINTEN(exmc_bank);
+        interrupt_enable = (status & (interrupt_source >> INTEN_INTEN_OFFSET));
+    }else{
+         /* SDRAM device0 or device1 */
+        status = EXMC_SDARI;
+        interrupt_enable = (EXMC_SDSTAT & EXMC_SDSDAT_REIF);
+    }
+
+    interrupt_state = (status & interrupt_source);
+
+    if ((interrupt_enable) && (interrupt_state)){
+        /* interrupt flag is set */
+        return SET;
+    }else{
+        /* interrupt flag is reset */
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear EXMC one channel interrupt flag
+    \param[in]  exmc_bank: specifies the NAND bank , PC card bank or SDRAM device
+      \arg        EXMC_BANK1_NAND: the NAND bank1
+      \arg        EXMC_BANK2_NAND: the NAND bank2
+      \arg        EXMC_BANK3_PCCARD: the PC card bank
+      \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
+      \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
+    \param[in]  interrupt_source: specify get which interrupt flag
+      \arg        EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
+      \arg        EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
+      \arg        EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
+      \arg        EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error
+    \param[out] none
+    \retval     none
+*/
+void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt_source)
+{
+    if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){
+        /* NAND bank1,bank2 or PC card bank3 */
+        EXMC_NPINTEN(exmc_bank) &= ~(interrupt_source >> INTEN_INTEN_OFFSET);
+    }else{
+        /* SDRAM device0 or device1 */
+        EXMC_SDARI |= EXMC_SDARI_REC;
+    }
+}
+
+/*!
+    \brief      enable EXMC interrupt
+    \param[in]  exmc_bank: specifies the NAND bank,PC card bank or SDRAM device
+      \arg        EXMC_BANK1_NAND: the NAND bank1
+      \arg        EXMC_BANK2_NAND: the NAND bank2
+      \arg        EXMC_BANK3_PCCARD: the PC card bank
+      \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
+      \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
+    \param[in]  interrupt_source: specify get which interrupt flag
+      \arg        EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
+      \arg        EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
+      \arg        EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
+      \arg        EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error
+    \param[out] none
+    \retval     none
+*/
+void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt_source)
+{
+    if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){
+        /* NAND bank1,bank2 or PC card bank3 */
+        EXMC_NPINTEN(exmc_bank) |= interrupt_source;
+    }else{
+        /* SDRAM device0 or device1 */
+        EXMC_SDARI |= EXMC_SDARI_REIE;
+    }
+}
+
+/*!
+    \brief      disable EXMC interrupt
+    \param[in]  exmc_bank: specifies the NAND bank , PC card bank or SDRAM device
+      \arg        EXMC_BANK1_NAND: the NAND bank1
+      \arg        EXMC_BANK2_NAND: the NAND bank2
+      \arg        EXMC_BANK3_PCCARD: the PC card bank
+      \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
+      \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
+    \param[in]  interrupt_source: specify get which interrupt flag
+      \arg        EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
+      \arg        EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
+      \arg        EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
+      \arg        EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error
+    \param[out] none
+    \retval     none
+*/
+void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt_source)
+{
+    if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){
+        /* NAND bank1,bank2 or PC card bank3 */
+        EXMC_NPINTEN(exmc_bank) &= ~interrupt_source;
+    }else{
+        /* SDRAM device0 or device1 */
+        EXMC_SDARI &= ~EXMC_SDARI_REIE;
+    }
+}

+ 229 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c

@@ -0,0 +1,229 @@
+/*!
+    \file  gd32f4xx_exti.c
+    \brief EXTI driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_exti.h"
+
+/*!
+    \brief      deinitialize the EXTI
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exti_deinit(void)
+{
+    /* reset the value of all the EXTI registers */
+    EXTI_INTEN = (uint32_t)0x00000000U;
+    EXTI_EVEN  = (uint32_t)0x00000000U;
+    EXTI_RTEN  = (uint32_t)0x00000000U;
+    EXTI_FTEN  = (uint32_t)0x00000000U;
+    EXTI_SWIEV = (uint32_t)0x00000000U;
+}
+
+/*!
+    \brief      initialize the EXTI
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[in]  mode: interrupt or event mode, refer to exti_mode_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_INTERRUPT: interrupt mode
+      \arg        EXTI_EVENT: event mode
+    \param[in]  trig_type: interrupt trigger type, refer to exti_trig_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_TRIG_RISING: rising edge trigger
+      \arg        EXTI_TRIG_FALLING: falling trigger
+      \arg        EXTI_TRIG_BOTH: rising and falling trigger
+    \param[out] none
+    \retval     none
+*/
+void exti_init(exti_line_enum linex, \
+                exti_mode_enum mode, \
+                exti_trig_type_enum trig_type)
+{
+    /* reset the EXTI line x */
+    EXTI_INTEN &= ~(uint32_t)linex;
+    EXTI_EVEN &= ~(uint32_t)linex;
+    EXTI_RTEN &= ~(uint32_t)linex;
+    EXTI_FTEN &= ~(uint32_t)linex;
+    
+    /* set the EXTI mode and enable the interrupts or events from EXTI line x */
+    switch(mode){
+    case EXTI_INTERRUPT:
+        EXTI_INTEN |= (uint32_t)linex;
+        break;
+    case EXTI_EVENT:
+        EXTI_EVEN |= (uint32_t)linex;
+        break;
+    default:
+        break;
+    }
+    
+    /* set the EXTI trigger type */
+    switch(trig_type){
+    case EXTI_TRIG_RISING:
+        EXTI_RTEN |= (uint32_t)linex;
+        EXTI_FTEN &= ~(uint32_t)linex;
+        break;
+    case EXTI_TRIG_FALLING:
+        EXTI_RTEN &= ~(uint32_t)linex;
+        EXTI_FTEN |= (uint32_t)linex;
+        break;
+    case EXTI_TRIG_BOTH:
+        EXTI_RTEN |= (uint32_t)linex;
+        EXTI_FTEN |= (uint32_t)linex;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      enable the interrupts from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_interrupt_enable(exti_line_enum linex)
+{
+    EXTI_INTEN |= (uint32_t)linex;
+}
+
+/*!
+    \brief      enable the events from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_event_enable(exti_line_enum linex)
+{
+    EXTI_EVEN |= (uint32_t)linex;
+}
+
+/*!
+    \brief      disable the interrupt from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_interrupt_disable(exti_line_enum linex)
+{
+    EXTI_INTEN &= ~(uint32_t)linex;
+}
+
+/*!
+    \brief      disable the events from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_event_disable(exti_line_enum linex)
+{
+    EXTI_EVEN &= ~(uint32_t)linex;
+}
+
+/*!
+    \brief      get EXTI lines flag
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     FlagStatus: status of flag (RESET or SET)
+*/
+FlagStatus exti_flag_get(exti_line_enum linex)
+{
+    if(RESET != (EXTI_PD & (uint32_t)linex)){
+        return SET;
+    }else{
+        return RESET;
+    } 
+}
+
+/*!
+    \brief      clear EXTI lines pending flag
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_flag_clear(exti_line_enum linex)
+{
+    EXTI_PD = (uint32_t)linex;
+}
+
+/*!
+    \brief      get EXTI lines flag when the interrupt flag is set
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     FlagStatus: status of flag (RESET or SET)
+*/
+FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
+{
+    uint32_t flag_left, flag_right;
+    
+    flag_left = EXTI_PD & (uint32_t)linex;
+    flag_right = EXTI_INTEN & (uint32_t)linex;
+    
+    if((RESET != flag_left) && (RESET != flag_right)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear EXTI lines pending flag
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_interrupt_flag_clear(exti_line_enum linex)
+{
+    EXTI_PD = (uint32_t)linex;
+}
+
+/*!
+    \brief      enable EXTI software interrupt event
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_software_interrupt_enable(exti_line_enum linex)
+{
+    EXTI_SWIEV |= (uint32_t)linex;
+}
+
+/*!
+    \brief      disable EXTI software interrupt event
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..22): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_software_interrupt_disable(exti_line_enum linex)
+{
+    EXTI_SWIEV &= ~(uint32_t)linex;
+}

+ 824 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c

@@ -0,0 +1,824 @@
+/*!
+    \file  gd32f4xx_fmc.c
+    \brief FMC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_fmc.h"
+
+/*!
+    \brief      set the wait state counter value
+    \param[in]  wscnt£ºwait state counter value
+      \arg        WS_WSCNT_0: FMC 0 wait
+      \arg        WS_WSCNT_1: FMC 1 wait
+      \arg        WS_WSCNT_2: FMC 2 wait
+      \arg        WS_WSCNT_3: FMC 3 wait
+      \arg        WS_WSCNT_4: FMC 4 wait
+      \arg        WS_WSCNT_5: FMC 5 wait
+      \arg        WS_WSCNT_6: FMC 6 wait
+      \arg        WS_WSCNT_7: FMC 7 wait
+      \arg        WS_WSCNT_8: FMC 8 wait
+      \arg        WS_WSCNT_9: FMC 9 wait
+      \arg        WS_WSCNT_10: FMC 10 wait
+      \arg        WS_WSCNT_11: FMC 11 wait
+      \arg        WS_WSCNT_12: FMC 12 wait
+      \arg        WS_WSCNT_13: FMC 13 wait
+      \arg        WS_WSCNT_14: FMC 14 wait
+      \arg        WS_WSCNT_15: FMC 15 wait
+    \param[out] none
+    \retval     none
+*/
+void fmc_wscnt_set(uint32_t wscnt)
+{
+    uint32_t reg;
+    
+    reg = FMC_WS;
+    /* set the wait state counter value */
+    reg &= ~FMC_WC_WSCNT;
+    FMC_WS = (reg | wscnt);
+}
+
+/*!
+    \brief      unlock the main FMC operation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fmc_unlock(void)
+{
+    if((RESET != (FMC_CTL & FMC_CTL_LK))){
+        /* write the FMC key */
+        FMC_KEY = UNLOCK_KEY0;
+        FMC_KEY = UNLOCK_KEY1;
+    }
+}
+
+/*!
+    \brief      lock the main FMC operation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fmc_lock(void)
+{
+    /* set the LK bit*/
+    FMC_CTL |= FMC_CTL_LK;
+}
+
+/*!
+    \brief      erase sector
+    \param[in]  fmc_sector: select the sector to erase
+      \arg        CTL_SECTOR_NUMBER_0: sector 0 
+      \arg        CTL_SECTOR_NUMBER_1: sector 1 
+      \arg        CTL_SECTOR_NUMBER_2: sector 2 
+      \arg        CTL_SECTOR_NUMBER_3: sector 3 
+      \arg        CTL_SECTOR_NUMBER_4: sector 4 
+      \arg        CTL_SECTOR_NUMBER_5: sector 5 
+      \arg        CTL_SECTOR_NUMBER_6: sector 6 
+      \arg        CTL_SECTOR_NUMBER_7: sector 7 
+      \arg        CTL_SECTOR_NUMBER_8: sector 8 
+      \arg        CTL_SECTOR_NUMBER_9: sector 9 
+      \arg        CTL_SECTOR_NUMBER_10: sector 10 
+      \arg        CTL_SECTOR_NUMBER_11: sector 11 
+      \arg        CTL_SECTOR_NUMBER_12: sector 12 
+      \arg        CTL_SECTOR_NUMBER_13: sector 13 
+      \arg        CTL_SECTOR_NUMBER_14: sector 14 
+      \arg        CTL_SECTOR_NUMBER_15: sector 15 
+      \arg        CTL_SECTOR_NUMBER_16: sector 16 
+      \arg        CTL_SECTOR_NUMBER_17: sector 17 
+      \arg        CTL_SECTOR_NUMBER_18: sector 18 
+      \arg        CTL_SECTOR_NUMBER_19: sector 19 
+      \arg        CTL_SECTOR_NUMBER_20: sector 20 
+      \arg        CTL_SECTOR_NUMBER_21: sector 21 
+      \arg        CTL_SECTOR_NUMBER_22: sector 22 
+      \arg        CTL_SECTOR_NUMBER_23: sector 23 
+      \arg        CTL_SECTOR_NUMBER_24: sector 24 
+      \arg        CTL_SECTOR_NUMBER_25: sector 25 
+      \arg        CTL_SECTOR_NUMBER_26: sector 26 
+      \arg        CTL_SECTOR_NUMBER_27: sector 27 
+      \arg        CTL_SECTOR_NUMBER_28: sector 28 
+      \arg        CTL_SECTOR_NUMBER_29: sector 29 
+      \arg        CTL_SECTOR_NUMBER_30: sector 30 
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_sector_erase(uint32_t fmc_sector)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){ 
+        /* start sector erase */
+        FMC_CTL &= ~FMC_CTL_SN;
+        FMC_CTL |= (FMC_CTL_SER | fmc_sector);
+        FMC_CTL |= FMC_CTL_START;
+
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the SER bit */
+        FMC_CTL &= (~FMC_CTL_SER);
+        FMC_CTL &= ~FMC_CTL_SN; 
+    }
+
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      erase whole chip
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_mass_erase(void)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){ 
+        /* start whole chip erase */  
+        FMC_CTL |= (FMC_CTL_MER0 | FMC_CTL_MER1);
+        FMC_CTL |= FMC_CTL_START;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+        /* reset the MER bits */
+        FMC_CTL &= ~(FMC_CTL_MER0 | FMC_CTL_MER1);
+    }
+
+    /* return the fmc state */
+    return fmc_state;
+}
+
+/*!
+    \brief      erase all FMC sectors in bank0
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_bank0_erase(void)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        /* start FMC bank0 erase */
+        FMC_CTL |= FMC_CTL_MER0;
+        FMC_CTL |= FMC_CTL_START;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+        /* reset the MER0 bit */
+        FMC_CTL &= (~FMC_CTL_MER0);
+    }
+
+    /* return the fmc state */
+    return fmc_state;
+}
+
+/*!
+    \brief      erase all FMC sectors in bank1
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_bank1_erase(void)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+   if(FMC_READY == fmc_state){
+        /* start FMC bank1 erase */
+        FMC_CTL |= FMC_CTL_MER1;
+        FMC_CTL |= FMC_CTL_START;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+        /* reset the MER1 bit */
+        FMC_CTL &= (~FMC_CTL_MER1);
+    }
+
+    /* return the fmc state */
+    return fmc_state;
+}
+
+/*!
+    \brief      program a word at the corresponding address
+    \param[in]  address: address to program
+    \param[in]  data: word to program
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_word_program(uint32_t address, uint32_t data)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){
+        /* set the PG bit to start program */
+        FMC_CTL &= ~FMC_CTL_PSZ;
+        FMC_CTL |= CTL_PSZ_WORD;
+        FMC_CTL |= FMC_CTL_PG; 
+  
+        REG32(address) = data;
+
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the PG bit */
+        FMC_CTL &= ~FMC_CTL_PG; 
+    } 
+  
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      program a half word at the corresponding address
+    \param[in]  address: address to program
+    \param[in]  data: halfword to program
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){ 
+        /* set the PG bit to start program */
+        FMC_CTL &= ~FMC_CTL_PSZ;
+        FMC_CTL |= CTL_PSZ_HALF_WORD;
+        FMC_CTL |= FMC_CTL_PG; 
+  
+        REG16(address) = data;
+
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the PG bit */
+        FMC_CTL &= ~FMC_CTL_PG; 
+    } 
+  
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      program a byte at the corresponding address
+    \param[in]  address: address to program
+    \param[in]  data: byte to program
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){
+        /* set the PG bit to start program */
+        FMC_CTL &= ~FMC_CTL_PSZ;
+        FMC_CTL |= CTL_PSZ_BYTE;
+        FMC_CTL |= FMC_CTL_PG;
+  
+        REG8(address) = data;
+
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the PG bit */
+        FMC_CTL &= ~FMC_CTL_PG; 
+    } 
+  
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      unlock the option byte operation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ob_unlock(void)
+{
+    if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_OB_LK)){
+        /* write the FMC key */
+        FMC_OBKEY = OB_UNLOCK_KEY0;
+        FMC_OBKEY = OB_UNLOCK_KEY1;
+    }
+}
+
+/*!
+    \brief      lock the option byte operation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ob_lock(void)
+{
+    /* reset the OB_LK bit */
+    FMC_OBCTL0 &= ~FMC_OBCTL0_OB_LK;
+}
+
+/*!
+    \brief      send option byte change command
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ob_start(void)
+{
+    /* set the OB_START bit in OBCTL0 register */
+    FMC_OBCTL0 |= FMC_OBCTL0_OB_START;
+}
+
+/*!
+    \brief      enable write protection
+    \param[in]  ob_wp: specify sector to be write protected
+      \arg        OB_WPx(x=0..11): write protect specify sector
+      \arg        OB_WP_ALL: write protect all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_write_protection0_enable(uint32_t ob_wp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL0 &= (~((uint32_t)ob_wp << 16));
+    }
+}
+
+/*!
+    \brief      disable write protection
+    \param[in]  ob_wp: specify sector to be write protected
+      \arg        OB_WPx(x=0..11): write protect specify sector
+      \arg        OB_WP_ALL: write protect all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_write_protection0_disable(uint32_t ob_wp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL0 |= ((uint32_t)ob_wp << 16);
+    }
+}
+
+/*!
+    \brief      enable write protection
+    \param[in]  ob_wp: specify sector to be write protected
+      \arg        OB_WPx(x=12..30): write protect specify sector
+      \arg        OB_WP_ALL: write protect all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_write_protection1_enable(uint32_t ob_wp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL1 &= (~((uint32_t)ob_wp << 16));
+    }
+}
+
+/*!
+    \brief      disable write protection
+    \param[in]  ob_wp: specify sector to be write protected
+      \arg        OB_WPx(x=12..30): write protect specify sector
+      \arg        OB_WP_ALL: write protect all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_write_protection1_disable(uint32_t ob_wp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL1 |= ((uint32_t)ob_wp << 16);
+    }
+}
+/*!
+    \brief      configure the protection mode
+    \param[in]  ob_drp: configure the protection mode of WPx bits
+      \arg        OB_DRP_DISABLE: the WPx bits used as erase/program protection of each sector
+      \arg        OB_DRP_ENABLE: the WPx bits used as erase/program protection and D-bus read protection of each sector
+    \param[out] none
+    \retval     none
+*/
+void ob_drp_config(uint32_t ob_drp)
+{
+    FMC_OBCTL0 &= ~FMC_OBCTL0_DRP; 
+    FMC_OBCTL0 |= ob_drp;
+}
+
+/*!
+    \brief      enable erase/program protection and D-bus read protection
+    \param[in]  ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector 
+      \arg        OB_DRPx(x=0..11): erase/program protection and D-bus read protection of specify sector
+      \arg        OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_drp0_enable(uint32_t ob_drp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL0 |= ((uint32_t)ob_drp << 16);
+    }
+}
+
+/*!
+    \brief      disable erase/program protection and D-bus read protection
+    \param[in]  ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector
+      \arg        OB_DRPx(x=0..11): erase/program protection and D-bus read protection of specify sector
+      \arg        OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_drp0_disable(uint32_t ob_drp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL0 &= (~((uint32_t)ob_drp << 16));
+    }
+}
+
+/*!
+    \brief      enable erase/program protection and D-bus read protection
+    \param[in]  ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector 
+      \arg        OB_DRPx(x=12..30): erase/program protection and D-bus read protection of specify sector
+      \arg        OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_drp1_enable(uint32_t ob_drp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL1 |= ((uint32_t)ob_drp << 16);  
+    }
+}
+
+/*!
+    \brief      disable erase/program protection and D-bus read protection
+    \param[in]  ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector
+      \arg        OB_DRPx(x=12..30): erase/program protection and D-bus read protection of specify sector
+      \arg        OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
+    \param[out] none
+    \retval     none
+*/
+void ob_drp1_disable(uint32_t ob_drp)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        FMC_OBCTL1 &= (~((uint32_t)ob_drp << 16));
+    }
+}
+
+/*!
+    \brief      configure security protection level
+    \param[in]  ob_spc: specify security protection level
+      \arg        FMC_NSPC: no security protection
+      \arg        FMC_LSPC: low security protection
+      \arg        FMC_HSPC: high security protection
+    \param[out] none
+    \retval     none
+*/
+void ob_security_protection_config(uint8_t ob_spc)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    if(FMC_READY == fmc_state){
+        uint32_t reg;
+    
+        reg = FMC_OBCTL0;
+        /* reset the OBCTL0_SPC, set according to ob_spc */
+        reg &= ~FMC_OBCTL0_SPC;
+        FMC_OBCTL0 |= ((uint32_t)ob_spc << 8);
+    }
+}
+
+/*!
+    \brief      program the FMC user option byte 
+    \param[in]  ob_fwdgt: option byte watchdog value
+      \arg        OB_FWDGT_SW: software free watchdog
+      \arg        OB_FWDGT_HW: hardware free watchdog
+    \param[in]  ob_deepsleep: option byte deepsleep reset value
+      \arg        OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode
+      \arg        OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode 
+    \param[in]  ob_stdby:option byte standby reset value
+      \arg        OB_STDBY_NRST: no reset when entering standby mode
+      \arg        OB_STDBY_RST: generate a reset instead of entering standby mode 
+    \param[out] none
+    \retval     none
+*/
+void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+
+    /* wait for the FMC ready */
+    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){
+        uint32_t reg;
+    
+        reg = FMC_OBCTL0;
+        /* reset the OB_FWDGT, OB_DEEPSLEEP and OB_STDBY, set according to ob_fwdgt ,ob_deepsleep and ob_stdby */
+        reg &= ~(FMC_OBCTL0_NWDG_HW | FMC_OBCTL0_NRST_DPSLP | FMC_OBCTL0_NRST_STDBY);
+        FMC_OBCTL0 = (reg | ob_fwdgt | ob_deepsleep | ob_stdby);
+    }
+}
+
+/*!
+    \brief      program the option byte BOR threshold value
+    \param[in]  ob_bor_th: user option byte
+      \arg        OB_BOR_TH_VALUE3: BOR threshold value 3
+      \arg        OB_BOR_TH_VALUE2: BOR threshold value 2
+      \arg        OB_BOR_TH_VALUE1: BOR threshold value 1
+      \arg        OB_BOR_TH_OFF: no BOR function.
+    \param[out] none
+    \retval     none
+*/
+void ob_user_bor_threshold(uint32_t ob_bor_th)
+{
+    uint32_t reg;
+    
+    reg = FMC_OBCTL0;
+    /* set the BOR level */
+    reg &= ~FMC_OBCTL0_BOR_TH;
+    FMC_OBCTL0 = (reg | ob_bor_th);
+}
+
+/*!
+    \brief      configure the option byte boot bank value
+    \param[in]  boot_mode: specifies the option byte boot bank value
+      \arg        OB_BB_DISABLE: boot from bank0
+      \arg        OB_BB_ENABLE: boot from bank1 or bank0 if bank1 is void
+    \param[out] none
+    \retval     none
+*/
+void ob_boot_mode_config(uint32_t boot_mode)
+{
+    uint32_t reg;
+    
+    reg = FMC_OBCTL0;
+    /* set option byte boot bank value */
+    reg &= ~FMC_OBCTL0_BB;
+    FMC_OBCTL0 = (reg | boot_mode);
+}
+
+/*!
+    \brief      get the FMC user option byte
+    \param[in]  none
+    \param[out] none
+    \retval     the FMC user option byte values: ob_fwdgt(Bit0), ob_deepsleep(Bit1), ob_stdby(Bit2).
+*/
+uint8_t ob_user_get(void)
+{
+    return (uint8_t)((uint8_t)(FMC_OBCTL0 >> 5) & (uint8_t)0x07);
+}
+
+/*!
+    \brief      get the FMC option byte write protection
+    \param[in]  none
+    \param[out] none
+    \retval     the FMC write protection option byte value
+*/
+uint16_t ob_write_protection0_get(void)
+{
+    /* return the FMC write protection option byte value */
+    return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF);
+}
+
+/*!
+    \brief      get the FMC option byte write protection
+    \param[in]  none
+    \param[out] none
+    \retval     the FMC write protection option byte value
+*/
+uint16_t ob_write_protection1_get(void)
+{
+    /* return the the FMC write protection option byte value */
+    return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF);
+}
+
+/*!
+    \brief      get the FMC D-bus read protection protection
+    \param[in]  none
+    \param[out] none
+    \retval     the FMC erase/program protection and D-bus read protection option bytes value
+*/
+uint16_t ob_drp0_get(void)
+{
+    /* return the FMC erase/program protection and D-bus read protection option bytes value */
+    return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF);
+}
+
+/*!
+    \brief      get the FMC D-bus read protection protection
+    \param[in]  none
+    \param[out] none
+    \retval     the FMC erase/program protection and D-bus read protection option bytes value
+*/
+uint16_t ob_drp1_get(void)
+{
+    /* return the FMC erase/program protection and D-bus read protection option bytes value */
+    return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF);
+}
+
+/*!
+    \brief      get the FMC option byte security protection
+    \param[in]  none
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus ob_spc_get(void)
+{
+    FlagStatus spc_state = RESET;
+  
+    if (((uint8_t)(FMC_OBCTL0 >> 8)) != (uint8_t)FMC_NSPC){
+        spc_state = SET;
+    }else{
+        spc_state = RESET;
+    }
+    return spc_state;
+}
+
+/*!
+    \brief      get the FMC option byte BOR threshold value
+    \param[in]  none
+    \param[out] none
+    \retval     the FMC BOR threshold value:OB_BOR_TH_OFF,OB_BOR_TH_VALUE1,OB_BOR_TH_VALUE2,OB_BOR_TH_VALUE3
+*/
+uint8_t ob_user_bor_threshold_get(void)
+{
+    /* return the FMC BOR threshold value */
+    return (uint8_t)((uint8_t)FMC_OBCTL0 & (uint8_t)0x0C);
+}
+
+/*!
+    \brief      enable FMC interrupt
+    \param[in]  the FMC interrupt source
+      \arg        FMC_INTEN_END: enable FMC end of program interrupt
+      \arg        FMC_INTEN_ERR: enable FMC error interrupt
+    \param[out] none
+    \retval     none
+*/
+void fmc_interrupt_enable(uint32_t fmc_int)
+{
+    FMC_CTL |= fmc_int;
+}
+
+/*!
+    \brief      disable FMC interrupt
+    \param[in]  the FMC interrupt source
+      \arg        FMC_INTEN_END: disable FMC end of program interrupt
+      \arg        FMC_INTEN_ERR: disable FMC error interrupt
+    \param[out] none
+    \retval     none
+*/
+void fmc_interrupt_disable(uint32_t fmc_int)
+{
+    FMC_CTL &= ~(uint32_t)fmc_int;
+}
+
+/*!
+    \brief      get flag set or reset
+    \param[in]  fmc_flag: check FMC flag
+      \arg        FMC_FLAG_BUSY: FMC busy flag
+      \arg        FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit
+      \arg        FMC_FLAG_PGSERR: FMC program sequence error flag bit
+      \arg        FMC_FLAG_PGMERR: FMC program size not match error flag bit
+      \arg        FMC_FLAG_WPERR: FMC Erase/Program protection error flag bit
+      \arg        FMC_FLAG_OPERR: FMC operation error flag bit 
+      \arg        FMC_FLAG_END: FMC end of operation flag bit
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus fmc_flag_get(uint32_t fmc_flag)
+{
+    if(FMC_STAT & fmc_flag){
+        return  SET;
+    }
+    /* return the state of corresponding FMC flag */
+    return RESET; 
+}
+
+/*!
+    \brief      clear the FMC pending flag
+    \param[in]  FMC_flag: clear FMC flag
+      \arg        FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit
+      \arg        FMC_FLAG_PGSERR: FMC program sequence error flag bit
+      \arg        FMC_FLAG_PGMERR: FMC program size not match error flag bit
+      \arg        FMC_FLAG_WPERR: FMC erase/program protection error flag bit
+      \arg        FMC_FLAG_OPERR: FMC operation error flag bit 
+      \arg        FMC_FLAG_END: FMC end of operation flag bit
+    \param[out] none
+    \retval     none
+*/
+void fmc_flag_clear(uint32_t fmc_flag)
+{
+    /* clear the flags */
+    FMC_STAT = fmc_flag;
+}
+
+/*!
+    \brief      get the FMC state
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_state_get(void)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+  
+    if((FMC_STAT & FMC_FLAG_BUSY) == FMC_FLAG_BUSY){
+        fmc_state = FMC_BUSY;
+    }else{
+        if((FMC_STAT & FMC_FLAG_WPERR) != (uint32_t)0x00){ 
+            fmc_state = FMC_WPERR;
+        }else{
+            if((FMC_STAT & FMC_FLAG_RDDERR) != (uint32_t)0x00){ 
+                fmc_state = FMC_RDDERR;
+            }else{
+                if((FMC_STAT & (uint32_t)0xEF) != (uint32_t)0x00){
+                    fmc_state = FMC_PGERR; 
+                }else{
+                    if((FMC_STAT & FMC_FLAG_OPERR) != (uint32_t)0x00){
+                        fmc_state = FMC_OPERR;
+                    }else{
+                        fmc_state = FMC_READY;
+                    }
+                }
+            }
+        }
+    }
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      check whether FMC is ready or not
+    \param[in]  count: FMC_TIMEOUT_COUNT
+    \param[out] none
+    \retval     fmc_state_enum
+*/
+fmc_state_enum fmc_ready_wait(uint32_t count)
+{
+    fmc_state_enum fmc_state = FMC_BUSY;
+  
+    /* wait for FMC ready */
+    do{
+        /* get FMC state */
+        fmc_state = fmc_state_get();
+        count--;
+    }while((FMC_BUSY == fmc_state) && ((uint32_t)RESET != count));
+  
+    if(FMC_BUSY == fmc_state){
+        fmc_state = FMC_TOERR;
+    }
+    /* return the FMC state */
+    return fmc_state;
+}

+ 120 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c

@@ -0,0 +1,120 @@
+/*!
+    \file  gd32f4xx_fwdgt.c
+    \brief FWDGT driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_fwdgt.h"
+
+/* write value to FWDGT_CTL_CMD bit field */
+#define CTL_CMD(regval)             (BITS(0,15) & ((uint32_t)(regval) << 0))
+/* write value to FWDGT_RLD_RLD bit field */
+#define RLD_RLD(regval)             (BITS(0,11) & ((uint32_t)(regval) << 0))
+
+/*!
+    \brief      disable write access to FWDGT_PSC and FWDGT_RLD
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_write_disable(void)
+{
+    FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE;
+}
+
+/*!
+    \brief      reload the counter of FWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_counter_reload(void)
+{
+    FWDGT_CTL = FWDGT_KEY_RELOAD;
+}
+
+/*!
+    \brief      start the free watchdog timer counter
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_enable(void)
+{
+    FWDGT_CTL = FWDGT_KEY_ENABLE;
+}
+
+
+/*!
+    \brief      configure counter reload value, and prescaler divider value
+    \param[in]  reload_value: specify reload value(0x0000 - 0x0FFF)
+    \param[in]  prescaler_div: FWDGT prescaler value
+      \arg        FWDGT_PSC_DIV4: FWDGT prescaler set to 4
+      \arg        FWDGT_PSC_DIV8: FWDGT prescaler set to 8
+      \arg        FWDGT_PSC_DIV16: FWDGT prescaler set to 16
+      \arg        FWDGT_PSC_DIV32: FWDGT prescaler set to 32
+      \arg        FWDGT_PSC_DIV64: FWDGT prescaler set to 64
+      \arg        FWDGT_PSC_DIV128: FWDGT prescaler set to 128
+      \arg        FWDGT_PSC_DIV256: FWDGT prescaler set to 256
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div)
+{
+    uint32_t timeout = FWDGT_PSC_TIMEOUT;
+    uint32_t flag_status = RESET;
+  
+    /* enable write access to FWDGT_PSC,and FWDGT_RLD */
+    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+  
+    /* wait until the PUD flag to be reset */
+    do{
+       flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
+    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
+    
+    if ((uint32_t)RESET != flag_status){
+        return ERROR;
+    }
+
+    /* configure FWDGT */
+    FWDGT_PSC = (uint32_t)prescaler_div;
+
+    timeout = FWDGT_RLD_TIMEOUT;
+    /* wait until the RUD flag to be reset */
+    do{
+       flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
+    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
+   
+    if ((uint32_t)RESET != flag_status){
+        return ERROR;
+    }
+    
+    FWDGT_RLD = RLD_RLD(reload_value);
+    
+    /* reload the counter */
+    FWDGT_CTL = FWDGT_KEY_RELOAD;
+
+    return SUCCESS;
+}
+
+/*!
+    \brief      get flag state of FWDGT
+    \param[in]  flag: flag to get 
+      \arg        FWDGT_STAT_PUD: a write operation to FWDGT_PSC register is on going
+      \arg        FWDGT_STAT_RUD: a write operation to FWDGT_RLD register is on going
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus fwdgt_flag_get(uint16_t flag)
+{
+  if(FWDGT_STAT & flag){
+        return SET;
+  }
+
+    return RESET;
+}

+ 357 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c

@@ -0,0 +1,357 @@
+/*!
+    \file  gd32f4xx_gpio.c
+    \brief GPIO driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_gpio.h"
+
+/*!
+    \brief      reset GPIO port
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I)
+    \param[out] none
+    \retval     none
+*/
+void gpio_deinit(uint32_t gpio_periph)
+{
+    switch(gpio_periph){
+    case GPIOA:
+        /* reset GPIOA */
+        rcu_periph_reset_enable(RCU_GPIOARST);
+        rcu_periph_reset_disable(RCU_GPIOARST);
+        break;
+    case GPIOB:
+        /* reset GPIOB */
+        rcu_periph_reset_enable(RCU_GPIOBRST);
+        rcu_periph_reset_disable(RCU_GPIOBRST);
+        break;
+    case GPIOC:
+        /* reset GPIOC */
+        rcu_periph_reset_enable(RCU_GPIOCRST);
+        rcu_periph_reset_disable(RCU_GPIOCRST);
+        break;
+    case GPIOD:
+        /* reset GPIOD */
+        rcu_periph_reset_enable(RCU_GPIODRST);
+        rcu_periph_reset_disable(RCU_GPIODRST);
+        break;
+    case GPIOE:
+        /* reset GPIOE */
+        rcu_periph_reset_enable(RCU_GPIOERST);
+        rcu_periph_reset_disable(RCU_GPIOERST);
+        break;
+    case GPIOF:
+        /* reset GPIOF */
+        rcu_periph_reset_enable(RCU_GPIOFRST);
+        rcu_periph_reset_disable(RCU_GPIOFRST);
+        break;
+    case GPIOG:
+        /* reset GPIOG */
+        rcu_periph_reset_enable(RCU_GPIOGRST);
+        rcu_periph_reset_disable(RCU_GPIOGRST);
+        break;
+    case GPIOH:
+        /* reset GPIOH */
+        rcu_periph_reset_enable(RCU_GPIOHRST);
+        rcu_periph_reset_disable(RCU_GPIOHRST);
+        break;
+    case GPIOI:
+        /* reset GPIOI */
+        rcu_periph_reset_enable(RCU_GPIOIRST);
+        rcu_periph_reset_disable(RCU_GPIOIRST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      set GPIO output mode
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  mode: gpio pin mode
+      \arg        GPIO_MODE_INPUT: input mode
+      \arg        GPIO_MODE_OUTPUT: output mode
+      \arg        GPIO_MODE_AF: alternate function mode
+      \arg        GPIO_MODE_ANALOG: analog mode
+    \param[in]  pull_up_down: gpio pin with pull-up or pull-down resistor
+      \arg        GPIO_PUPD_NONE: without weak pull-up and pull-down resistors
+      \arg        GPIO_PUPD_PULLUP: with weak pull-up resistor
+      \arg        GPIO_PUPD_PULLDOWN:with weak pull-down resistor
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin)
+{
+    uint16_t i;
+    uint32_t ctl, pupd;
+
+    ctl = GPIO_CTL(gpio_periph);
+    pupd = GPIO_PUD(gpio_periph);
+
+    for(i = 0U;i < 16U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin mode bits */
+            ctl &= ~GPIO_MODE_MASK(i);
+            /* set the specified pin mode bits */
+            ctl |= GPIO_MODE_SET(i, mode);
+
+            /* clear the specified pin pupd bits */
+            pupd &= ~GPIO_PUPD_MASK(i);
+            /* set the specified pin pupd bits */
+            pupd |= GPIO_PUPD_SET(i, pull_up_down);
+        }
+    }
+
+    GPIO_CTL(gpio_periph) = ctl;
+    GPIO_PUD(gpio_periph) = pupd;
+}
+
+/*!
+    \brief      set GPIO output type and speed
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  otype: gpio pin output mode
+      \arg        GPIO_OTYPE_PP: push pull mode
+      \arg        GPIO_OTYPE_OD: open drain mode
+    \param[in]  speed: gpio pin output max speed
+      \arg        GPIO_OSPEED_2MHZ: output max speed 2M 
+      \arg        GPIO_OSPEED_25MHZ: output max speed 25M 
+      \arg        GPIO_OSPEED_50MHZ: output max speed 50M
+      \arg        GPIO_OSPEED_200MHZ: output max speed 200M
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin)
+{
+    uint16_t i;
+    uint32_t ospeedr;
+
+    if(0x1U == otype){
+        GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
+    }else{
+        GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
+    }
+
+    /* get the specified pin output speed bits value */
+    ospeedr = GPIO_OSPD(gpio_periph);
+
+    for(i = 0U;i < 16U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin output speed bits */
+            ospeedr &= ~GPIO_OSPEED_MASK(i);
+            /* set the specified pin output speed bits */
+            ospeedr |= GPIO_OSPEED_SET(i,speed);
+        }
+    }
+    GPIO_OSPD(gpio_periph) = ospeedr;
+}
+
+/*!
+    \brief      set GPIO pin
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_set(uint32_t gpio_periph,uint32_t pin)
+{
+    GPIO_BOP(gpio_periph) = (uint32_t)pin;
+}
+
+/*!
+    \brief      reset GPIO pin
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)
+{
+    GPIO_BC(gpio_periph) = (uint32_t)pin;
+}
+
+/*!
+    \brief      write data to the specified GPIO pin
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[in]  bitvalue: SET or RESET
+      \arg        RESET: clear the port pin
+      \arg        SET: set the port pin
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value)
+{
+    if(RESET != bit_value){
+        GPIO_BOP(gpio_periph) = (uint32_t)pin;
+    }else{
+        GPIO_BC(gpio_periph) = (uint32_t)pin;
+    }
+}
+
+/*!
+    \brief      write data to the specified GPIO port
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  data: specify the value to be written to the port output data register
+    \param[out] none
+    \retval     none
+*/
+void gpio_port_write(uint32_t gpio_periph,uint16_t data)
+{
+    GPIO_OCTL(gpio_periph) = (uint32_t)data;
+}
+
+/*!
+    \brief      get GPIO pin input status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     input state of gpio pin: SET or RESET
+*/
+FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
+{
+    if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
+        return SET; 
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      get GPIO all pins input status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[out] none
+    \retval     input state of gpio all pins
+*/
+uint16_t gpio_input_port_get(uint32_t gpio_periph)
+{
+    return (uint16_t)(GPIO_ISTAT(gpio_periph));
+}
+
+/*!
+    \brief      get GPIO pin output status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     output state of gpio pin: SET or RESET
+*/
+FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin)
+{
+    if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      get GPIO all pins output status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[out] none
+    \retval     output state of gpio all pins
+*/
+uint16_t gpio_output_port_get(uint32_t gpio_periph)
+{
+    return ((uint16_t)GPIO_OCTL(gpio_periph));
+}
+
+/*!
+    \brief      set GPIO alternate function
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  alt_func_num: gpio pin af function
+      \arg        GPIO_AF_0: SYSTEM
+      \arg        GPIO_AF_1: TIMER0, TIMER1
+      \arg        GPIO_AF_2: TIMER2, TIMER3, TIMER4
+      \arg        GPIO_AF_3: TIMER7, TIMER8, TIMER9, TIMER10
+      \arg        GPIO_AF_4: I2C0, I2C1, I2C2
+      \arg        GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5
+      \arg        GPIO_AF_6: SPI1, SPI2, SAI0 
+      \arg        GPIO_AF_7: USART0, USART1, USART2
+      \arg        GPIO_AF_8: UART3, UART4, USART5, UART6, UART7
+      \arg        GPIO_AF_9: CAN0,CAN1, TLI, TIMER11, TIMER12, TIMER13
+      \arg        GPIO_AF_10: USB_FS, USB_HS
+      \arg        GPIO_AF_11: ENET
+      \arg        GPIO_AF_12: FMC, SDIO, USB_HS
+      \arg        GPIO_AF_13: DCI
+      \arg        GPIO_AF_14: TLI
+      \arg        GPIO_AF_15: EVENTOUT
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin)
+{
+    uint16_t i;
+    uint32_t afrl, afrh;
+
+    afrl = GPIO_AFSEL0(gpio_periph);
+    afrh = GPIO_AFSEL1(gpio_periph);
+
+    for(i = 0U;i < 8U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin alternate function bits */
+            afrl &= ~GPIO_AFR_MASK(i);
+            afrl |= GPIO_AFR_SET(i,alt_func_num);
+        }
+    }
+
+    for(i = 8U;i < 16U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin alternate function bits */
+            afrh &= ~GPIO_AFR_MASK(i - 8U);
+            afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
+        }
+    }
+
+    GPIO_AFSEL0(gpio_periph) = afrl;
+    GPIO_AFSEL1(gpio_periph) = afrh;
+}
+
+/*!
+    \brief      lock GPIO pin
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)
+{
+    uint32_t lock = 0x00010000U;
+    lock |= pin;
+
+    /* lock key writing sequence: write 1->write 0->write 1-> read 0-> read 1 */
+    GPIO_LOCK(gpio_periph) = (uint32_t)lock;
+    GPIO_LOCK(gpio_periph) = (uint32_t)pin;
+    GPIO_LOCK(gpio_periph) = (uint32_t)lock;
+    lock = GPIO_LOCK(gpio_periph);
+    lock = GPIO_LOCK(gpio_periph);
+}
+
+/*!
+    \brief      toggle GPIO pin
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) 
+    \param[in]  pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_toggle(uint32_t gpio_periph,uint32_t pin)
+{
+    GPIO_TG(gpio_periph) = (uint32_t)pin;
+}
+
+/*!
+    \brief      toggle GPIO port
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I)
+    \param[out] none
+    \retval     none
+*/
+void gpio_port_toggle(uint32_t gpio_periph)
+{
+    GPIO_TG(gpio_periph) = 0x0000FFFFU;
+}

+ 730 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c

@@ -0,0 +1,730 @@
+/*!
+    \file  gd32f4xx_i2c.c
+    \brief I2C driver
+
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_i2c.h"
+
+#define I2CCLK_MAX                    0x3fU              /*!< i2cclk max value */
+#define I2C_STATE_MASK                0x0000FFFFU        /*!< i2c state mask */
+
+/*!
+    \brief      reset I2C
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_deinit(uint32_t i2c_periph)
+{
+    switch(i2c_periph){
+    case I2C0:
+        rcu_periph_reset_enable(RCU_I2C0RST);
+        rcu_periph_reset_disable(RCU_I2C0RST);
+        break;
+    case I2C1:
+        rcu_periph_reset_enable(RCU_I2C1RST);
+        rcu_periph_reset_disable(RCU_I2C1RST);
+        break;
+    case I2C2:
+        rcu_periph_reset_enable(RCU_I2C2RST);
+        rcu_periph_reset_disable(RCU_I2C2RST);
+        break;
+    default:
+        break;
+    
+    }
+}
+
+/*!
+    \brief      I2C clock configure
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  clkspeed: i2c clock speed   
+    \param[in]  dutycyc: duty cycle in fast mode
+      \arg        I2C_DTCY_2:    T_low/T_high=2 
+      \arg        I2C_DTCY_16_9: T_low/T_high=16/9
+    \param[out] none
+    \retval     none
+*/
+void i2c_clock_config(uint32_t i2c_periph,uint32_t clkspeed,uint32_t dutycyc)
+{
+    uint32_t pclk1,clkc,i2cclk,risetime;
+    pclk1 = rcu_clock_freq_get(CK_APB1);
+    /* I2C Peripheral clock frequency */
+    i2cclk=((pclk1)/(uint32_t)(1000000));
+    if(i2cclk >= I2CCLK_MAX){
+        i2cclk = I2CCLK_MAX;
+    }
+        
+    I2C_CTL1(i2c_periph) |= (I2C_CTL1_I2CCLK & i2cclk) ;
+    
+    if(100000U >= clkspeed){
+         /* standard mode the maximum SCL rise time in standard mode is 1000ns  */
+        risetime = (uint32_t)((pclk1/1000000U)+1U);
+        if(risetime >= I2CCLK_MAX){
+            I2C_RT(i2c_periph) |= I2CCLK_MAX;
+        }else{
+            I2C_RT(i2c_periph) |= (uint32_t)((pclk1/1000000U)+1U);
+        }
+        clkc = (uint32_t)(pclk1/(clkspeed*2U));
+        if(clkc < 0x04U){
+            /* The CLKC in standard mode minmum value is 4*/
+            clkc = 0x04U;
+        }
+        I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc);        
+
+    }else{
+        /* fast mode the maximum SCL rise time in standard mode is 300ns  */
+        I2C_RT(i2c_periph) |= (uint16_t)(((i2cclk*(uint16_t)300)/(uint16_t)1000)+(uint16_t)1);
+        if(I2C_DTCY_2 == dutycyc){
+            /* I2C_DutyCycle == 2 */
+            clkc = (uint16_t)(pclk1/(clkspeed*3U));
+        } else{
+            /* I2C_DutyCycle == 16/9 */
+            clkc = (uint16_t)(pclk1/(clkspeed*25U));
+            I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
+        }
+        if((clkc & I2C_CKCFG_CLKC) == 0U){
+            /* The CLKC in standard mode minmum value is 1*/
+            clkc |= (uint16_t)0x0001;  
+        }
+        I2C_CKCFG(i2c_periph) |= clkc;
+    }
+}
+
+/*!
+    \brief      I2C address configure
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  i2cmod:
+      \arg        I2C_I2CMODE_ENABLE:  I2C mode
+      \arg        I2C_SMBUSMODE_ENABLE: SMBus mode
+    \param[in]  addformat: 7bits or 10bits
+      \arg        I2C_ADDFORMAT_7BITS:  7bits
+      \arg        I2C_ADDFORMAT_10BITS: 10bits
+    \param[in]  addr: I2C address
+    \param[out] none
+    \retval     none
+*/
+void i2c_mode_addr_config(uint32_t i2c_periph,uint32_t i2cmod,uint32_t addformat,uint32_t addr)
+{
+    /* SMBus/I2C mode selected */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SMBEN); 
+    ctl |= i2cmod;
+    I2C_CTL0(i2c_periph) = ctl;
+    /* configure address */
+    I2C_SADDR0(i2c_periph) = (addformat|addr);
+    
+}
+
+/*!
+    \brief      SMBus type selection
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  ack:
+      \arg        I2C_SMBUS_DEVICE: device
+      \arg        I2C_SMBUS_HOST: host
+    \param[out] none
+    \retval     none
+*/
+void i2c_smbus_type_config(uint32_t i2c_periph,uint32_t type)
+{
+    if(I2C_SMBUS_HOST == type){
+       I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL;  
+    }else{
+       I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL);  
+    } 
+}
+
+/*!
+    \brief      whether or not to send an ACK
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  ack:
+      \arg        I2C_ACK_ENABLE: ACK will be sent  
+      \arg        I2C_ACK_DISABLE: ACK will not be sent    
+    \param[out] none
+    \retval     none
+*/
+void i2c_ack_config(uint32_t i2c_periph,uint8_t ack)
+{
+    if(I2C_ACK_ENABLE == ack){
+       I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN;  
+    }else{
+       I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN);  
+    } 
+}
+
+/*!
+    \brief      I2C POAP position configure
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  pos:
+      \arg        I2C_ACK_ENABLE: ACK will be sent  
+      \arg        I2C_ACK_DISABLE: ACK will not be sent
+    \param[out] none
+    \retval     none
+*/
+void i2c_ackpos_config(uint32_t i2c_periph,uint8_t pos)
+{
+    /* configure i2c POAP position */
+    if(I2C_ACKPOS_NEXT == pos){
+       I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP;  
+    }else{
+       I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP);  
+    } 
+
+}
+
+/*!
+    \brief      master send slave address
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  addr: slave address  
+    \param[in]  trandirection: transmitter or receiver
+      \arg        I2C_TRANSMITTER: transmitter  
+      \arg        I2C_RECEIVER:    receiver  
+    \param[out] none
+    \retval     none
+*/
+void i2c_master_addressing(uint32_t i2c_periph,uint8_t addr,uint32_t trandirection)
+{
+    if(I2C_TRANSMITTER==trandirection){
+        addr = (uint8_t)((uint32_t)addr & I2C_TRANSMITTER);
+    }else{
+        addr = (uint8_t)((uint32_t)addr|I2C_RECEIVER);
+    }
+    I2C_DATA(i2c_periph) = addr;
+}
+
+/*!
+    \brief      dual-address mode switch
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  dualaddr:
+      \arg        I2C_DUADEN_DISABLE: dual-address mode disabled  
+      \arg        I2C_DUADEN_ENABLE: dual-address mode enabled
+    \param[out] none
+    \retval     none
+*/
+void i2c_dualaddr_enable(uint32_t i2c_periph,uint8_t dualaddr)
+{
+    if(I2C_DUADEN_ENABLE == dualaddr){
+       I2C_SADDR1(i2c_periph) |= I2C_SADDR1_DUADEN;  
+    }else{
+       I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN);  
+    }        
+}
+
+/*!
+    \brief      enable i2c
+    \param[in]  i2c_periph: I2Cx(x=0,1,2) 
+    \param[out] none
+    \retval     none
+*/
+void i2c_enable(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
+}
+
+/*!
+    \brief      disable i2c
+    \param[in]  i2c_periph: I2Cx(x=0,1,2) 
+    \param[out] none
+    \retval     none
+*/
+void i2c_disable(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN);
+    
+}
+
+/*!
+    \brief      generate a START condition on I2C bus
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_start_on_bus(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) |= I2C_CTL0_START;
+}
+
+/*!
+    \brief      generate a STOP condition on I2C bus
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_stop_on_bus(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP;
+}
+
+/*!
+    \brief      i2c transmit data function
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  data: data of transmission 
+    \param[out] none
+    \retval     none
+*/
+void i2c_transmit_data(uint32_t i2c_periph,uint8_t data)
+{
+    I2C_DATA(i2c_periph) = data;
+}
+
+/*!
+    \brief      i2c receive data function
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     data of received
+*/
+uint8_t i2c_receive_data(uint32_t i2c_periph)
+{
+    return (uint8_t)I2C_DATA(i2c_periph); 
+}
+
+/*!
+    \brief      I2C DMA mode enable
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  dmastste: 
+      \arg        I2C_DMA_ON: DMA mode enabled
+      \arg        I2C_DMA_OFF: DMA mode disabled
+    \param[out] none
+    \retval     none
+*/
+void i2c_dma_enable(uint32_t i2c_periph,uint32_t dmastste)
+{
+    /* configure i2c DMA function */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL1(i2c_periph);
+    ctl &= ~(I2C_CTL1_DMAON); 
+    ctl |= dmastste;
+    I2C_CTL1(i2c_periph) = ctl;
+
+}
+
+/*!
+    \brief      flag indicating DMA last transfer
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  dmastste: 
+      \arg        I2C_DMALST_ON: next DMA EOT is the last transfer
+      \arg        I2C_DMALST_OFF: next DMA EOT is not the last transfer
+    \param[out] none
+    \retval     none
+*/
+void i2c_dma_last_transfer_enable(uint32_t i2c_periph,uint32_t dmalast)
+{
+    /* configure DMA last transfer */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL1(i2c_periph);
+    ctl &= ~(I2C_CTL1_DMALST); 
+    ctl |= dmalast;
+    I2C_CTL1(i2c_periph) = ctl;
+
+}
+
+/*!
+    \brief      whether to stretch SCL low when data is not ready in slave mode 
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  stretchpara:
+      \arg        I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled
+      \arg        I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled
+    \param[out] none
+    \retval     none
+*/
+void i2c_stretch_scl_low_config(uint32_t i2c_periph,uint32_t stretchpara)
+{
+    /* configure I2C SCL strerching enable or disable */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_DISSTRC); 
+    ctl |= stretchpara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      whether or not to response to a general Cal 
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  gcallpara:
+      \arg        I2C_GCEN_ENABLE: slave will response to a general call
+      \arg        I2C_GCEN_DISABLE: slave will not response to a general call
+    \param[out] none
+    \retval     none
+*/
+void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara)
+{
+    /* configure slave response to a general call enable or disable */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_GCEN); 
+    ctl |= gcallpara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      software reset I2C 
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  sreset:
+      \arg        I2C_SRESET_SET: I2C is under reset
+      \arg        I2C_SRESET_RESET: I2C is not under reset
+    \param[out] none
+    \retval     none
+*/
+void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset)
+{
+    /* modify CTL0 and configure software reset I2C state */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SRESET); 
+    ctl |= sreset;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      check i2c state
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  state:
+      \arg        I2C_SBSEND: start condition send out 
+      \arg        I2C_ADDSEND: address is sent in master mode or received and matches in slave mode
+      \arg        I2C_BTC: byte transmission finishes
+      \arg        I2C_ADD10SEND: header of 10-bit address is sent in master mode
+      \arg        I2C_STPDET: etop condition detected in slave mode
+      \arg        I2C_RBNE: I2C_DATA is not Empty during receiving
+      \arg        I2C_TBE: I2C_DATA is empty during transmitting
+      \arg        I2C_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
+      \arg        I2C_LOSTARB: arbitration lost in master mode
+      \arg        I2C_AERR: acknowledge error
+      \arg        I2C_OUERR: over-run or under-run situation occurs in slave mode
+      \arg        I2C_PECERR: PEC error when receiving data
+      \arg        I2C_SMBTO: timeout signal in SMBus mode
+      \arg        I2C_SMBALT: SMBus alert status
+      \arg        I2C_MASTER: a flag indicating whether I2C block is in master or slave mode
+      \arg        I2C_I2CBSY: busy flag
+      \arg        I2C_TRS: whether the I2C is a transmitter or a receiver
+      \arg        I2C_RXGC: general call address (00h) received
+      \arg        I2C_DEFSMB: default address of SMBus device
+      \arg        I2C_HSTSMB: SMBus host header detected in slave mode
+      \arg        I2C_DUMODF: dual flag in slave mode indicating which address is matched in dual-address mode
+    \param[out] none
+    \retval     state of i2c
+*/
+FlagStatus i2c_flag_get(uint32_t i2c_periph,uint32_t state )
+{
+    uint32_t reg = 0U;
+    FlagStatus regstate = RESET;
+    /* get the state in which register */
+    reg = (BIT(31) & state);
+    if((BIT(31) == reg)){
+        if((I2C_STAT1(i2c_periph)&(state & I2C_STATE_MASK))){
+            regstate = SET;
+        }else{
+            regstate = RESET;
+        }
+    }else{
+        if((I2C_STAT0(i2c_periph)&(state & I2C_STATE_MASK))){
+            regstate = SET;
+        }else{
+            regstate = RESET;
+        }        
+    }
+    /* return the state */
+    return regstate;
+}
+
+/*!
+    \brief      clear i2c state
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  state: state type 
+      \@arg       I2C_STAT0_SMBALT: SMBus Alert status
+      \@arg       I2C_STAT0_SMBTO: timeout signal in SMBus mode
+      \@arg       I2C_STAT0_PECERR: PEC error when receiving data
+      \@arg       I2C_STAT0_OUERR: over-run or under-run situation occurs in slave mode    
+      \@arg       I2C_STAT0_AERR: acknowledge error
+      \@arg       I2C_STAT0_LOSTARB: arbitration lost in master mode   
+      \@arg       I2C_STAT0_BERR: a bus error   
+      \@arg       I2C_STAT0_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1
+    \param[out] none
+    \retval     none
+*/
+void i2c_flag_clear(uint32_t i2c_periph,uint32_t state)
+{
+    if(I2C_STAT0_ADDSEND == state){
+        /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
+        I2C_STAT0(i2c_periph);
+        I2C_STAT1(i2c_periph);
+    }else{
+        I2C_STAT0(i2c_periph) &= ~(state);
+    }
+}
+
+/*!
+    \brief      enable i2c interrupt
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  inttype:      interrupt type 
+      \arg        I2C_CTL1_ERRIE: error interrupt enable 
+      \arg        I2C_CTL1_EVIE:  event interrupt enable 
+      \arg        I2C_CTL1_BUFIE: buffer interrupt enable   
+    \param[out] none
+    \retval     none
+*/
+void i2c_interrupt_enable(uint32_t i2c_periph,uint32_t inttype)
+{
+    I2C_CTL1(i2c_periph) |= (inttype);   
+}
+
+/*!
+    \brief      disable i2c interrupt
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  inttype: interrupt type 
+      \arg        I2C_CTL1_ERRIE: error interrupt enable 
+      \arg        I2C_CTL1_EVIE: event interrupt enable 
+      \arg        I2C_CTL1_BUFIE: buffer interrupt enable   
+    \param[out] none
+    \retval     none
+*/
+void i2c_interrupt_disable(uint32_t i2c_periph,uint32_t inttype)
+{
+    I2C_CTL1(i2c_periph) &= ~(inttype);   
+}
+
+/*!
+    \brief      I2C PEC calculation on or off
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  pecpara:
+      \arg        I2C_PEC_ENABLE: PEC calculation on 
+      \arg        I2C_PEC_DISABLE: PEC calculation off 
+    \param[out] none
+    \retval     none
+*/
+void i2c_pec_enable(uint32_t i2c_periph,uint32_t pecstate)
+{
+    /* on/off PEC calculation */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_PECEN); 
+    ctl |= pecstate;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      I2C whether to transfer PEC value
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  pecpara:
+      \arg        I2C_PECTRANS_ENABLE: transfer PEC 
+      \arg        I2C_PECTRANS_DISABLE: not transfer PEC 
+    \param[out] none
+    \retval     none
+*/
+void i2c_pec_transfer_enable(uint32_t i2c_periph,uint32_t pecpara)
+{
+    /* whether to transfer PEC */
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_PECTRANS); 
+    ctl |= pecpara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      packet error checking value 
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     PEC value
+*/
+uint8_t i2c_pec_value(uint32_t i2c_periph)
+{
+    return  (uint8_t)((I2C_STAT1(i2c_periph) &I2C_STAT1_ECV)>>8);
+}
+
+/*!
+    \brief      I2C issue alert through SMBA pin 
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  smbuspara:
+      \arg        I2C_SALTSEND_ENABLE: issue alert through SMBA pin 
+      \arg        I2C_SALTSEND_DISABLE: not issue alert through SMBA pin 
+    \param[out] none
+    \retval     none
+*/
+void i2c_smbus_alert_issue(uint32_t i2c_periph,uint32_t smbuspara)
+{
+    /* issue alert through SMBA pin configure*/
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SALT); 
+    ctl |= smbuspara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      I2C ARP protocol in SMBus switch enable or disable 
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  smbuspara:
+      \arg        I2C_ARP_ENABLE: ARP is enabled 
+      \arg        I2C_ARP_DISABLE: ARP is disabled 
+    \param[out] none
+    \retval     none
+*/
+void i2c_smbus_arp_enable(uint32_t i2c_periph,uint32_t arpstate)
+{
+    /* enable or disable I2C ARP protocol*/
+    uint32_t ctl = 0U;
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_ARPEN); 
+    ctl |= arpstate;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      analog noise filter disable
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_analog_noise_filter_disable(uint32_t i2c_periph)
+{
+    I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD;  
+}
+
+/*!
+    \brief      analog noise filter enable
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_analog_noise_filter_enable(uint32_t i2c_periph)
+{
+    I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD);  
+}
+
+/*!
+    \brief      digital noise filter configuration
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  dfilterpara: refer to enum i2c_gcall_config_enum
+    \param[out] none
+    \retval     none
+*/
+void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara)
+{
+    I2C_FCTL(i2c_periph) |= dfilterpara;  
+}
+
+/*!
+    \brief      enable SAM_V interface
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_enable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN;  
+}
+
+/*!
+    \brief      disable SAM_V interface
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_disable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN);  
+}
+
+/*!
+    \brief      enable SAM_V interface timeout detect
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_timeout_enable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN;  
+}
+
+/*!
+    \brief      disable SAM_V interface timeout detect
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_timeout_disable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN);  
+}
+
+/*!
+    \brief      enable the specified I2C SAM interrupt
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  inttype: interrupt type 
+      \@arg       I2C_SAMCS_TFFIE: txframe fall interrupt
+      \@arg       I2C_SAMCS_TFRIE: txframe rise interrupt
+      \@arg       I2C_SAMCS_RFFIE: rxframe fall interrupt
+      \@arg       I2C_SAMCS_RFRIE: rxframe rise interrupt   
+    \param[out]  none
+    \retval      none
+*/
+void i2c_sam_interrupt_enable(uint32_t i2c_periph,uint32_t inttype)
+{
+    I2C_SAMCS(i2c_periph) |= (inttype);   
+}
+
+/*!
+    \brief      disable i2c interrupt
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  inttype:      interrupt type 
+      \@arg       I2C_SAMCS_TFFIE: txframe fall interrupt
+      \@arg       I2C_SAMCS_TFRIE: txframe rise interrupt
+      \@arg       I2C_SAMCS_RFFIE: rxframe fall interrupt
+      \@arg       I2C_SAMCS_RFRIE: rxframe rise interrupt    
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_interrupt_disable(uint32_t i2c_periph,uint32_t inttype)
+{
+    I2C_SAMCS(i2c_periph) &= ~(inttype);   
+}
+
+/*!
+    \brief      check i2c SAM state
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  samstate: state type 
+      \@arg       I2C_SAMCS_TXF: level of txframe signal
+      \@arg       I2C_SAMCS_RXF: level of rxframe signal
+      \@arg       I2C_SAMCS_TFF: txframe fall flag
+      \@arg       I2C_SAMCS_TFR: txframe rise flag    
+      \@arg       I2C_SAMCS_RFF: rxframe fall flag
+      \@arg       I2C_SAMCS_RFR: rxframe rise flag   
+    \param[out] none
+    \retval     state of i2c SAM
+*/
+FlagStatus i2c_sam_flag_get(uint32_t i2c_periph,uint32_t samstate)
+{
+    FlagStatus reg = RESET;
+    if(I2C_SAMCS(i2c_periph)&samstate){
+        reg =SET;
+    }else{
+        reg =RESET; 
+    }
+    return reg;
+}
+
+/*!
+    \brief      clear i2c SAM state
+    \param[in]  i2c_periph: I2Cx(x=0,1,2)
+    \param[in]  samstate: state type 
+      \@arg       I2C_SAMCS_TFF: txframe fall flag
+      \@arg       I2C_SAMCS_TFR: txframe rise flag    
+      \@arg       I2C_SAMCS_RFF: rxframe fall flag
+      \@arg       I2C_SAMCS_RFR: rxframe rise flag   
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_flag_clear(uint32_t i2c_periph,uint32_t samstate)
+{
+    I2C_SAMCS(i2c_periph) &= ~(samstate);
+  
+}
+

+ 409 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c

@@ -0,0 +1,409 @@
+/*!
+    \file  gd32f4xx_ipa.c
+    \brief IPA driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_ipa.h"
+
+/*!
+    \brief      deinitialize IPA registers 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ipa_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_IPAENRST);
+    rcu_periph_reset_disable(RCU_IPAENRST);
+}
+
+/*!
+    \brief      IPA transfer enable 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ipa_transfer_enable(void)
+{
+    IPA_CTL |= IPA_CTL_TEN;
+}
+
+/*!
+    \brief      IPA transfer hang up enable
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void ipa_transfer_hangup_enable(void)
+{
+    IPA_CTL |= IPA_CTL_THU;
+}
+
+/*!
+    \brief      IPA transfer hang up disable
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void ipa_transfer_hangup_disable(void)
+{
+    IPA_CTL &= ~(IPA_CTL_THU);
+}
+
+/*!
+    \brief      IPA transfer stop enable 
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void ipa_transfer_stop_enable(void)
+{
+    IPA_CTL |= IPA_CTL_TST;
+}
+
+/*!
+    \brief      IPA transfer stop disable 
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void ipa_transfer_stop_disable(void)
+{
+    IPA_CTL &= ~(IPA_CTL_TST);
+}
+/*!
+    \brief      IPA foreground LUT loading enable 
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void ipa_foreground_lut_loading_enable(void)
+{
+    IPA_FPCTL |= IPA_FPCTL_FLLEN;
+}
+
+/*!
+    \brief      IPA background LUT loading enable 
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void ipa_background_lut_loading_enable(void)
+{
+    IPA_BPCTL |= IPA_BPCTL_BLLEN;
+}
+
+/*!
+    \brief      Pixel format convert mode 
+    \param[in]  pfcm:
+      \arg        IPA_FGTODE: foreground memory to destination memory without pixel format convert 
+      \arg        IPA_FGTODE_PF_CONVERT: foreground memory to destination memory with pixel format convert 
+      \arg        IPA_FGBGTODE: blending foreground and background memory to destination memory 
+      \arg        IPA_FILL_UP_DE: fill up destination memory with specific color 
+    \param[out] none
+    \retval     none
+*/
+void ipa_pixel_format_convert_mod(uint32_t pfcm)
+{
+    IPA_CTL |= pfcm;
+}
+
+/*!
+    \brief      initialize foreground parameters 
+    \param[in]  foreground_struct: the data needed to initialize fore.
+                  foreground_memaddr: foreground memory base address
+                  foreground_lineoff: foreground line offset
+                  foreground_prealpha: foreground pre-defined alpha value 
+                  foreground_alpha_algorithm: IPA_FG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2
+                  foreground_pf: foreground pixel format
+                  foreground_prered: foreground pre-defined red value
+                  foreground_pregreen: foreground pre-defined green value 
+                  foreground_preblue: foreground pre-defined blue value
+    \param[out] none
+    \retval     none
+*/
+void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct)
+{
+    /* foreground memory base address configuration */
+    IPA_FMADDR &= ~(IPA_FMADDR_FMADDR);
+    IPA_FMADDR = foreground_struct->foreground_memaddr;
+    /* foreground line offset configuration */
+    IPA_FLOFF &= ~(IPA_FLOFF_FLOFF);
+    IPA_FLOFF = foreground_struct->foreground_lineoff;
+    /* foreground pixel format pre-defined alpha, alpha calculation algorithm configuration */    
+    IPA_FPCTL &= ~(IPA_FPCTL_FAVCA|IPA_FPCTL_FAVCA|IPA_FPCTL_FPF);
+    IPA_FPCTL |= (foreground_struct->foreground_prealpha<<24U);
+    IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm;
+    IPA_FPCTL |= foreground_struct->foreground_pf;
+    /* foreground pre-defined red green blue configuration */    
+    IPA_FPV &= ~(IPA_FPV_FPDRV|IPA_FPV_FPDGV|IPA_FPV_FPDBV);
+    IPA_FPV |= ((foreground_struct->foreground_prered<<16U)|(foreground_struct->foreground_pregreen<<8U)|(foreground_struct->foreground_preblue));
+}
+
+/*!
+    \brief      initialize background parameters 
+    \param[in]  background_struct: the data needed to initialize fore.
+                  background_memaddr: background memory base address
+                  background_lineoff: background line offset
+                  background_prealpha: background pre-defined alpha value 
+                  background_alpha_algorithm: IPA_BG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2
+                  background_pf: background pixel format
+                  background_prered: background pre-defined red value
+                  background_pregreen: background pre-defined green value 
+                  background_preblue: background pre-defined blue value
+    \param[out] none
+    \retval     none
+*/
+void ipa_background_init(ipa_background_parameter_struct* background_struct)
+{
+    /* background memory base address configuration */
+    IPA_BMADDR &= ~(IPA_BMADDR_BMADDR);
+    IPA_BMADDR = background_struct->background_memaddr;
+    /* background line offset configuration */
+    IPA_BLOFF &= ~(IPA_BLOFF_BLOFF);
+    IPA_BLOFF =background_struct->background_lineoff;
+    /* background pixel format pre-defined alpha, alpha calculation algorithm configuration */    
+    IPA_BPCTL &= ~(IPA_BPCTL_BAVCA|IPA_BPCTL_BAVCA|IPA_BPCTL_BPF);
+    IPA_BPCTL |= (background_struct->background_prealpha<<24U);
+    IPA_BPCTL |= background_struct->background_alpha_algorithm;
+    IPA_BPCTL |= background_struct->background_pf; 
+    /* background pre-defined red green blue configuration */  
+    IPA_BPV &= ~(IPA_BPV_BPDRV|IPA_BPV_BPDGV|IPA_BPV_BPDBV);
+    IPA_BPV |= ((background_struct->background_prered<<16U)|(background_struct->background_pregreen<<8U)|(background_struct->background_preblue));
+}
+
+/*!
+    \brief      initialize destination parameters  
+    \param[in]  destination_struct: the data needed to initialize tli.
+                  destination_pf: refer to ipa_dpf_enum 
+                  destination_lineoff: destination line offset
+                  destination_prealpha: destination pre-defined alpha value 
+                  destination_prered: destination pre-defined red value
+                  destination_pregreen: destination pre-defined green value
+                  destination_preblue: destination pre-defined blue value
+                  destination_memaddr: destination memory base address 
+                  image_width: width of the image to be processed
+                  image_height: height of the image to be processed
+    \param[out] none
+    \retval     none
+*/
+void ipa_destination_init(ipa_destination_parameter_struct* destination_struct)
+{
+    uint32_t destination_pixelformat;
+    /* destination pixel format configuration */
+    IPA_DPCTL &= ~(IPA_DPCTL_DPF);
+    IPA_DPCTL = destination_struct->destination_pf;
+    destination_pixelformat = destination_struct->destination_pf;
+    /* destination pixel format ARGB8888 */
+    switch(destination_pixelformat){
+    case IPA_DPF_ARGB8888:
+        IPA_DPV &= ~(IPA_DPV_DPDBV_0|(IPA_DPV_DPDGV_0)|(IPA_DPV_DPDRV_0)|(IPA_DPV_DPDAV_0));
+        IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<8U)
+                                                            |(destination_struct->destination_prered<<16U)
+                                                            |(destination_struct->destination_prealpha<<24U));
+        break;
+    /* destination pixel format RGB888 */
+    case IPA_DPF_RGB888:
+        IPA_DPV &= ~(IPA_DPV_DPDBV_1|(IPA_DPV_DPDGV_1)|(IPA_DPV_DPDRV_1));
+        IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<8U)
+                                                            |(destination_struct->destination_prered<<16U));
+        break;
+    /* destination pixel format RGB565 */
+    case IPA_DPF_RGB565:
+        IPA_DPV &= ~(IPA_DPV_DPDBV_2|(IPA_DPV_DPDGV_2)|(IPA_DPV_DPDRV_2));
+        IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U)
+                                                            |(destination_struct->destination_prered<<11U));
+        break;
+    /* destination pixel format ARGB1555 */
+    case IPA_DPF_ARGB1555:
+        IPA_DPV &= ~(IPA_DPV_DPDBV_3|(IPA_DPV_DPDGV_3)|(IPA_DPV_DPDRV_3)|(IPA_DPV_DPDAV_3));
+        IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U)
+                                                            |(destination_struct->destination_prered<<10U)
+                                                            |(destination_struct->destination_prealpha<<15U));
+        break;
+    /* destination pixel format ARGB4444 */
+    case IPA_DPF_ARGB4444:
+        IPA_DPV &= ~(IPA_DPV_DPDBV_4|(IPA_DPV_DPDGV_4)|(IPA_DPV_DPDRV_4)|(IPA_DPV_DPDAV_4));
+        IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U)
+                                                            |(destination_struct->destination_prered<<10U)
+                                                            |(destination_struct->destination_prealpha<<15U));
+        break;
+    default:
+        break;
+    }
+    /* destination memory base address configuration */
+    IPA_DMADDR &= ~(IPA_DMADDR_DMADDR);
+    IPA_DMADDR =destination_struct->destination_memaddr;
+    /* destination line offset configuration */    
+    IPA_DLOFF &= ~(IPA_DLOFF_DLOFF);
+    IPA_DLOFF =destination_struct->destination_lineoff;
+    /* image size configuration */    
+    IPA_IMS &= ~(IPA_IMS_HEIGHT|IPA_IMS_WIDTH);
+    IPA_IMS |= ((destination_struct->image_width<<16)|(destination_struct->image_height));
+}
+
+/*!
+    \brief      initialize IPA foreground LUT parameters  
+    \param[in]  fg_lut_num: foreground LUT number of pixel.
+    \param[in]  fg_lut_pf: foreground LUT pixel format,IPA_LUT_PF_ARGB8888,IPA_LUT_PF_RGB888.
+    \param[in]  fg_lut_addr: foreground LUT memory base address.
+    \param[out] none
+    \retval     none
+*/
+void ipa_foreground_lut_init(uint32_t fg_lut_num,uint8_t fg_lut_pf, uint32_t fg_lut_addr)
+{
+    /* foreground LUT number of pixel configuration */
+    IPA_FPCTL |= (fg_lut_num<<8U);
+    /* foreground LUT pixel format configuration */
+    if(IPA_LUT_PF_RGB888 == fg_lut_pf){
+        IPA_FPCTL |= IPA_FPCTL_FLPF;
+    }else{
+        IPA_FPCTL &= ~(IPA_FPCTL_FLPF);
+    }
+    /* foreground LUT memory base address configuration */
+    IPA_FLMADDR &= ~(IPA_FLMADDR_FLMADDR);
+    IPA_FLMADDR = fg_lut_addr;
+}
+
+/*!
+    \brief      initialize IPA background LUT parameters  
+    \param[in]  bg_lut_num: background LUT number of pixel.
+    \param[in]  bg_lut_pf: background LUT pixel format, IPA_LUT_PF_ARGB8888,IPA_LUT_PF_RGB888.
+    \param[in]  bg_lut_addr: background LUT memory base address.
+    \param[out] none
+    \retval     none
+*/
+void ipa_background_lut_init(uint32_t bg_lut_num,uint8_t bg_lut_pf, uint32_t bg_lut_addr)
+{
+    /* background LUT number of pixel configuration */
+    IPA_BPCTL|=(bg_lut_num<<8U);
+    /* background LUT pixel format configuration */
+    if(IPA_LUT_PF_RGB888 == bg_lut_pf){
+        IPA_BPCTL |= IPA_BPCTL_BLPF;
+    }else{
+        IPA_BPCTL &= ~(IPA_BPCTL_BLPF);
+    }
+    /* background LUT memory base address configuration */
+    IPA_BLMADDR &= ~(IPA_BLMADDR_BLMADDR);
+    IPA_BLMADDR = bg_lut_addr;
+}
+
+/*!
+    \brief      configure line mark 
+    \param[in]  linenum: line number.
+    \param[out] none
+    \retval     none
+*/
+void ipa_line_mark_config(uint32_t linenum)
+{
+    IPA_LM &= ~(IPA_LM_LM);
+    IPA_LM = linenum;
+}
+
+/*!
+    \brief      Inter-timer enable or disable 
+    \param[in]  timercfg: IPA_INTER_TIMER_ENABLE,IPA_INTER_TIMER_DISABLE
+    \param[out] none
+    \retval     none
+*/
+void ipa_inter_timer_config(uint8_t timercfg)
+{
+    if(IPA_INTER_TIMER_ENABLE == timercfg){
+        IPA_ITCTL |= IPA_ITCTL_ITEN;
+    }else{
+        IPA_ITCTL &= ~(IPA_ITCTL_ITEN);
+    }
+}
+
+/*!
+    \brief      number of clock cycles interval set 
+    \param[in]  clk_num: the number of clock cycles.
+    \param[out] none
+    \retval     none
+*/
+void ipa_interval_clock_num_config(uint32_t clk_num )
+{
+    IPA_ITCTL &= ~(IPA_ITCTL_NCCI);
+    IPA_ITCTL |= (clk_num<<8U);
+}
+
+/*!
+    \brief      IPA interrupt enable 
+    \param[in]  inttype: IPA interrupt bits.
+      \arg        IPA_CTL_TAEIE: transfer access error interrupt 
+      \arg        IPA_CTL_FTFIE: full transfer finish interrupt 
+      \arg        IPA_CTL_TLMIE: transfer line mark interrupt   
+      \arg        IPA_CTL_LACIE: LUT access conflict interrupt 
+      \arg        IPA_CTL_LLFIE: LUT loading finish interrupt
+      \arg        IPA_CTL_WCFIE: wrong configuration interrupt 
+    \param[out] none
+    \retval     none
+*/
+void ipa_interrupt_enable(uint32_t inttype)
+{
+    IPA_CTL |= (inttype);
+}
+
+/*!
+    \brief      IPA interrupt disable 
+    \param[in]  inttype: IPA interrupt bits.
+      \arg        IPA_CTL_TAEIE: transfer access error interrupt 
+      \arg        IPA_CTL_FTFIE: full transfer finish interrupt 
+      \arg        IPA_CTL_TLMIE: transfer line mark interrupt   
+      \arg        IPA_CTL_LACIE: LUT access conflict interrupt 
+      \arg        IPA_CTL_LLFIE: LUT loading finish interrupt
+      \arg        IPA_CTL_WCFIE: wrong configuration interrupt 
+    \param[out] none
+    \retval     none
+*/
+void ipa_interrupt_disable(uint32_t inttype)
+{
+    IPA_CTL &= ~(inttype);
+}
+
+/*!
+    \brief      get IPA interrupt flag 
+    \param[in]  intflag: tli interrupt flag bits.
+      \arg        IPA_INTF_TAEIF: transfer access error interrupt flag 
+      \arg        IPA_INTF_FTFIF: full transfer finish interrupt flag 
+      \arg        IPA_INTF_TLMIF: transfer line mark interrupt flag
+      \arg        IPA_INTF_LACIF: LUT access conflict interrupt flag 
+      \arg        IPA_INTF_LLFIF: LUT loading finish interrupt flag 
+      \arg        IPA_INTF_WCFIF: wrong configuration interrupt flag 
+    \param[out] none
+    \retval     none
+*/
+FlagStatus ipa_interrupt_flag_get(uint32_t intflag)
+{
+    uint32_t state;
+    state = IPA_INTF;
+    if(state & intflag){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear IPA interrupt flag 
+    \param[in]  intflag: tli interrupt flag bits.
+      \arg        IPA_INTC_TAEIFC: transfer access error interrupt flag 
+      \arg        IPA_INTC_FTFIFC: full transfer finish interrupt flag 
+      \arg        IPA_INTC_TLMIFC: transfer line mark interrupt flag
+      \arg        IPA_INTC_LACIFC: LUT access conflict interrupt flag 
+      \arg        IPA_INTC_LLFIFC: LUT loading finish interrupt flag 
+      \arg        IPA_INTC_WCFIFC: wrong configuration interrupt flag 
+    \param[out] none
+    \retval     none
+*/
+void ipa_interrupt_flag_clear(uint32_t intflag)
+{
+    IPA_INTC |= (intflag);
+}
+

+ 101 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c

@@ -0,0 +1,101 @@
+/*!
+    \file  gd32f4xx_iref.c
+    \brief IREF driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_iref.h"
+
+/*!
+    \brief      deinit IREF
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void iref_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_IREFRST);
+    rcu_periph_reset_disable(RCU_IREFRST);
+}
+
+/*!
+    \brief      enable IREF
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void iref_enable(void)
+{
+    IREF_CTL |= IREF_CTL_CREN;
+}
+
+/*!
+    \brief      disable IREF
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void iref_disable(void)
+{
+    IREF_CTL &= ~IREF_CTL_CREN;
+}
+
+/*!
+    \brief      set IREF mode
+    \param[in]  step
+      \arg        IREF_MODE_LOW_POWER: 1uA step
+      \arg        IREF_MODE_HIGH_CURRENT: 8uA step
+    \param[out] none
+    \retval     none
+*/
+void iref_mode_set(uint32_t step)
+{
+    IREF_CTL &= ~IREF_CTL_SSEL;
+    IREF_CTL |= step;
+}
+
+/*!
+    \brief      set IREF precision_trim_value
+    \param[in]  precisiontrim
+      \arg        IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)%
+    \param[out] none
+    \retval     none
+*/
+void iref_precision_trim_value_set(uint32_t precisiontrim)
+{
+    IREF_CTL &= ~IREF_CTL_CPT;
+    IREF_CTL |= precisiontrim;
+}
+
+/*!
+    \brief      set IREF sink mode
+    \param[in]  sinkmode
+      \arg        IREF_SOURCE_CURRENT : source current.
+      \arg        IREF_SINK_CURRENT: sink current
+    \param[out] none
+    \retval     none
+*/
+void iref_sink_set(uint32_t sinkmode)
+{
+    IREF_CTL &= ~IREF_CTL_SCMOD;
+    IREF_CTL |= sinkmode;
+}
+
+/*!
+    \brief      set IREF step data 
+    \param[in]  stepdata
+      \arg        IREF_CUR_STEP_DATA_X:(x=0..63): step*x
+    \param[out] none
+    \retval     none
+*/
+
+void iref_step_data_config(uint32_t stepdata)
+{
+    IREF_CTL &= ~IREF_CTL_CSDT;
+    IREF_CTL |= stepdata;
+}

+ 146 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c

@@ -0,0 +1,146 @@
+/*!
+    \file  gd32f4xx_misc.c
+    \brief MISC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_misc.h"
+
+/*!
+    \brief      set the priority group
+    \param[in]  nvic_prigroup: the NVIC priority group
+      \arg        NVIC_PRIGROUP_PRE0_SUB4:0 bits for pre-emption priority 4 bits for subpriority
+      \arg        NVIC_PRIGROUP_PRE1_SUB3:1 bits for pre-emption priority 3 bits for subpriority
+      \arg        NVIC_PRIGROUP_PRE2_SUB2:2 bits for pre-emption priority 2 bits for subpriority
+      \arg        NVIC_PRIGROUP_PRE3_SUB1:3 bits for pre-emption priority 1 bits for subpriority
+      \arg        NVIC_PRIGROUP_PRE4_SUB0:4 bits for pre-emption priority 0 bits for subpriority
+    \param[out] none
+    \retval     none
+*/
+void nvic_priority_group_set(uint32_t nvic_prigroup)
+{
+    /* set the priority group value */
+    SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup;
+}
+
+/*!
+    \brief      enable NVIC request
+    \param[in]  nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
+    \param[in]  nvic_irq_pre_priority: the pre-emption priority needed to set
+    \param[in]  nvic_irq_sub_priority: the subpriority needed to set
+    \param[out] none
+    \retval     none
+*/
+void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, 
+                     uint8_t nvic_irq_sub_priority)
+{
+    uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;
+    /* use the priority group value to get the temp_pre and the temp_sub */
+    if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE0_SUB4){
+        temp_pre=0U;
+        temp_sub=0x4U;
+    }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE1_SUB3){
+        temp_pre=1U;
+        temp_sub=0x3U;
+    }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE2_SUB2){
+        temp_pre=2U;
+        temp_sub=0x2U;
+    }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE3_SUB1){
+        temp_pre=3U;
+        temp_sub=0x1U;
+    }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE4_SUB0){
+        temp_pre=4U;
+        temp_sub=0x0U;
+    }else{
+    }
+    /* get the temp_priority to fill the NVIC->IP register */
+    temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
+    temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub));
+    temp_priority = temp_priority << 0x04U;
+    NVIC->IP[nvic_irq] = (uint8_t)temp_priority;
+    /* enable the selected IRQ */
+    NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
+}
+
+/*!
+    \brief      disable NVIC request
+    \param[in]  nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
+    \param[out] none
+    \retval     none
+*/
+void nvic_irq_disable(uint8_t nvic_irq)
+{
+    /* disable the selected IRQ.*/
+    NVIC->ICER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F);
+}
+
+/*!
+    \brief      set the NVIC vector table base address
+    \param[in]  nvic_vict_tab: the RAM or FLASH base address
+      \arg        NVIC_VECTTAB_RAM: RAM base address
+      \are        NVIC_VECTTAB_FLASH: Flash base address
+    \param[in]  offset: Vector Table offset
+    \param[out] none
+    \retval     none
+*/
+void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset)
+{
+    SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK);
+}
+
+/*!
+    \brief      set the state of the low power mode
+    \param[in]  lowpower_mode: the low power mode state
+      \arg        SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power 
+                    mode by exiting from ISR
+      \arg        SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode
+      \arg        SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up 
+                    by all the enable and disable interrupts
+    \param[out] none
+    \retval     none
+*/
+void system_lowpower_set(uint8_t lowpower_mode)
+{
+    SCB->SCR |= (uint32_t)lowpower_mode;
+}
+
+/*!
+    \brief      reset the state of the low power mode
+    \param[in]  lowpower_mode: the low power mode state
+      \arg        SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power 
+                    mode by exiting from ISR
+      \arg        SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode
+      \arg        SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be 
+                    woke up by the enable interrupts
+    \param[out] none
+    \retval     none
+*/
+void system_lowpower_reset(uint8_t lowpower_mode)
+{
+    SCB->SCR &= (~(uint32_t)lowpower_mode);
+}
+
+/*!
+    \brief      set the systick clock source
+    \param[in]  systick_clksource: the systick clock source needed to choose
+      \arg        SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK
+      \arg        SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8
+    \param[out] none
+    \retval     none
+*/
+
+void systick_clksource_set(uint32_t systick_clksource)
+{
+    if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){
+        /* set the systick clock source from HCLK */
+        SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
+    }else{
+        /* set the systick clock source from HCLK/8 */
+        SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8;
+    }
+}

+ 348 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c

@@ -0,0 +1,348 @@
+/*!
+    \file  gd32f4xx_pmu.c
+    \brief PMU driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_pmu.h"
+#include "core_cm4.h"
+/*!
+    \brief      reset PMU register
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_deinit(void)
+{
+    /* reset PMU */
+    rcu_periph_reset_enable(RCU_PMURST);
+    rcu_periph_reset_disable(RCU_PMURST);
+}
+
+/*!
+    \brief      select low voltage detector threshold
+    \param[in]  pmu_lvdt_n:
+      \arg        PMU_LVDT_0: voltage threshold is 2.2V
+      \arg        PMU_LVDT_1: voltage threshold is 2.3V
+      \arg        PMU_LVDT_2: voltage threshold is 2.4V
+      \arg        PMU_LVDT_3: voltage threshold is 2.5V
+      \arg        PMU_LVDT_4: voltage threshold is 2.6V
+      \arg        PMU_LVDT_5: voltage threshold is 2.7V
+      \arg        PMU_LVDT_6: voltage threshold is 2.8V
+      \arg        PMU_LVDT_7: voltage threshold is 2.9V
+    \param[out] none
+    \retval     none
+*/
+void pmu_lvd_select(uint32_t pmu_lvdt_n)
+{
+    /* disable LVD */
+    PMU_CTL &= ~PMU_CTL_LVDEN;
+    /* clear LVDT bits */
+    PMU_CTL &= ~PMU_CTL_LVDT;
+    /* set LVDT bits according to pmu_lvdt_n */
+    PMU_CTL |= pmu_lvdt_n;
+    /* enable LVD */
+    PMU_CTL |= PMU_CTL_LVDEN;
+}
+
+/*!
+    \brief      LDO output voltage select
+                this bit set by software when the main PLL closed, before closing PLL, change the system clock to IRC16M or HXTAL
+    \param[in]  ldo_output:
+      \arg        PMU_LDOVS_LOW: low-driver mode enable in deep-sleep mode
+      \arg        PMU_LDOVS_MID: low-driver mode disable in deep-sleep mode
+      \arg        PMU_LDOVS_HIGH: low-driver mode disable in deep-sleep mode
+    \param[out] none
+    \retval     none
+*/
+void pmu_ldo_output_select(uint32_t ldo_output)
+{
+    PMU_CTL &= ~PMU_CTL_LDOVS;
+    PMU_CTL |= ldo_output;
+}
+
+/*!
+    \brief      low-driver mode enable in deep-sleep mode
+    \param[in]  lowdr_mode:
+      \arg        PMU_LOWDRIVER_ENABLE: low-driver mode enable in deep-sleep mode
+      \arg        PMU_LOWDRIVER_DISABLE: low-driver mode disable in deep-sleep mode
+    \param[out] none
+    \retval     none
+*/
+void pmu_low_driver_mode_enable(uint32_t lowdr_mode)
+{
+    PMU_CTL &= ~PMU_CTL_LDEN;
+    PMU_CTL |= lowdr_mode;
+}
+
+/*!
+    \brief      high-driver mode switch
+                this bit set by software only when IRC16M or HXTAL used as system clock
+    \param[in]  highdr_switch:
+      \arg        PMU_HIGHDR_SWITCH_NONE: no high-driver mode switch
+      \arg        PMU_HIGHDR_SWITCH_EN: high-driver mode switch
+    \param[out] none
+    \retval     none
+*/
+void pmu_highdriver_switch_select(uint32_t highdr_switch)
+{
+    /* wait for HDRF flag set */
+    while(SET != pmu_flag_get(PMU_FLAG_HDRF)){
+    }
+    PMU_CTL &= ~PMU_CTL_HDS;
+    PMU_CTL |= highdr_switch;
+}
+
+/*!
+    \brief      enable high-driver mode
+                this bit set by software only when IRC16M or HXTAL used as system clock
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_highdriver_mode_enable(void)
+{
+    PMU_CTL |= PMU_CTL_HDEN;
+}
+
+/*!
+    \brief      disable high-driver mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_highdriver_mode_disable(void)
+{
+    PMU_CTL &= ~PMU_CTL_HDEN;
+}
+
+/*!
+    \brief      disable PMU lvd
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_lvd_disable(void)
+{
+    /* disable LVD */
+    PMU_CTL &= ~PMU_CTL_LVDEN;
+}
+
+/*!
+    \brief      low-driver mode when use low power LDO
+    \param[in]  mode:
+      \arg        PMU_NORMALDR_LOWPWR:  normal driver when use low power LDO
+      \arg        PMU_LOWDR_LOWPWR:  low-driver mode enabled when LDEN is 11 and use low power LDO
+    \param[out] none
+    \retval     none
+*/
+void pmu_lowdriver_lowpower_config(uint32_t mode)
+{
+    PMU_CTL &= ~PMU_CTL_LDLP;
+    PMU_CTL |= mode;
+}
+
+/*!
+    \brief      low-driver mode when use normal power LDO
+    \param[in]  mode:
+      \arg        PMU_NORMALDR_NORMALPWR:  normal driver when use low power LDO
+      \arg        PMU_LOWDR_NORMALPWR:  low-driver mode enabled when LDEN is 11 and use low power LDO
+    \param[out] none
+    \retval     none
+*/
+void pmu_lowdriver_normalpower_config(uint32_t mode)
+{
+    PMU_CTL &= ~PMU_CTL_LDNP;
+    PMU_CTL |= mode;
+}
+
+/*!
+    \brief      PMU work at sleep mode
+    \param[in]  sleepmodecmd:
+      \arg        WFI_CMD: use WFI command
+      \arg        WFE_CMD: use WFE command
+    \param[out] none
+    \retval     none
+*/
+void pmu_to_sleepmode(uint8_t sleepmodecmd)
+{
+    /* clear sleepdeep bit of Cortex-M4 system control register */
+    SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+    
+    /* select WFI or WFE command to enter sleep mode */
+    if(WFI_CMD == sleepmodecmd){
+        __WFI();
+    }else{
+        __WFE();
+    }
+}
+
+/*!
+    \brief      PMU work at deepsleep mode
+    \param[in]  pmu_ldo
+      \arg        PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode
+      \arg        PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
+    \param[in]  deepsleepmodecmd: 
+      \arg        WFI_CMD: use WFI command
+      \arg        WFE_CMD: use WFE command
+    \param[out] none
+    \retval     none
+*/
+void pmu_to_deepsleepmode(uint32_t pmu_ldo,uint8_t deepsleepmodecmd)
+{
+    /* clear stbmod and ldolp bits */
+    PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
+    
+    /* set ldolp bit according to pmu_ldo */
+    PMU_CTL |= pmu_ldo;
+    
+    /* set sleepdeep bit of Cortex-M4 system control register */
+    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+    
+    /* select WFI or WFE command to enter deepsleep mode */
+    if(WFI_CMD == deepsleepmodecmd){
+        __WFI();
+    }else{
+        __SEV();
+        __WFE();
+        __WFE();
+    }
+    /* reset sleepdeep bit of Cortex-M4 system control register */
+    SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+}
+
+/*!
+    \brief      pmu work at standby mode
+    \param[in]  standbymodecmd:
+      \arg        WFI_CMD: use WFI command
+      \arg        WFE_CMD: use WFE command
+    \param[out] none
+    \retval     none
+*/
+void pmu_to_standbymode(uint8_t standbymodecmd)
+{
+    /* set sleepdeep bit of Cortex-M4 system control register */
+    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+    /* set stbmod bit */
+    PMU_CTL |= PMU_CTL_STBMOD;
+        
+    /* reset wakeup flag */
+    PMU_CTL |= PMU_CTL_WURST;
+    
+    /* select WFI or WFE command to enter standby mode */
+    if(WFI_CMD == standbymodecmd){
+        __WFI();
+    }else{
+        __WFE();
+    }
+}
+
+/*!
+    \brief      backup SRAM LDO on
+    \param[in]  bkp_ldo:
+      \arg        PMU_BLDOON_OFF: backup SRAM LDO closed
+      \arg        PMU_BLDOON_ON: open the backup SRAM LDO
+    \param[out] none
+    \retval     none
+*/
+void pmu_backup_ldo_config(uint32_t bkp_ldo)
+{
+    PMU_CS &= ~PMU_CS_BLDOON;
+    PMU_CS |= bkp_ldo;
+}
+
+/*!
+    \brief      reset flag bit
+    \param[in]  flag_reset:
+      \arg        PMU_FLAG_RESET_WAKEUP: reset wakeup flag
+      \arg        PMU_FLAG_RESET_STANDBY: reset standby flag
+    \param[out] none
+    \retval     none
+*/
+void pmu_flag_reset(uint32_t flag_reset)
+{
+    switch(flag_reset){
+    case PMU_FLAG_RESET_WAKEUP:
+        /* reset wakeup flag */
+        PMU_CTL |= PMU_CTL_WURST;
+        break;
+    case PMU_FLAG_RESET_STANDBY:
+        /* reset standby flag */
+        PMU_CTL |= PMU_CTL_STBRST;
+        break;
+    default :
+        break;
+    }
+}
+
+/*!
+    \brief      get flag status
+    \param[in]  pmu_flag:
+      \arg        PMU_FLAG_WAKEUP: wakeup flag status
+      \arg        PMU_FLAG_STANDBY: standby flag status
+      \arg        PMU_FLAG_LVD: lvd flag status
+      \arg        PMU_FLAG_BLDORF: backup SRAM LDO ready flag
+      \arg        PMU_FLAG_LDOVSRF: LDO voltage select ready flag
+      \arg        PMU_FLAG_HDRF: high-driver ready flag
+      \arg        PMU_FLAG_HDSRF: high-driver switch ready flag
+      \arg        PMU_FLAG_LDRF: low-driver mode ready flag 
+    \param[out] none
+    \retval     FlagStatus SET or RESET
+*/
+FlagStatus pmu_flag_get(uint32_t pmu_flag )
+{
+    if(PMU_CS & pmu_flag){
+        return  SET;
+    }
+    return  RESET;
+}
+
+/*!
+    \brief      enable backup domain write
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_backup_write_enable(void)
+{
+    PMU_CTL |= PMU_CTL_BKPWEN;
+}
+
+/*!
+    \brief      disable backup domain write
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_backup_write_disable(void)
+{
+    PMU_CTL &= ~PMU_CTL_BKPWEN;
+}
+
+/*!
+    \brief      enable wakeup pin
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_wakeup_pin_enable(void)
+{
+    PMU_CS |= PMU_CS_WUPEN;
+}
+
+/*!
+    \brief      disable wakeup pin
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_wakeup_pin_disable(void)
+{
+    PMU_CS &= ~PMU_CS_WUPEN;
+}

+ 1281 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c

@@ -0,0 +1,1281 @@
+/*!
+    \file  gd32f4xx_rcu.c
+    \brief RCU driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_rcu.h"
+
+#define SEL_IRC16M                  0U
+#define SEL_HXTAL                   1U
+#define SEL_PLLP                    2U
+#define OSC_STARTUP_TIMEOUT         ((uint16_t)0xfffffU)
+#define LXTAL_STARTUP_TIMEOUT       ((uint16_t)0x3ffffffU)
+
+/*!
+    \brief      deinitialize the RCU
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_deinit(void)
+{
+    /* enable IRC16M */
+    RCU_CTL |= RCU_CTL_IRC16MEN;
+    rcu_osci_stab_wait(RCU_IRC16M);
+    /* reset CFG0 register */
+    RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |
+                  RCU_CFG0_RTCDIV | RCU_CFG0_CKOUT0SEL | RCU_CFG0_I2SSEL | RCU_CFG0_CKOUT0DIV |
+                  RCU_CFG0_CKOUT1DIV | RCU_CFG0_CKOUT1SEL);
+    /* reset CTL register */
+    RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN | RCU_CTL_PLLI2SEN |
+                 RCU_CTL_PLLSAIEN | RCU_CTL_HXTALBPS);
+    /* reset PLL register */
+    RCU_PLL = 0x24003010U;
+    /* reset PLLI2S register */
+    RCU_PLLI2S = 0x24003000U;
+    /* reset PLLSAI register */
+    RCU_PLLSAI = 0x24003010U;
+    /* reset INT register */
+    RCU_INT = 0x00000000U;
+    /* reset CFG1 register */
+    RCU_CFG1 &= ~(RCU_CFG1_PLLSAIRDIV | RCU_CFG1_TIMERSEL);                
+}
+
+/*!
+    \brief      enable the peripherals clock
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOx (x=A,B,C,D,E,F,G,H,I): GPIO ports clock
+      \arg        RCU_CRC: CRC clock
+      \arg        RCU_BKPSRAM: BKPSRAM clock
+      \arg        RCU_TCMSRAM: TCMSRAM clock
+      \arg        RCU_DMAx (x=0,1): DMA clock
+      \arg        RCU_IPA: IPA clock
+      \arg        RCU_ENET: ENET clock
+      \arg        RCU_ENETTX: ENETTX clock
+      \arg        RCU_ENETRX: ENETRX clock
+      \arg        RCU_ENETPTP: ENETPTP clock
+      \arg        RCU_USBHS: USBHS clock
+      \arg        RCU_USBHSULPI: USBHSULPI clock
+      \arg        RCU_DCI: DCI clock
+      \arg        RCU_TRNG: TRNG clock
+      \arg        RCU_USBFS: USBFS clock
+      \arg        RCU_EXMC: EXMC clock
+      \arg        RCU_TIMERx (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock
+      \arg        RCU_WWDGT: WWDGT clock
+      \arg        RCU_SPIx (x=0,1,2,3,4,5): SPI clock
+      \arg        RCU_USARTx (x=0,1,2,5): USART clock
+      \arg        RCU_UARTx (x=3,4,6,7): UART clock
+      \arg        RCU_I2Cx (x=0,1,2): I2C clock
+      \arg        RCU_CANx (x=0,1): CAN clock
+      \arg        RCU_PMU: PMU clock
+      \arg        RCU_DAC: DAC clock
+      \arg        RCU_RTC: RTC clock
+      \arg        RCU_ADCx (x=0,1,2): ADC clock
+      \arg        RCU_SDIO: SDIO clock
+      \arg        RCU_SYSCFG: SYSCFG clock
+      \arg        RCU_TLI: TLI clock
+      \arg        RCU_CTC: CTC clock
+      \arg        RCU_IREF: IREF clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_enable(rcu_periph_enum periph)
+{
+    RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      disable the peripherals clock
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOx (x=A,B,C,D,E,F,G,H,I): GPIO ports clock
+      \arg        RCU_CRC: CRC clock
+      \arg        RCU_BKPSRAM: BKPSRAM clock
+      \arg        RCU_TCMSRAM: TCMSRAM clock
+      \arg        RCU_DMAx (x=0,1): DMA clock
+      \arg        RCU_IPA: IPA clock
+      \arg        RCU_ENET: ENET clock
+      \arg        RCU_ENETTX: ENETTX clock
+      \arg        RCU_ENETRX: ENETRX clock
+      \arg        RCU_ENETPTP: ENETPTP clock
+      \arg        RCU_USBHS: USBHS clock
+      \arg        RCU_USBHSULPI: USBHSULPI clock
+      \arg        RCU_DCI: DCI clock
+      \arg        RCU_TRNG: TRNG clock
+      \arg        RCU_USBFS: USBFS clock
+      \arg        RCU_EXMC: EXMC clock
+      \arg        RCU_TIMERx (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock
+      \arg        RCU_WWDGT: WWDGT clock
+      \arg        RCU_SPIx (x=0,1,2,3,4,5): SPI clock
+      \arg        RCU_USARTx (x=0,1,2,5): USART clock
+      \arg        RCU_UARTx (x=3,4,6,7): UART clock
+      \arg        RCU_I2Cx (x=0,1,2): I2C clock
+      \arg        RCU_CANx (x=0,1): CAN clock
+      \arg        RCU_PMU: PMU clock
+      \arg        RCU_DAC: DAC clock
+      \arg        RCU_RTC: RTC clock
+      \arg        RCU_ADCx (x=0,1,2): ADC clock
+      \arg        RCU_SDIO: SDIO clock
+      \arg        RCU_SYSCFG: SYSCFG clock
+      \arg        RCU_TLI: TLI clock
+      \arg        RCU_CTC: CTC clock
+      \arg        RCU_IREF: IREF clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_disable(rcu_periph_enum periph)
+{
+    RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      enable the peripherals clock when sleep mode
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_sleep_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOx_SLP (x=A,B,C,D,E,F,G,H,I): GPIO ports clock
+      \arg        RCU_CRC_SLP: CRC clock
+      \arg        RCU_FMC_SLP: FMC clock
+      \arg        RCU_SRAM0_SLP: SRAM0 clock
+      \arg        RCU_SRAM1_SLP: SRAM1 clock
+      \arg        RCU_BKPSRAM: BKPSRAM clock
+      \arg        RCU_SRAM2_SLP: SRAM2 clock
+      \arg        RCU_DMAx_SLP (x=0,1): DMA clock
+      \arg        RCU_IPA_SLP: IPA clock
+      \arg        RCU_ENET_SLP: ENET clock
+      \arg        RCU_ENETTX_SLP: ENETTX clock
+      \arg        RCU_ENETRX_SLP: ENETRX clock
+      \arg        RCU_ENETPTP_SLP: ENETPTP clock
+      \arg        RCU_USBHS_SLP: USBHS clock
+      \arg        RCU_USBHSULPI_SLP: USBHSULPI clock
+      \arg        RCU_DCI_SLP: DCI clock
+      \arg        RCU_TRNG_SLP: TRNG clock
+      \arg        RCU_USBFS_SLP: USBFS clock
+      \arg        RCU_EXMC_SLP: EXMC clock
+      \arg        RCU_TIMERx_SLP (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock
+      \arg        RCU_WWDGT_SLP: WWDGT clock
+      \arg        RCU_SPIx_SLP (x=0,1,2,3,4,5): SPI clock
+      \arg        RCU_USARTx_SLP (x=0,1,2,5): USART clock
+      \arg        RCU_UARTx_SLP (x=3,4,6,7): UART clock
+      \arg        RCU_I2Cx_SLP (x=0,1,2): I2C clock
+      \arg        RCU_CANx_SLP (x=0,1): CAN clock
+      \arg        RCU_PMU_SLP: PMU clock
+      \arg        RCU_DAC_SLP: DAC clock
+      \arg        RCU_RTC_SLP: RTC clock
+      \arg        RCU_ADCx_SLP (x=0,1,2): ADC clock
+      \arg        RCU_SDIO_SLP: SDIO clock
+      \arg        RCU_SYSCFG_SLP: SYSCFG clock
+      \arg        RCU_TLI_SLP: TLI clock
+      \arg        RCU_CTC_SLP: CTC clock
+      \arg        RCU_IREF_SLP: IREF clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph)
+{
+    RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      disable the peripherals clock when sleep mode
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_sleep_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOx_SLP (x=A,B,C,D,E,F,G,H,I): GPIO ports clock
+      \arg        RCU_CRC_SLP: CRC clock
+      \arg        RCU_FMC_SLP: FMC clock
+      \arg        RCU_SRAM0_SLP: SRAM0 clock
+      \arg        RCU_SRAM1_SLP: SRAM1 clock
+      \arg        RCU_BKPSRAM: BKPSRAM clock
+      \arg        RCU_SRAM2_SLP: SRAM2 clock
+      \arg        RCU_DMAx_SLP (x=0,1): DMA clock
+      \arg        RCU_IPA_SLP: IPA clock
+      \arg        RCU_ENET_SLP: ENET clock
+      \arg        RCU_ENETTX_SLP: ENETTX clock
+      \arg        RCU_ENETRX_SLP: ENETRX clock
+      \arg        RCU_ENETPTP_SLP: ENETPTP clock
+      \arg        RCU_USBHS_SLP: USBHS clock
+      \arg        RCU_USBHSULPI_SLP: USBHSULPI clock
+      \arg        RCU_DCI_SLP: DCI clock
+      \arg        RCU_TRNG_SLP: TRNG clock
+      \arg        RCU_USBFS_SLP: USBFS clock
+      \arg        RCU_EXMC_SLP: EXMC clock
+      \arg        RCU_TIMERx_SLP (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock
+      \arg        RCU_WWDGT_SLP: WWDGT clock
+      \arg        RCU_SPIx_SLP (x=0,1,2,3,4,5): SPI clock
+      \arg        RCU_USARTx_SLP (x=0,1,2,5): USART clock
+      \arg        RCU_UARTx_SLP (x=3,4,6,7): UART clock
+      \arg        RCU_I2Cx_SLP (x=0,1,2): I2C clock
+      \arg        RCU_CANx_SLP (x=0,1): CAN clock
+      \arg        RCU_PMU_SLP: PMU clock
+      \arg        RCU_DAC_SLP: DAC clock
+      \arg        RCU_RTC_SLP: RTC clock
+      \arg        RCU_ADCx_SLP (x=0,1,2): ADC clock
+      \arg        RCU_SDIO_SLP: SDIO clock
+      \arg        RCU_SYSCFG_SLP: SYSCFG clock
+      \arg        RCU_TLI_SLP: TLI clock
+      \arg        RCU_CTC_SLP: CTC clock
+      \arg        RCU_IREF_SLP: IREF clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph)
+{
+    RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      reset the peripherals
+    \param[in]  periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOxRST (x=A,B,C,D,E,F,G,H,I): reset GPIO ports
+      \arg        RCU_CRCRST: reset CRC
+      \arg        RCU_DMAxRST (x=0,1): reset DMA
+      \arg        RCU_IPAENRST: reset IPA
+      \arg        RCU_ENETRST: reset ENET
+      \arg        RCU_USBHSRST: reset USBHS
+      \arg        RCU_DCIRST: reset DCI
+      \arg        RCU_TRNGRST: reset TRNG
+      \arg        RCU_USBFSRST: reset USBFS
+      \arg        RCU_EXMCRST: reset EXMC
+      \arg        RCU_TIMERxRST (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): reset TIMER
+      \arg        RCU_WWDGTRST: reset WWDGT
+      \arg        RCU_SPIxRST (x=0,1,2,3,4,5): reset SPI
+      \arg        RCU_USARTxRST (x=0,1,2,5): reset USART
+      \arg        RCU_UARTxRST (x=3,4,6,7): reset UART
+      \arg        RCU_I2CxRST (x=0,1,2): reset I2C
+      \arg        RCU_CANxRST (x=0,1): reset CAN
+      \arg        RCU_PMURST: reset PMU
+      \arg        RCU_DACRST: reset DAC
+      \arg        RCU_ADCRST (x=0,1,2): reset ADC
+      \arg        RCU_SDIORST: reset SDIO
+      \arg        RCU_SYSCFGRST: reset SYSCFG
+      \arg        RCU_TLIRST: reset TLI
+      \arg        RCU_CTCRST: reset CTC
+      \arg        RCU_IREFRST: reset IREF
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset)
+{
+    RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset));
+}
+
+/*!
+    \brief      disable reset the peripheral
+    \param[in]  periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOxRST (x=A,B,C,D,E,F,G,H,I): reset GPIO ports
+      \arg        RCU_CRCRST: reset CRC
+      \arg        RCU_DMAxRST (x=0,1): reset DMA
+      \arg        RCU_IPAENRST: reset IPA
+      \arg        RCU_ENETRST: reset ENET
+      \arg        RCU_USBHSRST: reset USBHS
+      \arg        RCU_DCIRST: reset DCI
+      \arg        RCU_TRNGRST: reset TRNG
+      \arg        RCU_USBFSRST: reset USBFS
+      \arg        RCU_EXMCRST: reset EXMC
+      \arg        RCU_TIMERxRST (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): reset TIMER
+      \arg        RCU_WWDGTRST: reset WWDGT
+      \arg        RCU_SPIxRST (x=0,1,2,3,4,5): reset SPI
+      \arg        RCU_USARTxRST (x=0,1,2,5): reset USART
+      \arg        RCU_UARTxRST (x=3,4,6,7): reset UART
+      \arg        RCU_I2CxRST (x=0,1,2): reset I2C
+      \arg        RCU_CANxRST (x=0,1): reset CAN
+      \arg        RCU_PMURST: reset PMU
+      \arg        RCU_DACRST: reset DAC
+      \arg        RCU_ADCRST (x=0,1,2): reset ADC
+      \arg        RCU_SDIORST: reset SDIO
+      \arg        RCU_SYSCFGRST: reset SYSCFG
+      \arg        RCU_TLIRST: reset TLI
+      \arg        RCU_CTCRST: reset CTC
+      \arg        RCU_IREFRST: reset IREF
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset)
+{
+    RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset));
+}
+
+/*!
+    \brief      reset the BKP
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_bkp_reset_enable(void)
+{
+    RCU_BDCTL |= RCU_BDCTL_BKPRST;
+}
+
+/*!
+    \brief      disable the BKP reset
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_bkp_reset_disable(void)
+{
+    RCU_BDCTL &= ~RCU_BDCTL_BKPRST;
+}
+
+/*!
+    \brief      configure the system clock source
+    \param[in]  ck_sys: system clock source select
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_CKSYSSRC_IRC16M: select CK_IRC16M as the CK_SYS source
+      \arg        RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source
+      \arg        RCU_CKSYSSRC_PLLP: select CK_PLLP as the CK_SYS source
+    \param[out] none
+    \retval     none
+*/
+void rcu_system_clock_source_config(uint32_t ck_sys)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0;
+    /* reset the SCS bits and set according to ck_sys */
+    reg &= ~RCU_CFG0_SCS;
+    RCU_CFG0 = (reg | ck_sys);
+}
+
+/*!
+    \brief      get the system clock source
+    \param[in]  none
+    \param[out] none
+    \retval     which clock is selected as CK_SYS source
+      \arg        RCU_SCSS_IRC16M: CK_IRC16M is selected as the CK_SYS source
+      \arg        RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source
+      \arg        RCU_SCSS_PLLP: CK_PLLP is selected as the CK_SYS source
+*/
+uint32_t rcu_system_clock_source_get(void)
+{
+    return (RCU_CFG0 & RCU_CFG0_SCSS);
+}
+
+/*!
+    \brief      configure the AHB clock prescaler selection
+    \param[in]  ck_ahb: AHB clock prescaler selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512
+    \param[out] none
+    \retval     none
+*/
+void rcu_ahb_clock_config(uint32_t ck_ahb)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0;
+    /* reset the AHBPS bits and set according to ck_ahb */
+    reg &= ~RCU_CFG0_AHBPSC;
+    RCU_CFG0 = (reg | ck_ahb);
+}
+
+/*!
+    \brief      configure the APB1 clock prescaler selection
+    \param[in]  ck_apb1: APB1 clock prescaler selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1
+    \param[out] none
+    \retval     none
+*/
+void rcu_apb1_clock_config(uint32_t ck_apb1)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0;
+    /* reset the APB1PS and set according to ck_apb1 */
+    reg &= ~RCU_CFG0_APB1PSC;
+    RCU_CFG0 = (reg | ck_apb1);
+}
+
+/*!
+    \brief      configure the APB2 clock prescaler selection
+    \param[in]  ck_apb2: APB2 clock prescaler selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2
+    \param[out] none
+    \retval     none
+*/
+void rcu_apb2_clock_config(uint32_t ck_apb2)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0;
+    /* reset the APB2PS and set according to ck_apb2 */
+    reg &= ~RCU_CFG0_APB2PSC;
+    RCU_CFG0 = (reg | ck_apb2);
+}
+
+/*!
+    \brief      configure the CK_OUT0 clock source and divider
+    \param[in]  ckout0_src: CK_OUT0 clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_CKOUT0SRC_IRC16M: IRC16M selected
+      \arg        RCU_CKOUT0SRC_LXTAL: LXTAL selected
+      \arg        RCU_CKOUT0SRC_HXTAL: HXTAL selected
+      \arg        RCU_CKOUT0SRC_PLLP: PLLP selected
+    \param[in]  ckout0_div: CK_OUT0 divider 
+      \arg        RCU_CKOUT0_DIVx(x=1,2,3,4,5): CK_OUT0 is divided by x
+    \param[out] none
+    \retval     none
+*/
+void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0;
+    /* reset the CKOUT0SRC, CKOUT0DIV and set according to ckout0_src and ckout0_div */
+    reg &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV );
+    RCU_CFG0 = (reg | ckout0_src | ckout0_div);
+}
+
+/*!
+    \brief      configure the CK_OUT1 clock source and divider
+    \param[in]  ckout1_src: CK_OUT1 clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_CKOUT1SRC_SYSTEMCLOCK: system clock selected
+      \arg        RCU_CKOUT1SRC_PLLI2SR: PLLI2SR selected
+      \arg        RCU_CKOUT1SRC_HXTAL: HXTAL selected
+      \arg        RCU_CKOUT1SRC_PLLP: PLLP selected           
+    \param[in]  ckout1_div: CK_OUT1 divider 
+      \arg        RCU_CKOUT1_DIVx(x=1,2,3,4,5): CK_OUT1 is divided by x
+    \param[out] none
+    \retval     none
+*/
+void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0;
+    /* reset the CKOUT1SRC, CKOUT1DIV and set according to ckout1_src and ckout1_div */
+    reg &= ~(RCU_CFG0_CKOUT1SEL | RCU_CFG0_CKOUT1DIV);
+    RCU_CFG0 = (reg | ckout1_src | ckout1_div);
+}
+
+/*!
+    \brief      configure the main PLL clock 
+    \param[in]  pll_src: PLL clock source selection
+      \arg        RCU_PLLSRC_IRC16M: select IRC16M as PLL source clock
+      \arg        RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock
+    \param[in]  pll_psc: the PLL VCO source clock prescaler
+      \arg         this parameter should be selected between 2 and 63
+    \param[in]  pll_n: the PLL VCO clock multi factor
+      \arg        this parameter should be selected between 64 and 500
+    \param[in]  pll_p: the PLLP output frequency division factor from PLL VCO clock
+      \arg        this parameter should be selected 2,4,6,8
+    \param[in]  pll_q: the PLL Q output frequency division factor from PLL VCO clock
+      \arg        this parameter should be selected between 2 and 15
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uint32_t pll_p, uint32_t pll_q)
+{
+    uint32_t ss_modulation_inc;
+    uint32_t ss_modulation_reg;
+    
+    ss_modulation_inc = 0U;
+    ss_modulation_reg = RCU_PLLSSCTL;
+
+    /* calculate the minimum factor of PLLN */
+    if((ss_modulation_reg & RCU_PLLSSCTL_SSCGON) == RCU_PLLSSCTL_SSCGON){
+        if((ss_modulation_reg & RCU_SS_TYPE_DOWN) == RCU_SS_TYPE_DOWN){
+            ss_modulation_inc += RCU_SS_MODULATION_DOWN_INC;
+        }else{
+            ss_modulation_inc += RCU_SS_MODULATION_CENTER_INC;
+        }
+    }
+    
+    /* check the function parameter */
+    if(CHECK_PLL_PSC_VALID(pll_psc) && CHECK_PLL_N_VALID(pll_n,ss_modulation_inc) && 
+       CHECK_PLL_P_VALID(pll_p) && CHECK_PLL_Q_VALID(pll_q)){
+         RCU_PLL = pll_psc | (pll_n << 6) | (((pll_p >> 1) - 1U) << 16) |
+                   (pll_src) | (pll_q << 24);
+    }else{
+        /* return status */
+        return ERROR;
+    }
+    
+    /* return status */
+    return SUCCESS;
+}
+
+/*!
+    \brief      configure the PLLI2S clock 
+    \param[in]  plli2s_n: the PLLI2S VCO clock multi factor
+      \arg        this parameter should be selected between 50 and 500
+    \param[in]  plli2s_q: the PLLI2S Q output frequency division factor from PLLI2S VCO clock
+      \arg        this parameter should be selected between 2 and 15
+    \param[in]  plli2s_r: the PLLI2S R output frequency division factor from PLLI2S VCO clock
+      \arg        this parameter should be selected between 2 and 7
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_q, uint32_t plli2s_r)
+{
+    /* check the function parameter */
+    if(CHECK_PLLI2S_N_VALID(plli2s_n) && CHECK_PLLI2S_Q_VALID(plli2s_q) && CHECK_PLLI2S_R_VALID(plli2s_r)){
+        RCU_PLLI2S = (plli2s_n << 6) | (plli2s_q << 24) | (plli2s_r << 28);
+    }else{
+        /* return status */
+        return ERROR;
+    }
+    
+    /* return status */
+    return SUCCESS;  
+}
+
+/*!
+    \brief      configure the PLLSAI clock 
+    \param[in]  pllsai_n: the PLLSAI VCO clock multi factor
+      \arg        this parameter should be selected between 50 and 500
+    \param[in]  pllsai_p: the PLLSAI P output frequency division factor from PLL VCO clock
+      \arg        this parameter should be selected 2,4,6,8
+    \param[in]  pllsai_q: the PLLSAI Q output frequency division factor from PLL VCO clock
+      \arg        this parameter should be selected between 2 and 15
+    \param[in]  pllsai_r: the PLLSAI R output frequency division factor from PLL VCO clock
+      \arg        this parameter should be selected between 2 and 7
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_q, uint32_t pllsai_r)
+{
+    /* check the function parameter */
+    if(CHECK_PLLSAI_N_VALID(pllsai_n) && CHECK_PLLSAI_P_VALID(pllsai_p) && 
+       CHECK_PLLSAI_Q_VALID(pllsai_q) && CHECK_PLLSAI_R_VALID(pllsai_r)){
+        RCU_PLLSAI = (pllsai_n << 6U) | (((pllsai_p >> 1U) - 1U) << 16U) | (pllsai_q << 24U) | (pllsai_r << 28U);
+    }else{
+        /* return status */
+        return ERROR;
+    }
+    
+    /* return status */
+    return SUCCESS;
+}
+
+/*!
+    \brief      configure the RTC clock source selection
+    \param[in]  rtc_clock_source: RTC clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_RTCSRC_NONE: no clock selected
+      \arg        RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock
+      \arg        RCU_RTCSRC_IRC32K: CK_IRC32K selected as RTC source clock
+      \arg        RCU_RTCSRC_HXTAL_DIV_RTCDIV: CK_HXTAL/RTCDIV selected as RTC source clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_rtc_clock_config(uint32_t rtc_clock_source)
+{
+    uint32_t reg;
+    
+    reg = RCU_BDCTL; 
+    /* reset the RTCSRC bits and set according to rtc_clock_source */
+    reg &= ~RCU_BDCTL_RTCSRC;
+    RCU_BDCTL = (reg | rtc_clock_source);
+}
+
+/*!
+    \brief      configure the I2S clock source selection
+    \param[in]  i2s_clock_source: I2S clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_I2SSRC_PLLI2S: CK_PLLI2S selected as I2S source clock
+      \arg        RCU_I2SSRC_I2S_CKIN: external i2s_ckin pin selected as I2S source clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_i2s_clock_config(uint32_t i2s_clock_source)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG0; 
+    /* reset the I2SSEL bit and set according to i2s_clock_source */
+    reg &= ~RCU_CFG0_I2SSEL;
+    RCU_CFG0 = (reg | i2s_clock_source);
+}
+
+/*!
+    \brief      configure the CK48M clock source selection
+    \param[in]  ck48m_clock_source: CK48M clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_CK48MSRC_PLL48M: CK_PLL48M selected as CK48M source clock
+      \arg        RCU_CK48MSRC_IRC48M: CK_IRC48M selected as CK48M source clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_ck48m_clock_config(uint32_t ck48m_clock_source)
+{
+    uint32_t reg;
+    
+    reg = RCU_ADDCTL;
+    /* reset the I2SSEL bit and set according to i2s_clock_source */
+    reg &= ~RCU_ADDCTL_CK48MSEL;
+    RCU_ADDCTL = (reg | ck48m_clock_source);
+}
+
+/*!
+    \brief      configure the PLL48M clock source selection
+    \param[in]  pll48m_clock_source: PLL48M clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_PLL48MSRC_PLLQ: CK_PLLQ selected as PLL48M source clock
+      \arg        RCU_PLL48MSRC_PLLSAIP: CK_PLLSAIP selected as PLL48M source clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_pll48m_clock_config(uint32_t pll48m_clock_source)
+{
+    uint32_t reg;
+    
+    reg = RCU_ADDCTL;
+    /* reset the PLL48MSEL bit and set according to pll48m_clock_source */
+    reg &= ~RCU_ADDCTL_PLL48MSEL;
+    RCU_ADDCTL = (reg | pll48m_clock_source);
+}
+
+/*!
+    \brief      configure the TIMER clock prescaler selection
+    \param[in]  timer_clock_prescaler: TIMER clock selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_TIMER_PSC_MUL2: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) 
+                                      or 0b100(CK_APBx = CK_AHB/2), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB).
+                                      or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; 
+                                      TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2)
+      \arg        RCU_TIMER_PSC_MUL4: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), 
+                                      0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). 
+                                      or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1;  
+                                      TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2)
+    \param[out] none
+    \retval     none
+*/
+void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler)
+{
+    /* configure the TIMERSEL bit and select the TIMER clock prescaler */
+    if(timer_clock_prescaler == RCU_TIMER_PSC_MUL2){
+        RCU_CFG1 &= timer_clock_prescaler;
+    }else{
+        RCU_CFG1 |= timer_clock_prescaler;
+    }
+}
+
+/*!
+    \brief      configure the PLLSAIR divider used as input of TLI
+    \param[in]  pllsai_r_div: PLLSAIR divider used as input of TLI
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_PLLSAIR_DIVx(x=2,4,8,16): PLLSAIR divided x used as input of TLI
+    \param[out] none
+    \retval     none
+*/
+void rcu_tli_clock_div_config(uint32_t pllsai_r_div)
+{
+    uint32_t reg;
+    
+    reg = RCU_CFG1;
+    /* reset the PLLSAIRDIV bit and set according to pllsai_r_div */
+    reg &= ~RCU_CFG1_PLLSAIRDIV;
+    RCU_CFG1 = (reg | pllsai_r_div);
+}
+
+/*!
+    \brief      get the clock stabilization and periphral reset flags
+    \param[in]  flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_FLAG_IRC16MSTB: IRC16M stabilization flag
+      \arg        RCU_FLAG_HXTALSTB: HXTAL stabilization flag
+      \arg        RCU_FLAG_PLLSTB: PLL stabilization flag
+      \arg        RCU_FLAG_PLLI2SSTB: PLLI2S stabilization flag
+      \arg        RCU_FLAG_PLLSAISTB: PLLSAI stabilization flag
+      \arg        RCU_FLAG_LXTALSTB: LXTAL stabilization flag
+      \arg        RCU_FLAG_IRC32KSTB: IRC32K stabilization flag
+      \arg        RCU_FLAG_IRC48MSTB: IRC48M stabilization flag
+      \arg        RCU_FLAG_BORRST: BOR reset flags
+      \arg        RCU_FLAG_EPRST: external PIN reset flag
+      \arg        RCU_FLAG_PORRST: Power reset flag
+      \arg        RCU_FLAG_SWRST: software reset flag
+      \arg        RCU_FLAG_FWDGTRST: free watchdog timer reset flag
+      \arg        RCU_FLAG_WWDGTRST: window watchdog timer reset flag
+      \arg        RCU_FLAG_LPRST: low-power reset flag
+    \param[out] none
+    \retval     none
+*/
+FlagStatus rcu_flag_get(rcu_flag_enum flag)
+{
+    /* get the rcu flag */
+    if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear all the reset flag
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_all_reset_flag_clear(void)
+{
+    RCU_RSTSCK |= RCU_RSTSCK_RSTFC;
+}
+
+/*!
+    \brief      get the clock stabilization interrupt and ckm flags
+    \param[in]  int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_FLAG_IRC32KSTB: IRC40K stabilization interrupt flag
+      \arg        RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag
+      \arg        RCU_INT_FLAG_IRC8MSTB: IRC8M stabilization interrupt flag
+      \arg        RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag
+      \arg        RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag
+      \arg        RCU_INT_FLAG_PLLI2SSTB: PLLI2S stabilization interrupt flag
+      \arg        RCU_INT_FLAG_PLLSAISTB: PLLSAI stabilization interrupt flag
+      \arg        RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag
+      \arg        RCU_INT_FLAG_IRC48MSTB: IRC48M stabilization interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag)
+{
+    /* get the rcu interrupt flag */
+    if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the interrupt flags
+    \param[in]  int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_FLAG_IRC32KSTB_CLR: IRC32K stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_IRC16MSTB_CLR: IRC16M stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_PLLI2SSTB_CLR: PLLI2S stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_PLLSAISTB_CLR: PLLSAI stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear
+      \arg        RCU_INT_FLAG_IRC48MSTB_CLR: IRC48M stabilization interrupt flag clear
+    \param[out] none
+    \retval     none
+*/
+void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear)
+{
+    RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear));
+}
+
+/*!
+    \brief      enable the stabilization interrupt
+    \param[in]  stab_int: clock stabilization interrupt, refer to rcu_int_enum
+                Only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_IRC32KSTB: IRC32K stabilization interrupt enable
+      \arg        RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable
+      \arg        RCU_INT_IRC16MSTB: IRC16M stabilization interrupt enable
+      \arg        RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable
+      \arg        RCU_INT_PLLSTB: PLL stabilization interrupt enable
+      \arg        RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt enable
+      \arg        RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt enable
+      \arg        RCU_INT_IRC48MSTB: IRC48M stabilization interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void rcu_interrupt_enable(rcu_int_enum stab_int)
+{
+    RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int));
+}
+
+
+/*!
+    \brief      disable the stabilization interrupt
+    \param[in]  stab_int: clock stabilization interrupt, refer to rcu_int_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_IRC32KSTB: IRC32K stabilization interrupt disable
+      \arg        RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable
+      \arg        RCU_INT_IRC16MSTB: IRC16M stabilization interrupt disable
+      \arg        RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable
+      \arg        RCU_INT_PLLSTB: PLL stabilization interrupt disable
+      \arg        RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt disable
+      \arg        RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt disable
+      \arg        RCU_INT_IRC48MSTB: IRC48M stabilization interrupt disable
+    \param[out] none
+    \retval     none
+*/
+void rcu_interrupt_disable(rcu_int_enum stab_int)
+{
+    RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int));
+}
+
+/*!
+    \brief      configure the LXTAL drive capability
+    \param[in]  lxtal_dricap: drive capability of LXTAL
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_LXTALDRI_LOWER_DRIVE: lower driving capability
+      \arg        RCU_LXTALDRI_HIGHER_DRIVE: higher driving capability
+    \param[out] none
+    \retval     none
+*/
+void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap)
+{
+    uint32_t reg;
+    
+    reg = RCU_BDCTL;
+    
+    /* reset the LXTALDRI bits and set according to lxtal_dricap */
+    reg &= ~RCU_BDCTL_LXTALDRI;
+    RCU_BDCTL = (reg | lxtal_dricap);
+}
+
+/*!
+    \brief      wait for oscillator stabilization flags is SET or oscillator startup is timeout
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+      \arg        RCU_IRC16M: IRC16M
+      \arg        RCU_IRC48M: IRC48M
+      \arg        RCU_IRC32K: IRC32K
+      \arg        RCU_PLL_CK: PLL
+      \arg        RCU_PLLI2S_CK: PLLI2S
+      \arg        RCU_PLLSAI_CK: PLLSAI
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci)
+{
+    uint32_t stb_cnt = 0U;
+    ErrStatus reval = ERROR;
+    FlagStatus osci_stat = RESET;
+    
+    switch(osci){
+    /* wait HXTAL stable */
+    case RCU_HXTAL:
+        while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait LXTAL stable */
+    case RCU_LXTAL:
+        while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait IRC16M stable */    
+    case RCU_IRC16M:
+        while((RESET == osci_stat) && (IRC16M_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_IRC16MSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_IRC16MSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait IRC48M stable */    
+    case RCU_IRC48M:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_IRC48MSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if (RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait IRC32K stable */
+    case RCU_IRC32K:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_IRC32KSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait PLL stable */    
+    case RCU_PLL_CK:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait PLLI2S stable */
+    case RCU_PLLI2S_CK:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_PLLI2SSTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_PLLI2SSTB)){
+            reval = SUCCESS;
+        }
+        break;
+    /* wait PLLSAI stable */    
+    case RCU_PLLSAI_CK:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_PLLSAISTB);
+            stb_cnt++;
+        }
+        
+        /* check whether flag is set */
+        if(RESET != rcu_flag_get(RCU_FLAG_PLLSAISTB)){
+            reval = SUCCESS;
+        }
+        break;
+    
+    default:
+        break;
+    }
+    
+    /* return value */
+    return reval;
+}
+
+/*!
+    \brief      turn on the oscillator
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+      \arg        RCU_IRC16M: IRC16M
+      \arg        RCU_IRC48M: IRC48M
+      \arg        RCU_IRC32K: IRC32K
+      \arg        RCU_PLL_CK: PLL
+      \arg        RCU_PLLI2S_CK: PLLI2S
+      \arg        RCU_PLLSAI_CK: PLLSAI
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_on(rcu_osci_type_enum osci)
+{
+    RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci));
+}
+
+/*!
+    \brief      turn off the oscillator
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+      \arg        RCU_IRC16M: IRC16M
+      \arg        RCU_IRC48M: IRC48M
+      \arg        RCU_IRC32K: IRC32K
+      \arg        RCU_PLL_CK: PLL
+      \arg        RCU_PLLI2S_CK: PLLI2S
+      \arg        RCU_PLLSAI_CK: PLLSAI
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_off(rcu_osci_type_enum osci)
+{
+    RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci));
+}
+
+/*!
+    \brief      enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci)
+{
+    uint32_t reg;
+
+    switch(osci){
+    /* enable HXTAL to bypass mode */    
+    case RCU_HXTAL:
+        reg = RCU_CTL;
+        RCU_CTL &= ~RCU_CTL_HXTALEN;
+        RCU_CTL = (reg | RCU_CTL_HXTALBPS);
+        break;
+    /* enable LXTAL to bypass mode */
+    case RCU_LXTAL:
+        reg = RCU_BDCTL;
+        RCU_BDCTL &= ~RCU_BDCTL_LXTALEN;
+        RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS);
+        break;
+    case RCU_IRC16M:
+    case RCU_IRC48M:
+    case RCU_IRC32K:
+    case RCU_PLL_CK:
+    case RCU_PLLI2S_CK:
+    case RCU_PLLSAI_CK:    
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci)
+{
+    uint32_t reg;
+    
+    switch(osci){
+    /* disable HXTAL to bypass mode */    
+    case RCU_HXTAL:
+        reg = RCU_CTL;
+        RCU_CTL &= ~RCU_CTL_HXTALEN;
+        RCU_CTL = (reg & ~RCU_CTL_HXTALBPS);
+        break;
+    /* disable LXTAL to bypass mode */
+    case RCU_LXTAL:
+        reg = RCU_BDCTL;
+        RCU_BDCTL &= ~RCU_BDCTL_LXTALEN;
+        RCU_BDCTL = (reg & ~RCU_BDCTL_LXTALBPS);
+        break;
+    case RCU_IRC16M:
+    case RCU_IRC48M:
+    case RCU_IRC32K:
+    case RCU_PLL_CK:
+    case RCU_PLLI2S_CK:
+    case RCU_PLLSAI_CK:    
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      enable the HXTAL clock monitor
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+
+void rcu_hxtal_clock_monitor_enable(void)
+{
+    RCU_CTL |= RCU_CTL_CKMEN;
+}
+
+/*!
+    \brief      disable the HXTAL clock monitor
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_hxtal_clock_monitor_disable(void)
+{
+    RCU_CTL &= ~RCU_CTL_CKMEN;
+}
+
+/*!
+    \brief      set the IRC16M adjust value
+    \param[in]  irc16m_adjval: IRC16M adjust value, must be between 0 and 0x1F
+    \param[out] none
+    \retval     none
+*/
+void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval)
+{
+    uint32_t reg;
+    
+    reg = RCU_CTL;
+    /* reset the IRC16MADJ bits and set according to irc16m_adjval */
+    reg &= ~RCU_CTL_IRC16MADJ;
+    RCU_CTL = (reg | ((irc16m_adjval & 0x1FU) << 3));
+}
+
+/*!
+    \brief      unlock the voltage key
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_voltage_key_unlock(void)
+{
+    RCU_VKEY = RCU_VKEY_UNLOCK;
+}
+
+/*!
+    \brief      deep-sleep mode voltage select
+    \param[in]  dsvol: deep sleep mode voltage
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V
+      \arg        RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V
+      \arg        RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V
+      \arg        RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V
+    \param[out] none
+    \retval     none
+*/
+void rcu_deepsleep_voltage_set(uint32_t dsvol)
+{    
+    dsvol &= RCU_DSV_DSLPVS;
+    RCU_DSV = dsvol;
+}
+
+/*!
+    \brief      configure the spread spectrum modulation for the main PLL clock
+    \param[in]  spread_spectrum_type: PLL spread spectrum modulation type select
+      \arg        RCU_SS_TYPE_CENTER: center spread type is selected
+      \arg        RCU_SS_TYPE_DOWN: down spread type is selected
+    \param[in]  modstep: configure PLL spread spectrum modulation profile amplitude and frequency
+      \arg        This parameter should be selected between 0 and 7FFF.The following criteria must be met: MODSTEP*MODCNT=215-1
+    \param[in]  modcnt: configure PLL spread spectrum modulation profile amplitude and frequency
+      \arg        This parameter should be selected between 0 and 1FFF.The following criteria must be met: MODSTEP*MODCNT=215-1
+    \param[out] none
+    \retval     none
+*/
+void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt)
+{
+    uint32_t reg;
+    
+    reg = RCU_PLLSSCTL;
+    /* reset the RCU_PLLSSCTL register bits */
+    reg &= ~(RCU_PLLSSCTL_MODCNT | RCU_PLLSSCTL_MODSTEP | RCU_PLLSSCTL_SS_TYPE);
+    RCU_PLLSSCTL = (reg | spread_spectrum_type | modstep << 13 | modcnt);
+}
+
+/*!
+    \brief      enable the PLL spread spectrum modulation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_spread_spectrum_enable(void)
+{
+    RCU_PLLSSCTL |= RCU_PLLSSCTL_SSCGON;
+}
+
+/*!
+    \brief      disable the PLL spread spectrum modulation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_spread_spectrum_disable(void)
+{
+    RCU_PLLSSCTL &= ~RCU_PLLSSCTL_SSCGON;
+}
+
+/*!
+    \brief      get the system clock, bus and peripheral clock frequency
+    \param[in]  clock: the clock frequency which to get
+                only one parameter can be selected which is shown as below:
+      \arg        CK_SYS: system clock frequency
+      \arg        CK_AHB: AHB clock frequency
+      \arg        CK_APB1: APB1 clock frequency
+      \arg        CK_APB2: APB2 clock frequency
+    \param[out] none
+    \retval     clock frequency of system, AHB, APB1, APB2
+*/
+uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock)
+{
+    uint32_t sws, ck_freq = 0U;
+    uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq;
+    uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp;
+    
+    /* exponent of AHB, APB1 and APB2 clock divider */
+    const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+    const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+    const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+    sws = GET_BITS(RCU_CFG0, 2, 3);
+    switch(sws){
+    /* IRC16M is selected as CK_SYS */
+    case SEL_IRC16M:
+        cksys_freq = IRC16M_VALUE;
+        break;
+    /* HXTAL is selected as CK_SYS */
+    case SEL_HXTAL:
+        cksys_freq = HXTAL_VALUE;
+        break;
+    /* PLLP is selected as CK_SYS */
+    case SEL_PLLP:
+        /* get the value of PLLPSC[5:0] */
+        pllpsc = GET_BITS(RCU_PLL, 0U, 5U);
+        plln = GET_BITS(RCU_PLL, 6U, 14U);
+        pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U;
+        /* PLL clock source selection, HXTAL or IRC8M/2 */
+        pllsel = (RCU_PLL & RCU_PLL_PLLSEL);
+        if (RCU_PLLSRC_HXTAL == pllsel) {
+            ck_src = HXTAL_VALUE;
+        } else {
+            ck_src = IRC16M_VALUE;
+        }
+        cksys_freq = ((ck_src / pllpsc) * plln)/pllp;
+        break;
+    /* IRC16M is selected as CK_SYS */
+    default:
+        cksys_freq = IRC16M_VALUE;
+        break;
+    }
+    /* calculate AHB clock frequency */
+    idx = GET_BITS(RCU_CFG0, 4, 7);
+    clk_exp = ahb_exp[idx];
+    ahb_freq = cksys_freq >> clk_exp;
+    
+    /* calculate APB1 clock frequency */
+    idx = GET_BITS(RCU_CFG0, 10, 12);
+    clk_exp = apb1_exp[idx];
+    apb1_freq = ahb_freq >> clk_exp;
+    
+    /* calculate APB2 clock frequency */
+    idx = GET_BITS(RCU_CFG0, 13, 15);
+    clk_exp = apb2_exp[idx];
+    apb2_freq = ahb_freq >> clk_exp;
+    
+    /* return the clocks frequency */
+    switch(clock){
+    case CK_SYS:
+        ck_freq = cksys_freq;
+        break;
+    case CK_AHB:
+        ck_freq = ahb_freq;
+        break;
+    case CK_APB1:
+        ck_freq = apb1_freq;
+        break;
+    case CK_APB2:
+        ck_freq = apb2_freq;
+        break;
+    default:
+        break;
+    }
+    return ck_freq;
+}

+ 1257 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c

@@ -0,0 +1,1257 @@
+/*!
+    \file  gd32f4xx_rtc.c
+    \brief RTC driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_rtc.h"
+
+/* RTC timeout value */
+#define RTC_WTWF_TIMEOUT                   ((uint32_t)0x00004000U)                    /*!< wakeup timer can be write flag timeout */
+#define RTC_INITM_TIMEOUT                  ((uint32_t)0x00004000U)                    /*!< initialization state flag timeout */
+#define RTC_RSYNF_TIMEOUT                  ((uint32_t)0x00008000U)                    /*!< register synchronization flag timeout */
+#define RTC_HRFC_TIMEOUT                   ((uint32_t)0x20000000U)                    /*!< recalibration pending flag timeout */
+#define RTC_SHIFTCTL_TIMEOUT               ((uint32_t)0x00001000U)                    /*!< shift function operation pending flag timeout */
+#define RTC_ALRMXWF_TIMEOUT                ((uint32_t)0x00008000U)                    /*!< alarm configuration can be write flag timeout */
+
+
+/*!
+    \brief      reset most of the RTC registers
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_deinit(void)
+{
+    ErrStatus error_status = ERROR;
+    volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
+    uint32_t flag_status = RESET;
+    /* RTC_TAMP register is not under write protection */
+    RTC_TAMP = RTC_REGISTER_RESET;
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){
+        /* reset RTC_CTL register, but RTC_CTL[2£º0] */
+        RTC_CTL &= (RTC_REGISTER_RESET | RTC_CTL_WTCS);
+        /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition.
+           in order to read calendar from shadow register, not the real registers being reset */
+        RTC_TIME = RTC_REGISTER_RESET;
+        RTC_DATE = RTC_DATE_RESET;
+
+        RTC_PSC = RTC_PSC_RESET;
+        /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2£º0] */
+        /* wait until the WTWF flag to be set */
+        do{
+           flag_status = RTC_STAT & RTC_STAT_WTWF;
+        }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+
+        if ((uint32_t)RESET == flag_status){
+            error_status = ERROR;
+        }else{
+            RTC_CTL &= RTC_REGISTER_RESET;
+            RTC_WUT = RTC_WUT_RESET;
+            RTC_COSC = RTC_REGISTER_RESET;
+            /* to write RTC_ALRMxSS register, ALRMxEN bit in RTC_CTL register should be reset as the condition */
+            RTC_ALRM0TD = RTC_REGISTER_RESET;        
+            RTC_ALRM1TD = RTC_REGISTER_RESET;
+            RTC_ALRM0SS = RTC_REGISTER_RESET;
+            RTC_ALRM1SS = RTC_REGISTER_RESET;
+            /* reset RTC_STAT register, also exit init mode.
+               at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */
+            RTC_STAT = RTC_STAT_RESET;
+            /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */
+            RTC_SHIFTCTL   = RTC_REGISTER_RESET;       
+            RTC_HRFC       = RTC_REGISTER_RESET;
+            error_status = rtc_register_sync_wait(); 
+        }
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      initialize RTC registers
+    \param[in]  rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains 
+                parameters for initialization of the rtc peripheral
+                members of the structure and the member values are shown as below:
+                  year: 0x0 - 0x99(BCD format)
+                  month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
+                             RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
+                  date: 0x1 - 0x31(BCD format)
+                  day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
+                                   RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
+                  hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
+                  minute: 0x0 - 0x59(BCD format)
+                  second: 0x0 - 0x59(BCD format)
+                  factor_asyn: 0x0 - 0x7F
+                  factor_syn: 0x0 - 0x7FFF
+                  am_pm: RTC_AM, RTC_PM
+                  display_format: RTC_24HOUR, RTC_12HOUR
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)
+{
+    ErrStatus error_status = ERROR;
+    uint32_t reg_time = 0U, reg_date = 0U;
+
+    reg_date = (DATE_YR(rtc_initpara_struct->year) | \
+                DATE_DOW(rtc_initpara_struct->day_of_week) | \
+                DATE_MON(rtc_initpara_struct->month) | \
+                DATE_DAY(rtc_initpara_struct->date)); 
+    
+    reg_time = (rtc_initpara_struct->am_pm| \
+                TIME_HR(rtc_initpara_struct->hour)  | \
+                TIME_MN(rtc_initpara_struct->minute) | \
+                TIME_SC(rtc_initpara_struct->second)); 
+              
+    /* 1st: disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* 2nd: enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){    
+        RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn)| \
+                             PSC_FACTOR_S(rtc_initpara_struct->factor_syn));
+
+        RTC_TIME = (uint32_t)reg_time;
+        RTC_DATE = (uint32_t)reg_date;
+
+        RTC_CTL &= (uint32_t)(~RTC_CTL_CS);
+        RTC_CTL |=  rtc_initpara_struct->display_format;
+        
+        /* 3rd: exit init mode */  
+        rtc_init_mode_exit();
+        
+        /* 4th: wait the RSYNF flag to set */          
+        error_status = rtc_register_sync_wait();
+    }
+
+    /* 5th:  enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enter RTC init mode
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_init_mode_enter(void)
+{
+    volatile uint32_t time_index = RTC_INITM_TIMEOUT;
+    uint32_t flag_status = RESET;
+    ErrStatus error_status = ERROR;
+
+    /* check whether it has been in init mode */
+    if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){   
+        RTC_STAT |= RTC_STAT_INITM;
+        
+        /* wait until the INITF flag to be set */
+        do{
+           flag_status = RTC_STAT & RTC_STAT_INITF;
+        }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+
+        if ((uint32_t)RESET != flag_status){        
+            error_status = SUCCESS;
+        }
+    }else{
+        error_status = SUCCESS;
+    }
+    return error_status;
+}
+
+/*!
+    \brief      exit RTC init mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_init_mode_exit(void)
+{
+    RTC_STAT &= (uint32_t)(~RTC_STAT_INITM);
+}
+
+/*!
+    \brief      wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow 
+                registers are updated
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_register_sync_wait(void)
+{
+    volatile uint32_t time_index = RTC_RSYNF_TIMEOUT;
+    uint32_t flag_status = RESET;
+    ErrStatus error_status = ERROR;
+
+    if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){
+        /* disable the write protection */
+        RTC_WPK = RTC_UNLOCK_KEY1;
+        RTC_WPK = RTC_UNLOCK_KEY2;
+
+        /* firstly clear RSYNF flag */
+        RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF);
+
+        /* wait until RSYNF flag to be set */
+        do{
+            flag_status = RTC_STAT & RTC_STAT_RSYNF;
+        }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+
+        if ((uint32_t)RESET != flag_status){  
+            error_status = SUCCESS;
+        }
+        
+        /* enable the write protection */
+        RTC_WPK = RTC_LOCK_KEY;
+    }else{ 
+        error_status = SUCCESS;
+    }
+
+    return error_status;
+}
+
+/*!
+    \brief      get current time and date
+    \param[in]  none
+    \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains 
+                parameters for initialization of the rtc peripheral
+                members of the structure and the member values are shown as below:
+                  year: 0x0 - 0x99(BCD format)
+                  month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
+                             RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
+                  date: 0x1 - 0x31(BCD format)
+                  day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
+                                   RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
+                  hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
+                  minute: 0x0 - 0x59(BCD format)
+                  second: 0x0 - 0x59(BCD format)
+                  factor_asyn: 0x0 - 0x7F
+                  factor_syn: 0x0 - 0x7FFF
+                  am_pm: RTC_AM, RTC_PM
+                  display_format: RTC_24HOUR, RTC_12HOUR
+    \retval     none
+*/
+void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct)
+{
+    uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U;
+
+    temp_tr = (uint32_t)RTC_TIME;   
+    temp_dr = (uint32_t)RTC_DATE;
+    temp_pscr = (uint32_t)RTC_PSC;
+    temp_ctlr = (uint32_t)RTC_CTL;
+  
+    /* get current time and construct rtc_parameter_struct structure */
+    rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr);
+    rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr);
+    rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr);
+    rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr);  
+    rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr);
+    rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr);
+    rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr);
+    rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr);
+    rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr);
+    rtc_initpara_struct->am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); 
+    rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS);
+}
+
+/*!
+    \brief      get current subsecond value
+    \param[in]  none
+    \param[out] none
+    \retval     current subsecond value
+*/
+uint32_t rtc_subsecond_get(void)
+{
+    uint32_t reg = 0U;
+    /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */
+    reg = (uint32_t)RTC_SS;
+    /* read RTC_DATE to unlock the 3 shadow registers */
+    (void) (RTC_DATE);
+
+    return reg;
+}
+
+/*!
+    \brief      configure RTC alarm
+    \param[in]  rtc_alarm: RTC_ALARM0 or RTC_ALARM1
+    \param[in]  rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains 
+                parameters for RTC alarm configuration
+                members of the structure and the member values are shown as below:
+                  alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
+                                  RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
+                  weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
+                  alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
+                                 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
+                                    RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
+                  alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
+                  alarm_minute: 0x0 - 0x59(BCD format)
+                  alarm_second: 0x0 - 0x59(BCD format)
+                  am_pm: RTC_AM, RTC_PM
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time)
+{
+    uint32_t reg_alrmtd = 0U;
+
+    reg_alrmtd =(rtc_alarm_time->alarm_mask | \
+                 rtc_alarm_time->weekday_or_date | \
+                 rtc_alarm_time->am_pm | \
+                 ALRMTD_DAY(rtc_alarm_time->alarm_day) | \
+                 ALRMTD_HR(rtc_alarm_time->alarm_hour) | \
+                 ALRMTD_MN(rtc_alarm_time->alarm_minute) | \
+                 ALRMTD_SC(rtc_alarm_time->alarm_second));
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    if(RTC_ALARM0 == rtc_alarm){
+        RTC_ALRM0TD = (uint32_t)reg_alrmtd;
+    
+    }else{
+        RTC_ALRM1TD = (uint32_t)reg_alrmtd;
+    }
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      configure subsecond of RTC alarm
+    \param[in]  rtc_alarm: RTC_ALARM0 or RTC_ALARM1
+    \param[in]  mask_subsecond: alarm subsecond mask
+      \arg        RTC_MASKSSC_0_14: mask alarm subsecond configuration
+      \arg        RTC_MASKSSC_1_14: mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared
+      \arg        RTC_MASKSSC_2_14: mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared
+      \arg        RTC_MASKSSC_3_14: mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared
+      \arg        RTC_MASKSSC_4_14: mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared
+      \arg        RTC_MASKSSC_5_14: mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared
+      \arg        RTC_MASKSSC_6_14: mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared
+      \arg        RTC_MASKSSC_7_14: mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared
+      \arg        RTC_MASKSSC_8_14: mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared
+      \arg        RTC_MASKSSC_9_14: mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared
+      \arg        RTC_MASKSSC_10_14: mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared
+      \arg        RTC_MASKSSC_11_14: mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared
+      \arg        RTC_MASKSSC_12_14: mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared
+      \arg        RTC_MASKSSC_13_14: mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared
+      \arg        RTC_MASKSSC_14: mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared
+      \arg        RTC_MASKSSC_NONE: mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared
+    \param[in]  subsecond: alarm subsecond value(0x000 - 0x7FFF)
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;  
+
+    if(RTC_ALARM0 == rtc_alarm){
+        RTC_ALRM0SS = mask_subsecond | subsecond;  
+    }else{
+        RTC_ALRM1SS = mask_subsecond | subsecond; 
+    }
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      get RTC alarm
+    \param[in]  rtc_alarm: RTC_ALARM0 or RTC_ALARM1
+    \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains 
+                parameters for RTC alarm configuration
+                members of the structure and the member values are shown as below:
+                  alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
+                                  RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
+                  weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
+                  alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
+                                 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
+                                    RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
+                  alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
+                  alarm_minute: 0x0 - 0x59(BCD format)
+                  alarm_second: 0x0 - 0x59(BCD format)
+                  am_pm: RTC_AM, RTC_PM
+    \retval     none
+*/
+void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time)
+{
+    uint32_t reg_alrmtd = 0U;
+
+    /* get the value of RTC_ALRM0TD register */
+    if(RTC_ALARM0 == rtc_alarm){
+        reg_alrmtd = RTC_ALRM0TD;
+    }else{
+        reg_alrmtd = RTC_ALRM1TD;
+    }
+    /* get alarm parameters and construct the rtc_alarm_struct structure */
+    rtc_alarm_time->alarm_mask = reg_alrmtd & RTC_ALARM_ALL_MASK; 
+    rtc_alarm_time->am_pm = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_PM);
+    rtc_alarm_time->weekday_or_date = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_DOWS);
+    rtc_alarm_time->alarm_day = (uint8_t)GET_ALRMTD_DAY(reg_alrmtd);
+    rtc_alarm_time->alarm_hour = (uint8_t)GET_ALRMTD_HR(reg_alrmtd);
+    rtc_alarm_time->alarm_minute = (uint8_t)GET_ALRMTD_MN(reg_alrmtd);
+    rtc_alarm_time->alarm_second = (uint8_t)GET_ALRMTD_SC(reg_alrmtd);  
+}
+
+/*!
+    \brief      get RTC alarm subsecond
+    \param[in]  rtc_alarm: RTC_ALARM0 or RTC_ALARM1
+    \param[out] none
+    \retval     RTC alarm subsecond value
+*/
+uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm)
+{
+    if(RTC_ALARM0 == rtc_alarm){
+        return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC));
+    }else{
+        return ((uint32_t)(RTC_ALRM1SS & RTC_ALRM1SS_SSC));
+    }
+}
+
+/*!
+    \brief      enable RTC alarm
+    \param[in]  rtc_alarm: RTC_ALARM0 or RTC_ALARM1
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_enable(uint8_t rtc_alarm)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    if(RTC_ALARM0 == rtc_alarm){
+        RTC_CTL |= RTC_CTL_ALRM0EN;
+    }else{
+        RTC_CTL |= RTC_CTL_ALRM1EN;
+    }
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC alarm
+    \param[in]  rtc_alarm: RTC_ALARM0 or RTC_ALARM1
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_alarm_disable(uint8_t rtc_alarm)
+{
+    volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT;
+    ErrStatus error_status = ERROR;
+    uint32_t flag_status = RESET;
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* clear the state of alarm */
+    if(RTC_ALARM0 == rtc_alarm){
+        RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); 
+        /* wait until ALRM0WF flag to be set after the alarm is disabled */
+        do{
+            flag_status = RTC_STAT & RTC_STAT_ALRM0WF;
+        }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); 
+    }else{
+        RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN);  
+        /* wait until ALRM1WF flag to be set after the alarm is disabled */
+        do{
+            flag_status = RTC_STAT & RTC_STAT_ALRM1WF;
+        }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+    }
+  
+    if ((uint32_t)RESET != flag_status){     
+        error_status = SUCCESS;
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enable RTC time-stamp
+    \param[in]  edge: specify which edge to detect of time-stamp
+      \arg        RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event
+      \arg        RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event
+    \param[out] none
+    \retval     none
+*/
+void rtc_timestamp_enable(uint32_t edge)
+{
+    uint32_t reg_ctl = 0U;
+
+    /* clear the bits to be configured in RTC_CTL */
+    reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN)));
+
+    /* new configuration */
+    reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN);
+   
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL = (uint32_t)reg_ctl;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC time-stamp
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_timestamp_disable(void)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* clear the TSEN bit */
+    RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      get RTC timestamp time and date
+    \param[in]  none
+    \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains 
+                parameters for RTC time-stamp configuration
+                members of the structure and the member values are shown as below:
+                  timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
+                                       RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
+                  timestamp_date: 0x1 - 0x31(BCD format)
+                  timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
+                                     RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
+                  timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
+                  timestamp_minute: 0x0 - 0x59(BCD format)
+                  timestamp_second: 0x0 - 0x59(BCD format)
+                  am_pm: RTC_AM, RTC_PM
+    \retval     none
+*/
+void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp)
+{
+    uint32_t temp_tts = 0U, temp_dts = 0U;
+
+    /* get the value of time_stamp registers */
+    temp_tts = (uint32_t)RTC_TTS;
+    temp_dts = (uint32_t)RTC_DTS;
+  
+    /* get timestamp time and construct the rtc_timestamp_struct structure */
+    rtc_timestamp->am_pm = (uint32_t)(temp_tts & RTC_TTS_PM);
+    rtc_timestamp->timestamp_month = (uint8_t)GET_DTS_MON(temp_dts);
+    rtc_timestamp->timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts);
+    rtc_timestamp->timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts);
+    rtc_timestamp->timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts);
+    rtc_timestamp->timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts);
+    rtc_timestamp->timestamp_second = (uint8_t)GET_TTS_SC(temp_tts);
+}
+
+/*!
+    \brief      get RTC time-stamp subsecond
+    \param[in]  none
+    \param[out] none
+    \retval     RTC time-stamp subsecond value
+*/
+uint32_t rtc_timestamp_subsecond_get(void)
+{
+    return ((uint32_t)RTC_SSTS);
+}
+
+/*!
+    \brief      RTC time-stamp mapping 
+    \param[in]  rtc_af:
+      \arg        RTC_AF0_TIMESTAMP: RTC_AF0 use for timestamp
+      \arg        RTC_AF1_TIMESTAMP: RTC_AF1 use for timestamp
+    \param[out] none
+    \retval     none
+*/
+void rtc_timestamp_pin_map(uint32_t rtc_af)
+{
+    RTC_TAMP &= ~RTC_TAMP_TSSEL;
+    RTC_TAMP |= rtc_af;
+}
+
+/*!
+    \brief      enable RTC tamper
+    \param[in]  rtc_tamper: pointer to a rtc_tamper_struct structure which contains 
+                parameters for RTC tamper configuration
+                members of the structure and the member values are shown as below:
+                  tamper_source: RTC_TAMPER0, RTC_TAMPER1
+                  tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING
+                                      RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH
+                  tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S
+                  tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192,
+                                               RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024,
+                                               RTC_FREQ_DIV512, RTC_FREQ_DIV256
+                  tamper_precharge_enable: DISABLE, ENABLE
+                  tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C
+                  tamper_with_timestamp: DISABLE, ENABLE
+    \param[out] none
+    \retval     none
+*/
+void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper)
+{
+    /* disable tamper */
+    RTC_TAMP &= (uint32_t)~(rtc_tamper->tamper_source); 
+
+    /* tamper filter must be used when the tamper source is voltage level detection */
+    RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT;
+    
+    /* the tamper source is voltage level detection */
+    if((uint32_t)(rtc_tamper->tamper_filter) != RTC_FLT_EDGE ){ 
+        RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT);
+
+        /* check if the tamper pin need precharge, if need, then configure the precharge time */
+        if(DISABLE == rtc_tamper->tamper_precharge_enable){
+            RTC_TAMP |=  (uint32_t)RTC_TAMP_DISPU;    
+        }else{
+            RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_precharge_time);
+        }
+
+        RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_sample_frequency);
+        RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_filter);
+    }
+    
+    RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS;  
+    
+    if(DISABLE != rtc_tamper->tamper_with_timestamp){           
+        /* the tamper event also cause a time-stamp event */
+        RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS;
+    } 
+    
+    /* configure the tamper trigger */
+    RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS));    
+    if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->tamper_trigger){
+        RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source)<< RTC_TAMPER_TRIGGER_POS);  
+    }    
+    /* enable tamper */
+    RTC_TAMP |=  (uint32_t)(rtc_tamper->tamper_source); 
+}
+
+/*!
+    \brief      disable RTC tamper
+    \param[in]  source: specify which tamper source to be disabled
+      \arg        RTC_TAMPER0
+      \arg        RTC_TAMPER1
+    \param[out] none
+    \retval     none
+*/
+void rtc_tamper_disable(uint32_t source)
+{
+    /* disable tamper */
+    RTC_TAMP &= (uint32_t)~source; 
+
+}
+
+/*!
+    \brief      RTC tamper0 mapping 
+    \param[in]  rtc_af:
+      \arg        RTC_AF0_TAMPER0: RTC_AF0 use for tamper0
+      \arg        RTC_AF1_TAMPER0: RTC_AF1 use for tamper0
+    \param[out] none
+    \retval     none
+*/
+void rtc_tamper0_pin_map(uint32_t rtc_af)
+{
+    RTC_TAMP &= ~(RTC_TAMP_TP0EN | RTC_TAMP_TP0SEL);
+    RTC_TAMP |= rtc_af;
+}
+/*!
+    \brief      enable specified RTC interrupt
+    \param[in]  interrupt: specify which interrupt source to be enabled
+      \arg        RTC_INT_TIMESTAMP: timestamp interrupt
+      \arg        RTC_INT_ALARM0: alarm0 interrupt
+      \arg        RTC_INT_ALARM1: alarm1 interrupt
+      \arg        RTC_INT_TAMP: tamp interrupt
+      \arg        RTC_INT_WAKEUP: wakeup timer interrupt
+    \param[out] none
+    \retval     none
+*/
+void rtc_interrupt_enable(uint32_t interrupt)
+{  
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+ 
+    /* enable the interrupts in RTC_CTL register */
+    RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE);
+    /* enable the interrupts in RTC_TAMP register */
+    RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE);
+    
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY; 
+}
+
+/*!
+    \brief      disble specified RTC interrupt
+    \param[in]  interrupt: specify which interrupt source to be disabled
+      \arg        RTC_INT_TIMESTAMP: timestamp interrupt
+      \arg        RTC_INT_ALARM0: alarm interrupt
+      \arg        RTC_INT_ALARM1: alarm interrupt
+      \arg        RTC_INT_TAMP: tamp interrupt
+      \arg        RTC_INT_WAKEUP: wakeup timer interrupt
+    \param[out] none
+    \retval     none
+*/
+void rtc_interrupt_disable(uint32_t interrupt)
+{  
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+ 
+    /* disable the interrupts in RTC_CTL register */
+    RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE);
+    /* disable the interrupts in RTC_TAMP register */
+    RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      check specified flag
+    \param[in]  flag: specify which flag to check
+      \arg        RTC_STAT_RECPF: recalibration pending flag
+      \arg        RTC_STAT_TP1F: tamper 1 event flag
+      \arg        RTC_STAT_TP0F: tamper 0 event flag
+      \arg        RTC_STAT_TSOVRF: time-stamp overflow event flag
+      \arg        RTC_STAT_TSF: time-stamp event flag
+      \arg        RTC_STAT_ALRM0F: alarm0 event flag
+      \arg        RTC_STAT_ALRM1F: alarm1 event flag
+      \arg        RTC_STAT_WTF: wakeup timer event flag
+      \arg        RTC_STAT_INITF: init mode event flag
+      \arg        RTC_STAT_RSYNF: time and date registers synchronized event flag
+      \arg        RTC_STAT_YCM: year parameter configured event flag
+      \arg        RTC_STAT_SOPF: shift operation pending flag
+      \arg        RTC_STAT_ALRM0WF: alarm0 writen available flag
+      \arg        RTC_STAT_ALRM1WF: alarm1 writen available flag
+      \arg        RTC_STAT_WTWF: wakeup timer writen available flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus rtc_flag_get(uint32_t flag)
+{
+    FlagStatus flag_state = RESET;
+    
+    if ((uint32_t)RESET != (RTC_STAT & flag)){
+        flag_state = SET;
+    }
+    return flag_state;
+}
+
+/*!
+    \brief      clear specified flag
+    \param[in]  flag: specify which flag to clear
+      \arg        RTC_STAT_TP1F: tamper 1 event flag
+      \arg        RTC_STAT_TP0F: tamper 0 event flag
+      \arg        RTC_STAT_TSOVRF: time-stamp overflow event flag
+      \arg        RTC_STAT_TSF: time-stamp event flag
+      \arg        RTC_STAT_WTF: time-stamp event flag
+      \arg        RTC_STAT_ALRM0F: alarm0 event flag
+      \arg        RTC_STAT_ALRM1F: alarm1 event flag
+      \arg        RTC_STAT_RSYNF: time and date registers synchronized event flag
+    \param[out] none
+    \retval     none
+*/
+void rtc_flag_clear(uint32_t flag)
+{
+    RTC_STAT &= (uint32_t)(~flag);  
+}
+
+/*!
+    \brief      configure rtc alarm output source
+    \param[in]  source: specify signal to output
+      \arg        RTC_ALARM0_HIGH: when the  alarm0 flag is set, the output pin is high
+      \arg        RTC_ALARM0_LOW: when the  alarm0 flag is set, the output pin is low
+      \arg        RTC_ALARM1_HIGH: when the  alarm1 flag is set, the output pin is high
+      \arg        RTC_ALARM1_LOW: when the  alarm1 flag is set, the output pin is low
+      \arg        RTC_WAKEUP_HIGH: when the  wakeup flag is set, the output pin is high
+      \arg        RTC_WAKEUP_LOW: when the  wakeup flag is set, the output pin is low
+    \param[in]  mode: specify the output pin mode when output alarm signal
+      \arg        RTC_ALARM_OUTPUT_OD: open drain mode
+      \arg        RTC_ALARM_OUTPUT_PP: push pull mode
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_output_config(uint32_t source, uint32_t mode)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL &= ~(RTC_CTL_OS | RTC_CTL_OPOL);
+    RTC_TAMP &= ~RTC_TAMP_AOT;
+
+    RTC_CTL |= (uint32_t)(source);
+    /* alarm output */
+    RTC_TAMP |= (uint32_t)(mode);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      configure rtc calibration output source
+    \param[in]  source: specify signal to output
+      \arg        RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC 
+                                         is the default value, output 512Hz signal
+      \arg        RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC 
+                                       is the default value, output 512Hz signal
+    \param[out] none
+    \retval     none
+*/
+void rtc_calibration_output_config(uint32_t source)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_COS);
+
+    RTC_CTL |= (uint32_t)(source);
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+
+/*!
+    \brief      adjust the daylight saving time by adding or substracting one hour from the current time
+    \param[in]  operation: hour adjustment operation
+      \arg        RTC_CTL_A1H: add one hour
+      \arg        RTC_CTL_S1H: substract one hour
+    \param[out] none
+    \retval     none
+*/
+void rtc_hour_adjust(uint32_t operation)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    RTC_CTL |= (uint32_t)(operation);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      adjust RTC second or subsecond value of current time
+    \param[in]  add: add 1s to current time or not
+      \arg        RTC_SHIFT_ADD1S_RESET: no effect
+      \arg        RTC_SHIFT_ADD1S_SET: add 1s to current time
+    \param[in]  minus: number of subsecond to minus from current time(0x0 - 0x7FFF)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus)
+{
+    volatile uint32_t time_index = RTC_SHIFTCTL_TIMEOUT;
+    ErrStatus error_status = ERROR;
+    uint32_t flag_status = RESET;
+    uint32_t temp=0U;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* check if a shift operation is ongoing */    
+    do{
+        flag_status = RTC_STAT & RTC_STAT_SOPF;
+    }while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
+    
+    /* check if the function of reference clock detection is disabled */
+    temp = RTC_CTL & RTC_CTL_REFEN;
+    if((RESET == flag_status) && (RESET == temp)){  
+        RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus));
+        error_status = rtc_register_sync_wait();        
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enable RTC bypass shadow registers function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_bypass_shadow_enable(void)
+{ 
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL |= RTC_CTL_BPSHAD;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC bypass shadow registers function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_bypass_shadow_disable(void)
+{ 
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL &= ~RTC_CTL_BPSHAD;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      enable RTC reference clock detection function
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_refclock_detection_enable(void)
+{
+    ErrStatus error_status = ERROR;
+    
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){
+        RTC_CTL |= (uint32_t)RTC_CTL_REFEN;
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      disable RTC reference clock detection function
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_refclock_detection_disable(void)
+{
+    ErrStatus error_status = ERROR;
+    
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){ 
+        RTC_CTL &= (uint32_t)~RTC_CTL_REFEN;
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enable RTC auto wakeup function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_wakeup_enable(void)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2; 
+
+    RTC_CTL |= RTC_CTL_WTEN;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC auto wakeup function
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_wakeup_disable(void)
+{
+    ErrStatus error_status = ERROR;
+    volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
+    uint32_t flag_status = RESET;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    RTC_CTL &= ~RTC_CTL_WTEN;
+    /* wait until the WTWF flag to be set */
+    do{
+        flag_status = RTC_STAT & RTC_STAT_WTWF;
+    }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+
+    if ((uint32_t)RESET == flag_status){
+        error_status = ERROR;
+    }else{
+        error_status = SUCCESS;
+    }
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+    return error_status;
+}
+
+/*!
+    \brief      set RTC auto wakeup timer clock
+    \param[in]  wakeup_clock:
+      \arg        WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16 
+      \arg        WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8 
+      \arg        WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4 
+      \arg        WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2 
+      \arg        WAKEUP_CKSPRE: RTC auto wakeup timer clock is ckspre
+      \arg        WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16 
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock)
+{
+    ErrStatus error_status = ERROR;
+    volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
+    uint32_t flag_status = RESET;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2; 
+    /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2£º0] */
+    /* wait until the WTWF flag to be set */
+    do{
+        flag_status = RTC_STAT & RTC_STAT_WTWF;
+    }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+
+    if ((uint32_t)RESET == flag_status){
+        error_status = ERROR;
+    }else{
+        RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS;
+        RTC_CTL |= (uint32_t)wakeup_clock;
+        error_status = SUCCESS;
+    }
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+    
+    return error_status;
+}
+
+/*!
+    \brief      set wakeup timer value
+    \param[in]  wakeup_timer: 0x0000-0xffff
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer)
+{
+    ErrStatus error_status = ERROR;
+    volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
+    uint32_t flag_status = RESET;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    /* wait until the WTWF flag to be set */
+    do{
+        flag_status = RTC_STAT & RTC_STAT_WTWF;
+    }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
+
+    if ((uint32_t)RESET == flag_status){
+        error_status = ERROR;
+    }else{
+        RTC_WUT = (uint32_t)wakeup_timer;
+        error_status = SUCCESS;
+    }
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+    return error_status;
+}
+
+/*!
+    \brief      get wakeup timer value
+    \param[in]  none
+    \param[out] none
+    \retval     wakeup timer value
+*/
+ uint16_t rtc_wakeup_timer_get(void)
+{
+    return (uint16_t)RTC_WUT;
+}
+
+/*!
+    \brief      configure RTC smooth calibration
+    \param[in]  window: select calibration window
+      \arg        RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz
+      \arg        RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz
+      \arg        RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz
+    \param[in]  plus: add RTC clock or not
+      \arg        RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock
+      \arg        RTC_CALIBRATION_PLUS_RESET: no effect
+    \param[in]  minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus)
+{
+    volatile uint32_t time_index = RTC_HRFC_TIMEOUT;
+    ErrStatus error_status = ERROR;
+    uint32_t flag_status = RESET;
+    
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;    
+    
+    /* check if a smooth calibration operation is ongoing */        
+    do{
+        flag_status = RTC_STAT & RTC_STAT_SCPF;
+    }while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
+    
+    if((uint32_t)RESET == flag_status){
+        RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus));
+        error_status = SUCCESS;
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enable RTC coarse calibration
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_coarse_calibration_enable(void)
+{
+    ErrStatus error_status = ERROR;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){ 
+        RTC_CTL |= (uint32_t)RTC_CTL_CCEN;
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+    
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+    return error_status;
+}
+
+/*!
+    \brief      disable RTC coarse calibration
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_coarse_calibration_disable(void)
+{
+    ErrStatus error_status = ERROR;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;    
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){ 
+        RTC_CTL &= (uint32_t)~RTC_CTL_CCEN;
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+    
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;	
+    return error_status;
+}
+
+/*!
+    \brief      config coarse calibration direction and step
+    \param[in]  direction: CALIB_INCREASE or CALIB_DECREASE      
+    \param[in]  step: 0x00-0x1F
+                COSD=0:
+                  0x00:+0 PPM
+                  0x01:+4 PPM
+                  0x02:+8 PPM
+                  ....
+                  0x1F:+126 PPM
+                COSD=1:
+                  0x00:-0 PPM
+                  0x01:-2 PPM
+                  0x02:-4 PPM
+                  ....
+                  0x1F:-63 PPM
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step)
+{
+    ErrStatus error_status = ERROR;
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){ 
+        if(CALIB_DECREASE == direction){
+            RTC_COSC |= (uint32_t)RTC_COSC_COSD;
+        }else{
+            RTC_COSC &= (uint32_t)~RTC_COSC_COSD;
+        }
+        RTC_COSC &= ~RTC_COSC_COSS;
+        RTC_COSC |= (uint32_t)((uint32_t)step & 0x1FU);
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+    
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+    
+    return error_status;
+}

+ 759 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c

@@ -0,0 +1,759 @@
+/*!
+    \file  gd32f4xx_sdio.c
+    \brief SDIO driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_sdio.h"
+
+/*!
+    \brief      deinitialize the SDIO
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_SDIORST);
+    rcu_periph_reset_disable(RCU_SDIORST);
+}
+
+/*!
+    \brief      configure the SDIO clock
+    \param[in]  clock_edge: SDIO_CLK clock edge
+      \arg        SDIO_SDIOCLKEDGE_RISING: select the rising edge of the SDIOCLK to generate SDIO_CLK
+      \arg        SDIO_SDIOCLKEDGE_FALLING: select the falling edge of the SDIOCLK to generate SDIO_CLK
+    \param[in]  clock_bypass: clock bypass
+      \arg        SDIO_CLOCKBYPASS_ENABLE: clock bypass
+      \arg        SDIO_CLOCKBYPASS_DISABLE: no bypass
+    \param[in]  clock_powersave: SDIO_CLK clock dynamic switch on/off for power saving
+      \arg        SDIO_CLOCKPWRSAVE_ENABLE: SDIO_CLK closed when bus is idle
+      \arg        SDIO_CLOCKPWRSAVE_DISABLE: SDIO_CLK clock is always on
+    \param[in]  clock_division: clock division, less than 512
+    \param[out] none
+    \retval     none
+*/
+void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division)
+{
+    uint32_t clock_config = 0U;
+    clock_config = SDIO_CLKCTL;
+    /* reset the CLKEDGE, CLKBYP, CLKPWRSAV, DIV */
+    clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKBYP | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV8 | SDIO_CLKCTL_DIV);
+    /* if the clock division is greater or equal to 256, set the DIV[8] */
+    if(clock_division >= 256U){
+        clock_config |= SDIO_CLKCTL_DIV8;
+        clock_division -= 256U;
+    }
+    /* configure the SDIO_CLKCTL according to the parameters */
+    clock_config |= (clock_edge | clock_bypass | clock_powersave | clock_division);
+    SDIO_CLKCTL = clock_config;
+}
+
+/*!
+    \brief      enable hardware clock control
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_hardware_clock_enable(void)
+{
+    SDIO_CLKCTL |= SDIO_CLKCTL_HWCLKEN;
+}
+
+/*!
+    \brief      disable hardware clock control
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_hardware_clock_disable(void)
+{
+    SDIO_CLKCTL &= ~SDIO_CLKCTL_HWCLKEN;
+}
+
+/*!
+    \brief      set different SDIO card bus mode
+    \param[in]  bus_mode: SDIO card bus mode
+      \arg        SDIO_BUSMODE_1BIT: 1-bit SDIO card bus mode
+      \arg        SDIO_BUSMODE_4BIT: 4-bit SDIO card bus mode
+      \arg        SDIO_BUSMODE_8BIT: 8-bit SDIO card bus mode
+    \param[out] none
+    \retval     none
+*/
+void sdio_bus_mode_set(uint32_t bus_mode)
+{
+    /* reset the SDIO card bus mode bits and set according to bus_mode */
+    SDIO_CLKCTL &= ~SDIO_CLKCTL_BUSMODE;
+    SDIO_CLKCTL |= bus_mode;
+}
+
+/*!
+    \brief      set the SDIO power state
+    \param[in]  power_state: SDIO power state
+      \arg        SDIO_POWER_ON: SDIO power on
+      \arg        SDIO_POWER_OFF: SDIO power off
+    \param[out] none
+    \retval     none
+*/
+void sdio_power_state_set(uint32_t power_state)
+{
+    SDIO_PWRCTL = power_state;
+}
+
+/* get the SDIO power state */
+/*!
+    \brief      get the SDIO power state
+    \param[in]  none
+    \param[out] none
+    \retval     SDIO power state
+      \arg        SDIO_POWER_ON: SDIO power on
+      \arg        SDIO_POWER_OFF: SDIO power off
+*/
+uint32_t sdio_power_state_get(void)
+{
+    return SDIO_PWRCTL;
+}
+
+/*!
+    \brief      enable SDIO_CLK clock output
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_clock_enable(void)
+{
+    SDIO_CLKCTL |= SDIO_CLKCTL_CLKEN;
+}
+
+/*!
+    \brief      disable SDIO_CLK clock output
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_clock_disable(void)
+{
+    SDIO_CLKCTL &= ~SDIO_CLKCTL_CLKEN;
+}
+
+/*!
+    \brief      configure the command and response
+    \param[in]  cmd_index: command index, refer to the related specifications
+    \param[in]  cmd_argument: command argument, refer to the related specifications
+    \param[in]  response_type: response type
+      \arg        SDIO_RESPONSETYPE_NO: no response
+      \arg        SDIO_RESPONSETYPE_SHORT: short response
+      \arg        SDIO_RESPONSETYPE_LONG: long response
+    \param[out] none
+    \retval     none
+*/
+void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type)
+{
+    uint32_t cmd_config = 0U;
+    /* reset the command index, command argument and response type */
+    SDIO_CMDAGMT &= ~SDIO_CMDAGMT_CMDAGMT;
+    SDIO_CMDAGMT = cmd_argument;
+    cmd_config = SDIO_CMDCTL;
+    cmd_config &= ~(SDIO_CMDCTL_CMDIDX | SDIO_CMDCTL_CMDRESP);
+    /* configure SDIO_CMDCTL and SDIO_CMDAGMT according to the parameters */
+    cmd_config |= (cmd_index | response_type);
+    SDIO_CMDCTL = cmd_config;
+}
+
+/*!
+    \brief      set the command state machine wait type
+    \param[in]  wait_type: wait type
+      \arg        SDIO_WAITTYPE_NO: not wait interrupt
+      \arg        SDIO_WAITTYPE_INTERRUPT: wait interrupt
+      \arg        SDIO_WAITTYPE_DATAEND: wait the end of data transfer
+    \param[out] none
+    \retval     none
+*/
+void sdio_wait_type_set(uint32_t wait_type)
+{
+    /* reset INTWAIT and WAITDEND */
+    SDIO_CMDCTL &= ~(SDIO_CMDCTL_INTWAIT | SDIO_CMDCTL_WAITDEND);
+    /* set the wait type according to wait_type */
+    SDIO_CMDCTL |= wait_type;
+}
+
+/*!
+    \brief      enable the CSM(command state machine)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_csm_enable(void)
+{
+    SDIO_CMDCTL |= SDIO_CMDCTL_CSMEN;
+}
+
+/*!
+    \brief      disable the CSM(command state machine)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_csm_disable(void)
+{
+    SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN;
+}
+
+/*!
+    \brief      get the last response command index
+    \param[in]  none
+    \param[out] none
+    \retval     last response command index
+*/
+uint8_t sdio_command_index_get(void)
+{
+    return (uint8_t)SDIO_RSPCMDIDX;
+}
+
+/*!
+    \brief      get the response for the last received command
+    \param[in]  sdio_responsex: SDIO response
+      \arg       SDIO_RESPONSE0: card response[31:0]/card response[127:96]
+      \arg       SDIO_RESPONSE1: card response[95:64]
+      \arg       SDIO_RESPONSE2: card response[63:32]
+      \arg       SDIO_RESPONSE3: card response[31:1], plus bit 0
+    \param[out] none
+    \retval     response for the last received command
+*/
+uint32_t sdio_response_get(uint32_t sdio_responsex)
+{
+    uint32_t resp_content = 0U;
+    switch(sdio_responsex){
+    case SDIO_RESPONSE0:
+        resp_content = SDIO_RESP0;
+        break;
+    case SDIO_RESPONSE1:
+        resp_content = SDIO_RESP1;
+        break;
+    case SDIO_RESPONSE2:
+        resp_content = SDIO_RESP2;
+        break;
+    case SDIO_RESPONSE3:
+        resp_content = SDIO_RESP3;
+        break;
+    default:
+        break;
+    }
+    return resp_content;
+}
+
+/*!
+    \brief      configure the data timeout, data length and data block size
+    \param[in]  data_timeout: data timeout period in card bus clock periods
+    \param[in]  data_length: number of data bytes to be transferred
+    \param[in]  data_blocksize: size of data block for block transfer
+      \arg        SDIO_DATABLOCKSIZE_1BYTE: block size = 1 byte
+      \arg        SDIO_DATABLOCKSIZE_2BYTES: block size = 2 bytes
+      \arg        SDIO_DATABLOCKSIZE_4BYTES: block size = 4 bytes
+      \arg        SDIO_DATABLOCKSIZE_8BYTES: block size = 8 bytes
+      \arg        SDIO_DATABLOCKSIZE_16BYTES: block size = 16 bytes
+      \arg        SDIO_DATABLOCKSIZE_32BYTES: block size = 32 bytes
+      \arg        SDIO_DATABLOCKSIZE_64BYTES: block size = 64 bytes
+      \arg        SDIO_DATABLOCKSIZE_128BYTES: block size = 128 bytes
+      \arg        SDIO_DATABLOCKSIZE_256BYTES: block size = 256 bytes
+      \arg        SDIO_DATABLOCKSIZE_512BYTES: block size = 512 bytes
+      \arg        SDIO_DATABLOCKSIZE_1024BYTES: block size = 1024 bytes
+      \arg        SDIO_DATABLOCKSIZE_2048BYTES: block size = 2048 bytes
+      \arg        SDIO_DATABLOCKSIZE_4096BYTES: block size = 4096 bytes
+      \arg        SDIO_DATABLOCKSIZE_8192BYTES: block size = 8192 bytes
+      \arg        SDIO_DATABLOCKSIZE_16384BYTES: block size = 16384 bytes
+    \param[out] none
+    \retval     none
+*/
+void sdio_data_config(uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize)
+{
+    /* reset data timeout, data length and data block size */
+    SDIO_DATATO &= ~SDIO_DATATO_DATATO;
+    SDIO_DATALEN &= ~SDIO_DATALEN_DATALEN;
+    SDIO_DATACTL &= ~SDIO_DATACTL_BLKSZ;
+    /* configure the related parameters of data */
+    SDIO_DATATO = data_timeout;
+    SDIO_DATALEN = data_length;
+    SDIO_DATACTL |= data_blocksize;
+}
+
+/*!
+    \brief      configure the data transfer mode and direction
+    \param[in]  transfer_mode: mode of data transfer
+      \arg       SDIO_TRANSMODE_BLOCK: block transfer
+      \arg       SDIO_TRANSMODE_STREAM: stream transfer or SDIO multibyte transfer
+    \param[in]  transfer_direction: data transfer direction, read or write
+      \arg       SDIO_TRANSDIRECTION_TOCARD: write data to card
+      \arg       SDIO_TRANSDIRECTION_TOSDIO: read data from card
+    \param[out] none
+    \retval     none
+*/
+void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction)
+{
+    uint32_t data_trans = 0U;
+    /* reset the data transfer mode, transfer direction and set according to the parameters */
+    data_trans = SDIO_DATACTL;
+    data_trans &= ~(SDIO_DATACTL_TRANSMOD | SDIO_DATACTL_DATADIR);
+    data_trans |= (transfer_mode | transfer_direction);
+    SDIO_DATACTL = data_trans;
+}
+
+/*!
+    \brief      enable the DSM(data state machine) for data transfer
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_dsm_enable(void)
+{
+    SDIO_DATACTL |= SDIO_DATACTL_DATAEN;
+}
+
+/*!
+    \brief      disable the DSM(data state machine)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_dsm_disable(void)
+{
+    SDIO_DATACTL &= ~SDIO_DATACTL_DATAEN;
+}
+
+/*!
+    \brief      write data(one word) to the transmit FIFO
+    \param[in]  data: 32-bit data write to card
+    \param[out] none
+    \retval     none
+*/
+void sdio_data_write(uint32_t data)
+{
+    SDIO_FIFO = data;
+}
+
+/*!
+    \brief      read data(one word) from the receive FIFO
+    \param[in]  none
+    \param[out] none
+    \retval     received data
+*/
+uint32_t sdio_data_read(void)
+{
+    return SDIO_FIFO;
+}
+
+/*!
+    \brief      get the number of remaining data bytes to be transferred to card
+    \param[in]  none
+    \param[out] none
+    \retval     number of remaining data bytes to be transferred
+*/
+uint32_t sdio_data_counter_get(void)
+{
+    return SDIO_DATACNT;
+}
+
+/*!
+    \brief      get the number of words remaining to be written or read from FIFO
+    \param[in]  none
+    \param[out] none
+    \retval     remaining number of words
+*/
+uint32_t sdio_fifo_counter_get(void)
+{
+    return SDIO_FIFOCNT;
+}
+
+/*!
+    \brief      enable the DMA request for SDIO
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_dma_enable(void)
+{
+    SDIO_DATACTL |= SDIO_DATACTL_DMAEN;
+}
+
+/*!
+    \brief      disable the DMA request for SDIO
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_dma_disable(void)
+{
+    SDIO_DATACTL &= ~SDIO_DATACTL_DMAEN;
+}
+
+/*!
+    \brief      get the flags state of SDIO
+    \param[in]  flag: flags state of SDIO
+      \arg        SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag
+      \arg        SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
+      \arg        SDIO_FLAG_CMDTMOUT: command response timeout flag
+      \arg        SDIO_FLAG_DTTMOUT: data timeout flag
+      \arg        SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag
+      \arg        SDIO_FLAG_RXORE: received FIFO overrun error occurs flag
+      \arg        SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag
+      \arg        SDIO_FLAG_CMDSEND: command sent (no response required) flag
+      \arg        SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
+      \arg        SDIO_FLAG_STBITE: start bit error in the bus flag
+      \arg        SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
+      \arg        SDIO_FLAG_CMDRUN: command transmission in progress flag
+      \arg        SDIO_FLAG_TXRUN: data transmission in progress flag
+      \arg        SDIO_FLAG_RXRUN: data reception in progress flag
+      \arg        SDIO_FLAG_TFH: transmit FIFO is half empty flag: at least 8 words can be written into the FIFO
+      \arg        SDIO_FLAG_RFH: receive FIFO is half full flag: at least 8 words can be read in the FIFO
+      \arg        SDIO_FLAG_TFF: transmit FIFO is full flag
+      \arg        SDIO_FLAG_RFF: receive FIFO is full flag
+      \arg        SDIO_FLAG_TFE: transmit FIFO is empty flag
+      \arg        SDIO_FLAG_RFE: receive FIFO is empty flag
+      \arg        SDIO_FLAG_TXDTVAL: data is valid in transmit FIFO flag
+      \arg        SDIO_FLAG_RXDTVAL: data is valid in receive FIFO flag
+      \arg        SDIO_FLAG_SDIOINT: SD I/O interrupt received flag
+      \arg        SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus sdio_flag_get(uint32_t flag)
+{
+    FlagStatus temp_flag = RESET;
+    if(RESET != (SDIO_STAT & flag)){
+        temp_flag = SET;
+    }
+    return temp_flag;
+}
+
+/*!
+    \brief      clear the pending flags of SDIO
+    \param[in]  flag: flags state of SDIO
+      \arg        SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag
+      \arg        SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
+      \arg        SDIO_FLAG_CMDTMOUT: command response timeout flag
+      \arg        SDIO_FLAG_DTTMOUT: data timeout flag
+      \arg        SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag
+      \arg        SDIO_FLAG_RXORE: received FIFO overrun error occurs flag
+      \arg        SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag
+      \arg        SDIO_FLAG_CMDSEND: command sent (no response required) flag
+      \arg        SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
+      \arg        SDIO_FLAG_STBITE: start bit error in the bus flag
+      \arg        SDIO_FLAG_DTBLKEND: 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 (only for CMD61) flag
+    \param[out] none
+    \retval     none
+*/
+void sdio_flag_clear(uint32_t flag)
+{
+    SDIO_INTC = flag;
+}
+
+/*!
+    \brief      enable the SDIO interrupt
+    \param[in]  int_flag: interrupt flags state of SDIO
+      \arg        SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
+      \arg        SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
+      \arg        SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
+      \arg        SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
+      \arg        SDIO_INT_TXURE: SDIO TXURE interrupt
+      \arg        SDIO_INT_RXORE: SDIO RXORE interrupt
+      \arg        SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
+      \arg        SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
+      \arg        SDIO_INT_DTEND: SDIO DTEND interrupt
+      \arg        SDIO_INT_STBITE: SDIO STBITE interrupt
+      \arg        SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
+      \arg        SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
+      \arg        SDIO_INT_TXRUN: SDIO TXRUN interrupt
+      \arg        SDIO_INT_RXRUN: SDIO RXRUN interrupt
+      \arg        SDIO_INT_TFH: SDIO TFH interrupt
+      \arg        SDIO_INT_RFH: SDIO RFH interrupt
+      \arg        SDIO_INT_TFF: SDIO TFF interrupt
+      \arg        SDIO_INT_RFF: SDIO RFF interrupt
+      \arg        SDIO_INT_TFE: SDIO TFE interrupt
+      \arg        SDIO_INT_RFE: SDIO RFE interrupt
+      \arg        SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
+      \arg        SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
+      \arg        SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
+      \arg        SDIO_INT_ATAEND: SDIO ATAEND interrupt
+    \param[out] none
+    \retval     none
+*/
+void sdio_interrupt_enable(uint32_t int_flag)
+{
+    SDIO_INTEN |= int_flag;
+}
+
+/*!
+    \brief      disable the SDIO interrupt
+    \param[in]  int_flag: interrupt flags state of SDIO
+      \arg        SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
+      \arg        SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
+      \arg        SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
+      \arg        SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
+      \arg        SDIO_INT_TXURE: SDIO TXURE interrupt
+      \arg        SDIO_INT_RXORE: SDIO RXORE interrupt
+      \arg        SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
+      \arg        SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
+      \arg        SDIO_INT_DTEND: SDIO DTEND interrupt
+      \arg        SDIO_INT_STBITE: SDIO STBITE interrupt
+      \arg        SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
+      \arg        SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
+      \arg        SDIO_INT_TXRUN: SDIO TXRUN interrupt
+      \arg        SDIO_INT_RXRUN: SDIO RXRUN interrupt
+      \arg        SDIO_INT_TFH: SDIO TFH interrupt
+      \arg        SDIO_INT_RFH: SDIO RFH interrupt
+      \arg        SDIO_INT_TFF: SDIO TFF interrupt
+      \arg        SDIO_INT_RFF: SDIO RFF interrupt
+      \arg        SDIO_INT_TFE: SDIO TFE interrupt
+      \arg        SDIO_INT_RFE: SDIO RFE interrupt
+      \arg        SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
+      \arg        SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
+      \arg        SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
+      \arg        SDIO_INT_ATAEND: SDIO ATAEND interrupt
+    \param[out] none
+    \retval     none
+*/
+void sdio_interrupt_disable(uint32_t int_flag)
+{
+    SDIO_INTEN &= ~int_flag;
+}
+
+/*!
+    \brief      get the interrupt flags state of SDIO
+    \param[in]  int_flag: interrupt flags state of SDIO
+      \arg        SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
+      \arg        SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
+      \arg        SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
+      \arg        SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
+      \arg        SDIO_INT_TXURE: SDIO TXURE interrupt
+      \arg        SDIO_INT_RXORE: SDIO RXORE interrupt
+      \arg        SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
+      \arg        SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
+      \arg        SDIO_INT_DTEND: SDIO DTEND interrupt
+      \arg        SDIO_INT_STBITE: SDIO STBITE interrupt
+      \arg        SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
+      \arg        SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
+      \arg        SDIO_INT_TXRUN: SDIO TXRUN interrupt
+      \arg        SDIO_INT_RXRUN: SDIO RXRUN interrupt
+      \arg        SDIO_INT_TFH: SDIO TFH interrupt
+      \arg        SDIO_INT_RFH: SDIO RFH interrupt
+      \arg        SDIO_INT_TFF: SDIO TFF interrupt
+      \arg        SDIO_INT_RFF: SDIO RFF interrupt
+      \arg        SDIO_INT_TFE: SDIO TFE interrupt
+      \arg        SDIO_INT_RFE: SDIO RFE interrupt
+      \arg        SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
+      \arg        SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
+      \arg        SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
+      \arg        SDIO_INT_ATAEND: SDIO ATAEND interrupt
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus sdio_interrupt_flag_get(uint32_t int_flag)
+{
+    FlagStatus temp_flag = RESET;
+    if(RESET != (SDIO_STAT & int_flag)){
+        temp_flag = SET;
+    }
+    return temp_flag;
+}
+
+/*!
+    \brief      clear the interrupt pending flags of SDIO
+    \param[in]  int_flag: interrupt flags state of SDIO
+      \arg        SDIO_INT_CCRCERR: command response received (CRC check failed) flag
+      \arg        SDIO_INT_DTCRCERR: data block sent/received (CRC check failed) flag
+      \arg        SDIO_INT_CMDTMOUT: command response timeout flag
+      \arg        SDIO_INT_DTTMOUT: data timeout flag
+      \arg        SDIO_INT_TXURE: transmit FIFO underrun error occurs flag
+      \arg        SDIO_INT_RXORE: received FIFO overrun error occurs flag
+      \arg        SDIO_INT_CMDRECV: command response received (CRC check passed) flag
+      \arg        SDIO_INT_CMDSEND: command sent (no response required) flag
+      \arg        SDIO_INT_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
+      \arg        SDIO_INT_STBITE: start bit error in the bus flag
+      \arg        SDIO_INT_DTBLKEND: data block sent/received (CRC check passed) flag
+      \arg        SDIO_INT_SDIOINT: SD I/O interrupt received flag
+      \arg        SDIO_INT_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
+    \param[out] none
+    \retval     none
+*/
+void sdio_interrupt_flag_clear(uint32_t int_flag)
+{
+    SDIO_INTC = int_flag;
+}
+
+/*!
+    \brief      enable the read wait mode(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_readwait_enable(void)
+{
+    SDIO_DATACTL |= SDIO_DATACTL_RWEN;
+}
+
+/*!
+    \brief      disable the read wait mode(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_readwait_disable(void)
+{
+    SDIO_DATACTL &= ~SDIO_DATACTL_RWEN;
+}
+
+/*!
+    \brief      enable the function that stop the read wait process(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_stop_readwait_enable(void)
+{
+    SDIO_DATACTL |= SDIO_DATACTL_RWSTOP;
+}
+
+/*!
+    \brief      disable the function that stop the read wait process(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_stop_readwait_disable(void)
+{
+    SDIO_DATACTL &= ~SDIO_DATACTL_RWSTOP;
+}
+
+/*!
+    \brief      set the read wait type(SD I/O only)
+    \param[in]  readwait_type: SD I/O read wait type
+      \arg        SDIO_READWAITTYPE_CLK: read wait control by stopping SDIO_CLK
+      \arg        SDIO_READWAITTYPE_DAT2: read wait control using SDIO_DAT[2]
+    \param[out] none
+    \retval     none
+*/
+void sdio_readwait_type_set(uint32_t readwait_type)
+{
+    if(SDIO_READWAITTYPE_CLK == readwait_type){
+        SDIO_DATACTL |= SDIO_DATACTL_RWTYPE;
+    }else{
+        SDIO_DATACTL &= ~SDIO_DATACTL_RWTYPE;
+    }
+}
+
+/*!
+    \brief      enable the SD I/O mode specific operation(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_operation_enable(void)
+{
+    SDIO_DATACTL |= SDIO_DATACTL_IOEN;
+}
+
+/*!
+    \brief      disable the SD I/O mode specific operation(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_operation_disable(void)
+{
+    SDIO_DATACTL &= ~SDIO_DATACTL_IOEN;
+}
+
+/*!
+    \brief      enable the SD I/O suspend operation(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_suspend_enable(void)
+{
+    SDIO_CMDCTL |= SDIO_CMDCTL_SUSPEND;
+}
+
+/*!
+    \brief      disable the SD I/O suspend operation(SD I/O only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_suspend_disable(void)
+{
+    SDIO_CMDCTL &= ~SDIO_CMDCTL_SUSPEND;
+}
+
+/*!
+    \brief      enable the CE-ATA command(CE-ATA only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_ceata_command_enable(void)
+{
+    SDIO_CMDCTL |= SDIO_CMDCTL_ATAEN;
+}
+
+/*!
+    \brief      disable the CE-ATA command(CE-ATA only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_ceata_command_disable(void)
+{
+    SDIO_CMDCTL &= ~SDIO_CMDCTL_ATAEN;
+}
+
+/*!
+    \brief      enable the CE-ATA interrupt(CE-ATA only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_ceata_interrupt_enable(void)
+{
+    SDIO_CMDCTL &= ~SDIO_CMDCTL_NINTEN;
+}
+
+/*!
+    \brief      disable the CE-ATA interrupt(CE-ATA only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_ceata_interrupt_disable(void)
+{
+    SDIO_CMDCTL |= SDIO_CMDCTL_NINTEN;
+}
+
+/*!
+    \brief      enable the CE-ATA command completion signal(CE-ATA only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_ceata_command_completion_enable(void)
+{
+    SDIO_CMDCTL |= SDIO_CMDCTL_ENCMDC;
+}
+
+/*!
+    \brief      disable the CE-ATA command completion signal(CE-ATA only)
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void sdio_ceata_command_completion_disable(void)
+{
+    SDIO_CMDCTL &= ~SDIO_CMDCTL_ENCMDC;
+}

+ 811 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c

@@ -0,0 +1,811 @@
+/*!
+    \file  gd32f4xx_spi.c
+    \brief SPI driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_spi.h"
+#include "gd32f4xx_rcu.h"
+
+#define SPI_INIT_MASK                   ((uint32_t)0x00003040U)
+#define I2S_INIT_MASK                   ((uint32_t)0x0000F047U)
+#define I2S_FULL_DUPLEX_MASK            ((uint32_t)0x0000F040U)
+
+/*!
+    \brief      SPI and I2S reset
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5),include I2S1_ADD and I2S2_ADD
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_deinit(uint32_t spi_periph)
+{
+    switch(spi_periph){
+    case SPI0:
+        /* reset SPI0 and I2S0 */
+        rcu_periph_reset_enable(RCU_SPI0RST);
+        rcu_periph_reset_disable(RCU_SPI0RST);
+        break;
+    case SPI1:
+        /* reset SPI1,I2S1 and I2S1_ADD */
+        rcu_periph_reset_enable(RCU_SPI1RST);
+        rcu_periph_reset_disable(RCU_SPI1RST);
+        break;
+    case SPI2:
+        /* reset SPI2,I2S2 and I2S2_ADD */
+        rcu_periph_reset_enable(RCU_SPI2RST);
+        rcu_periph_reset_disable(RCU_SPI2RST);
+        break;
+    case SPI3:
+        /* reset SPI3 and I2S3 */
+        rcu_periph_reset_enable(RCU_SPI3RST);
+        rcu_periph_reset_disable(RCU_SPI3RST);
+        break;
+    case SPI4:
+        /* reset SPI4 and I2S4 */
+        rcu_periph_reset_enable(RCU_SPI4RST);
+        rcu_periph_reset_disable(RCU_SPI4RST);
+        break;
+    case SPI5:
+        /* reset SPI5 */
+        rcu_periph_reset_enable(RCU_SPI5RST);
+        rcu_periph_reset_disable(RCU_SPI5RST);
+        break;
+    default :
+        break;
+    }
+}
+
+/*!
+    \brief      SPI parameter initialization
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_struct: SPI parameter initialization stuct
+                members of the structure and the member values are shown as below:
+                  device_mode          : SPI_MASTER, SPI_SLAVE.
+                  trans_mode           : SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY,
+                                         SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT
+                  frame_size           : SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT
+                  nss:                 : SPI_NSS_SOFT, SPI_NSS_HARD
+                  endian               : SPI_ENDIAN_MSB, SPI_ENDIAN_LSB
+                  clock_polarity_phase : SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE
+                                         SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE
+                  prescale             : SPI_PSC_n (n=2,4,8,16,32,64,128,256)
+    \param[out] none
+    \retval     none
+*/
+void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct)
+{   
+    uint32_t reg = 0U;
+    reg = SPI_CTL0(spi_periph);
+    reg &= SPI_INIT_MASK;
+
+    /* (1) select SPI as master or slave */
+    reg |= spi_struct->device_mode;
+    /* (2) select SPI transfer mode */
+    reg |= spi_struct->trans_mode;
+    /* (3) select SPI frame size */
+    reg |= spi_struct->frame_size;
+    /* (4) select SPI nss use hardware or software */
+    reg |= spi_struct->nss;
+    /* (5) select SPI LSB or MSB */
+    reg |= spi_struct->endian;
+    /* (6) select SPI polarity and phase */
+    reg |= spi_struct->clock_polarity_phase;
+    /* (7) select SPI prescale to adjust transmit speed */
+    reg |= spi_struct->prescale;
+
+    /* write to SPI_CTL0 register */
+    SPI_CTL0(spi_periph) = (uint32_t)reg;
+
+    SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
+}
+
+/*!
+    \brief      SPI enable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_enable(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN;
+}
+
+/*!
+    \brief      SPI disable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_disable(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
+}
+
+/*!
+    \brief      I2S prescale config
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4)
+    \param[in]  audiosample:
+      \arg        I2S_AUDIOSAMPLE_8K: audio sample rate is 8khz
+      \arg        I2S_AUDIOSAMPLE_11K: audio sample rate is 11khz
+      \arg        I2S_AUDIOSAMPLE_16K: audio sample rate is 16khz
+      \arg        I2S_AUDIOSAMPLE_22K: audio sample rate is 22khz
+      \arg        I2S_AUDIOSAMPLE_32K: audio sample rate is 32khz
+      \arg        I2S_AUDIOSAMPLE_44K: audio sample rate is 44khz
+      \arg        I2S_AUDIOSAMPLE_48K: audio sample rate is 48khz
+      \arg        I2S_AUDIOSAMPLE_96K: audio sample rate is 96khz
+      \arg        I2S_AUDIOSAMPLE_192K: audio sample rate is 192khz
+    \param[in]  frameformat:
+      \arg        I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
+      \arg        I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
+      \arg        I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
+      \arg        I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
+    \param[in]  mckout:
+      \arg        I2S_MCKOUT_ENABLE: I2S master clock output enable
+      \arg        I2S_MCKOUT_DISABLE: I2S master clock output disable
+    \param[out] none
+    \retval     none
+*/
+void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout)
+{
+    uint32_t temp_div = 2U, temp_of = 0U;
+    uint32_t temp = 0U;
+    uint32_t i2sclock = 0U;
+
+#ifndef I2S_EXTERNAL_CLOCK_IN
+  uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U;
+#endif /* I2S_EXTERNAL_CLOCK_IN */
+
+    /* deinit SPI_I2SPSC register */
+    SPI_I2SPSC(spi_periph) = 0x0002U;
+
+#ifdef I2S_EXTERNAL_CLOCK_IN
+    rcu_i2s_clock_config(RCU_I2SSRC_I2S_CKIN);
+
+    /* set the I2S clock to the external clock input value */
+    i2sclock = I2S_EXTERNAL_CLOCK_IN;
+#else
+
+    /* turn on the oscillator HXTAL */
+    rcu_osci_on(RCU_HXTAL);
+    /* wait for oscillator stabilization flags is SET */
+    rcu_osci_stab_wait(RCU_HXTAL);
+    /* turn on the PLLI2S */
+    rcu_osci_on(RCU_PLLI2S_CK);
+    /* wait for PLLI2S flags is SET */
+    rcu_osci_stab_wait(RCU_PLLI2S_CK);
+    /* configure the I2S clock source selection */
+    rcu_i2s_clock_config(RCU_I2SSRC_PLLI2S);
+
+    /* get the RCU_PLL_PLLPSC value */
+    plli2sm = (uint32_t)(RCU_PLL & RCU_PLL_PLLPSC);
+    /* get the RCU_PLLI2S_PLLI2SN value */
+    plli2sn = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SN) >> 6);
+    /* get the RCU_PLLI2S_PLLI2SR value */
+    plli2sr = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SR) >> 28);
+
+    if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL)
+    {
+      /* get the I2S source clock value */
+      i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr);
+    }
+    else
+    { /* get the I2S source clock value */
+      i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr);
+    }
+#endif /* I2S_EXTERNAL_CLOCK_IN */
+
+    /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
+    if(I2S_MCKOUT_ENABLE == i2s_mckout){
+        temp = (uint32_t)(((i2sclock / 256U) * 10U) / i2s_audiosample);
+    }else{
+        if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat){
+            temp = (uint32_t)(((i2sclock / 32U) *10U ) / i2s_audiosample);
+        }else{
+            temp = (uint32_t)(((i2sclock / 64U) *10U ) / i2s_audiosample);
+        }
+    }
+    /* remove the floating point */
+    temp = (temp + 5U) / 10U;
+    temp_of = (temp & 0x00000001U);
+    temp_div = ((temp - temp_of) / 2U);
+    temp_of = (temp_of << 8);
+
+    /* set the default values */
+    if((temp_div< 2U) || (temp_div > 255U)){
+        temp_div = 2U;
+        temp_of = 0U;
+    }
+
+    /* configure SPI_I2SPSC */
+    SPI_I2SPSC(spi_periph) = (uint32_t)(temp_div | temp_of | i2s_mckout);
+
+    /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */
+    SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN|SPI_I2SCTL_CHLEN));
+    /* configure data frame format */
+    SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat;
+}
+
+/*!
+    \brief      I2S parameter configuration
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4)
+    \param[in]  i2s_mode: 
+      \arg        I2S_MODE_SLAVETX : I2S slave transmit mode
+      \arg        I2S_MODE_SLAVERX : I2S slave receive mode
+      \arg        I2S_MODE_MASTERTX : I2S master transmit mode
+      \arg        I2S_MODE_MASTERRX : I2S master receive mode
+    \param[in]  i2s_std: 
+      \arg        I2S_STD_PHILLIPS : I2S phillips standard
+      \arg        I2S_STD_MSB : I2S MSB standard
+      \arg        I2S_STD_LSB : I2S LSB standard
+      \arg        I2S_STD_PCMSHORT : I2S PCM short standard
+      \arg        I2S_STD_PCMLONG : I2S PCM long standard
+    \param[in]  i2s_ckpl: 
+      \arg        I2S_CKPL_LOW : I2S clock polarity low level
+      \arg        I2S_CKPL_HIGH : I2S clock polarity high level
+    \param[out] none
+    \retval     none
+*/
+void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl)
+{
+    uint32_t reg= 0U;
+    reg = SPI_I2SCTL(spi_periph);
+    reg &= I2S_INIT_MASK;
+
+    /* enable I2S mode */
+    reg |= (uint32_t)SPI_I2SCTL_I2SSEL; 
+    /* select I2S mode */
+    reg |= (uint32_t)i2s_mode;
+    /* select I2S standard */
+    reg |= (uint32_t)i2s_standard;
+    /* select I2S polarity */
+    reg |= (uint32_t)i2s_ckpl;
+
+    /* write to SPI_I2SCTL register */
+    SPI_I2SCTL(spi_periph) = (uint32_t)reg;
+}
+
+/*!
+    \brief      I2S enable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4)
+    \param[out] none
+    \retval     none
+*/
+void i2s_enable(uint32_t spi_periph)
+{
+    SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
+}
+
+/*!
+    \brief      I2S disable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4)
+    \param[out] none
+    \retval     none
+*/
+void i2s_disable(uint32_t spi_periph)
+{
+    SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
+}
+
+/*!
+    \brief      SPI nss output enable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_output_enable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
+}
+
+/*!
+    \brief      SPI nss output disable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_output_disable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV);
+}
+
+/*!
+    \brief      SPI nss pin high level in software mode
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_internal_high(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS;
+}
+
+/*!
+    \brief      SPI nss pin low level in software mode
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_internal_low(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS);
+}
+
+/*!
+    \brief      SPI dma send or receive enable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_dma: 
+      \arg        SPI_DMA_TRANSMIT: enable DMA transmit
+      \arg        SPI_DMA_RECEIVE: enable DMA receive
+    \param[out] none
+    \retval     none
+*/
+void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma)
+{
+    if(SPI_DMA_TRANSMIT == spi_dma){
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
+    }else{
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
+    }
+}
+
+/*!
+    \brief      SPI dma send or receive diable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_dma: 
+      \arg        SPI_DMA_TRANSMIT: disable DMA transmit
+      \arg        SPI_DMA_RECEIVE: disable DMA receive
+    \param[out] none
+    \retval     none
+*/
+void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma)
+{
+    if(SPI_DMA_TRANSMIT == spi_dma){
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN);
+    }else{
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN);
+    }
+}
+
+/*!
+    \brief      configure SPI/I2S data frame format
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  frame_format: 
+      \arg        SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits
+      \arg        SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format)
+{
+    /* clear SPI_CTL0_FF16 bit */
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16);
+    /* confige SPI_CTL0_FF16 bit */
+    SPI_CTL0(spi_periph) |= (uint32_t)frame_format;
+}
+
+/*!
+    \brief      SPI transmit data
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  data: 16-bit data
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data)
+{
+    SPI_DATA(spi_periph) = (uint32_t)data;
+}
+
+/*!
+    \brief      receive data
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     16-bit data
+*/
+uint16_t spi_i2s_data_receive(uint32_t spi_periph)
+{
+    return ((uint16_t)SPI_DATA(spi_periph));
+}
+
+/*!
+    \brief      configure SPI bidirectional transfer direction
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  transfer_direction:
+      \arg        SPI_BIDIRECTIONAL_TEANSMIT: SPI work in transmit-only mode
+      \arg        SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode
+    \retval     none
+*/
+void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction)
+{
+    if(SPI_BIDIRECTIONAL_TEANSMIT == transfer_direction){
+        /* set the transmit only mode */
+        SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TEANSMIT;
+    }else{
+        /* set the receive only mode */
+        SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE;
+    }
+}
+
+/*!
+    \brief      SPI and I2S interrupt enable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_i2s_int:
+      \arg        SPI_I2S_INT_TBE: transmit buffer empty interrupt
+      \arg        SPI_I2S_INT_RBNE: receive buffer not empty interrupt
+      \arg        SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
+                                   transmission underrun error and format error interrupt
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t spi_i2s_int)
+{
+    switch(spi_i2s_int){
+    case SPI_I2S_INT_TBE:
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE;
+        break;
+    case SPI_I2S_INT_RBNE:
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE;
+        break;
+    case SPI_I2S_INT_ERR:
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      SPI and I2S interrupt disable
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_i2s_int:
+      \arg        SPI_I2S_INT_TBE: transmit buffer empty interrupt
+      \arg        SPI_I2S_INT_RBNE: receive buffer not empty interrupt
+      \arg        SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
+                                   transmission underrun error and format error interrupt
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t spi_i2s_int)
+{
+    switch(spi_i2s_int){
+    case SPI_I2S_INT_TBE :
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE);
+        break;
+    case SPI_I2S_INT_RBNE :
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE);
+        break;
+    case SPI_I2S_INT_ERR :
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE);
+        break;
+    default :
+        break;
+    }
+}
+
+/*!
+    \brief      get interrupt flag status
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_i2s_int:
+      \arg        SPI_I2S_INT_TBE: transmit buffer empty interrupt
+      \arg        SPI_I2S_INT_RBNE: receive buffer not empty interrupt
+      \arg        SPI_I2S_INT_RXORERR: overrun interrupt
+      \arg        SPI_INT_CONFERR: config error interrupt
+      \arg        SPI_INT_CRCERR: CRC error interrupt
+      \arg        I2S_INT_TXURERR: underrun error interrupt
+      \arg        SPI_I2S_INT_FERR: format error interrupt
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t spi_i2s_int)
+{
+    uint32_t reg1 = SPI_STAT(spi_periph);
+    uint32_t reg2 = SPI_CTL1(spi_periph);
+    
+    uint32_t temp1 = 0U;
+    uint32_t temp2 = 0U;
+
+    switch(spi_i2s_int){
+    case SPI_I2S_INT_TBE :
+        temp1 = reg1 & SPI_STAT_TBE;
+        temp2 = reg2 & SPI_CTL1_TBEIE;
+        break;
+    case SPI_I2S_INT_RBNE :
+        temp1 = reg1 & SPI_STAT_RBNE;
+        temp2 = reg2 & SPI_CTL1_RBNEIE;
+        break;
+    case SPI_I2S_INT_RXORERR :
+        temp1 = reg1 & SPI_STAT_RXORERR;
+        temp2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    case SPI_INT_CONFERR :
+        temp1 = reg1 & SPI_STAT_CONFERR;
+        temp2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    case SPI_INT_CRCERR :
+        temp1 = reg1 & SPI_STAT_CRCERR;
+        temp2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    case I2S_INT_TXURERR :
+        temp1 = reg1 & SPI_STAT_TXURERR;
+        temp2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    case SPI_I2S_INT_FERR :
+        temp1 = reg1 & SPI_STAT_FERR;
+        temp2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    default :
+        break;
+    }
+
+    if(temp1 && temp2){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      get flag status
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_i2s_flag:
+      \arg        SPI_FLAG_TBE: transmit buffer empty flag
+      \arg        SPI_FLAG_RBNE: receive buffer not empty flag
+      \arg        SPI_FLAG_TRANS: transmit on-going flag
+      \arg        SPI_FLAG_RXORERR: receive Overrun flag
+      \arg        SPI_FLAG_CONFERR: mode config error flag
+      \arg        SPI_FLAG_CRCERR: CRC error flag
+      \arg        SPI_FLAG_FERR: format error interrupt flag
+      \arg        I2S_FLAG_TBE: transmit buffer empty flag
+      \arg        I2S_FLAG_RBNE: receive buffer not empty flag
+      \arg        I2S_FLAG_TRANS: transmit on-going flag
+      \arg        I2S_FLAG_RXORERR: overrun flag
+      \arg        I2S_FLAG_TXURERR: underrun error flag
+      \arg        I2S_FLAG_CH: channel side flag
+      \arg        I2S_FLAG_FERR: format error interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t spi_i2s_flag)
+{
+    if(SPI_STAT(spi_periph) & spi_i2s_flag){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear SPI CRC error flag status
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_error_clear(uint32_t spi_periph)
+{
+    SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR);
+}
+
+/*!
+    \brief      CRC function turn on
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_on(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
+}
+
+/*!
+    \brief      CRC function turn off
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_off(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
+}
+
+/*!
+    \brief      CRC polynomial set
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  crc_poly: CRC polynomial value
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly)
+{
+    /* enable SPI CRC */
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
+
+    /* set SPI CRC polynomial */
+    SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly;
+}
+
+/*!
+    \brief      get SPI CRC polynomial 
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     16-bit CRC polynomial
+*/
+uint16_t spi_crc_polynomial_get(uint32_t spi_periph)
+{
+    return ((uint16_t)SPI_CRCPOLY(spi_periph));
+}
+
+/*!
+    \brief      SPI next data is CRC value
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_next(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT;
+}
+
+/*!
+    \brief      get SPI CRC send value or receive value
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[in]  spi_crc: 
+      \arg        SPI_CRC_TX: get transmit crc value
+      \arg        SPI_CRC_RX: get receive crc value
+    \param[out] none
+    \retval     16-bit CRC value
+*/
+uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc)
+{
+    if(SPI_CRC_TX == spi_crc){
+        return ((uint16_t)(SPI_TCRC(spi_periph)));
+    }else{
+        return ((uint16_t)(SPI_RCRC(spi_periph)));
+    }
+}
+
+/*!
+    \brief      enable SPI TI mode
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_ti_mode_enable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD;
+}
+
+/*!
+    \brief      disable SPI TI mode
+    \param[in]  spi_periph: SPIx(x=0,1,2,3,4,5)
+    \param[out] none
+    \retval     none
+*/
+void spi_ti_mode_disable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD);
+}
+
+/*!
+    \brief      configure i2s full duplex mode
+    \param[in]  i2s_add_periph: I2Sx_ADD(x=1,2)
+    \param[in]  i2s_mode: 
+      \arg        I2S_MODE_SLAVETX : I2S slave transmit mode
+      \arg        I2S_MODE_SLAVERX : I2S slave receive mode
+      \arg        I2S_MODE_MASTERTX : I2S master transmit mode
+      \arg        I2S_MODE_MASTERRX : I2S master receive mode
+    \param[in]  i2s_standard: 
+      \arg        I2S_STD_PHILLIPS : I2S phillips standard
+      \arg        I2S_STD_MSB : I2S MSB standard
+      \arg        I2S_STD_LSB : I2S LSB standard
+      \arg        I2S_STD_PCMSHORT : I2S PCM short standard
+      \arg        I2S_STD_PCMLONG : I2S PCM long standard
+    \param[in]  i2s_ckpl: 
+      \arg        I2S_CKPL_LOW : I2S clock polarity low level
+      \arg        I2S_CKPL_HIGH : I2S clock polarity high level
+    \param[in]  i2s_frameformat:
+      \arg        I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
+      \arg        I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
+      \arg        I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
+      \arg        I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
+    \param[out] none
+    \retval     none
+*/
+void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard,
+                                 uint32_t i2s_ckpl, uint32_t i2s_frameformat)
+{
+    uint32_t reg = 0U, tmp = 0U;
+
+    reg = I2S_ADD_I2SCTL(i2s_add_periph);
+    reg &= I2S_FULL_DUPLEX_MASK;  
+
+    /* get the mode of the extra I2S module I2Sx_ADD */
+    if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)){
+        tmp = I2S_MODE_SLAVERX;
+    }else{
+        tmp = I2S_MODE_SLAVETX;
+    }
+
+    /* enable I2S mode */
+    reg |= (uint32_t)SPI_I2SCTL_I2SSEL; 
+    /* select I2S mode */
+    reg |= (uint32_t)tmp;
+    /* select I2S standard */
+    reg |= (uint32_t)i2s_standard;
+    /* select I2S polarity */
+    reg |= (uint32_t)i2s_ckpl;
+    /* configure data frame format */
+    reg |= (uint32_t)i2s_frameformat;
+
+    /* write to SPI_I2SCTL register */
+    I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg;
+}
+
+/*!
+    \brief      quad wire SPI enable 
+    \param[in]  spi_periph: SPIx(only x=5)
+    \param[out] none
+    \retval     none
+*/
+void qspi_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD;
+}
+
+/*!
+    \brief      quad wire SPI disable
+    \param[in]  spi_periph: SPIx(only x=5)
+    \param[out] none
+    \retval     none
+*/
+void qspi_disable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD);
+}
+
+/*!
+    \brief      quad wire SPI write enable
+    \param[in]  spi_periph: SPIx(only x=5)
+    \param[out] none
+    \retval     none
+*/
+void qspi_write_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD);
+}
+
+/*!
+    \brief      quad wire SPI read enable
+    \param[in]  spi_periph: SPIx(only x=5)
+    \param[out] none
+    \retval     none
+*/
+void qspi_read_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD;
+}
+
+/*!
+    \brief      SPI_IO2 and SPI_IO3 pin output enable
+    \param[in]  spi_periph: SPIx(only x=5)
+    \param[out] none
+    \retval     none
+*/
+void qspi_io23_output_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV;
+}
+
+ /*!
+    \brief      SPI_IO2 and SPI_IO3 pin output disable
+    \param[in]  spi_periph: SPIx(only x=5)
+    \param[out] none
+    \retval     none
+*/
+ void qspi_io23_output_disable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
+}

+ 172 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c

@@ -0,0 +1,172 @@
+/*!
+    \file  gd32f4xx_syscfg.c
+    \brief SYSCFG driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_syscfg.h"
+
+/*!
+    \brief      reset the SYSCFG registers
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void syscfg_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_SYSCFGRST);
+    rcu_periph_reset_disable(RCU_SYSCFGRST);
+}
+
+/*!
+    \brief      configure the boot mode 
+    \param[in]  syscfg_bootmode: selects the memory remapping
+      \arg        SYSCFG_BOOTMODE_FLASH: main flash memory (0x08000000~0x083BFFFF) is mapped at address 0x00000000
+      \arg        SYSCFG_BOOTMODE_BOOTLOADER: boot loader (0x1FFF0000 - 0x1FFF77FF) is mapped at address 0x00000000
+      \arg        SYSCFG_BOOTMODE_EXMC_SRAM: SRAM/NOR 0 and 1 of EXMC (0x60000000~0x67FFFFFF) is mapped at address 0x00000000
+      \arg        SYSCFG_BOOTMODE_SRAM: SRAM0 of on-chip SRAM (0x20000000~0x2001BFFF) is mapped at address 0x00000000
+      \arg        SYSCFG_BOOTMODE_EXMC_SDRAM: SDRAM bank0 of EXMC (0xC0000000~0xC7FFFFFF) is mapped at address 0x00000000
+    \param[out] none
+    \retval     none
+*/
+void syscfg_bootmode_config(uint8_t syscfg_bootmode)
+{
+    /* reset the SYSCFG_CFG0_BOOT_MODE bit and set according to syscfg_bootmode */
+    SYSCFG_CFG0 &= ~SYSCFG_CFG0_BOOT_MODE;
+    SYSCFG_CFG0 |= (uint32_t)syscfg_bootmode;
+}
+
+/*!
+    \brief      FMC memory mapping swap
+    \param[in]  syscfg_fmc_swap: selects the interal flash bank swapping
+      \arg        SYSCFG_FMC_SWP_BANK0: bank 0 is mapped at address 0x08000000 and bank 1 is mapped at address 0x08100000
+      \arg        SYSCFG_FMC_SWP_BANK1: bank 1 is mapped at address 0x08000000 and bank 0 is mapped at address 0x08100000
+    \param[out] none
+    \retval     none
+*/
+void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap)
+{
+    uint32_t reg;
+    reg = SYSCFG_CFG0;
+    /* reset the FMC_SWP bit and set according to syscfg_fmc_swap */
+    reg &= ~SYSCFG_CFG0_FMC_SWP;
+    SYSCFG_CFG0 = (reg | syscfg_fmc_swap);
+}
+
+/*!
+    \brief      EXMC memory mapping swap
+    \param[in]  syscfg_exmc_swap: selects the memories in EXMC swapping
+      \arg        SYSCFG_EXMC_SWP_ENABLE: SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card
+      \arg        SYSCFG_EXMC_SWP_DISABLE: no memory mapping swap
+    \param[out] none
+    \retval     none
+*/
+void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap)
+{
+    uint32_t reg;
+
+    reg = SYSCFG_CFG0;
+    /* reset the SYSCFG_CFG0_EXMC_SWP bits and set according to syscfg_exmc_swap */
+    reg &= ~SYSCFG_CFG0_EXMC_SWP;
+    SYSCFG_CFG0 = (reg | syscfg_exmc_swap);
+}
+
+/*!
+    \brief      configure the GPIO pin as EXTI Line
+    \param[in]  exti_port: specify the GPIO port used in EXTI
+      \arg        EXTI_SOURCE_GPIOx(x = A,B,C,D,E,F,G,H,I): EXTI GPIO port
+    \param[in]  exti_pin: specify the EXTI line
+      \arg        EXTI_SOURCE_PINx(x = 0..15): EXTI GPIO pin
+    \param[out] none
+    \retval     none
+*/
+void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin)
+{
+    uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin)));
+    uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin));
+
+    switch(exti_pin/EXTI_SS_JSTEP){
+    case EXTISS0:
+        /* clear EXTI source line(0..3) */
+        SYSCFG_EXTISS0 &= clear_exti_mask;
+        /* configure EXTI soure line(0..3) */
+        SYSCFG_EXTISS0 |= config_exti_mask;
+        break;
+    case EXTISS1:
+        /* clear EXTI soure line(4..7) */
+        SYSCFG_EXTISS1 &= clear_exti_mask;
+        /* configure EXTI soure line(4..7) */
+        SYSCFG_EXTISS1 |= config_exti_mask;
+        break;
+    case EXTISS2:
+        /* clear EXTI soure line(8..11) */
+        SYSCFG_EXTISS2 &= clear_exti_mask;
+        /* configure EXTI soure line(8..11) */
+        SYSCFG_EXTISS2 |= config_exti_mask;
+        break;
+    case EXTISS3:
+        /* clear EXTI soure line(12..15) */
+        SYSCFG_EXTISS3 &= clear_exti_mask;
+        /* configure EXTI soure line(12..15) */
+        SYSCFG_EXTISS3 |= config_exti_mask;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure the PHY interface for the ethernet MAC
+    \param[in]  syscfg_enet_phy_interface: specifies the media interface mode.
+      \arg        SYSCFG_ENET_PHY_MII: MII mode is selected
+      \arg        SYSCFG_ENET_PHY_RMII: RMII mode is selected 
+    \param[out] none
+    \retval     none
+*/
+void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface)
+{ 
+    uint32_t reg;
+    
+    reg = SYSCFG_CFG1;
+    /* reset the ENET_PHY_SEL bit and set according to syscfg_enet_phy_interface */
+    reg &= ~SYSCFG_CFG1_ENET_PHY_SEL;
+    SYSCFG_CFG1 = (reg | syscfg_enet_phy_interface);
+}
+
+/*!
+    \brief      configure the I/O compensation cell
+    \param[in]  syscfg_compensation: specifies the I/O compensation cell mode
+      \arg        SYSCFG_COMPENSATION_ENABLE: I/O compensation cell is enabled
+      \arg        SYSCFG_COMPENSATION_DISABLE: I/O compensation cell is disabled
+    \param[out] none
+    \retval     none
+*/
+void syscfg_compensation_config(uint32_t syscfg_compensation) 
+{
+    uint32_t reg;
+
+    reg = SYSCFG_CPSCTL;
+    /* reset the SYSCFG_CPSCTL_CPS_EN bit and set according to syscfg_compensation */
+    reg &= ~SYSCFG_CPSCTL_CPS_EN;
+    SYSCFG_CPSCTL = (reg | syscfg_compensation);
+}
+
+/*!
+    \brief      checks whether the I/O compensation cell ready flag is set or not
+    \param[in]  none
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+  */
+FlagStatus syscfg_flag_get(void)
+{
+    if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}

+ 1892 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c

@@ -0,0 +1,1892 @@
+/*!
+    \file  gd32f4xx_timer.c
+    \brief TIMER driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_timer.h"
+
+/*!
+    \brief      deinit a TIMER
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_deinit(uint32_t timer_periph)
+{
+    switch(timer_periph){
+    case TIMER0:
+        /* reset TIMER0 */
+        rcu_periph_reset_enable(RCU_TIMER0RST);
+        rcu_periph_reset_disable(RCU_TIMER0RST);
+        break;
+    case TIMER1:
+        /* reset TIMER1 */
+        rcu_periph_reset_enable(RCU_TIMER1RST);
+        rcu_periph_reset_disable(RCU_TIMER1RST);
+        break;
+    case TIMER2:
+        /* reset TIMER2 */
+        rcu_periph_reset_enable(RCU_TIMER2RST);
+        rcu_periph_reset_disable(RCU_TIMER2RST);
+        break;
+    case TIMER3:
+        /* reset TIMER3 */
+        rcu_periph_reset_enable(RCU_TIMER3RST);
+        rcu_periph_reset_disable(RCU_TIMER3RST);
+        break;
+    case TIMER4:
+        /* reset TIMER4 */
+        rcu_periph_reset_enable(RCU_TIMER4RST);
+        rcu_periph_reset_disable(RCU_TIMER4RST);
+        break;
+    case TIMER5:
+        /* reset TIMER5 */
+        rcu_periph_reset_enable(RCU_TIMER5RST);
+        rcu_periph_reset_disable(RCU_TIMER5RST);
+        break;
+    case TIMER6:
+        /* reset TIMER6 */
+        rcu_periph_reset_enable(RCU_TIMER6RST);
+        rcu_periph_reset_disable(RCU_TIMER6RST);
+        break;
+    case TIMER7:
+        /* reset TIMER7 */
+        rcu_periph_reset_enable(RCU_TIMER7RST);
+        rcu_periph_reset_disable(RCU_TIMER7RST);
+        break;
+    case TIMER8:
+        /* reset TIMER8 */
+        rcu_periph_reset_enable(RCU_TIMER8RST);
+        rcu_periph_reset_disable(RCU_TIMER8RST);
+        break;
+    case TIMER9:
+        /* reset TIMER9 */
+        rcu_periph_reset_enable(RCU_TIMER9RST);
+        rcu_periph_reset_disable(RCU_TIMER9RST);
+        break;
+    case TIMER10:
+        /* reset TIMER10 */
+        rcu_periph_reset_enable(RCU_TIMER10RST);
+        rcu_periph_reset_disable(RCU_TIMER10RST);
+        break;
+    case TIMER11:
+        /* reset TIMER11 */
+        rcu_periph_reset_enable(RCU_TIMER11RST);
+        rcu_periph_reset_disable(RCU_TIMER11RST);
+        break;
+    case TIMER12:
+        /* reset TIMER12 */
+        rcu_periph_reset_enable(RCU_TIMER12RST);
+        rcu_periph_reset_disable(RCU_TIMER12RST);
+        break;
+    case TIMER13:
+        /* reset TIMER13 */
+        rcu_periph_reset_enable(RCU_TIMER13RST);
+        rcu_periph_reset_disable(RCU_TIMER13RST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      initialize TIMER counter
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[in]  timer_initpara: init parameter struct
+                prescaler: prescaler value of the counter clock,0~65535
+                alignedmode: TIMER_COUNTER_EDGE,TIMER_COUNTER_CENTER_DOWN,TIMER_COUNTER_CENTER_UP,TIMER_COUNTER_CENTER_BOTH
+                counterdirection: TIMER_COUNTER_UP,TIMER_COUNTER_DOWN
+                period: counter auto reload value,(TIMER1,TIMER4,32 bit)
+                clockdivision: TIMER_CKDIV_DIV1,TIMER_CKDIV_DIV2,TIMER_CKDIV_DIV4
+                repetitioncounter: counter repetition value,0~255
+    \param[out] none
+    \retval     none
+*/
+void timer_init(uint32_t timer_periph, timer_parameter_struct* timer_initpara)
+{
+    /* configure the counter prescaler value */
+    TIMER_PSC(timer_periph) = (uint16_t)timer_initpara->prescaler;
+
+    /* configure the counter direction and aligned mode */
+    if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph)
+        || (TIMER3 == timer_periph) || (TIMER4 == timer_periph) || (TIMER7 == timer_periph)){
+        TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR|TIMER_CTL0_CAM);
+        TIMER_CTL0(timer_periph) |= (uint32_t)timer_initpara->alignedmode;
+        TIMER_CTL0(timer_periph) |= (uint32_t)timer_initpara->counterdirection;
+    }
+
+    /* configure the autoreload value */
+    TIMER_CAR(timer_periph) = (uint32_t)timer_initpara->period;
+
+    if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)){
+        /* reset the CKDIV bit */
+        TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV;
+        TIMER_CTL0(timer_periph) |= (uint32_t)timer_initpara->clockdivision;
+    }
+
+    if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){
+        /* configure the repetition counter value */
+        TIMER_CREP(timer_periph) = (uint32_t)timer_initpara->repetitioncounter;
+    }
+
+    /* generate an update event */
+    TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG;
+}
+
+/*!
+    \brief      enable a TIMER
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_enable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN;
+}
+
+/*!
+    \brief      disable a TIMER
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_disable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN;
+}
+
+/*!
+    \brief      enable the auto reload shadow function
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_auto_reload_shadow_enable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE;
+}
+
+/*!
+    \brief      disable the auto reload shadow function
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_auto_reload_shadow_disable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE;
+}
+
+/*!
+    \brief      enable the update event
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_update_event_enable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS;
+}
+
+/*!
+    \brief      disable the update event
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     none
+*/
+void timer_update_event_disable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS;
+}
+
+/*!
+    \brief      set TIMER counter alignment mode
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[in]  timer_aligned: 
+      \arg        TIMER_COUNTER_EDGE: edge-aligned mode
+      \arg        TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode
+      \arg        TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode
+      \arg        TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode
+    \param[out] none
+    \retval     none
+*/
+void timer_counter_alignment(uint32_t timer_periph,uint16_t timer_aligned)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CAM;
+    TIMER_CTL0(timer_periph) |= (uint32_t)timer_aligned;
+}
+
+/*!
+    \brief      set TIMER counter up direction
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_counter_up_direction(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR;
+}
+
+/*!
+    \brief      set TIMER counter down direction
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_counter_down_direction(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR;
+}
+
+/*!
+    \brief      configure TIMER prescaler
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[in]  timer_prescaler: prescaler value
+    \param[in]  timer_pscreload: prescaler reload mode
+      \arg        TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now
+      \arg        TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event
+    \param[out] none
+    \retval     none
+*/
+void timer_prescaler_config(uint32_t timer_periph,uint16_t timer_prescaler,uint8_t timer_pscreload)
+{
+    TIMER_PSC(timer_periph) = (uint32_t)timer_prescaler;
+    
+    if(TIMER_PSC_RELOAD_NOW == timer_pscreload){
+        TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG;
+    }
+}
+
+/*!
+    \brief      configure TIMER repetition register value
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  timer_repetition: the counter repetition value,0~255
+    \param[out] none
+    \retval     none
+*/
+void timer_repetition_value_config(uint32_t timer_periph,uint16_t timer_repetition)
+{
+    TIMER_CREP(timer_periph) = (uint32_t)timer_repetition;
+} 
+ 
+/*!
+    \brief      configure TIMER autoreload register value
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[in]  timer_autoreload: the counter auto-reload value
+    \param[out] none
+    \retval     none
+*/         
+void timer_autoreload_value_config(uint32_t timer_periph,uint32_t timer_autoreload)
+{
+    TIMER_CAR(timer_periph) = (uint32_t)timer_autoreload;
+}
+
+/*!
+    \brief      configure TIMER counter register value
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[in]  timer_counter: the counter value
+    \param[out] none
+    \retval     none
+*/         
+void timer_counter_value_config(uint32_t timer_periph , uint32_t timer_counter)
+{
+    TIMER_CNT(timer_periph) = (uint32_t)timer_counter;
+}
+
+/*!
+    \brief      read TIMER counter value
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     counter value
+*/         
+uint32_t timer_counter_read(uint32_t timer_periph)
+{
+    uint32_t count_value = 0U;
+    count_value = TIMER_CNT(timer_periph);
+    return (count_value);
+}
+
+/*!
+    \brief      read TIMER prescaler value
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[out] none
+    \retval     prescaler register value
+*/         
+uint16_t timer_prescaler_read(uint32_t timer_periph)
+{
+    uint16_t prescaler_value = 0U;
+    prescaler_value = (uint16_t)(TIMER_CAR(timer_periph));
+    return (prescaler_value);
+}
+
+/*!
+    \brief      configure TIMER single pulse mode
+    \param[in]  timer_periph: TIMERx(x=0..8,11)
+    \param[in]  timer_spmode: 
+      \arg        TIMER_SP_MODE_SINGLE: single pulse mode
+      \arg        TIMER_SP_MODE_REPETITIVE: repetitive pulse mode
+    \param[out] none
+    \retval     none
+*/
+void timer_single_pulse_mode_config(uint32_t timer_periph,uint8_t timer_spmode)
+{
+    if(TIMER_SP_MODE_SINGLE == timer_spmode){
+        TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM;
+    }else if(TIMER_SP_MODE_REPETITIVE == timer_spmode){
+        TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM);
+    }else{
+    }
+}
+
+/*!
+    \brief      configure TIMER update source 
+    \param[in]  timer_periph: TIMERx(x=0..13)
+    \param[in]  timer_update: 
+      \arg        TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger
+      \arg        TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow
+    \param[out] none
+    \retval     none
+*/
+void timer_update_source_config(uint32_t timer_periph,uint8_t timer_update)
+{
+    if(TIMER_UPDATE_SRC_REGULAR == timer_update){
+        TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS;
+    }else if(timer_update == TIMER_UPDATE_SRC_GLOBAL){
+        TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS;
+    }else{
+    }
+}
+
+/*!
+    \brief      enable the TIMER interrupt
+    \param[in]  timer_periph: please refer to the following parameters 
+    \param[in]  timer_interrupt: timer interrupt enable source
+      \arg        TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13)
+      \arg        TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13)
+      \arg        TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7)
+      \arg        TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_interrupt_enable(uint32_t timer_periph,uint32_t timer_interrupt)
+{
+    TIMER_DMAINTEN(timer_periph) |= (uint32_t) timer_interrupt; 
+}
+
+/*!
+    \brief      disable the TIMER interrupt
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_interrupt: timer interrupt source enable 
+      \arg        TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13)
+      \arg        TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13)
+      \arg        TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7)
+      \arg        TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_interrupt_disable(uint32_t timer_periph,uint32_t timer_interrupt)
+{
+    TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)timer_interrupt); 
+}
+
+/*!
+    \brief      get timer interrupt flag
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_interrupt: the timer interrupt bits
+      \arg        TIMER_INT_UP: update interrupt flag,TIMERx(x=0..13)
+      \arg        TIMER_INT_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13)
+      \arg        TIMER_INT_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_INT_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CMT: channel commutation interrupt flag,TIMERx(x=0,7) 
+      \arg        TIMER_INT_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11)
+      \arg        TIMER_INT_BRK:  break interrupt flag,TIMERx(x=0,7)
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus timer_interrupt_flag_get(uint32_t timer_periph,uint32_t timer_interrupt)
+{
+    uint32_t val;
+    val = (TIMER_DMAINTEN(timer_periph) & timer_interrupt);
+    if((RESET != (TIMER_INTF(timer_periph) & timer_interrupt) ) && (RESET != val)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear TIMER interrupt flag
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_interrupt: the timer interrupt bits
+      \arg        TIMER_INT_UP: update interrupt flag,TIMERx(x=0..13)
+      \arg        TIMER_INT_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13)
+      \arg        TIMER_INT_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_INT_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7)
+      \arg        TIMER_INT_CMT: channel commutation interrupt flag,TIMERx(x=0,7) 
+      \arg        TIMER_INT_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11)
+      \arg        TIMER_INT_BRK:  break interrupt flag,TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_interrupt_flag_clear(uint32_t timer_periph,uint32_t timer_interrupt)
+{
+    TIMER_INTF(timer_periph) &= (~(uint32_t)timer_interrupt);
+}
+
+/*!
+    \brief      get TIMER flags
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_flag: the timer interrupt flags
+      \arg        TIMER_FLAG_UP: update flag,TIMERx(x=0..13)
+      \arg        TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13)
+      \arg        TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7)
+      \arg        TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7)
+      \arg        TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) 
+      \arg        TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) 
+      \arg        TIMER_FLAG_BRK: break flag,TIMERx(x=0,7)
+      \arg        TIMER_FLAG_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11)
+      \arg        TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7)
+      \arg        TIMER_FLAG_CH3OF: channel 3 overcapture flag,TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus timer_flag_get(uint32_t timer_periph , uint32_t timer_flag)
+{
+    if(RESET != (TIMER_INTF(timer_periph) & timer_flag)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear TIMER flags
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_flag: the timer interrupt flags
+      \arg        TIMER_FLAG_UP: update flag,TIMERx(x=0..13)
+      \arg        TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13)
+      \arg        TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7)
+      \arg        TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7)
+      \arg        TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) 
+      \arg        TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) 
+      \arg        TIMER_FLAG_BRK: break flag,TIMERx(x=0,7)
+      \arg        TIMER_FLAG_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11)
+      \arg        TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7)
+      \arg        TIMER_FLAG_CH3OF: channel 3 overcapture flag,TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_flag_clear(uint32_t timer_periph , uint32_t timer_flag)
+{
+    TIMER_INTF(timer_periph) &= (~(uint32_t)timer_flag);
+}
+
+/*!
+    \brief      enable the TIMER DMA
+    \param[in]  timer_periph: TIMERx(x=0,1,2,5,14,15,16)
+    \param[in]  timer_dma: timer DMA source enable 
+      \arg        TIMER_DMA_UPD:  update DMA enable,TIMERx(x=0..7)
+      \arg        TIMER_DMA_CH0D: channel 0 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CH1D: channel 1 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CH2D: channel 2 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CH3D: channel 3 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CMTD: commutation DMA request enable,TIMERx(x=0,7)
+      \arg        TIMER_DMA_TRGD: trigger DMA enable,TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_dma_enable(uint32_t timer_periph,uint16_t timer_dma)
+{
+    TIMER_DMAINTEN(timer_periph) |= (uint32_t) timer_dma; 
+}
+
+/*!
+    \brief      disable the TIMER DMA
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_dma: timer DMA source enable 
+      \arg        TIMER_DMA_UPD:  update DMA enable,TIMERx(x=0..7)
+      \arg        TIMER_DMA_CH0D: channel 0 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CH1D: channel 1 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CH2D: channel 2 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CH3D: channel 3 DMA enable,TIMERx(x=0..4,7)
+      \arg        TIMER_DMA_CMTD: commutation DMA request enable,TIMERx(x=0,7)
+      \arg        TIMER_DMA_TRGD: trigger DMA enable,TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_dma_disable(uint32_t timer_periph,uint16_t timer_dma)
+{
+    TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(timer_dma)); 
+}
+
+/*!
+    \brief      channel DMA request source selection
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[in]  dma_request: channel DMA request source selection
+       \arg        TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs
+       \arg        TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_dma_request_source_select(uint32_t timer_periph,uint8_t dma_request)
+{
+    if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS;
+    }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){
+        TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS;
+    }else{
+    }
+}
+
+/*!
+    \brief      configure the TIMER DMA transfer
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  dma_baseaddr: 
+       \arg        TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP,TIMERx(x=0,7)
+       \arg        TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP,TIMERx(x=0,7)
+       \arg        TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG,TIMERx(x=0..4,7)
+       \arg        TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB,TIMERx(x=0..4,7)
+    \param[in]  dma_lenth:
+       \arg        TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time
+    \param[out] none
+    \retval     none
+*/
+void timer_dma_transfer_config(uint32_t timer_periph,uint32_t dma_baseaddr,uint32_t dma_lenth)
+{
+    TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC));
+    TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth);
+}
+
+/*!
+    \brief      software generate events 
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_event: the timer software event generation sources
+      \arg        TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0..13)
+      \arg        TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation,TIMERx(x=0..4,7..13) 
+      \arg        TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation,TIMERx(x=0..4,7) 
+      \arg        TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation,TIMERx(x=0..4,7) 
+      \arg        TIMER_EVENT_SRC_CMTG: channel commutation event generation,TIMERx(x=0,7) 
+      \arg        TIMER_EVENT_SRC_TRGG: trigger event generation,TIMERx(x=0..4,7,8,11)
+      \arg        TIMER_EVENT_SRC_BRKG:  break event generation,TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_event_software_generate(uint32_t timer_periph,uint16_t timer_event)
+{
+    TIMER_SWEVG(timer_periph) |= (uint32_t)timer_event;
+}
+
+/*!
+    \brief      configure TIMER break function 
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  timer_bkdtpara: TIMER break parameter struct
+                runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE
+                ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE
+                deadtime: 0~255
+                breakpolarity: TIMER_BREAK_POLARITY_LOW,TIMER_BREAK_POLARITY_HIGH
+                outputautostate: TIMER_OUTAUTO_ENABLE,TIMER_OUTAUTO_DISABLE
+                protectmode: TIMER_CCHP_PROT_OFF,TIMER_CCHP_PROT_0,TIMER_CCHP_PROT_1,TIMER_CCHP_PROT_2
+                breakstate: TIMER_BREAK_ENABLE,TIMER_BREAK_DISABLE
+    \param[out] none
+    \retval     none
+*/
+void timer_break_config(uint32_t timer_periph,timer_break_parameter_struct* timer_bkdtpara)
+{
+    TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(timer_bkdtpara->runoffstate))|
+                                          ((uint32_t)(timer_bkdtpara->ideloffstate))|
+                                          ((uint32_t)(timer_bkdtpara->deadtime))|
+                                          ((uint32_t)(timer_bkdtpara->breakpolarity))|
+                                          ((uint32_t)(timer_bkdtpara->outputautostate)) |
+                                          ((uint32_t)(timer_bkdtpara->protectmode))|
+                                          ((uint32_t)(timer_bkdtpara->breakstate))) ;
+}
+
+/*!
+    \brief      enable TIMER break function
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_break_enable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN;
+}
+
+/*!
+    \brief      disable TIMER break function
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_break_disable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN;
+}
+
+/*!
+    \brief      enable TIMER output automatic function
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_automatic_output_enable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN;
+}
+
+/*!
+    \brief      disable TIMER output automatic function
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_automatic_output_disable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN;
+}
+
+/*!
+    \brief      configure TIMER primary output function
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void timer_primary_output_config(uint32_t timer_periph,ControlStatus newvalue)
+{
+    if(ENABLE == newvalue){
+        TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN;
+    }else{
+        TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN);
+    }
+}
+
+/*!
+    \brief      channel capture/compare control shadow register enable
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  newvalue: ENABLE or DISABLE 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_control_shadow_config(uint32_t timer_periph,ControlStatus newvalue)
+{
+     if(ENABLE == newvalue){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE;
+    }else{
+        TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE);
+    }
+}
+
+/*!
+    \brief      configure TIMER channel control shadow register update control
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  timer_ccuctl: channel control shadow register update control
+      \arg        TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set
+      \arg        TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs 
+    \param[out] none
+    \retval     none
+*/              
+void timer_channel_control_shadow_update_config(uint32_t timer_periph,uint8_t timer_ccuctl)
+{
+    if(TIMER_UPDATECTL_CCU == timer_ccuctl){
+        TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC);
+    }else if(TIMER_UPDATECTL_CCUTRI == timer_ccuctl){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC;
+    }else{
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4,7))
+    \param[in]  timer_ocpara: TIMER channeln output parameter struct
+                outputstate: TIMER_CCX_ENABLE,TIMER_CCX_DISABLE
+                outputnstate: TIMER_CCXN_ENABLE,TIMER_CCXN_DISABLE
+                ocpolarity: TIMER_OC_POLARITY_HIGH,TIMER_OC_POLARITY_LOW
+                ocnpolarity: TIMER_OCN_POLARITY_HIGH,TIMER_OCN_POLARITY_LOW
+                ocidlestate: TIMER_OC_IDLE_STATE_LOW,TIMER_OC_IDLE_STATE_HIGH
+                ocnidlestate: TIMER_OCN_IDLE_STATE_LOW,TIMER_OCN_IDLE_STATE_HIGH
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_config(uint32_t timer_periph,uint16_t timer_channel,timer_oc_parameter_struct* timer_ocpara)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocpara->outputstate;
+        /* reset the CH0P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P);
+        /* set the CH0P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocpara->ocpolarity;
+
+        if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){
+            /* reset the CH0NEN bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN);
+            /* set the CH0NEN bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocpara->outputnstate;
+            /* reset the CH0NP bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP);
+            /* set the CH0NP bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocpara->ocnpolarity;
+            /* reset the ISO0 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0);
+            /* set the ISO0 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)timer_ocpara->ocidlestate;
+            /* reset the ISO0N bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N);
+            /* set the ISO0N bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)timer_ocpara->ocnidlestate;
+        }
+        TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_ocpara->outputstate<< 4U);
+        /* reset the CH1P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P);
+        /* set the CH1P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocpolarity)<< 4U);
+
+        if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){
+            /* reset the CH1NEN bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN);
+            /* set the CH1NEN bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->outputnstate)<< 4U);
+            /* reset the CH1NP bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP);
+            /* set the CH1NP bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnpolarity)<< 4U);
+            /* reset the ISO1 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1);
+            /* set the ISO1 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocidlestate)<< 2U);
+            /* reset the ISO1N bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N);
+            /* set the ISO1N bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnidlestate)<< 2U);
+        }
+        TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS;
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        /* reset the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN);
+        /* set the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_ocpara->outputstate<< 8U);
+        /* reset the CH2P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P);
+        /* set the CH2P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocpolarity)<< 8U);
+
+        if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){
+            /* reset the CH2NEN bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN);
+            /* set the CH2NEN bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->outputnstate)<< 8U);
+            /* reset the CH2NP bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP);
+            /* set the CH2NP bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnpolarity)<< 8U);
+            /* reset the ISO2 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2);
+            /* set the ISO2 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocidlestate)<< 4U);
+            /* reset the ISO2N bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N);
+            /* set the ISO2N bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnidlestate)<< 4U);
+        }
+        TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        /* reset the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN);
+        /* set the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_ocpara->outputstate<< 12U);
+        /* reset the CH3P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P);
+        /* set the CH3P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocpolarity)<< 12U);
+
+        if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){
+            /* reset the ISO3 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3);
+            /* set the ISO3 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocidlestate)<< 6U);
+        }
+        TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output compare mode
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_ocmode: channel output compare mode
+      \arg        TIMER_OC_MODE_TIMING: timing mode
+      \arg        TIMER_OC_MODE_ACTIVE: active mode
+      \arg        TIMER_OC_MODE_INACTIVE: inactive mode
+      \arg        TIMER_OC_MODE_TOGGLE: toggle mode
+      \arg        TIMER_OC_MODE_LOW: force low mode
+      \arg        TIMER_OC_MODE_HIGH: force high mode
+      \arg        TIMER_OC_MODE_PWM0: PWM0 mode
+      \arg        TIMER_OC_MODE_PWM1: PWM1 mode
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_mode_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocmode)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_ocmode;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_ocmode)<< 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_ocmode;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocmode)<< 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output pulse value
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_pluse: channel output pulse value
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_pulse_value_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_pluse)
+{
+    switch(timer_channel){
+    case TIMER_CH_0:
+        TIMER_CH0CV(timer_periph) = (uint32_t)timer_pluse;
+        break;
+    case TIMER_CH_1:
+        TIMER_CH1CV(timer_periph) = (uint32_t)timer_pluse;
+        break;
+    case TIMER_CH_2:
+        TIMER_CH2CV(timer_periph) = (uint32_t)timer_pluse;
+        break;
+    case TIMER_CH_3:
+         TIMER_CH3CV(timer_periph) = (uint32_t)timer_pluse;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output shadow function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_ocshadow: channel output shadow state
+      \arg        TIMER_OC_SHADOW_ENABLE: channel output shadow state enable
+      \arg        TIMER_OC_SHADOW_DISABLE: channel output shadow state disable
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_shadow_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocshadow)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_ocshadow;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_ocshadow) << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_ocshadow;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocshadow) << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output fast function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_ocfast: channel output fast function
+      \arg        TIMER_OC_FAST_ENABLE: channel output fast function enable
+      \arg        TIMER_OC_FAST_DISABLE: channel output fast function disable
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_fast_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocfast)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_ocfast;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)timer_ocfast << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_ocfast;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)timer_ocfast << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output clear function
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0
+      \arg        TIMER_CH_1: TIMER channel1
+      \arg        TIMER_CH_2: TIMER channel2
+      \arg        TIMER_CH_3: TIMER channel3
+    \param[in]  timer_occlear: channel output clear function
+      \arg        TIMER_OC_CLEAR_ENABLE: channel output clear function enable
+      \arg        TIMER_OC_CLEAR_DISABLE: channel output clear function disable
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_clear_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_occlear)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_occlear;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)timer_occlear << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_occlear;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)timer_occlear << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output polarity 
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_ocpolarity: channel output polarity 
+      \arg        TIMER_OC_POLARITY_HIGH: channel output polarity is high
+      \arg        TIMER_OC_POLARITY_LOW: channel output polarity is low
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_polarity_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocpolarity)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocpolarity;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocpolarity << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocpolarity << 8U);
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocpolarity << 12U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel complementary output polarity 
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+    \param[in]  timer_ocnpolarity: channel complementary output polarity 
+      \arg        TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high
+      \arg        TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_complementary_output_polarity_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocnpolarity)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocnpolarity;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocnpolarity << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocnpolarity << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel enable state
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_state: TIMER channel enable state
+      \arg        TIMER_CCX_ENABLE: channel enable 
+      \arg        TIMER_CCX_DISABLE: channel disable 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_state_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_state)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_state;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_state << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_state << 8U);
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_state << 12U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel complementary output enable state
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0
+      \arg        TIMER_CH_1: TIMER channel1
+      \arg        TIMER_CH_2: TIMER channel2
+    \param[in]  timer_ocnstate: TIMER channel complementary output enable state
+      \arg        TIMER_CCXN_ENABLE: channel complementary enable 
+      \arg        TIMER_CCXN_DISABLE: channel complementary disable 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_complementary_output_state_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocnstate)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_ocnstate;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocnstate << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocnstate << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER input capture parameter 
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+     \param[in]  timer_icpara: TIMER channel intput parameter struct
+                 icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_BOTH_EDGE
+                 icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI,TIMER_IC_SELECTION_ITS
+                 icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8
+                 icfilter: 0~15
+    \param[out]  none
+    \retval      none
+*/
+void timer_input_capture_config(uint32_t timer_periph,uint16_t timer_channel,timer_ic_parameter_struct* timer_icpara)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_icpara->icpolarity);
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)(timer_icpara->icselection);
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter) << 4U);
+
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+        break;
+    
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+
+        /* reset the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icpolarity)<< 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icselection)<< 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter)<< 12U);
+
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        /* reset the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN);
+
+        /* reset the CH2P and CH2NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icpolarity)<< 8U);
+
+        /* reset the CH2MS bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icselection));
+
+        /* reset the CH2CAPFLT bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter)<< 4U);
+
+        /* set the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        /* reset the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN);
+
+        /* reset the CH3P bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icpolarity)<< 12U);
+
+        /* reset the CH3MS bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icselection)<< 8U);
+
+        /* reset the CH3CAPFLT bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter)<< 12U);
+
+        /* set the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN;
+        break;
+    default:
+        break;
+    }
+    /* configure TIMER channel input capture prescaler value */
+    timer_channel_input_capture_prescaler_config(timer_periph,timer_channel,(uint16_t)(timer_icpara->icprescaler));
+}
+
+/*!
+    \brief      configure TIMER channel input capture prescaler value
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[in]  timer_prescaler: channel input capture prescaler value
+      \arg        TIMER_IC_PSC_DIV1: no prescaler
+      \arg        TIMER_IC_PSC_DIV2: divided by 2
+      \arg        TIMER_IC_PSC_DIV4: divided by 4
+      \arg        TIMER_IC_PSC_DIV8: divided by 8
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_input_capture_prescaler_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_prescaler)
+{
+    switch(timer_channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_prescaler;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC);
+        TIMER_CHCTL0(timer_periph) |= ((uint32_t)timer_prescaler << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_prescaler;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC);
+        TIMER_CHCTL1(timer_periph) |= ((uint32_t)timer_prescaler << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      read TIMER channel capture compare register value
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7))
+    \param[out] none
+    \retval     channel capture compare register value
+*/
+uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph,uint16_t timer_channel)
+{
+    uint32_t count_value = 0U;
+
+    switch(timer_channel){
+    case TIMER_CH_0:
+        count_value = TIMER_CH0CV(timer_periph);
+        break;
+    case TIMER_CH_1:
+        count_value = TIMER_CH1CV(timer_periph);
+        break;
+    case TIMER_CH_2:
+        count_value = TIMER_CH2CV(timer_periph);
+        break;
+    case TIMER_CH_3:
+        count_value = TIMER_CH3CV(timer_periph);
+        break;
+    default:
+        break;
+    }
+    return (count_value);
+}
+
+/*!
+    \brief      configure TIMER input pwm capture function 
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_channel: 
+      \arg        TIMER_CH_0: TIMER channel0
+      \arg        TIMER_CH_1: TIMER channel1
+     \param[in]  timer_icpwm:TIMER channel intput pwm parameter struct
+                 icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING
+                 icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI
+                 icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8
+                 icfilter: 0~15
+    \param[out] none
+    \retval     none
+*/
+void timer_input_pwm_capture_config(uint32_t timer_periph,uint16_t timer_channel,timer_ic_parameter_struct* timer_icpwm)
+{
+    uint16_t icpolarity  = 0x0U;
+    uint16_t icselection = 0x0U;
+
+    if(TIMER_IC_POLARITY_RISING == timer_icpwm->icpolarity){
+        icpolarity = TIMER_IC_POLARITY_FALLING;
+    }else{
+        icpolarity = TIMER_IC_POLARITY_RISING;
+    }
+
+    if(TIMER_IC_SELECTION_DIRECTTI == timer_icpwm->icselection){
+        icselection = TIMER_IC_SELECTION_INDIRECTTI;
+    }else{
+        icselection = TIMER_IC_SELECTION_DIRECTTI;
+    }
+
+    if(TIMER_CH_0 == timer_channel){
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+        /* set the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_icpwm->icpolarity);
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        /* set the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)(timer_icpwm->icselection);
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        /* set the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= ((uint32_t)(timer_icpwm->icfilter) << 4U);
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(timer_icpwm->icprescaler));
+
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* reset the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+        /* set the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity<< 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        /* set the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection<< 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        /* set the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icfilter)<< 12U);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(timer_icpwm->icprescaler));
+    }else{
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* reset the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+        /* set the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icpolarity)<< 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        /* set the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icselection)<< 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        /* set the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icfilter)<< 12U);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(timer_icpwm->icprescaler));
+
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+        /* set the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity;
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        /* set the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection;
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        /* set the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= ((uint32_t)(timer_icpwm->icfilter) << 4U);
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(timer_icpwm->icprescaler));
+    }
+}
+
+/*!
+    \brief      configure TIMER hall sensor mode
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[in]  timer_hallmode: 
+      \arg        TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable
+      \arg        TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable
+    \param[out] none
+    \retval     none
+*/
+void timer_hall_mode_config(uint32_t timer_periph,uint8_t timer_hallmode)
+{
+    if(TIMER_HALLINTERFACE_ENABLE == timer_hallmode){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S;
+    }else if(TIMER_HALLINTERFACE_DISABLE == timer_hallmode){
+        TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S;
+    }else{
+    }
+}
+
+/*!
+    \brief      select TIMER input trigger source 
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_intrigger: 
+      \arg        TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0
+      \arg        TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1
+      \arg        TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2
+      \arg        TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3
+      \arg        TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 Edge Detector
+      \arg        TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0
+      \arg        TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1
+      \arg        TIMER_SMCFG_TRGSEL_ETIFP: external trigger
+    \param[out] none
+    \retval     none
+*/
+void timer_input_trigger_source_select(uint32_t timer_periph,uint32_t timer_intrigger)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS);
+    TIMER_SMCFG(timer_periph) |= (uint32_t)timer_intrigger;
+}
+
+/*!
+    \brief      select TIMER master mode output trigger source 
+    \param[in]  timer_periph: TIMERx(x=0..7)
+    \param[in]  timer_outrigger: 
+      \arg        TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output
+      \arg        TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output
+      \arg        TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output
+      \arg        TIMER_TRI_OUT_SRC_CC0: a capture or a compare match occurred in channal0 as trigger output TRGO
+      \arg        TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output
+      \arg        TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output
+      \arg        TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output
+      \arg        TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output
+    \param[out] none
+    \retval     none
+*/
+void timer_master_output_trigger_source_select(uint32_t timer_periph,uint32_t timer_outrigger)
+{
+    TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC);
+    TIMER_CTL1(timer_periph) |= (uint32_t)timer_outrigger;
+}
+
+/*!
+    \brief      select TIMER slave mode 
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_slavemode: 
+      \arg        TIMER_SLAVE_MODE_DISABLE: slave mode disable
+      \arg        TIMER_ENCODER_MODE0: encoder mode 0
+      \arg        TIMER_ENCODER_MODE1: encoder mode 1
+      \arg        TIMER_ENCODER_MODE2: encoder mode 2
+      \arg        TIMER_SLAVE_MODE_RESTART: restart mode
+      \arg        TIMER_SLAVE_MODE_PAUSE: pause mode
+      \arg        TIMER_SLAVE_MODE_EVENT: event mode
+      \arg        TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0.
+    \param[out] none
+    \retval     none
+*/
+
+void timer_slave_mode_select(uint32_t timer_periph,uint32_t timer_slavemode)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+
+    TIMER_SMCFG(timer_periph) |= (uint32_t)timer_slavemode;
+}
+
+/*!
+    \brief      configure TIMER master slave mode 
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_masterslave: 
+      \arg        TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable
+      \arg        TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable
+    \param[out] none
+    \retval     none
+*/ 
+void timer_master_slave_mode_config(uint32_t timer_periph,uint8_t timer_masterslave)
+{
+    if(TIMER_MASTER_SLAVE_MODE_ENABLE == timer_masterslave){
+        TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM;
+    }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == timer_masterslave){
+        TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM;
+    }else{
+    }
+}
+
+/*!
+    \brief      configure TIMER external trigger input
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[in]  timer_extprescaler: 
+      \arg        TIMER_EXT_TRI_PSC_OFF: no divided
+      \arg        TIMER_EXT_TRI_PSC_DIV2: divided by 2
+      \arg        TIMER_EXT_TRI_PSC_DIV4: divided by 4
+      \arg        TIMER_EXT_TRI_PSC_DIV8: divided by 8
+    \param[in]  timer_expolarity: 
+      \arg        TIMER_ETP_FALLING: active low or falling edge active
+      \arg        TIMER_ETP_RISING: active high or rising edge active
+    \param[in]  timer_extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_trigger_config(uint32_t timer_periph,uint32_t timer_extprescaler,
+                                   uint32_t timer_expolarity,uint32_t timer_extfilter)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP|TIMER_SMCFG_ETPSC|TIMER_SMCFG_ETFC));
+    TIMER_SMCFG(timer_periph) |= (uint32_t)(timer_extprescaler|timer_expolarity);
+    TIMER_SMCFG(timer_periph) |= (uint32_t)(timer_extfilter<< 8U);
+}
+
+/*!
+    \brief      configure TIMER quadrature decoder mode
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_decomode: 
+      \arg        TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level
+      \arg        TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level
+      \arg        TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input
+    \param[in]  timer_ic0polarity: 
+      \arg        TIMER_IC_POLARITY_RISING: capture rising edge
+      \arg        TIMER_IC_POLARITY_FALLING: capture falling edge
+    \param[in]  timer_ic1polarity: 
+      \arg        TIMER_IC_POLARITY_RISING: capture rising edge
+      \arg        TIMER_IC_POLARITY_FALLING: capture falling edge
+    \param[out] none
+    \retval     none
+*/
+void timer_quadrature_decoder_mode_config(uint32_t timer_periph,uint32_t timer_decomode,
+                                   uint16_t timer_ic0polarity,uint16_t timer_ic1polarity)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+    TIMER_SMCFG(timer_periph) |= (uint32_t)timer_decomode;
+
+    TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS))&((~(uint32_t)TIMER_CHCTL0_CH1MS)));
+    TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI<< 8U));
+
+    TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+    TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+    TIMER_CHCTL2(timer_periph) |= ((uint32_t)timer_ic0polarity|((uint32_t)timer_ic1polarity<< 4U));
+}
+
+/*!
+    \brief      configure TIMER internal clock mode
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[out] none
+    \retval     none
+*/
+void timer_internal_clock_config(uint32_t timer_periph)
+{
+    TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC;
+}
+
+/*!
+    \brief      configure TIMER the internal trigger as external clock input
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_intrigger: 
+      \arg        TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0
+      \arg        TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1
+      \arg        TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2
+      \arg        TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3
+    \param[out] none
+    \retval     none
+*/
+void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t timer_intrigger)
+{
+    timer_input_trigger_source_select(timer_periph,timer_intrigger);
+    TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC;
+    TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0;
+}
+
+/*!
+    \brief      configure TIMER the external trigger as external clock input
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_extrigger: 
+      \arg        TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 Edge Detector
+      \arg        TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0
+      \arg        TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1
+    \param[in]  timer_expolarity: 
+      \arg        TIMER_IC_POLARITY_RISING: active low or falling edge active
+      \arg        TIMER_IC_POLARITY_FALLING: active high or rising edge active
+    \param[in]  timer_extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_trigger_as_external_clock_config(uint32_t timer_periph,uint32_t timer_extrigger,
+                                       uint16_t timer_expolarity,uint32_t timer_extfilter)
+{
+    if(TIMER_SMCFG_TRGSEL_CI1FE1 == timer_extrigger){
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* reset the CH1NP bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+        /* set the CH1NP bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_expolarity << 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        /* set the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI<< 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        /* set the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)(timer_extfilter<< 8U);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+    }else{
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+        /* set the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_expolarity;
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        /* set the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI;
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_extfilter;
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+    }
+    /* select TIMER input trigger source */
+    timer_input_trigger_source_select(timer_periph,timer_extrigger);
+    /* reset the SMC bit */
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+    /* set the SMC bit */
+    TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0;
+}
+
+/*!
+    \brief      configure TIMER the external clock mode0
+    \param[in]  timer_periph: TIMERx(x=0..4,7,8,11)
+    \param[in]  timer_extprescaler: 
+      \arg        TIMER_EXT_TRI_PSC_OFF: no divided
+      \arg        TIMER_EXT_TRI_PSC_DIV2: divided by 2
+      \arg        TIMER_EXT_TRI_PSC_DIV4: divided by 4
+      \arg        TIMER_EXT_TRI_PSC_DIV8: divided by 8
+    \param[in]  timer_expolarity: 
+      \arg        TIMER_ETP_FALLING: active low or falling edge active
+      \arg        TIMER_ETP_RISING: active high or rising edge active
+    \param[in]  timer_extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_clock_mode0_config(uint32_t timer_periph,uint32_t timer_extprescaler,
+                                       uint32_t timer_expolarity,uint32_t timer_extfilter)
+{
+    /* configure TIMER external trigger input */
+    timer_external_trigger_config(timer_periph,timer_extprescaler,timer_expolarity,timer_extfilter);
+
+    /* reset the SMC bit,TRGS bit */
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS));
+    /* set the SMC bit,TRGS bit */
+    TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP);
+}
+
+/*!
+    \brief      configure TIMER the external clock mode1
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[in]  timer_extprescaler: 
+      \arg        TIMER_EXT_TRI_PSC_OFF: no divided
+      \arg        TIMER_EXT_TRI_PSC_DIV2: divided by 2
+      \arg        TIMER_EXT_TRI_PSC_DIV4: divided by 4
+      \arg        TIMER_EXT_TRI_PSC_DIV8: divided by 8
+    \param[in]  timer_expolarity: 
+      \arg        TIMER_ETP_FALLING: active low or falling edge active
+      \arg        TIMER_ETP_RISING: active high or rising edge active
+    \param[in]  timer_extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_clock_mode1_config(uint32_t timer_periph,uint32_t timer_extprescaler,
+                                       uint32_t timer_expolarity,uint32_t timer_extfilter)
+{
+    /* configure TIMER external trigger input */
+    timer_external_trigger_config(timer_periph,timer_extprescaler,timer_expolarity,timer_extfilter);
+
+    TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1;
+}
+
+/*!
+    \brief      disable TIMER the external clock mode1
+    \param[in]  timer_periph: TIMERx(x=0..4,7)
+    \param[out] none
+    \retval     none
+*/
+void timer_external_clock_mode1_disable(uint32_t timer_periph)
+{
+    TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1;
+}
+
+/*!
+    \brief      configure TIMER1 channel0 remap function
+    \param[in]  timer_periph: TIMERx(x=1,4,10)
+    \param[in]  timer_remap: 
+      \arg        TIMER1_ITI1_RMP_TIMER7_TRGO: timer1 internal trigger input1 remap to TIMER7_TRGO
+      \arg        TIMER1_ITI1_RMP_ETHERNET_PTP: timer1 internal trigger input1 remap to ethernet PTP
+      \arg        TIMER1_ITI1_RMP_USB_FS_SOF: timer1 internal trigger input1 remap to USB FS SOF
+      \arg        TIMER1_ITI1_RMP_USB_HS_SOF: timer1 internal trigger input1 remap to USB HS SOF
+      \arg        TIMER4_CI3_RMP_GPIO: timer4 channel 3 input remap to GPIO pin
+      \arg        TIMER4_CI3_RMP_IRC32K: timer4 channel 3 input remap to IRC32K
+      \arg        TIMER4_CI3_RMP_LXTAL: timer4 channel 3 input remap to  LXTAL
+      \arg        TIMER4_CI3_RMP_RTC_WAKEUP_INT: timer4 channel 3 input remap to RTC wakeup interrupt 
+      \arg        TIMER10_ITI1_RMP_GPIO: timer10 internal trigger input1 remap based on GPIO setting
+      \arg        TIMER10_ITI1_RMP_RTC_HXTAL_DIV: timer10 internal trigger input1 remap  HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register)
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_remap_config(uint32_t timer_periph,uint32_t timer_remap)
+{
+    TIMER_IRMP(timer_periph) = (uint32_t)timer_remap;
+}
+
+/*!
+    \brief      configure TIMER write CHxVAL register selection
+    \param[in]  timer_periph: TIMERx(x=0,1,2,13,14,15,16)
+    \param[in]  timer_ccsel: 
+      \arg        TIMER_CCSEL_DISABLE: no effect
+      \arg        TIMER_CCSEL_ENABLE:  if write the CHxVAL register, the write value is same as the CHxVAL value, the write access ignored
+    \param[out] none
+    \retval     none
+*/
+void timer_write_cc_register_config(uint32_t timer_periph, uint16_t timer_ccsel)
+{
+    if(TIMER_CCSEL_ENABLE == timer_ccsel){
+        TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL;
+    }else if(TIMER_CCSEL_DISABLE == timer_ccsel){
+        TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL;
+    }else{
+    }
+}
+
+/*!
+    \brief      configure TIMER output value selection
+    \param[in]  timer_periph: TIMERx(x=0,7)
+    \param[in]  timer_outsel: 
+      \arg        TIMER_OUTSEL_DISABLE: no effect
+      \arg        TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled
+    \param[out] none
+    \retval     none
+*/
+void timer_output_value_selection_config(uint32_t timer_periph, uint16_t timer_outsel)
+{
+    if(TIMER_OUTSEL_ENABLE == timer_outsel){
+        TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL;
+    }else if(TIMER_OUTSEL_DISABLE == timer_outsel){
+        TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL;
+    }else{
+    }
+}

+ 443 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c

@@ -0,0 +1,443 @@
+/*!
+    \file  gd32f4xx_tli.c
+    \brief TLI driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_tli.h"
+
+/*!
+    \brief      deinitialize TLI registers 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void tli_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_TLIRST);
+    rcu_periph_reset_disable(RCU_TLIRST);
+}
+
+/*!
+    \brief      initialize TLI display timing parameters 
+    \param[in]  tli_struct: the data needed to initialize tli.
+                  synpsz_vpsz: size of the vertical synchronous pulse
+                  synpsz_hpsz: size of the horizontal synchronous pulse
+                  backpsz_vbpsz: size of the vertical back porch plus synchronous pulse 
+                  backpsz_hbpsz: size of the horizontal back porch plus synchronous pulse
+                  activesz_vasz: size of the vertical active area width plus back porch and synchronous pulse
+                  activesz_hasz: size of the horizontal active area width plus back porch and synchronous pulse
+                  totalsz_vtsz: vertical total size of the display, including active area, back porch, synchronous 
+                  totalsz_htsz: vorizontal total size of the display, including active area, back porch, synchronous
+                  backcolor_red: background value red
+                  backcolor_green: background value green
+                  backcolor_blue: background value blue
+                  signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGHT
+                  signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGHT
+                  signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT
+                  signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI
+    \param[out] none
+    \retval     none
+*/
+void tli_init(tli_parameter_struct *tli_struct)
+{
+    /* synchronous pulse size configuration */
+    TLI_SPSZ &= ~(TLI_SPSZ_VPSZ|TLI_SPSZ_HPSZ);
+    TLI_SPSZ = (tli_struct->synpsz_vpsz|(tli_struct->synpsz_hpsz<<16U));
+    /* back-porch size configuration */
+    TLI_BPSZ &= ~(TLI_BPSZ_VBPSZ|TLI_BPSZ_HBPSZ);
+    TLI_BPSZ = (tli_struct->backpsz_vbpsz|(tli_struct->backpsz_hbpsz<<16U));
+    /* active size configuration */    
+    TLI_ASZ &= ~(TLI_ASZ_VASZ|TLI_ASZ_HASZ);
+    TLI_ASZ = (tli_struct->activesz_vasz|(tli_struct->activesz_hasz<<16U));
+    /* total size configuration */    
+    TLI_TSZ &= ~(TLI_TSZ_VTSZ|TLI_TSZ_HTSZ);
+    TLI_TSZ = (tli_struct->totalsz_vtsz|(tli_struct->totalsz_htsz<<16U));
+    /* background color configuration */    
+    TLI_BGC &= ~(TLI_BGC_BVB|(TLI_BGC_BVG)|(TLI_BGC_BVR));
+    TLI_BGC = (tli_struct->backcolor_blue|(tli_struct->backcolor_green<<8U)|(tli_struct->backcolor_red<<16U));    
+    TLI_CTL &= ~(TLI_CTL_HPPS|TLI_CTL_VPPS|TLI_CTL_DEPS|TLI_CTL_CLKPS);
+    TLI_CTL |= (tli_struct->signalpolarity_hs|tli_struct->signalpolarity_vs|\
+                tli_struct->signalpolarity_de|tli_struct->signalpolarity_pixelck);
+
+}
+
+/*!
+    \brief      dither function configure 
+    \param[in]  ditherstat: TLI_DITHER_ENABLE,TLI_DITHER_DISABLE
+    \param[out] none
+    \retval     none
+*/
+void tli_dither_config(uint8_t ditherstat)
+{
+    if(TLI_DITHER_ENABLE == ditherstat){
+        TLI_CTL |= TLI_CTL_DFEN;
+    }else{
+        TLI_CTL &= ~(TLI_CTL_DFEN);
+    }
+}
+
+/*!
+    \brief      TLI enable 
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void tli_enable(void)
+{
+    TLI_CTL |= TLI_CTL_TLIEN;
+}
+
+/*!
+    \brief      TLI disable 
+    \param[in]  none.
+    \param[out] none
+    \retval     none
+*/
+void tli_disable(void)
+{
+    TLI_CTL &= ~(TLI_CTL_DFEN);
+}
+
+/*!
+    \brief      TLI reload layer configure 
+    \param[in]  reloadmod: TLI_FRAME_BLANK_RELOAD_EN,TLI_REQUEST_RELOAD_EN
+    \param[out] none
+    \retval     none
+*/
+void tli_reload_config(uint8_t reloadmod)
+{
+    if(TLI_FRAME_BLANK_RELOAD_EN == reloadmod){
+        TLI_RL |= TLI_RL_FBR;
+    }else{
+        TLI_RL |= TLI_RL_RQR;
+    }
+}
+
+/*!
+    \brief      TLI interrupt enable 
+    \param[in]  inttype: TLI interrupt bits.
+      \arg        TLI_INTEN_LMIE: line mark interrupt 
+      \arg        TLI_INTEN_FEIE: FIFO error interrupt  
+      \arg        TLI_INTEN_TEIE: transaction error interrupt   
+      \arg        TLI_INTEN_LCRIE: layer configuration reloaded interrupt 
+    \param[out] none
+    \retval     none
+*/
+void tli_interrupt_enable(uint32_t inttype)
+{
+    TLI_INTEN |= (inttype);
+}
+
+/*!
+    \brief      TLI interrupt disable 
+    \param[in]  inttype: TLI interrupt bits.
+      \arg        TLI_INTEN_LMIE: line mark interrupt 
+      \arg        TLI_INTEN_FEIE: FIFO error interrupt  
+      \arg        TLI_INTEN_TEIE: transaction error interrupt   
+      \arg        TLI_INTEN_LCRIE: layer configuration reloaded interrupt 
+    \param[out] none
+    \retval     none
+*/
+void tli_interrupt_disable(uint32_t inttype)
+{
+    TLI_INTEN &= ~(inttype);
+}
+
+/*!
+    \brief      get TLI interrupt flag 
+    \param[in]  intflag: TLI interrupt flag bits.
+      \arg        TLI_INTF_LMF: line mark flag 
+      \arg        TLI_INTF_FEF: FIFO error flag  
+      \arg        TLI_INTF_TEF: transaction error flag   
+      \arg        TLI_INTF_LCRF: layer configuration reloaded flag 
+    \param[out] none
+    \retval     none
+*/
+FlagStatus tli_interrupt_flag_get(uint32_t intflag)
+{
+    uint32_t state;
+    state = TLI_INTF;
+    if(state & intflag){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear TLI interrupt flag 
+    \param[in]  intflag: TLI interrupt flag bits.
+      \arg        TLI_INTC_LMC: line mark flag 
+      \arg        TLI_INTC_FEC: FIFO error flag  
+      \arg        TLI_INTC_TEC: transaction error flag   
+      \arg        TLI_INTC_LCRC: layer configuration reloaded flag 
+    \param[out] none
+    \retval     none
+*/
+void tli_interrupt_flag_clear(uint32_t intflag)
+{
+    TLI_INTC |= (intflag);
+}
+
+/*!
+    \brief      set line mark value 
+    \param[in]  linenum: line number. 
+    \param[out] none
+    \retval     none
+*/
+void tli_line_mark_set(uint32_t linenum)
+{
+    TLI_LM &= ~(TLI_LM_LM);
+    TLI_LM = linenum;
+}
+
+/*!
+    \brief      get current displayed position 
+    \param[in]  none 
+    \param[out] none
+    \retval     none
+*/
+uint32_t tli_current_pos_get(void)
+{
+    return TLI_CPPOS;
+}
+
+
+/*!
+    \brief      get TLI state 
+    \param[in]  state: TLI state.
+      \arg        TLI_STAT_VDE: current VDE state 
+      \arg        TLI_STAT_HDE: current HDE state
+      \arg        TLI_STAT_VS: current vs state
+      \arg        TLI_STAT_HS: current hs state 
+    \param[out] none
+    \retval     none
+*/
+FlagStatus tli_flag_get(uint32_t state)
+{
+    uint32_t stat;
+    stat = TLI_STAT;
+    if(state & stat){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      TLI layer enable 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[out] none
+    \retval     none
+*/
+void tli_layer_enable(uint32_t layerx)
+{
+    TLI_LxCTL(layerx) |= TLI_LxCTL_LEN;
+}
+
+/*!
+    \brief      TLI layer disable 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[out] none
+    \retval     none
+*/
+void tli_layer_disable(uint32_t layerx)
+{
+    TLI_LxCTL(layerx) &= ~(TLI_LxCTL_LEN);
+}
+
+/*!
+    \brief      TLI layer color keying enable 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[out] none
+    \retval     none
+*/
+void tli_color_key_enable(uint32_t layerx)
+{
+    TLI_LxCTL(layerx) |= TLI_LxCTL_CKEYEN;
+}
+
+/*!
+    \brief      TLI layer color keying disable 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[out] none
+    \retval     none
+*/
+void tli_color_key_disable(uint32_t layerx)
+{
+    TLI_LxCTL(layerx) &= ~(TLI_LxCTL_CKEYEN);
+}
+
+/*!
+    \brief      TLI layer LUT enable 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[out] none
+    \retval     none
+*/
+void tli_lut_enable(uint32_t layerx)
+{
+    TLI_LxCTL(layerx) |= TLI_LxCTL_LUTEN;
+}
+
+/*!
+    \brief      TLI layer LUT disable 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[out] none
+    \retval     none
+*/
+void tli_lut_disable(uint32_t layerx)
+{
+    TLI_LxCTL(layerx) &= ~(TLI_LxCTL_LUTEN);
+}
+
+/*!
+    \brief      TLI layer initialize 
+    \param[in]  layerx: LAYERx(x=0,1)
+    \param[in]  layer_struct: TLI Layer parameter struct
+                  layer_window_rightpos: window right position
+                  layer_window_leftpos: window left position
+                  layer_window_bottompos: window bottom position 
+                  layer_window_toppos: window top position
+                  layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565,
+                                 LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8,
+                                 LAYER_PPF_AL44,LAYER_PPF_AL88
+                  layer_sa: specified alpha
+                  layer_default_alpha: the default color alpha
+                  layer_default_red: the default color red
+                  layer_default_green: the default color green
+                  layer_default_blue: the default color blue
+                  layer_acf1: LAYER_ACF1_SA,LAYER_ACF1_PASA
+                  layer_acf2: LAYER_ACF2_SA,LAYER_ACF2_PASA
+                  layer_frame_bufaddr: frame buffer base address
+                  layer_frame_buf_stride_offset: frame buffer stride offset
+                  layer_frame_line_length: frame line length
+                  layer_frame_total_line_number: frame total line number
+    \param[out] none
+    \retval     none
+*/
+void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct)
+{
+    /* configure layer window horizontal position */
+    TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP|(TLI_LxHPOS_WRP));
+    TLI_LxHPOS(layerx) = (layer_struct->layer_window_leftpos | (layer_struct->layer_window_rightpos<<16U));
+    /* configure layer window vertical position */
+    TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP|(TLI_LxVPOS_WBP));
+    TLI_LxVPOS(layerx) = (layer_struct->layer_window_toppos |(layer_struct->layer_window_bottompos<<16U));
+    /* configure layer packeted pixel format */
+    TLI_LxPPF(layerx) &= ~(TLI_LxPPF_PPF);
+    TLI_LxPPF(layerx) = layer_struct->layer_ppf;
+    /* configure layer specified alpha */
+    TLI_LxSA(layerx) &= ~(TLI_LxSA_SA);
+    TLI_LxSA(layerx) = layer_struct->layer_sa;
+    /* configure layer default color */
+    TLI_LxDC(layerx) &= ~(TLI_LxDC_DCB|(TLI_LxDC_DCG)|(TLI_LxDC_DCR)|(TLI_LxDC_DCA));
+    TLI_LxDC(layerx) = (layer_struct->layer_default_blue |(layer_struct->layer_default_green<<8U)
+                                                               |(layer_struct->layer_default_red<<16U)
+                                                               |(layer_struct->layer_default_alpha<<24U));
+
+    /* configure layer alpha calculation factors */
+    TLI_LxBLEND(layerx) &= ~(TLI_LxBLEND_ACF2|(TLI_LxBLEND_ACF1));
+    TLI_LxBLEND(layerx) = ((layer_struct->layer_acf2)|(layer_struct->layer_acf1));
+    /* configure layer frame buffer base address */
+    TLI_LxFBADDR(layerx) &= ~(TLI_LxFBADDR_FBADD);
+    TLI_LxFBADDR(layerx) = (layer_struct->layer_frame_bufaddr);
+    /* configure layer frame line length */
+    TLI_LxFLLEN(layerx) &= ~(TLI_LxFLLEN_FLL|(TLI_LxFLLEN_STDOFF));
+    TLI_LxFLLEN(layerx) = (layer_struct->layer_frame_line_length|(layer_struct->layer_frame_buf_stride_offset<<16U));
+    /* configure layer frame buffer base address */
+    TLI_LxFBADDR(layerx) &= ~(TLI_LxFBADDR_FBADD);
+    TLI_LxFBADDR(layerx) = (layer_struct->layer_frame_bufaddr);
+    /* configure layer frame total line number */
+    TLI_LxFTLN(layerx) &= ~(TLI_LxFTLN_FTLN); 
+    TLI_LxFTLN(layerx) = (layer_struct->layer_frame_total_line_number);
+
+}
+
+/*!
+    \brief      reconfigure window position 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[in]  offset_x: new horizontal offset .
+    \param[in]  offset_y: new vertical offset.
+    \param[out] none
+    \retval     none
+*/
+void tli_layer_window_offset_modify(uint32_t layerx,uint32_t offset_x,uint32_t offset_y)
+{
+    /* configure window start position */
+    uint32_t layer_ppf,line_length,line_num,hstart,vstart;
+    TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP|(TLI_LxHPOS_WRP));
+    TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP|(TLI_LxVPOS_WBP));
+    hstart = offset_x+(((TLI_BPSZ & TLI_BPSZ_HBPSZ)>>16U)+1U);
+    vstart = offset_y+((TLI_BPSZ & TLI_BPSZ_VBPSZ)+1U);
+    line_num = (TLI_LxFTLN(layerx) & TLI_LxFTLN_FTLN);
+    layer_ppf = (TLI_LxPPF(layerx) & TLI_LxPPF_PPF);
+    /* the bytes of a line equal TLI_LxFLLEN_FLL bits value minus 3 */
+    switch(layer_ppf){
+    case LAYER_PPF_ARGB8888:
+        /* each pixel includes 4bytes,when pixel format is ARGB8888 */
+        line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/4U);
+        break;
+    case LAYER_PPF_RGB888:
+        /* each pixel includes 3bytes,when pixel format is RGB888 */
+        line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/3U);
+        break;
+    case LAYER_PPF_RGB565:
+    case LAYER_PPF_ARGB1555:
+    case LAYER_PPF_ARGB4444:
+    case LAYER_PPF_AL88:
+        /* each pixel includes 2bytes,when pixel format is RGB565,ARG1555,ARGB4444 or AL88 */
+        line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/2U);
+        break;
+    case LAYER_PPF_L8:
+    case LAYER_PPF_AL44:
+        /* each pixel includes 1byte,when pixel format is L8 or AL44 */
+        line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U));
+        break;
+    default:
+        break;
+    }
+    /* reconfigure window position */
+    TLI_LxHPOS(layerx) = (hstart|((hstart+line_length-1U)<<16U));
+    TLI_LxVPOS(layerx) = (vstart|((vstart+line_num-1U)<<16U));
+    
+    
+}
+
+/*!
+    \brief      TLI layer lut initialize 
+    \param[in]  layerx: LAYERx(x=0,1)
+    \param[in]  lut_struct: TLI layer LUT parameter struct
+                  layer_table_addr: window right position
+                  layer_lut_channel_red: window left position
+                  layer_window_bottompos: window bottom position 
+                  layer_window_toppos: window top position
+    \param[out] none
+    \retval     none
+*/
+void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct)
+{
+    TLI_LxLUT(layerx) &= ~(TLI_LxLUT_TB|TLI_LxLUT_TG|TLI_LxLUT_TR|TLI_LxLUT_TADD);
+    TLI_LxLUT(layerx) = ((lut_struct->layer_lut_channel_blue)|(lut_struct->layer_lut_channel_green<<8)
+                                                                   |(lut_struct->layer_lut_channel_red<<16
+                                                                   |(lut_struct->layer_table_addr<<24)));
+}
+
+/*!
+    \brief      TLI layer key initialize 
+    \param[in]  layerx: LAYERx(x=0,1).
+    \param[in]  redkey: color key red.
+    \param[in]  greenkey: color key green 
+    \param[in]  bluekey: color key blue.
+    \param[out] none
+    \retval     none
+*/
+void tli_ckey_init(uint32_t layerx,uint32_t redkey,uint32_t greenkey,uint32_t bluekey)
+{
+    TLI_LxCKEY(layerx) = ((bluekey)|(greenkey<<8U)|(redkey<<16U));
+}

+ 144 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c

@@ -0,0 +1,144 @@
+/*!
+    \file  gd32f4xx_trng.c
+    \brief TRNG driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_trng.h"
+
+/*!
+    \brief      deinitialize the TRNG
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void trng_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_TRNGRST);
+    rcu_periph_reset_disable(RCU_TRNGRST);
+}
+
+/*!
+    \brief      enable the TRNG interface
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void trng_enable(void)
+{
+    TRNG_CTL |= TRNG_CTL_TRNGEN;
+}
+
+/*!
+    \brief      disable the TRNG interface
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void trng_disable(void)
+{
+    TRNG_CTL &= ~TRNG_CTL_TRNGEN;
+}
+
+/*!
+    \brief      get the true random data
+    \param[in]  none
+    \param[out] none
+    \retval     the generated random data
+*/
+uint32_t trng_get_true_random_data(void)
+{
+    return (TRNG_DATA);
+}
+
+/*!
+    \brief      get the trng status flags
+    \param[in]  flag: trng status flag, refer to trng_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        TRNG_FLAG_DRDY: Random Data ready status
+      \arg        TRNG_FLAG_CECS: Clock error current status
+      \arg        TRNG_FLAG_SECS: Seed error current status
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus trng_flag_get(trng_flag_enum flag)
+{
+    if(RESET != (TRNG_STAT & flag)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the trng status flags
+    \param[in]  flag: the special status flag
+                only one parameter can be selected which is shown as below:
+      \arg        TRNG_FLAG_CECS: Clock error current status
+      \arg        TRNG_FLAG_SECS: Seed error current status
+    \param[out] none
+    \retval     none
+*/
+void trng_flag_clear(trng_flag_enum flag)
+{
+    TRNG_STAT &= ~(uint32_t)flag;
+}
+
+/*!
+    \brief      enable the TRNG interrupt
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void trng_interrupt_enable(void) 
+{
+    TRNG_CTL |= TRNG_CTL_IE;
+}
+
+/*!
+    \brief      disable the TRNG interrupt
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void trng_interrupt_disable(void)
+{
+    TRNG_CTL &= ~TRNG_CTL_IE;
+}
+
+/*!
+    \brief      get the trng interrupt flags
+    \param[in]  int_flag: trng interrupt flag, refer to trng_int_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        TRNG_INT_FLAG_CEIF: clock error interrupt flag
+      \arg        TRNG_INT_FLAG_SEIF: Seed error interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag)
+{
+    if(RESET != (TRNG_STAT & int_flag)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the trng interrupt flags
+    \param[in]  int_flag: trng interrupt flag, refer to trng_int_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        TRNG_INT_FLAG_CEIF: clock error interrupt flag
+      \arg        TRNG_INT_FLAG_SEIF: Seed error interrupt flag
+    \param[out] none
+    \retval     none
+*/
+void trng_interrupt_flag_clear(trng_int_flag_enum int_flag)
+{
+    TRNG_STAT &= ~(uint32_t)int_flag;
+}

+ 952 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c

@@ -0,0 +1,952 @@
+/*!
+    \file  gd32f4xx_usart.c
+    \brief USART driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_usart.h"
+
+/*!
+    \brief      reset USART/UART 
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_deinit(uint32_t usart_periph)
+{
+    switch(usart_periph){
+    case USART0:
+        rcu_periph_reset_enable(RCU_USART0RST);
+        rcu_periph_reset_disable(RCU_USART0RST);
+        break;
+    case USART1:
+        rcu_periph_reset_enable(RCU_USART1RST);
+        rcu_periph_reset_disable(RCU_USART1RST);
+        break;
+    case USART2:
+        rcu_periph_reset_enable(RCU_USART2RST);
+        rcu_periph_reset_disable(RCU_USART2RST);
+        break;
+    case USART5:
+        rcu_periph_reset_enable(RCU_USART5RST);
+        rcu_periph_reset_disable(RCU_USART5RST);
+        break;
+    case UART3:
+        rcu_periph_reset_enable(RCU_UART3RST);
+        rcu_periph_reset_disable(RCU_UART3RST);
+        break;
+    case UART4:
+        rcu_periph_reset_enable(RCU_UART4RST);
+        rcu_periph_reset_disable(RCU_UART4RST);
+        break;
+    case UART6:
+        rcu_periph_reset_enable(RCU_UART6RST);
+        rcu_periph_reset_disable(RCU_UART6RST);
+        break;
+    case UART7:
+        rcu_periph_reset_enable(RCU_UART7RST);
+        rcu_periph_reset_disable(RCU_UART7RST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure USART baud rate value
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  baudval: baud rate value
+    \param[out] none
+    \retval     none
+*/ 
+void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval)
+{
+    uint32_t uclk=0U, intdiv=0U, fradiv=0U, udiv=0U;
+    switch(usart_periph){
+         /* get clock frequency */
+    case USART0:
+         uclk=rcu_clock_freq_get(CK_APB2);
+         break;
+    case USART5:
+         uclk=rcu_clock_freq_get(CK_APB2);
+         break;
+    case USART1:
+         uclk=rcu_clock_freq_get(CK_APB1);
+         break;
+    case USART2:
+         uclk=rcu_clock_freq_get(CK_APB1);
+         break;
+    case UART3:
+         uclk=rcu_clock_freq_get(CK_APB1);
+         break;
+    case UART4:
+         uclk=rcu_clock_freq_get(CK_APB1);
+         break;
+    case UART6:
+         uclk=rcu_clock_freq_get(CK_APB1);
+         break;
+    case UART7:
+         uclk=rcu_clock_freq_get(CK_APB1);
+         break;
+    default:
+         break;
+    }
+    if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){
+        /* when oversampling by 8, configure the value of USART_BAUD */
+        udiv = ((2U*uclk) + baudval/2U)/baudval;
+        intdiv = udiv & 0xfff0U;
+        fradiv = udiv & 0x7U;
+        USART_BAUD(usart_periph) |= ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
+    }else{
+        /* when oversampling by 16, configure the value of USART_BAUD */
+        udiv = (uclk+baudval/2U)/baudval;
+        intdiv = udiv & 0xfff0U;
+        fradiv = udiv & 0xfU;
+        USART_BAUD(usart_periph) |= ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
+    }   
+}
+
+/*!
+    \brief     configure USART parity function
+    \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in] paritycfg: configure USART parity
+      \arg       USART_PM_NONE: no parity
+      \arg       USART_PM_ODD:  odd parity
+      \arg       USART_PM_EVEN: even parity 
+    \param[out] none
+    \retval     none
+*/
+void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg)
+{
+    /* clear USART_CTL0 PM,PCEN Bits */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN);
+     /* configure USART parity mode */
+    USART_CTL0(usart_periph) |= paritycfg ;
+}
+
+/*!
+    \brief     configure USART word length
+    \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in] wlen: USART word length configure
+      \arg       USART_WL_8BIT: 8 bits
+      \arg       USART_WL_9BIT: 9 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_word_length_set(uint32_t usart_periph, uint32_t wlen)
+{
+    /* clear USART_CTL0 WL bit */
+    USART_CTL0(usart_periph) &= ~USART_CTL0_WL;
+    /* configure USART word length */
+    USART_CTL0(usart_periph) |= wlen;
+}
+
+/*!
+    \brief     configure USART stop bit length
+    \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in] stblen: USART stop bit configure
+      \arg       USART_STB_1BIT:   1 bit
+      \arg       USART_STB_0_5BIT: 0.5 bit
+      \arg       USART_STB_2BIT:   2 bits
+      \arg       USART_STB_1_5BIT: 1.5 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen)
+{
+    /* clear USART_CTL1 STB bits */
+    USART_CTL1(usart_periph) &= ~USART_CTL1_STB; 
+    /* configure USART stop bits */
+    USART_CTL1(usart_periph) |= stblen;
+}
+/*!
+    \brief      enable USART
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_enable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) |= USART_CTL0_UEN;
+}
+
+/*!
+    \brief     disable USART
+    \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_disable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+}
+
+/*!
+    \brief      configure USART transmitter
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  rtconfig: enable or disable USART transmitter
+      \arg        USART_TRANSMIT_ENABLE: enable USART transmission
+      \arg        USART_TRANSMIT_DISABLE: enable USART transmission
+    \param[out] none
+    \retval     none
+*/
+void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig)
+{
+    uint32_t ctl = 0U;
+    
+    ctl = USART_CTL0(usart_periph);
+    ctl &= ~USART_CTL0_TEN;
+    ctl |= txconfig;
+    /* configure transfer mode */
+    USART_CTL0(usart_periph) = ctl;
+}
+
+/*!
+    \brief      configure USART receiver
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  rtconfig: enable or disable USART receiver
+      \arg        USART_RECEIVE_ENABLE: enable USART reception
+      \arg        USART_RECEIVE_DISABLE: disable USART reception
+    \param[out] none
+    \retval     none
+*/
+void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig)
+{
+    uint32_t ctl = 0U;
+    
+    ctl = USART_CTL0(usart_periph);
+    ctl &= ~USART_CTL0_REN;
+    ctl |= rxconfig;
+    /* configure transfer mode */
+    USART_CTL0(usart_periph) = ctl;
+}
+
+/*!
+    \brief      data is transmitted/received with the LSB/MSB first
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  msbf: LSB/MSB
+      \arg        USART_MSBF_LSB: LSB first
+      \arg        USART_MSBF_MSB: MSB first
+    \param[out] none
+    \retval     none
+*/
+void usart_data_first_config(uint32_t usart_periph, uint32_t msbf)
+{
+    USART_CTL3(usart_periph) &= ~(USART_CTL3_MSBF); 
+    USART_CTL3(usart_periph) |= msbf;
+}
+
+/*!
+    \brief      configure USART inversion
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  invertpara: refer to enum USART_INVERT_CONFIG
+      \arg        USART_DINV_ENABLE: data bit level inversion
+      \arg        USART_DINV_DISABLE: data bit level not inversion
+      \arg        USART_TXPIN_ENABLE: TX pin level inversion
+      \arg        USART_TXPIN_DISABLE: TX pin level not inversion
+      \arg        USART_RXPIN_ENABLE: RX pin level inversion
+      \arg        USART_RXPIN_DISABLE: RX pin level not inversion
+    \param[out] none
+    \retval     none
+*/
+void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara)
+{
+    /* inverted or not the specified siginal */ 
+    switch(invertpara){
+    case USART_DINV_ENABLE:
+        USART_CTL3(usart_periph) |= USART_CTL3_DINV;
+        break;
+    case USART_TXPIN_ENABLE:
+        USART_CTL3(usart_periph) |= USART_CTL3_TINV;
+        break;
+    case USART_RXPIN_ENABLE:
+        USART_CTL3(usart_periph) |= USART_CTL3_RINV;
+        break;
+    case USART_DINV_DISABLE:
+        USART_CTL3(usart_periph) &= ~(USART_CTL3_DINV);
+        break;
+    case USART_TXPIN_DISABLE:
+        USART_CTL3(usart_periph) &= ~(USART_CTL3_TINV);
+        break;
+    case USART_RXPIN_DISABLE:
+        USART_CTL3(usart_periph) &= ~(USART_CTL3_RINV);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure the USART oversample mode 
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  oversamp: oversample value
+      \arg        USART_OVSMOD_8: 8 bits
+      \arg        USART_OVSMOD_16: 16 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp)
+{
+    /*  clear OVSMOD bit */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD);
+    USART_CTL0(usart_periph) |= oversamp;
+}
+
+/*!
+    \brief      configure sample bit method
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  obsm: sample bit
+      \arg        USART_OSB_1bit: 1 bit
+      \arg        USART_OSB_3bit: 3 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm)
+{
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); 
+    USART_CTL2(usart_periph) |= obsm;
+}
+
+/*!
+    \brief      enable receiver timeout of USART
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_receiver_timeout_enable(uint32_t usart_periph)
+{
+    USART_CTL3(usart_periph) |= USART_CTL3_RTEN;
+}
+
+/*!
+    \brief      disable receiver timeout of USART
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_receiver_timeout_disable(uint32_t usart_periph)
+{
+    USART_CTL3(usart_periph) &= ~(USART_CTL3_RTEN);
+}
+
+/*!
+    \brief      set the receiver timeout threshold of USART
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  rtimeout: 0-0x00FFFFFF
+    \param[out] none
+    \retval     none
+*/
+void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout)
+{
+    USART_RT(usart_periph) &= ~(USART_RT_RT);
+    USART_RT(usart_periph) |= rtimeout;
+}
+
+/*!
+    \brief      USART transmit data function
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  data: data of transmission 
+    \param[out] none
+    \retval     none
+*/
+void usart_data_transmit(uint32_t usart_periph, uint32_t data)
+{
+    USART_DATA(usart_periph) = ((uint16_t)USART_DATA_DATA & data);
+}
+
+/*!
+    \brief      USART receive data function
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     data of received
+*/
+uint16_t usart_data_receive(uint32_t usart_periph)
+{
+    return (uint16_t)(USART_DATA(usart_periph) & (uint16_t)USART_DATA_DATA); 
+}
+
+/*!
+    \brief      configure the address of the USART in wake up by address match mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  addr: address of USART/UART
+    \param[out] none
+    \retval     none
+*/
+void usart_address_config(uint32_t usart_periph, uint8_t addr)
+{
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR);
+    USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & addr);
+}
+
+/*!
+    \brief      receiver in mute mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_mute_mode_enable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) |= USART_CTL0_RWU;
+}
+
+/*!
+    \brief      receiver in active mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_mute_mode_disable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_RWU);
+}
+
+/*!
+    \brief      configure wakeup method in mute mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  wmehtod: two method be used to enter or exit the mute mode
+      \arg        USART_WM_IDLE: idle line
+      \arg        USART_WM_ADDR: address mask
+    \param[out] none
+    \retval     none
+*/
+void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_WM);
+    USART_CTL0(usart_periph) |= wmehtod;
+}
+
+/*!
+    \brief      enable LIN mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_lin_mode_enable(uint32_t usart_periph)
+{   
+    USART_CTL1(usart_periph) |= USART_CTL1_LMEN;
+}
+
+/*!
+    \brief      disable LIN mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_lin_mode_disable(uint32_t usart_periph)
+{   
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN);
+}
+
+/*!
+    \brief      configure lin break frame length
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  lblen: lin break frame length
+      \arg        USART_LBLEN_10B: 10 bits
+      \arg        USART_LBLEN_11B: 11 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_lin_break_dection_length_config(uint32_t usart_periph, uint32_t lblen)
+{
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN);
+    USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen);
+}
+
+/*!
+    \brief      send break frame
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_send_break(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD;
+}
+
+/*!
+    \brief      enable half duplex mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_halfduplex_enable(uint32_t usart_periph)
+{   
+    USART_CTL2(usart_periph) |= USART_CTL2_HDEN;
+}
+
+/*!
+    \brief      disable half duplex mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_halfduplex_disable(uint32_t usart_periph)
+{  
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN);
+}
+
+/*!
+    \brief      enable CK pin in synchronous mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_synchronous_clock_enable(uint32_t usart_periph)
+{
+    USART_CTL1(usart_periph) |= USART_CTL1_CKEN;
+}
+
+/*!
+    \brief      disable CK pin in synchronous mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_synchronous_clock_disable(uint32_t usart_periph)
+{
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN);
+}
+
+/*!
+    \brief      configure USART synchronous mode parameters
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  clen: CK length
+      \arg        USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame 
+      \arg        USART_CLEN_EN:   there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame
+    \param[in]  cph: clock phase
+      \arg        USART_CPH_1CK: first clock transition is the first data capture edge 
+      \arg        USART_CPH_2CK: second clock transition is the first data capture edge
+    \param[in]  cpl: clock polarity 
+      \arg        USART_CPL_LOW:  steady low value on CK pin 
+      \arg        USART_CPL_HIGH: steady high value on CK pin
+    \param[out] none
+    \retval     none
+*/
+void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl)
+{
+    uint32_t ctl = 0U;
+    
+    /* read USART_CTL1 register */
+    ctl = USART_CTL1(usart_periph);
+    /* set CK length, CK phase, CK polarity */
+    ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl);
+
+    USART_CTL1(usart_periph) |= ctl;
+}
+
+/*!
+    \brief      configure guard time value in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  gaut: guard time value
+    \param[out] none
+    \retval     none
+*/
+void usart_guard_time_config(uint32_t usart_periph,uint32_t gaut)
+{
+    USART_GP(usart_periph) &= ~(USART_GP_GUAT);
+    USART_GP(usart_periph) |= (USART_GP_GUAT & ((gaut)<<8));
+}
+
+/*!
+    \brief      enable smartcard mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_enable(uint32_t usart_periph)
+{
+    USART_CTL2(usart_periph) |= USART_CTL2_SCEN;
+}
+
+/*!
+    \brief      disable smartcard mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_disable(uint32_t usart_periph)
+{
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN);
+}
+
+/*!
+    \brief      enable NACK in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_nack_enable(uint32_t usart_periph)
+{
+    USART_CTL2(usart_periph) |= USART_CTL2_NKEN;
+}
+
+/*!
+    \brief      disable NACK in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_nack_disable(uint32_t usart_periph)
+{
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN);
+}
+
+/*!
+    \brief      configure smartcard auto-retry number
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  scrtnum: smartcard auto-retry number
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum)
+{
+    USART_CTL3(usart_periph) &= ~(USART_CTL3_SCRTNUM);
+    USART_CTL3(usart_periph) |= (USART_CTL3_SCRTNUM & ((scrtnum)<<1));
+}
+
+/*!
+    \brief      configure block length in Smartcard T=1 reception
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  bl: block length
+    \param[out] none
+    \retval     none
+*/
+void usart_block_length_config(uint32_t usart_periph, uint32_t bl)
+{
+    USART_RT(usart_periph) &= ~(USART_RT_BL);
+    USART_RT(usart_periph) |= (USART_RT_BL & ((bl)<<24));
+}
+
+/*!
+    \brief      enable IrDA mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_irda_mode_enable(uint32_t usart_periph)
+{
+    USART_CTL2(usart_periph) |= USART_CTL2_IREN;
+}
+
+/*!
+    \brief      disable IrDA mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[out] none
+    \retval     none
+*/
+void usart_irda_mode_disable(uint32_t usart_periph)
+{
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN);
+}
+
+/*!
+    \brief      configure the peripheral clock prescaler in USART IrDA low-power mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  psc: 0-0x00FFFFFF
+    \param[out] none
+    \retval     none
+*/
+void usart_prescaler_config(uint32_t usart_periph, uint32_t psc)
+{
+    USART_GP(usart_periph) &= ~(USART_GP_PSC);
+    USART_GP(usart_periph) |= psc;
+}
+
+/*!
+    \brief      configure IrDA low-power
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  irlp: IrDA low-power or normal
+      \arg        USART_IRLP_LOW:    low-power
+      \arg        USART_IRLP_NORMAL: normal
+    \param[out] none
+    \retval     none
+*/
+void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp)
+{
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP);
+    USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp);
+}
+
+/*!
+    \brief      configure hardware flow control RTS
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  hardwareflow: enable or disable RTS
+      \arg        USART_RTS_ENABLE:  enable RTS
+      \arg        USART_RTS_DISABLE: disable RTS
+    \param[out] none
+    \retval     none
+*/
+void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig)
+{
+    uint32_t ctl = 0U;
+    
+    ctl = USART_CTL2(usart_periph);
+    ctl &= ~USART_CTL2_RTSEN;
+    ctl |= rtsconfig;
+    /* configure RTS */
+    USART_CTL2(usart_periph) = ctl;
+}
+
+/*!
+    \brief      configure hardware flow control CTS
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  hardwareflow: enable or disable CTS
+      \arg        USART_CTS_ENABLE:  enable CTS
+      \arg        USART_CTS_DISABLE: disable CTS
+    \param[out] none
+    \retval     none
+*/
+void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig)
+{
+    uint32_t ctl = 0U;
+    
+    ctl = USART_CTL2(usart_periph);
+    ctl &= ~USART_CTL2_CTSEN;
+    ctl |= ctsconfig;
+    /* configure CTS */
+    USART_CTL2(usart_periph) = ctl;
+}
+
+/*!
+    \brief      configure break frame coherence mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  bcm: 
+      \arg        USART_BCM_NONE: no parity error is detected
+      \arg        USART_BCM_EN:   parity error is detected
+    \param[out] none
+    \retval     none
+*/
+void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm)
+{
+    USART_CHC(usart_periph) &= ~(USART_CHC_BCM);
+    USART_CHC(usart_periph) |= (USART_CHC_BCM & bcm);
+}
+
+/*!
+    \brief      configure parity check coherence mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  pcm: 
+      \arg        USART_PCM_NONE: not check parity
+      \arg        USART_PCM_EN:   check the parity
+    \param[out] none
+    \retval     none
+*/
+void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm)
+{
+    USART_CHC(usart_periph) &= ~(USART_CHC_PCM);
+    USART_CHC(usart_periph) |= (USART_CHC_PCM & pcm);
+}
+
+/*!
+    \brief      configure hardware flow control coherence mode
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)
+    \param[in]  hcm: 
+      \arg        USART_HCM_NONE: nRTS signal equals to the rxne status register
+      \arg        USART_HCM_EN:   nRTS signal is set when the last data bit has been sampled
+    \param[out] none
+    \retval     none
+*/
+void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm)
+{
+    USART_CHC(usart_periph) &= ~(USART_CHC_HCM);
+    USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm);
+}
+
+/*!
+    \brief      configure USART DMA reception
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  dmacmd: enable or disable DMA for reception
+      \arg        USART_DENR_ENABLE:  DMA enable for reception
+      \arg        USART_DENR_DISABLE: DMA disable for reception
+    \param[out] none
+    \retval     none
+*/
+void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd)
+{
+    uint32_t ctl = 0U;
+    
+    ctl = USART_CTL2(usart_periph);
+    ctl &= ~USART_CTL2_DENR;
+    ctl |= dmacmd;
+    /* configure DMA reception */
+    USART_CTL2(usart_periph) = ctl;
+}
+
+/*!
+    \brief      configure USART DMA transmission
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  dmacmd: enable or disable DMA for transmission
+      \arg        USART_DENT_ENABLE:  DMA enable for transmission
+      \arg        USART_DENT_DISABLE: DMA disable for transmission
+    \param[out] none
+    \retval     none
+*/
+void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd)
+{
+    uint32_t ctl = 0U;
+    
+    ctl = USART_CTL2(usart_periph);
+    ctl &= ~USART_CTL2_DENT;
+    ctl |= dmacmd;
+    /* configure DMA transmission */
+    USART_CTL2(usart_periph) = ctl;
+}
+
+/*!
+    \brief      get flag in STAT0/STAT1/CHC register
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  flag: USART flags, refer to usart_flag_enum
+      \arg        USART_FLAG_CTSF: CTS change flag
+      \arg        USART_FLAG_LBDF: LIN break detected flag 
+      \arg        USART_FLAG_TBE: transmit data buffer empty 
+      \arg        USART_FLAG_TC: transmission complete 
+      \arg        USART_FLAG_RBNE: read data buffer not empty 
+      \arg        USART_FLAG_IDLEF: IDLE frame detected flag 
+      \arg        USART_FLAG_ORERR: overrun error 
+      \arg        USART_FLAG_NERR: noise error flag 
+      \arg        USART_FLAG_FERR: frame error flag 
+      \arg        USART_FLAG_PERR: parity error flag 
+      \arg        USART_FLAG_BSY: busy flag 
+      \arg        USART_FLAG_EBF: end of block flag 
+      \arg        USART_FLAG_RTF: receiver timeout flag 
+      \arg        USART_FLAG_EPERR: early parity error flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
+{
+    if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear flag in STAT0/STAT1/CHC register
+    \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  flag: USART flags, refer to usart_flag_enum
+      \arg        USART_FLAG_CTSF: CTS change flag
+      \arg        USART_FLAG_LBDF: LIN break detected flag
+      \arg        USART_FLAG_TC: transmission complete
+      \arg        USART_FLAG_RBNE: read data buffer not empty
+      \arg        USART_FLAG_EBF: end of block flag
+      \arg        USART_FLAG_RTF: receiver timeout flag
+      \arg        USART_FLAG_EPERR: early parity error flag
+    \param[out] none
+    \retval     none
+*/
+void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag)
+{
+    USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag));
+}
+
+/*!
+    \brief      enable USART interrupt
+     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  int_flag
+      \arg        USART_INTEN_PERRIE: parity error interrupt
+      \arg        USART_INTEN_TBEIE: transmitter buffer empty interrupt
+      \arg        USART_INTEN_TCIE: transmission complete interrupt
+      \arg        USART_INTEN_RBNEIE: read data buffer not empty interrupt and overrun error interrupt
+      \arg        USART_INTEN_IDLEIE: IDLE line detected interrupt
+      \arg        USART_INTEN_LBDIE: LIN break detected interrupt
+      \arg        USART_INTEN_ERRIE: error interrupt
+      \arg        USART_INTEN_CTSIE: CTS interrupt
+      \arg        USART_INTEN_RTIE: interrupt enable bit of receive timeout event
+      \arg        USART_INTEN_EBIE: interrupt enable bit of end of block event
+    \param[out] none
+*/
+void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag)
+{
+    uint32_t usart_reg = 0U;
+    
+    usart_reg = int_flag & (~(uint32_t)USART_INTEN_MASK);
+    int_flag &= USART_INTEN_MASK;
+    /* flags in USART_CTL0 */
+    if(USART_INTS_CTL0 == usart_reg){
+        USART_CTL0(usart_periph) |= int_flag;
+    /* flags in USART_CTL1 */
+    }else if(USART_INTS_CTL1 == usart_reg){
+        USART_CTL1(usart_periph) |= int_flag;
+    /* flags in USART_CTL2 */
+    }else if(USART_INTS_CTL2 == usart_reg){
+        USART_CTL2(usart_periph) |= int_flag;
+    /* flags in USART_CTL3 */
+    }else if(USART_INTS_CTL3 == usart_reg){
+        USART_CTL3(usart_periph) |= int_flag;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      disable USART interrupt
+     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  int_flag
+      \arg        USART_INTEN_PERRIE: parity error interrupt
+      \arg        USART_INTEN_TBEIE: transmitter buffer empty interrupt
+      \arg        USART_INTEN_TCIE: transmission complete interrupt
+      \arg        USART_INTEN_RBNEIE: read data buffer not empty interrupt and overrun error interrupt
+      \arg        USART_INTEN_IDLEIE: IDLE line detected interrupt
+      \arg        USART_INTEN_LBDIE: LIN break detected interrupt
+      \arg        USART_INTEN_ERRIE: error interrupt
+      \arg        USART_INTEN_CTSIE: CTS interrupt
+      \arg        USART_INTEN_RTIE: interrupt enable bit of receive timeout event
+      \arg        USART_INTEN_EBIE: interrupt enable bit of end of block event
+    \param[out] none
+*/
+void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag)
+{
+    uint32_t usart_reg = 0U;
+    
+    usart_reg = int_flag & (~(uint32_t)USART_INTEN_MASK);
+    int_flag &= USART_INTEN_MASK;
+    /* flags in USART_CTL0 */
+    if(USART_INTS_CTL0 == usart_reg){
+        USART_CTL0(usart_periph) &= ~(int_flag);
+    /* flags in USART_CTL1 */
+    }else if(USART_INTS_CTL1 == usart_reg){
+        USART_CTL1(usart_periph) &= ~(int_flag);
+    /* flags in USART_CTL2 */
+    }else if(USART_INTS_CTL2 == usart_reg){
+        USART_CTL2(usart_periph) &= ~(int_flag);
+    /* flags in USART_CTL3 */
+    }else if(USART_INTS_CTL3 == usart_reg){
+        USART_CTL3(usart_periph) &= ~(int_flag);
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      get USART interrupt enable flag
+     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
+    \param[in]  int_flag
+      \arg        USART_INT_PERRIE: parity error interrupt
+      \arg        USART_INT_TBEIE: transmitter buffer empty interrupt
+      \arg        USART_INT_TCIE: transmission complete interrupt
+      \arg        USART_INT_RBNEIE: read data buffer not empty interrupt and overrun error interrupt
+      \arg        USART_INT_IDLEIE: IDLE line detected interrupt
+      \arg        USART_INT_LBDIE: LIN break detected interrupt
+      \arg        USART_INT_CTSIE: CTS interrupt
+      \arg        USART_INT_ERRIE: error interrupt
+      \arg        USART_INT_EBIE: interrupt enable bit of end of block event
+      \arg        USART_INT_RTIE: interrupt enable bit of receive timeout event
+    \param[out] none
+    \retval     FlagStatus
+*/
+FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag)
+{
+    if(RESET != (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+

+ 122 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_wwdgt.c

@@ -0,0 +1,122 @@
+/*!
+    \file  gd32f4xx_wwdgt.c
+    \brief WWDGT driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "gd32f4xx_wwdgt.h"
+
+/* write value to WWDGT_CTL_CNT bit field */
+#define CTL_CNT(regval)             (BITS(0,6) & ((uint32_t)(regval) << 0))
+/* write value to WWDGT_CFG_WIN bit field */
+#define CFG_WIN(regval)             (BITS(0,6) & ((uint32_t)(regval) << 0))
+
+/*!
+    \brief      reset the window watchdog timer configuration
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_WWDGTRST);
+    rcu_periph_reset_disable(RCU_WWDGTRST);
+}
+
+/*!
+    \brief      configure the window watchdog timer counter value
+    \param[in]  counter_value: 0x00 - 0x7F
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_counter_update(uint16_t counter_value)
+{
+    uint32_t reg = 0U;
+    
+    reg = (WWDGT_CTL & (~WWDGT_CTL_CNT));
+    reg |= CTL_CNT(counter_value);
+    
+    WWDGT_CTL = reg;
+}
+
+/*!
+    \brief      start the window watchdog timer counter
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_enable(void)
+{
+    WWDGT_CTL |= WWDGT_CTL_WDGTEN;
+}
+
+/*!
+    \brief      configure counter value, window value, and prescaler divider value  
+    \param[in]  counter: 0x00 - 0x7F   
+    \param[in]  window: 0x00 - 0x7F
+    \param[in]  prescaler: wwdgt prescaler value
+      \arg        WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1
+      \arg        WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2
+      \arg        WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4
+      \arg        WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler)
+{
+    uint32_t reg_cfg = 0U, reg_ctl = 0U;
+
+    /* clear WIN and PSC bits, clear CNT bit */
+    reg_cfg = (WWDGT_CFG &(~(WWDGT_CFG_WIN|WWDGT_CFG_PSC)));
+    reg_ctl = (WWDGT_CTL &(~WWDGT_CTL_CNT));
+  
+    /* configure WIN and PSC bits, configure CNT bit */
+    reg_cfg |= CFG_WIN(window);
+    reg_cfg |= prescaler;
+    reg_ctl |= CTL_CNT(counter);
+    
+    WWDGT_CTL = reg_ctl;
+    WWDGT_CFG = reg_cfg;
+}
+
+/*!
+    \brief      enable early wakeup interrupt of WWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_interrupt_enable(void)
+{
+    WWDGT_CFG |= WWDGT_CFG_EWIE;
+}
+
+/*!
+    \brief      check early wakeup interrupt state of WWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus wwdgt_flag_get(void)
+{
+    if(WWDGT_STAT & WWDGT_STAT_EWIF){
+        return SET;
+    }
+
+    return RESET;
+}
+
+/*!
+    \brief      clear early wakeup interrupt state of WWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_flag_clear(void)
+{
+    WWDGT_STAT &= (~WWDGT_STAT_EWIF);
+}

+ 287 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_core.h

@@ -0,0 +1,287 @@
+/*!
+    \file  usb_core.h
+    \brief USB core driver header file
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USB_CORE_H
+#define USB_CORE_H
+
+#include "usb_conf.h"
+#include "usb_regs.h"
+#include "usb_defines.h"
+
+#define USB_MAX_EP0_SIZE                        64U   /* endpoint 0 max packet size */
+#define RX_MAX_DATA_LENGTH                      512U  /* host rx buffer max data length */
+#define HC_MAX_PACKET_COUNT                     140U  /* host channel max packet count */
+
+#ifdef USE_USBFS
+    #define USB_MAX_DEV_EPCOUNT                 USBFS_MAX_DEV_EPCOUNT
+    #define USB_MAX_FIFOS                       (USBFS_MAX_HOST_CHANNELCOUNT * 2U - 1U)
+#elif defined(USE_USBHS)
+    #define USB_MAX_DEV_EPCOUNT                 USBHS_MAX_DEV_EPCOUNT
+    #define USB_MAX_FIFOS                       (USBHS_MAX_HOST_CHANNELCOUNT * 2U - 1U)
+#endif /* USE_USBFS */
+
+/* USB core status */
+typedef enum
+{
+    USB_OK = 0,         /* USB core OK status */
+    USB_FAIL            /* USB core fail status */
+}usb_status_enum;
+
+/* USB host channel status */
+typedef enum
+{
+    HC_IDLE = 0,        /* USB host channel idle status */
+    HC_XF,              /* USB host channel transfer status */
+    HC_HALTED,          /* USB host channel halted status */
+    HC_NAK,             /* USB host channel nak status */
+    HC_NYET,            /* USB host channel nyet status */
+    HC_STALL,           /* USB host channel stall status */
+    HC_TRACERR,         /* USB host channel tracerr status */
+    HC_BBERR,           /* USB host channel bberr status */
+    HC_DTGERR,          /* USB host channel dtgerr status */
+}hc_status_enum;
+
+/* USB URB(USB request block) state */
+typedef enum
+{
+    URB_IDLE = 0,       /* USB URB idle status */
+    URB_DONE,           /* USB URB done status */
+    URB_NOTREADY,       /* USB URB notready status */
+    URB_ERROR,          /* USB URB error status */
+    URB_STALL,          /* USB URB stall status */
+    URB_PING            /* USB URB ping status */
+}urb_state_enum;
+
+/* USB core configuration */
+typedef struct
+{
+    uint8_t        core_id;            /* USB core id */
+    uint8_t        core_speed;         /* USB core speed */
+    uint8_t        phy_interface;      /* USB PHY interface */
+    uint8_t        host_channel_num;   /* USB host channel number */
+    uint8_t        dev_endp_num;       /* USB device endpoint number */
+    uint8_t        dma_enable;         /* USBHS can use DMA  */
+    uint8_t        sof_output;         /* USB SOF output */
+    uint8_t        low_power;          /* USB low power */
+    uint16_t       max_packet_size;    /* USB max packet size */
+    uint16_t       max_fifo_size;      /* USB fifo size */
+}usb_core_cfgs_struct;
+
+typedef enum
+{
+    USBD_OK = 0,      /* USB device ok status */
+    USBD_BUSY,        /* USB device busy status */
+    USBD_FAIL,        /* USB device fail stauts */
+}usbd_status_enum;
+
+/* USB control transfer state */
+typedef enum
+{
+    USB_CTRL_IDLE = 0,     /* USB control transfer idle state */
+    USB_CTRL_SETUP,        /* USB control transfer setup state */
+    USB_CTRL_DATA_IN,      /* USB control transfer data in state */
+    USB_CTRL_DATA_OUT,     /* USB control transfer data out state */
+    USB_CTRL_STATUS_IN,    /* USB control transfer status in state*/
+    USB_CTRL_STATUS_OUT,   /* USB control transfer status out state */
+    USB_CTRL_STALL         /* USB control transfer stall state */
+}usbd_control_state_enum;
+
+/* USB transfer direction */
+typedef enum
+{
+    USBD_RX = 0,         /* receive direction type value */
+    USBD_TX              /* transmit direction type value */
+}usbd_dir_enum;
+
+/* USB endpoint in device mode */
+typedef struct
+{
+    uint8_t         endp_type;   /* USB endpoint type */
+    uint8_t         endp_frame;  /* USB endpoint frame */
+    uint32_t        endp_mps;    /* USB endpoint max packet size */
+
+    /* Transaction level variables */
+    uint8_t        *xfer_buff;   /* USB transfer buffer */
+    uint32_t        xfer_len;    /* USB transfer length */
+    uint32_t        xfer_count;  /* USB transfer count */
+
+    uint32_t        dma_addr;    /* USBHS can use DMA */
+}usb_ep_struct;
+
+/* USB device standard request */
+typedef struct
+{
+    uint8_t         bmRequestType;  /* USB device request type */
+    uint8_t         bRequest;       /* USB device request */
+    uint16_t        wValue;         /* USB device request value */
+    uint16_t        wIndex;         /* USB device request index */
+    uint16_t        wLength;        /* USB device request length */
+}usb_device_req_struct;
+
+/* USB core device driver */
+typedef struct
+{
+    uint8_t         config_num;          /* USB configuration number */
+    uint8_t         status;              /* USB status */
+    uint8_t         ctl_status;          /* USB control status */
+    uint8_t         prev_status;         /* USB previous status */
+    uint8_t         connection_status;   /* USB connection status */
+    uint32_t        remote_wakeup;       /* USB remote wakeup */
+
+    /* transfer level variables */
+    uint32_t        remain_len;          /* USB remain length */
+    uint32_t        sum_len;             /* USB sum length */
+    uint32_t        ctl_len;             /* USB control length */
+    uint8_t         setup_packet[8 * 3]; /* USB setup packet */
+
+    usb_ep_struct   in_ep[USB_MAX_DEV_EPCOUNT];   /* USB IN endpoint */
+    usb_ep_struct   out_ep[USB_MAX_DEV_EPCOUNT];  /* USB OUT endpoint */
+
+    uint8_t  *dev_desc;                  /* device descriptor */
+    uint8_t  *config_desc;               /* configuration descriptor */
+    uint8_t* *strings;                   /* configuration strings */
+
+    /* device class handler */
+    uint8_t (*class_init)         (void *pudev, uint8_t config_index);         /* device class initialize */
+    uint8_t (*class_deinit)       (void *pudev, uint8_t config_index);         /* device class deinitialize */
+    uint8_t (*class_req_handler)  (void *pudev, usb_device_req_struct *req);   /* device request handler */
+    uint8_t (*class_data_handler) (void *pudev, usbd_dir_enum rx_tx, uint8_t ep_id);  /* device data handler */
+}dcd_dev_struct;
+
+/* USB core host mode channel */
+typedef struct
+{
+    uint8_t         dev_addr;     /* device address */
+    uint8_t         dev_speed;    /* device speed */
+    uint8_t         DPID;         /* endpoint transfer data pid */
+    uint8_t         endp_id;      /* endpoint id */
+    uint8_t         endp_in;      /* endpoint in */
+    uint8_t         endp_type;    /* endpoint type */
+    uint16_t        endp_mps;     /* endpoint max pactet size */
+    uint16_t        info;         /* channel information */
+
+    uint8_t         do_ping;      /* USBHS ping */
+
+    uint8_t        *xfer_buff;    /* transfer buffer */
+    uint32_t        xfer_len;     /* transfer length */
+    uint32_t        xfer_count;   /* trasnfer count */
+
+    uint32_t        err_count;    /* USB transfer error count */
+    uint32_t        dma_addr;     /* USBHS can use DMA */
+
+    hc_status_enum  status;       /* channel status */
+    urb_state_enum  urb_state;    /* URB state */
+
+    uint8_t         data_tg_in;   /* data in toggle */
+    uint8_t         data_tg_out;  /* data out toggle */
+}usb_hostchannel_struct;
+
+/* USB core host driver */
+typedef struct
+{
+    uint8_t                 rx_buffer[RX_MAX_DATA_LENGTH]; /* rx buffer */
+    uint8_t                 connect_status;                /* device connect status */
+    usb_hostchannel_struct  host_channel[USB_MAX_FIFOS];   /* host channel */
+    void (*vbus_drive)     (void *pudev, uint8_t state);   /* the vbus driver function */
+}hcd_dev_struct;
+
+#ifdef USE_OTG_MODE
+
+/* USB core OTG-mode driver */
+typedef struct
+{
+    uint8_t         OTG_State;      /* OTG state */
+    uint8_t         OTG_PrevState;  /* OTG previous state */
+    uint8_t         OTG_Mode;       /* OTG mode */
+}otg_dev_struct;
+
+#endif /* USE_OTG_MODE */
+
+/* USB core driver */
+typedef struct
+{
+    usb_core_cfgs_struct   cfg;
+
+#ifdef USE_DEVICE_MODE
+    dcd_dev_struct         dev;
+#endif /* USE_DEVICE_MODE */
+
+#ifdef USE_HOST_MODE
+    hcd_dev_struct         host;
+#endif /* USE_HOST_MODE */
+
+#ifdef USE_OTG_MODE
+    otg_dev_struct         otg;
+#endif /* USE_OTG_MODE */
+
+    void (*udelay) (const uint32_t usec);
+    void (*mdelay) (const uint32_t msec);
+}usb_core_handle_struct;
+
+/* function declarations */
+
+/* global APIs */
+/* initializes the USB controller registers and prepares the core device mode or host mode operation */
+usb_status_enum usb_core_init (usb_core_handle_struct *pudev);
+/* initialize core parameters */
+usb_status_enum usb_core_select (usb_core_handle_struct *pudev, usb_core_id_enum core_id);
+/* read a packet from the Rx FIFO associated with the endpoint */
+void* usb_fifo_read (uint8_t *dest, uint16_t len);
+/* write a packet into the Tx FIFO associated with the endpoint */
+usb_status_enum usb_fifo_write (uint8_t *src, uint8_t ep_id, uint16_t len);
+/* flush a Tx FIFO or all Tx FIFOs */
+usb_status_enum usb_txfifo_flush (usb_core_handle_struct *pudev, uint8_t fifo_num);
+/* flush the entire Rx FIFO */
+usb_status_enum usb_rxfifo_flush (usb_core_handle_struct *pudev);
+/* set operation mode (host or device) */
+usb_status_enum usb_mode_set (usb_core_handle_struct *pudev, uint8_t mode);
+
+/* host APIs */
+#ifdef USE_HOST_MODE
+
+/* initializes USB core for host mode */
+usb_status_enum usb_hostcore_init (usb_core_handle_struct *pudev);
+/* enables the host mode interrupts */
+usb_status_enum usb_hostint_enable (usb_core_handle_struct *pudev);
+/* initialize host channel */
+usb_status_enum usb_hostchannel_init (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* halt channel */
+usb_status_enum usb_hostchannel_halt (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* prepare host channel for transferring packets */
+usb_status_enum usb_hostchannel_startxfer (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* issue a ping token */
+usb_status_enum usb_hostchannel_ping (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* reset host port */
+uint32_t usb_port_reset (usb_core_handle_struct *pudev);
+/* control the VBUS to power */
+void usb_vbus_drive (usb_core_handle_struct *pudev, uint8_t state);
+/* stop the USB host and clean up fifos */
+void usb_host_stop (usb_core_handle_struct *pudev);
+
+#endif /* USE_HOST_MODE */
+
+/* device APIs */
+#ifdef USE_DEVICE_MODE
+
+/* initialize USB core registers for device mode */
+usb_status_enum usb_devcore_init (usb_core_handle_struct *pudev);
+/* configures endpoint 0 to receive SETUP packets */
+void usb_ep0_startout (usb_core_handle_struct *pudev);
+/* active remote wakeup signalling */
+void usb_remotewakeup_active (usb_core_handle_struct *pudev);
+/* active USB core clock */
+void usb_clock_ungate (usb_core_handle_struct *pudev);
+/* stop the device and clean up fifos */
+void usb_device_stop (usb_core_handle_struct *pudev);
+
+#endif /* USE_DEVICE_MODE */
+
+#endif  /* USB_CORE_H */

+ 100 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_defines.h

@@ -0,0 +1,100 @@
+/*!
+    \file  usb_defines.h
+    \brief USB core defines
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USB_DEFINES_H
+#define USB_DEFINES_H
+
+#include  "usb_conf.h"
+
+#ifndef NULL
+    #define NULL                                (void *)0   /*!< USB null marco value*/
+#endif /* NULL */
+
+#define USB_CORE_SPEED_HIGH                     0U    /* USB core speed is high-speed */
+#define USB_CORE_SPEED_FULL                     1U    /* USB core speed is full-speed */
+
+#define USBFS_MAX_PACKET_SIZE                   64U   /* USBFS max packet size */
+#define USBFS_MAX_HOST_CHANNELCOUNT             8U    /* USBFS host channel count */
+#define USBFS_MAX_DEV_EPCOUNT                   4U    /* USBFS device endpoint count */
+#define USBFS_MAX_FIFO_WORDLEN                  320U  /* USBFS max fifo size in words */
+
+#define USBHS_MAX_PACKET_SIZE                   512U  /* USBHS max packet size */
+#define USBHS_MAX_HOST_CHANNELCOUNT             12U   /* USBHS host channel count */
+#define USBHS_MAX_DEV_EPCOUNT                   6U    /* USBHS device endpoint count */
+#define USBHS_MAX_FIFO_WORDLEN                  1280U /* USBHS max fifo size in words */
+
+#define USB_CORE_ULPI_PHY                       1U    /* USB core use external ULPI PHY */
+#define USB_CORE_EMBEDDED_PHY                   2U    /* USB core use embedded PHY */
+
+#define DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ     0U    /* USB enumerate speed use high-speed PHY clock in 30MHz or 60MHz */
+#define DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ     1U    /* USB enumerate speed use full-speed PHY clock in 30MHz or 60MHz */
+#define DSTAT_ENUMSPD_LS_PHY_6MHZ               2U    /* USB enumerate speed use low-speed PHY clock in 6MHz */
+#define DSTAT_ENUMSPD_FS_PHY_48MHZ              3U    /* USB enumerate speed use full-speed PHY clock in 48MHz */
+
+#define GRSTATR_RPCKST_IN                       2U    /* IN data packet received */
+#define GRSTATR_RPCKST_IN_XFER_COMP             3U    /* IN transfer completed (generates an interrupt if poped) */
+#define GRSTATR_RPCKST_DATA_TOGGLE_ERR          5U    /* Data toggle error (generates an interrupt if poped) */
+#define GRSTATR_RPCKST_CH_HALTED                7U    /* Channel halted (generates an interrupt if poped) */
+
+#define DEVICE_MODE                             0U    /* USB core in device mode */
+#define HOST_MODE                               1U    /* USB core in host mode */
+#define OTG_MODE                                2U    /* USB core in OTG mode */
+
+#define USB_EPTYPE_CTRL                         0U    /* USB control endpoint type */
+#define USB_EPTYPE_ISOC                         1U    /* USB synchronous endpoint type */
+#define USB_EPTYPE_BULK                         2U    /* USB bulk endpoint type */
+#define USB_EPTYPE_INTR                         3U    /* USB interrupt endpoint type */
+#define USB_EPTYPE_MASK                         3U    /* USB endpoint type mask */
+
+#define RXSTAT_GOUT_NAK                         1U    /* global OUT NAK (triggers an interrupt) */
+#define RXSTAT_DATA_UPDT                        2U    /* OUT data packet received */
+#define RXSTAT_XFER_COMP                        3U    /* OUT transfer completed (triggers an interrupt) */
+#define RXSTAT_SETUP_COMP                       4U    /* SETUP transaction completed (triggers an interrupt) */
+#define RXSTAT_SETUP_UPDT                       6U    /* SETUP data packet received */
+
+#define DPID_DATA0                              0U    /* device endpoint data PID is DATA0 */
+#define DPID_DATA1                              2U    /* device endpoint data PID is DATA1 */
+#define DPID_DATA2                              1U    /* device endpoint data PID is DATA2 */
+#define DPID_MDATA                              3U    /* device endpoint data PID is MDATA */
+
+#define HC_PID_DATA0                            0U    /* host channel data PID is DATA0 */
+#define HC_PID_DATA2                            1U    /* host channel data PID is DATA2 */
+#define HC_PID_DATA1                            2U    /* host channel data PID is DATA1 */
+#define HC_PID_SETUP                            3U    /* host channel data PID is SETUP */
+
+#define HPRT_PRTSPD_HIGH_SPEED                  0U    /* host port speed use high speed */
+#define HPRT_PRTSPD_FULL_SPEED                  1U    /* host port speed use full speed */
+#define HPRT_PRTSPD_LOW_SPEED                   2U    /* host port speed use low speed */
+
+#define HCTLR_30_60_MHZ                         0U    /* USB PHY(ULPI) clock is 60MHz */
+#define HCTLR_48_MHZ                            1U    /* USB PHY(embedded full-speed) clock is 48MHz */
+#define HCTLR_6_MHZ                             2U    /* USB PHY(embedded low-speed) clock is 6MHz */
+
+#define HCCHAR_CTRL                             0U    /* control channel type */
+#define HCCHAR_ISOC                             1U    /* synchronous channel type */
+#define HCCHAR_BULK                             2U    /* bulk channel type */
+#define HCCHAR_INTR                             3U    /* interrupt channel type */
+
+typedef enum
+{
+    USB_HS_CORE_ID = 0,
+    USB_FS_CORE_ID = 1
+}usb_core_id_enum;
+
+typedef enum
+{
+    USB_SPEED_UNKNOWN = 0,
+    USB_SPEED_LOW,
+    USB_SPEED_FULL,
+    USB_SPEED_HIGH
+}usb_speed_enum;
+
+#endif /* USB_DEFINES_H */

+ 676 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_regs.h

@@ -0,0 +1,676 @@
+/*!
+    \file  usb_regs.h
+    \brief USB FS&HS cell registers definition and handle macros
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USB_REGS_H
+#define USB_REGS_H
+
+#include "usb_conf.h"
+
+#define USBFS                     USBFS_BASE                              /*!< base address of USBFS registers */
+#define USBHS                     USBHS_BASE                              /*!< base address of USBHS registers */
+
+#ifdef USE_USBFS
+    #define USBX    USBFS                                                 /*!< USB full speed mode */
+#endif /* USE_USBFS */
+
+#ifdef USE_USBHS
+    #define USBX    USBHS                                                 /*!< USB high speed mode */
+#endif /* USE_USBHS */
+
+/* registers location definitions */
+#define LOCATE_DIEPTFLEN(x)       (0x104U + 4U * ((x) - 1U))              /*!< locate device IN endpoint-x transfer length registers */
+#define LOCATE_HCHCTL(x)          (0x500U + 0x20U * (x))                  /*!< locate host channel-x control registers */
+#define LOCATE_HCHSTCTL(x)        (0x504U + 0x20U * (x))                  /*!< locate host channel-x split transaction control registers */
+#define LOCATE_HCHINTF(x)         (0x508U + 0x20U * (x))                  /*!< locate host channel-x interrupt flag registers */
+#define LOCATE_HCHINTEN(x)        (0x50CU + 0x20U * (x))                  /*!< locate host channel-x interrupt enable registers */
+#define LOCATE_HCHLEN(x)          (0x510U + 0x20U * (x))                  /*!< locate host channel-x transfer length registers */
+#define LOCATE_HCHDMAADDR(x)      (0x514U + 0x20U * (x))                  /*!< locate host channel-x DMA address registers */
+#define LOCATE_DIEPCTL(x)         (0x900U + 0x20U * (x))                  /*!< locate device IN endpoint-x control registers */
+#define LOCATE_DOEPCTL(x)         (0xB00U + 0x20U * (x))                  /*!< locate device OUT endpoint-x control registers */
+#define LOCATE_DIEPINTF(x)        (0x908U + 0x20U * (x))                  /*!< locate device IN endpoint-x interrupt flag registers */
+#define LOCATE_DOEPINTF(x)        (0xB08U + 0x20U * (x))                  /*!< locate device OUT endpoint-x interrupt flag registers */
+#define LOCATE_DIEPLEN(x)         (0x910U + 0x20U * (x))                  /*!< locate device IN endpoint-x transfer length registers */
+#define LOCATE_DOEPLEN(x)         (0xB10U + 0x20U * (x))                  /*!< locate device OUT endpoint-x transfer length registers */
+#define LOCATE_DIEPxDMAADDR(x)    (0x914U + 0x20U * (x))                  /*!< locate device IN endpoint-x DMA address registers */
+#define LOCATE_DOEPxDMAADDR(x)    (0xB14U + 0x20U * (x))                  /*!< locate device OUT endpoint-x DMA address registers */
+#define LOCATE_DIEPxTFSTAT(x)     (0x918U + 0x20U * (x))                  /*!< locate Device IN endpoint-x transmit FIFO status register */
+#define LOCATE_FIFO(x)            (((x) + 1U) << 12U)                     /*!< locate FIFO-x memory */
+
+/* registers definitions */
+#define USB_GOTGCS                REG32(((USBX) + 0x0000U))               /*!< global OTG control and status register */
+#define USB_GOTGINTF              REG32(((USBX) + 0x0004U))               /*!< global OTG interrupt flag register */
+#define USB_GAHBCS                REG32(((USBX) + 0x0008U))               /*!< global AHB control and status register */
+#define USB_GUSBCS                REG32(((USBX) + 0x000CU))               /*!< global USB control and status register */
+#define USB_GRSTCTL               REG32(((USBX) + 0x0010U))               /*!< global reset control register */
+#define USB_GINTF                 REG32(((USBX) + 0x0014U))               /*!< global interrupt flag register */
+#define USB_GINTEN                REG32(((USBX) + 0x0018U))               /*!< global interrupt enable register */
+#define USB_GRSTATR               REG32(((USBX) + 0x001CU))               /*!< global receive status read register */
+#define USB_GRSTATP               REG32(((USBX) + 0x0020U))               /*!< global receive status read and pop register */
+#define USB_GRFLEN                REG32(((USBX) + 0x0024U))               /*!< global receive FIFO length register */
+#define USB_HNPTFLEN              REG32(((USBX) + 0x0028U))               /*!< host non-periodic transmit FIFO length register */
+#define USB_DIEP0TFLEN            REG32(((USBX) + 0x0028U))               /*!< device IN endpoint 0 transmit FIFO length register */
+#define USB_HNPTFQSTAT            REG32(((USBX) + 0x002CU))               /*!< host non-periodic transmint FIFO/queue status register */
+#define USB_GCCFG                 REG32(((USBX) + 0x0038U))               /*!< global core configuration register */
+#define USB_CID                   REG32(((USBX) + 0x003CU))               /*!< core id register */
+#define USB_HPTFLEN               REG32(((USBX) + 0x0100U))               /*!< host periodic transmit FIFO length register */
+#define USB_DIEPxTFLEN(x)         REG32(((USBX) + LOCATE_DIEPTFLEN(x)))   /*!< device IN endpoint transmit FIFO length register */
+
+#define USB_HCTL                  REG32(((USBX) + 0x0400U))               /*!< host control register */
+#define USB_HFT                   REG32(((USBX) + 0x0404U))               /*!< host frame interval register */
+#define USB_HFINFR                REG32(((USBX) + 0x0408U))               /*!< host frame information remaining register */
+#define USB_HPTFQSTAT             REG32(((USBX) + 0x0410U))               /*!< host periodic transmit FIFO/queue status register */
+#define USB_HACHINT               REG32(((USBX) + 0x0414U))               /*!< host all channels interrupt register */
+#define USB_HACHINTEN             REG32(((USBX) + 0x0418U))               /*!< host all channels interrupt enable register */
+#define USB_HPCS                  REG32(((USBX) + 0x0440U))               /*!< host port control and status register */
+#define USB_HCHxCTL(x)            REG32(((USBX) + LOCATE_HCHCTL(x)))      /*!< host channel-x control register */
+#define USB_HCHxSTCTL(x)          REG32(((USBX) + LOCATE_HCHSTCTL(x)))    /*!< host channel-x split transaction control register */
+#define USB_HCHxINTF(x)           REG32(((USBX) + LOCATE_HCHINTF(x)))     /*!< host channel-x interrupt flag register */
+#define USB_HCHxINTEN(x)          REG32(((USBX) + LOCATE_HCHINTEN(x)))    /*!< host channel-x interrupt enable register */
+#define USB_HCHxLEN(x)            REG32(((USBX) + LOCATE_HCHLEN(x)))      /*!< host channel-x tranfer length register */
+#define USB_HCHxDMAADDR(x)        REG32(((USBX) + LOCATE_HCHDMAADDR(x)))  /*!< host channel-x DMA address register */
+
+#define USB_DCFG                  REG32(((USBX) + 0x0800U))               /*!< device configuration register */
+#define USB_DCTL                  REG32(((USBX) + 0x0804U))               /*!< device control register */
+#define USB_DSTAT                 REG32(((USBX) + 0x0808U))               /*!< device status register */
+#define USB_DIEPINTEN             REG32(((USBX) + 0x0810U))               /*!< device IN endpoint common interrupt enable register */
+#define USB_DOEPINTEN             REG32(((USBX) + 0x0814U))               /*!< device OUT endpoint common interrupt enable register */
+#define USB_DAEPINT               REG32(((USBX) + 0x0818U))               /*!< device all endpoints interrupt register */
+#define USB_DAEPINTEN             REG32(((USBX) + 0x081CU))               /*!< device all endpoints interrupt enable register */
+#define USB_DVBUSDT               REG32(((USBX) + 0x0828U))               /*!< device vbus discharge time register */
+#define USB_DVBUSPT               REG32(((USBX) + 0x082CU))               /*!< device vbus pulsing time register */
+#define USB_DIEPFEINTEN           REG32(((USBX) + 0x0834U))               /*!< device IN endpoint FIFO empty interrupt enable register */
+#define USB_DEP1INT               REG32(((USBX) + 0x0838U))               /*!< device endpoint 1 interrupt register */
+#define USB_DEP1INTEN             REG32(((USBX) + 0x083CU))               /*!< device endpoint 1 interrupt enable register */
+#define USB_DIEP1INTEN            REG32(((USBX) + 0x0844U))               /*!< device IN endpoint 1 interrupt enable register */
+#define USB_DOEP1INTEN            REG32(((USBX) + 0x0884U))               /*!< device OUT endpoint 1 interrupt enable register */
+#define USB_DIEP0CTL              REG32(((USBX) + 0x0900U))               /*!< device IN endpoint 0 control register */
+#define USB_DIEP0LEN              REG32(((USBX) + 0x0910U))               /*!< device IN endpoint 0 transfer length register */
+#define USB_DOEP0CTL              REG32(((USBX) + 0x0B00U))               /*!< device OUT endpoint 0 control register */
+#define USB_DOEP0LEN              REG32(((USBX) + 0x0B10U))               /*!< device OUT endpoint 0 transfer length register */
+#define USB_DIEPxCTL(x)           REG32(((USBX) + LOCATE_DIEPCTL(x)))     /*!< device IN endpoint-x control register */
+#define USB_DOEPxCTL(x)           REG32(((USBX) + LOCATE_DOEPCTL(x)))     /*!< device OUT endpoint-x control register */
+#define USB_DIEPxINTF(x)          REG32(((USBX) + LOCATE_DIEPINTF(x)))    /*!< device IN endpoint-x interrupt flag register */
+#define USB_DOEPxINTF(x)          REG32(((USBX) + LOCATE_DOEPINTF(x)))    /*!< device OUT endpoint-x interrupt flag register */
+#define USB_DIEPxLEN(x)           REG32(((USBX) + LOCATE_DIEPLEN(x)))     /*!< device IN endpoint-x transfer length register */
+#define USB_DOEPxLEN(x)           REG32(((USBX) + LOCATE_DOEPLEN(x)))     /*!< device OUT endpoint-x transfer length register */
+#define USB_DIEPxDMAADDR(x)       REG32(((USBX) + LOCATE_DIEPxDMAADDR(x)))/*!< device IN endpoint-x DMA address register */
+#define USB_DOEPxDMAADDR(x)       REG32(((USBX) + LOCATE_DOEPxDMAADDR(x)))/*!< device OUT endpoint-x DMA address register */
+#define USB_DIEPxTFSTAT(x)        REG32(((USBX) + LOCATE_DIEPxTFSTAT(x))) /*!< device IN endpoint-x transmit FIFO status register */
+
+#define USB_PWRCLKCTL             REG32(((USBX) + 0x0E00U))               /*!< power and clock register */
+
+#define USB_FIFO(x)               (&REG32(((USBX) + LOCATE_FIFO(x))))     /*!< FIFO memory */
+
+/* global OTG control and status register bits definitions */
+#define GOTGCS_BSV                BIT(19)             /*!< B-Session Valid */
+#define GOTGCS_ASV                BIT(18)             /*!< A-session valid */
+#define GOTGCS_DI                 BIT(17)             /*!< debounce interval */
+#define GOTGCS_CIDPS              BIT(16)             /*!< id pin status */
+#define GOTGCS_DHNPEN             BIT(11)             /*!< device HNP enable */
+#define GOTGCS_HHNPEN             BIT(10)             /*!< host HNP enable */
+#define GOTGCS_HNPREQ             BIT(9)              /*!< HNP request */
+#define GOTGCS_HNPS               BIT(8)              /*!< HNP successes */
+#define GOTGCS_SRPREQ             BIT(1)              /*!< SRP request */
+#define GOTGCS_SRPS               BIT(0)              /*!< SRP successes */
+
+/* global OTG interrupt flag register bits definitions */
+#define GOTGINTF_DF               BIT(19)             /*!< debounce finish */
+#define GOTGINTF_ADTO             BIT(18)             /*!< A-device timeout */
+#define GOTGINTF_HNPDET           BIT(17)             /*!< host negotiation request detected */
+#define GOTGINTF_HNPEND           BIT(9)              /*!< HNP end */
+#define GOTGINTF_SRPEND           BIT(8)              /*!< SRP end */
+#define GOTGINTF_SESEND           BIT(2)              /*!< session end */
+
+/* global AHB control and status register bits definitions */
+#define GAHBCS_PTXFTH             BIT(8)              /*!< periodic Tx FIFO threshold */
+#define GAHBCS_TXFTH              BIT(7)              /*!< tx FIFO threshold */
+#define GAHBCS_DMAEN              BIT(5)              /*!< DMA function Enable */
+#define GAHBCS_BURST              BITS(1, 4)          /*!< the AHB burst type used by DMA */
+#define GAHBCS_GINTEN             BIT(0)              /*!< global interrupt enable */
+
+/* global USB control and status register bits definitions */
+#define GUSBCS_FDM                BIT(30)             /*!< force device mode */
+#define GUSBCS_FHM                BIT(29)             /*!< force host mode */
+#define GUSBCS_ULPIEOI            BIT(21)             /*!< ULPI external over-current indicator */
+#define GUSBCS_ULPIEVD            BIT(20)             /*!< ULPI external VBUS driver */
+#define GUSBCS_UTT                BITS(10, 13)        /*!< USB turnaround time */
+#define GUSBCS_HNPCEN             BIT(9)              /*!< HNP capability enable */
+#define GUSBCS_SRPCEN             BIT(8)              /*!< SRP capability enable */
+#define GUSBCS_EMBPHY             BIT(6)              /*!< embedded PHY selected */
+#define GUSBCS_TOC                BITS(0, 2)          /*!< timeout calibration */
+
+/* global reset control register bits definitions */
+#define GRSTCTL_DMAIDL            BIT(31)             /*!< DMA idle state */
+#define GRSTCTL_DMABSY            BIT(30)             /*!< DMA busy */
+#define GRSTCTL_TXFNUM            BITS(6, 10)         /*!< tx FIFO number */
+#define GRSTCTL_TXFF              BIT(5)              /*!< tx FIFO flush */
+#define GRSTCTL_RXFF              BIT(4)              /*!< rx FIFO flush */
+#define GRSTCTL_HFCRST            BIT(2)              /*!< host frame counter reset */
+#define GRSTCTL_HCSRST            BIT(1)              /*!< HCLK soft reset */
+#define GRSTCTL_CSRST             BIT(0)              /*!< core soft reset */
+
+/* global interrupt flag register bits definitions */
+#define GINTF_WKUPIF              BIT(31)             /*!< wakeup interrupt flag */
+#define GINTF_SESIF               BIT(30)             /*!< session interrupt flag */
+#define GINTF_DISCIF              BIT(29)             /*!< disconnect interrupt flag */
+#define GINTF_IDPSC               BIT(28)             /*!< id pin status change */
+#define GINTF_PTXFEIF             BIT(26)             /*!< periodic tx FIFO empty interrupt flag */
+#define GINTF_HCIF                BIT(25)             /*!< host channels interrupt flag */
+#define GINTF_HPIF                BIT(24)             /*!< host port interrupt flag */
+#define GINTF_PXNCIF              BIT(21)             /*!< periodic transfer not complete interrupt flag */
+#define GINTF_ISOONCIF            BIT(21)             /*!< isochronous OUT transfer not complete interrupt flag */
+#define GINTF_ISOINCIF            BIT(20)             /*!< isochronous IN transfer not complete interrupt flag */
+#define GINTF_OEPIF               BIT(19)             /*!< OUT endpoint interrupt flag */
+#define GINTF_IEPIF               BIT(18)             /*!< IN endpoint interrupt flag */
+#define GINTF_EOPFIF              BIT(15)             /*!< end of periodic frame interrupt flag */
+#define GINTF_ISOOPDIF            BIT(14)             /*!< isochronous OUT packet dropped interrupt flag */
+#define GINTF_ENUMFIF             BIT(13)             /*!< enumeration finished */
+#define GINTF_RST                 BIT(12)             /*!< USB reset */
+#define GINTF_SP                  BIT(11)             /*!< USB suspend */
+#define GINTF_ESP                 BIT(10)             /*!< early suspend */
+#define GINTF_GONAK               BIT(7)              /*!< global OUT NAK effective */
+#define GINTF_GNPINAK             BIT(6)              /*!< global IN non-periodic NAK effective */
+#define GINTF_NPTXFEIF            BIT(5)              /*!< non-periodic tx FIFO empty interrupt flag */
+#define GINTF_RXFNEIF             BIT(4)              /*!< rx FIFO non-empty interrupt flag */
+#define GINTF_SOF                 BIT(3)              /*!< start of frame */
+#define GINTF_OTGIF               BIT(2)              /*!< OTG interrupt flag */
+#define GINTF_MFIF                BIT(1)              /*!< mode fault interrupt flag */
+#define GINTF_COPM                BIT(0)              /*!< current operation mode */
+
+/* global interrupt enable register bits definitions */
+#define GINTEN_WKUPIE             BIT(31)             /*!< wakeup interrupt enable */
+#define GINTEN_SESIE              BIT(30)             /*!< session interrupt enable */
+#define GINTEN_DISCIE             BIT(29)             /*!< disconnect interrupt enable */
+#define GINTEN_IDPSCIE            BIT(28)             /*!< id pin status change interrupt enable */
+#define GINTEN_PTXFEIE            BIT(26)             /*!< periodic tx FIFO empty interrupt enable */
+#define GINTEN_HCIE               BIT(25)             /*!< host channels interrupt enable */
+#define GINTEN_HPIE               BIT(24)             /*!< host port interrupt enable */
+#define GINTEN_IPXIE              BIT(21)             /*!< periodic transfer not complete interrupt enable */
+#define GINTEN_ISOONCIE           BIT(21)             /*!< isochronous OUT transfer not complete interrupt enable */
+#define GINTEN_ISOINCIE           BIT(20)             /*!< isochronous IN transfer not complete interrupt enable */
+#define GINTEN_OEPIE              BIT(19)             /*!< OUT endpoints interrupt enable */
+#define GINTEN_IEPIE              BIT(18)             /*!< IN endpoints interrupt enable */
+#define GINTEN_EOPFIE             BIT(15)             /*!< end of periodic frame interrupt enable */
+#define GINTEN_ISOOPDIE           BIT(14)             /*!< isochronous OUT packet dropped interrupt enable */
+#define GINTEN_ENUMFIE            BIT(13)             /*!< enumeration finish enable */
+#define GINTEN_RSTIE              BIT(12)             /*!< USB reset interrupt enable */
+#define GINTEN_SPIE               BIT(11)             /*!< USB suspend interrupt enable */
+#define GINTEN_ESPIE              BIT(10)             /*!< early suspend interrupt enable */
+#define GINTEN_GONAKIE            BIT(7)              /*!< global OUT NAK effective interrupt enable */
+#define GINTEN_GNPINAKIE          BIT(6)              /*!< global non-periodic IN NAK effective interrupt enable */
+#define GINTEN_NPTXFEIE           BIT(5)              /*!< non-periodic Tx FIFO empty interrupt enable */
+#define GINTEN_RXFNEIE            BIT(4)              /*!< receive FIFO non-empty interrupt enable */
+#define GINTEN_SOFIE              BIT(3)              /*!< start of frame interrupt enable */
+#define GINTEN_OTGIE              BIT(2)              /*!< OTG interrupt enable */
+#define GINTEN_MFIE               BIT(1)              /*!< mode fault interrupt enable */
+
+/* global receive status debug read register bits definitions */
+#define GRSTATR_RPCKST            BITS(17, 20)        /*!< received packet status */
+#define GRSTATR_DPID              BITS(15, 16)        /*!< data PID */
+#define GRSTATR_BCOUNT            BITS(4, 14)         /*!< byte count */
+#define GRSTATR_CNUM              BITS(0, 3)          /*!< channel number */
+
+/* global status read and pop register bits definitions */
+#define GRSTATP_RPCKST            BITS(17, 20)        /*!< received packet status */
+#define GRSTATP_DPID              BITS(15, 16)        /*!< data PID */
+#define GRSTATP_BCOUNT            BITS(4, 14)         /*!< byte count */
+#define GRSTATP_EPNUM             BITS(0, 3)          /*!< endpoint number */
+
+/* global receive FIFO length register bits definitions */
+#define GRFLEN_RXFD               BITS(0, 15)         /*!< rx FIFO depth */
+
+/* host non-periodic transmit FIFO length register bits definitions */
+#define HNPTFLEN_HNPTXFD          BITS(16, 31)        /*!< non-periodic Tx FIFO depth */
+#define HNPTFLEN_HNPTXRSAR        BITS(0, 15)         /*!< non-periodic Tx RAM start address */
+
+/* IN endpoint 0 transmit FIFO length register bits definitions */
+#define DIEP0TFLEN_IEP0TXFD       BITS(16, 31)        /*!< IN Endpoint 0 Tx FIFO depth */
+#define DIEP0TFLEN_IEP0TXRSAR     BITS(0, 15)         /*!< IN Endpoint 0 TX RAM start address */
+
+/* host non-periodic transmit FIFO/queue status register bits definitions */
+#define HNPTFQSTAT_NPTXRQTOP      BITS(24, 30)        /*!< top entry of the non-periodic Tx request queue */
+#define HNPTFQSTAT_NPTXRQS        BITS(16, 23)        /*!< non-periodic Tx request queue space */
+#define HNPTFQSTAT_NPTXFS         BITS(0, 15)         /*!< non-periodic Tx FIFO space */
+#define HNPTFQSTAT_CNUM           BITS(27, 30)        /*!< channel number*/
+#define HNPTFQSTAT_EPNUM          BITS(27, 30)        /*!< endpoint number */
+#define HNPTFQSTAT_TYPE           BITS(25, 26)        /*!< token type */
+#define HNPTFQSTAT_TMF            BIT(24)             /*!< terminate flag */
+
+/* global core configuration register bits definitions */
+#define GCCFG_VBUSIG              BIT(21)             /*!< vbus ignored */
+#define GCCFG_SOFOEN              BIT(20)             /*!< SOF output enable */
+#define GCCFG_VBUSBCEN            BIT(19)             /*!< the VBUS B-device comparer enable */
+#define GCCFG_VBUSACEN            BIT(18)             /*!< the VBUS A-device comparer enable */
+#define GCCFG_PWRON               BIT(16)             /*!< power on */
+
+/* core ID register bits definitions */
+#define CID_CID                   BITS(0, 31)         /*!< core ID */
+
+/* host periodic transmit FIFO length register bits definitions */
+#define HPTFLEN_HPTXFD            BITS(16, 31)        /*!< host periodic Tx FIFO depth */
+#define HPTFLEN_HPTXFSAR          BITS(0, 15)         /*!< host periodic Tx RAM start address */
+
+/* device IN endpoint transmit FIFO length register bits definitions */
+#define DIEPTFLEN_IEPTXFD         BITS(16, 31)        /*!< IN endpoint Tx FIFO x depth */
+#define DIEPTFLEN_IEPTXRSAR       BITS(0, 15)         /*!< IN endpoint FIFOx Tx x RAM start address */
+
+/* host control register bits definitions */
+#define HCTL_SPDFSLS              BIT(2)              /*!< speed limited to FS and LS */
+#define HCTL_CLKSEL               BITS(0, 1)          /*!< clock select for USB clock */
+
+/* host frame interval register bits definitions */
+#define HFT_FRI                   BITS(0, 15)         /*!< frame interval */
+
+/* host frame information remaining register bits definitions */
+#define HFINFR_FRT                BITS(16, 31)        /*!< frame remaining time */
+#define HFINFR_FRNUM              BITS(0, 15)         /*!< frame number */
+
+/* host periodic transmit FIFO/queue status register bits definitions */
+#define HPTFQSTAT_PTXREQT         BITS(24, 31)        /*!< top entry of the periodic Tx request queue */
+#define HPTFQSTAT_PTXREQS         BITS(16, 23)        /*!< periodic Tx request queue space */
+#define HPTFQSTAT_PTXFS           BITS(0, 15)         /*!< periodic Tx FIFO space */
+#define HPTFQSTAT_OEFRM           BIT(31)             /*!< odd/eveb frame */
+#define HPTFQSTAT_CNUM            BITS(27, 30)        /*!< channel number */
+#define HPTFQSTAT_EPNUM           BITS(27, 30)        /*!< endpoint number */
+#define HPTFQSTAT_TYPE            BITS(25, 26)        /*!< token type */
+#define HPTFQSTAT_TMF             BIT(24)             /*!< terminate flag */
+
+/* host all channels interrupt register bits definitions */
+#define HACHINT_HACHINT           BITS(0, 11)         /*!< host all channel interrupts */
+
+/* host all channels interrupt enable register bits definitions */
+#define HACHINTEN_CINTEN          BITS(0, 11)         /*!< channel interrupt enable */
+
+/* host port control and status register bits definitions */
+#define HPCS_PS                   BITS(17, 18)        /*!< port speed */
+#define HPCS_PP                   BIT(12)             /*!< port power */
+#define HPCS_PLST                 BITS(10, 11)        /*!< port line status */
+#define HPCS_PRST                 BIT(8)              /*!< port reset */
+#define HPCS_PSP                  BIT(7)              /*!< port suspend */
+#define HPCS_PREM                 BIT(6)              /*!< port resume */
+#define HPCS_PEDC                 BIT(3)              /*!< port enable/disable change */
+#define HPCS_PE                   BIT(2)              /*!< port enable */
+#define HPCS_PCD                  BIT(1)              /*!< port connect detected */
+#define HPCS_PCST                 BIT(0)              /*!< port connect status */
+
+/* host channel-x control register bits definitions */
+#define HCHCTL_CEN                BIT(31)             /*!< channel enable */
+#define HCHCTL_CDIS               BIT(30)             /*!< channel disable */
+#define HCHCTL_ODDFRM             BIT(29)             /*!< odd frame */
+#define HCHCTL_DAR                BITS(22, 28)        /*!< device address */
+#define HCHCTL_MPC                BITS(20, 21)        /*!< multiple packet count */
+#define HCHCTL_EPTYPE             BITS(18, 19)        /*!< endpoint type */
+#define HCHCTL_LSD                BIT(17)             /*!< low-speed device */
+#define HCHCTL_EPDIR              BIT(15)             /*!< endpoint direction */
+#define HCHCTL_EPNUM              BITS(11, 14)        /*!< endpoint number */
+#define HCHCTL_MPL                BITS(0, 10)         /*!< maximum packet length */
+
+/* host channel-x split transaction register bits definitions */
+#define HCHSTCTL_SPLEN            BIT(31)             /*!< enable high-speed split transaction */
+#define HCHSTCTL_CSPLT            BIT(16)             /*!< complete-split enable */
+#define HCHSTCTL_ISOPCE           BITS(14, 15)        /*!< isochronous OUT payload continuation encoding */
+#define HCHSTCTL_HADDR            BITS(7, 13)         /*!< HUB address */
+#define HCHSTCTL_PADDR            BITS(0, 6)          /*!< port address */
+
+/* host channel-x interrupt flag register bits definitions */
+#define HCHINTF_DTER              BIT(10)             /*!< data toggle error */
+#define HCHINTF_REQOVR            BIT(9)              /*!< request queue overrun */
+#define HCHINTF_BBER              BIT(8)              /*!< babble error */
+#define HCHINTF_USBER             BIT(7)              /*!< USB bus Error */
+#define HCHINTF_NYET              BIT(6)              /*!< NYET */
+#define HCHINTF_ACK               BIT(5)              /*!< ACK */
+#define HCHINTF_NAK               BIT(4)              /*!< NAK */
+#define HCHINTF_STALL             BIT(3)              /*!< STALL */
+#define HCHINTF_DMAER             BIT(2)              /*!< DMA error */
+#define HCHINTF_CH                BIT(1)              /*!< channel halted */
+#define HCHINTF_TF                BIT(0)              /*!< transfer finished */
+
+/* host channel-x interrupt enable register bits definitions */
+#define HCHINTEN_DTERIE           BIT(10)             /*!< data toggle error interrupt enable */
+#define HCHINTEN_REQOVRIE         BIT(9)              /*!< request queue overrun interrupt enable */
+#define HCHINTEN_BBERIE           BIT(8)              /*!< babble error interrupt enable */
+#define HCHINTEN_USBERIE          BIT(7)              /*!< USB bus error interrupt enable */
+#define HCHINTEN_NYETIE           BIT(6)              /*!< NYET interrupt enable */
+#define HCHINTEN_ACKIE            BIT(5)              /*!< ACK interrupt enable */
+#define HCHINTEN_NAKIE            BIT(4)              /*!< NAK interrupt enable */
+#define HCHINTEN_STALLIE          BIT(3)              /*!< STALL interrupt enable */
+#define HCHINTEN_DMAERIE          BIT(2)              /*!< DMA error interrupt enable */
+#define HCHINTEN_CHIE             BIT(1)              /*!< channel halted interrupt enable */
+#define HCHINTEN_TFIE             BIT(0)              /*!< transfer finished interrupt enable */
+
+/* host channel-x transfer length register bits definitions */
+#define HCHLEN_PING               BIT(31)             /*!< PING token request */
+#define HCHLEN_DPID               BITS(29, 30)        /*!< data PID */
+#define HCHLEN_PCNT               BITS(19, 28)        /*!< packet count */
+#define HCHLEN_TLEN               BITS(0, 18)         /*!< transfer length */
+
+/* host channel-x DMA address register bits definitions */
+#define HCHDMAADDR_DMAADDR        BITS(0, 31)         /*!< DMA address */
+
+/* device control and status registers */
+/* device configuration registers bits definitions */
+#define DCFG_EOPFT                BITS(11, 12)        /*!< end of periodic frame time */
+#define DCFG_DAR                  BITS(4, 10)         /*!< device address */
+#define DCFG_NZLSOH               BIT(2)              /*!< non-zero-length status OUT handshake */
+#define DCFG_DS                   BITS(0, 1)          /*!< device speed */
+
+/* device control registers bits definitions */
+#define DCTL_POIF                 BIT(11)             /*!< power-on initialization finished */
+#define DCTL_CGONAK               BIT(10)             /*!< clear global OUT NAK */
+#define DCTL_SGONAK               BIT(9)              /*!< set global OUT NAK */
+#define DCTL_CGINAK               BIT(8)              /*!< clear global IN NAK */
+#define DCTL_SGINAK               BIT(7)              /*!< set global IN NAK */
+#define DCTL_GONS                 BIT(3)              /*!< global OUT NAK status */
+#define DCTL_GINS                 BIT(2)              /*!< global IN NAK status */
+#define DCTL_SD                   BIT(1)              /*!< soft disconnect */
+#define DCTL_RWKUP                BIT(0)              /*!< remote wakeup */
+
+/* device status registers bits definitions */
+#define DSTAT_FNRSOF              BITS(8, 21)         /*!< the frame number of the received SOF. */
+#define DSTAT_ES                  BITS(1, 2)          /*!< enumerated speed */
+#define DSTAT_SPST                BIT(0)              /*!< suspend status */
+
+/* device IN endpoint common interrupt enable registers bits definitions */
+#define DIEPINTEN_NAKEN           BIT(13)             /*!< NAK handshake sent by USBHS interrupt enable bit */
+#define DIEPINTEN_TXFEEN          BIT(7)              /*!< transmit FIFO empty interrupt enable bit */
+#define DIEPINTEN_IEPNEEN         BIT(6)              /*!< IN endpoint NAK effective interrupt enable bit */
+#define DIEPINTEN_EPTXFUDEN       BIT(4)              /*!< endpoint Tx FIFO underrun interrupt enable bit */
+#define DIEPINTEN_CITOEN          BIT(3)              /*!< control In Timeout interrupt enable bit */
+#define DIEPINTEN_EPDISEN         BIT(1)              /*!< endpoint disabled interrupt enable bit */
+#define DIEPINTEN_TFEN            BIT(0)              /*!< transfer finished interrupt enable bit */ 
+
+/* device OUT endpoint common interrupt enable registers bits definitions */
+#define DOEPINTEN_NYETEN          BIT(14)             /*!< NYET handshake is sent interrupt enable bit */
+#define DOEPINTEN_BTBSTPEN        BIT(6)              /*!< back-to-back SETUP packets interrupt enable bit */
+#define DOEPINTEN_EPRXFOVREN      BIT(4)              /*!< endpoint Rx FIFO overrun interrupt enable bit */
+#define DOEPINTEN_STPFEN          BIT(3)              /*!< SETUP phase finished interrupt enable bit */
+#define DOEPINTEN_EPDISEN         BIT(1)              /*!< endpoint disabled interrupt enable bit */
+#define DOEPINTEN_TFEN            BIT(0)              /*!< transfer finished interrupt enable bit */
+
+/* device all endpoints interrupt registers bits definitions */
+#define DAEPINT_OEPITB            BITS(16, 21)        /*!< device all OUT endpoint interrupt bits */
+#define DAEPINT_IEPITB            BITS(0, 5)          /*!< device all IN endpoint interrupt bits */
+
+/* device all endpoints interrupt enable registers bits definitions */
+#define DAEPINTEN_OEPIE           BITS(16, 21)        /*!< OUT endpoint interrupt enable */
+#define DAEPINTEN_IEPIE           BITS(0, 3)          /*!< IN endpoint interrupt enable */
+
+/* device Vbus discharge time registers bits definitions */
+#define DVBUSDT_DVBUSDT           BITS(0, 15)         /*!< device VBUS discharge time */
+
+/* device Vbus pulsing time registers bits definitions */
+#define DVBUSPT_DVBUSPT           BITS(0, 11)         /*!< device VBUS pulsing time */
+
+/* device IN endpoint FIFO empty interrupt enable register bits definitions */
+#define DIEPFEINTEN_IEPTXFEIE     BITS(0, 5)          /*!< IN endpoint Tx FIFO empty interrupt enable bits */
+
+/* device endpoint 1 interrupt register bits definitions */
+#define DEP1INT_OEP1INT           BIT(17)             /*!< OUT Endpoint 1 interrupt */
+#define DEP1INT_IEP1INT           BIT(1)              /*!< IN Endpoint 1 interrupt */
+
+/* device endpoint 1 interrupt register enable bits definitions */
+#define DEP1INTEN_OEP1INTEN       BIT(17)             /*!< OUT Endpoint 1 interrupt enable */
+#define DEP1INTEN_IEP1INTEN       BIT(1)              /*!< IN Endpoint 1 interrupt enable */
+
+/* device IN endpoint 1 interrupt enable register bits definitions */
+#define DIEP1INTEN_NAKEN          BIT(13)             /*!< NAK handshake sent by USBHS interrupt enable bit */
+#define DIEP1INTEN_IEPNEEN        BIT(6)              /*!< IN endpoint NAK effective interrupt enable bit */
+#define DIEP1INTEN_EPTXFUDEN      BIT(4)              /*!< endpoint Tx FIFO underrun interrupt enable bit */
+#define DIEP1INTEN_CITOEN         BIT(3)              /*!< control In Timeout interrupt enable bit */
+#define DIEP1INTEN_EPDISEN        BIT(1)              /*!< endpoint disabled interrupt enable bit */
+#define DIEP1INTEN_TFEN           BIT(0)              /*!< transfer finished interrupt enable bit */
+
+/* device OUT endpoint 1 interrupt enable register bits definitions */
+#define DOEP1INTEN_NYETEN         BIT(14)             /*!< NYET handshake is sent interrupt enable bit */
+#define DOEP1INTEN_BTBSTPEN       BIT(6)              /*!< back-to-back SETUP packets interrupt enable bit */
+#define DOEP1INTEN_EPRXOVREN      BIT(4)              /*!< endpoint Rx FIFO over run interrupt enable bit */
+#define DOEP1INTEN_STPFEN         BIT(3)              /*!< SETUP phase finished interrupt enable bit */
+#define DOEP1INTEN_EPDISEN        BIT(1)              /*!< endpoint disabled interrupt enable bit */
+#define DOEP1INTEN_TFEN           BIT(0)              /*!< back-to-back SETUP packets interrupt enable bit */
+
+/* device IN endpoint 0 control register bits definitions */
+#define DIEP0CTL_EPEN             BIT(31)             /*!< endpoint enable */
+#define DIEP0CTL_EPD              BIT(30)             /*!< endpoint disable */
+#define DIEP0CTL_SNAK             BIT(27)             /*!< set NAK */
+#define DIEP0CTL_CNAK             BIT(26)             /*!< clear NAK */
+#define DIEP0CTL_TXFNUM           BITS(22, 25)        /*!< tx FIFO number */
+#define DIEP0CTL_STALL            BIT(21)             /*!< STALL handshake */
+#define DIEP0CTL_EPTYPE           BITS(18, 19)        /*!< endpoint type */
+#define DIEP0CTL_NAKS             BIT(17)             /*!< NAK status */
+#define DIEP0CTL_EPACT            BIT(15)             /*!< endpoint active */
+#define DIEP0CTL_MPL              BITS(0, 1)          /*!< maximum packet length */
+
+/* device IN endpoint x control register bits definitions */
+#define DIEPCTL_EPEN              BIT(31)             /*!< endpoint enable */
+#define DIEPCTL_EPD               BIT(30)             /*!< endpoint disable */
+#define DIEPCTL_SODDFRM           BIT(29)             /*!< set odd frame */
+#define DIEPCTL_SD1PID            BIT(29)             /*!< set DATA1 PID */
+#define DIEPCTL_SEVNFRM           BIT(28)             /*!< set even frame */
+#define DIEPCTL_SD0PID            BIT(28)             /*!< set DATA0 PID */
+#define DIEPCTL_SNAK              BIT(27)             /*!< set NAK */
+#define DIEPCTL_CNAK              BIT(26)             /*!< clear NAK */
+#define DIEPCTL_TXFNUM            BITS(22, 25)        /*!< tx FIFO number */
+#define DIEPCTL_STALL             BIT(21)             /*!< STALL handshake */
+#define DIEPCTL_EPTYPE            BITS(18, 19)        /*!< endpoint type */
+#define DIEPCTL_NAKS              BIT(17)             /*!< NAK status */
+#define DIEPCTL_EOFRM             BIT(16)             /*!< even/odd frame */
+#define DIEPCTL_DPID              BIT(16)             /*!< endpoint data PID */
+#define DIEPCTL_EPACT             BIT(15)             /*!< endpoint active */
+#define DIEPCTL_MPL               BITS(0, 10)         /*!< maximum packet length */
+
+/* device OUT endpoint 0 control register bits definitions */
+#define DOEP0CTL_EPEN             BIT(31)             /*!< endpoint enable */
+#define DOEP0CTL_EPD              BIT(30)             /*!< endpoint disable */
+#define DOEP0CTL_SNAK             BIT(27)             /*!< set NAK */
+#define DOEP0CTL_CNAK             BIT(26)             /*!< clear NAK */
+#define DOEP0CTL_STALL            BIT(21)             /*!< STALL handshake */
+#define DOEP0CTL_SNOOP            BIT(20)             /*!< snoop mode */
+#define DOEP0CTL_EPTYPE           BITS(18, 19)        /*!< endpoint type */
+#define DOEP0CTL_NAKS             BIT(17)             /*!< NAK status */
+#define DOEP0CTL_EPACT            BIT(15)             /*!< endpoint active */
+#define DOEP0CTL_MPL              BITS(0, 1)          /*!< maximum packet length */
+
+/* device OUT endpoint-x control register bits definitions */
+#define DOEPCTL_EPEN              BIT(31)             /*!< endpoint enable */
+#define DOEPCTL_EPD               BIT(30)             /*!< endpoint disable */
+#define DOEPCTL_SODDFRM           BIT(29)             /*!< set odd frame */
+#define DOEPCTL_SD1PID            BIT(29)             /*!< set DATA1 PID */
+#define DOEPCTL_SEVNFRM           BIT(28)             /*!< set even frame */
+#define DOEPCTL_SD0PID            BIT(28)             /*!< set DATA0 PID */
+#define DOEPCTL_SNAK              BIT(27)             /*!< set NAK */
+#define DOEPCTL_CNAK              BIT(26)             /*!< clear NAK */
+#define DOEPCTL_STALL             BIT(21)             /*!< STALL handshake */
+#define DOEPCTL_SNOOP             BIT(20)             /*!< snoop mode */
+#define DOEPCTL_EPTYPE            BITS(18, 19)        /*!< endpoint type */
+#define DOEPCTL_NAKS              BIT(17)             /*!< NAK status */
+#define DOEPCTL_EOFRM             BIT(16)             /*!< even/odd frame */
+#define DOEPCTL_DPID              BIT(16)             /*!< endpoint data PID */
+#define DOEPCTL_EPACT             BIT(15)             /*!< endpoint active */
+#define DOEPCTL_MPL               BITS(0, 10)         /*!< maximum packet length */
+
+/* device IN endpoint-x interrupt flag register bits definitions */
+#define DIEPINTF_NAK              BIT(13)             /*!< NAK handshake sent by USBHS */
+#define DIEPINTF_TXFE             BIT(7)              /*!< transmit FIFO empty */
+#define DIEPINTF_IEPNE            BIT(6)              /*!< IN endpoint NAK effective */
+#define DIEPINTF_EPTXFUD          BIT(4)              /*!< endpoint Tx FIFO underrun */
+#define DIEPINTF_CITO             BIT(3)              /*!< control In Timeout interrupt */
+#define DIEPINTF_EPDIS            BIT(1)              /*!< endpoint disabled */
+#define DIEPINTF_TF               BIT(0)              /*!< transfer finished */
+
+/* device OUT endpoint-x interrupt flag register bits definitions */
+#define DOEPINTF_NYET             BIT(14)             /*!< NYET handshake is sent */
+#define DOEPINTF_BTBSTP           BIT(6)              /*!< back-to-back SETUP packets */
+#define DOEPINTF_EPRXFOVR         BIT(4)              /*!< endpoint Rx FIFO overrun */
+#define DOEPINTF_STPF             BIT(3)              /*!< SETUP phase finished */
+#define DOEPINTF_EPDIS            BIT(1)              /*!< endpoint disabled */
+#define DOEPINTF_TF               BIT(0)              /*!< transfer finished */
+
+/* device IN endpoint 0 transfer length register bits definitions */
+#define DIEP0LEN_PCNT             BITS(19, 20)        /*!< packet count */
+#define DIEP0LEN_TLEN             BITS(0, 6)          /*!< transfer length */
+
+/* device OUT endpoint 0 transfer length register bits definitions */
+#define DOEP0LEN_STPCNT           BITS(29, 30)        /*!< SETUP packet count */
+#define DOEP0LEN_PCNT             BIT(19)             /*!< packet count */
+#define DOEP0LEN_TLEN             BITS(0, 6)          /*!< transfer length */
+
+/* device IN endpoint-x transfer length register bits definitions */
+#define DIEPLEN_MCNT              BITS(29, 30)        /*!< multi count */
+#define DIEPLEN_PCNT              BITS(19, 28)        /*!< packet count */
+#define DIEPLEN_TLEN              BITS(0, 18)         /*!< transfer length */
+
+/* device OUT endpoint-x transfer length register bits definitions */
+#define DOEPLEN_RXDPID            BITS(29, 30)        /*!< received data PID */
+#define DOEPLEN_STPCNT            BITS(29, 30)        /*!< SETUP packet count */
+#define DOEPLEN_PCNT              BITS(19, 28)        /*!< packet count */
+#define DOEPLEN_TLEN              BITS(0, 18)         /*!< transfer length */
+
+/* device IN endpoint-x DMA address register bits definitions */
+#define DIEPDMAADDR_DMAADDR       BITS(0, 31)         /*!< DMA address */
+
+/* device OUT endpoint-x DMA address register bits definitions */
+#define DOEPDMAADDR_DMAADDR       BITS(0, 31)         /*!< DMA address */
+
+/* device IN endpoint-x transmit FIFO status register bits definitions */
+#define DIEPTFSTAT_IEPTFS         BITS(0, 15)         /*!< IN endpoint¡¯s Tx FIFO space remaining */
+
+/* USB power and clock registers bits definition */
+#define PWRCLKCTL_SHCLK           BIT(1)              /*!< stop HCLK */
+#define PWRCLKCTL_SUCLK           BIT(0)              /*!< stop the USB clock */
+
+/* register options defines */
+#define DCFG_DEVSPEED(regval)     (DCFG_DS & ((regval) << 0U))      /*!< device speed configuration */
+
+#define USB_SPEED_EXP_HIGH        DCFG_DEVSPEED(0U)                 /*!< device external PHY high speed */
+#define USB_SPEED_EXP_FULL        DCFG_DEVSPEED(1U)                 /*!< device external PHY full speed */
+#define USB_SPEED_INP_FULL        DCFG_DEVSPEED(3U)                 /*!< device internal PHY full speed */
+
+#define GAHBCS_TFEL(regval)       (GAHBCS_TXFTH & ((regval) << 7U)) /*!< device speed configuration */
+
+#define TXFIFO_EMPTY_HALF         GAHBCS_TFEL(0U)                   /*!< Tx FIFO half empty */
+#define TXFIFO_EMPTY              GAHBCS_TFEL(1U)                   /*!< Tx FIFO completely empty */
+
+#define GAHBCS_DMAINCR(regval)    (GAHBCS_BURST & ((regval) << 1U)) /*!< AHB burst type used by DMA*/
+
+#define DMA_INCR0                 GAHBCS_DMAINCR(0U)                /*!< single burst type used by DMA*/
+#define DMA_INCR1                 GAHBCS_DMAINCR(1U)                /*!< 4-beat incrementing burst type used by DMA*/
+#define DMA_INCR4                 GAHBCS_DMAINCR(3U)                /*!< 8-beat incrementing burst type used by DMA*/
+#define DMA_INCR8                 GAHBCS_DMAINCR(5U)                /*!< 16-beat incrementing burst type used by DMA*/
+#define DMA_INCR16                GAHBCS_DMAINCR(7U)                /*!< 32-beat incrementing burst type used by DMA*/
+
+#define DCFG_PFRI(regval)         (DCFG_EOPFT & ((regval) << 11U))  /*!< end of periodic frame time configuration */
+
+#define FRAME_INTERVAL_80         DCFG_PFRI(0U)                     /*!< 80% of the frame time */
+#define FRAME_INTERVAL_85         DCFG_PFRI(1U)                     /*!< 85% of the frame time */
+#define FRAME_INTERVAL_90         DCFG_PFRI(2U)                     /*!< 90% of the frame time */
+#define FRAME_INTERVAL_95         DCFG_PFRI(3U)                     /*!< 95% of the frame time */
+
+#define DEP0CTL_MPL(regval)       (DOEP0CTL_MPL & ((regval) << 0U))   /*!< maximum packet length configuration */
+
+#define EP0MPL_64                 DEP0CTL_MPL(0U)                   /*!< maximum packet length 64 bytes */
+#define EP0MPL_32                 DEP0CTL_MPL(1U)                   /*!< maximum packet length 32 bytes */
+#define EP0MPL_16                 DEP0CTL_MPL(2U)                   /*!< maximum packet length 16 bytes */
+#define EP0MPL_8                  DEP0CTL_MPL(3U)                   /*!< maximum packet length 8 bytes */
+
+/* endpoints address */
+
+/* first bit is direction(0 for Rx and 1 for Tx) */
+#define EP0_OUT                   ((uint8_t)0x00U)                  /*!< endpoint out 0 */
+#define EP0_IN                    ((uint8_t)0x80U)                  /*!< endpoint in 0 */
+#define EP1_OUT                   ((uint8_t)0x01U)                  /*!< endpoint out 1 */
+#define EP1_IN                    ((uint8_t)0x81U)                  /*!< endpoint in 1 */
+#define EP2_OUT                   ((uint8_t)0x02U)                  /*!< endpoint out 2 */
+#define EP2_IN                    ((uint8_t)0x82U)                  /*!< endpoint in 2 */
+#define EP3_OUT                   ((uint8_t)0x03U)                  /*!< endpoint out 3 */
+#define EP3_IN                    ((uint8_t)0x83U)                  /*!< endpoint in 3 */
+
+/* enable global interrupt */
+#define USB_GLOBAL_INT_ENABLE()       (USB_GAHBCS |= GAHBCS_GINTEN)
+
+/* disable global interrupt */
+#define USB_GLOBAL_INT_DISABLE()      (USB_GAHBCS &= ~GAHBCS_GINTEN)
+
+/* get current operation mode */
+#define USB_CURRENT_MODE_GET()        (USB_GINTF & GINTF_COPM)
+
+/* read global interrupt flag */
+#define USB_CORE_INTR_READ(x) \
+do { \
+  uint32_t global_intf = USB_GINTF; \
+  (x) = global_intf & USB_GINTEN; \
+} while(0)
+
+/* read global interrupt flag */
+#define USB_DAOEP_INTR_READ(x) \
+do { \
+  uint32_t dev_all_ep_inten = USB_DAEPINTEN; \
+  uint32_t dev_all_ep_int = USB_DAEPINT; \
+  uint32_t out_ep_intb = DAEPINT_OEPITB;  \
+  (x) = (dev_all_ep_inten & dev_all_ep_int & out_ep_intb) >> 16; \
+} while(0)
+
+/* read out endpoint-x interrupt flag */
+#define USB_DOEP_INTR_READ(x, EpID) \
+do { \
+    uint32_t out_epintf = USB_DOEPxINTF(EpID); \
+    (x) = out_epintf & USB_DOEPINTEN; \
+} while(0) 
+
+/* read all in endpoint interrupt flag */
+#define USB_DAIEP_INTR_READ(x) \
+do { \
+  uint32_t dev_all_ep_inten = USB_DAEPINTEN; \
+  uint32_t dev_all_ep_int = USB_DAEPINT; \
+  uint32_t in_ep_intb = DAEPINT_IEPITB;  \
+  (x) = dev_all_ep_inten & dev_all_ep_int & in_ep_intb; \
+} while(0)
+
+
+/* read in endpoint-x interrupt flag */
+#define USB_DIEP_INTR_READ(x, EpID) \
+do { \
+    uint32_t dev_ep_intf = USB_DIEPxINTF(EpID); \
+    uint32_t dev_ep_fifoempty_intf = (((USB_DIEPFEINTEN >> (EpID)) & 0x1U) << 7U); \
+    uint32_t dev_inep_inten = USB_DIEPINTEN; \
+    (x) = dev_ep_intf & (dev_ep_fifoempty_intf | dev_inep_inten); \
+} while(0)
+
+/* generate remote wakup signal */
+#define USB_REMOTE_WAKEUP_SET()       (USB_DCTL |= DCTL_RWKUP)
+
+/* no remote wakup signal generate */
+#define USB_REMOTE_WAKEUP_RESET()     (USB_DCTL &= ~DCTL_RWKUP)
+
+/* generate soft disconnect */
+#define USB_SOFT_DISCONNECT_ENABLE()  (USB_DCTL |= DCTL_SD)
+
+/* no soft disconnect generate */
+#define USB_SOFT_DISCONNECT_DISABLE() (USB_DCTL &= ~DCTL_SD)
+
+/* set device address */
+#define USB_SET_DEVADDR(DevAddr)      (USB_DCFG |= (DevAddr) << 4U)
+
+/* check whether frame is even */
+#define USB_EVEN_FRAME()              (!(USB_HFINFR & 0x01U))
+
+/* read port status */
+#define USB_PORT_READ()               (USB_HPCS & (~HPCS_PE) & (~HPCS_PCD) & (~HPCS_PEDC))
+
+/* usb clock initialize */
+#define USB_FSLSCLOCK_INIT(ClockFreq) (USB_HCTL &= ~HCTL_CLKSEL | (ClockFreq))
+
+/* get usb current speed */
+#define USB_CURRENT_SPEED_GET()       ((USB_HPCS & HPCS_PS) >> 17)
+
+/* get usb current frame */
+#define USB_CURRENT_FRAME_GET()       (USB_HFINFR & 0xFFFFU)
+
+#endif /* USB_REGS_H */

+ 188 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_std.h

@@ -0,0 +1,188 @@
+/*!
+    \file  usb_std.h
+    \brief USB 2.0 standard defines
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USB_STD_H
+#define USB_STD_H
+
+#include "usb_conf.h"
+
+#define USB_DEV_QUALIFIER_DESC_LEN                     0x0AU       /*!< USB device qualifier descriptor length */
+#define USB_DEV_DESC_LEN                               0x12U       /*!< USB device descriptor length */
+#define USB_CFG_DESC_LEN                               0x09U       /*!< USB device configuration descriptor length */
+#define USB_IF_DESC_LEN                                0x09U       /*!< USB device interface descriptor length */
+#define USB_EP_DESC_LEN                                0x07U       /*!< USB device endpoint descriptor length */
+#define USB_OTG_DESC_LEN                               0x03U       /*!< USB device OTG descriptor length */
+
+/* bit 7 of bmRequestType: data phase transfer direction */
+#define USB_DIR_MASK                                   0x80U       /*!< USB transfer direction mask */
+#define USB_DIR_OUT                                    0x00U       /*!< USB transfer OUT direction */
+#define USB_DIR_IN                                     0x80U       /*!< USB transfer IN direction */
+
+/* bit 6..5 of bmRequestType: request type */
+#define USB_STANDARD_REQ                               0x00U       /*!< USB standard request */
+#define USB_CLASS_REQ                                  0x20U       /*!< USB class request */
+#define USB_VENDOR_REQ                                 0x40U       /*!< USB vebdor request */
+#define USB_REQ_MASK                                   0x60U       /*!< USB request mask */
+
+/* bit 4..0 of bmRequestType: recipient type */
+#define USB_REQTYPE_DEVICE                             0x00U       /*!< USB device request type */
+#define USB_REQTYPE_INTERFACE                          0x01U       /*!< USB interface request type*/
+#define USB_REQTYPE_ENDPOINT                           0x02U       /*!< USB endpoint request type*/
+#define USB_REQTYPE_MASK                               0x03U       /*!< USB request type mask*/
+
+/* bRequest value */
+#define USBREQ_GET_STATUS                              0x00U       /*!< USB get status request*/
+#define USBREQ_CLEAR_FEATURE                           0x01U       /*!< USB clear feature request*/
+#define USBREQ_SET_FEATURE                             0x03U       /*!< USB set feature request*/
+#define USBREQ_SET_ADDRESS                             0x05U       /*!< USB set address request*/
+#define USBREQ_GET_DESCRIPTOR                          0x06U       /*!< USB get descriptor request*/
+#define USBREQ_SET_DESCRIPTOR                          0x07U       /*!< USB set descriptor request*/
+#define USBREQ_GET_CONFIGURATION                       0x08U       /*!< USB get configuration request*/
+#define USBREQ_SET_CONFIGURATION                       0x09U       /*!< USB set configuration request*/
+#define USBREQ_GET_INTERFACE                           0x0AU       /*!< USB get interface request*/
+#define USBREQ_SET_INTERFACE                           0x0BU       /*!< USB set interface request*/
+#define USBREQ_SYNCH_FRAME                             0x0CU       /*!< USB synchronize frame request*/
+
+/* descriptor types of usb specifications */
+#define USB_DESCTYPE_DEVICE                            0x01U       /*!< USB device descriptor type*/
+#define USB_DESCTYPE_CONFIGURATION                     0x02U       /*!< USB configuration descriptor type*/
+#define USB_DESCTYPE_STRING                            0x03U       /*!< USB string descriptor type*/
+#define USB_DESCTYPE_INTERFACE                         0x04U       /*!< USB interface descriptor type*/
+#define USB_DESCTYPE_ENDPOINT                          0x05U       /*!< USB endpoint descriptor type*/
+#define USB_DESCTYPE_DEVICE_QUALIFIER                  0x06U       /*!< USB device qualtfier descriptor type*/
+#define USB_DESCTYPE_OTHER_SPEED_CONFIGURATION         0x07U       /*!< USB other speed configuration descriptor type*/
+#define USB_DESCTYPE_INTERFACE_POWER                   0x08U       /*!< USB interface power descriptor type*/
+
+#define USB_DESCTYPE_HID                               0x21U       /*!< USB HID descriptor type*/
+#define USB_DESCTYPE_HID_REPORT                        0x22U       /*!< USB HID report descriptor type*/
+
+#define USB_DEVDESC_SIZE                               18U         /*!< USB device descriptor size*/
+#define USB_CFGDESC_SIZE                               9U          /*!< USB configure descriptor size*/
+#define USB_INTDESC_SIZE                               9U          /*!< USB interface descriptor size*/
+#define USB_EPDESC_SIZE                                7U          /*!< USB endpoint descriptor size*/
+
+/* descriptor type and descriptor index  */
+/* use the following values when USB host need to get descriptor  */
+#define  USB_DEVDESC                    ((USB_DESCTYPE_DEVICE                    << 8U) & 0xFF00U)  /*!< USB device operation marco */
+#define  USB_CFGDESC                    ((USB_DESCTYPE_CONFIGURATION             << 8U) & 0xFF00U)  /*!< USB configuration operation marco */
+#define  USB_STRDESC                    ((USB_DESCTYPE_STRING                    << 8U) & 0xFF00U)  /*!< USB string operation marco */
+#define  USB_INTDESC                    ((USB_DESCTYPE_INTERFACE                 << 8U) & 0xFF00U)  /*!< USB interface operation marco */
+#define  USB_EPDESC                     ((USB_DESCTYPE_INTERFACE                 << 8U) & 0xFF00U)  /*!< USB endpoint operation marco */
+#define  USB_DEVQUADESC                 ((USB_DESCTYPE_DEVICE_QUALIFIER          << 8U) & 0xFF00U)  /*!< USB device qualifier operation marco */
+#define  USB_OSPCFGDESC                 ((USB_DESCTYPE_OTHER_SPEED_CONFIGURATION << 8U) & 0xFF00U)  /*!< USB other speed configuration operation marco */
+#define  USB_INTPWRDESC                 ((USB_DESCTYPE_INTERFACE_POWER           << 8U) & 0xFF00U)  /*!< USB interface power operation marco */
+#define  USB_HIDREPDESC                 ((USB_DESCTYPE_HID_REPORT                << 8U) & 0xFF00U)  /*!< USB HID report operation marco */
+#define  USB_HIDDESC                    ((USB_DESCTYPE_HID                       << 8U) & 0xFF00U)  /*!< USB HID operation marco */
+
+#define SWAPBYTE(addr)       (((uint16_t)(*((uint8_t *)(addr)))) + \
+                             (uint16_t)(((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U))
+
+/* supported classes */
+#define USB_MSC_CLASS                                   0x08U     /*!< USB MSC class*/
+#define USB_HID_CLASS                                   0x03U     /*!< USB HID class*/
+
+/* interface descriptor field values for hid boot protocol */
+#define HID_BOOT_CODE                                   0x01U     /*!< USB HID boot code*/
+#define HID_KEYBRD_BOOT_CODE                            0x01U     /*!< USB HID keyboard boot code*/
+#define HID_MOUSE_BOOT_CODE                             0x02U     /*!< USB HID mouse boot code*/
+
+/* as per usb specs 9.2.6.4 :standard request with data request timeout: 5sec
+   standard request with no data stage timeout : 50ms */
+#define DATA_STAGE_TIMEOUT                              5000U     /*!< USB data stage timeout*/
+#define NODATA_STAGE_TIMEOUT                            50U       /*!< USB no data stage timeout*/
+
+#define USBH_CFG_DESC_SET_SIZE (USB_CFGDESC_SIZE + USB_INTDESC_SIZE \
+                                + (USBH_MAX_EP_NUM * USB_EPDESC_SIZE))    /*!< USB host set configuration descriptor size */
+
+#pragma pack(1)
+
+typedef union
+{
+    uint8_t data[8];
+
+    struct _setup_packet_struct
+    {
+        uint8_t           bmRequestType;  /*!< type of request */
+        uint8_t           bRequest;       /*!< request of setup packet */
+        uint16_t          wValue;         /*!< value of setup packet */
+        uint16_t          wIndex;         /*!< index of setup packet */
+        uint16_t          wLength;        /*!< length of setup packet */
+    } b;
+}usb_setup_union;
+
+typedef struct
+{
+    uint8_t bLength;                      /*!< size of the descriptor */
+    uint8_t bDescriptorType;              /*!< type of the descriptor */
+} usb_descriptor_header_struct;
+
+typedef struct
+{
+    usb_descriptor_header_struct Header;  /*!< descriptor header, including type and size */
+
+    uint16_t bcdUSB;                      /*!< BCD of the supported USB specification */
+    uint8_t  bDeviceClass;                /*!< USB device class */
+    uint8_t  bDeviceSubClass;             /*!< USB device subclass */
+    uint8_t  bDeviceProtocol;             /*!< USB device protocol */
+    uint8_t  bMaxPacketSize0;             /*!< size of the control (address 0) endpoint's bank in bytes */
+    uint16_t idVendor;                    /*!< vendor ID for the USB product */
+    uint16_t idProduct;                   /*!< unique product ID for the USB product */
+    uint16_t bcdDevice;                   /*!< product release (version) number */
+    uint8_t  iManufacturer;               /*!< string index for the manufacturer's name */
+    uint8_t  iProduct;                    /*!< string index for the product name/details */
+    uint8_t  iSerialNumber;               /*!< string index for the product's globally unique hexadecimal serial number */
+    uint8_t  bNumberConfigurations;       /*!< total number of configurations supported by the device */
+} usb_descriptor_device_struct;
+
+typedef struct
+{
+    usb_descriptor_header_struct Header;  /*!< descriptor header, including type and size */
+
+    uint16_t wTotalLength;                /*!< size of the configuration descriptor header,and all sub descriptors inside the configuration */
+    uint8_t  bNumInterfaces;              /*!< total number of interfaces in the configuration */
+    uint8_t  bConfigurationValue;         /*!< configuration index of the current configuration */
+    uint8_t  iConfiguration;              /*!< index of a string descriptor describing the configuration */
+    uint8_t  bmAttributes;                /*!< configuration attributes */
+    uint8_t  bMaxPower;                   /*!< maximum power consumption of the device while in the current configuration */
+} usb_descriptor_configuration_struct;
+
+typedef struct
+{
+    usb_descriptor_header_struct Header;  /*!< descriptor header, including type and size */
+
+    uint8_t bInterfaceNumber;             /*!< index of the interface in the current configuration */
+    uint8_t bAlternateSetting;            /*!< alternate setting for the interface number */
+    uint8_t bNumEndpoints;                /*!< total number of endpoints in the interface */
+    uint8_t bInterfaceClass;              /*!< interface class ID */
+    uint8_t bInterfaceSubClass;           /*!< interface subclass ID */
+    uint8_t bInterfaceProtocol;           /*!< interface protocol ID */
+    uint8_t iInterface;                   /*!< index of the string descriptor describing the interface */
+} usb_descriptor_interface_struct;
+
+typedef struct
+{
+    usb_descriptor_header_struct Header;  /*!< descriptor header, including type and size. */
+
+    uint8_t  bEndpointAddress;            /*!< logical address of the endpoint */
+    uint8_t  bmAttributes;                /*!< endpoint attributes */
+    uint16_t wMaxPacketSize;              /*!< size of the endpoint bank, in bytes */
+    uint8_t  bInterval;                   /*!< polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type */
+} usb_descriptor_endpoint_struct;
+
+typedef struct
+{
+    usb_descriptor_header_struct Header;  /*!< descriptor header, including type and size. */
+    uint16_t wLANGID;                     /*!< LANGID code */
+}usb_descriptor_language_id_struct;
+
+#pragma pack()
+
+#endif /* USB_STD_H */

+ 54 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_core.h

@@ -0,0 +1,54 @@
+/*!
+    \file  usbd_core.h
+    \brief USB device-mode core driver header file
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+
+#ifndef USBD_CORE_H
+#define USBD_CORE_H
+
+#include "usbd_conf.h"
+#include "usb_core.h"
+#include "usbd_std.h"
+
+/* device status */
+#define USB_STATUS_DEFAULT                          1U     /* default status */
+#define USB_STATUS_ADDRESSED                        2U     /* addressed status */
+#define USB_STATUS_CONFIGURED                       3U     /* configured status */
+#define USB_STATUS_SUSPENDED                        4U     /* suspended status */
+
+/* function declarations */
+/* initailizes the USB device-mode handler stack */
+void usbd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id);
+/* endpoint initialization */
+void usbd_ep_init (usb_core_handle_struct *pudev, const usb_descriptor_endpoint_struct *pep_desc);
+/* endpoint deinitialize */
+void usbd_ep_deinit (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* endpoint prepare to receive data */
+void usbd_ep_rx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len);
+/* endpoint prepare to transmit data */
+void usbd_ep_tx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len);
+/* transmit data on the control channel */
+usbd_status_enum usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len);
+/* receive data on the control channel */
+usbd_status_enum usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len);
+/* transmit status on the control channel */
+usbd_status_enum usbd_ctlstatus_tx (usb_core_handle_struct *pudev);
+/* receive status on the control channel */
+usbd_status_enum usbd_ctlstatus_rx (usb_core_handle_struct *pudev);
+/* set an endpoint to STALL status */
+void usbd_ep_stall (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* clear endpoint stalled status */
+void usbd_ep_clear_stall (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* flushes the FIFOs */
+void usbd_ep_fifo_flush (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* get the received data length */
+uint16_t usbd_rxcount_get (usb_core_handle_struct *pudev, uint8_t ep_id);
+
+#endif /* USBD_CORE_H */

+ 31 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_int.h

@@ -0,0 +1,31 @@
+/*!
+    \file  usbd_int.h
+    \brief USB device-mode interrupt handler header file
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USBD_INT_H
+#define USBD_INT_H
+
+#include "usbd_core.h"
+
+/* function declarations */
+/* USB device-mode interrupts global service routine handler */
+uint32_t usbd_isr (usb_core_handle_struct *pudev);
+
+#ifdef USBHS_DEDICATED_EP1_ENABLED
+
+/* USB dedicated OUT endpoint 1 interrupt service routine handler */
+uint32_t USBD_EP1OUT_ISR_Handler (usb_core_handle_struct *pudev);
+/* USB dedicated IN endpoint 1 interrupt service routine handler */
+uint32_t USBD_EP1IN_ISR_Handler (usb_core_handle_struct *pudev);
+
+#endif /* USBHS_DEDICATED_EP1_ENABLED */
+
+#endif /* USBD_INT_H */
+

+ 70 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_std.h

@@ -0,0 +1,70 @@
+/*!
+    \file  usbd_std.h
+    \brief USB 2.0 standard driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-06-30, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USBD_STD_H
+#define USBD_STD_H
+
+#include "usb_std.h"
+#include "usbd_core.h"
+#include "usbd_conf.h"
+#include <wchar.h>
+
+#define USBD_LANGID_STR_IDX                            0x00U     /*!< USB language ID string index*/
+#define USBD_MFC_STR_IDX                               0x01U     /*!< USB manufacturer string index*/
+#define USBD_PRODUCT_STR_IDX                           0x02U     /*!< USB product string index*/
+#define USBD_SERIAL_STR_IDX                            0x03U     /*!< USB serial string index*/
+#define USBD_CONFIG_STR_IDX                            0x04U     /*!< USB configuration string index*/
+#define USBD_INTERFACE_STR_IDX                         0x05U     /*!< USB interface string index*/
+
+#define USB_STATUS_REMOTE_WAKEUP                       0x02U     /*!< USB remote wakeup status*/
+#define USB_STATUS_SELF_POWERED                        0x01U     /*!< USB self power status*/
+
+#define USB_FEATURE_ENDP_HALT                          0x00U     /*!< USB halt endpoint feature*/
+#define USB_FEATURE_REMOTE_WAKEUP                      0x01U     /*!< USB remote wakeup feature*/
+#define USB_FEATURE_TEST_MODE                          0x02U     /*!< USB test mode feature*/
+
+#define ENG_LANGID                                     0x0409U   /*!< USB english language id*/
+#define CHN_LANGID                                     0x0804U   /*!< USB chinese language id*/
+
+#define USB_DEVICE_DESC_SIZE                           0x12U     /*!< USB device descriptor size*/
+
+#define LOWBYTE(x)           ((uint8_t)((x) & 0x00FFU))          /*!< USB lowbyte operation marco*/
+#define HIGHBYTE(x)          ((uint8_t)(((x) & 0xFF00U) >> 8U))  /*!< USB highbyte operation marco*/
+
+#define USB_MIN(a, b)        (((a) < (b)) ? (a) : (b))           /*!< USB minimum operation marco*/
+
+#define WIDE_STRING(string)  _WIDE_STRING(string)
+#define _WIDE_STRING(string) L##string
+
+#define USBD_STRING_DESC(string) \
+    (uint8_t *)&(struct { \
+        uint8_t _len; \
+        uint8_t _type; \
+        wchar_t _data[sizeof(string)]; \
+    }) { \
+        sizeof(WIDE_STRING(string)) + 2U - 2U, \
+        USB_DESCTYPE_STRING, \
+        WIDE_STRING(string) \
+    }
+
+#define IS_NOT_EP0(ep_addr)   (((ep_addr) != 0x00U) && ((ep_addr) != 0x80U))
+
+/* function declarations */
+/* USB device setup transaction*/
+usbd_status_enum usbd_setup_transaction (usb_core_handle_struct *pudev);
+/* USB device out transaction*/
+usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num);
+/* USB device in transaction*/
+usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num);
+/* USB device enum error handle*/
+void usbd_enum_error (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+#endif /* USBD_STD_H */

+ 283 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_core.h

@@ -0,0 +1,283 @@
+/*!
+    \file  usbh_core.h
+    \brief header file for usbh_core.c
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#ifndef USBH_CORE_H
+#define USBH_CORE_H
+
+#include "usbh_conf.h"
+#include "usb_std.h"
+#include "usb_core.h"
+
+#define MSC_CLASS                       0x08    /*!< the MSC class define */
+#define HID_CLASS                       0x03    /*!< the HID class define */
+#define MSC_PROTOCOL                    0x50    /*!< the MSC protocal define */
+#define CBI_PROTOCOL                    0x01    /*!< the CBI protocal define */
+
+#define USBH_DEVICE_ADDRESS_DEFAULT     0U      /*!< the default device address define */
+#define USBH_DEVICE_ADDRESS             1U      /*!< the device address define */
+#define USBH_MAX_ERROR_COUNT            2U      /*!< the max error count define */
+
+#define HOST_USER_SELECT_CONFIGURATION  1U      /*!< the user select configuration define */
+#define HOST_USER_CLASS_ACTIVE          2U      /*!< the user class active define */
+#define HOST_USER_CLASS_SELECTED        3U      /*!< the user class selected define */
+#define HOST_USER_CONNECTION            4U      /*!< the user connecttion define */
+#define HOST_USER_DISCONNECTION         5U      /*!< the user disconnection define */
+#define HOST_USER_UNRECOVERED_ERROR     6U      /*!< the user unrecovered error define */
+
+#define MAX_USBH_STATE_STACK_DEEP       4       /*!< the max state stack deep define */
+#define MAX_USBH_STATE_TABLE_NUM        10U     /*!< the max state table number */
+
+#define HOST_FSM_ID                     0U      /*!< the host state table id */
+#define ENUM_FSM_ID                     1U      /*!< the enum state table id */
+#define CMD_FSM_ID                      2U      /*!< the cmd state table id */
+#define CTRL_FSM_ID                     3U      /*!< the ctrl state table id */
+#define CLASS_REQ_FSM_ID                4U      /*!< the class req state table id */
+#define CLASS_FSM_ID                    5U      /*!< the class state table id */
+
+#define UP_STATE                        100U    /*!< up state define */
+#define GO_TO_UP_STATE_EVENT            100U    /*!< go to up state event define */
+
+#define HOST_HANDLE_TABLE_SIZE          9U      /*!< the host handle table size define */
+
+/* the enum of host state */
+typedef enum 
+{
+    HOST_IDLE = 0,                     /* the host idle state definition */
+    HOST_DEV_ATTACHED,                 /* the host device attached state definition */
+    HOST_DEV_DETACHED,                 /* the host device detached state definition */
+    HOST_DETECT_DEV_SPEED,             /* the host detect device speed state definition */
+    HOST_ENUMERATION,                  /* the host enumeration state definition */
+    HOST_CLASS_REQUEST,                /* the host class request state definition */
+    HOST_CLASS,                        /* the host class state definition */
+    HOST_USER_INPUT,                   /* the host user input state definition */
+    HOST_SUSPENDED,                    /* the host suspended state definition */
+    HOST_ERROR                         /* the host error state definition */
+}host_state_enum;
+
+/* the enum of host event */
+typedef enum 
+{
+    HOST_EVENT_ATTACHED = 0,           /* the host attached event */
+    HOST_EVENT_ENUM,                   /* the host enum event */
+    HOST_EVENT_USER_INPUT,             /* the host user input event */
+    HOST_EVENT_CLASS_REQ,              /* the host class request event */
+    HOST_EVENT_CLASS,                  /* the host class event */
+    HOST_EVENT_ERROR,                  /* the host error event */
+    HOST_EVENT_DEV_DETACHED,           /* the host device detached event */
+    HOST_EVENT_IDLE                    /* the host idle event */
+}host_event_enum;
+
+/* the enum of enum state */
+typedef enum
+{
+    ENUM_IDLE = 0,                     /* the enum idle state definition */
+    ENUM_SET_ADDR,                     /* the enum set address state definition */
+    ENUM_GET_FULL_DEV_DESC,            /* the enum get full device descripter state definition */
+    ENUM_GET_CFG_DESC,                 /* the enum get configuration descripter state definition */
+    ENUM_GET_FULL_CFG_DESC,            /* the enum get full configuration descripter state definition */
+    ENUM_GET_MFC_STRING_DESC,          /* the enum get MFC string descripter state definition */
+    ENUM_GET_PRODUCT_STRING_DESC,      /* the enum get product string descripter state definition */
+    ENUM_GET_SERIALNUM_STRING_DESC,    /* the enum get serialnum string descripter state definition */
+    ENUM_SET_CONFIGURATION,            /* the enum set congiguration state definition */
+    ENUM_DEV_CONFIGURED                /* the enum device configuration state definition */
+}enum_state_enum;
+
+/* the enum of ctrl state */
+typedef enum 
+{
+    CTRL_IDLE = 0,                     /* the ctrl idle state definition */
+    CTRL_SETUP,                        /* the ctrl setup state definition */
+    CTRL_DATA,                         /* the ctrl data state definition */
+    CTRL_STATUS,                       /* the ctrl status state definition */
+    CTRL_ERROR,                        /* the ctrl error state definition */
+    CTRL_STALLED,                      /* the ctrl stalled state definition */
+    CTRL_COMPLETE                      /* the ctrl complete state definition */
+}ctrl_state_enum;
+
+/* the enum of host status */
+typedef enum 
+{
+    USBH_OK = 0,                       /* the usbh ok status definition */
+    USBH_BUSY,                         /* the usbh busy status definition */
+    USBH_FAIL,                         /* the usbh fail status definition */
+    USBH_NOT_SUPPORTED,                /* the usbh not supported status definition */
+    USBH_UNRECOVERED_ERROR,            /* the usbh unrecovered error status definition */
+    USBH_SPEED_UNKNOWN_ERROR,          /* the usbh speed unknown error status definition */
+    USBH_APPLY_DEINIT                  /* the usbh apply deinit status definition */
+}usbh_status_enum;
+
+/* the state of user action */
+typedef enum 
+{
+    USBH_USER_NO_RESP = 0,             /* the user no response */
+    USBH_USER_RESP_OK = 1,             /* the user response ok */
+}usbh_user_status_enum;
+
+/* control transfer information */
+typedef struct
+{
+    uint8_t               hc_in_num;   /* the host in channel number */
+    uint8_t               hc_out_num;  /* the host out channel number */
+    uint8_t               ep0_size;    /* the endpoint 0 max packet size */
+    uint8_t               error_count; /* the error count */
+    uint16_t              length;      /* the length */
+    uint16_t              timer;       /* the timer */
+    uint8_t              *buff;        /* the buffer */
+    usb_setup_union       setup;       /* the setup packet */
+}usbh_ctrl_struct;
+
+/* device property */
+typedef struct
+{
+    uint8_t                              address;                                           /* the device address */
+    uint8_t                              speed;                                             /* the device speed */
+    usb_descriptor_device_struct         dev_desc;                                          /* the device descripter */
+    usb_descriptor_configuration_struct  cfg_desc;                                          /* the configuration descripter */
+    usb_descriptor_interface_struct      itf_desc[USBH_MAX_INTERFACES_NUM];                 /* the interface descripter */
+    usb_descriptor_endpoint_struct       ep_desc[USBH_MAX_INTERFACES_NUM][USBH_MAX_EP_NUM]; /* the endpoint descripter */
+}usbh_device_struct;
+
+/* user callbacks */
+typedef struct
+{
+    void (*init)                        (void);                 /* the user callback init function */
+    void (*deinit)                      (void);                 /* the user callback deinit function */
+    void (*device_connected)            (void);                 /* the user callback device connected function */
+    void (*device_reset)                (void);                 /* the user callback device reset function */
+    void (*device_disconnected)         (void);                 /* the user callback device disconnected function */
+    void (*over_current_detected)       (void);                 /* the user callback over current detected function */
+    void (*device_speed_detected)       (uint8_t device_speed);  /* the user callback device speed detected function */
+    void (*device_desc_available)       (void *devDesc);        /* the user callback device descrpiter available function */
+    void (*device_address_set)          (void);                 /* the user callback set device address function */
+
+    void (*configuration_desc_available)(usb_descriptor_configuration_struct *cfg_desc,
+                                         usb_descriptor_interface_struct *itf_desc,
+                                         usb_descriptor_endpoint_struct *ep_desc);  
+                                                                /* the configuration descripter available function */
+
+    void (*manufacturer_string)         (void *mfc_string);      /* the user callback manufacturer string function */
+    void (*product_string)              (void *prod_string);     /* the user callback product string function */
+    void (*serial_num_string)           (void *serial_string);   /* the user callback serial number string function */
+    void (*enumeration_finish)          (void);                 /* the user callback enumeration finish function */
+    usbh_user_status_enum (*user_input) (void);                 /* the user callback user input function */
+    int  (*user_application)            (usb_core_handle_struct *pudev, uint8_t id);          
+                                                                /* the user callback user appliction function */
+    void (*device_not_supported)        (void);                 /* the user callback device not supported function */
+    void (*unrecovered_error)           (void);                 /* the user callback unrecovered error function */
+}usbh_user_callback_struct;
+
+/* the backup state struct */
+typedef struct
+{
+    host_state_enum                      host_backup_state;     /* the host backup state */
+    enum_state_enum                      enum_backup_state;     /* the enum backup state */
+    ctrl_state_enum                      ctrl_backup_state;     /* the ctrl backup state */
+    uint8_t                              class_req_backup_state;/* the class request backup state */
+    uint8_t                              class_backup_state;    /* the class backup state */
+} backup_state_struct;
+
+/* host information */
+typedef struct
+{
+    backup_state_struct                  usbh_backup_state;                            /* the usbh backup state variable */
+    usbh_ctrl_struct                     control;                                      /* the control struct variable */
+    usbh_device_struct                   device;                                       /* the device struct variable */
+    usbh_user_callback_struct           *usr_cb;                                       /* the user callback function */
+    usbh_status_enum (*class_init)      (usb_core_handle_struct *pudev, void *phost);  /* the class init function */
+    void (*class_deinit)                (usb_core_handle_struct *pudev, void *phost);  /* the class deinit function */
+}usbh_host_struct;
+
+/* the action function definition */
+typedef usbh_status_enum (*ACT_FUN)     (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void* pustate);
+
+/* the state table struct */
+typedef struct 
+{
+    uint8_t                              cur_state;             /* the current state */
+    uint8_t                              cur_event;             /* the current event */
+    uint8_t                              next_state;            /* the next state */
+    ACT_FUN                              event_action_fun;      /* the event action function entry */
+} state_table_struct;
+
+/* the state stack struct */
+typedef struct
+{
+    uint8_t                              state;                 /* the state in state stack */
+    state_table_struct*                  table;                 /* the table in state stack */
+    uint8_t                              table_size;            /* the table size in state stack */
+} usbh_state_stack_struct;
+
+/* the state regist table struct */
+typedef struct
+{
+    uint8_t                              id;                    /* the id of the state table */
+    state_table_struct*                  table;                 /* the table entry to regist */
+    uint8_t                              table_size;            /* the table size to regist */
+} usbh_state_regist_table_struct;
+
+/* the state handle struct */
+typedef struct 
+{
+    uint8_t                              usbh_current_state;                                 /* current state */
+    uint8_t                              usbh_current_state_table_size;                      /* current state table size */
+    state_table_struct*                  usbh_current_state_table;                           /* current state table */
+  
+    usbh_state_stack_struct              stack[MAX_USBH_STATE_STACK_DEEP];                   /* the stack of state table */
+    int8_t                               usbh_current_state_stack_top;                       /* the current state top */
+  
+    usbh_state_regist_table_struct       usbh_regist_state_table[MAX_USBH_STATE_TABLE_NUM];  /* the array of regist state table */
+    uint8_t                              usbh_regist_state_table_num;                        /* the number of regist state table */
+} usbh_state_handle_struct;
+
+/* function declarations */
+/* the host core driver function */
+usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* initialize the host portion of the driver */
+uint32_t  hcd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id);
+/* check if the device is connected */
+uint32_t  hcd_is_device_connected (usb_core_handle_struct *pudev);
+/* this function returns the last URBstate */
+urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num);
+/* this function returns the last URBstate */
+uint32_t  hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num);
+/* de-initialize host */
+usbh_status_enum usbh_deinit (usb_core_handle_struct *pudev, 
+                              usbh_host_struct *puhost, 
+                              usbh_state_handle_struct* pustate);
+
+/* the state core driver function */
+/* state core driver init */
+void scd_init (usbh_state_handle_struct* pustate);
+/* state core driver table regist */
+void scd_table_regist (usbh_state_handle_struct* pustate, 
+                       state_table_struct* pstate_table,
+                       uint8_t table_id,
+                       uint8_t current_table_size);
+/* state core driver begin */
+void scd_begin (usbh_state_handle_struct* pustate, uint8_t table_id);
+/* state core driver move state */
+void scd_state_move (usbh_state_handle_struct* pustate, uint8_t state);
+/* state core driver event handle */
+usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev,
+                                   usbh_host_struct *puhost,
+                                   usbh_state_handle_struct* pustate,
+                                   uint8_t event, 
+                                   uint8_t state);
+/* state core driver table push */
+void scd_table_push (usbh_state_handle_struct* pustate);
+/* state core driver table pop */
+void scd_table_pop (usbh_state_handle_struct* pustate);
+/* the function is only used to state move */
+usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* the function to the up state */
+usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+
+#endif /* USBH_CORE_H */

+ 45 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_ctrl.h

@@ -0,0 +1,45 @@
+/*!
+    \file  usbh_ctrl.h
+    \brief header file for usbh_ctrl.c
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USBH_CTRL_H
+#define USBH_CTRL_H
+
+#include "usbh_core.h"
+#include "usbh_usr.h"
+
+#define CTRL_HANDLE_TABLE_SIZE   13U    /*!< the ctrl handle table size define */
+
+extern state_table_struct        ctrl_handle_table[CTRL_HANDLE_TABLE_SIZE];
+extern uint8_t                   ctrl_polling_handle_flag;
+
+/* the enum of CTRL event */
+typedef enum 
+{
+    CTRL_EVENT_IDLE = 0,   /* the ctrl idle event */
+    CTRL_EVENT_SETUP,      /* the ctrl setup event */
+    CTRL_EVENT_DATA,       /* the ctrl data event */
+    CTRL_EVENT_STATUS,     /* the ctrl status event */
+    CTRL_EVENT_COMPLETE,   /* the ctrl complete event */
+    CTRL_EVENT_ERROR,      /* the ctrl error event */
+    CTRL_EVENT_STALLED,    /* the ctrl stalled event */
+}ctrl_event_enum;
+
+/* function declarations */
+/* the polling function of control transfer state handle */
+usbh_status_enum ctrl_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* send datas from the host channel */
+usbh_status_enum usbh_xfer (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t  hc_num, uint16_t len);
+/* send the setup packet to the device */
+usbh_status_enum usbh_ctltx_setup (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t  hc_num);
+/* this function prepare a hc and start a transfer */
+uint32_t  hcd_submit_request (usb_core_handle_struct *pudev, uint8_t channel_num);
+
+#endif /* USBH_CTRL_H */

+ 46 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_hcs.h

@@ -0,0 +1,46 @@
+/*!
+    \file  usbh_hcs.h
+    \brief header file for usbh_hcs.c
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USBH_HCS_H
+#define USBH_HCS_H
+
+#include "usbh_core.h"
+
+#define HC_MAX                  8U
+
+#define HC_OK                   0x0000U
+#define HC_USED                 0x8000U
+#define HC_ERROR                0xFFFFU
+#define HC_USED_MASK            0x7FFFU
+
+/* function declarations */
+/* allocate a new channel for the pipe */
+uint8_t usbh_channel_alloc (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* free all usb host channel */
+uint8_t usbh_allchannel_dealloc (usb_core_handle_struct *pudev);
+/* free the usb host channel */
+uint8_t usbh_channel_free (usb_core_handle_struct *pudev, uint8_t index);
+/* open a channel */
+uint8_t usbh_channel_open (usb_core_handle_struct *pudev, 
+                           uint8_t  channel_num,
+                           uint8_t  dev_addr,
+                           uint8_t  dev_speed,
+                           uint8_t  ep_type,
+                           uint16_t ep_mps);
+/* modify a channel */
+uint8_t usbh_channel_modify (usb_core_handle_struct *pudev,
+                             uint8_t  channel_num,
+                             uint8_t  dev_addr,
+                             uint8_t  dev_speed,
+                             uint8_t  ep_type,
+                             uint16_t ep_mps);
+
+#endif /* USBH_HCS_H */

+ 30 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_int.h

@@ -0,0 +1,30 @@
+/*!
+    \file  usbh_int.h
+    \brief USB host mode interrupt handler header file
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#ifndef USBH_INT_H
+#define USBH_INT_H
+
+#include "usb_core.h"
+
+typedef struct
+{
+    uint8_t (*sof)                  (usb_core_handle_struct *pudev);
+    uint8_t (*device_connected)     (usb_core_handle_struct *pudev);
+    uint8_t (*device_disconnected)  (usb_core_handle_struct *pudev);
+}usbh_hcd_int_cb_struct;
+
+extern usbh_hcd_int_cb_struct *usbh_hcd_int_fops;
+
+/* function declarations */
+/* handle global host interrupt */
+uint32_t usbh_isr (usb_core_handle_struct *pudev);
+
+#endif /* USBH_INT_H */

+ 74 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_std.h

@@ -0,0 +1,74 @@
+/*!
+    \file  usbh_std.h
+    \brief header file for usbh_std.c
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef USBH_STD_H
+#define USBH_STD_H
+
+#include "usbh_core.h"
+#include "usbh_usr.h"
+
+/* standard feature selector for clear feature command */
+#define FEATURE_SELECTOR_ENDPOINT      0x00U
+#define FEATURE_SELECTOR_DEVICE        0x01U
+
+#define USBH_SETUP_PACKET_SIZE         8U      /* setup packet size */
+#define ENUM_HANDLE_TABLE_SIZE         10U     /* enumerate handle table size */
+
+extern uint8_t                         usbh_cfg_desc[512];
+extern uint8_t                         enum_polling_handle_flag;
+extern state_table_struct              enum_handle_table[ENUM_HANDLE_TABLE_SIZE];
+
+typedef enum 
+{
+    ENUN_EVENT_IDLE = 0,                   /* the enum idle event */
+    ENUM_EVENT_SET_ADDR,                   /* the enum set address event */
+    ENUN_EVENT_GET_FULL_DEV_DESC,          /* the enum get full device descripter event */
+    ENUN_EVENT_GET_CFG_DESC,               /* the enum get congiguration descripter event */
+    ENUN_EVENT_GET_FULL_CFG_DESC,          /* the enum get full configuration descripter event */
+    ENUN_EVENT_GET_MFC_STRING_DESC,        /* the enum get MFC string descripter event */
+    ENUN_EVENT_GET_PRODUCT_STRING_DESC,    /* the enum get product string event */
+    ENUN_EVENT_GET_SERIALNUM_STRING_DESC,  /* the enum get serialnum string event */
+    ENUN_EVENT_SET_CONFIGURATION,          /* the enum set configuration event */
+    ENUN_EVENT_DEV_CONFIGURED              /* the enum device configured event */
+}enum_event_enum;
+
+/* function declarations */
+/* the polling function of enumeration state */
+usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* get descriptor in usb host enumeration stage */
+void usbh_enum_desc_get (usb_core_handle_struct *pudev, 
+                         usbh_host_struct *puhost, 
+                         uint8_t *buf, 
+                         uint8_t  req_type, 
+                         uint16_t value_idx, 
+                         uint16_t len);
+/* set address in usb host enumeration stage */
+void usbh_enum_addr_set (usb_core_handle_struct *pudev, usbh_host_struct *puhost, uint8_t device_address);
+/* set configuration in usb host enumeration stage */
+void usbh_enum_cfg_set (usb_core_handle_struct *pudev, usbh_host_struct *puhost, uint16_t cfg_idx);
+/* parse the device descriptor */
+void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len);
+/* parse the configuration descriptor */
+void usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc,
+                          usb_descriptor_interface_struct *itf_desc,
+                          usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM],
+                          uint8_t *buf,
+                          uint16_t len);
+/* parse the interface descriptor */
+void usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf);
+/* parse the endpoint descriptor */
+void usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf);
+/* parse the string descriptor */
+void usbh_string_desc_parse (uint8_t *psrc, uint8_t *pdest, uint16_t len);
+/* get the next descriptor header */
+usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr);
+
+#endif /* USBH_STD_H */

+ 1132 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usb_core.c

@@ -0,0 +1,1132 @@
+/*!
+    \file  usb_core.c
+    \brief USB core driver which can operate in host-mode and device-mode
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "usb_core.h"
+
+static void usb_commonint_enable      (usb_core_handle_struct *pudev);
+static usb_status_enum usb_core_reset (usb_core_handle_struct *pudev);
+
+/*!
+    \brief      enable the commmon interrupts which are used in both device and host modes
+    \param[in]  pudev: pointer to selected usb device
+    \param[out] none
+    \retval     none
+*/
+static void usb_commonint_enable (usb_core_handle_struct *pudev)
+{
+#ifndef USE_OTG_MODE
+
+    /* clear any pending USB interrupts */
+    USB_GOTGINTF = 0xFFFFFFFFU;
+
+#endif /* USE_OTG_MODE */
+
+    /* enable the usb wakeup and suspend interrupts */
+    USB_GINTEN = GINTEN_WKUPIE | GINTEN_SPIE;
+
+#ifdef USE_OTG_MODE
+
+    /* enable the OTG interrupts, session interrrupts and connector ID pin interrupt */
+    USB_GINTEN |= GINTEN_OTGIE | GINTEN_SESIE | GINTEN_CIDPSCIE;
+
+#endif /* USE_OTG_MODE */
+}
+
+/*!
+    \brief      soft reset of the OTG_FS core
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+static usb_status_enum usb_core_reset (usb_core_handle_struct *pudev)
+{
+    uint32_t count = 0U;
+
+    /* enable core soft reset */
+    USB_GRSTCTL |= GRSTCTL_CSRST;
+
+    /* wait for the core to be soft reset */
+    do {
+        if (++count > 200000U) {
+            break;
+        }
+    } while (1U == (USB_GRSTCTL & GRSTCTL_CSRST));
+
+    /* wait for addtional 3 PHY clocks */
+    if (NULL != pudev->udelay) {
+        pudev->udelay(3U);
+    }
+
+    return USB_OK;
+}
+
+/*!
+    \brief      write a packet into the Tx FIFO associated with the endpoint
+    \param[in]  src: pointer to source buffer
+    \param[in]  ep_id: endpoint identifier which is in (0..3)
+    \param[in]  len: packet length
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_fifo_write (uint8_t *src, uint8_t ep_id, uint16_t len)
+{
+    uint32_t count32b = 0U, i = 0U;
+    __IO uint32_t *fifo = USB_FIFO(ep_id);
+
+    count32b = (len + 3U) / 4U;
+
+    for (i = 0U; i < count32b; i++) {
+        *fifo = *((__packed uint32_t *)src);
+
+        src += 4U;
+    }
+
+    return USB_OK;
+}
+
+/*!
+    \brief      read a packet from the Rx FIFO associated with the endpoint
+    \param[in]  dest: pointer to destination buffer
+    \param[in]  len: packet length
+    \param[out] none
+    \retval     void type pointer
+*/
+void *usb_fifo_read (uint8_t *dest, uint16_t len)
+{
+    uint32_t i = 0U;
+    uint32_t count32b = (len + 3U) / 4U;
+
+    __IO uint32_t *fifo = USB_FIFO(0U);
+
+    for (i = 0U; i < count32b; i++) {
+        *(__packed uint32_t *)dest = *fifo;
+        
+        dest += 4U;
+    }
+
+    return ((void *)dest);
+}
+
+/*!
+    \brief      initialize core parameters
+    \param[in]  pudev: pointer to usb device
+    \param[in]  core_id: USB core id
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_core_select (usb_core_handle_struct *pudev, usb_core_id_enum core_id)
+{
+    /* at startup the core is in FS mode */
+    pudev->cfg.core_speed = USB_CORE_SPEED_FULL;
+    pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE;
+
+    pudev->cfg.dma_enable = 0U;
+
+    /* initialize the core parameters */
+    if (USB_FS_CORE_ID == core_id) {
+        pudev->cfg.core_id = USB_FS_CORE_ID;
+
+        /* set the host channel numbers */
+        pudev->cfg.host_channel_num = USBFS_MAX_HOST_CHANNELCOUNT;
+
+        /* set the device endpoint numbers */
+        pudev->cfg.dev_endp_num = USBFS_MAX_DEV_EPCOUNT;
+
+        /* fifo size is in terms of DWORD */
+        pudev->cfg.max_fifo_size = USBFS_MAX_FIFO_WORDLEN;
+
+        /* OTG_FS core use embedded physical layer */
+        pudev->cfg.phy_interface = USB_CORE_EMBEDDED_PHY;
+
+#ifdef USBFS_SOF_OUTPUT_ENABLED
+    pudev->cfg.sof_output = 1U;
+#endif /* USBFS_SOF_OUTPUT_ENABLED */
+
+#ifdef USBFS_LOW_PWR_MGMT_SUPPORT
+    pudev->cfg.low_power = 1U;
+#endif /* USBFS_LOW_PWR_MGMT_SUPPORT */
+
+    } else if (USB_HS_CORE_ID == core_id) {
+        pudev->cfg.core_id = USB_HS_CORE_ID;
+
+        /* set the host channel numbers */
+        pudev->cfg.host_channel_num = USBHS_MAX_HOST_CHANNELCOUNT;
+
+        /* set the device endpoint numbers */
+        pudev->cfg.dev_endp_num = USBHS_MAX_DEV_EPCOUNT;
+
+        /* fifo size is in terms of DWORD */
+        pudev->cfg.max_fifo_size = USBHS_MAX_FIFO_WORDLEN;
+
+#ifdef USB_ULPI_PHY_ENABLED
+        pudev->cfg.phy_interface = USB_CORE_ULPI_PHY;
+#elif defined(USB_EMBEDDED_PHY_ENABLED)
+        pudev->cfg.phy_interface = USB_CORE_EMBEDDED_PHY; 
+#endif /* USB_ULPI_PHY_ENABLED */
+
+#ifdef USBHS_INTERNAL_DMA_ENABLED
+        pudev->cfg.dma_enable = 1U;
+#endif /* USBHS_INTERNAL_DMA_ENABLED */
+
+#ifdef USBHS_SOF_OUTPUT_ENABLED
+        pudev->cfg.sof_output = 1U;
+#endif /* USBHS_SOF_OUTPUT_ENABLED */
+
+#ifdef USBHS_LOW_PWR_MGMT_SUPPORT
+        pudev->cfg.low_power = 1U;
+#endif /* USBHS_LOW_PWR_MGMT_SUPPORT */
+    } else {
+         /* no operation */
+    }
+
+    return USB_OK;
+}
+
+/*!
+    \brief      initializes the USB controller registers and 
+                prepares the core device mode or host mode operation
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_core_init (usb_core_handle_struct *pudev)
+{
+    if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) {
+        USB_GCCFG &= ~GCCFG_PWRON;
+
+        if (pudev->cfg.sof_output) {
+            USB_GCCFG |= GCCFG_SOFOEN;
+        }
+
+        /* use high-speed interface */
+        USB_GUSBCS &= ~GUSBCS_EMBPHY;
+
+        /* use internal over-current indicator */
+        USB_GUSBCS &= ~GUSBCS_ULPIEOI;
+
+#ifdef USBHS_EXTERNAL_VBUS_ENABLED
+        /* use external VBUS driver */
+        USB_GUSBCS |= GUSBCS_ULPIEVD;
+#else
+        /* use internal VBUS driver */
+        USB_GUSBCS &= ~GUSBCS_ULPIEVD;
+#endif
+
+        /* soft reset the core */
+        usb_core_reset(pudev);
+    } else if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
+        if (USB_HS_CORE_ID == pudev->cfg.core_id) {
+            USB_GUSBCS |= GUSBCS_EMBPHY;
+        }
+
+        /* soft reset the core */
+        usb_core_reset(pudev);
+
+        /* active the transceiver and enable vbus sensing */
+        USB_GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN;
+
+        /* set Tx FIFO empty level to half empty mode */
+        USB_GAHBCS &= ~GAHBCS_TXFTH | TXFIFO_EMPTY_HALF;
+
+#ifndef VBUS_SENSING_ENABLED
+        USB_GCCFG |= GCCFG_VBUSIG;
+#endif /* VBUS_SENSING_ENABLED */
+
+        if(pudev->cfg.sof_output){
+            USB_GCCFG |= GCCFG_SOFOEN;
+        }
+
+        if (NULL != pudev->mdelay) {
+            pudev->mdelay(20U);
+        }
+    } else {
+        /* no operation */
+    }
+
+    if (1U == pudev->cfg.dma_enable) {
+        USB_GAHBCS = DMA_INCR8 | GAHBCS_DMAEN;
+    }
+
+#ifdef USE_OTG_MODE
+    /* enable OTG features */
+    USB_GUSBCS |= GUSBCS_HNPCAP | GUSBCS_SRPCAP;
+    USB_OTG_EnableCommonInt(pudev);
+
+#endif /* USE_OTG_MODE */
+
+    return USB_OK;
+}
+
+/*!
+    \brief      flush a Tx FIFO or all Tx FIFOs
+    \param[in]  pudev: pointer to usb device
+    \param[in]  fifo_num: FIFO number which is in (0..3)
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_txfifo_flush (usb_core_handle_struct *pudev, uint8_t fifo_num)
+{
+    uint32_t count = 0U;
+
+    USB_GRSTCTL = ((uint32_t)fifo_num << 6U) | GRSTCTL_TXFF;
+
+    /* wait for Tx FIFO flush bit is set */
+    do {
+        if (++count > 200000U) {
+            break;
+        }
+    } while (USB_GRSTCTL & GRSTCTL_TXFF);
+
+    /* wait for 3 PHY clocks */
+   if (NULL != pudev->udelay) {
+       pudev->udelay(3U);
+   }
+
+    return USB_OK;
+}
+
+/*!
+    \brief      flush the entire Rx FIFO
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_rxfifo_flush (usb_core_handle_struct *pudev)
+{
+    uint32_t count = 0U;
+
+    USB_GRSTCTL = GRSTCTL_RXFF;
+
+    /* wait for Rx FIFO flush bit is set */
+    do {
+        if (++count > 200000U) {
+            break;
+        }
+    } while (USB_GRSTCTL & GRSTCTL_RXFF);
+
+    /* wait for 3 PHY clocks */
+   if (NULL != pudev->udelay) {
+       pudev->udelay(3U);
+   }
+
+    return USB_OK;
+}
+
+/*!
+    \brief      set operation mode (host or device)
+    \param[in]  pudev: pointer to usb device
+    \param[in]  mode: operation mode which need to set
+      \arg        HOST_MODE
+      \arg        DEVICE_MODE
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_mode_set (usb_core_handle_struct *pudev, uint8_t mode)
+{
+    if (HOST_MODE == mode) {
+        USB_GUSBCS &= ~GUSBCS_FDM;
+        USB_GUSBCS |= GUSBCS_FHM;
+    } else if (DEVICE_MODE == mode) {
+        USB_GUSBCS &= ~GUSBCS_FHM;
+        USB_GUSBCS |= GUSBCS_FDM;
+    } else {
+        /* no operation */
+    }
+
+   if (NULL != pudev->mdelay) {
+       pudev->mdelay(50U);
+   }
+
+    return USB_OK;
+}
+
+#ifdef USE_HOST_MODE
+
+/*!
+    \brief      initializes USB core for host mode
+    \param[in]  pudev: pointer to selected usb host
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_hostcore_init (usb_core_handle_struct *pudev)
+{
+    uint32_t i = 0U;
+    __IO uint32_t host_nptxfifo_size = 0U;
+    __IO uint32_t host_ptxfifo_size = 0U;
+
+#ifdef USE_OTG_MODE
+    __IO uint32_t OtgCtrl = 0;
+#endif /* USE_OTG_MODE */
+
+    /* restart the PHY clock */
+    USB_PWRCLKCTL = 0U;
+
+    /* initialize host configuration register */
+    if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) {
+        USB_FSLSCLOCK_INIT(HCTLR_30_60_MHZ); 
+    } else {
+        USB_FSLSCLOCK_INIT(HCTLR_48_MHZ);
+    }
+
+    /* configure data FIFO sizes */
+#ifdef USBFS_CORE
+    if (USB_FS_CORE_ID == pudev->cfg.core_id) {
+        /* set Rx FIFO size */
+        USB_GRFLEN = USBFS_RX_FIFO_SIZE;
+
+        /* set non-periodic Tx FIFO size and address */
+        host_nptxfifo_size &= ~HNPTFLEN_HNPTXRSAR;
+        host_nptxfifo_size |= USBFS_RX_FIFO_SIZE;
+        host_nptxfifo_size &= ~HNPTFLEN_HNPTXFD;
+        host_nptxfifo_size |= USBFS_HTX_NPFIFO_SIZE << 16;
+        USB_HNPTFLEN = host_nptxfifo_size;
+
+        /* set periodic Tx FIFO size and address */
+        host_ptxfifo_size &= ~HPTFLEN_HPTXFSAR;
+        host_ptxfifo_size |= USBFS_RX_FIFO_SIZE + USBFS_HTX_PFIFO_SIZE;
+        host_ptxfifo_size &= ~HPTFLEN_HPTXFD;
+        host_ptxfifo_size |= USBFS_HTX_PFIFO_SIZE << 16;
+        USB_HPTFLEN = host_ptxfifo_size;
+    }
+#endif /* USBFS_CORE */
+
+#ifdef USBHS_CORE
+    if (USB_HS_CORE_ID == pudev->cfg.core_id) {
+        /* set Rx FIFO size */
+        USB_GRFLEN = USBHS_RX_FIFO_SIZE;
+
+        /* set non-periodic Tx FIFO size and address */
+        host_nptxfifo_size &= ~HNPTFLEN_HNPTXRSAR;
+        host_nptxfifo_size |= USBHS_RX_FIFO_SIZE;
+        host_nptxfifo_size &= ~HNPTFLEN_HNPTXFD;
+        host_nptxfifo_size |= USBHS_HTX_NPFIFO_SIZE << 16;
+        USB_HNPTFLEN = host_nptxfifo_size;
+
+        /* set periodic Tx FIFO size and address */
+        host_ptxfifo_size &= ~HPTFLEN_HPTXFSAR;
+        host_ptxfifo_size |= USBHS_RX_FIFO_SIZE + USBHS_HTX_PFIFO_SIZE;
+        host_ptxfifo_size &= ~HPTFLEN_HPTXFD;
+        host_ptxfifo_size |= USBHS_HTX_PFIFO_SIZE << 16;
+        USB_HPTFLEN = host_ptxfifo_size;
+    }
+#endif /* USBHS_CORE */
+
+#ifdef USE_OTG_MODE
+
+    /* clear Host Set HNP Enable bit in the USB OTG Control Register */
+    OtgCtrl |= GOTGCS_HHNPEN;
+    USB_GOTGCS &= ~OtgCtrl;
+    USB_GOTGCS |= 0;
+
+#endif /* USE_OTG_MODE */
+
+    /* make sure the FIFOs are flushed */
+
+    /* flush all Tx FIFOs in device or host mode */
+    usb_txfifo_flush(pudev, 0x10U);
+
+    /* flush the entire Rx FIFO */
+    usb_rxfifo_flush(pudev);
+
+    /* clear all pending host channel interrupts */
+    USB_HACHINTEN &= ~HACHINTEN_CINTEN;
+
+    for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
+        USB_HCHxINTEN(i) = 0U;
+        USB_HCHxINTF(i) = 0xFFFFFFFFU;
+    }
+
+#ifndef USE_OTG_MODE
+    usb_vbus_drive(pudev, 1U);
+#endif /* USE_OTG_MODE */
+
+    usb_hostint_enable(pudev);
+
+    return USB_OK;
+}
+
+/*!
+    \brief      control the VBUS to power
+    \param[in]  pudev: pointer to selected usb host
+    \param[in]  state: VBUS state
+    \param[out] none
+    \retval     none
+*/
+void usb_vbus_drive (usb_core_handle_struct *pudev, uint8_t state)
+{
+    __IO uint32_t host_port = 0U;
+
+    /* enable or disable the external charge pump */
+    if ((void *)0 != pudev->host.vbus_drive) {
+        pudev->host.vbus_drive(pudev, state);
+    }
+
+    /* turn on the host port power. */
+    host_port = USB_PORT_READ();
+
+    if ((0U == (host_port & HPCS_PP)) && (1U == state)) {
+        host_port |= HPCS_PP;
+    } else if ((1U == (host_port & HPCS_PP)) && (0U == state)) {
+        host_port &= ~HPCS_PP;
+    } else {
+        /* no operation */
+    }
+
+    USB_HPCS = host_port;
+
+    if (NULL != pudev->mdelay) {
+        pudev->mdelay(200U);
+    }
+}
+
+/*!
+    \brief      enables the host mode interrupts
+    \param[in]  pudev: pointer to selected usb host
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_hostint_enable (usb_core_handle_struct *pudev)
+{
+    uint32_t global_int_flag = 0U;
+
+    /* disable all interrupts */
+    USB_GINTEN = 0U;
+
+    /* clear any pending interrupts */
+    USB_GINTF = 0xFFFFFFFFU;
+
+    /* enable the common interrupts */
+    usb_commonint_enable(pudev);
+
+    if (0U == pudev->cfg.dma_enable) {
+        global_int_flag |= GINTF_RXFNEIF;
+    }
+
+    /* enable host_mode-related interrupts */
+    global_int_flag |= GINTF_HPIF | GINTF_HCIF | GINTF_DISCIF \
+                | GINTF_SOF | GINTF_ISOONCIF;
+
+    USB_GINTEN &= ~global_int_flag;
+    USB_GINTEN |= global_int_flag;
+
+    return USB_OK;
+}
+
+/*!
+    \brief      reset host port
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+uint32_t usb_port_reset (usb_core_handle_struct *pudev)
+{
+    USB_HPCS = USB_PORT_READ() | HPCS_PRST;
+
+    if (NULL != pudev->mdelay) {
+        pudev->mdelay(10U);
+    }
+
+    USB_HPCS &= ~HPCS_PRST;
+
+    if (NULL != pudev->mdelay) {
+        pudev->mdelay(20U);
+    }
+
+    return USB_OK;
+}
+
+/*!
+    \brief      initialize host channel
+    \param[in]  pudev: pointer to usb device
+    \param[in]  hc_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_hostchannel_init(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+    usb_status_enum status = USB_OK;
+    uint8_t is_low_speed = 0U;
+    __IO uint32_t host_channel_inten = 0U;
+    __IO uint32_t host_channel_ctlr = 0U;
+
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+    /* clear old interrupt conditions for this host channel */
+    USB_HCHxINTF((uint16_t)hc_num) = 0xFFFFFFFFU;
+
+    if (1U == pudev->cfg.dma_enable) {
+        host_channel_inten |= HCHINTEN_DMAERIE;
+    }
+
+    /* enable channel interrupts required for this transfer */
+    switch (puhc->endp_type) {
+        case USB_EPTYPE_CTRL:
+        case USB_EPTYPE_BULK:
+            host_channel_inten |= HCHINTEN_TFIE | HCHINTEN_STALLIE | HCHINTEN_USBERIE \
+                        | HCHINTEN_DTERIE | HCHINTEN_NAKIE;
+
+            if (puhc->endp_in) {
+                host_channel_inten |= HCHINTEN_BBERIE;
+            } else {
+                host_channel_inten |= HCHINTEN_NYETIE;
+
+                if (puhc->do_ping) {
+                    host_channel_inten |= HCHINTEN_ACKIE;
+                }
+            }
+            break;
+
+        case USB_EPTYPE_INTR:
+            host_channel_inten |= HCHINTEN_TFIE | HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE \
+                            | HCHINTEN_NAKIE | HCHINTEN_REQOVRIE;
+
+            if (puhc->endp_in) {
+                host_channel_inten |= HCHINTEN_BBERIE;
+            }
+            break;
+
+        case USB_EPTYPE_ISOC:
+            host_channel_inten |= HCHINTEN_TFIE | HCHINTEN_REQOVRIE | HCHINTEN_ACKIE;
+
+            if (puhc->endp_in) {
+                host_channel_inten |= HCHINTEN_USBERIE | HCHINTEN_BBERIE;
+            }
+            break;
+
+        default:
+            break;
+    }
+
+    USB_HCHxINTEN((uint16_t)hc_num) = host_channel_inten;
+
+    /* enable the top level host channel interrupt */
+    USB_HACHINTEN |= 1U << hc_num;
+
+    /* make sure host channel interrupts are enabled */
+    USB_GINTEN |= GINTEN_HCIE;
+
+    /* program the hcctlr register */
+    host_channel_ctlr = 0U;
+
+    if (HPRT_PRTSPD_LOW_SPEED == puhc->dev_speed) {
+        is_low_speed = 1U;
+    }
+
+    host_channel_ctlr |= (uint32_t)puhc->dev_addr << 22U;
+    host_channel_ctlr |= (uint32_t)puhc->endp_type << 18U;
+    host_channel_ctlr |= (uint32_t)puhc->endp_id << 11U;
+    host_channel_ctlr |= (uint32_t)puhc->endp_in << 15U;
+    host_channel_ctlr |= (uint32_t)is_low_speed << 17U;
+    host_channel_ctlr |= puhc->endp_mps;
+
+    if (HCCHAR_INTR == puhc->endp_type) {
+        host_channel_ctlr |= HCHCTL_ODDFRM;
+    }
+
+    USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctlr;
+
+    return status;
+}
+
+/*!
+    \brief      prepare host channel for transferring packets
+    \param[in]  pudev: pointer to usb device
+    \param[in]  hc_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_hostchannel_startxfer(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+    usb_status_enum status = USB_OK;
+
+    uint16_t dword_len = 0U;
+    uint16_t packet_num = 0U;
+
+    __IO uint32_t host_channel_xlen = 0U;
+    __IO uint32_t host_channel_ctlr = 0U;
+
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+    /* compute the expected number of packets associated to the transfer */
+    if (puhc->xfer_len > 0U) {
+        packet_num = ((uint16_t)puhc->xfer_len + puhc->endp_mps - 1U) / puhc->endp_mps;
+
+        if (packet_num > HC_MAX_PACKET_COUNT) {
+            packet_num = HC_MAX_PACKET_COUNT;
+            puhc->xfer_len = (uint32_t)(packet_num) * (uint32_t)(puhc->endp_mps);
+        }
+    } else {
+        packet_num = 1U;
+    }
+
+    if (puhc->endp_in) {
+        puhc->xfer_len = (uint32_t)(packet_num) * (uint32_t)(puhc->endp_mps);
+    }
+
+    /* initialize the host channel length register */
+    host_channel_xlen &= ~HCHLEN_TLEN;
+    host_channel_xlen |= puhc->xfer_len;
+    host_channel_xlen &= ~HCHLEN_PCNT;
+    host_channel_xlen |= (uint32_t)packet_num << 19U;
+    host_channel_xlen &= ~HCHLEN_DPID;
+    host_channel_xlen |= (uint32_t)(puhc->DPID) << 29U;
+    USB_HCHxLEN((uint16_t)hc_num) = (uint32_t)host_channel_xlen;
+
+    if (1U == pudev->cfg.dma_enable) {
+        USB_HCHxDMAADDR((uint16_t)hc_num) = (uint32_t)puhc->xfer_buff;
+    }
+
+    /* set host channel enable */
+    host_channel_ctlr = USB_HCHxCTL((uint16_t)hc_num);
+
+    if (1U == USB_EVEN_FRAME()) {
+        host_channel_ctlr |= HCHCTL_ODDFRM;
+    } else {
+        host_channel_ctlr &= ~HCHCTL_ODDFRM;
+    }
+
+    host_channel_ctlr |= HCHCTL_CEN;
+    host_channel_ctlr &= ~HCHCTL_CDIS;
+    USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctlr;
+
+    if (0U == pudev->cfg.dma_enable) {
+        if ((0U == puhc->endp_in) && (puhc->xfer_len > 0U)) {
+            dword_len = (uint16_t)(puhc->xfer_len + 3U) / 4U;
+
+            switch (puhc->endp_type) {
+                /* non-periodic transfer */
+                case USB_EPTYPE_CTRL:
+                case USB_EPTYPE_BULK:
+                    /* check if there is enough space in fifo space */
+                    if (dword_len > (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) {
+                        /* need to process data in non-periodic transfer fifo empty interrupt */
+                        USB_GINTEN |= GINTEN_NPTXFEIE;
+                    }
+                    break;
+
+                /* periodic transfer */
+                case USB_EPTYPE_INTR:
+                case USB_EPTYPE_ISOC:
+                    /* check if there is enough space in FIFO space */
+                    if (dword_len > (USB_HPTFQSTAT & HPTFQSTAT_PTXFS)) {
+                        /* need to process data in periodic transfer fifo empty interrupt */
+                        USB_GINTEN |= GINTEN_PTXFEIE;
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+
+            /* write packet into the Tx FIFO. */
+            usb_fifo_write(puhc->xfer_buff, hc_num, (uint16_t)puhc->xfer_len);
+        }
+    }
+
+    return status;
+}
+
+/*!
+    \brief      halt channel
+    \param[in]  pudev: pointer to usb device
+    \param[in]  hc_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_hostchannel_halt(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+    uint8_t endp_type = 0U;
+    __IO uint32_t host_channel_ctrl = USB_HCHxCTL((uint16_t)hc_num);
+
+    host_channel_ctrl |= HCHCTL_CEN | HCHCTL_CDIS;
+
+    endp_type = (uint8_t)((host_channel_ctrl & HCHCTL_EPTYPE) >> 18U);
+
+    /* check for space in the request queue to issue the halt. */
+    if ((HCCHAR_CTRL == endp_type) || (HCCHAR_BULK == endp_type)) {
+        if (0U == (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) {
+            host_channel_ctrl |= HCHCTL_CDIS;
+        }
+    } else {
+        if (0U == (USB_HPTFQSTAT & HPTFQSTAT_PTXFS)) {
+            host_channel_ctrl |= HCHCTL_CEN;
+        }
+    }
+
+    USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctrl;
+
+    return USB_OK;
+}
+
+/*!
+    \brief      issue a ping token
+    \param[in]  pudev: pointer to usb device
+    \param[in]  hc_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_hostchannel_ping(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+    uint32_t host_channel_ctrl = 0U;
+
+    USB_HCHxLEN((uint16_t)hc_num) = HCHLEN_PING | (HCHLEN_PCNT & (1U << 19U));
+
+    host_channel_ctrl = USB_HCHxCTL((uint16_t)hc_num);
+    host_channel_ctrl |= HCHCTL_CEN;
+    host_channel_ctrl &= ~HCHCTL_CDIS;
+
+    USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctrl;
+
+    return USB_OK;
+}
+
+/*!
+    \brief      stop the USB host and clean up fifos
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void usb_host_stop(usb_core_handle_struct *pudev)
+{
+    uint32_t i;
+
+    /* disable all host channel interrupt */
+    USB_HACHINTEN = 0U;
+    USB_HACHINT = 0xFFFFFFFFU;
+
+    /* flush out any leftover queued requests */
+    for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
+        USB_HCHxCTL(i) |= HCHCTL_CEN | HCHCTL_CDIS | HCHCTL_EPDIR;
+    }
+
+    /* flush the FIFO */
+    usb_rxfifo_flush(pudev);
+    usb_txfifo_flush(pudev, 0x10U);
+}
+
+#endif /* USE_HOST_MODE */
+
+
+#ifdef USE_DEVICE_MODE
+
+#ifdef USBFS_CORE
+
+/* USB endpoint Tx FIFO size */
+static uint16_t USBFS_TX_FIFO_SIZE[USBFS_MAX_DEV_EPCOUNT] = 
+{
+    (uint16_t)TX0_FIFO_FS_SIZE,
+    (uint16_t)TX1_FIFO_FS_SIZE,
+    (uint16_t)TX2_FIFO_FS_SIZE,
+    (uint16_t)TX3_FIFO_FS_SIZE
+};
+
+#elif defined(USBHS_CORE)
+
+uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_DEV_EPCOUNT] = 
+{
+    (uint16_t)TX0_FIFO_HS_SIZE,
+    (uint16_t)TX1_FIFO_HS_SIZE,
+    (uint16_t)TX2_FIFO_HS_SIZE,
+    (uint16_t)TX3_FIFO_HS_SIZE,
+    (uint16_t)TX4_FIFO_HS_SIZE,
+    (uint16_t)TX5_FIFO_HS_SIZE
+};
+
+#endif /* USBFS_CORE */
+
+static usb_status_enum usb_devint_enable(usb_core_handle_struct *pudev);
+
+/*!
+    \brief      initialize USB core registers for device mode
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+usb_status_enum usb_devcore_init (usb_core_handle_struct *pudev)
+{
+    uint32_t i, ram_address = 0U;
+    __IO uint32_t dev_in_ep0_inf = USB_DIEP0TFLEN;
+    __IO uint32_t dev_in_ep_inf = 0U;
+
+    /* restart the Phy Clock (Maybe don't need to...) */
+    USB_PWRCLKCTL = 0U;
+
+    /* config periodic frmae interval to default */
+    USB_DCFG &= ~DCFG_EOPFT;
+    USB_DCFG |= FRAME_INTERVAL_80;
+
+#ifdef USBFS_CORE
+    if (USB_FS_CORE_ID == pudev->cfg.core_id) {
+        /* set full speed PHY */
+        USB_DCFG &= ~DCFG_DS;
+        USB_DCFG |= USB_SPEED_INP_FULL;
+
+        /* set Rx FIFO size */
+        USB_GRFLEN &= ~GRFLEN_RXFD;
+        USB_GRFLEN |= RX_FIFO_FS_SIZE;
+
+        /* set endpoint 0 Tx FIFO length and RAM address */
+        dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXFD;
+        dev_in_ep0_inf |= TX0_FIFO_FS_SIZE << 16;
+        dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXRSAR;
+        dev_in_ep0_inf |= RX_FIFO_FS_SIZE;
+
+        USB_DIEP0TFLEN = dev_in_ep0_inf;
+
+        ram_address = RX_FIFO_FS_SIZE;
+
+        /* set endpoint 1 to 3's Tx FIFO length and RAM address */
+        for (i = 1U; i < USBFS_MAX_DEV_EPCOUNT; i++) {
+            ram_address += USBFS_TX_FIFO_SIZE[i - 1U];
+
+            dev_in_ep_inf &= ~DIEPTFLEN_IEPTXFD;
+            dev_in_ep_inf |= (uint32_t)USBFS_TX_FIFO_SIZE[i] << 16U;
+            dev_in_ep_inf &= ~DIEPTFLEN_IEPTXRSAR;
+            dev_in_ep_inf |= ram_address;
+
+            USB_DIEPxTFLEN(i) = dev_in_ep_inf;
+        }
+    }
+#endif /* USBFS_CORE */
+
+#ifdef USBHS_CORE
+    if (USB_HS_CORE_ID == pudev->cfg.core_id) {
+        USB_DCFG &= ~DCFG_DS;
+
+        if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
+            /* set full speed PHY in USB high speed core */
+            USB_DCFG |= USB_SPEED_INP_FULL;
+        } else if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) {
+            USB_DCFG |= USB_SPEED_EXP_HIGH;
+        }
+
+        /* set Rx FIFO size */
+        USB_GRFLEN &= ~GRFLEN_RXFD;
+        USB_GRFLEN |= RX_FIFO_HS_SIZE;
+
+        /* set endpoint 0 Tx FIFO length and RAM address */
+        dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXFD;
+        dev_in_ep0_inf |= TX0_FIFO_HS_SIZE << 16;
+        dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXRSAR;
+        dev_in_ep0_inf |= RX_FIFO_HS_SIZE;
+
+        USB_DIEP0TFLEN = dev_in_ep0_inf;
+
+        ram_address = RX_FIFO_HS_SIZE;
+
+        /* set endpoint 1 to 3's Tx FIFO length and RAM address */
+        for (i = 1; i < USBHS_MAX_DEV_EPCOUNT; i++) {
+            ram_address += USBHS_TX_FIFO_SIZE[i - 1];
+
+            dev_in_ep_inf &= ~DIEPTFLEN_IEPTXFD;
+            dev_in_ep_inf |= USBHS_TX_FIFO_SIZE[i] << 16;
+            dev_in_ep_inf &= ~DIEPTFLEN_IEPTXRSAR;
+            dev_in_ep_inf |= ram_address;
+
+            USB_DIEPxTFLEN(i) = dev_in_ep_inf;
+        }
+    }
+#endif /* USBHS_CORE */
+
+    /* make sure all FIFOs are flushed */
+
+    /* flush all Tx FIFOs */
+    usb_txfifo_flush(pudev, 0x10U);
+
+    /* flush entire Rx FIFO */
+    usb_rxfifo_flush(pudev);
+
+    /* clear all pending device interrupts */
+    USB_DIEPINTEN = 0U;
+    USB_DOEPINTEN = 0U;
+    USB_DAEPINT = 0xFFFFFFFF;
+    USB_DAEPINTEN = 0U;
+
+    /* configure all IN/OUT endpoints */
+    for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
+        if (USB_DIEPxCTL(i) & DIEPCTL_EPEN) {
+            USB_DIEPxCTL(i) |= DIEPCTL_EPD | DIEPCTL_SNAK;
+        } else {
+            USB_DIEPxCTL(i) = 0U;
+        }
+
+        if (USB_DOEPxCTL(i) & DOEPCTL_EPEN) {
+            USB_DOEPxCTL(i) |= DOEPCTL_EPD | DOEPCTL_SNAK;
+        } else {
+            USB_DOEPxCTL(i) = 0U;
+        }
+
+        /* set IN/OUT endpoint transfer length to 0 */
+        USB_DIEPxLEN(i) = 0U;
+        USB_DOEPxLEN(i) = 0U;
+
+        /* clear all pending IN/OUT endpoints interrupts */
+        USB_DIEPxINTF(i) = 0xFFU;
+        USB_DOEPxINTF(i) = 0xFFU;
+    }
+
+    USB_DIEPINTEN |= DIEPINTEN_EPTXFUDEN;
+    usb_devint_enable(pudev);
+
+    return USB_OK;
+}
+
+/*!
+    \brief      enable the device mode interrupts
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     status
+*/
+static usb_status_enum usb_devint_enable(usb_core_handle_struct *pudev)
+{
+    uint32_t int_mask = 0U;
+
+    /* disable all interrupts */
+    USB_GINTEN = 0U;
+
+    /* clear any pending interrupts */
+    USB_GINTF = 0xBFFFFFFFU;
+
+    /* enable the common interrupts */
+    usb_commonint_enable(pudev);
+
+    if (0U == pudev->cfg.dma_enable) {
+        int_mask = GINTEN_RXFNEIE;
+    }
+
+    /* enable device_mode-related interrupts */
+    int_mask |= GINTEN_SPIE | GINTEN_RSTIE | GINTEN_ENUMFIE \
+               | GINTEN_IEPIE | GINTEN_OEPIE | GINTEN_SOFIE | GINTEN_ISOONCIE \
+               | GINTEN_ISOINCIE;
+
+#ifdef VBUS_SENSING_ENABLED
+    int_mask |= GINTEN_SESIE | GINTEN_OTGIE;
+#endif /* VBUS_SENSING_ENABLED */
+
+    USB_GINTEN &= ~int_mask;
+    USB_GINTEN |= int_mask;
+
+    return USB_OK;
+}
+
+/*!
+    \brief      configures endpoint 0 to receive SETUP packets
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     none
+*/
+void usb_ep0_startout(usb_core_handle_struct *pudev)
+{
+    __IO uint32_t ep0_xlen = 0U;
+
+    /* set OUT endpoint 0 receive length to 24 bytes */
+    ep0_xlen &= ~DOEP0LEN_TLEN;
+    ep0_xlen |= 8U * 3U;
+
+    /* set OUT endpoint 0 receive length to 1 packet */
+    ep0_xlen &= ~DOEP0LEN_PCNT;
+    ep0_xlen |= 1U << 19;
+
+    /* set SETUP packet count to 3 */
+    ep0_xlen &= ~DOEP0LEN_STPCNT;
+    ep0_xlen |= 3U << 29;
+
+    USB_DOEPxLEN(0U) = ep0_xlen;
+
+    if (1U == pudev->cfg.dma_enable) {
+        USB_DOEPxDMAADDR(0U) = (uint32_t)&pudev->dev.setup_packet;
+
+        USB_DOEPxCTL(0U) = DOEPCTL_EPEN | DOEPCTL_EPACT;
+    }
+}
+
+/*!
+    \brief      active remote wakeup signalling
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     none
+*/
+void usb_remotewakeup_active(usb_core_handle_struct *pudev)
+{
+    __IO uint32_t power_clock;
+
+    if (pudev->dev.remote_wakeup) {
+        if (1U == (USB_DSTAT & DSTAT_SPST)) {
+            if (pudev->cfg.low_power) {
+                /* ungate USB core clock */
+                power_clock = USB_PWRCLKCTL;
+                power_clock &= ~PWRCLKCTL_SHCLK;
+                power_clock &= ~PWRCLKCTL_SUCLK;
+
+                USB_PWRCLKCTL = power_clock;
+            }
+
+            /* active remote wakeup signaling */
+            USB_DCTL |= DCTL_RWKUP;
+
+            if (pudev->mdelay != (void *)0) {
+                pudev->mdelay(5U);
+            }
+
+            USB_DCTL &= ~DCTL_RWKUP;
+        }
+    }
+}
+
+/*!
+    \brief      active USB core clock
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     none
+*/
+void usb_clock_ungate(usb_core_handle_struct *pudev)
+{
+    if (pudev->cfg.low_power) {
+        __IO uint32_t power_clock;
+
+        if (1U == (USB_DSTAT & DSTAT_SPST)) {
+            /* un-gate USB core clock */
+            power_clock = USB_PWRCLKCTL;
+            power_clock &= ~PWRCLKCTL_SHCLK;
+            power_clock &= ~PWRCLKCTL_SUCLK;
+
+            USB_PWRCLKCTL = power_clock;
+        }
+    }
+}
+
+/*!
+    \brief      stop the device and clean up fifos
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     none
+*/
+void usb_device_stop (usb_core_handle_struct *pudev)
+{
+    uint32_t i;
+
+    pudev->dev.status = 1U;
+
+    for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
+        USB_DIEPxINTF(i) = 0xFFU;
+        USB_DOEPxINTF(i) = 0xFFU;
+    }
+
+    USB_DIEPINTEN = 0U;
+    USB_DOEPINTEN = 0U;
+    USB_DAEPINTEN = 0U;
+    USB_DAEPINT = 0xFFFFFFFFU;
+
+    /* flush the FIFO */
+    usb_rxfifo_flush(pudev);
+    usb_txfifo_flush(pudev, 0x10U);
+}
+#endif /* USE_DEVICE_MODE */

+ 520 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_core.c

@@ -0,0 +1,520 @@
+/*!
+    \file  usbd_core.c
+    \brief USB device-mode core driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "usbd_core.h"
+#include "usbd_std.h"
+
+/*!
+    \brief      initailizes the USB device-mode handler stack
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  core_id: USB core ID
+    \param[out] none
+    \retval     none
+*/
+void usbd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id)
+{
+    /* select USB core */
+    usb_core_select (pudev, core_id);
+
+    pudev->dev.status = USB_STATUS_DEFAULT;
+
+    /* disable USB global interrupt */
+    USB_GLOBAL_INT_DISABLE();
+
+    /* init the core (common init.) */
+    usb_core_init(pudev);
+
+    /* force device mode*/
+    usb_mode_set(pudev, DEVICE_MODE);
+
+    /* set device disconnect */
+    USB_SOFT_DISCONNECT_ENABLE();
+
+    if ((void *)0 != pudev->mdelay) {
+        pudev->mdelay(3U);
+    }
+
+    /* init device */
+    usb_devcore_init(pudev);
+
+    /* set device Connect */
+    USB_SOFT_DISCONNECT_DISABLE();
+
+    if ((void *)0 != pudev->mdelay) {
+        pudev->mdelay(3U);
+    }
+
+    /* enable USB global interrupt */
+    USB_GLOBAL_INT_ENABLE();
+}
+
+/*!
+    \brief      endpoint initialization
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  pep_desc: pointer to usb endpoint descriptor 
+    \param[out] none
+    \retval     none
+*/
+void usbd_ep_init (usb_core_handle_struct *pudev, const usb_descriptor_endpoint_struct *pep_desc)
+{
+    usb_ep_struct *ep;
+
+    uint32_t dev_all_ep_int_en = 0U;
+    uint32_t dev_ep_ctlr = 0U; 
+
+    uint8_t ep_id = pep_desc->bEndpointAddress & 0x7FU;
+    uint8_t ep_type = pep_desc->bmAttributes & USB_EPTYPE_MASK;
+    uint16_t ep_mps = pep_desc->wMaxPacketSize;
+
+    if (pep_desc->bEndpointAddress >> 7) {
+        ep = &pudev->dev.in_ep[ep_id];
+
+        dev_all_ep_int_en |= 1U << ep_id;
+        dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id);
+
+        /* if the endpoint is not active, need change the endpoint control register */
+        if (!(dev_ep_ctlr & DIEPCTL_EPACT)) {
+            if (0U == ep_id) {
+                dev_ep_ctlr &= ~DIEP0CTL_MPL;
+            } else {
+                dev_ep_ctlr &= ~DIEPCTL_MPL;
+            }
+            dev_ep_ctlr |= ep_mps;
+
+            dev_ep_ctlr &= ~DIEPCTL_EPTYPE;
+            dev_ep_ctlr |= (uint32_t)ep_type << 18;
+
+            dev_ep_ctlr &= ~DIEPCTL_TXFNUM;
+            dev_ep_ctlr |= (uint32_t)ep_id << 22;
+
+            if (0U != ep_id) {
+                dev_ep_ctlr |= DIEPCTL_SD0PID;
+                dev_ep_ctlr |= DIEPCTL_EPACT;
+            }
+
+            USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+        }
+    } else {
+        ep = &pudev->dev.out_ep[ep_id];
+
+        dev_all_ep_int_en |= (1U << ep_id) << 16;
+        dev_ep_ctlr = USB_DOEPxCTL((uint16_t)ep_id);
+
+        /* if the endpoint is not active, need change the endpoint control register */
+        if (!(dev_ep_ctlr & DOEPCTL_EPACT)) {
+            if (0U == ep_id) {
+                dev_ep_ctlr &= ~DOEP0CTL_MPL;
+            } else {
+                dev_ep_ctlr &= ~DOEPCTL_MPL;
+            }
+            dev_ep_ctlr |= ep_mps;
+
+            dev_ep_ctlr &= ~DOEPCTL_EPTYPE;
+            dev_ep_ctlr |= (uint32_t)ep_type << 18;
+
+            if (0U != ep_id) {
+                dev_ep_ctlr |= DOEPCTL_SD0PID;
+                dev_ep_ctlr |= DOEPCTL_EPACT;
+            }
+
+            USB_DOEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+        }
+    }
+
+    ep->endp_mps = ep_mps;
+    ep->endp_type = ep_type;
+
+    /* enable the interrupts for this endpoint */
+#ifdef USBHS_DEDICATED_EP1_ENABLED
+    if ((1 == ep_id) && (USB_HS_CORE_ID == pudev->cfg.core_id)) {
+        USB_DEP1INTEN |= dev_all_ep_int_en;
+    } else
+#endif /* USBHS_DEDICATED_EP1_ENABLED */
+    {
+        USB_DAEPINTEN |= dev_all_ep_int_en;
+    }
+}
+
+/*!
+    \brief      endpoint deinitialize
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_addr: endpoint address
+    \param[out] none
+    \retval     none
+*/
+void usbd_ep_deinit (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+    uint32_t dev_all_ep_int_en = 0U;
+    uint8_t ep_id = ep_addr & 0x7FU;
+
+    if (ep_addr >> 7) {
+        dev_all_ep_int_en |= 1U << ep_id;
+
+        USB_DIEPxCTL((uint16_t)ep_id) &= ~DIEPCTL_EPACT;
+    } else {
+        dev_all_ep_int_en |= (1U << ep_id) << 16U;
+
+        USB_DOEPxCTL((uint16_t)ep_id) &= ~DOEPCTL_EPACT;
+    }
+
+    /* disable the interrupts for this endpoint */
+#ifdef USBHS_DEDICATED_EP1_ENABLED
+    if ((1U == ep_id) && (USB_HS_CORE_ID == pudev->cfg.core_id)) {
+        USB_DEP1INTEN &= ~dev_all_ep_int_en;
+    } else
+#endif /* USBHS_DEDICATED_EP1_ENABLED */
+    {
+        USB_DAEPINTEN &= ~dev_all_ep_int_en;
+    }
+}
+
+/*!
+    \brief      endpoint prepare to receive data
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_addr: endpoint address
+    \param[in]  pbuf: pointer to buffer
+    \param[in]  buf_len: buffer length
+    \param[out] none
+    \retval     none
+*/
+void usbd_ep_rx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len)
+{
+    usb_ep_struct *ep;
+    uint8_t ep_id = ep_addr & 0x7FU;
+    uint32_t dev_ep_ctlr = 0U, dev_ep_xlen = 0U;
+
+    ep = &pudev->dev.out_ep[ep_id];
+
+    /* setup and start the Xfer */
+    ep->xfer_buff = pbuf;
+    ep->xfer_len = buf_len;
+    ep->xfer_count = 0U;
+
+    if (1U == pudev->cfg.dma_enable) {
+        ep->dma_addr = (uint32_t)pbuf;
+    }
+
+    dev_ep_ctlr = USB_DOEPxCTL((uint16_t)ep_id);
+    dev_ep_xlen = USB_DOEPxLEN((uint16_t)ep_id);
+
+    dev_ep_xlen &= ~DOEPLEN_TLEN;
+    dev_ep_xlen &= ~DOEPLEN_PCNT;
+
+    /* zero length packet */
+    if (0U == ep->xfer_len) {
+        /* set the transfer length to max packet size */
+        dev_ep_xlen |= ep->endp_mps;
+
+        /* set the transfer packet count to 1 */
+        dev_ep_xlen |= 1U << 19U;
+    } else {
+        if (0U == ep_id) {
+            /* set the transfer length to max packet size */
+            dev_ep_xlen |= ep->endp_mps;
+
+            /* set the transfer packet count to 1 */
+            dev_ep_xlen |= 1U << 19U;
+        } else {
+            /* configure the transfer size and packet count as follows:
+             * pktcnt = N
+             * xfersize = N * maxpacket
+             */
+            dev_ep_xlen |= ((ep->xfer_len + ep->endp_mps - 1U) / ep->endp_mps) << 19U;
+            dev_ep_xlen |= ((dev_ep_xlen & DOEPLEN_PCNT) >> 19U) * ep->endp_mps;
+        }
+    }
+
+    USB_DOEPxLEN((uint16_t)ep_id) = dev_ep_xlen;
+
+    if (1U == pudev->cfg.dma_enable) {
+        USB_DOEPxDMAADDR((uint16_t)ep_id) = ep->dma_addr;
+    }
+
+    if (USB_EPTYPE_ISOC == ep->endp_type) {
+        if (ep->endp_frame) {
+            dev_ep_ctlr |= DOEPCTL_SODDFRM;
+        } else {
+            dev_ep_ctlr |= DOEPCTL_SEVNFRM;
+        }
+    }
+
+    /* enable the endpoint and clear the NAK */
+    dev_ep_ctlr |= DOEPCTL_EPEN | DOEPCTL_CNAK;
+
+    USB_DOEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+}
+
+/*!
+    \brief      endpoint prepare to transmit data
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_addr: endpoint address
+    \param[in]  pbuf: pointer to buffer
+    \param[in]  len: buffer length
+    \param[out] none
+    \retval     none
+*/
+void  usbd_ep_tx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
+{
+    usb_ep_struct *ep;
+    uint8_t ep_id = ep_addr & 0x7FU;
+    __IO uint32_t dev_ep_ctlr = 0U;
+    __IO uint32_t dev_ep_xlen = 0U;
+
+    ep = &pudev->dev.in_ep[ep_id];
+
+    /* setup and start the transfer */
+    ep->xfer_buff = pbuf;
+    ep->xfer_len = buf_len;
+    ep->xfer_count = 0U;
+
+    if (1U == pudev->cfg.dma_enable) {
+        ep->dma_addr = (uint32_t)pbuf;
+    }
+
+    dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id);
+    dev_ep_xlen = USB_DIEPxLEN((uint16_t)ep_id);
+
+    /* clear transfer length to 0 */
+    dev_ep_xlen &= ~DIEPLEN_TLEN;
+
+    /* clear transfer packet to 0 */
+    dev_ep_xlen &= ~DIEPLEN_PCNT;
+
+    /* zero length packet */
+    if (0U == ep->xfer_len) {
+        /* set transfer packet count to 1 */
+        dev_ep_xlen |= 1U << 19U;
+    } else {
+        if (0U == ep_id) {
+            if (ep->xfer_len > ep->endp_mps) {
+                ep->xfer_len = ep->endp_mps;
+            }
+
+            dev_ep_xlen |= 1U << 19U;
+        } else {
+            dev_ep_xlen |= ((ep->xfer_len - 1U + ep->endp_mps) / ep->endp_mps) << 19U;
+        }
+
+        /* configure the transfer size and packet count as follows: 
+         * xfersize = N * maxpacket + short_packet 
+         * pktcnt = N + (short_packet exist ? 1 : 0)
+         */
+        dev_ep_xlen |= ep->xfer_len;
+
+        if (USB_EPTYPE_ISOC == ep->endp_type) {
+            dev_ep_xlen |= DIEPLEN_MCNT & (1U << 29U);
+        }
+    }
+
+    USB_DIEPxLEN((uint16_t)ep_id) = dev_ep_xlen;
+
+    if (USB_EPTYPE_ISOC == ep->endp_type) {
+        if (0U == (((USB_DSTAT & DSTAT_FNRSOF) >> 8U) & 0x1U)) {
+            dev_ep_ctlr |= DIEPCTL_SODDFRM;
+        } else {
+            dev_ep_ctlr |= DIEPCTL_SEVNFRM;
+        }
+    }
+
+    if (1U == pudev->cfg.dma_enable) {
+        USB_DIEPxDMAADDR((uint16_t)ep_id) = ep->dma_addr;
+    }
+
+    /* enable the endpoint and clear the NAK */
+    dev_ep_ctlr |= DIEPCTL_EPEN | DIEPCTL_CNAK;
+
+    USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+
+    if (0U == pudev->cfg.dma_enable) {
+        if (USB_EPTYPE_ISOC != ep->endp_type) {
+            /* enable the Tx FIFO empty interrupt for this endpoint */
+            if (ep->xfer_len > 0U) {
+                USB_DIEPFEINTEN |= 1U << ep_id;
+            }
+        } else {
+            usb_fifo_write(ep->xfer_buff, ep_id, (uint16_t)ep->xfer_len);
+        }
+    }
+}
+
+/*!
+    \brief      transmit data on the control channel
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  pbuf: pointer to buffer
+    \param[in]  len: buffer length
+    \param[out] none
+    \retval     usb device operation status
+*/
+usbd_status_enum  usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len)
+{
+    usbd_status_enum ret = USBD_OK;
+
+    pudev->dev.sum_len = len;
+    pudev->dev.remain_len = len;
+    pudev->dev.ctl_status = USB_CTRL_DATA_IN;
+
+    usbd_ep_tx (pudev, 0U, pbuf, (uint32_t)len);
+
+    return ret;
+}
+
+/*!
+    \brief      receive data on the control channel
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  pbuf: pointer to buffer
+    \param[in]  len: buffer length
+    \param[out] none
+    \retval     usb device operation status
+*/
+usbd_status_enum  usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len)
+{
+    pudev->dev.sum_len = len;
+    pudev->dev.remain_len = len;
+    pudev->dev.ctl_status = USB_CTRL_DATA_OUT;
+
+    usbd_ep_rx (pudev, 0U, pbuf, len);
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      transmit status on the control channel
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     usb device operation status
+*/
+usbd_status_enum  usbd_ctlstatus_tx (usb_core_handle_struct *pudev)
+{
+    pudev->dev.ctl_status = USB_CTRL_STATUS_IN;
+
+    usbd_ep_tx (pudev, 0U, NULL, 0U);
+
+    usb_ep0_startout(pudev);
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      receive status on the control channel
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     usb device operation status
+*/
+usbd_status_enum  usbd_ctlstatus_rx (usb_core_handle_struct *pudev)
+{
+    pudev->dev.ctl_status = USB_CTRL_STATUS_OUT;
+
+    usbd_ep_rx (pudev, 0U, NULL, 0U);
+
+    usb_ep0_startout(pudev);
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      set an endpoint to STALL status
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_addr: endpoint address
+    \param[out] none
+    \retval     none
+*/
+void  usbd_ep_stall (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+    uint8_t ep_id = ep_addr & 0x7FU;
+    __IO uint32_t dev_ep_ctlr = 0U;
+
+    if (ep_addr >> 7U) {
+        dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id);
+
+        /* set the endpoint disable bit */
+        if (dev_ep_ctlr & DIEPCTL_EPEN) {
+            dev_ep_ctlr |= DIEPCTL_EPD;
+        }
+
+        /* set the endpoint stall bit */
+        dev_ep_ctlr |= DIEPCTL_STALL;
+
+        USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+    } else {
+        /* set the endpoint stall bit */
+        USB_DOEPxCTL((uint16_t)ep_id) |= DOEPCTL_STALL;
+    }
+}
+
+/*!
+    \brief      clear endpoint stalled status
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_addr: endpoint address
+    \param[out] none
+    \retval     none
+*/
+void usbd_ep_clear_stall (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+    usb_ep_struct *ep;
+    uint8_t ep_id = ep_addr & 0x7FU;
+    __IO uint32_t dev_ep_ctlr = 0U;
+
+    if(ep_addr >> 7){
+        ep = &pudev->dev.in_ep[ep_id];
+
+        dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id);
+
+        /* clear the IN endpoint stall bits */
+        dev_ep_ctlr &= ~DIEPCTL_STALL;
+
+        if ((USB_EPTYPE_INTR == ep->endp_type) || (USB_EPTYPE_BULK == ep->endp_type)) {
+            dev_ep_ctlr |= DIEPCTL_SEVNFRM;
+        }
+
+        USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+    } else {
+        ep = &pudev->dev.out_ep[ep_id];
+
+        dev_ep_ctlr = USB_DOEPxCTL((uint16_t)ep_id);
+
+        /* clear the OUT endpoint stall bits */
+        dev_ep_ctlr &= ~DOEPCTL_STALL;
+
+        if ((USB_EPTYPE_INTR == ep->endp_type) || (USB_EPTYPE_BULK == ep->endp_type)) {
+            dev_ep_ctlr |= DOEPCTL_SEVNFRM;
+        }
+
+        USB_DOEPxCTL((uint16_t)ep_id) = dev_ep_ctlr;
+    }
+}
+
+/*!
+    \brief      flushes the FIFOs
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_addr: endpoint address
+    \param[out] none
+    \retval     none
+*/
+void  usbd_ep_fifo_flush (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+    if (ep_addr >> 7) {
+        usb_txfifo_flush(pudev, ep_addr & 0x7FU);
+    } else {
+        usb_rxfifo_flush(pudev);
+    }
+}
+
+/*!
+    \brief      get the received data length
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_id: endpoint identifier which is in (0..3)
+    \param[out] none
+    \retval     received data length
+*/
+uint16_t  usbd_rxcount_get (usb_core_handle_struct *pudev, uint8_t ep_id)
+{
+    return (uint16_t)pudev->dev.out_ep[ep_id].xfer_count;
+}

+ 758 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_int.c

@@ -0,0 +1,758 @@
+/*!
+    \file  usbd_int.c
+    \brief USB device mode interrupt routines
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "usbd_int.h"
+#include "usbd_std.h"
+
+/* interrupt handlers */
+static uint32_t usbd_intf_outep               (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_inep                (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_earlysuspend        (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_suspend             (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_resume              (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_sof                 (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_rxfifo              (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_reset               (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_enumfinish          (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_isoinincomplete     (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_isooutincomplete    (usb_core_handle_struct *pudev);
+
+static uint32_t usbd_emptytxfifo_write        (usb_core_handle_struct *pudev, uint8_t ep_num);
+
+#ifdef VBUS_SENSING_ENABLED
+
+    static uint32_t usbd_intf_otg             (usb_core_handle_struct *pudev);
+    static uint32_t usbd_intf_sessionrequest  (usb_core_handle_struct *pudev);
+
+#endif
+
+static usb_speed_enum USB_SPEED[4] = {
+    [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_HIGH,
+    [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_FULL,
+    [DSTAT_ENUMSPD_FS_PHY_48MHZ] = USB_SPEED_FULL,
+    [DSTAT_ENUMSPD_LS_PHY_6MHZ] = USB_SPEED_LOW
+};
+
+static const uint8_t EP0_MAXLEN[4] = {
+    [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64,
+    [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64,
+    [DSTAT_ENUMSPD_FS_PHY_48MHZ] = EP0MPL_64,
+    [DSTAT_ENUMSPD_LS_PHY_6MHZ] = EP0MPL_8
+};
+
+#ifdef USBHS_DEDICATED_EP1_ENABLED
+
+/*!
+    \brief      USB dedicated OUT endpoint 1 interrupt service routine handler
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+uint32_t USBD_EP1OUT_ISR_Handler (usb_core_handle_struct *pudev)
+{
+    uint32_t out_endp_int = 0;
+    uint32_t out_endp_size = 0;
+
+    out_endp_int = USB_DOEPxINTF(1);
+    out_endp_int &= USB_DOEP1INTEN;
+
+    /* transfer complete */
+    if (out_endp_int & DOEPINTF_TF) {
+        /* clear the interrupt bit */
+        USB_DOEPxINTF(1) = DOEPINTF_TF;
+
+        if (1U == pudev->cfg.dma_enable) {
+            out_endp_size = USB_DOEPxLEN(1);
+
+            /* handle more than one single MPS size packet */
+            pudev->dev.out_ep[1].xfer_count = pudev->dev.out_ep[1].endp_mps - \
+                                              (out_endp_size & DOEPLEN_TLEN);
+        }
+
+        /* inform upper layer: data ready */
+
+        /* receive complete */
+        usbd_out_transaction(pudev, 1);
+    }
+
+    /* endpoint disable interrupt */
+    if (out_endp_int & DOEPINTF_EPDIS) {
+        /* clear the interrupt bit */
+        USB_DOEPxINTF(1) = DOEPINTF_EPDIS;
+    }
+
+    return 1;
+}
+
+/*!
+    \brief      USB dedicated IN endpoint 1 interrupt service routine handler
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+uint32_t USBD_EP1IN_ISR_Handler (usb_core_handle_struct *pudev)
+{
+    uint32_t fifoemptymask = 0, mask = 0;
+    uint32_t in_endp_int = 0;
+
+    mask = USB_DIEP1INTEN;
+    mask |= ((USB_DIEPFEINTEN >> 1) & 0x01) << 7;
+    in_endp_int = USB_DIEPxINTF(1) & mask;
+
+    if (in_endp_int & DIEPINTF_TF) {
+        fifoemptymask = 0x01 << 1;
+        USB_DIEPFEINTEN &= ~fifoemptymask;
+
+        USB_DIEPxINTF(1) = DIEPINTF_TF;
+
+        /* transmit complete */
+        usbd_in_transaction(pudev , 1);
+    }
+
+    if (in_endp_int & DIEPINTF_EPDIS) {
+        USB_DIEPxINTF(1) = DIEPINTF_EPDIS;
+    }
+
+    if (in_endp_int & DIEPINTF_CITO) {
+        USB_DIEPxINTF(1) = DIEPINTF_CITO;
+    }
+
+    if (in_endp_int & DIEPINTF_EPTXFUD) {
+        USB_DIEPxINTF(1) = DIEPINTF_EPTXFUD;
+    }
+
+    if (in_endp_int & DIEPINTF_IEPNE) {
+        USB_DIEPxINTF(1) = DIEPINTF_IEPNE;
+    }
+
+    if (in_endp_int & DIEPINTF_TXFE) {
+        usbd_emptytxfifo_write(pudev, 1);
+
+        USB_DIEPxINTF(1) = DIEPINTF_IEPNE;
+    }
+
+    return 1;
+}
+
+#endif
+
+
+/*!
+    \brief      USB device-mode interrupts global service routine handler
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+uint32_t usbd_isr (usb_core_handle_struct *pudev)
+{
+    uint32_t retval = 0U;
+    uint32_t int_status = 0U, gintf = USB_GINTF, ginten = USB_GINTEN;
+
+    /* ensure the core is in device mode */
+    if (DEVICE_MODE == USB_CURRENT_MODE_GET()) {
+        int_status = gintf & ginten;
+
+        /* there are no interrupts, avoid spurious interrupt */
+        if (!int_status) {
+            return 0U;
+        }
+
+        /* OUT endpoints interrupts */
+        if (int_status & GINTF_OEPIF) {
+            retval |= usbd_intf_outep(pudev);
+        }
+
+        /* IN endpoints interrupts */
+        if (int_status & GINTF_IEPIF) {
+            retval |= usbd_intf_inep(pudev);
+        }
+
+        /* mode mismatch interrupt */
+        if (int_status & GINTF_MFIF) {
+            /* clear interrupt */
+            USB_GINTF = GINTF_MFIF;
+        }
+
+        /* early suspend interrupt */
+        if (int_status & GINTF_ESP) {
+            retval |= usbd_intf_earlysuspend(pudev);
+        }
+
+        /* suspend interrupt */
+        if (int_status & GINTF_SP) {
+            retval |= usbd_intf_suspend(pudev);
+        }
+
+        /* wakeup interrupt */
+        if (int_status & GINTF_WKUPIF) {
+            retval |= usbd_intf_resume(pudev);
+        }
+
+        /* start of frame interrupt */
+        if (int_status & GINTF_SOF) {
+            retval |= usbd_intf_sof(pudev);
+        }
+
+        /* reveive fifo not empty interrupt */
+        if (int_status & GINTF_RXFNEIF) {
+            retval |= usbd_intf_rxfifo(pudev);
+        }
+
+        /* USB reset interrupt */
+        if (int_status & GINTF_RST) {
+            retval |= usbd_intf_reset(pudev);
+        }
+
+        /* enumeration has been finished interrupt */
+        if (int_status & GINTF_ENUMFIF) {
+            retval |= usbd_intf_enumfinish(pudev);
+        }
+
+        /* incomplete synchronization in transfer interrupt*/
+        if (int_status & GINTF_ISOINCIF) {
+            retval |= usbd_intf_isoinincomplete(pudev);
+        }
+
+        /* incomplete synchronization out transfer interrupt*/
+        if (int_status & GINTF_ISOONCIF) {
+            retval |= usbd_intf_isooutincomplete(pudev);
+        }
+
+#ifdef VBUS_SENSING_ENABLED
+
+        /* session request interrupt */
+        if (int_status & GINTF_SESIF) {
+            retval |= usbd_intf_sessionrequest(pudev);
+        }
+
+        /* OTG mode interrupt */
+        if (int_status & GINTF_OTGIF) {
+            retval |= usbd_intf_otg(pudev);
+        }
+#endif /* VBUS_SENSING_ENABLED */
+    }
+
+    return retval;
+}
+
+/*!
+    \brief      indicates that an OUT endpoint has a pending interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev)
+{
+    uint8_t endp_num = 0U;
+    uint32_t endp_intr = 0U;
+
+    __IO uint32_t out_endp_intr = 0U;
+
+    /* read in the device interrupt bits */
+    USB_DAOEP_INTR_READ(endp_intr);
+
+    while (endp_intr) {
+        if (endp_intr & 0x1U) {
+            USB_DOEP_INTR_READ(out_endp_intr, (uint16_t)endp_num);
+
+            /* transfer complete interrupt */
+            if (out_endp_intr & DOEPINTF_TF) {
+                USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_TF;
+
+                if (1U == pudev->cfg.dma_enable) {
+                    uint32_t xfer_size = USB_DOEPxLEN((uint16_t)endp_num) & DOEPLEN_TLEN;
+
+                    pudev->dev.out_ep[endp_num].xfer_count = pudev->dev.out_ep[endp_num].endp_mps - \
+                                                             xfer_size;
+                }
+
+                /* data receive is completed */
+                usbd_out_transaction(pudev, endp_num);
+   
+                if (1U == pudev->cfg.dma_enable) {
+                    if ((0U == endp_num) && (USB_CTRL_STATUS_OUT == pudev->dev.ctl_status)) {
+                        /* prepare to receive more setup packets */
+                        usb_ep0_startout(pudev);
+                    }
+                }
+            }
+
+            /* endpoint disable interrupt */
+            if (out_endp_intr & DOEPINTF_EPDIS) {
+                USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_EPDIS;
+            }
+
+            /* setup phase finished interrupt (just for control endpoints) */
+            if (out_endp_intr & DOEPINTF_STPF) {
+                /* setup phase is completed */
+                usbd_setup_transaction(pudev);
+
+                USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_STPF;
+            }
+
+            /* back to back setup packets received */
+            if (out_endp_intr & DOEPINTF_BTBSTP) {
+                USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_BTBSTP;
+            }
+        }
+
+        endp_num ++;
+        endp_intr >>= 1;
+    }
+
+    return 1U;
+}
+
+/*!
+    \brief      indicates that an IN endpoint has a pending interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_inep(usb_core_handle_struct *pudev)
+{
+    uint8_t endp_num = 0U;
+    uint32_t endp_intr = 0U;
+
+    __IO uint32_t in_endp_intr = 0U;
+
+    /* get all in endpoints which have interrupts */
+    USB_DAIEP_INTR_READ(endp_intr);
+
+    while (endp_intr) {
+        if (endp_intr & 0x1U) {
+            USB_DIEP_INTR_READ(in_endp_intr, (uint16_t)endp_num);
+
+            if (in_endp_intr & DIEPINTF_TF) {
+                /* disable the fifo empty interrupt for the endpoint */
+                USB_DIEPFEINTEN &= ~(0x1U << endp_num);
+
+                USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TF;
+
+                /* data transmittion is completed */
+                usbd_in_transaction(pudev, endp_num);
+
+                if (1U == pudev->cfg.dma_enable) {
+                    if ((0U == endp_num) && (USB_CTRL_STATUS_IN == pudev->dev.ctl_status)) {
+                        /* prepare to receive more setup packets */
+                        usb_ep0_startout(pudev);
+                    }
+                }
+            }
+
+            if (in_endp_intr & DIEPINTF_CITO) {
+                USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_CITO;
+            }
+
+            if (in_endp_intr & DIEPINTF_IEPNE) {
+                USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_IEPNE;
+            }
+
+            if (in_endp_intr & DIEPINTF_EPDIS) {
+                USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_EPDIS;
+            }
+
+            if (in_endp_intr & DIEPINTF_TXFE) {
+                usbd_emptytxfifo_write(pudev, endp_num);
+                USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TXFE;
+            }
+        }
+
+        endp_num ++;
+        endp_intr >>= 1;
+    }
+
+    return 1U;
+}
+
+/*!
+    \brief      indicates that early SUSPEND state has been detected on the USB
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev)
+{
+    USB_GINTEN &= ~GINTEN_ESPIE;
+    USB_GINTF = GINTF_ESP;
+
+    return 1U;
+}
+
+/*!
+    \brief      indicates that SUSPEND state has been detected on the USB
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_suspend(usb_core_handle_struct *pudev)
+{
+    __IO uint8_t low_power = pudev->cfg.low_power;
+    __IO uint8_t suspend = (uint8_t)(USB_DSTAT & DSTAT_SPST);
+    __IO uint8_t is_configured = (pudev->dev.status == USB_STATUS_CONFIGURED)? 1U : 0U;
+
+    pudev->dev.prev_status = pudev->dev.status;
+    pudev->dev.status = USB_STATUS_SUSPENDED;
+
+    if (low_power && suspend && is_configured) {
+        /* switch-off the otg clocks */
+        USB_PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK;
+
+        /* enter DEEP_SLEEP mode with LDO in low power mode */
+        pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
+    }
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_SP;
+
+    return 1U;
+}
+
+/*!
+    \brief      indicates that the USB controller has detected a resume or remote Wake-up sequence
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev)
+{
+    pudev->dev.status = pudev->dev.prev_status;
+    pudev->dev.status = USB_STATUS_CONFIGURED;
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_WKUPIF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the SOF interrupts
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_sof(usb_core_handle_struct *pudev)
+{
+//    USBD_DCD_INT_fops->SOF(pudev);
+
+    USB_GINTF = GINTF_SOF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the Rx status queue level interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev)
+{
+    usb_ep_struct *ep;
+    uint8_t data_pid = 0U, endp_num = 0U;
+    uint32_t bcount = 0U;
+
+    /* get the status from the top of the fifo (must be read to a variable) */
+    __IO uint32_t rx_status = USB_GRSTATP;
+
+    /* disable the rx fifo non-empty interrupt */
+    USB_GINTEN &= ~GINTEN_RXFNEIE;
+
+    endp_num = (uint8_t)(rx_status & GRSTATP_EPNUM);
+    bcount = (rx_status & GRSTATP_BCOUNT) >> 4U;
+    data_pid = (uint8_t)((rx_status & GRSTATP_DPID) >> 15U);
+
+    if ((endp_num == 1) && ((*(uint32_t *)0x40040B30 & 0x1FF80000) == 0)) {
+        *(uint32_t *)0x40040B20 = ((*(uint32_t *)0x40040B20 | 0x08000000) & 0x3FFFFFFF);
+    }
+
+    ep = &pudev->dev.out_ep[endp_num];
+
+    switch ((rx_status & GRSTATP_RPCKST) >> 17U) {
+        case RXSTAT_GOUT_NAK:
+            if(0U != bcount) {
+                return 0U;
+            }
+            break;
+        case RXSTAT_DATA_UPDT:
+            if (bcount > 0U) {
+                usb_fifo_read(ep->xfer_buff, (uint16_t)bcount);
+                ep->xfer_buff += bcount;
+                ep->xfer_count += bcount;
+            }
+            break;
+        case RXSTAT_XFER_COMP:
+            if (0U != bcount) {
+                return 0U;
+            }
+            break;
+        case RXSTAT_SETUP_COMP:
+            if(0U != bcount) {
+                return 0U;
+            }
+            break;
+        case RXSTAT_SETUP_UPDT:
+            if ((0U == endp_num) && (8U == bcount) && (DPID_DATA0 == data_pid)) {
+                /* copy the setup packet received in fifo into the setup buffer in ram */
+                usb_fifo_read(pudev->dev.setup_packet, 8U);
+
+                ep->xfer_count += bcount;
+            }
+            break;
+        default:
+            break;
+    }
+
+    /* enable the Rx fifo non-empty interrupt */
+    USB_GINTEN |= GINTEN_RXFNEIE;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle USB reset interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_intf_reset(usb_core_handle_struct *pudev)
+{
+    uint8_t i = 0U;
+    usb_ep_struct *ep;
+
+    /* clear the remote wakeup signaling */
+    USB_DCTL &= ~DCTL_RWKUP;
+
+    /* flush the tx fifo */
+    usb_txfifo_flush(pudev, 0U);
+
+    for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
+        USB_DIEPxINTF((uint16_t)i) = 0xFFU;
+        USB_DOEPxINTF((uint16_t)i) = 0xFFU;
+    }
+
+    /* clear all pending device endpoint interrupts */
+    USB_DAEPINT = 0xFFFFFFFF;
+
+    /* enable endpoint 0 interrupts */
+    USB_DAEPINTEN &= ~DAEPINTEN_OEPIE;
+    USB_DAEPINTEN &= ~DAEPINTEN_IEPIE;
+    USB_DAEPINTEN = (1U << 16) | 1U;
+
+    /* enable out endpoint interrupts */
+    USB_DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN | DOEPINTEN_EPDISEN;
+
+#ifdef USBHS_DEDICATED_EP1_ENABLED
+    USB_DOEP1INTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN | DOEPINTEN_EPDISEN;
+#endif
+
+    /* enable in endpoint interrupts */
+    USB_DIEPINTEN = DIEPINTEN_TFEN | DIEPINTEN_CITOEN | DIEPINTEN_EPDISEN;
+
+#ifdef USBHS_DEDICATED_EP1_ENABLED
+    USB_DIEP1INTEN = DIEPINTEN_TFEN | DIEPINTEN_CITOEN | DIEPINTEN_EPDISEN;
+#endif
+
+    /* reset device address */
+    USB_DCFG &= ~DCFG_DAR;
+    USB_DCFG |= 0U << 4U;
+
+    /* configure endpoint 0 to receive setup packets */
+    usb_ep0_startout(pudev);
+
+    /* clear usb reset interrupt */
+    USB_GINTF = GINTF_RST;
+
+    /* open EP0 IN */
+    ep = &pudev->dev.in_ep[0];
+
+    USB_DIEPxCTL(0U) &= ~DIEP0CTL_MPL;
+    USB_DIEPxCTL(0U) &= ~DIEPCTL_EPTYPE;
+    USB_DIEPxCTL(0U) &= ~DIEPCTL_TXFNUM;
+
+    if (!(USB_DIEPxCTL(0U) & DIEPCTL_EPACT)) {
+        USB_DIEPxCTL(0U) |= USB_MAX_EP0_SIZE;
+        USB_DIEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U);
+        USB_DIEPxCTL(0U) |= DIEP0CTL_EPACT;
+    }
+
+    ep->endp_mps = USB_MAX_EP0_SIZE;
+    ep->endp_type = USB_EPTYPE_CTRL;
+
+    /* open EP0 OUT */
+    ep = &pudev->dev.out_ep[0];
+
+    USB_DOEPxCTL(0U) &= ~DOEP0CTL_MPL;
+    USB_DOEPxCTL(0U) &= ~DOEPCTL_EPTYPE;
+
+    if (!(USB_DOEPxCTL(0U) & DOEPCTL_EPACT)) {
+        USB_DOEPxCTL(0U) |= USB_MAX_EP0_SIZE;
+        USB_DOEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U);
+        USB_DOEPxCTL(0U) |= DOEP0CTL_EPACT;
+    }
+
+    ep->endp_mps = USB_MAX_EP0_SIZE;
+    ep->endp_type = USB_EPTYPE_CTRL;
+
+    pudev->dev.status = USB_STATUS_DEFAULT;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle enumeration finish interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_intf_enumfinish(usb_core_handle_struct *pudev)
+{
+    uint8_t enum_speed = (uint8_t)((USB_DSTAT & DSTAT_ES) >> 1U);
+
+    /* set the max packet size of devie in endpoint based on the enumeration speed */
+    USB_DIEPxCTL(0U) |= EP0_MAXLEN[enum_speed];
+
+    /* clear global IN NAK */
+    USB_DCTL &= ~DCTL_CGINAK;
+    USB_DCTL |= DCTL_CGINAK;
+
+    /* set USB turn-around time based on device speed and PHY interface */
+    if (USB_SPEED_HIGH == USB_SPEED[enum_speed]) {
+        pudev->cfg.core_speed = USB_CORE_SPEED_HIGH;
+        pudev->cfg.max_packet_size = USBHS_MAX_PACKET_SIZE;
+
+        USB_GUSBCS &= ~GUSBCS_UTT;
+        USB_GUSBCS |= 0x09U << 10;
+    } else {
+        pudev->cfg.core_speed = USB_CORE_SPEED_FULL;
+        pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE;
+
+        USB_GUSBCS &= ~GUSBCS_UTT;
+        USB_GUSBCS |= 0x05U << 10;
+    }
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_ENUMFIF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the ISO IN incomplete interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_intf_isoinincomplete(usb_core_handle_struct *pudev)
+{
+//    USBD_DCD_INT_fops->IsoINIncomplete (pudev);
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_ISOINCIF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the ISO OUT incomplete interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_intf_isooutincomplete(usb_core_handle_struct *pudev)
+{
+//    USBD_DCD_INT_fops->IsoOUTIncomplete (pudev);
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_ISOONCIF;
+
+    return 1U;
+}
+
+/*!
+    \brief      check FIFO for the next packet to be loaded
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  ep_id: endpoint identifier which is in (0..3)
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_emptytxfifo_write(usb_core_handle_struct *pudev, uint8_t ep_num)
+{
+    uint32_t len = 0U, word_len = 0U;
+    usb_ep_struct *ep;
+
+    ep = &pudev->dev.in_ep[ep_num];
+    len = ep->xfer_len - ep->xfer_count;
+
+    if (len > ep->endp_mps) {
+        len = ep->endp_mps;
+    }
+
+    word_len = (len + 3U) / 4U;
+
+    while (((USB_DIEPxTFSTAT((uint16_t)ep_num) & DIEPTFSTAT_IEPTFS) > word_len) &&
+            (ep->xfer_count < ep->xfer_len)) {
+        /* write the FIFO */
+        len = ep->xfer_len - ep->xfer_count;
+
+        if (len > ep->endp_mps) {
+            len = ep->endp_mps;
+        }
+
+        word_len = (len + 3U) / 4U;
+
+        usb_fifo_write (ep->xfer_buff, ep_num, (uint16_t)len);
+
+        ep->xfer_buff += len;
+        ep->xfer_count += len;
+    }
+
+    return 1U;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+
+/*!
+    \brief      indicates that the USB_OTG controller has detected a connection
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_intf_sessionrequest(usb_core_handle_struct *pudev)
+{
+    pudev->dev.connection_status = 1U;
+
+    /* clear the interrupt bit */
+    USB_GINTF = GINTF_SESIF;
+
+    return 1;
+}
+
+/*!
+    \brief      indicates that the USB_OTG controller has detected an OTG event
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     status
+*/
+static uint32_t usbd_intf_otg(usb_core_handle_struct *pudev)
+{
+    if (USB_GOTGINTF & GOTGINTF_SESEND) {
+        pudev->dev.class_deinit(pudev, 0);
+        pudev->dev.connection_status = 0;
+    }
+
+    /* clear OTG interrupt */
+    USB_GOTGINTF |= GOTGINTF_SESEND;
+
+    return 1;
+}
+
+#endif /* VBUS_SENSING_ENABLED */

+ 699 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_std.c

@@ -0,0 +1,699 @@
+/*!
+    \file  usbd_std.c
+    \brief USB 2.0 standard handler driver
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "usbd_std.h"
+#include "usb_core.h"
+
+static usbd_status_enum usbd_standard_request     (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static usbd_status_enum usbd_vendor_request       (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+static void usbd_getdescriptor  (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setaddress     (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setconfig      (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_getconfig      (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_getstatus      (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setfeature     (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_clrfeature     (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_reserved       (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setdescriptor  (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_getinterface   (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setinterface   (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_synchframe     (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
+static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
+static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
+
+static void (*StandardDeviceRequest[])(usb_core_handle_struct *pudev, usb_device_req_struct *req) =
+{
+    usbd_getstatus,
+    usbd_clrfeature,
+    usbd_reserved,
+    usbd_setfeature,
+    usbd_reserved,
+    usbd_setaddress,
+    usbd_getdescriptor,
+    usbd_setdescriptor,
+    usbd_getconfig,
+    usbd_setconfig,
+    usbd_getinterface,
+    usbd_setinterface,
+    usbd_synchframe,
+};
+
+/* get standard descriptor handler */
+static uint8_t* (*standard_descriptor_get[])(usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) = 
+{
+    usbd_device_descriptor_get,
+    usbd_configuration_descriptor_get,
+    usbd_string_descriptor_get
+};
+
+/*!
+    \brief      USB setup stage processing
+    \param[in]  pudev: pointer to USB device instance
+    \param[out] none
+    \retval     USB device operation status
+*/
+usbd_status_enum usbd_setup_transaction(usb_core_handle_struct *pudev)
+{
+    usb_device_req_struct req;
+
+    usbd_setup_request_parse(pudev, &req);
+
+    switch (req.bmRequestType & USB_REQ_MASK) {
+        /* standard device request */
+        case USB_STANDARD_REQ:
+            usbd_standard_request(pudev, &req);
+            break;
+        /* device class request */
+        case USB_CLASS_REQ:
+            usbd_device_class_request(pudev, &req);
+            break;
+        /* vendor defined request */
+        case USB_VENDOR_REQ:
+            usbd_vendor_request(pudev, &req);
+            break;
+        default:
+            usbd_ep_stall(pudev, req.bmRequestType & 0x80U);
+            break;
+    }
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      data out stage processing
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  ep_id: endpoint identifier(0..7)
+    \param[out] none
+    \retval     USB device operation status
+*/
+usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
+{
+    usb_ep_struct *ep;
+
+    if (0U == endp_num) {
+        ep = &pudev->dev.out_ep[0];
+
+        if (USB_CTRL_DATA_OUT == pudev->dev.ctl_status) {
+            if (pudev->dev.remain_len > ep->endp_mps) {
+                pudev->dev.remain_len -= ep->endp_mps;
+
+                if (1U == pudev->cfg.dma_enable) {
+                    /* update buffer location */
+                    ep->xfer_buff += ep->endp_mps;
+                }
+
+                usbd_ep_rx (pudev, 
+                            0U, 
+                            ep->xfer_buff, 
+                            (uint16_t)USB_MIN(pudev->dev.remain_len, ep->endp_mps));
+            } else {
+                if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+                    pudev->dev.class_data_handler(pudev, USBD_RX, 0U);
+                }
+
+                usbd_ctlstatus_tx(pudev);
+            }
+        }
+    } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+        pudev->dev.class_data_handler(pudev, USBD_RX, endp_num);
+    } else {
+        /* no operation */
+    }
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      data in stage processing
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  ep_id: endpoint identifier(0..7)
+    \param[out] none
+    \retval     USB device operation status
+*/
+usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
+{
+    usb_ep_struct *ep;
+
+    if (0U == endp_num) {
+        ep = &pudev->dev.in_ep[0];
+
+        if (USB_CTRL_DATA_IN == pudev->dev.ctl_status) {
+            if (pudev->dev.remain_len > ep->endp_mps) {
+                pudev->dev.remain_len -= ep->endp_mps;
+
+                if (1U == pudev->cfg.dma_enable) {
+                    /* update buffer location */
+                    ep->xfer_buff += ep->endp_mps;
+                }
+
+                usbd_ep_tx (pudev, 0U, ep->xfer_buff, pudev->dev.remain_len);
+            } else {
+                /* last packet is MPS multiple, so send ZLP packet */
+                if ((pudev->dev.sum_len % ep->endp_mps == 0U) &&
+                     (pudev->dev.sum_len >= ep->endp_mps) &&
+                      (pudev->dev.sum_len < pudev->dev.ctl_len)) {
+                    usbd_ep_tx (pudev, 0U, NULL, 0U);
+                    pudev->dev.ctl_len = 0U;
+                } else {
+                    if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+                        pudev->dev.class_data_handler(pudev, USBD_TX, 0U);
+                    }
+
+                    usbd_ctlstatus_rx(pudev);
+                }
+            }
+        }
+    } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+        pudev->dev.class_data_handler(pudev, USBD_TX, endp_num);
+    } else {
+        /* no operation */
+    }
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      handle USB standard device request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     USB device operation status
+*/
+static usbd_status_enum  usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    /* call device request handle function */
+    (*StandardDeviceRequest[req->bRequest])(pudev, req);
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      handle USB device class request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device class request
+    \param[out] none
+    \retval     USB device operation status
+*/
+static usbd_status_enum  usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    usbd_status_enum ret = USBD_OK;
+
+    switch (pudev->dev.status) {
+        case USB_STATUS_CONFIGURED:
+            if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
+                ret = (usbd_status_enum)(pudev->dev.class_req_handler(pudev, req));
+
+                if ((0U == req->wLength) && (USBD_OK == ret)) {
+                    /* no data stage */
+                    usbd_ctlstatus_tx(pudev);
+                }
+            } else {
+                usbd_enum_error(pudev, req);
+            }
+            break;
+
+        default:
+            usbd_enum_error(pudev, req);
+            break;
+    }
+
+    return ret;
+}
+
+/*!
+    \brief      handle USB vendor request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB vendor request
+    \param[out] none
+    \retval     USB device operation status
+*/
+static usbd_status_enum  usbd_vendor_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    /* added by user... */
+
+    return USBD_OK;
+}
+
+/*!
+    \brief      no operation, just for reserved
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_reserved (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    /* no operation... */
+}
+
+/*!
+    \brief      get the device descriptor
+    \brief[in]  index: no use
+    \param[in]  none
+    \param[out] pLen: data length pointer
+    \retval     descriptor buffer pointer
+*/
+static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
+{
+    *pLen = pudev->dev.dev_desc[0];
+
+    return pudev->dev.dev_desc;
+}
+
+/*!
+    \brief      get the configuration descriptor
+    \brief[in]  index: no use
+    \param[in]  none
+    \param[out] pLen: data length pointer
+    \retval     descriptor buffer pointer
+*/
+static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
+{
+    *pLen = pudev->dev.config_desc[2];
+
+    return pudev->dev.config_desc;
+}
+
+/*!
+    \brief      get string descriptor
+    \param[in]  index: string descriptor index
+    \param[in]  pLen: pointer to string length
+    \param[out] none
+    \retval     none
+*/
+static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
+{
+    uint8_t *desc = pudev->dev.strings[index];
+
+    *pLen = desc[0];
+
+    return desc;
+}
+
+/*!
+    \brief      handle Get_Status request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_getstatus (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+}
+
+/*!
+    \brief      handle USB Clear_Feature request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    uint8_t ep_addr = 0U;
+
+    switch (req->bmRequestType & USB_REQTYPE_MASK) {
+        case USB_REQTYPE_DEVICE:
+            switch (pudev->dev.status) {
+                case USB_STATUS_ADDRESSED:
+                case USB_STATUS_CONFIGURED:
+                    if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
+                        pudev->dev.remote_wakeup = 0U;
+                        pudev->dev.class_req_handler(pudev, req);
+
+                        usbd_ctlstatus_tx(pudev);
+                    }
+                    break;
+
+                default:
+                    usbd_enum_error(pudev, req);
+                    break;
+            }
+            break;
+        case USB_REQTYPE_INTERFACE:
+            switch (pudev->dev.status) {
+                case USB_STATUS_ADDRESSED:
+                    usbd_enum_error(pudev, req);
+                    break;
+                case USB_STATUS_CONFIGURED:
+                    if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
+                        /* no operation */
+                    } else {
+                        usbd_enum_error(pudev, req);
+                    }
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case USB_REQTYPE_ENDPOINT:
+            ep_addr = LOWBYTE(req->wIndex);
+
+            switch (pudev->dev.status) {
+                case USB_STATUS_ADDRESSED:
+                    if (IS_NOT_EP0(ep_addr)) {
+                        usbd_ep_stall(pudev, ep_addr);
+                    }
+                    break;
+                case USB_STATUS_CONFIGURED:
+                    if (USB_FEATURE_ENDP_HALT == req->wValue) {
+                        if (IS_NOT_EP0(ep_addr)) {
+                            usbd_ep_clear_stall(pudev, ep_addr);
+
+                            pudev->dev.class_req_handler(pudev, req);
+                        }
+                    }
+                    usbd_ctlstatus_tx(pudev);
+                    break;
+                default:
+                    break;
+            }
+            break;
+        default:
+            usbd_enum_error(pudev, req);
+            break;
+    }
+}
+
+/*!
+    \brief      handle USB Set_Feature request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    uint8_t ep_addr = 0U;
+    __IO uint32_t DctlrStatus;
+
+    switch (req->bmRequestType & USB_REQ_MASK) {
+        case USB_REQTYPE_DEVICE:
+            switch (pudev->dev.status) {
+                case USB_STATUS_ADDRESSED:
+                case USB_STATUS_CONFIGURED:
+                    if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
+                        pudev->dev.remote_wakeup = 1U;
+                        pudev->dev.class_req_handler(pudev, req);
+
+                        usbd_ctlstatus_tx(pudev);
+                    } else if ((req->wValue == USB_FEATURE_TEST_MODE) && 
+                                (0U == (req->wIndex & 0xFFU))) {
+                        DctlrStatus = USB_DCTL;
+
+                        usbd_ctlstatus_tx(pudev);
+                    } else {
+                        /* no operation */
+                    }
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case USB_REQTYPE_INTERFACE:
+            switch (pudev->dev.status) {
+                case USB_STATUS_ADDRESSED:
+                    usbd_enum_error(pudev, req);
+                    break;
+                case USB_STATUS_CONFIGURED:
+                    if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
+                        /* no operation */
+                    } else {
+                        usbd_enum_error(pudev, req);
+                    }
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case USB_REQTYPE_ENDPOINT:
+            switch (pudev->dev.status) {
+                case USB_STATUS_ADDRESSED:
+                    if (IS_NOT_EP0(ep_addr)) {
+                        usbd_ep_stall(pudev, ep_addr);
+                    }
+                    break;
+                case USB_STATUS_CONFIGURED:
+                    if (USB_FEATURE_ENDP_HALT == req->wValue) {
+                        if (IS_NOT_EP0(ep_addr)) {
+                            usbd_ep_stall(pudev, ep_addr);
+                        }
+                    }
+                    pudev->dev.class_req_handler(pudev, req);
+
+                    usbd_ctlstatus_tx(pudev);
+                    break;
+                default:
+                    break;
+            }
+            break;
+        default:
+            usbd_enum_error(pudev, req);
+            break;
+    }
+}
+
+/*!
+    \brief      handle USB Set_Address request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    uint8_t DevAddr;
+
+    if ((0U == req->wIndex) && (0U == req->wLength)) {
+        DevAddr = (uint8_t)(req->wValue) & 0x7FU;
+
+        if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+            usbd_enum_error(pudev, req);
+        } else {
+            USB_SET_DEVADDR((uint32_t)DevAddr);
+
+            usbd_ctlstatus_tx(pudev);
+
+            if (0U != DevAddr) {
+                pudev->dev.status = USB_STATUS_ADDRESSED;
+            } else {
+                pudev->dev.status = USB_STATUS_DEFAULT;
+            }
+        }
+    } else {
+        usbd_enum_error(pudev, req);
+    }
+}
+
+/*!
+    \brief      handle USB Get_Descriptor request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQTYPE_MASK)) {
+        uint8_t desc_index = (uint8_t)(req->wValue >> 8U);
+
+        if (desc_index <= 0x03U) {
+            uint16_t len;
+            uint8_t *pbuf;
+
+            /* call corresponding descriptor get function */
+            pbuf = standard_descriptor_get[desc_index - 1U](pudev, (uint8_t)(req->wValue) & 0xFFU, &len);
+
+            if ((0U != len) && (0U != req->wLength)) {
+                len = USB_MIN(len, req->wLength);
+
+                if ((1U == desc_index) && (64U == req->wLength)) {
+                    len = 8U;
+                }
+
+                usbd_ctltx(pudev, pbuf, len);
+            }
+        } else {
+            usbd_enum_error(pudev, req);
+        }
+    } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQTYPE_MASK)) {
+        pudev->dev.class_req_handler(pudev, req);
+    } else {
+        /* no operation */
+    }
+}
+
+/*!
+    \brief      handle USB Set_Descriptor request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_setdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    /* no handle... */
+}
+
+/*!
+    \brief      handle USB Get_Configuration request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    uint32_t USBD_default_config = 0U;
+
+    if (1U != req->wLength) {
+        usbd_enum_error(pudev, req);
+    } else {
+        switch (pudev->dev.status) {
+            case USB_STATUS_ADDRESSED:
+                usbd_ctltx(pudev, (uint8_t *)&USBD_default_config, 1U);
+                break;
+            case USB_STATUS_CONFIGURED:
+                usbd_ctltx(pudev, &pudev->dev.config_num, 1U);
+                break;
+            default:
+                usbd_enum_error(pudev, req);
+                break;
+        }
+    }
+}
+
+/*!
+    \brief      handle USB Set_Configuration request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_setconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    static uint8_t  cfgidx;
+
+    cfgidx = (uint8_t)(req->wValue);
+
+    if (cfgidx > USBD_CFG_MAX_NUM) {
+        usbd_enum_error(pudev, req);
+    } else {
+        switch (pudev->dev.status) {
+            case USB_STATUS_ADDRESSED:
+                if (cfgidx) {
+                    pudev->dev.config_num = cfgidx;
+                    pudev->dev.status = USB_STATUS_CONFIGURED;
+                    pudev->dev.class_init(pudev, cfgidx);
+                }
+
+                usbd_ctlstatus_tx(pudev);
+                break;
+            case USB_STATUS_CONFIGURED:
+                if (0U == cfgidx) {
+                    pudev->dev.status = USB_STATUS_ADDRESSED;
+                    pudev->dev.config_num = cfgidx;
+                    pudev->dev.class_deinit(pudev, cfgidx);
+                } else if (cfgidx != pudev->dev.config_num) {
+                    /* clear old configuration */
+                    pudev->dev.class_deinit(pudev, pudev->dev.config_num);
+
+                    /* set new configuration */
+                    pudev->dev.config_num = cfgidx;
+                    pudev->dev.class_init(pudev, cfgidx);
+                } else {
+                    /* no operation */
+                }
+
+                usbd_ctlstatus_tx(pudev);
+                break;
+            default:
+                usbd_enum_error(pudev, req);
+                break;
+        }
+    }
+}
+
+/*!
+    \brief      handle USB Get_Interface request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_getinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    pudev->dev.class_req_handler(pudev, req);
+}
+
+/*!
+    \brief      handle USB Set_Interface request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_setinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    pudev->dev.class_req_handler(pudev, req);
+}
+
+/*!
+    \brief      handle USB SynchFrame request
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void  usbd_synchframe (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    /* no handle... */
+}
+
+/*!
+    \brief      decode setup data packet
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    uint8_t *psetup = pudev->dev.setup_packet;
+  
+    req->bmRequestType = *psetup;
+    req->bRequest      = *(uint8_t *)(psetup + 1U);
+    req->wValue        = SWAPBYTE (psetup + 2U);
+    req->wIndex        = SWAPBYTE (psetup + 4U);
+    req->wLength       = SWAPBYTE (psetup + 6U);
+
+    pudev->dev.ctl_len = req->wLength;
+}
+
+/*!
+    \brief      handle USB low level error event
+    \param[in]  pudev: pointer to USB device instance
+    \param[in]  req: pointer to USB device request
+    \param[out] none
+    \retval     none
+*/
+void usbd_enum_error(usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+    usbd_ep_stall(pudev, 0x80U);
+    usbd_ep_stall(pudev, 0x00U);
+    usb_ep0_startout(pudev);
+}

+ 710 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_core.c

@@ -0,0 +1,710 @@
+/*!
+    \file  usbh_core.c 
+    \brief this file implements the functions for the core state machine process
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "usbh_hcs.h"
+#include "usbh_core.h"
+#include "usbh_int.h"
+#include "stdio.h"
+#include "usbh_std.h"
+#include "usbh_ctrl.h"
+#include "usb_core.h"
+
+extern class_polling_fun_cb_struct class_polling_cb;
+
+uint8_t usbh_sof          (usb_core_handle_struct *pudev);
+uint8_t usbh_connected    (usb_core_handle_struct *pudev);
+uint8_t usbh_disconnected (usb_core_handle_struct *pudev);
+
+usbh_hcd_int_cb_struct usbh_hcd_int_cb = 
+{
+    usbh_sof,
+    usbh_connected,
+    usbh_disconnected,
+};
+
+usbh_hcd_int_cb_struct  *usbh_hcd_int_fops = &usbh_hcd_int_cb;
+extern usbh_state_handle_struct usbh_state_core;
+
+static void host_idle_handle             (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_dev_attached_handle     (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_dev_detached_handle     (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_enum_handle             (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_class_request_handle    (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_class_handle            (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_user_input_handle       (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_suspended_handle        (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_error_handle            (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+
+static usbh_status_enum class_req_state_polling_fun  (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+static usbh_status_enum class_state_polling_fun      (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+
+/* the host state handle function array */
+void (*host_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) =
+{
+    host_idle_handle,
+    host_dev_attached_handle,
+    host_dev_detached_handle,
+    host_detect_dev_speed_handle,
+    host_enum_handle,
+    host_class_request_handle,
+    host_class_handle,
+    host_user_input_handle,
+    host_suspended_handle,
+    host_error_handle,
+};
+
+/* the host state handle table */
+state_table_struct host_handle_table[HOST_HANDLE_TABLE_SIZE] = 
+{
+    /* the current state  the current event        the next state        the event function */
+    {HOST_IDLE,           HOST_EVENT_ATTACHED,     HOST_DEV_ATTACHED,    only_state_move     },
+    {HOST_DEV_ATTACHED,   HOST_EVENT_ENUM,         HOST_ENUMERATION,     only_state_move     },
+    {HOST_ENUMERATION,    HOST_EVENT_USER_INPUT,   HOST_USER_INPUT,      only_state_move     },
+    {HOST_USER_INPUT,     HOST_EVENT_CLASS_REQ,    HOST_CLASS_REQUEST,   only_state_move     },
+    {HOST_CLASS_REQUEST,  HOST_EVENT_CLASS,        HOST_CLASS,           only_state_move     },
+    {HOST_CLASS,          HOST_EVENT_ERROR,        HOST_ERROR,           only_state_move     },
+    {HOST_ERROR,          HOST_EVENT_IDLE,         HOST_IDLE,            only_state_move     },
+    {HOST_DEV_DETACHED,   HOST_EVENT_IDLE,         HOST_IDLE,            only_state_move     },
+    {HOST_CLASS_REQUEST,  HOST_EVENT_ERROR,        HOST_ERROR,           only_state_move     },
+};
+
+/*!
+    \brief      the polling function of HOST state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev, 
+                                         usbh_host_struct *puhost, 
+                                         void *pustate)
+{
+    usbh_state_handle_struct *p_state = (usbh_state_handle_struct *)pustate;
+
+    scd_begin(p_state, HOST_FSM_ID);
+
+    if (-1 == p_state->usbh_current_state_stack_top) {
+        uint8_t cur_state = p_state->usbh_current_state;
+
+        if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != cur_state)) {
+            if (HOST_DEV_DETACHED != cur_state) {
+                p_state->usbh_current_state = HOST_DEV_DETACHED;
+                cur_state = HOST_DEV_DETACHED;
+            }
+        }
+
+        host_state_handle[cur_state](pudev, puhost, p_state);
+    } else {
+        uint8_t stack0_state = p_state->stack[0].state;
+
+        if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != stack0_state)) {
+            if (HOST_DEV_DETACHED != stack0_state) {
+                p_state->stack[0].state = HOST_DEV_DETACHED;
+                stack0_state = HOST_DEV_DETACHED;
+                p_state->usbh_current_state = HOST_DEV_DETACHED;
+            }
+        }
+
+        host_state_handle[stack0_state](pudev, puhost, p_state);
+    }
+
+    return USBH_OK;
+}
+
+/*!
+    \brief      the handle function of HOST_IDLE state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_idle_handle (usb_core_handle_struct *pudev, 
+                              usbh_host_struct *puhost, 
+                              usbh_state_handle_struct *pustate)
+{
+    if (hcd_is_device_connected(pudev)) {
+        scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ATTACHED, pustate->usbh_current_state);
+
+        if ((void *)0 != pudev->mdelay) {
+            pudev->mdelay(100U);
+        }
+    }
+}
+
+/*!
+    \brief      the handle function of HOST_DEV_ATTACHED state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_dev_attached_handle (usb_core_handle_struct *pudev, 
+                                      usbh_host_struct *puhost, 
+                                      usbh_state_handle_struct *pustate)
+{
+    puhost->usr_cb->device_connected();
+    puhost->control.hc_out_num = usbh_channel_alloc(pudev, 0x00U);
+    puhost->control.hc_in_num = usbh_channel_alloc(pudev, 0x80U);
+
+    /* reset usb device */
+    if (0U == usb_port_reset(pudev)) {
+        puhost->usr_cb->device_reset();
+
+        /* wait for USB USBH_ISR_PrtEnDisableChange()
+         * host is now ready to start the enumeration
+         */
+        puhost->device.speed = (uint8_t)USB_CURRENT_SPEED_GET();
+        puhost->usr_cb->device_speed_detected(puhost->device.speed);
+
+        /* open IN control pipes */
+        usbh_channel_open (pudev,
+                           puhost->control.hc_in_num,
+                           puhost->device.address,
+                           puhost->device.speed,
+                           USB_EPTYPE_CTRL,
+                           (uint16_t)puhost->control.ep0_size);
+
+        /* open OUT control pipes */
+        usbh_channel_open (pudev,
+                           puhost->control.hc_out_num,
+                           puhost->device.address,
+                           puhost->device.speed,
+                           USB_EPTYPE_CTRL,
+                           (uint16_t)puhost->control.ep0_size);
+
+        scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ENUM, pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of HOST_ENUMERATION state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_enum_handle (usb_core_handle_struct *pudev, 
+                              usbh_host_struct *puhost, 
+                              usbh_state_handle_struct *pustate)
+{
+    if (USBH_OK == enum_state_polling_fun(pudev, puhost, pustate)) {
+        puhost->usr_cb->enumeration_finish();
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         HOST_EVENT_USER_INPUT, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of HOST_USER_INPUT state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_user_input_handle (usb_core_handle_struct *pudev, 
+                                    usbh_host_struct *puhost, 
+                                    usbh_state_handle_struct *pustate)
+{
+    if (USBH_USER_RESP_OK == puhost->usr_cb->user_input()) {
+        if (USBH_OK == (puhost->class_init(pudev, puhost))) {
+            scd_event_handle(pudev, 
+                             puhost, 
+                             pustate, 
+                             HOST_EVENT_CLASS_REQ, 
+                             pustate->usbh_current_state);
+        }
+    }
+}
+
+/*!
+    \brief      the handle function of HOST_CLASS_REQUEST state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_class_request_handle (usb_core_handle_struct *pudev, 
+                                       usbh_host_struct *puhost, 
+                                       usbh_state_handle_struct *pustate)
+{
+    if (USBH_OK == class_req_state_polling_fun(pudev, puhost, pustate)) {
+        scd_event_handle(pudev, puhost, pustate, HOST_EVENT_CLASS, pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of HOST_CLASS state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_class_handle (usb_core_handle_struct *pudev, 
+                               usbh_host_struct *puhost, 
+                               usbh_state_handle_struct *pustate)
+{
+    class_state_polling_fun(pudev, puhost, pustate);
+}
+
+/*!
+    \brief      the handle function of HOST_SUSPENDED state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_suspended_handle (usb_core_handle_struct *pudev, 
+                                   usbh_host_struct *puhost, 
+                                   usbh_state_handle_struct *pustate)
+{
+    /* no operation */
+}
+
+/*!
+    \brief      the handle function of HOST_ERROR state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_error_handle (usb_core_handle_struct *pudev, 
+                               usbh_host_struct *puhost, 
+                               usbh_state_handle_struct *pustate)
+{
+    /* re-initilaize host for new enumeration */
+    usbh_deinit (pudev, puhost,&usbh_state_core);
+    puhost->usr_cb->deinit();
+    puhost->class_deinit(pudev, &puhost->device);
+    scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state);
+}
+
+/*!
+    \brief      the handle function of HOST_DEV_DETACHED state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_dev_detached_handle (usb_core_handle_struct *pudev, 
+                                      usbh_host_struct *puhost, 
+                                      usbh_state_handle_struct *pustate)
+{
+    /* manage user disconnect operations*/
+    puhost->usr_cb->device_disconnected();
+
+    /* re-initilaize host for new enumeration */
+    usbh_deinit(pudev, puhost,&usbh_state_core);
+    puhost->usr_cb->deinit();
+    puhost->class_deinit(pudev, &puhost->device);
+    usbh_allchannel_dealloc(pudev);
+    scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state);
+}
+
+/*!
+    \brief      the handle function of HOST_DETECT_DEV_SPEED state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev, 
+                                          usbh_host_struct *puhost, 
+                                          usbh_state_handle_struct *pustate)
+{
+    /* no operation */
+}
+
+/*!
+    \brief      usb connect callback function from the interrupt. 
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+uint8_t usbh_connected (usb_core_handle_struct *pudev)
+{
+    pudev->host.connect_status = 1U;
+
+    return 0U;
+}
+
+/*!
+    \brief      usb disconnect callback function from the interrupt. 
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+uint8_t usbh_disconnected (usb_core_handle_struct *pudev)
+{
+    pudev->host.connect_status = 0U;
+
+    return 0U;
+}
+
+/*!
+    \brief      usb sof callback function from the interrupt. 
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     operation status
+*/
+uint8_t usbh_sof (usb_core_handle_struct *pudev)
+{
+    /* this callback could be used to implement a scheduler process */
+    return 0U;
+}
+
+/*!
+    \brief      initialize the host portion of the driver.
+    \param[in]  pudev: pointer to usb device
+    \param[in]  core_id: usb otg core identifier(high-speed or full-speed)
+    \param[out] none
+    \retval     operation status
+*/
+uint32_t hcd_init(usb_core_handle_struct *pudev, usb_core_id_enum core_id)
+{
+    pudev->host.connect_status = 0U;
+
+    pudev->host.host_channel[0].endp_mps = 8U;
+
+    usb_core_select(pudev, core_id);
+
+#ifndef DUAL_ROLE_MODE_ENABLED
+
+    USB_GLOBAL_INT_DISABLE();
+
+    usb_core_init(pudev);
+
+    /* force host mode*/
+    usb_mode_set(pudev, HOST_MODE);
+
+    usb_hostcore_init(pudev);
+
+    USB_GLOBAL_INT_ENABLE();
+
+#endif
+
+    return 0U;
+}
+
+/*!
+    \brief      check if the device is connected.
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     device connection status. 1 -> connected and 0 -> disconnected
+*/
+uint32_t hcd_is_device_connected(usb_core_handle_struct *pudev)
+{
+    return (uint32_t)(pudev->host.connect_status);
+}
+
+/*!
+    \brief      this function returns the last URBstate
+    \param[in]  pudev: pointer to usb device
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     urb_state_enum
+*/
+urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num) 
+{
+    return pudev->host.host_channel[channel_num].urb_state;
+}
+
+/*!
+    \brief      this function returns the last URBstate
+    \param[in]  pudev: pointer to usb device
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     No. of data bytes transferred
+*/
+uint32_t hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num) 
+{
+    return pudev->host.host_channel[channel_num].xfer_count;
+}
+
+/*!
+    \brief      de-initialize host
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[out] none
+    \retval     host status
+*/
+usbh_status_enum usbh_deinit(usb_core_handle_struct *pudev, 
+                             usbh_host_struct *puhost, 
+                             usbh_state_handle_struct* pustate)
+{
+    /* software init */
+
+    puhost->control.ep0_size = USB_MAX_EP0_SIZE;
+
+    puhost->device.address = USBH_DEVICE_ADDRESS_DEFAULT;
+    puhost->device.speed = HPRT_PRTSPD_FULL_SPEED;
+
+    usbh_channel_free(pudev, puhost->control.hc_in_num);
+    usbh_channel_free(pudev, puhost->control.hc_out_num);
+    
+    scd_init(pustate);
+    scd_table_regist(pustate, host_handle_table, HOST_FSM_ID, HOST_HANDLE_TABLE_SIZE);
+    scd_table_regist(pustate, enum_handle_table, ENUM_FSM_ID, ENUM_HANDLE_TABLE_SIZE);
+    scd_table_regist(pustate, ctrl_handle_table, CTRL_FSM_ID, CTRL_HANDLE_TABLE_SIZE);
+  
+    scd_begin(pustate,HOST_FSM_ID);
+    scd_state_move(pustate, HOST_IDLE);
+
+    return USBH_OK;
+}
+
+/*!
+    \brief      state core driver init
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+void scd_init(usbh_state_handle_struct* pustate)
+{
+    /* init the state core */
+    pustate->usbh_current_state = 0U;
+    pustate->usbh_current_state_table = NULL;
+    pustate->usbh_current_state_table_size = 0U;
+  
+    pustate->usbh_current_state_stack_top = -1;
+    pustate->stack->state = 0U;
+    pustate->stack->table_size = 0U;
+    pustate->stack->table = NULL;
+  
+    pustate->usbh_regist_state_table_num = 0U;
+    pustate->usbh_regist_state_table->table = NULL;
+    pustate->usbh_regist_state_table->table_size = 0U;
+    pustate->usbh_regist_state_table->id = 0U;
+  
+    /* init the control and the enumeration polling handle flag */
+    ctrl_polling_handle_flag = 0U;
+    enum_polling_handle_flag = 0U;
+}
+
+/*!
+    \brief      state core driver table regist
+    \param[in]  pustate: pointer to usb state driver
+    \param[in]  pstate_table: pointer to the table to regist
+    \param[in]  table_id: the id of the table to regist
+    \param[in]  current_table_size: the size of the current table to regist
+    \param[out] none
+    \retval     none
+*/
+void scd_table_regist (usbh_state_handle_struct* pustate, 
+                       state_table_struct* pstate_table, 
+                       uint8_t table_id, 
+                       uint8_t current_table_size)
+{
+    usbh_state_regist_table_struct *cur_state_reg_table;
+
+    cur_state_reg_table = &pustate->usbh_regist_state_table[pustate->usbh_regist_state_table_num];
+
+    cur_state_reg_table->id = table_id;
+    cur_state_reg_table->table = pstate_table;
+    cur_state_reg_table->table_size = current_table_size;
+
+    pustate->usbh_regist_state_table_num++;
+}
+
+/*!
+    \brief      state core driver begin
+    \param[in]  pustate: pointer to usb state driver
+    \param[in]  table_id: the id of the table to begin
+    \param[out] none
+    \retval     none
+*/
+void scd_begin(usbh_state_handle_struct* pustate, uint8_t table_id)
+{
+    uint8_t i = 0, table_num = pustate->usbh_regist_state_table_num;
+    usbh_state_regist_table_struct *cur_state_reg_table;
+
+    for (i = 0; i < table_num; i++) {
+        cur_state_reg_table = &pustate->usbh_regist_state_table[i];
+
+        if (table_id == cur_state_reg_table->id) {
+            pustate->usbh_current_state_table = cur_state_reg_table->table;
+            pustate->usbh_current_state_table_size = cur_state_reg_table->table_size;
+            break;
+        }
+    }
+}
+
+/*!
+    \brief      state core driver move state
+    \param[in]  pustate: pointer to usb state driver
+    \param[in]  state: the state to move
+    \param[out] none
+    \retval     none
+*/
+void scd_state_move(usbh_state_handle_struct* pustate, uint8_t state)
+{
+    pustate->usbh_current_state = state;
+}
+
+/*!
+    \brief      state core driver event handle
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[in]  event: the current event
+    \param[in]  state: the current state
+    \param[out] none
+    \retval     host status
+*/
+usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev, 
+                                   usbh_host_struct *puhost, 
+                                   usbh_state_handle_struct* pustate, 
+                                   uint8_t event, 
+                                   uint8_t state)
+{
+    uint8_t i = 0;
+    ACT_FUN event_act_fun = NULL;
+    state_table_struct *backup_state_t = pustate->usbh_current_state_table;
+    state_table_struct *executive_state_table = pustate->usbh_current_state_table;
+
+    /* look up the table to find the action function */
+    for (i = 0; i < pustate->usbh_current_state_table_size; i++) {
+        if (state == executive_state_table->cur_state) {
+            if (event == executive_state_table->cur_event) {
+                 state = executive_state_table->next_state;
+                 event_act_fun = executive_state_table->event_action_fun;
+                 break;
+            } else {
+                executive_state_table++;
+            }
+        } else {
+            executive_state_table++;
+        }
+    }
+
+    pustate->usbh_current_state_table = backup_state_t;
+
+    /* if the action function is not NULL, execute the action function */
+    if (event_act_fun) {
+        if (event_act_fun == &only_state_move) {
+            pustate->usbh_current_state = state;
+        } else {
+            return event_act_fun(pudev, puhost, pustate);
+        }
+    }
+
+    return USBH_BUSY;
+}
+
+/*!
+    \brief      state core driver table push
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+void scd_table_push(usbh_state_handle_struct* pustate)
+{
+    usbh_state_stack_struct *top_state_element;
+
+    if (pustate->usbh_current_state_stack_top < MAX_USBH_STATE_STACK_DEEP) {
+        pustate->usbh_current_state_stack_top++;
+
+        top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top];
+
+        /* put the current state table into the state stack */
+        top_state_element->state = pustate->usbh_current_state;
+        top_state_element->table = pustate->usbh_current_state_table;
+        top_state_element->table_size = pustate->usbh_current_state_table_size;
+    }
+}
+
+/*!
+    \brief      state core driver table pop
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+void scd_table_pop (usbh_state_handle_struct* pustate)
+{
+    usbh_state_stack_struct *top_state_element;
+
+    top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top];
+
+    if (pustate->usbh_current_state_stack_top > -1) {
+        /* get the current state table from the state stack */
+        pustate->usbh_current_state = top_state_element->state;
+        pustate->usbh_current_state_table = top_state_element->table;
+        pustate->usbh_current_state_table_size = top_state_element->table_size;
+        pustate->usbh_current_state_stack_top--;
+    }
+}
+/*!
+    \brief      the polling function of class req state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     host status
+*/
+static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+    return class_polling_cb.class_req_polling(pudev, puhost, pustate);
+}
+
+/*!
+    \brief      the polling function of class state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     host status
+*/
+static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+    return class_polling_cb.class_polling(pudev, puhost, pustate);
+}
+
+/*!
+    \brief      the function is only used to state move
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+    return USBH_OK;
+}
+
+/*!
+    \brief      the function to the up state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+    scd_table_pop((usbh_state_handle_struct *)pustate);
+
+    return USBH_OK;
+}

+ 620 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_ctrl.c

@@ -0,0 +1,620 @@
+/*!
+    \file  usbh_ctrl.c 
+    \brief this file implements the functions for the control transmit process
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+#include "usbh_core.h"
+#include "usbh_std.h"
+#include "usbh_ctrl.h"
+
+uint8_t ctrl_polling_handle_flag = 0U;
+uint8_t ctrl_setup_wait_flag = 0U;
+uint8_t ctrl_data_wait_flag = 0U;
+uint8_t ctrl_status_wait_flag = 0U;
+
+static uint16_t timeout = 0U;
+
+static void ctrl_idle_handle      (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_setup_handle     (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_data_handle      (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_status_handle    (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_error_handle     (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_stalled_handle   (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_complete_handle  (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+
+/* the ctrl state handle function array */
+void (*ctrl_state_handle[]) (usb_core_handle_struct *pudev, 
+                             usbh_host_struct *puhost, 
+                             usbh_state_handle_struct *pustate) =
+{
+    ctrl_idle_handle,
+    ctrl_setup_handle,
+    ctrl_data_handle,
+    ctrl_status_handle,
+    ctrl_error_handle,
+    ctrl_stalled_handle,
+    ctrl_complete_handle,
+};
+
+/* the ctrl state handle table */
+state_table_struct ctrl_handle_table[CTRL_HANDLE_TABLE_SIZE] = 
+{
+    /* the current state   the current event           the next state        the event function */
+    {CTRL_IDLE,            CTRL_EVENT_SETUP,           CTRL_SETUP,           only_state_move     },
+    {CTRL_SETUP,           CTRL_EVENT_DATA,            CTRL_DATA,            only_state_move     },
+    {CTRL_SETUP,           CTRL_EVENT_STATUS,          CTRL_STATUS,          only_state_move     },
+    {CTRL_SETUP,           CTRL_EVENT_ERROR,           CTRL_ERROR,           only_state_move     },
+    {CTRL_DATA,            CTRL_EVENT_STATUS,          CTRL_STATUS,          only_state_move     },
+    {CTRL_DATA,            CTRL_EVENT_ERROR,           CTRL_ERROR,           only_state_move     },
+    {CTRL_DATA,            CTRL_EVENT_STALLED,         CTRL_STALLED,         only_state_move     },
+    {CTRL_STATUS,          CTRL_EVENT_COMPLETE,        CTRL_COMPLETE,        only_state_move     },
+    {CTRL_STATUS,          CTRL_EVENT_ERROR,           CTRL_ERROR,           only_state_move     },
+    {CTRL_STATUS,          CTRL_EVENT_STALLED,         CTRL_STALLED,         only_state_move     },
+    {CTRL_ERROR,           GO_TO_UP_STATE_EVENT,       UP_STATE,             goto_up_state_fun   },
+    {CTRL_STALLED,         GO_TO_UP_STATE_EVENT,       UP_STATE,             goto_up_state_fun   },
+    {CTRL_COMPLETE,        GO_TO_UP_STATE_EVENT,       UP_STATE,             goto_up_state_fun   },
+};
+
+/*!
+    \brief      the polling function of CTRL state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+usbh_status_enum ctrl_state_polling_fun (usb_core_handle_struct *pudev, 
+                                    usbh_host_struct *puhost, 
+                                    void *pustate)
+{
+    usbh_status_enum exe_state = USBH_BUSY;
+    usbh_state_handle_struct *p_state;
+
+    p_state = (usbh_state_handle_struct *)pustate;
+  
+    /* if first enter this function, begin the ctrl state */
+    if (0U == ctrl_polling_handle_flag) {
+        ctrl_polling_handle_flag = 1U;
+        scd_table_push(p_state);
+        scd_state_move(p_state, CTRL_IDLE);
+    }
+
+    /* base on the current state to handle the ctrl state */
+    scd_begin(p_state, CTRL_FSM_ID);
+    ctrl_state_handle[p_state->usbh_current_state](pudev, puhost, p_state);
+
+    /* determine the control transfer whether to complete */
+    switch (puhost->usbh_backup_state.ctrl_backup_state) {
+        case CTRL_COMPLETE:
+            ctrl_polling_handle_flag = 0U;
+            puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+            exe_state = USBH_OK;
+            break;
+        case CTRL_STALLED:
+            ctrl_polling_handle_flag = 0U;
+            puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+            exe_state = USBH_NOT_SUPPORTED;
+            break;
+        case CTRL_ERROR:
+            ctrl_polling_handle_flag = 0U;
+            puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+            exe_state = USBH_FAIL;
+            break;
+        default:
+            exe_state = USBH_BUSY;
+            break;
+    }
+
+    return exe_state;
+}
+
+/*!
+    \brief      the handle function of CTRL_IDLE state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_idle_handle (usb_core_handle_struct *pudev, 
+                              usbh_host_struct *puhost, 
+                              usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+    scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_SETUP, pustate->usbh_current_state);
+}
+
+/*!
+    \brief      the handle function of CTRL_SETUP state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_setup_handle (usb_core_handle_struct *pudev, 
+                               usbh_host_struct *puhost, 
+                               usbh_state_handle_struct *pustate)
+{
+    urb_state_enum urb_status = URB_IDLE;
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_SETUP;
+
+    if (0U == ctrl_setup_wait_flag) {
+        ctrl_setup_wait_flag = 1U;
+
+        /* send a setup packet */
+        usbh_ctltx_setup (pudev, 
+                          puhost->control.setup.data, 
+                          puhost->control.hc_out_num);
+    } else {
+        urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num);
+
+        /* case setup packet sent successfully */
+        if (URB_DONE == urb_status) {
+            /* check if there is a data stage */
+            if (0U != puhost->control.setup.b.wLength) {
+                ctrl_setup_wait_flag = 0U;
+                timeout = DATA_STAGE_TIMEOUT;
+                scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_DATA, pustate->usbh_current_state);
+            /* no data stage */
+            } else {
+                timeout = NODATA_STAGE_TIMEOUT;
+                ctrl_setup_wait_flag = 0U;
+                scd_event_handle(pudev, 
+                                 puhost, 
+                                 pustate, 
+                                 CTRL_EVENT_STATUS, 
+                                 pustate->usbh_current_state);
+            }
+
+            /* set the delay timer to enable timeout for data stage completion */
+            puhost->control.timer = (uint16_t)USB_CURRENT_FRAME_GET();
+        } else if (URB_ERROR == urb_status) {
+            ctrl_setup_wait_flag = 0U;
+            scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_ERROR, pustate->usbh_current_state);
+        } else {
+            /* no operation */
+        }
+    }
+}
+
+/*!
+    \brief      the handle function of CTRL_DATA state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_data_handle (usb_core_handle_struct *pudev, 
+                              usbh_host_struct *puhost, 
+                              usbh_state_handle_struct *pustate)
+{
+    uint8_t direction;  
+    urb_state_enum urb_status = URB_IDLE;
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_DATA;
+  
+    direction = (puhost->control.setup.b.bmRequestType & USB_DIR_MASK);
+    
+    if (USB_DIR_IN == direction) {
+        if (0U == ctrl_data_wait_flag) {
+            ctrl_data_wait_flag = 1U;
+
+            /* issue an IN token */ 
+            usbh_xfer(pudev,
+                      puhost->control.buff,
+                      puhost->control.hc_in_num,
+                      puhost->control.length);
+        } else {
+            urb_status = hcd_urb_state_get(pudev, puhost->control.hc_in_num);
+
+            /* check is data packet transfered successfully */
+            switch (urb_status) {
+                case URB_DONE:
+                    ctrl_data_wait_flag = 0U;
+
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_STATUS, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_STALL:
+                    ctrl_data_wait_flag = 0U;
+   
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_STALLED, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_ERROR:
+                    ctrl_data_wait_flag = 0U;
+
+                    /* device error */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_ERROR, 
+                                     pustate->usbh_current_state);
+                    break;
+                default:
+                    if (((uint16_t)USB_CURRENT_FRAME_GET() - puhost->control.timer) > timeout) {
+                        ctrl_data_wait_flag = 0U;
+
+                        /* timeout for IN transfer */
+                        scd_event_handle(pudev, 
+                                         puhost, 
+                                         pustate, 
+                                         CTRL_EVENT_ERROR, 
+                                         pustate->usbh_current_state);
+                    }
+                    break;
+            }
+        }
+    } else {
+        if (0U == ctrl_data_wait_flag) {
+            ctrl_data_wait_flag = 1U;
+
+            /* start DATA out transfer (only one DATA packet)*/
+            pudev->host.host_channel[puhost->control.hc_out_num].data_tg_out = 1U; 
+
+            usbh_xfer(pudev,
+                      puhost->control.buff,
+                      puhost->control.hc_out_num,
+                      puhost->control.length);
+        } else {
+            urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num);
+
+            switch (urb_status) {
+                case URB_DONE:
+                    ctrl_data_wait_flag = 0U;
+
+                    /* if the setup pkt is sent successful, then change the state */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_STATUS, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_STALL:
+                    ctrl_data_wait_flag = 0U;
+
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_STALLED, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_NOTREADY:
+                    /* nack received from device */
+                    ctrl_data_wait_flag = 0U;
+                    break;
+                case URB_ERROR:
+                    ctrl_data_wait_flag = 0U;
+
+                    /* device error */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_ERROR, 
+                                     pustate->usbh_current_state);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+/*!
+    \brief      the handle function of CTRL_STATUS state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_status_handle (usb_core_handle_struct *pudev, 
+                                usbh_host_struct *puhost, 
+                                usbh_state_handle_struct *pustate)
+{
+    uint8_t direction;  
+    urb_state_enum urb_status = URB_IDLE;
+  
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_STATUS;
+
+    /* get the transfer direction in the data state, but the transfer direction in the status state is opposite */
+    direction = (puhost->control.setup.b.bmRequestType & USB_DIR_MASK);
+
+    if (USB_DIR_OUT == direction) {
+        /* handle status in */
+        if (0U == ctrl_status_wait_flag) {
+            ctrl_status_wait_flag = 1U;
+            usbh_xfer (pudev, 0U, puhost->control.hc_in_num, 0U);
+        } else {
+            urb_status = hcd_urb_state_get(pudev, puhost->control.hc_in_num); 
+
+            switch (urb_status) {
+                case URB_DONE:
+                    ctrl_status_wait_flag = 0U;
+
+                    /* handle URB_DONE status */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_COMPLETE, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_ERROR:
+                    ctrl_status_wait_flag = 0U;
+
+                    /* handle URB_STALL status*/
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_ERROR, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_STALL:
+                    ctrl_status_wait_flag = 0U;
+
+                    /* handle URB_STALL status */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_STALLED, 
+                                     pustate->usbh_current_state);
+                    break;
+                default:
+                    if (((uint16_t)USB_CURRENT_FRAME_GET() - puhost->control.timer) > timeout) {
+                        ctrl_status_wait_flag = 0U;
+
+                        /* handle timeout */
+                        scd_event_handle(pudev, 
+                                         puhost, 
+                                         pustate, 
+                                         CTRL_EVENT_ERROR, 
+                                         pustate->usbh_current_state);
+                    }
+                    break;
+            }
+        }
+    } else {
+        /* handle status out */
+        if (0U == ctrl_status_wait_flag) {
+            ctrl_status_wait_flag = 1U;
+            pudev->host.host_channel[puhost->control.hc_out_num].data_tg_out ^= 1U;
+            usbh_xfer (pudev, 0U, puhost->control.hc_out_num, 0U);
+
+            {
+                uint32_t host_ctlr = 0;
+
+                host_ctlr = USB_HCHxLEN(puhost->control.hc_out_num);
+                USB_HCHxLEN(puhost->control.hc_out_num) = host_ctlr | 1;
+                host_ctlr = USB_HCHxCTL(puhost->control.hc_out_num);
+                USB_HCHxCTL(puhost->control.hc_out_num) = (host_ctlr & 0x3FFFFFFF) | 0x80000000;
+            }
+        } else {
+            urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num);
+
+            switch (urb_status) {
+                case URB_DONE:
+                    ctrl_status_wait_flag = 0U;
+
+                    /* handle URB_DONE status */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_COMPLETE, 
+                                     pustate->usbh_current_state);
+                    break;
+                case URB_NOTREADY:
+                    /* handle URB_NOTREADY status */
+                    ctrl_status_wait_flag = 0U;
+                    break;
+                case URB_ERROR:
+                    ctrl_status_wait_flag = 0U;
+
+                    /* handle URB_ERROR status */
+                    scd_event_handle(pudev, 
+                                     puhost, 
+                                     pustate, 
+                                     CTRL_EVENT_ERROR, 
+                                     pustate->usbh_current_state);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+/*!
+    \brief      the handle function of CTRL_ERROR state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_error_handle (usb_core_handle_struct *pudev, 
+                               usbh_host_struct *puhost, 
+                               usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_ERROR;
+
+    if (++puhost->control.error_count <= USBH_MAX_ERROR_COUNT) {
+        /* do the transmission again, starting from SETUP Packet */
+        scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_SETUP, pustate->usbh_current_state);
+    } else {
+        scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of CTRL_STALLED state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_stalled_handle (usb_core_handle_struct *pudev, 
+                                 usbh_host_struct *puhost, 
+                                 usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_STALLED;
+    scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+}
+
+/*!
+    \brief      the handle function of CTRL_COMPLETE state
+    \param[in]  pudev: pointer to usb device
+    \param[in]  puhost: pointer to usb host
+    \param[in]  pustate: pointer to usb state driver
+    \param[out] none
+    \retval     none
+*/
+static void ctrl_complete_handle (usb_core_handle_struct *pudev, 
+                                  usbh_host_struct *puhost, 
+                                  usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.ctrl_backup_state = CTRL_COMPLETE;
+    scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+}
+
+/*!
+    \brief      send datas from the host channel
+    \param[in]  pudev: pointer to usb device
+    \param[in]  buf: data buffer address to send datas
+    \param[in]  hc_num: the number of the host channel
+    \param[in]  len: length of the send data
+    \param[out] none
+    \retval     host operation status
+*/
+usbh_status_enum usbh_xfer (usb_core_handle_struct *pudev, 
+                       uint8_t *buf, 
+                       uint8_t  hc_num,
+                       uint16_t len)
+{
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+    puhc->xfer_buff = buf;
+    puhc->xfer_len = len;
+
+    switch (puhc->endp_type) {
+        case USB_EPTYPE_CTRL:
+            if (0U == puhc->endp_in) {
+                if (0U == len) {
+                    /* for status out stage, length = 0, status out pid = 1 */
+                    puhc->data_tg_out = 1U;
+                }
+
+                /* set the data toggle bit as per the flag */
+                if (0U == puhc->data_tg_out) {
+                    /* put the pid 0 */
+                    puhc->DPID = HC_PID_DATA0;
+                } else {
+                    /* put the pid 1 */
+                    puhc->DPID = HC_PID_DATA1;
+                }
+            } else {
+                puhc->DPID = HC_PID_DATA1;
+            }
+            break;
+
+        case USB_EPTYPE_ISOC:
+            puhc->DPID = HC_PID_DATA0;
+            break;
+
+        case USB_EPTYPE_BULK:
+            if (0U == puhc->endp_in) {
+                /* set the data toggle bit as per the flag */
+                if (0U == puhc->data_tg_out) {
+                    /* put the pid 0 */
+                    puhc->DPID = HC_PID_DATA0;
+                } else {
+                    /* put the pid 1 */
+                    puhc->DPID = HC_PID_DATA1;
+                }
+            } else {
+                if (0U == puhc->data_tg_in) {
+                    puhc->DPID = HC_PID_DATA0;
+                } else {
+                    puhc->DPID = HC_PID_DATA1;
+                }
+            }
+            break;
+
+        case USB_EPTYPE_INTR:
+            if (0U == puhc->endp_in) {
+                if (0U == puhc->data_tg_out) {
+                    puhc->DPID = HC_PID_DATA0;
+                } else {
+                    puhc->DPID = HC_PID_DATA1;
+                }
+
+                /* toggle data pid */
+                puhc->data_tg_out ^= 1U;
+            } else {
+                if (0U == puhc->data_tg_in) {
+                    puhc->DPID = HC_PID_DATA0;
+                } else {
+                    puhc->DPID = HC_PID_DATA1;
+                }
+
+                /* toggle data pid */
+                puhc->data_tg_in ^= 1U;
+            }
+            break;
+
+        default:
+            break;
+    }
+
+    hcd_submit_request (pudev, hc_num);
+
+    return USBH_OK;
+}
+
+/*!
+    \brief      send the setup packet to the device
+    \param[in]  pudev: pointer to usb device
+    \param[in]  buf: buffer pointer from which the data will be send to device
+    \param[in]  hc_num: host channel number
+    \param[out] none
+    \retval     host operation status
+*/
+usbh_status_enum usbh_ctltx_setup (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t  hc_num)
+{
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+    puhc->DPID = HC_PID_SETUP;
+    puhc->xfer_buff = buf;
+    puhc->xfer_len = USBH_SETUP_PACKET_SIZE;
+
+    return (usbh_status_enum)hcd_submit_request (pudev, hc_num);
+}
+
+/*!
+    \brief      this function prepare a hc and start a transfer
+    \param[in]  pudev: pointer to usb device
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     host operation status
+*/
+uint32_t hcd_submit_request (usb_core_handle_struct *pudev, uint8_t channel_num) 
+{
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+    puhc->urb_state = URB_IDLE;
+    puhc->xfer_count = 0U;
+
+    return (uint32_t)usb_hostchannel_startxfer(pudev, channel_num);
+}

+ 162 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_hcs.c

@@ -0,0 +1,162 @@
+/*!
+    \file  usbh_hcs.c
+    \brief this file implements functions for opening and closing host channels
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.0, firmware for GD32F4xx
+*/
+
+#include "usbh_hcs.h"
+
+static uint16_t usbh_freechannel_get (usb_core_handle_struct *pudev);
+
+/*!
+    \brief      open a channel
+    \param[in]  pudev: pointer to usb device
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[in]  dev_addr: USB device address allocated to attached device
+    \param[in]  dev_speed: USB device speed (Full speed/Low speed)
+    \param[in]  ep_type: endpoint type (bulk/int/ctl)
+    \param[in]  ep_mps: max packet size
+    \param[out] none
+    \retval     operation status
+*/
+uint8_t usbh_channel_open (usb_core_handle_struct *pudev, 
+                           uint8_t  channel_num,
+                           uint8_t  dev_addr,
+                           uint8_t  dev_speed,
+                           uint8_t  ep_type,
+                           uint16_t ep_mps)
+{
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+    uint16_t channel_info = puhc->info;
+
+    puhc->endp_id   = (uint8_t)channel_info & 0x7FU;
+    puhc->endp_in   = (uint8_t)(channel_info & 0x80U) >> 7;
+    puhc->endp_type = ep_type;
+    puhc->endp_mps  = ep_mps;
+    puhc->dev_addr  = dev_addr;
+    puhc->dev_speed = dev_speed;
+
+    puhc->data_tg_in  = 0U;
+    puhc->data_tg_out = 0U;
+
+    if (HPRT_PRTSPD_HIGH_SPEED == dev_speed) {
+        puhc->do_ping = 1U;
+    }
+
+    usb_hostchannel_init(pudev, channel_num);
+
+    return (uint8_t)HC_OK;
+}
+
+/*!
+    \brief      modify a channel
+    \param[in]  pudev: pointer to usb device
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[in]  dev_addr: USB Device address allocated to attached device
+    \param[in]  dev_speed: USB device speed (Full speed/Low speed)
+    \param[in]  ep_type: endpoint type (bulk/int/ctl)
+    \param[in]  ep_mps: max packet size
+    \param[out] none
+    \retval     operation status
+*/
+uint8_t usbh_channel_modify (usb_core_handle_struct *pudev,
+                             uint8_t  channel_num,
+                             uint8_t  dev_addr,
+                             uint8_t  dev_speed,
+                             uint8_t  ep_type,
+                             uint16_t ep_mps)
+{
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+    if (0U != dev_addr) {
+        puhc->dev_addr = dev_addr;
+    }
+
+    if ((puhc->endp_mps != ep_mps) && (0U != ep_mps)) {
+        puhc->endp_mps = ep_mps; 
+    }
+
+    if ((puhc->dev_speed != dev_speed) && (0U != dev_speed)) {
+        puhc->dev_speed = dev_speed;
+    }
+
+    usb_hostchannel_init(pudev, channel_num);
+
+    return (uint8_t)HC_OK;
+}
+
+/*!
+    \brief      allocate a new channel for the pipe
+    \param[in]  pudev: pointer to usb device
+    \param[in]  ep_addr: endpoint for which the channel to be allocated
+    \param[out] none
+    \retval     host channel number
+*/
+uint8_t usbh_channel_alloc (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+    uint16_t hc_num = usbh_freechannel_get(pudev);
+
+    if ((uint16_t)HC_ERROR != hc_num) {
+        pudev->host.host_channel[hc_num].info = HC_USED | ep_addr;
+    }
+
+    return (uint8_t)hc_num;
+}
+
+/*!
+    \brief      free the usb host channel
+    \param[in]  pudev: pointer to usb device
+    \param[in]  index: channel number to be freed  which is in (0..7)
+    \param[out] none
+    \retval     host operation status
+*/
+uint8_t usbh_channel_free (usb_core_handle_struct *pudev, uint8_t index)
+{
+    if (index < HC_MAX) {
+        pudev->host.host_channel[index].info &= HC_USED_MASK;
+    }
+
+    return USBH_OK;
+}
+
+/*!
+    \brief      free all usb host channel
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     host operation status
+*/
+uint8_t usbh_allchannel_dealloc (usb_core_handle_struct *pudev)
+{
+    uint8_t index;
+
+    for (index = 2U; index < HC_MAX; index ++) {
+        pudev->host.host_channel[index].info = 0U;
+    }
+
+    return USBH_OK;
+}
+
+/*!
+    \brief      get a free channel number for allocation to a device endpoint
+    \param[in]  pudev: pointer to usb device
+    \param[out] none
+    \retval     free channel number
+*/
+static uint16_t usbh_freechannel_get (usb_core_handle_struct *pudev)
+{
+    uint8_t index = 0U;
+
+    for (index = 0U; index < HC_MAX; index++) {
+        if (0U == (pudev->host.host_channel[index].info & HC_USED)) {
+            return (uint16_t)index;
+        }
+    }
+
+    return HC_ERROR;
+}
+

+ 591 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_int.c

@@ -0,0 +1,591 @@
+/*!
+    \file  usbh_int.c
+    \brief USB host mode interrupt handler file
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#include "usb_core.h"
+#include "usb_defines.h"
+#include "usbh_int.h"
+
+static uint32_t usbh_intf_sof                 (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_port                (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_hc                  (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_hc_in               (usb_core_handle_struct *pudev, uint8_t channel_num);
+static uint32_t usbh_intf_hc_out              (usb_core_handle_struct *pudev, uint8_t channel_num);
+static uint32_t usbh_intf_rxfifo_noempty      (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_nptxfifo_empty      (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_ptxfifo_empty       (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_disconnect          (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev);
+
+/*!
+    \brief      handle global host interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+uint32_t usbh_isr (usb_core_handle_struct *pudev)
+{
+    uint32_t retval = 0U;
+    uint32_t int_flag = 0U;
+
+    /* check if host mode */
+    if (USB_CURRENT_MODE_GET() == HOST_MODE) {
+        USB_CORE_INTR_READ(int_flag);
+
+        if (!int_flag) {
+            return 0U;
+        }
+        
+        /* start of frame interrupt handle */
+        if (int_flag & GINTF_SOF) {
+            retval |= usbh_intf_sof (pudev);
+        }
+
+        /* Rx FIFO non-empty interrupt handle */
+        if (int_flag & GINTF_RXFNEIF) {
+            retval |= usbh_intf_rxfifo_noempty (pudev);
+        }
+
+        /* Non-Periodic Tx FIFO empty interrupt hanlde */
+        if (int_flag & GINTF_NPTXFEIF) {
+            retval |= usbh_intf_nptxfifo_empty (pudev);
+        }
+
+        /* periodic Tx FIFO empty interrupt handle */
+        if (int_flag & GINTF_PTXFEIF) {
+            retval |= usbh_intf_ptxfifo_empty (pudev);
+        }
+
+        /* host channels interrupt handle */
+        if (int_flag & GINTF_HCIF) {
+            retval |= usbh_intf_hc (pudev);
+        }
+
+        /* host port interrupt handle */
+        if (int_flag & GINTF_HPIF) {
+            retval |= usbh_intf_port (pudev);
+        }
+
+        /* disconnect interrupt handle */
+        if (int_flag & GINTF_DISCIF) {
+            retval |= usbh_intf_disconnect (pudev);
+        }
+
+        /* isochronous IN transfer not complete interrupt handle */
+        if (int_flag & GINTF_ISOONCIF) {
+            retval |= usbh_intf_iso_incomplete_xfer (pudev);
+        }
+    }
+
+    return retval;
+}
+
+/*!
+    \brief      handle the start-of-frame interrupt in host mode
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev)
+{
+    usbh_hcd_int_fops->sof(pudev);
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_SOF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle all host channels interrupt in host mode
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev)
+{
+    uint8_t i = 0U;
+    uint32_t retval = 0U;
+
+    for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
+        if ((USB_HACHINT & HACHINT_HACHINT) & ((uint32_t)1U << i)) {
+            if ((USB_HCHxCTL((uint16_t)i) & HCHCTL_EPDIR) >> 15U) {
+                retval |= usbh_intf_hc_in (pudev, i);
+            } else {
+                retval |= usbh_intf_hc_out (pudev, i);
+            }
+        }
+    }
+
+    return retval;
+}
+
+/*!
+    \brief      handle the disconnect interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev)
+{
+    usbh_hcd_int_fops->device_disconnected(pudev);
+
+    /* clear interrupt */
+    USB_GINTF = GINTF_DISCIF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the non-periodic tx fifo empty interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev)
+{
+    uint8_t channel_num = 0U;
+    uint32_t dword_len = 0U, len = 0U;
+    usb_hostchannel_struct *puhc;
+
+    channel_num = (uint8_t)((USB_HNPTFQSTAT & HNPTFQSTAT_CNUM) >> 27U);
+    puhc = &pudev->host.host_channel[channel_num];
+    dword_len = (puhc->xfer_len + 3U) / 4U;
+
+    while (((USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) > dword_len) && (0U != puhc->xfer_len)) {
+        len = (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) * 4U;
+
+        if (len > puhc->xfer_len) {
+            /* last packet */
+            len = (uint16_t)puhc->xfer_len;
+
+            USB_GINTEN &= ~GINTF_NPTXFEIF;
+
+        }
+
+        dword_len = (puhc->xfer_len + 3U) / 4U;
+        usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len);
+
+        puhc->xfer_buff += len;
+        puhc->xfer_len -= len;
+        puhc->xfer_count += len;
+    }
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the periodic tx fifo empty interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev)
+{
+    uint8_t channel_num = 0U;
+    uint32_t dword_len = 0U, len = 0U;
+    usb_hostchannel_struct *puhc; 
+
+    channel_num = (uint8_t)((USB_HPTFQSTAT & HPTFQSTAT_CNUM) >> 27U);
+    puhc = &pudev->host.host_channel[channel_num];
+    dword_len = (puhc->xfer_len + 3U) / 4U;
+
+    while (((USB_HPTFQSTAT & HPTFQSTAT_PTXFS) > dword_len) && (0U != puhc->xfer_len)) {
+        len = (USB_HPTFQSTAT & HPTFQSTAT_PTXFS) * 4U;
+
+        if (len > puhc->xfer_len) {
+            len = puhc->xfer_len;
+
+            /* last packet */
+            USB_GINTEN &= ~GINTF_PTXFEIF;
+        }
+
+        dword_len = (puhc->xfer_len + 3U) / 4U;
+        usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len);
+
+        puhc->xfer_buff += len;
+        puhc->xfer_len -= len;
+        puhc->xfer_count += len;
+    }
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the host port interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_port (usb_core_handle_struct *pudev)
+{
+    uint8_t port_speed = 0U;
+    uint8_t port_reset = 0U;
+    uint32_t retval = 0U;
+    __IO uint32_t hostportdup = USB_HPCS;
+
+    /* clear the interrupt bits in gintsts */
+    hostportdup &= ~HPCS_PE;
+    hostportdup &= ~HPCS_PCD;
+    hostportdup &= ~HPCS_PEDC;
+
+    /* port connect detected */
+    if (USB_HPCS & HPCS_PCD) {
+        hostportdup |= HPCS_PCD;
+        usbh_hcd_int_fops->device_connected(pudev);
+        retval |= 1U;
+    }
+
+    /* port enable changed */
+    if (USB_HPCS & HPCS_PEDC) {
+        hostportdup |= HPCS_PEDC;
+
+        if (USB_HPCS & HPCS_PE) {
+            port_speed = (uint8_t)((USB_HPCS & HPCS_PS) >> 17U);
+
+            if (HPRT_PRTSPD_LOW_SPEED == port_speed) {
+                USB_HFT = 6000U;
+
+                if (HCTLR_6_MHZ != (USB_HCTL & HCTL_CLKSEL)) {
+                    if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
+                        USB_FSLSCLOCK_INIT(HCTLR_6_MHZ);
+                    }
+                    port_reset = 1U;
+                }
+            } else if(HPRT_PRTSPD_FULL_SPEED == port_speed) {
+                USB_HFT = 48000U;
+
+                if (HCTLR_48_MHZ != (USB_HCTL & HCTL_CLKSEL)) {
+                    if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
+                        USB_FSLSCLOCK_INIT(HCTLR_48_MHZ);
+                    }
+                    port_reset = 1U;
+                }
+            } else {
+                /* for high speed device and others */
+                port_reset = 1U;
+            }
+
+
+        }
+    }
+
+    if (port_reset) {
+        usb_port_reset(pudev);
+    }
+
+    /* clear port interrupts */
+    USB_HPCS = hostportdup;
+
+    return retval;
+}
+
+/*!
+    \brief      handle the OUT channel interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+    uint32_t channel_intr = USB_HCHxINTF((uint16_t)channel_num);
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+    channel_intr &= USB_HCHxINTEN((uint16_t)channel_num);
+
+    if (channel_intr & HCHINTF_ACK) {
+        if (URB_PING ==  puhc->urb_state) {
+            puhc->err_count = 0U;
+            USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+            usb_hostchannel_halt(pudev, channel_num);
+            USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
+            puhc->status = HC_XF;
+        }
+
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK;
+    } else if (channel_intr & HCHINTF_REQOVR) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR;
+    } else if (channel_intr & HCHINTF_TF) {
+        puhc->err_count = 0U;
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
+        puhc->status = HC_XF;
+    } else if (channel_intr & HCHINTF_STALL) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL;
+        usb_hostchannel_halt(pudev, channel_num);
+        puhc->status = HC_STALL;
+    } else if (channel_intr & HCHINTF_NAK) {
+        puhc->err_count = 0U;
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+        puhc->status = HC_NAK;
+    } else if (channel_intr & HCHINTF_USBER) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        puhc->err_count ++;
+        puhc->status = HC_TRACERR;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER;
+    } else if (channel_intr & HCHINTF_NYET) {
+        puhc->err_count = 0U;
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        puhc->status = HC_NYET;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NYET;
+    } else if (channel_intr & HCHINTF_DTER) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        puhc->status= HC_DTGERR;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER;
+    } else if (channel_intr & HCHINTF_CH) {
+        USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE;
+
+        switch (puhc->status) {
+            case HC_XF:
+                puhc->urb_state = URB_DONE;
+
+                if (USB_EPTYPE_BULK == ((USB_HCHxCTL((uint16_t)channel_num) & HCHCTL_EPTYPE) >> 18)) {
+                    puhc->data_tg_out ^= 1U; 
+                }
+                break;
+            case HC_NAK:
+                if (URB_PING == puhc->urb_state) {
+                    usb_hostchannel_ping(pudev, channel_num);
+                } else {
+                    puhc->urb_state = URB_NOTREADY;
+                }
+                break;
+            case HC_NYET:
+                if (1U == puhc->do_ping) {
+                    usb_hostchannel_ping(pudev, channel_num);
+                    puhc->urb_state = URB_PING;
+                }
+                break;
+            case HC_STALL:
+                puhc->urb_state = URB_STALL;
+                break;
+            case HC_TRACERR:
+                if (3U == puhc->err_count) {
+                    puhc->urb_state = URB_ERROR;
+                    puhc->err_count = 0U;
+                }
+                break;
+            default:
+                break;
+        }
+
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH;
+    } else {
+        /* no operation */
+    }
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the IN channel interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[in]  channel_num: host channel number which is in (0..7)
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+    uint8_t endp_type = 0U;
+    usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+    uint32_t channle_intf = USB_HCHxINTF((uint16_t)channel_num);
+    __IO uint32_t channel_ctrl = USB_HCHxCTL((uint16_t)channel_num);
+
+    channle_intf &= USB_HCHxINTEN((uint16_t)channel_num);
+
+    endp_type = (uint8_t)((channel_ctrl & HCHCTL_EPTYPE) >> 18U);
+
+    if (channle_intf & HCHINTF_ACK) {
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK;
+    } else if (channle_intf & HCHINTF_STALL) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        puhc->status = HC_STALL;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL;
+
+        /* NOTE: When there is a 'stall', reset also nak,
+           else, the pudev->host.status = HC_STALL
+           will be overwritten by 'nak' in code below */
+        channle_intf &= ~HCHINTF_NAK;
+
+        usb_hostchannel_halt(pudev, channel_num);
+    } else if (channle_intf & HCHINTF_DTER) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+        puhc->status = HC_DTGERR; 
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER;
+    } else {
+        /* no operation */
+    }
+
+    if (channle_intf & HCHINTF_REQOVR) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        usb_hostchannel_halt(pudev, channel_num);
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR;
+    } else if (channle_intf & HCHINTF_TF) {
+        if (pudev->cfg.dma_enable == 1U) {
+            uint32_t xfer_size = USB_HCHxLEN((uint16_t)channel_num) & HCHLEN_TLEN;
+            puhc->xfer_count = puhc->xfer_len - xfer_size;
+        }
+
+        puhc->status = HC_XF;
+        puhc->err_count = 0U;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
+
+        if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) {
+            USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+            usb_hostchannel_halt(pudev, channel_num);
+            USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+            puhc->data_tg_in ^= 1U;
+        } else if (USB_EPTYPE_INTR == endp_type) {
+            channel_ctrl |= HCHCTL_ODDFRM;
+            USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl;
+            puhc->urb_state = URB_DONE;
+        } else {
+            /* no operation */
+        }
+    } else if (channle_intf & HCHINTF_CH) {
+        USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE;
+
+        switch (puhc->status) {
+            case HC_XF:
+                puhc->urb_state = URB_DONE;
+                break;
+            case HC_TRACERR:
+            case HC_DTGERR:
+                puhc->err_count = 0U;
+                puhc->urb_state = URB_ERROR;
+                break;
+            case HC_STALL:
+                puhc->urb_state = URB_STALL;
+                break;
+            default:
+                if (USB_EPTYPE_INTR == endp_type) {
+                    puhc->data_tg_in ^= 1U;
+                }
+                break;
+        }
+
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH;
+    } else if (channle_intf & HCHINTF_USBER) {
+        USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+        (puhc->err_count)++;
+        puhc->status = HC_TRACERR;
+        usb_hostchannel_halt(pudev, channel_num);
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER;
+    } else if (channle_intf & HCHINTF_NAK) {
+        if (USB_EPTYPE_INTR == endp_type) {
+            USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+            usb_hostchannel_halt(pudev, channel_num);
+        } else if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) {
+            /* re-activate the channel */
+            channel_ctrl |= HCHCTL_CEN;
+            channel_ctrl &= ~HCHCTL_CDIS;
+            USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl;
+        } else {
+            /* no operation */
+        }
+
+        puhc->status = HC_NAK;
+        USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+    } else {
+        /* no operation */
+    }
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the rx fifo non-empty interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev)
+{
+    uint32_t count = 0U;
+    __IO uint8_t channel_num = 0U;
+    __IO uint32_t rx_status = 0U;
+    uint32_t usbh_ch_ctl_reg = 0U;
+    usb_hostchannel_struct *puhc;
+
+    /* disable the Rx status queue level interrupt */
+    USB_GINTEN &= ~GINTF_RXFNEIF;
+
+    rx_status = USB_GRSTATP;
+    channel_num = (uint8_t)(rx_status & GRSTATR_CNUM);
+    puhc = &pudev->host.host_channel[channel_num];
+
+    switch ((rx_status & GRSTATR_RPCKST) >> 17) {
+        case GRSTATR_RPCKST_IN:
+            count = (rx_status & GRSTATR_BCOUNT) >> 4;
+
+            /* read the data into the host buffer. */
+            if ((count > 0U) && (puhc->xfer_buff != (void *)0)) {
+                usb_fifo_read(puhc->xfer_buff, (uint16_t)count);
+
+                /* manage multiple Xfer */
+                puhc->xfer_buff += count;
+                puhc->xfer_count += count;
+
+                if (USB_HCHxLEN((uint16_t)channel_num) & HCHLEN_PCNT) {
+                    /* re-activate the channel when more packets are expected */
+                    usbh_ch_ctl_reg = USB_HCHxCTL((uint16_t)channel_num);
+                    usbh_ch_ctl_reg |= HCHCTL_CEN;
+                    usbh_ch_ctl_reg &= ~HCHCTL_CDIS;
+                    USB_HCHxCTL((uint16_t)channel_num) = usbh_ch_ctl_reg;
+                }
+            }
+            break;
+        case GRSTATR_RPCKST_IN_XFER_COMP:
+        case GRSTATR_RPCKST_DATA_TOGGLE_ERR:
+        case GRSTATR_RPCKST_CH_HALTED:
+        default:
+            break;
+    }
+
+    /* enable the Rx status queue level interrupt */
+    USB_GINTEN |= GINTF_RXFNEIF;
+
+    return 1U;
+}
+
+/*!
+    \brief      handle the incomplete periodic transfer interrupt
+    \param[in]  pudev: pointer to usb device instance
+    \param[out] none
+    \retval     operation status
+*/
+static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev)
+{
+    __IO uint32_t gint_flag = 0U;
+
+    gint_flag = USB_HCHxCTL(0U);
+    USB_HCHxCTL(0U) = 0U;
+
+    gint_flag = 0U;
+
+    /* clear interrupt */
+    gint_flag |= GINTF_ISOONCIF;
+    USB_GINTF = gint_flag;
+
+    return 1U;
+}

+ 808 - 0
bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_std.c

@@ -0,0 +1,808 @@
+/*!
+    \file  usbh_std.c
+    \brief USB 2.0 standard function definition
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-08-15, V1.0.1, firmware for GD32F4xx
+*/
+
+#include "usbh_core.h"
+#include "usbh_usr.h"
+#include "usbh_std.h"
+#include "usbh_ctrl.h"
+
+uint8_t local_buffer[64];
+uint8_t usbh_cfg_desc[512];
+uint8_t enum_polling_handle_flag = 0U;
+
+static void enum_idle_handle                       (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_full_dev_desc_handle          (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_set_addr_handle                   (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_cfg_desc_handle               (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_full_cfg_desc_handle          (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_mfc_string_desc_handle        (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_product_string_desc_handle    (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_serialnum_string_desc_handle  (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_set_configuration_handle          (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_dev_configured_handle             (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+
+/* the enumeration state handle function array */
+void (*enum_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) =
+{
+    enum_idle_handle,
+    enum_set_addr_handle,
+    enum_get_full_dev_desc_handle,
+    enum_get_cfg_desc_handle,
+    enum_get_full_cfg_desc_handle,
+    enum_get_mfc_string_desc_handle,
+    enum_get_product_string_desc_handle,
+    enum_get_serialnum_string_desc_handle,
+    enum_set_configuration_handle,
+    enum_dev_configured_handle,
+};
+
+/* the enumeration state handle table */
+state_table_struct enum_handle_table[ENUM_HANDLE_TABLE_SIZE] = 
+{
+    /* the current state             the current event                     the next state                   the event function */
+    {ENUM_IDLE,                      ENUM_EVENT_SET_ADDR,                  ENUM_SET_ADDR,                   only_state_move     },
+    {ENUM_SET_ADDR,                  ENUN_EVENT_GET_FULL_DEV_DESC,         ENUM_GET_FULL_DEV_DESC,          only_state_move     },
+    {ENUM_GET_FULL_DEV_DESC,         ENUN_EVENT_GET_CFG_DESC,              ENUM_GET_CFG_DESC,               only_state_move     },
+    {ENUM_GET_CFG_DESC,              ENUN_EVENT_GET_FULL_CFG_DESC,         ENUM_GET_FULL_CFG_DESC,          only_state_move     },
+    {ENUM_GET_FULL_CFG_DESC,         ENUN_EVENT_GET_MFC_STRING_DESC,       ENUM_GET_MFC_STRING_DESC,        only_state_move     },
+    {ENUM_GET_MFC_STRING_DESC,       ENUN_EVENT_GET_PRODUCT_STRING_DESC,   ENUM_GET_PRODUCT_STRING_DESC,    only_state_move     },
+    {ENUM_GET_PRODUCT_STRING_DESC,   ENUN_EVENT_GET_SERIALNUM_STRING_DESC, ENUM_GET_SERIALNUM_STRING_DESC,  only_state_move     },
+    {ENUM_GET_SERIALNUM_STRING_DESC, ENUN_EVENT_SET_CONFIGURATION,         ENUM_SET_CONFIGURATION,          only_state_move     },
+    {ENUM_SET_CONFIGURATION,         ENUN_EVENT_DEV_CONFIGURED,            ENUM_DEV_CONFIGURED,             only_state_move     },
+    {ENUM_DEV_CONFIGURED,            GO_TO_UP_STATE_EVENT,                 UP_STATE,                        goto_up_state_fun   },
+};
+
+/*!
+    \brief      the polling function of enumeration state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     usb host status
+*/
+usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+    usbh_status_enum exe_state = USBH_BUSY;
+    usbh_state_handle_struct *p_state;
+    p_state = (usbh_state_handle_struct *)pustate;
+
+    if (0U == enum_polling_handle_flag) {
+        enum_polling_handle_flag = 1U;
+        scd_table_push(p_state);
+        scd_state_move(p_state, ENUM_IDLE);
+    }
+    
+    /* start the enumeration state handle */
+    scd_begin(p_state,ENUM_FSM_ID);
+    
+    if (0U == p_state->usbh_current_state_stack_top) {
+        enum_state_handle[p_state->usbh_current_state](pudev, puhost, p_state);
+    } else {
+        enum_state_handle[p_state->stack[1].state](pudev, puhost, p_state);
+    }
+
+    /* determine the enumeration whether to complete  */
+    if (ENUM_DEV_CONFIGURED == puhost->usbh_backup_state.enum_backup_state) {
+        puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE;
+        enum_polling_handle_flag = 0U;
+        exe_state = USBH_OK;
+    }
+
+    return exe_state;
+}
+
+/*!
+    \brief      the handle function of ENUM_IDLE state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE;
+
+    if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+        usbh_enum_desc_get(pudev, 
+                           puhost, 
+                           pudev->host.rx_buffer, 
+                           USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                           USB_DEVDESC, 
+                           8U);
+        if ((void *)0 != pudev->mdelay) {
+            pudev->mdelay(100U);
+        }
+    }
+
+    if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+        usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, 8U);
+        puhost->control.ep0_size = puhost->device.dev_desc.bMaxPacketSize0;
+
+        /* issue reset */
+        usb_port_reset(pudev);
+
+        /* modify control channels configuration for maxpacket size */
+        usbh_channel_modify (pudev,
+                             puhost->control.hc_out_num,
+                             0U,
+                             0U,
+                             0U,
+                             (uint16_t)puhost->control.ep0_size);
+
+        usbh_channel_modify (pudev,
+                             puhost->control.hc_in_num,
+                             0U,
+                             0U,
+                             0U,
+                             (uint16_t)puhost->control.ep0_size);
+
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUM_EVENT_SET_ADDR, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_GET_FULL_DEV_DESC state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev, 
+                                           usbh_host_struct *puhost, 
+                                           usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_DEV_DESC;
+
+    if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+        usbh_enum_desc_get(pudev, 
+                           puhost, 
+                           pudev->host.rx_buffer, 
+                           USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                           USB_DEVDESC, 
+                           USB_DEVDESC_SIZE);
+    }
+    
+    if(USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){
+        usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, USB_DEVDESC_SIZE);
+        puhost->usr_cb->device_desc_available(&puhost->device.dev_desc);
+
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_GET_CFG_DESC, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_SET_ADDR state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_set_addr_handle (usb_core_handle_struct *pudev, 
+                                  usbh_host_struct *puhost, 
+                                  usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_SET_ADDR;
+
+    if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+        usbh_enum_addr_set(pudev, puhost,USBH_DEVICE_ADDRESS);
+        if ((void *)0 != pudev->mdelay) {
+            pudev->mdelay(100U);
+        }
+    }
+    
+    if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+        if ((void *)0 != pudev->mdelay) {
+            pudev->mdelay(2U);
+        }
+        puhost->device.address = USBH_DEVICE_ADDRESS;
+
+        /* user callback for device address assigned */
+        puhost->usr_cb->device_address_set();
+
+        /* modify control channels to update device address */
+        usbh_channel_modify (pudev,
+                             puhost->control.hc_in_num,
+                             puhost->device.address,
+                             0U,
+                             0U,
+                             0U);
+
+        usbh_channel_modify (pudev,
+                             puhost->control.hc_out_num,
+                             puhost->device.address,
+                             0U,
+                             0U,
+                             0U);
+
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_GET_FULL_DEV_DESC, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_GET_CFG_DESC state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev, 
+                                      usbh_host_struct *puhost, 
+                                      usbh_state_handle_struct *pustate)
+{
+    uint16_t index = 0U;
+
+    puhost->usbh_backup_state.enum_backup_state = ENUM_GET_CFG_DESC;
+
+    if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+        usbh_enum_desc_get(pudev, 
+                           puhost, 
+                           pudev->host.rx_buffer, 
+                           USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                           USB_CFGDESC, 
+                           USB_CFGDESC_SIZE);
+    }
+    
+    if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+        /* save configuration descriptor for class parsing usage */
+        for (; index < USB_CFGDESC_SIZE; index ++) {
+            usbh_cfg_desc[index] = pudev->host.rx_buffer[index];
+        }
+
+        /* commands successfully sent and response received */
+        usbh_cfg_desc_parse (&puhost->device.cfg_desc,
+                              puhost->device.itf_desc,
+                              puhost->device.ep_desc, 
+                              pudev->host.rx_buffer,
+                              USB_CFGDESC_SIZE);
+
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_GET_FULL_CFG_DESC, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_GET_FULL_CFG_DESC state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev, 
+                                           usbh_host_struct *puhost, 
+                                           usbh_state_handle_struct *pustate)
+{
+
+    uint16_t index = 0U;
+
+    puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_CFG_DESC;
+
+    if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+        usbh_enum_desc_get (pudev, puhost, pudev->host.rx_buffer, 
+                            USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                            USB_CFGDESC, puhost->device.cfg_desc.wTotalLength);
+    }
+
+    
+    if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+        /* save configuration descriptor for class parsing usage */
+        for (; index < puhost->device.cfg_desc.wTotalLength; index ++) {
+            usbh_cfg_desc[index] = pudev->host.rx_buffer[index];
+        }
+
+        /* commands successfully sent and response received */
+        usbh_cfg_desc_parse (&puhost->device.cfg_desc, 
+                              puhost->device.itf_desc, 
+                              puhost->device.ep_desc, 
+                              pudev->host.rx_buffer, 
+                              puhost->device.cfg_desc.wTotalLength);
+
+        /* User callback for configuration descriptors available */
+        puhost->usr_cb->configuration_desc_available(&puhost->device.cfg_desc,
+                                                      puhost->device.itf_desc,
+                                                      puhost->device.ep_desc[0]);
+
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_GET_MFC_STRING_DESC, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_GET_MFC_STRING_DESC state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev, 
+                                             usbh_host_struct *puhost, 
+                                             usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_GET_MFC_STRING_DESC;
+
+    if (0U != puhost->device.dev_desc.iManufacturer) {
+        if(CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+            usbh_enum_desc_get(pudev, 
+                               puhost, 
+                               pudev->host.rx_buffer, 
+                               USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                               USB_STRDESC | puhost->device.dev_desc.iManufacturer,
+                               0xffU);
+        }
+        
+        if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+            usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
+            puhost->usr_cb->manufacturer_string(local_buffer);
+            
+            scd_event_handle(pudev, 
+                             puhost, 
+                             pustate, 
+                             ENUN_EVENT_GET_PRODUCT_STRING_DESC, 
+                             pustate->usbh_current_state);
+        }
+    } else {
+        puhost->usr_cb->manufacturer_string("N/A");
+        scd_state_move((usbh_state_handle_struct *)pustate, ENUM_GET_PRODUCT_STRING_DESC);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_GET_PRODUCT_STRING_DESC state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev, 
+                                                 usbh_host_struct *puhost, 
+                                                 usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_GET_PRODUCT_STRING_DESC;
+
+    if (0U != puhost->device.dev_desc.iProduct) {
+        if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+            usbh_enum_desc_get(pudev, 
+                               puhost, 
+                               pudev->host.rx_buffer,
+                               USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                               USB_STRDESC | puhost->device.dev_desc.iProduct,
+                               0xffU);
+        }
+        
+        if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+            usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
+          
+            /* User callback for Product string */
+            puhost->usr_cb->product_string(local_buffer);
+          
+            scd_event_handle(pudev, 
+                             puhost, 
+                             pustate, 
+                             ENUN_EVENT_GET_SERIALNUM_STRING_DESC, 
+                             pustate->usbh_current_state);
+        }
+        
+    } else {
+        puhost->usr_cb->product_string("N/A");
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_GET_SERIALNUM_STRING_DESC, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_GET_SERIALNUM_STRING_DESC state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev, 
+                                                   usbh_host_struct *puhost, 
+                                                   usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_GET_SERIALNUM_STRING_DESC;
+
+    if (0U != puhost->device.dev_desc.iSerialNumber) {
+        if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+            usbh_enum_desc_get(pudev, 
+                               puhost, 
+                               pudev->host.rx_buffer, 
+                               USB_REQTYPE_DEVICE | USB_STANDARD_REQ, 
+                               USB_STRDESC | puhost->device.dev_desc.iSerialNumber,
+                               0xffU);
+        }
+        
+        if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){
+            usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
+          
+            /* user callback for product string */
+            puhost->usr_cb->serial_num_string(local_buffer);
+            scd_event_handle(pudev, 
+                             puhost, 
+                             pustate, 
+                             ENUN_EVENT_SET_CONFIGURATION, 
+                             pustate->usbh_current_state);
+        }
+    } else {
+        puhost->usr_cb->serial_num_string("N/A");
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_SET_CONFIGURATION, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_SET_CONFIGURATION state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_set_configuration_handle (usb_core_handle_struct *pudev, 
+                                           usbh_host_struct *puhost, 
+                                           usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_SET_CONFIGURATION;
+
+    if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state ) {
+        usbh_enum_cfg_set(pudev, puhost, (uint16_t)puhost->device.cfg_desc.bConfigurationValue);
+    }
+    
+    if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+        scd_event_handle(pudev, 
+                         puhost, 
+                         pustate, 
+                         ENUN_EVENT_DEV_CONFIGURED, 
+                         pustate->usbh_current_state);
+    }
+}
+
+/*!
+    \brief      the handle function of ENUM_DEV_CONFIGURED state
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  pustate: pointer to USB state driver
+    \param[out] none
+    \retval     none
+*/
+static void enum_dev_configured_handle (usb_core_handle_struct *pudev, 
+                                        usbh_host_struct *puhost, 
+                                        usbh_state_handle_struct *pustate)
+{
+    puhost->usbh_backup_state.enum_backup_state = ENUM_DEV_CONFIGURED;
+    scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+}
+
+/*!
+    \brief      get descriptor in usb host enumeration stage
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  buf: buffer to store the descriptor
+    \param[in]  ReqType: descriptor type
+    \param[in]  ValueIdx: wValue for the GetDescriptr request
+    \param[in]  Len: length of the descriptor
+    \param[out] none
+    \retval     none
+*/
+void usbh_enum_desc_get(usb_core_handle_struct *pudev, 
+                        usbh_host_struct *puhost, 
+                        uint8_t *buf, 
+                        uint8_t  req_type, 
+                        uint16_t value_idx, 
+                        uint16_t len)
+{
+    usb_setup_union *pSetup = &(puhost->control.setup);
+
+    pSetup->b.bmRequestType = USB_DIR_IN | req_type;
+    pSetup->b.bRequest = USBREQ_GET_DESCRIPTOR;
+    pSetup->b.wValue = value_idx;
+
+    if (USB_STRDESC == (value_idx & 0xff00U)){
+        pSetup->b.wIndex = 0x0409U;
+    } else {
+        pSetup->b.wIndex = 0U;
+    }
+
+    pSetup->b.wLength = len;
+    
+    puhost->control.buff = buf;
+    puhost->control.length = len;
+    
+}
+
+/*!
+    \brief      set address in usb host enumeration stage
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  device_address: the device address
+    \param[out] none
+    \retval     none
+*/
+void usbh_enum_addr_set(usb_core_handle_struct *pudev, 
+                        usbh_host_struct *puhost,
+                        uint8_t device_address)
+{
+    usb_setup_union *p_setup = &(puhost->control.setup);
+
+    p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ;
+    p_setup->b.bRequest = USBREQ_SET_ADDRESS;
+    p_setup->b.wValue = (uint16_t)device_address;
+    p_setup->b.wIndex = 0U;
+    p_setup->b.wLength = 0U;
+    puhost->control.buff = 0U;
+    puhost->control.length = 0U;
+}
+
+/*!
+    \brief      set configuration in usb host enumeration stage
+    \param[in]  pudev: pointer to USB device
+    \param[in]  puhost: pointer to USB host
+    \param[in]  cfg_idx: the index of the configuration
+    \param[out] none
+    \retval     none
+*/
+void usbh_enum_cfg_set(usb_core_handle_struct *pudev, 
+                       usbh_host_struct *puhost,
+                       uint16_t cfg_idx)
+{
+    usb_setup_union *p_setup = &(puhost->control.setup);
+
+    p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ;
+    p_setup->b.bRequest = USBREQ_SET_CONFIGURATION;
+    p_setup->b.wValue = cfg_idx;
+    p_setup->b.wIndex = 0U;
+    p_setup->b.wLength = 0U;
+    puhost->control.buff = 0;
+    puhost->control.length = 0U;
+}
+
+/*!
+    \brief      parse the device descriptor
+    \param[in]  dev_desc: device_descriptor destinaton address 
+    \param[in]  buf: buffer where the source descriptor is available
+    \param[in]  len: length of the descriptor
+    \param[out] none
+    \retval     none
+*/
+void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len)
+{
+    dev_desc->Header.bLength  = *(uint8_t *)(buf + 0);
+    dev_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+    dev_desc->bcdUSB          = SWAPBYTE(buf + 2);
+    dev_desc->bDeviceClass    = *(uint8_t *)(buf + 4);
+    dev_desc->bDeviceSubClass = *(uint8_t *)(buf + 5);
+    dev_desc->bDeviceProtocol = *(uint8_t *)(buf + 6);
+    dev_desc->bMaxPacketSize0 = *(uint8_t *)(buf + 7);
+
+    if (len > 8U){
+        /* for 1st time after device connection, host may issue only 8 bytes for device descriptor length  */
+        dev_desc->idVendor      = SWAPBYTE(buf + 8);
+        dev_desc->idProduct     = SWAPBYTE(buf + 10);
+        dev_desc->bcdDevice     = SWAPBYTE(buf + 12);
+        dev_desc->iManufacturer = *(uint8_t *)(buf + 14);
+        dev_desc->iProduct      = *(uint8_t *)(buf + 15);
+        dev_desc->iSerialNumber = *(uint8_t *)(buf + 16);
+        dev_desc->bNumberConfigurations = *(uint8_t *)(buf + 17);
+    }
+}
+
+/*!
+    \brief      parse the configuration descriptor
+    \param[in]  cfg_desc: configuration descriptor address
+    \param[in]  itf_desc: interface descriptor address
+    \param[in]  ep_desc: endpoint descriptor address
+    \param[in]  buf: buffer where the source descriptor is available
+    \param[in]  len: length of the descriptor
+    \param[out] none
+    \retval     none
+*/
+void  usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc,
+                           usb_descriptor_interface_struct *itf_desc,
+                           usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM],
+                           uint8_t *buf,
+                           uint16_t len)
+{  
+    usb_descriptor_interface_struct *pitf = NULL;
+    usb_descriptor_interface_struct temp_pitf;
+    usb_descriptor_endpoint_struct *pep = NULL;
+    usb_descriptor_header_struct *pdesc = (usb_descriptor_header_struct *)buf;
+
+    uint8_t itf_ix = 0U;
+    uint8_t ep_ix = 0U;
+    uint16_t ptr = 0U;
+    static uint8_t prev_itf = 0U;
+    static uint16_t prev_ep_size = 0U;
+
+    /* parse configuration descriptor */
+    cfg_desc->Header.bLength         = *(uint8_t *)(buf + 0);
+    cfg_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+    cfg_desc->wTotalLength           = SWAPBYTE(buf + 2);
+    cfg_desc->bNumInterfaces         = *(uint8_t *)(buf + 4);
+    cfg_desc->bConfigurationValue    = *(uint8_t *)(buf + 5);
+    cfg_desc->iConfiguration         = *(uint8_t *)(buf + 6);
+    cfg_desc->bmAttributes           = *(uint8_t *)(buf + 7);
+    cfg_desc->bMaxPower              = *(uint8_t *)(buf + 8);
+
+    if (len > USB_CFGDESC_SIZE) {
+        ptr = USB_CFG_DESC_LEN;
+
+        if (cfg_desc->bNumInterfaces <= USBH_MAX_INTERFACES_NUM) {
+            pitf = (usb_descriptor_interface_struct *)0;
+
+            for (; ptr < cfg_desc->wTotalLength; ) {
+                pdesc = usbh_next_desc_get((uint8_t *)pdesc, &ptr);
+
+                if (USB_DESCTYPE_INTERFACE == pdesc->bDescriptorType) {
+                    itf_ix = *((uint8_t *)pdesc + 2U);
+                    pitf = &itf_desc[itf_ix];
+
+                    if (*((uint8_t *)pdesc + 3U) < 3U) {
+                        usbh_interface_desc_parse (&temp_pitf, (uint8_t *)pdesc);
+
+                        /* parse endpoint descriptors relative to the current interface */
+                        if (temp_pitf.bNumEndpoints <= USBH_MAX_EP_NUM) {
+                            for (ep_ix = 0U; ep_ix < temp_pitf.bNumEndpoints;) {
+                                pdesc = usbh_next_desc_get((void* )pdesc, &ptr);
+
+                                if (USB_DESCTYPE_ENDPOINT == pdesc->bDescriptorType) {
+                                    pep = &ep_desc[itf_ix][ep_ix];
+
+                                    if (prev_itf != itf_ix) {
+                                        prev_itf = itf_ix;
+                                        usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf);
+                                    } else {
+                                        if (prev_ep_size > SWAPBYTE((uint8_t *)pdesc + 4)) {
+                                            break;
+                                        } else {
+                                            usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf);
+                                        }
+                                    }
+
+                                    usbh_endpoint_desc_parse (pep, (uint8_t *)pdesc);
+                                    prev_ep_size = SWAPBYTE((uint8_t *)pdesc + 4);
+                                    ep_ix++;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        prev_ep_size = 0U;
+        prev_itf = 0U; 
+    }
+}
+
+/*!
+    \brief      parse the interface descriptor
+    \param[in]  itf_desc: interface descriptor destination
+    \param[in]  buf: buffer where the descriptor data is available
+    \param[out] none
+    \retval     none
+*/
+void  usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf)
+{
+    itf_desc->Header.bLength         = *(uint8_t *)(buf + 0);
+    itf_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+    itf_desc->bInterfaceNumber       = *(uint8_t *)(buf + 2);
+    itf_desc->bAlternateSetting      = *(uint8_t *)(buf + 3);
+    itf_desc->bNumEndpoints          = *(uint8_t *)(buf + 4);
+    itf_desc->bInterfaceClass        = *(uint8_t *)(buf + 5);
+    itf_desc->bInterfaceSubClass     = *(uint8_t *)(buf + 6);
+    itf_desc->bInterfaceProtocol     = *(uint8_t *)(buf + 7);
+    itf_desc->iInterface             = *(uint8_t *)(buf + 8);
+}
+
+/*!
+    \brief      parse the endpoint descriptor
+    \param[in]  ep_desc: endpoint descriptor destination address
+    \param[in]  buf: buffer where the parsed descriptor stored
+    \param[out] none
+    \retval     none
+*/
+void  usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf)
+{
+    ep_desc->Header.bLength          = *(uint8_t *)(buf + 0);
+    ep_desc->Header.bDescriptorType  = *(uint8_t *)(buf + 1);
+    ep_desc->bEndpointAddress = *(uint8_t *)(buf + 2);
+    ep_desc->bmAttributes     = *(uint8_t *)(buf + 3);
+    ep_desc->wMaxPacketSize   = SWAPBYTE(buf + 4);
+    ep_desc->bInterval        = *(uint8_t *)(buf + 6);
+}
+
+/*!
+    \brief      parse the string descriptor
+    \param[in]  psrc: source pointer containing the descriptor data
+    \param[in]  pdest: destination address pointer
+    \param[in]  len: length of the descriptor
+    \param[out] none
+    \retval     none
+*/
+void usbh_string_desc_parse (uint8_t* psrc, uint8_t* pdest, uint16_t len)
+{
+    uint16_t strlength;
+    uint16_t idx;
+
+    /* the unicode string descriptor is not null-terminated. the string length is
+        computed by substracting two from the value of the first byte of the descriptor.
+    */
+
+    /* check which is lower size, the size of string or the length of bytes read from the device */
+
+    if (USB_DESCTYPE_STRING == psrc[1]){
+        /* make sure the descriptor is string type */
+
+        /* psrc[0] contains size of descriptor, subtract 2 to get the length of string */      
+        strlength = ((((uint16_t)psrc[0] - 2U) <= len) ? ((uint16_t)psrc[0] - 2U) : len);
+        psrc += 2; /* adjust the offset ignoring the string len and descriptor type */
+
+        for (idx = 0U; idx < strlength; idx += 2U) {
+            /* copy only the string and ignore the unicode id, hence add the src */
+            *pdest = psrc[idx];
+            pdest++;
+        }
+
+        *pdest = 0U; /* mark end of string */  
+    }
+}
+
+/*!
+    \brief      get the next descriptor header
+    \param[in]  pbuf: pointer to buffer where the cfg descriptor is available
+    \param[in]  ptr: data popinter inside the configuration descriptor
+    \param[out] none
+    \retval     next descriptor header
+*/
+usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr)
+{
+    uint8_t len = ((usb_descriptor_header_struct *)pbuf)->bLength;
+
+    usb_descriptor_header_struct *pnext;
+
+    *ptr += len;
+
+    pnext = (usb_descriptor_header_struct *)((uint8_t *)pbuf + len);
+
+    return(pnext);
+}
+

+ 36 - 0
bsp/gd32450z-eval/Libraries/SConscript

@@ -0,0 +1,36 @@
+import rtconfig
+from building import *
+
+# get current directory
+cwd = GetCurrentDir()
+
+# The set of source files associated with this SConscript file.
+
+src = Glob('GD32F4xx_standard_peripheral/Source/*.c')
+src += [cwd + '/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c']
+
+#add for startup script
+if rtconfig.CROSS_TOOL == 'gcc':
+    print '================================================='
+    print 'Not support gcc yet!'
+    print '================================================='
+    exit(0)
+elif rtconfig.CROSS_TOOL == 'keil':
+    src += [cwd + '/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s']
+elif rtconfig.CROSS_TOOL == 'iar':
+    src += [cwd + '/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s']
+
+path = [
+    cwd + '/CMSIS/GD/GD32F4xx/Include',
+    cwd + '/CMSIS',
+    cwd + '/GD32F4xx_standard_peripheral/Include',]
+    
+if GetDepend(['RT_USING_BSP_USB']):
+    path += [cwd + '/GD32F4xx_usb_driver/Include']
+    src  += [cwd + '/GD32F4xx_usb_driver/Source']
+
+CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'GD32F4XX']
+
+group = DefineGroup('GD32_Lib', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
+
+Return('group')

+ 14 - 0
bsp/gd32450z-eval/SConscript

@@ -0,0 +1,14 @@
+# for module compiling
+import os
+Import('RTT_ROOT')
+
+cwd = str(Dir('#'))
+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')

+ 39 - 0
bsp/gd32450z-eval/SConstruct

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

+ 11 - 0
bsp/gd32450z-eval/applications/SConscript

@@ -0,0 +1,11 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd     = os.path.join(str(Dir('#')), 'applications')
+src	= Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 45 - 0
bsp/gd32450z-eval/applications/application.c

@@ -0,0 +1,45 @@
+/*
+ * File      : application.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      the first version
+ * 2014-04-27     Bernard      make code cleanup. 
+ */
+
+#include <board.h>
+#include <rtthread.h>
+#include "finsh.h"
+
+#include <gd32f4xx.h>
+
+void rt_init_thread_entry(void* parameter)
+{    
+     /* initialization RT-Thread Components */
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_init();
+#endif
+
+}
+int rt_application_init()
+{
+    rt_thread_t tid;
+
+
+    tid = rt_thread_create("init",
+        rt_init_thread_entry, RT_NULL,
+        2048, RT_THREAD_PRIORITY_MAX/3, 20);
+
+    if (tid != RT_NULL)
+        rt_thread_startup(tid);
+    
+
+
+    return 0;
+}

+ 107 - 0
bsp/gd32450z-eval/applications/startup.c

@@ -0,0 +1,107 @@
+/*
+ * File      : startup.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-31     Bernard      first implementation
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <gd32f4xx.h>
+#include "board.h"
+
+/**
+ * @addtogroup GD32F4xx
+ */
+
+/*@{*/
+
+extern int  rt_application_init(void);
+
+#ifdef RT_USING_FINSH
+extern int finsh_system_init(void);
+extern void finsh_set_device(const char* device);
+#endif
+
+/*******************************************************************************
+* Function Name  : assert_failed
+* Description    : Reports the name of the source file and the source line number
+*                  where the assert error has occurred.
+* Input          : - file: pointer to the source file name
+*                  - line: assert error line source number
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void assert_failed(uint8_t* file, uint32_t line)
+{
+    rt_kprintf("\n\r Wrong parameter value detected on\r\n");
+    rt_kprintf("       file  %s\r\n", file);
+    rt_kprintf("       line  %d\r\n", line);
+
+    while (1) ;
+}
+
+/**
+ * This function will startup RT-Thread RTOS.
+ */
+void rtthread_startup(void)
+{
+    /* init board */
+    rt_hw_board_init();
+
+    /* show version */
+    rt_show_version();
+
+    /* init tick */
+    rt_system_tick_init();
+
+    /* init kernel object */
+    rt_system_object_init();
+
+    /* init timer system */
+    rt_system_timer_init();
+
+#ifdef RT_USING_EXT_SDRAM
+    rt_system_heap_init((void*)EXT_SDRAM_BEGIN, (void*)EXT_SDRAM_END);
+#else
+    rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END);
+#endif
+
+    /* init scheduler system */
+    rt_system_scheduler_init();
+
+    /* init application */
+    rt_application_init();
+
+    /* init timer thread */
+    rt_system_timer_thread_init();
+
+    /* init idle thread */
+    rt_thread_idle_init();
+
+    /* start scheduler */
+    rt_system_scheduler_start();
+
+    /* never reach here */
+    return ;
+}
+
+int main(void)
+{
+    /* disable interrupt first */
+    rt_hw_interrupt_disable();
+
+    /* startup RT-Thread RTOS */
+    rtthread_startup();
+    return 0;
+}
+
+/*@}*/

+ 17 - 0
bsp/gd32450z-eval/drivers/SConscript

@@ -0,0 +1,17 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd     = os.path.join(str(Dir('#')), 'drivers')
+
+# add the general drivers.
+src = Split("""
+board.c
+drv_usart.c
+""")
+
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 139 - 0
bsp/gd32450z-eval/drivers/board.c

@@ -0,0 +1,139 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      first implementation
+ */
+#include <stdint.h>
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <gd32f4xx.h>
+#include <board.h>
+#include <drv_usart.h>
+
+void _init(void)
+{
+
+}
+
+/**
+  * @brief  This function is executed in case of error occurrence.
+  * @param  None
+  * @retval None
+  */
+void Error_Handler(void)
+{
+  /* USER CODE BEGIN Error_Handler */
+  /* User can add his own implementation to report the HAL error return state */
+  while(1)
+  {
+  }
+  /* USER CODE END Error_Handler */
+}
+
+/** System Clock Configuration
+*/
+void SystemClock_Config(void)
+{
+
+//  RCC_OscInitTypeDef RCC_OscInitStruct;
+//  RCC_ClkInitTypeDef RCC_ClkInitStruct;
+//  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+
+//  __HAL_RCC_PWR_CLK_ENABLE();
+
+//  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+//  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+//  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+//  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+//  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+//  RCC_OscInitStruct.PLL.PLLM = 25;
+//  RCC_OscInitStruct.PLL.PLLN = 360;
+//  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+//  RCC_OscInitStruct.PLL.PLLQ = 8;
+//  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+//  {
+//    Error_Handler();
+//  }
+
+//  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+//                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+//  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+//  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+//  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+//  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
+//  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
+//  {
+//    Error_Handler();
+//  }
+
+//  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+//  PeriphClkInitStruct.PLLSAI.PLLSAIN = 260;
+//  PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;
+//  PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
+//  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
+//  {
+//    Error_Handler();
+//  }
+
+    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
+    NVIC_SetPriority(SysTick_IRQn, 0);
+}
+
+/**
+ * This is the timer interrupt service routine.
+ *
+ */
+void SysTick_Handler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    rt_tick_increase();
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+
+/**
+ * This function will initial GD32 board.
+ */
+void rt_hw_board_init()
+{
+     /* NVIC Configuration */
+#define NVIC_VTOR_MASK              0x3FFFFF80
+#ifdef  VECT_TAB_RAM
+    /* Set the Vector Table base location at 0x10000000 */
+    SCB->VTOR  = (0x10000000 & NVIC_VTOR_MASK);
+#else  /* VECT_TAB_FLASH  */
+    /* Set the Vector Table base location at 0x08000000 */
+    SCB->VTOR  = (0x08000000 & NVIC_VTOR_MASK);
+#endif
+    
+    SystemClock_Config();
+    
+#ifdef RT_USING_CONSOLE
+    rt_console_set_device(CONSOLE_DEVICE);
+#endif
+    
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+
+#else
+    SDRAM_Init();
+    mpu_init();
+#endif
+
+}
+
+/*@}*/

+ 74 - 0
bsp/gd32450z-eval/drivers/board.h

@@ -0,0 +1,74 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-09-22     Bernard      add board.h to this bsp
+ */
+
+// <<< Use Configuration Wizard in Context Menu >>>
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <gd32f4xx.h>
+
+//	<o>Begin Address of External SDRAM
+//		<i>Default: 0xD0000000
+#define EXT_SDRAM_BEGIN    SDRAM_BANK_ADDR /* the begining address of external SDRAM */
+//	<o>End Address of External SRAM
+//		<i>Default: 0xD0800000
+#define EXT_SDRAM_END      (SDRAM_BANK_ADDR + W9825G6KH_SIZE) /* the end address of external SDRAM */
+
+// <o> Internal SRAM memory size[Kbytes] <8-64>
+//	<i>Default: 64
+#ifdef __ICCARM__
+// Use *.icf ram symbal, to avoid hardcode.
+extern char __ICFEDIT_region_RAM_end__;
+#define GD32_SRAM_END          &__ICFEDIT_region_RAM_end__
+#else
+#define GD32_SRAM_SIZE         128
+#define GD32_SRAM_END          (0x20000000 + GD32_SRAM_SIZE * 1024)
+#endif
+
+#ifdef __CC_ARM
+extern int Image$$RW_IRAM1$$ZI$$Limit;
+#define HEAP_BEGIN    (&Image$$RW_IRAM1$$ZI$$Limit)
+#elif __ICCARM__
+#pragma section="HEAP"
+#define HEAP_BEGIN    (__segment_end("HEAP"))
+#else
+extern int __bss_end;
+#define HEAP_BEGIN    (&__bss_end)
+#endif
+
+#define HEAP_END          GD32_SRAM_END
+
+// <o> Console on USART: <0=> no console <1=>USART 1 <2=>USART 2 <3=> USART 3
+// 	<i>Default: 1
+#define GD32_CONSOLE_USART		1
+
+void rt_hw_board_init(void);
+
+#if GD32_CONSOLE_USART == 0
+#define CONSOLE_DEVICE "no"
+#elif GD32_CONSOLE_USART == 1
+#define CONSOLE_DEVICE "uart1"
+#elif GD32_CONSOLE_USART == 2
+#define CONSOLE_DEVICE "uart2"
+#elif GD32_CONSOLE_USART == 3
+#define CONSOLE_DEVICE "uart3"
+#endif
+
+#define FINSH_DEVICE_NAME   CONSOLE_DEVICE
+
+void Error_Handler(void);
+
+#endif
+
+//*** <<< end of configuration section >>>    ***

+ 695 - 0
bsp/gd32450z-eval/drivers/drv_usart.c

@@ -0,0 +1,695 @@
+/*
+ * File      : usart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      the first version
+ * 2010-03-29     Bernard      remove interrupt Tx and DMA Rx mode
+ * 2012-02-08     aozima       update for F4.
+ * 2012-07-28     aozima       update for ART board.
+ * 2016-05-28     armink       add DMA Rx mode
+ */
+
+#include <gd32f4xx.h>
+#include <drv_usart.h>
+#include <board.h>
+
+#include <rtdevice.h>
+
+#ifdef RT_USING_UART1
+#define USART1_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
+#define USART1_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
+
+/* Definition for USART1 Pins */
+#define USART1_TX_PIN                    GPIO_PIN_9
+#define USART1_TX_GPIO_PORT              GPIOA
+#define USART1_TX_AF                     GPIO_AF7_USART1
+#define USART1_RX_PIN                    GPIO_PIN_10
+#define USART1_RX_GPIO_PORT              GPIOA
+#define USART1_RX_AF                     GPIO_AF7_USART1
+#endif
+
+#ifdef RT_USING_UART2
+#define USART2_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
+#define USART2_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
+
+/* Definition for USART2 Pins */
+#define USART2_TX_PIN                    GPIO_PIN_2
+#define USART2_TX_GPIO_PORT              GPIOA
+#define USART2_TX_AF                     GPIO_AF7_USART2
+#define USART2_RX_PIN                    GPIO_PIN_3
+#define USART2_RX_GPIO_PORT              GPIOA
+#define USART2_RX_AF                     GPIO_AF7_USART2
+#endif
+
+#ifdef RT_USING_UART3
+#define USART3_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()
+#define USART3_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()
+
+/* Definition for USART3 Pins */
+#define USART3_TX_PIN                    GPIO_PIN_10
+#define USART3_TX_GPIO_PORT              GPIOB
+#define USART3_TX_AF                     GPIO_AF7_USART3
+#define USART3_RX_PIN                    GPIO_PIN_11
+#define USART3_RX_GPIO_PORT              GPIOB
+#define USART3_RX_AF                     GPIO_AF7_USART3
+#endif
+
+#ifdef RT_USING_UART4
+#define USART4_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
+#define USART4_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
+
+/* Definition for USART4 Pins */
+#define USART4_TX_PIN                    GPIO_PIN_10
+#define USART4_TX_GPIO_PORT              GPIOC
+#define USART4_TX_AF                     GPIO_AF7_USART4
+#define USART4_RX_PIN                    GPIO_PIN_11
+#define USART4_RX_GPIO_PORT              GPIOC
+#define USART4_RX_AF                     GPIO_AF7_USART4
+#endif
+
+#ifdef RT_USING_UART5
+#define USART5_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOD_CLK_ENABLE()
+#define USART5_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
+
+/* Definition for USART5 Pins */
+#define USART5_TX_PIN                    GPIO_PIN_12
+#define USART5_TX_GPIO_PORT              GPIOC
+#define USART5_TX_AF                     GPIO_AF7_USART5
+#define USART5_RX_PIN                    GPIO_PIN_2
+#define USART5_RX_GPIO_PORT              GPIOD
+#define USART5_RX_AF                     GPIO_AF7_USART5
+#endif
+
+/* GD32 uart driver */
+struct gd32_uart
+{
+    UART_HandleTypeDef UartHandle;
+    IRQn_Type irq;
+};
+
+static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+  struct gd32_uart *uart;
+
+  RT_ASSERT(serial != RT_NULL);
+  RT_ASSERT(cfg != RT_NULL);
+
+  uart = (struct gd32_uart *)serial->parent.user_data;
+
+  uart->UartHandle.Init.BaudRate   = cfg->baud_rate;
+  uart->UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
+  uart->UartHandle.Init.Mode       = UART_MODE_TX_RX;
+  uart->UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
+
+  switch (cfg->data_bits)
+  {
+  case DATA_BITS_8:
+      uart->UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
+      break;
+  case DATA_BITS_9:
+      uart->UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
+      break;
+  default:
+      uart->UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
+      break;
+  }
+  switch (cfg->stop_bits)
+  {
+  case STOP_BITS_1:
+      uart->UartHandle.Init.StopBits   = UART_STOPBITS_1;
+      break;
+  case STOP_BITS_2:
+      uart->UartHandle.Init.StopBits   = UART_STOPBITS_2;
+      break;
+  default:
+      uart->UartHandle.Init.StopBits   = UART_STOPBITS_1;
+      break;
+  }
+  switch (cfg->parity)
+  {
+  case PARITY_NONE:
+      uart->UartHandle.Init.Parity     = UART_PARITY_NONE;
+      break;
+  case PARITY_ODD:
+      uart->UartHandle.Init.Parity     = UART_PARITY_ODD;
+      break;
+  case PARITY_EVEN:
+      uart->UartHandle.Init.Parity     = UART_PARITY_EVEN;
+      break;
+  default:
+      uart->UartHandle.Init.Parity     = UART_PARITY_NONE;
+      break;
+  }
+
+  if (HAL_UART_Init(&uart->UartHandle) != HAL_OK)
+  {
+      return RT_ERROR;
+  }
+
+  return RT_EOK;
+}
+
+static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+  struct gd32_uart *uart;
+
+  RT_ASSERT(serial != RT_NULL);
+  uart = (struct gd32_uart *)serial->parent.user_data;
+
+  switch (cmd)
+  {
+  case RT_DEVICE_CTRL_CLR_INT:
+      /* disable rx irq */
+      NVIC_DisableIRQ(uart->irq);
+      /* disable interrupt */
+      __HAL_UART_DISABLE_IT(&uart->UartHandle, UART_IT_RXNE);
+      break;
+  case RT_DEVICE_CTRL_SET_INT:
+      /* enable rx irq */
+      NVIC_EnableIRQ(uart->irq);
+      /* enable interrupt */
+      __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_RXNE);
+      break;
+  }
+
+  return RT_EOK;
+}
+
+static int gd32_putc(struct rt_serial_device *serial, char c)
+{
+    struct gd32_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct gd32_uart *)serial->parent.user_data;
+
+    while((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_TXE) == RESET));
+    uart->UartHandle.Instance->DR = c;
+    return 1;
+}
+
+static int gd32_getc(struct rt_serial_device *serial)
+{
+    int ch;
+    struct gd32_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct gd32_uart *)serial->parent.user_data;
+
+    ch = -1;
+    if (__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET)
+        ch = uart->UartHandle.Instance->DR & 0xff;
+    return ch;
+}
+
+/**
+ * Uart common interrupt process. This need add to uart ISR.
+ *
+ * @param serial serial device
+ */
+static void uart_isr(struct rt_serial_device *serial) {
+    struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
+
+    RT_ASSERT(uart != RT_NULL);
+
+    /* UART in mode Receiver -------------------------------------------------*/
+    if ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET) &&
+            (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
+    {
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+        /* Clear RXNE interrupt flag */
+        __HAL_UART_CLEAR_FLAG(&uart->UartHandle, UART_FLAG_RXNE);
+    }
+}
+
+/**
+* @brief UART MSP Initialization
+*        This function configures the hardware resources used in this example:
+*           - Peripheral's clock enable
+*           - Peripheral's GPIO Configuration
+*           - NVIC configuration for UART interrupt request enable
+* @param huart: UART handle pointer
+* @retval None
+*/
+void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+    GPIO_InitTypeDef  GPIO_InitStruct;
+
+#if defined(RT_USING_UART1)
+    if (huart->Instance == USART1)
+    {
+        /*##-1- Enable peripherals and GPIO Clocks #################################*/
+        /* Enable GPIO TX/RX clock */
+        USART1_TX_GPIO_CLK_ENABLE();
+        USART1_RX_GPIO_CLK_ENABLE();
+
+        /* Enable USARTx clock */
+        __HAL_RCC_USART1_CLK_ENABLE();
+
+        /*##-2- Configure peripheral GPIO ##########################################*/
+        /* UART TX GPIO pin configuration  */
+        GPIO_InitStruct.Pin       = USART1_TX_PIN;
+        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull      = GPIO_PULLUP;
+        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
+        GPIO_InitStruct.Alternate = USART1_TX_AF;
+
+        HAL_GPIO_Init(USART1_TX_GPIO_PORT, &GPIO_InitStruct);
+
+        /* UART RX GPIO pin configuration  */
+        GPIO_InitStruct.Pin = USART1_RX_PIN;
+        GPIO_InitStruct.Alternate = USART1_RX_AF;
+
+        HAL_GPIO_Init(USART1_RX_GPIO_PORT, &GPIO_InitStruct);
+
+        HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
+        HAL_NVIC_EnableIRQ(USART1_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART2)
+    if (huart->Instance == USART2)
+    {
+        /*##-1- Enable peripherals and GPIO Clocks #################################*/
+        /* Enable GPIO TX/RX clock */
+        USART2_TX_GPIO_CLK_ENABLE();
+        USART2_RX_GPIO_CLK_ENABLE();
+
+        /* Enable USARTx clock */
+        __HAL_RCC_USART2_CLK_ENABLE();
+
+        /*##-2- Configure peripheral GPIO ##########################################*/
+        /* UART TX GPIO pin configuration  */
+        GPIO_InitStruct.Pin       = USART2_TX_PIN;
+        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull      = GPIO_PULLUP;
+        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
+        GPIO_InitStruct.Alternate = USART2_TX_AF;
+
+        HAL_GPIO_Init(USART2_TX_GPIO_PORT, &GPIO_InitStruct);
+
+        /* UART RX GPIO pin configuration  */
+        GPIO_InitStruct.Pin = USART2_RX_PIN;
+        GPIO_InitStruct.Alternate = USART2_RX_AF;
+
+        HAL_GPIO_Init(USART2_RX_GPIO_PORT, &GPIO_InitStruct);
+
+        HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);
+        HAL_NVIC_EnableIRQ(USART2_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART3)
+    if (huart->Instance == USART3)
+    {
+        /*##-1- Enable peripherals and GPIO Clocks #################################*/
+        /* Enable GPIO TX/RX clock */
+        USART3_TX_GPIO_CLK_ENABLE();
+        USART3_RX_GPIO_CLK_ENABLE();
+
+        /* Enable USARTx clock */
+        __HAL_RCC_USART3_CLK_ENABLE();
+
+        /*##-2- Configure peripheral GPIO ##########################################*/
+        /* UART TX GPIO pin configuration  */
+        GPIO_InitStruct.Pin       = USART3_TX_PIN;
+        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull      = GPIO_PULLUP;
+        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
+        GPIO_InitStruct.Alternate = USART3_TX_AF;
+
+        HAL_GPIO_Init(USART3_TX_GPIO_PORT, &GPIO_InitStruct);
+
+        /* UART RX GPIO pin configuration  */
+        GPIO_InitStruct.Pin = USART3_RX_PIN;
+        GPIO_InitStruct.Alternate = USART3_RX_AF;
+
+        HAL_GPIO_Init(USART3_RX_GPIO_PORT, &GPIO_InitStruct);
+
+        HAL_NVIC_SetPriority(USART3_IRQn, 0, 1);
+        HAL_NVIC_EnableIRQ(USART3_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART4)
+    if (huart->Instance == USART4)
+    {
+        /*##-1- Enable peripherals and GPIO Clocks #################################*/
+        /* Enable GPIO TX/RX clock */
+        USART4_TX_GPIO_CLK_ENABLE();
+        USART4_RX_GPIO_CLK_ENABLE();
+
+        /* Enable USARTx clock */
+        __HAL_RCC_USART4_CLK_ENABLE();
+
+        /*##-2- Configure peripheral GPIO ##########################################*/
+        /* UART TX GPIO pin configuration  */
+        GPIO_InitStruct.Pin       = USART4_TX_PIN;
+        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull      = GPIO_PULLUP;
+        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
+        GPIO_InitStruct.Alternate = USART4_TX_AF;
+
+        HAL_GPIO_Init(USART4_TX_GPIO_PORT, &GPIO_InitStruct);
+
+        /* UART RX GPIO pin configuration  */
+        GPIO_InitStruct.Pin = USART4_RX_PIN;
+        GPIO_InitStruct.Alternate = USART4_RX_AF;
+
+        HAL_GPIO_Init(USART4_RX_GPIO_PORT, &GPIO_InitStruct);
+
+        HAL_NVIC_SetPriority(USART4_IRQn, 0, 1);
+        HAL_NVIC_EnableIRQ(USART4_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART5)
+    if (huart->Instance == USART5)
+    {
+        /*##-1- Enable peripherals and GPIO Clocks #################################*/
+        /* Enable GPIO TX/RX clock */
+        USART5_TX_GPIO_CLK_ENABLE();
+        USART5_RX_GPIO_CLK_ENABLE();
+
+        /* Enable USARTx clock */
+        __HAL_RCC_USART5_CLK_ENABLE();
+
+        /*##-2- Configure peripheral GPIO ##########################################*/
+        /* UART TX GPIO pin configuration  */
+        GPIO_InitStruct.Pin       = USART5_TX_PIN;
+        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull      = GPIO_PULLUP;
+        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
+        GPIO_InitStruct.Alternate = USART5_TX_AF;
+
+        HAL_GPIO_Init(USART5_TX_GPIO_PORT, &GPIO_InitStruct);
+
+        /* UART RX GPIO pin configuration  */
+        GPIO_InitStruct.Pin = USART5_RX_PIN;
+        GPIO_InitStruct.Alternate = USART5_RX_AF;
+
+        HAL_GPIO_Init(USART5_RX_GPIO_PORT, &GPIO_InitStruct);
+
+        HAL_NVIC_SetPriority(USART5_IRQn, 0, 1);
+        HAL_NVIC_EnableIRQ(USART5_IRQn);
+    }
+#endif
+}
+
+/**
+* @brief UART MSP De-Initialization
+*        This function frees the hardware resources used in this example:
+*          - Disable the Peripheral's clock
+*          - Revert GPIO and NVIC configuration to their default state
+* @param huart: UART handle pointer
+* @retval None
+*/
+void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+#if defined(RT_USING_UART1)
+    if (huart->Instance == USART1)
+    {
+        /*##-1- Reset peripherals ##################################################*/
+        __HAL_RCC_USART1_FORCE_RESET();
+        __HAL_RCC_USART1_RELEASE_RESET();
+
+        /*##-2- Disable peripherals and GPIO Clocks #################################*/
+        /* Configure UART Tx as alternate function  */
+        HAL_GPIO_DeInit(USART1_TX_GPIO_PORT, USART1_TX_PIN);
+        /* Configure UART Rx as alternate function  */
+        HAL_GPIO_DeInit(USART1_RX_GPIO_PORT, USART1_RX_PIN);
+
+        HAL_NVIC_DisableIRQ(USART1_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART2)
+    if (huart->Instance == USART2)
+    {
+        /*##-1- Reset peripherals ##################################################*/
+        __HAL_RCC_USART2_FORCE_RESET();
+        __HAL_RCC_USART2_RELEASE_RESET();
+
+        /*##-2- Disable peripherals and GPIO Clocks #################################*/
+        /* Configure UART Tx as alternate function  */
+        HAL_GPIO_DeInit(USART2_TX_GPIO_PORT, USART2_TX_PIN);
+        /* Configure UART Rx as alternate function  */
+        HAL_GPIO_DeInit(USART2_RX_GPIO_PORT, USART2_RX_PIN);
+
+        HAL_NVIC_DisableIRQ(USART2_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART3)
+    if (huart->Instance == USART3)
+    {
+        /*##-1- Reset peripherals ##################################################*/
+        __HAL_RCC_USART3_FORCE_RESET();
+        __HAL_RCC_USART3_RELEASE_RESET();
+
+        /*##-2- Disable peripherals and GPIO Clocks #################################*/
+        /* Configure UART Tx as alternate function  */
+        HAL_GPIO_DeInit(USART3_TX_GPIO_PORT, USART3_TX_PIN);
+        /* Configure UART Rx as alternate function  */
+        HAL_GPIO_DeInit(USART3_RX_GPIO_PORT, USART3_RX_PIN);
+
+        HAL_NVIC_DisableIRQ(USART3_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART4)
+    if (huart->Instance == USART4)
+    {
+        /*##-1- Reset peripherals ##################################################*/
+        __HAL_RCC_USART4_FORCE_RESET();
+        __HAL_RCC_USART4_RELEASE_RESET();
+
+        /*##-2- Disable peripherals and GPIO Clocks #################################*/
+        /* Configure UART Tx as alternate function  */
+        HAL_GPIO_DeInit(USART4_TX_GPIO_PORT, USART4_TX_PIN);
+        /* Configure UART Rx as alternate function  */
+        HAL_GPIO_DeInit(USART4_RX_GPIO_PORT, USART4_RX_PIN);
+
+        HAL_NVIC_DisableIRQ(USART4_IRQn);
+    }
+#endif
+
+#if defined(RT_USING_UART5)
+    if (huart->Instance == USART5)
+    {
+        /*##-1- Reset peripherals ##################################################*/
+        __HAL_RCC_USART5_FORCE_RESET();
+        __HAL_RCC_USART5_RELEASE_RESET();
+
+        /*##-2- Disable peripherals and GPIO Clocks #################################*/
+        /* Configure UART Tx as alternate function  */
+        HAL_GPIO_DeInit(USART5_TX_GPIO_PORT, USART5_TX_PIN);
+        /* Configure UART Rx as alternate function  */
+        HAL_GPIO_DeInit(USART5_RX_GPIO_PORT, USART5_RX_PIN);
+
+        HAL_NVIC_DisableIRQ(USART5_IRQn);
+    }
+#endif
+}
+
+
+static const struct rt_uart_ops gd32_uart_ops =
+{
+    gd32_configure,
+    gd32_control,
+    gd32_putc,
+    gd32_getc,
+};
+
+#if defined(RT_USING_UART1)
+/* UART1 device driver structure */
+struct gd32_uart uart1 =
+{
+    {USART1},
+    USART1_IRQn,
+};
+struct rt_serial_device serial1;
+
+void USART1_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial1);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART1 */
+
+#if defined(RT_USING_UART2)
+/* UART2 device driver structure */
+struct gd32_uart uart2 =
+{
+    {USART2},
+    USART2_IRQn,
+};
+struct rt_serial_device serial2;
+
+void USART2_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial2);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART2 */
+
+#if defined(RT_USING_UART3)
+/* UART3 device driver structure */
+struct gd32_uart uart3 =
+{
+    {USART3},
+    USART3_IRQn,
+};
+struct rt_serial_device serial3;
+
+void USART3_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial3);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART3 */
+
+#if defined(RT_USING_UART4)
+/* UART4 device driver structure */
+struct gd32_uart uart4 =
+{
+    {UART4},
+    UART4_IRQn,
+};
+struct rt_serial_device serial4;
+
+void UART4_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial4);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif /* RT_USING_UART4 */
+
+#if defined(RT_USING_UART5)
+/* UART5 device driver structure */
+struct gd32_uart uart5 =
+{
+    {UART5},
+    UART5_IRQn,
+};
+struct rt_serial_device serial5;
+
+void UART5_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial5);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART5 */
+
+int gd32_hw_usart_init(void)
+{
+    struct gd32_uart *uart;
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+#ifdef RT_USING_UART1
+    uart = &uart1;
+    uart->UartHandle.Instance = USART1;
+
+    serial1.ops    = &gd32_uart_ops;
+    serial1.config = config;
+
+    /* register UART1 device */
+    rt_hw_serial_register(&serial1,
+                          "uart1",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+#endif /* RT_USING_UART1 */
+
+#ifdef RT_USING_UART2
+    uart = &uart2;
+    uart->UartHandle.Instance = USART2;
+
+    serial2.ops    = &gd32_uart_ops;
+    serial2.config = config;
+
+    /* register UART1 device */
+    rt_hw_serial_register(&serial2,
+                          "uart2",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+#endif /* RT_USING_UART2 */
+
+#ifdef RT_USING_UART3
+    uart = &uart3;
+    uart->UartHandle.Instance = USART3;
+
+    serial3.ops    = &gd32_uart_ops;
+    serial3.config = config;
+
+    /* register UART3 device */
+    rt_hw_serial_register(&serial3,
+                          "uart3",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+#endif /* RT_USING_UART3 */
+
+#ifdef RT_USING_UART4
+    uart = &uart4;
+    uart->UartHandle.Instance = USART4;
+
+    serial4.ops    = &gd32_uart_ops;
+    serial4.config = config;
+
+    /* register UART4 device */
+    rt_hw_serial_register(&serial4,
+                          "uart4",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+#endif /* RT_USING_UART4 */
+
+#ifdef RT_USING_UART5
+    uart = &uart5;
+    uart->UartHandle.Instance = USART5;
+
+    serial5.ops    = &gd32_uart_ops;
+    serial5.config = config;
+
+    /* register UART5 device */
+    rt_hw_serial_register(&serial5,
+                          "uart5",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+#endif /* RT_USING_UART5 */
+    return 0;
+}
+INIT_BOARD_EXPORT(gd32_hw_usart_init);

+ 26 - 0
bsp/gd32450z-eval/drivers/drv_usart.h

@@ -0,0 +1,26 @@
+/*
+ * File      : usart.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      the first version
+ */
+
+#ifndef __USART_H__
+#define __USART_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define UART_ENABLE_IRQ(n)            NVIC_EnableIRQ((n))
+#define UART_DISABLE_IRQ(n)           NVIC_DisableIRQ((n))
+
+int gd32_hw_usart_init(void);
+
+#endif

+ 45 - 0
bsp/gd32450z-eval/drivers/gd32f4xx_libopt.h

@@ -0,0 +1,45 @@
+/*!
+    \file  gd32f4xx_libopt.h
+    \brief library optional for gd32f4xx
+*/
+
+/*
+    Copyright (C) 2016 GigaDevice
+
+    2016-10-19, V1.0.0, firmware for GD32F4xx
+*/
+
+#ifndef GD32F4XX_LIBOPT_H
+#define GD32F4XX_LIBOPT_H
+#include "gd32f4xx_rcu.h"
+#include "gd32f4xx_adc.h"
+#include "gd32f4xx_can.h"
+#include "gd32f4xx_crc.h"
+#include "gd32f4xx_ctc.h"
+#include "gd32f4xx_dac.h"
+#include "gd32f4xx_dbg.h"
+#include "gd32f4xx_dci.h"
+#include "gd32f4xx_dma.h"
+#include "gd32f4xx_enet.h"
+#include "gd32f4xx_exmc.h"
+#include "gd32f4xx_exti.h"
+#include "gd32f4xx_fmc.h"
+#include "gd32f4xx_fwdgt.h"
+#include "gd32f4xx_gpio.h"
+#include "gd32f4xx_syscfg.h"
+#include "gd32f4xx_i2c.h"
+#include "gd32f4xx_ipa.h"
+#include "gd32f4xx_iref.h"
+#include "gd32f4xx_pmu.h"
+#include "gd32f4xx_rcu.h"
+#include "gd32f4xx_rtc.h"
+#include "gd32f4xx_sdio.h"
+#include "gd32f4xx_spi.h"
+#include "gd32f4xx_timer.h"
+#include "gd32f4xx_tli.h"
+#include "gd32f4xx_trng.h"
+#include "gd32f4xx_usart.h"
+#include "gd32f4xx_wwdgt.h"
+#include "gd32f4xx_misc.h"
+
+#endif /* GD32F4XX_LIBOPT_H */

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