diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_adc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_adc.h
new file mode 100644
index 0000000000..e3b44fc49f
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_adc.h
@@ -0,0 +1,396 @@
+/*!
+ \file gd32e10x_adc.h
+ \brief definitions for the ADC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_ADC_H
+#define GD32E10X_ADC_H
+
+#include "gd32e10x.h"
+
+/* ADC definitions */
+#define ADC0 ADC_BASE
+#define ADC1 (ADC_BASE + 0x400U)
+
+/* 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 */
+
+/* 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 */
+
+/* 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_SYNCM BITS(16,19) /*!< sync mode selection */
+#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */
+#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */
+
+/* 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_DAL BIT(11) /*!< data alignment */
+#define ADC_CTL1_ETSIC BITS(12,14) /*!< external trigger select for inserted channel */
+#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */
+#define ADC_CTL1_ETSRC BITS(17,19) /*!< external trigger select for regular channel */
+#define ADC_CTL1_ETERC BIT(20) /*!< external trigger conversion mode for inserted channels */
+#define ADC_CTL1_SWICST BIT(21) /*!< start on inserted channel */
+#define ADC_CTL1_SWRCST BIT(22) /*!< start on regular channel */
+#define ADC_CTL1_TSVREN BIT(23) /*!< channel 16 and 17 enable of ADC0 */
+
+/* ADC_SAMPTx x=0..1 */
+#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel n 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 x=0..2 */
+#define ADC_RSQX_RSQN BITS(0,4) /*!< nth conversion in regular sequence */
+#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */
+
+/* ADC_ISQ */
+#define ADC_ISQ_ISQN BITS(0,4) /*!< nth conversion in inserted 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 n */
+
+/* ADC_RDATA */
+#define ADC_RDATA_RDATA BITS(0,15) /*!< regular data */
+#define ADC_RDATA_ADC1RDTR BITS(16,31) /*!< ADC1 regular channel 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 */
+#define ADC_OVSAMPCTL_DRES BITS(12,13) /*!< ADC resolution */
+
+/* constants definitions */
+/* adc_stat register value */
+#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 */
+
+/* adc_ctl0 register value */
+#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */
+
+/* scan mode */
+#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */
+
+/* inserted channel group convert automatically */
+#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */
+
+/* ADC sync mode */
+#define CTL0_SYNCM(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) /*!< write value to ADC_CTL0_SYNCM bit field */
+#define ADC_MODE_FREE CTL0_SYNCM(0) /*!< all the ADCs work independently */
+#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL CTL0_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel + inserted parallel mode */
+#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION CTL0_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular parallel + trigger rotation mode */
+#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(3) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode */
+#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(4) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode */
+#define ADC_DAUL_INSERTED_PARALLEL CTL0_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode only */
+#define ADC_DAUL_REGULAL_PARALLEL CTL0_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode only */
+#define ADC_DAUL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up fast mode only */
+#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(8) /*!< ADC0 and ADC1 work in follow-up slow mode only */
+#define ADC_DAUL_INSERTED_TRIGGER_ROTATION CTL0_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode only */
+
+/* adc_ctl1 register value */
+#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */
+#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */
+
+/* continuous mode */
+#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */
+
+/* external trigger select for regular channel */
+#define CTL1_ETSRC(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) /*!< write value to ADC_CTL1_ETSRC bit field */
+#define ADC0_1_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< timer 0 CC0 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< timer 0 CC1 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< timer 0 CC2 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< timer 1 CC1 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< timer 2 TRGO event select */
+#define ADC0_1_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(5) /*!< timer 3 CC3 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T7_TRGO CTL1_ETSRC(6) /*!< timer 7 TRGO event select */
+#define ADC0_1_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 */
+#define ADC0_1_EXTTRIG_REGULAR_NONE CTL1_ETSRC(7) /*!< software trigger */
+
+/* external trigger mode for inserted channel */
+#define CTL1_ETSIC(regval) (BITS(12,14) & ((uint32_t)(regval) << 12)) /*!< write value to ADC_CTL1_ETSIC bit field */
+#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< timer 0 TRGO event select */
+#define ADC0_1_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< timer 0 CC3 event select */
+#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(2) /*!< timer 1 TRGO event select */
+#define ADC0_1_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< timer 1 CC0 event select */
+#define ADC0_1_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< timer 2 CC3 event select */
+#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(5) /*!< timer 3 TRGO event select */
+#define ADC0_1_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */
+#define ADC0_1_EXTTRIG_INSERTED_T7_CH3 CTL1_ETSIC(6) /*!< timer 7 CC3 event select */
+#define ADC0_1_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger */
+
+/* adc_samptx register value */
+#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */
+#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */
+#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */
+#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */
+#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */
+#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */
+#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */
+#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */
+#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */
+
+/* adc_ioffx register value */
+#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */
+
+/* adc_wdht register value */
+#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */
+
+/* adc_wdlt register value */
+#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */
+
+/* adc_rsqx register value */
+#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */
+
+/* adc_isq register value */
+#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */
+
+/* adc_ovsampctl register value */
+/* ADC resolution */
+#define OVSAMPCTL_DRES(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) /*!< write value to ADC_OVSAMPCTL_DRES bit field */
+#define ADC_RESOLUTION_12B OVSAMPCTL_DRES(0) /*!< 12-bit ADC resolution */
+#define ADC_RESOLUTION_10B OVSAMPCTL_DRES(1) /*!< 10-bit ADC resolution */
+#define ADC_RESOLUTION_8B OVSAMPCTL_DRES(2) /*!< 8-bit ADC resolution */
+#define ADC_RESOLUTION_6B OVSAMPCTL_DRES(3) /*!< 6-bit ADC resolution */
+
+/* oversampling shift */
+#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */
+#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */
+
+/* oversampling ratio */
+#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */
+#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */
+#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */
+#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */
+#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */
+#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */
+#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */
+#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */
+#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */
+
+/* triggered Oversampling */
+#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */
+#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */
+
+/* ADC channel group definitions */
+#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */
+#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted channel group */
+#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */
+
+#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */
+
+/* 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 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 */
+
+/* ADC interrupt */
+#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 */
+
+/* ADC interrupt flag */
+#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt flag */
+#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */
+#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */
+
+/* function declarations */
+/* initialization config */
+/* reset ADC */
+void adc_deinit(uint32_t adc_periph);
+/* configure the ADC sync mode */
+void adc_mode_config(uint32_t mode);
+/* enable or disable ADC special function */
+void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue);
+/* configure ADC data alignment */
+void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment);
+/* enable ADC interface */
+void adc_enable(uint32_t adc_periph);
+/* disable ADC interface */
+void adc_disable(uint32_t adc_periph);
+/* ADC calibration and reset calibration */
+void adc_calibration_enable(uint32_t adc_periph);
+/* enable the temperature sensor and Vrefint channel */
+void adc_tempsensor_vrefint_enable(void);
+/* disable the temperature sensor and Vrefint channel */
+void adc_tempsensor_vrefint_disable(void);
+/* configure ADC resolution */
+void adc_resolution_config(uint32_t adc_periph, uint32_t resolution);
+/* configure ADC oversample mode */
+void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_t ratio);
+/* enable ADC oversample mode */
+void adc_oversample_mode_enable(uint32_t adc_periph);
+/* disable ADC oversample mode */
+void adc_oversample_mode_disable(uint32_t adc_periph);
+
+/* DMA config */
+/* enable DMA request */
+void adc_dma_mode_enable(uint32_t adc_periph);
+/* disable DMA request */
+void adc_dma_mode_disable(uint32_t adc_periph);
+
+/* regular group and inserted group config */
+/* configure ADC discontinuous mode */
+void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length);
+/* configure 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);
+/* configure ADC regular channel */
+void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time);
+/* configure ADC inserted channel */
+void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time);
+/* configure ADC inserted channel offset */
+void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset);
+/* configure ADC external trigger source */
+void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source);
+/* enable ADC external trigger */
+void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue);
+/* enable ADC software trigger */
+void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group);
+
+/* get channel data */
+/* read ADC regular group data register */
+uint16_t adc_regular_data_read(uint32_t adc_periph);
+/* read ADC inserted group data register */
+uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel);
+/* read the last ADC0 and ADC1 conversion result data in sync mode */
+uint32_t adc_sync_mode_convert_value_read(void);
+
+/* watchdog config */
+/* configure ADC analog watchdog single channel */
+void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel);
+/* configure ADC analog watchdog group channel */
+void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group);
+/* disable ADC analog watchdog */
+void adc_watchdog_disable(uint32_t adc_periph);
+/* configure ADC analog watchdog threshold */
+void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold);
+
+/* interrupt & flag functions */
+/* 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 bit state of ADCx software start conversion */
+FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph);
+/* get the bit state of ADCx software inserted channel start conversion */
+FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph);
+/* 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);
+/* enable ADC interrupt */
+void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt);
+/* disable ADC interrupt */
+void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt);
+
+#endif /* GD32E10X_ADC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_bkp.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_bkp.h
new file mode 100644
index 0000000000..2cc4cce39c
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_bkp.h
@@ -0,0 +1,244 @@
+/*!
+ \file gd32e10x_bkp.h
+ \brief definitions for the BKP
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_BKP_H
+#define GD32E10X_BKP_H
+
+#include "gd32e10x.h"
+
+/* BKP definitions */
+#define BKP BKP_BASE /*!< BKP base address */
+
+/* registers definitions */
+#define BKP_DATA0 REG16((BKP) + 0x04U) /*!< BKP data register 0 */
+#define BKP_DATA1 REG16((BKP) + 0x08U) /*!< BKP data register 1 */
+#define BKP_DATA2 REG16((BKP) + 0x0CU) /*!< BKP data register 2 */
+#define BKP_DATA3 REG16((BKP) + 0x10U) /*!< BKP data register 3 */
+#define BKP_DATA4 REG16((BKP) + 0x14U) /*!< BKP data register 4 */
+#define BKP_DATA5 REG16((BKP) + 0x18U) /*!< BKP data register 5 */
+#define BKP_DATA6 REG16((BKP) + 0x1CU) /*!< BKP data register 6 */
+#define BKP_DATA7 REG16((BKP) + 0x20U) /*!< BKP data register 7 */
+#define BKP_DATA8 REG16((BKP) + 0x24U) /*!< BKP data register 8 */
+#define BKP_DATA9 REG16((BKP) + 0x28U) /*!< BKP data register 9 */
+#define BKP_DATA10 REG16((BKP) + 0x40U) /*!< BKP data register 10 */
+#define BKP_DATA11 REG16((BKP) + 0x44U) /*!< BKP data register 11 */
+#define BKP_DATA12 REG16((BKP) + 0x48U) /*!< BKP data register 12 */
+#define BKP_DATA13 REG16((BKP) + 0x4CU) /*!< BKP data register 13 */
+#define BKP_DATA14 REG16((BKP) + 0x50U) /*!< BKP data register 14 */
+#define BKP_DATA15 REG16((BKP) + 0x54U) /*!< BKP data register 15 */
+#define BKP_DATA16 REG16((BKP) + 0x58U) /*!< BKP data register 16 */
+#define BKP_DATA17 REG16((BKP) + 0x5CU) /*!< BKP data register 17 */
+#define BKP_DATA18 REG16((BKP) + 0x60U) /*!< BKP data register 18 */
+#define BKP_DATA19 REG16((BKP) + 0x64U) /*!< BKP data register 19 */
+#define BKP_DATA20 REG16((BKP) + 0x68U) /*!< BKP data register 20 */
+#define BKP_DATA21 REG16((BKP) + 0x6CU) /*!< BKP data register 21 */
+#define BKP_DATA22 REG16((BKP) + 0x70U) /*!< BKP data register 22 */
+#define BKP_DATA23 REG16((BKP) + 0x74U) /*!< BKP data register 23 */
+#define BKP_DATA24 REG16((BKP) + 0x78U) /*!< BKP data register 24 */
+#define BKP_DATA25 REG16((BKP) + 0x7CU) /*!< BKP data register 25 */
+#define BKP_DATA26 REG16((BKP) + 0x80U) /*!< BKP data register 26 */
+#define BKP_DATA27 REG16((BKP) + 0x84U) /*!< BKP data register 27 */
+#define BKP_DATA28 REG16((BKP) + 0x88U) /*!< BKP data register 28 */
+#define BKP_DATA29 REG16((BKP) + 0x8CU) /*!< BKP data register 29 */
+#define BKP_DATA30 REG16((BKP) + 0x90U) /*!< BKP data register 30 */
+#define BKP_DATA31 REG16((BKP) + 0x94U) /*!< BKP data register 31 */
+#define BKP_DATA32 REG16((BKP) + 0x98U) /*!< BKP data register 32 */
+#define BKP_DATA33 REG16((BKP) + 0x9CU) /*!< BKP data register 33 */
+#define BKP_DATA34 REG16((BKP) + 0xA0U) /*!< BKP data register 34 */
+#define BKP_DATA35 REG16((BKP) + 0xA4U) /*!< BKP data register 35 */
+#define BKP_DATA36 REG16((BKP) + 0xA8U) /*!< BKP data register 36 */
+#define BKP_DATA37 REG16((BKP) + 0xACU) /*!< BKP data register 37 */
+#define BKP_DATA38 REG16((BKP) + 0xB0U) /*!< BKP data register 38 */
+#define BKP_DATA39 REG16((BKP) + 0xB4U) /*!< BKP data register 39 */
+#define BKP_DATA40 REG16((BKP) + 0xB8U) /*!< BKP data register 40 */
+#define BKP_DATA41 REG16((BKP) + 0xBCU) /*!< BKP data register 41 */
+#define BKP_OCTL REG16((BKP) + 0x2CU) /*!< RTC signal output control register */
+#define BKP_TPCTL REG16((BKP) + 0x30U) /*!< tamper pin control register */
+#define BKP_TPCS REG16((BKP) + 0x34U) /*!< tamper control and status register */
+
+/* bits definitions */
+/* BKP_DATA */
+#define BKP_DATA BITS(0,15) /*!< backup data */
+
+/* BKP_OCTL */
+#define BKP_OCTL_RCCV BITS(0,6) /*!< RTC clock calibration value */
+#define BKP_OCTL_COEN BIT(7) /*!< RTC clock calibration output enable */
+#define BKP_OCTL_ASOEN BIT(8) /*!< RTC alarm or second signal output enable */
+#define BKP_OCTL_ROSEL BIT(9) /*!< RTC output selection */
+#define BKP_OCTL_CCOSEL BIT(14) /*!< RTC clock output selection */
+#define BKP_OCTL_CALDIR BIT(15) /*!< RTC clock calibration direction */
+
+/* BKP_TPCTL */
+#define BKP_TPCTL_TPEN BIT(0) /*!< tamper detection enable */
+#define BKP_TPCTL_TPAL BIT(1) /*!< tamper pin active level */
+
+/* BKP_TPCS */
+#define BKP_TPCS_TER BIT(0) /*!< tamper event reset */
+#define BKP_TPCS_TIR BIT(1) /*!< tamper interrupt reset */
+#define BKP_TPCS_TPIE BIT(2) /*!< tamper interrupt enable */
+#define BKP_TPCS_TEF BIT(8) /*!< tamper event flag */
+#define BKP_TPCS_TIF BIT(9) /*!< tamper interrupt flag */
+
+/* constants definitions */
+/* BKP data register number */
+typedef enum {
+ BKP_DATA_0 = 1, /*!< BKP data register 0 */
+ BKP_DATA_1, /*!< BKP data register 1 */
+ BKP_DATA_2, /*!< BKP data register 2 */
+ BKP_DATA_3, /*!< BKP data register 3 */
+ BKP_DATA_4, /*!< BKP data register 4 */
+ BKP_DATA_5, /*!< BKP data register 5 */
+ BKP_DATA_6, /*!< BKP data register 6 */
+ BKP_DATA_7, /*!< BKP data register 7 */
+ BKP_DATA_8, /*!< BKP data register 8 */
+ BKP_DATA_9, /*!< BKP data register 9 */
+ BKP_DATA_10, /*!< BKP data register 10 */
+ BKP_DATA_11, /*!< BKP data register 11 */
+ BKP_DATA_12, /*!< BKP data register 12 */
+ BKP_DATA_13, /*!< BKP data register 13 */
+ BKP_DATA_14, /*!< BKP data register 14 */
+ BKP_DATA_15, /*!< BKP data register 15 */
+ BKP_DATA_16, /*!< BKP data register 16 */
+ BKP_DATA_17, /*!< BKP data register 17 */
+ BKP_DATA_18, /*!< BKP data register 18 */
+ BKP_DATA_19, /*!< BKP data register 19 */
+ BKP_DATA_20, /*!< BKP data register 20 */
+ BKP_DATA_21, /*!< BKP data register 21 */
+ BKP_DATA_22, /*!< BKP data register 22 */
+ BKP_DATA_23, /*!< BKP data register 23 */
+ BKP_DATA_24, /*!< BKP data register 24 */
+ BKP_DATA_25, /*!< BKP data register 25 */
+ BKP_DATA_26, /*!< BKP data register 26 */
+ BKP_DATA_27, /*!< BKP data register 27 */
+ BKP_DATA_28, /*!< BKP data register 28 */
+ BKP_DATA_29, /*!< BKP data register 29 */
+ BKP_DATA_30, /*!< BKP data register 30 */
+ BKP_DATA_31, /*!< BKP data register 31 */
+ BKP_DATA_32, /*!< BKP data register 32 */
+ BKP_DATA_33, /*!< BKP data register 33 */
+ BKP_DATA_34, /*!< BKP data register 34 */
+ BKP_DATA_35, /*!< BKP data register 35 */
+ BKP_DATA_36, /*!< BKP data register 36 */
+ BKP_DATA_37, /*!< BKP data register 37 */
+ BKP_DATA_38, /*!< BKP data register 38 */
+ BKP_DATA_39, /*!< BKP data register 39 */
+ BKP_DATA_40, /*!< BKP data register 40 */
+ BKP_DATA_41, /*!< BKP data register 41 */
+} bkp_data_register_enum;
+
+/* BKP data register */
+#define BKP_DATA0_9(number) REG16((BKP) + 0x04U + (number) * 0x04U)
+#define BKP_DATA10_41(number) REG16((BKP) + 0x40U + ((number)-10U) * 0x04U)
+
+/* get data of BKP data register */
+#define BKP_DATA_GET(regval) GET_BITS((uint32_t)(regval), 0, 15)
+
+/* RTC clock calibration value */
+#define OCTL_RCCV(regval) (BITS(0,6) & ((uint32_t)(regval) << 0))
+
+/* RTC output selection */
+#define RTC_OUTPUT_ALARM_PULSE ((uint16_t)0x0000U) /*!< RTC alarm pulse is selected as the RTC output */
+#define RTC_OUTPUT_SECOND_PULSE ((uint16_t)BKP_OCTL_ROSEL) /*!< RTC second pulse is selected as the RTC output */
+
+/* RTC clock output selection */
+#define RTC_CLOCK_DIV_64 ((uint16_t)0x0000U) /*!< RTC clock div 64 */
+#define RTC_CLOCK_DIV_1 ((uint16_t)BKP_OCTL_CCOSEL) /*!< RTC clock div 1 */
+
+/* RTC clock calibration direction */
+#define RTC_CLOCK_SLOWED_DOWN ((uint16_t)0x0000U) /*!< RTC clock slow down */
+#define RTC_CLOCK_SPEED_UP ((uint16_t)BKP_OCTL_CALDIR) /*!< RTC clock speed up */
+
+/* tamper pin active level */
+#define TAMPER_PIN_ACTIVE_HIGH ((uint16_t)0x0000U) /*!< the tamper pin is active high */
+#define TAMPER_PIN_ACTIVE_LOW ((uint16_t)BKP_TPCTL_TPAL) /*!< the tamper pin is active low */
+
+/* tamper flag */
+#define BKP_FLAG_TAMPER BKP_TPCS_TEF /*!< tamper event flag */
+
+/* tamper interrupt flag */
+#define BKP_INT_FLAG_TAMPER BKP_TPCS_TIF /*!< tamper interrupt flag */
+
+/* function declarations */
+/* operation functions */
+/* reset BKP registers */
+void bkp_deinit(void);
+/* write BKP data register */
+void bkp_data_write(bkp_data_register_enum register_number, uint16_t data);
+/* read BKP data register */
+uint16_t bkp_data_read(bkp_data_register_enum register_number);
+
+/* RTC related functions */
+/* enable RTC clock calibration output */
+void bkp_rtc_calibration_output_enable(void);
+/* disable RTC clock calibration output */
+void bkp_rtc_calibration_output_disable(void);
+/* enable RTC alarm or second signal output */
+void bkp_rtc_signal_output_enable(void);
+/* disable RTC alarm or second signal output */
+void bkp_rtc_signal_output_disable(void);
+/* select RTC output */
+void bkp_rtc_output_select(uint16_t outputsel);
+/* select RTC clock output */
+void bkp_rtc_clock_output_select(uint16_t clocksel);
+/* select RTC clock calibration direction */
+void bkp_rtc_clock_calibration_direction_select(uint16_t direction);
+/* set RTC clock calibration value */
+void bkp_rtc_calibration_value_set(uint8_t value);
+
+/* tamper pin related functions */
+/* enable tamper pin detection */
+void bkp_tamper_detection_enable(void);
+/* disable tamper pin detection */
+void bkp_tamper_detection_disable(void);
+/* set tamper pin active level */
+void bkp_tamper_active_level_set(uint16_t level);
+
+/* interrupt & flag functions */
+/* enable tamper interrupt */
+void bkp_interrupt_enable(void);
+/* disable tamper interrupt */
+void bkp_interrupt_disable(void);
+/* get tamper flag state */
+FlagStatus bkp_flag_get(void);
+/* clear tamper flag state */
+void bkp_flag_clear(void);
+/* get tamper interrupt flag state */
+FlagStatus bkp_interrupt_flag_get(void);
+/* clear tamper interrupt flag state */
+void bkp_interrupt_flag_clear(void);
+
+#endif /* GD32E10X_BKP_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_can.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_can.h
new file mode 100644
index 0000000000..9b0c0125a6
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_can.h
@@ -0,0 +1,831 @@
+/*!
+ \file gd32e10x_can.h
+ \brief definitions for the CAN
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_CAN_H
+#define GD32E10X_CAN_H
+
+#include "gd32e10x.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_FDCTL(canx) REG32((canx) + 0x20U) /*!< CAN FD control register */
+#define CAN_FDSTAT(canx) REG32((canx) + 0x24U) /*!< CAN FD status register */
+#define CAN_FDTDC(canx) REG32((canx) + 0x28U) /*!< CAN FD transmitter delay compensation register */
+#define CAN_DBT(canx) REG32((canx) + 0x2CU) /*!< CAN date 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) + 0x1BCU) /*!< 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_WIE 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_6_4 BITS(10,12) /*!< bit segment 1 [6:4] */
+#define CAN_BT_BS2_4_3 BITS(13,14) /*!< bit segment 2 [4:3] */
+#define CAN_BT_BS1_3_0 BITS(16,19) /*!< bit segment 1 [3:0] */
+#define CAN_BT_BS2_2_0 BITS(20,22) /*!< bit segment 2 [2:0]*/
+#define CAN_BT_SJW BITS(24,28) /*!< resynchronization jump width */
+#define CAN_BT_LCMOD BIT(30) /*!< loopback communication mode */
+#define CAN_BT_SCMOD BIT(31) /*!< silent communication mode */
+
+/* CAN_FDCTL */
+#define CAN_FDCTL_FDEN BIT(0) /*!< FD operation enable */
+#define CAN_FDCTL_PRED BIT(2) /*!< protocol exception event detection disable */
+#define CAN_FDCTL_NISO BIT(3) /*!< ISO/Bosch */
+#define CAN_FDCTL_TDCEN BIT(4) /*!< transmitter delay compensation enable */
+#define CAN_FDCTL_TDCMOD BIT(5) /*!< transmitter delay compensation mode */
+#define CAN_FDCTL_ESIMOD BIT(6) /*!< error state indicator mode */
+
+/* CAN_FDSTAT */
+#define CAN_FDSTAT_TDCV BITS(0,6) /*!< transmitter delay compensation value */
+#define CAN_FDSTAT_PRE BIT(16) /*!< protocol exception event */
+
+/* CAN_FDTDC */
+#define CAN_FDTDC_TDCF BITS(0,6) /*!< transmitter delay compensation filter */
+#define CAN_FDTDC_TDCO BITS(8,14) /*!< transmitter delay compensation offset */
+
+/* CAN_DBT */
+#define CAN_DBT_DBAUDPSC BITS(0,9) /*!< baud rate prescaler */
+#define CAN_DBT_DBS1 BITS(16,19) /*!< bit segment 1 */
+#define CAN_DBT_DBS2 BITS(20,22) /*!< bit segment 2 */
+#define CAN_DBT_DSJW BITS(24,26) /*!< resynchronization jump width */
+
+/* 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_ESI BIT(4) /*!< error status indicator */
+#define CAN_TMP_BRS BIT(5) /*!< bit rate of data switch */
+#define CAN_TMP_FDF BIT(7) /*!< CAN FD frame flag */
+#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_ESI BIT(4) /*!< error status indicator */
+#define CAN_RFIFOMP_BRS BIT(5) /*!< bit rate of data switch */
+#define CAN_RFIFOMP_FDF BIT(7) /*!< CAN FD frame flag */
+#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 */
+
+/* CAN_FxDATAy */
+#define CAN_FDATA_FD(regval) BIT(regval) /*!< filter data */
+
+/* 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)
+
+#define CAN_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1))
+#define CAN_REG_VALS(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 12)))
+#define CAN_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU)
+#define CAN_BIT_POS1(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_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */
+ CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */
+ CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */
+ /* interrupt flags in TSTAT register */
+ CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */
+ CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */
+ CAN_INT_FLAG_MTF0 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 0U, 0U), /*!< mailbox 0 transmit finished interrupt flag */
+ /* interrupt flags in RFIFO0 register */
+ CAN_INT_FLAG_RFO0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 4U, 3U), /*!< receive FIFO0 overfull interrupt flag */
+ CAN_INT_FLAG_RFF0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 3U, 2U), /*!< receive FIFO0 full interrupt flag */
+ /* interrupt flags in RFIFO0 register */
+ CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */
+ CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */
+} can_interrupt_flag_enum;
+
+/* CAN FD transmitter delay compensation parameters struct */
+typedef struct {
+ uint32_t tdc_mode; /*!< transmitter delay compensation mode */
+ uint8_t tdc_filter; /*!< transmitter delay compensation filter */
+ uint8_t tdc_offset; /*!< transmitter delay compensation offset */
+} can_fd_tdc_struct;
+
+/* CAN initiliaze FD frame parameters struct */
+typedef struct {
+ ControlStatus fd_frame; /*!< FD operation function */
+ ControlStatus excp_event_detect; /*!< protocol exception event detection function*/
+ ControlStatus delay_compensation; /*!< transmitter delay compensation mode */
+ can_fd_tdc_struct *p_delay_compensation; /*!< pointer to the struct of the transmitter delay compensation */
+ uint32_t iso_bosch; /*!< ISO/Bosch mode choice */
+ uint32_t esi_mode; /*!< error state indicator mode */
+ uint8_t data_resync_jump_width; /*!< CAN resynchronization jump width */
+ uint8_t data_time_segment_1; /*!< time segment 1 */
+ uint8_t data_time_segment_2; /*!< time segment 2 */
+ uint16_t data_prescaler; /*!< baudrate prescaler */
+} can_fdframe_struct;
+
+/* 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[64]; /*!< transmit data */
+ uint8_t fd_flag; /*!< CAN FD frame flag */
+ uint8_t fd_brs; /*!< bit rate of data switch */
+ uint8_t fd_esi; /*!< error status indicator */
+} 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[64]; /*!< receive data */
+ uint8_t rx_fi; /*!< filtering index */
+ uint8_t fd_flag; /*!< CAN FD frame flag */
+ uint8_t fd_brs; /*!< bit rate of data switch */
+ uint8_t fd_esi; /*!< error status indicator */
+} 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;
+
+/* format and fifo states */
+typedef enum {
+ CAN_STANDARD_FIFO0 = 0, /*!< standard frame and used FIFO0 */
+ CAN_STANDARD_FIFO1, /*!< standard frame and used FIFO1 */
+ CAN_EXTENDED_FIFO0, /*!< extended frame and used FIFO0 */
+ CAN_EXTENDED_FIFO1, /*!< extended frame and used FIFO1 */
+} can_format_fifo_enum;
+
+typedef enum {
+ CAN_INIT_STRUCT = 0, /* CAN initiliaze parameters struct */
+ CAN_FILTER_STRUCT, /* CAN filter parameters struct */
+ CAN_FD_FRAME_STRUCT, /* CAN initiliaze FD frame parameters struct */
+ CAN_TX_MESSAGE_STRUCT, /* CAN transmit message struct */
+ CAN_RX_MESSAGE_STRUCT, /* CAN receive message struct */
+} can_struct_type_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)) | (BITS(10,12) & ((uint32_t)(regval) << 6)))
+#define BT_DBS1(regval) ((BITS(16,19) & ((uint32_t)(regval) << 16)))
+
+/* CAN bit segment 2*/
+#define BT_BS2(regval) ((BITS(20,22) & ((uint32_t)(regval) << 20)) | (BITS(13,14) & ((uint32_t)(regval) << 10)))
+#define BT_DBS2(regval) ((BITS(20,22)) & ((uint32_t)(regval) << 20))
+
+/* CAN resynchronization jump width*/
+#define BT_SJW(regval) (BITS(24,28) & ((uint32_t)(regval) << 24))
+#define BT_DSJW(regval) (BITS(24,26) & ((uint32_t)(regval) << 24))
+
+#define FDTDC_TDCF(regval) (BITS(0,6) & ((uint32_t)(regval) << 0))
+#define FDTDC_TDCO(regval) (BITS(8,14) & ((uint32_t)(regval) << 8))
+
+/* 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 GET_RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3, 31)
+
+/* receive mailbox standrad identifier*/
+#define GET_RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21, 31)
+
+/* receive data length */
+#define GET_RFIFOMP_DLENC(regval) GET_BITS((uint32_t)(regval), 0, 3)
+
+/* the index of the filter by which the frame is passed */
+#define GET_RFIFOMP_FI(regval) GET_BITS((uint32_t)(regval), 8, 15)
+
+/* receive data byte 0 */
+#define GET_RFIFOMDATA0_DB0(regval) GET_BITS((uint32_t)(regval), 0, 7)
+
+/* receive data byte 1 */
+#define GET_RFIFOMDATA0_DB1(regval) GET_BITS((uint32_t)(regval), 8, 15)
+
+/* receive data byte 2 */
+#define GET_RFIFOMDATA0_DB2(regval) GET_BITS((uint32_t)(regval), 16, 23)
+
+/* receive data byte 3 */
+#define GET_RFIFOMDATA0_DB3(regval) GET_BITS((uint32_t)(regval), 24, 31)
+
+/* receive data byte 4 */
+#define GET_RFIFOMDATA1_DB4(regval) GET_BITS((uint32_t)(regval), 0, 7)
+
+/* receive data byte 5 */
+#define GET_RFIFOMDATA1_DB5(regval) GET_BITS((uint32_t)(regval), 8, 15)
+
+/* receive data byte 6 */
+#define GET_RFIFOMDATA1_DB6(regval) GET_BITS((uint32_t)(regval), 16, 23)
+
+/* receive data byte 7 */
+#define GET_RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24, 31)
+
+/* error number */
+#define GET_ERR_ERRN(regval) GET_BITS((uint32_t)(regval), 4, 6)
+
+/* transmit error count */
+#define GET_ERR_TECNT(regval) GET_BITS((uint32_t)(regval), 16, 23)
+
+/* receive error count */
+#define GET_ERR_RECNT(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_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */
+
+#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) /*!< can filter 16 bits mask */
+
+/* frame type */
+#define CAN_FT_DATA ((uint32_t)0x00000000U) /*!< data frame */
+#define CAN_FT_REMOTE ((uint32_t)0x00000002U) /*!< remote frame */
+
+#define CAN_ESIMOD_HARDWARE ((uint32_t)0x00000000U) /*!< displays the node error state by hardware */
+#define CAN_ESIMOD_SOFTWARE CAN_FDCTL_ESIMOD /*!< displays the node error state by software */
+
+#define CAN_TDCMOD_CALC_AND_OFFSET ((uint32_t)0x00000000U) /*!< measurement and offset */
+#define CAN_TDCMOD_OFFSET CAN_FDCTL_TDCMOD /*!< only offset */
+
+#define CAN_FDMOD_ISO ((uint32_t)0x00000000U) /*!< ISO mode */
+#define CAN_FDMOD_BOSCH CAN_FDCTL_NISO /*!< BOSCH mode */
+
+
+/* CAN FD frame flag */
+#define CAN_FDF_CLASSIC (0U) /*!< classical frames */
+#define CAN_FDF_FDFRAME (1U) /*!< FD frames */
+
+/* bit rate of data switch */
+#define CAN_BRS_DISABLE (0U) /*!< bit rate not switch */
+#define CAN_BRS_ENABLE (1U) /*!< the bit rate shall be switched */
+
+/* error status indicator */
+#define CAN_ESI_DOMINANT (0U) /*!< transmit the dominant bit in ESI phase */
+#define CAN_ESI_RECESSIVE (1U) /*!< transmit the recessive bit in ESI phase */
+
+/* CAN timeout */
+#define CAN_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< timeout value */
+
+/* interrupt enable bits */
+#define CAN_INT_TME CAN_INTEN_TMEIE /*!< transmit mailbox empty interrupt enable */
+#define CAN_INT_RFNE0 CAN_INTEN_RFNEIE0 /*!< receive FIFO0 not empty interrupt enable */
+#define CAN_INT_RFF0 CAN_INTEN_RFFIE0 /*!< receive FIFO0 full interrupt enable */
+#define CAN_INT_RFO0 CAN_INTEN_RFOIE0 /*!< receive FIFO0 overfull interrupt enable */
+#define CAN_INT_RFNE1 CAN_INTEN_RFNEIE1 /*!< receive FIFO1 not empty interrupt enable */
+#define CAN_INT_RFF1 CAN_INTEN_RFFIE1 /*!< receive FIFO1 full interrupt enable */
+#define CAN_INT_RFO1 CAN_INTEN_RFOIE1 /*!< receive FIFO1 overfull interrupt enable */
+#define CAN_INT_WERR CAN_INTEN_WERRIE /*!< warning error interrupt enable */
+#define CAN_INT_PERR CAN_INTEN_PERRIE /*!< passive error interrupt enable */
+#define CAN_INT_BO CAN_INTEN_BOIE /*!< bus-off interrupt enable */
+#define CAN_INT_ERRN CAN_INTEN_ERRNIE /*!< error number interrupt enable */
+#define CAN_INT_ERR CAN_INTEN_ERRIE /*!< error interrupt enable */
+#define CAN_INT_WAKEUP CAN_INTEN_WIE /*!< wakeup interrupt enable */
+#define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */
+
+/* function declarations */
+/* deinitialize CAN */
+void can_deinit(uint32_t can_periph);
+/* initialize CAN struct */
+void can_struct_para_init(can_struct_type_enum type, void *p_struct);
+/* initialize CAN */
+#ifdef GD_MBED_USED
+ErrStatus can_para_init(uint32_t can_periph, can_parameter_struct *can_parameter_init);
+#else
+ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init);
+#endif
+/* initialize CAN FD function */
+ErrStatus can_fd_init(uint32_t can_periph, can_fdframe_struct *can_fdframe_init);
+/* CAN filter init */
+void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init);
+/* CAN filter mask mode initialization */
+void can_filter_mask_mode_init(uint32_t id, uint32_t mask, can_format_fifo_enum format_fifo, uint16_t filter_number);
+/* CAN frequency configuration */
+ErrStatus can_frequency_set(uint32_t can_periph, uint32_t hz);
+/* CAN FD frequency configuration */
+ErrStatus can_fd_frequency_set(uint32_t can_periph, uint32_t hz);
+/* CAN communication mode configure */
+ErrStatus can_monitor_mode_set(uint32_t can_periph, uint8_t mode);
+/* CAN FD frame function enable */
+void can_fd_function_enable(uint32_t can_periph);
+/* CAN FD frame function disable */
+void can_fd_function_disable(uint32_t can_periph);
+
+/* 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 trigger mode enable */
+void can_time_trigger_mode_enable(uint32_t can_periph);
+/* CAN time trigger mode disable */
+void can_time_trigger_mode_disable(uint32_t can_periph);
+
+/* transmit CAN message */
+uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message);
+/* get CAN transmit state */
+can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number);
+/* stop CAN transmission */
+void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number);
+/* 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_get(uint32_t can_periph, uint8_t fifo_number);
+/* 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);
+
+/* CAN get error */
+can_error_enum can_error_get(uint32_t can_periph);
+/* get CAN receive error number */
+uint8_t can_receive_error_number_get(uint32_t can_periph);
+/* get CAN transmit error number */
+uint8_t can_transmit_error_number_get(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);
+/* 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 /* GD32E10X_CAN_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_crc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_crc.h
new file mode 100644
index 0000000000..6628855bd6
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_crc.h
@@ -0,0 +1,81 @@
+/*!
+ \file gd32e10x_crc.h
+ \brief definitions for the CRC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_CRC_H
+#define GD32E10X_CRC_H
+
+#include "gd32e10x.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(CRC_DATA) to the value of 0xFFFFFFFF */
+void crc_data_register_reset(void);
+/* read the value of the data register */
+uint32_t crc_data_register_read(void);
+
+/* read the value of the free data register */
+uint8_t crc_free_data_register_read(void);
+/* write data to the free data register */
+void crc_free_data_register_write(uint8_t free_data);
+
+/* calculate the CRC value of a 32-bit data */
+uint32_t crc_single_data_calculate(uint32_t sdata);
+/* calculate the CRC value of an array of 32-bit values */
+uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size);
+
+#endif /* GD32E10X_CRC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_ctc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_ctc.h
new file mode 100644
index 0000000000..f40c9cab90
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_ctc.h
@@ -0,0 +1,186 @@
+/*!
+ \file gd32e10x_ctc.h
+ \brief definitions for the CTC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_CTC_H
+#define GD32E10X_CTC_H
+
+#include "gd32e10x.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_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*/
+
+/* 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 selected */
+#define CTC_REFSOURCE_USBSOF CTL1_REFSEL(2) /*!< USBFS_SOF 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_CKOK CTC_CTL0_CKOKIE /*!< clock trim OK interrupt enable */
+#define CTC_INT_CKWARN CTC_CTL0_CKWARNIE /*!< clock trim warning interrupt enable */
+#define CTC_INT_ERR CTC_CTL0_ERRIE /*!< error interrupt enable */
+#define CTC_INT_EREF CTC_CTL0_EREFIE /*!< expect reference interrupt enable */
+
+/* CTC interrupt source definitions */
+#define CTC_INT_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK interrupt flag */
+#define CTC_INT_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning interrupt flag */
+#define CTC_INT_FLAG_ERR CTC_STAT_ERRIF /*!< error interrupt flag */
+#define CTC_INT_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference interrupt flag */
+#define CTC_INT_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */
+#define CTC_INT_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */
+#define CTC_INT_FLAG_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 CTC trim counter */
+void ctc_counter_enable(void);
+/* disable CTC trim counter */
+void ctc_counter_disable(void);
+
+/* configure the IRC48M trim value */
+void ctc_irc48m_trim_value_config(uint8_t 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 hardmode);
+
+/* configure reference signal source polarity */
+void ctc_refsource_polarity_config(uint32_t polarity);
+/* select reference signal source */
+void ctc_refsource_signal_select(uint32_t refs);
+/* configure reference signal source prescaler */
+void ctc_refsource_prescaler_config(uint32_t prescaler);
+/* configure clock trim base limit value */
+void ctc_clock_limit_value_config(uint8_t limit_value);
+/* configure CTC counter reload value */
+void ctc_counter_reload_value_config(uint16_t 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);
+
+/* interrupt & flag functions */
+/* enable the CTC interrupt */
+void ctc_interrupt_enable(uint32_t interrupt);
+/* disable the CTC interrupt */
+void ctc_interrupt_disable(uint32_t interrupt);
+/* get CTC interrupt flag */
+FlagStatus ctc_interrupt_flag_get(uint32_t interrupt);
+/* clear CTC interrupt flag */
+void ctc_interrupt_flag_clear(uint32_t interrupt);
+/* get CTC flag */
+FlagStatus ctc_flag_get(uint32_t flag);
+/* clear CTC flag */
+void ctc_flag_clear(uint32_t flag);
+
+#endif /* GD32E10X_CTC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dac.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dac.h
new file mode 100644
index 0000000000..982a1aab36
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dac.h
@@ -0,0 +1,246 @@
+/*!
+ \file gd32e10x_dac.h
+ \brief definitions for the DAC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_DAC_H
+#define GD32E10X_DAC_H
+
+#include "gd32e10x.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 */
+
+/* bits definitions */
+/* DAC_CTL */
+#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/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/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(8,15) /*!< 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 */
+
+/* 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_T2_TRGO CTL_DTSEL(1) /*!< TIMER2 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] */
+
+/* DAC data alignment */
+#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12 bit alignment */
+#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12 bit alignment */
+#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8 bit alignment */
+
+/* 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 */
+
+/* function declarations */
+/* initialization functions */
+/* 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);
+/* 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);
+
+/* DAC trigger configuration */
+/* enable DAC trigger */
+void dac_trigger_enable(uint32_t dac_periph);
+/* disable DAC trigger */
+void dac_trigger_disable(uint32_t dac_periph);
+/* configure DAC trigger source */
+void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource);
+/* 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);
+
+/* DAC wave mode configuration */
+/* 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);
+
+/* DAC concurrent mode configuration */
+/* 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);
+/* set DAC concurrent mode data holding register value */
+void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1);
+
+#endif /* GD32E10X_DAC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dbg.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dbg.h
new file mode 100644
index 0000000000..e6c8d97a58
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dbg.h
@@ -0,0 +1,138 @@
+/*!
+ \file gd32e10x_dbg.h
+ \brief definitions for the DBG
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_DBG_H
+#define GD32E10X_DBG_H
+
+#include "gd32e10x.h"
+
+/* DBG definitions */
+#define DBG DBG_BASE
+
+/* registers definitions */
+#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */
+#define DBG_CTL REG32(DBG + 0x04U) /*!< DBG control register */
+
+/* bits definitions */
+/* DBG_ID */
+#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */
+
+/* DBG_CTL */
+#define DBG_CTL_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */
+#define DBG_CTL_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */
+#define DBG_CTL_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */
+#define DBG_CTL_TRACE_IOEN BIT(5) /*!< enable trace pin assignment */
+#define DBG_CTL_TRACE_MODE BITS(6,7) /*!< trace pin mode selection */
+#define DBG_CTL_FWDGT_HOLD BIT(8) /*!< debug FWDGT kept when core is halted */
+#define DBG_CTL_WWDGT_HOLD BIT(9) /*!< debug WWDGT kept when core is halted */
+#define DBG_CTL_TIMER0_HOLD BIT(10) /*!< hold TIMER0 counter when core is halted */
+#define DBG_CTL_TIMER1_HOLD BIT(11) /*!< hold TIMER1 counter when core is halted */
+#define DBG_CTL_TIMER2_HOLD BIT(12) /*!< hold TIMER2 counter when core is halted */
+#define DBG_CTL_TIMER3_HOLD BIT(13) /*!< hold TIMER3 counter when core is halted */
+#define DBG_CTL_CAN0_HOLD BIT(14) /*!< debug CAN0 kept when core is halted */
+#define DBG_CTL_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */
+#define DBG_CTL_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */
+#define DBG_CTL_TIMER4_HOLD BIT(17) /*!< hold TIMER4 counter when core is halted */
+#define DBG_CTL_TIMER5_HOLD BIT(18) /*!< hold TIMER5 counter when core is halted */
+#define DBG_CTL_TIMER6_HOLD BIT(19) /*!< hold TIMER6 counter when core is halted */
+#define DBG_CTL_TIMER7_HOLD BIT(20) /*!< hold TIMER7 counter when core is halted */
+#define DBG_CTL_CAN1_HOLD BIT(21) /*!< debug CAN1 kept when core is halted */
+#define DBG_CTL_TIMER11_HOLD BIT(25) /*!< hold TIMER11 counter when core is halted */
+#define DBG_CTL_TIMER12_HOLD BIT(26) /*!< hold TIMER12 counter when core is halted */
+#define DBG_CTL_TIMER13_HOLD BIT(27) /*!< hold TIMER13 counter when core is halted */
+#define DBG_CTL_TIMER8_HOLD BIT(28) /*!< hold TIMER8 counter when core is halted */
+#define DBG_CTL_TIMER9_HOLD BIT(29) /*!< hold TIMER9 counter when core is halted */
+#define DBG_CTL_TIMER10_HOLD BIT(30) /*!< hold TIMER10 counter when core is halted */
+
+/* constants definitions */
+#define DBG_LOW_POWER_SLEEP DBG_CTL_SLP_HOLD /*!< keep debugger connection during sleep mode */
+#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */
+#define DBG_LOW_POWER_STANDBY DBG_CTL_STB_HOLD /*!< keep debugger connection during standby mode */
+
+/* debug hold when core is halted */
+typedef enum {
+ DBG_FWDGT_HOLD = BIT(8), /*!< debug FWDGT kept when core is halted */
+ DBG_WWDGT_HOLD = BIT(9), /*!< debug WWDGT kept when core is halted */
+ DBG_TIMER0_HOLD = BIT(10), /*!< hold TIMER0 counter when core is halted */
+ DBG_TIMER1_HOLD = BIT(11), /*!< hold TIMER1 counter when core is halted */
+ DBG_TIMER2_HOLD = BIT(12), /*!< hold TIMER2 counter when core is halted */
+ DBG_TIMER3_HOLD = BIT(13), /*!< hold TIMER3 counter when core is halted */
+ DBG_CAN0_HOLD = BIT(14), /*!< debug CAN0 kept when core is halted */
+ DBG_I2C0_HOLD = BIT(15), /*!< hold I2C0 smbus when core is halted */
+ DBG_I2C1_HOLD = BIT(16), /*!< hold I2C1 smbus when core is halted */
+ DBG_TIMER4_HOLD = BIT(17), /*!< hold TIMER4 counter when core is halted */
+ DBG_TIMER5_HOLD = BIT(18), /*!< hold TIMER5 counter when core is halted */
+ DBG_TIMER6_HOLD = BIT(19), /*!< hold TIMER6 counter when core is halted */
+ DBG_TIMER7_HOLD = BIT(20), /*!< hold TIMER7 counter when core is halted */
+ DBG_CAN1_HOLD = BIT(21), /*!< debug CAN1 kept when core is halted */
+ DBG_TIMER11_HOLD = BIT(25), /*!< hold TIMER11 counter when core is halted */
+ DBG_TIMER12_HOLD = BIT(26), /*!< hold TIMER12 counter when core is halted */
+ DBG_TIMER13_HOLD = BIT(27), /*!< hold TIMER13 counter when core is halted */
+ DBG_TIMER8_HOLD = BIT(28), /*!< hold TIMER8 counter when core is halted */
+ DBG_TIMER9_HOLD = BIT(29), /*!< hold TIMER9 counter when core is halted */
+ DBG_TIMER10_HOLD = BIT(30), /*!< hold TIMER10 counter when core is halted */
+} dbg_periph_enum;
+
+/* DBG_CTL0_TRACE_MODE configurations */
+#define CTL_TRACE_MODE(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U))
+#define TRACE_MODE_ASYNC CTL_TRACE_MODE(0) /*!< trace pin used for async mode */
+#define TRACE_MODE_SYNC_DATASIZE_1 CTL_TRACE_MODE(1) /*!< trace pin used for sync mode and data size is 1 */
+#define TRACE_MODE_SYNC_DATASIZE_2 CTL_TRACE_MODE(2) /*!< trace pin used for sync mode and data size is 2 */
+#define TRACE_MODE_SYNC_DATASIZE_4 CTL_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 /* GD32E10X_DBG_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dma.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dma.h
new file mode 100644
index 0000000000..aabc5f03b5
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_dma.h
@@ -0,0 +1,275 @@
+/*!
+ \file gd32e10x_dma.h
+ \brief definitions for the DMA
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_DMA_H
+#define GD32E10X_DMA_H
+
+#include "gd32e10x.h"
+
+/* DMA definitions */
+#define DMA0 (DMA_BASE) /*!< DMA0 base address */
+#define DMA1 (DMA_BASE + 0x0400U) /*!< DMA1 base address */
+
+/* registers definitions */
+#define DMA_INTF(dmax) REG32((dmax) + 0x00U) /*!< DMA interrupt flag register */
+#define DMA_INTC(dmax) REG32((dmax) + 0x04U) /*!< DMA interrupt flag clear register */
+#define DMA_CH0CTL(dmax) REG32((dmax) + 0x08U) /*!< DMA channel 0 control register */
+#define DMA_CH0CNT(dmax) REG32((dmax) + 0x0CU) /*!< DMA channel 0 counter register */
+#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x10U) /*!< DMA channel 0 peripheral base address register */
+#define DMA_CH0MADDR(dmax) REG32((dmax) + 0x14U) /*!< DMA channel 0 memory base address register */
+#define DMA_CH1CTL(dmax) REG32((dmax) + 0x1CU) /*!< DMA channel 1 control register */
+#define DMA_CH1CNT(dmax) REG32((dmax) + 0x20U) /*!< DMA channel 1 counter register */
+#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x24U) /*!< DMA channel 1 peripheral base address register */
+#define DMA_CH1MADDR(dmax) REG32((dmax) + 0x28U) /*!< DMA channel 1 memory base address register */
+#define DMA_CH2CTL(dmax) REG32((dmax) + 0x30U) /*!< DMA channel 2 control register */
+#define DMA_CH2CNT(dmax) REG32((dmax) + 0x34U) /*!< DMA channel 2 counter register */
+#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x38U) /*!< DMA channel 2 peripheral base address register */
+#define DMA_CH2MADDR(dmax) REG32((dmax) + 0x3CU) /*!< DMA channel 2 memory base address register */
+#define DMA_CH3CTL(dmax) REG32((dmax) + 0x44U) /*!< DMA channel 3 control register */
+#define DMA_CH3CNT(dmax) REG32((dmax) + 0x48U) /*!< DMA channel 3 counter register */
+#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x4CU) /*!< DMA channel 3 peripheral base address register */
+#define DMA_CH3MADDR(dmax) REG32((dmax) + 0x50U) /*!< DMA channel 3 memory base address register */
+#define DMA_CH4CTL(dmax) REG32((dmax) + 0x58U) /*!< DMA channel 4 control register */
+#define DMA_CH4CNT(dmax) REG32((dmax) + 0x5CU) /*!< DMA channel 4 counter register */
+#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x60U) /*!< DMA channel 4 peripheral base address register */
+#define DMA_CH4MADDR(dmax) REG32((dmax) + 0x64U) /*!< DMA channel 4 memory base address register */
+#define DMA_CH5CTL(dmax) REG32((dmax) + 0x6CU) /*!< DMA channel 5 control register */
+#define DMA_CH5CNT(dmax) REG32((dmax) + 0x70U) /*!< DMA channel 5 counter register */
+#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x74U) /*!< DMA channel 5 peripheral base address register */
+#define DMA_CH5MADDR(dmax) REG32((dmax) + 0x78U) /*!< DMA channel 5 memory base address register */
+#define DMA_CH6CTL(dmax) REG32((dmax) + 0x80U) /*!< DMA channel 6 control register */
+#define DMA_CH6CNT(dmax) REG32((dmax) + 0x84U) /*!< DMA channel 6 counter register */
+#define DMA_CH6PADDR(dmax) REG32((dmax) + 0x88U) /*!< DMA channel 6 peripheral base address register */
+#define DMA_CH6MADDR(dmax) REG32((dmax) + 0x8CU) /*!< DMA channel 6 memory base address register */
+
+/* bits definitions */
+/* DMA_INTF */
+#define DMA_INTF_GIF BIT(0) /*!< global interrupt flag of channel */
+#define DMA_INTF_FTFIF BIT(1) /*!< full transfer finish flag of channel */
+#define DMA_INTF_HTFIF BIT(2) /*!< half transfer finish flag of channel */
+#define DMA_INTF_ERRIF BIT(3) /*!< error flag of channel */
+
+/* DMA_INTC */
+#define DMA_INTC_GIFC BIT(0) /*!< clear global interrupt flag of channel */
+#define DMA_INTC_FTFIFC BIT(1) /*!< clear transfer finish flag of channel */
+#define DMA_INTC_HTFIFC BIT(2) /*!< clear half transfer finish flag of channel */
+#define DMA_INTC_ERRIFC BIT(3) /*!< clear error flag of channel */
+
+/* DMA_CHxCTL, x=0..6 */
+#define DMA_CHXCTL_CHEN BIT(0) /*!< channel enable */
+#define DMA_CHXCTL_FTFIE BIT(1) /*!< enable bit for channel full transfer finish interrupt */
+#define DMA_CHXCTL_HTFIE BIT(2) /*!< enable bit for channel half transfer finish interrupt */
+#define DMA_CHXCTL_ERRIE BIT(3) /*!< enable bit for channel error interrupt */
+#define DMA_CHXCTL_DIR BIT(4) /*!< transfer direction */
+#define DMA_CHXCTL_CMEN BIT(5) /*!< circular mode enable */
+#define DMA_CHXCTL_PNAGA BIT(6) /*!< next address generation algorithm of peripheral */
+#define DMA_CHXCTL_MNAGA BIT(7) /*!< next address generation algorithm of memory */
+#define DMA_CHXCTL_PWIDTH BITS(8,9) /*!< transfer data width of peripheral */
+#define DMA_CHXCTL_MWIDTH BITS(10,11) /*!< transfer data width of memory */
+#define DMA_CHXCTL_PRIO BITS(12,13) /*!< priority level */
+#define DMA_CHXCTL_M2M BIT(14) /*!< memory to memory mode */
+
+/* DMA_CHxCNT,x=0..6 */
+#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */
+
+/* DMA_CHxPADDR,x=0..6 */
+#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */
+
+/* DMA_CHxMADDR,x=0..6 */
+#define DMA_CHXMADDR_MADDR BITS(0,31) /*!< memory base address */
+
+/* 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_channel_enum;
+
+/* DMA initialize struct */
+typedef struct {
+ uint32_t periph_addr; /*!< peripheral base address */
+ uint32_t periph_width; /*!< transfer data size of peripheral */
+ uint32_t memory_addr; /*!< memory base address */
+ uint32_t memory_width; /*!< transfer data size of memory */
+ uint32_t number; /*!< channel transfer number */
+ uint32_t priority; /*!< channel priority level */
+ uint8_t periph_inc; /*!< peripheral increasing mode */
+ uint8_t memory_inc; /*!< memory increasing mode */
+ uint8_t direction; /*!< channel data transfer direction */
+} dma_parameter_struct;
+
+#define DMA_FLAG_ADD(flag, shift) ((flag) << ((shift) * 4U)) /*!< DMA channel flag shift */
+
+/* DMA_register address */
+#define DMA_CHCTL(dma, channel) REG32(((dma) + 0x08U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */
+#define DMA_CHCNT(dma, channel) REG32(((dma) + 0x0CU) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */
+#define DMA_CHPADDR(dma, channel) REG32(((dma) + 0x10U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */
+#define DMA_CHMADDR(dma, channel) REG32(((dma) + 0x14U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXMADDR register */
+
+/* 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 (DMA_INTF_GIF | DMA_INTF_FTFIF | \
+ DMA_INTF_HTFIF | DMA_INTF_ERRIF) /*!< clear DMA channel DMA_INTF register */
+
+/* DMA_INTF register */
+/* interrupt flag bits */
+#define DMA_INT_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */
+#define DMA_INT_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish interrupt flag of channel */
+#define DMA_INT_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish interrupt flag of channel */
+#define DMA_INT_FLAG_ERR DMA_INTF_ERRIF /*!< error interrupt flag of channel */
+
+/* flag bits */
+#define DMA_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */
+#define DMA_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag of channel */
+#define DMA_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag of channel */
+#define DMA_FLAG_ERR DMA_INTF_ERRIF /*!< error flag of channel */
+
+/* DMA_CHxCTL register */
+/* interrupt enable bits */
+#define DMA_INT_FTF DMA_CHXCTL_FTFIE /*!< enable bit for channel full transfer finish interrupt */
+#define DMA_INT_HTF DMA_CHXCTL_HTFIE /*!< enable bit for channel half transfer finish interrupt */
+#define DMA_INT_ERR DMA_CHXCTL_ERRIE /*!< enable bit for channel error interrupt */
+
+/* transfer direction */
+#define DMA_PERIPHERAL_TO_MEMORY ((uint8_t)0x0000U) /*!< read from peripheral and write to memory */
+#define DMA_MEMORY_TO_PERIPHERAL ((uint8_t)0x0001U) /*!< read from memory and write to peripheral */
+
+/* peripheral increasing mode */
+#define DMA_PERIPH_INCREASE_DISABLE ((uint8_t)0x0000U) /*!< next address of peripheral is fixed address mode */
+#define DMA_PERIPH_INCREASE_ENABLE ((uint8_t)0x0001U) /*!< next address of peripheral is increasing address mode */
+
+/* memory increasing mode */
+#define DMA_MEMORY_INCREASE_DISABLE ((uint8_t)0x0000U) /*!< next address of memory is fixed address mode */
+#define DMA_MEMORY_INCREASE_ENABLE ((uint8_t)0x0001U) /*!< next address of memory is increasing address mode */
+
+/* transfer data size of peripheral */
+#define CHCTL_PWIDTH(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) /*!< transfer data size of peripheral */
+#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PWIDTH(0) /*!< transfer data size of peripheral is 8-bit */
+#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PWIDTH(1) /*!< transfer data size of peripheral is 16-bit */
+#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PWIDTH(2) /*!< transfer data size of peripheral is 32-bit */
+
+/* transfer data size of memory */
+#define CHCTL_MWIDTH(regval) (BITS(10,11) & ((uint32_t)(regval) << 10)) /*!< transfer data size of memory */
+#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0) /*!< transfer data size of memory is 8-bit */
+#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1) /*!< transfer data size of memory is 16-bit */
+#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2) /*!< transfer data size of memory is 32-bit */
+
+/* channel priority level */
+#define CHCTL_PRIO(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) /*!< DMA channel priority level */
+#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 */
+
+/* DMA_CHxCNT register */
+/* transfer counter */
+#define DMA_CHANNEL_CNT_MASK DMA_CHXCNT_CNT /*!< transfer counter mask */
+
+/* function declarations */
+/* DMA deinitialization and initialization functions */
+/* deinitialize DMA a channel registers */
+void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx);
+/* initialize the parameters of DMA struct with the default values */
+void dma_struct_para_init(dma_parameter_struct *init_struct);
+/* initialize DMA channel */
+#ifdef GD_MBED_USED
+void dma_para_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct *init_struct);
+#else
+void dma_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct *init_struct);
+#endif
+/* 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 memory to memory mode */
+void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx);
+/* disable memory to memory mode */
+void dma_memory_to_memory_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);
+
+/* DMA configuration functions */
+/* 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, 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 data size of memory */
+void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth);
+/* configure transfer data size of peripheral */
+void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth);
+/* enable next address increasement algorithm of memory */
+void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx);
+/* disable next address increasement algorithm of memory */
+void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx);
+/* enable next address increasement algorithm of peripheral */
+void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx);
+/* disable next address increasement algorithm of peripheral */
+void dma_periph_increase_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, uint32_t direction);
+
+/* flag and interrupt functions */
+/* check DMA flag is set or not */
+FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag);
+/* clear the flag of a DMA channel */
+void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag);
+/* check DMA flag and interrupt enable bit is set or not */
+FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag);
+/* clear the interrupt flag of a DMA channel */
+void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag);
+/* 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 /* GD32E10X_DMA_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_exmc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_exmc.h
new file mode 100644
index 0000000000..b80573805d
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_exmc.h
@@ -0,0 +1,212 @@
+/*!
+ \file gd32e10x_exmc.h
+ \brief definitions for the EXMC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_EXMC_H
+#define GD32E10X_EXMC_H
+
+#include "gd32e10x.h"
+
+/* EXMC definitions */
+#define EXMC (EXMC_BASE) /*!< EXMC register base address */
+
+/* registers definitions */
+/* NOR/PSRAM */
+#define EXMC_SNCTL REG32(EXMC + 0x00U) /*!< EXMC SRAM/NOR flash control register */
+#define EXMC_SNTCFG REG32(EXMC + 0x04U) /*!< EXMC SRAM/NOR flash timing configuration register */
+#define EXMC_SNWTCFG REG32(EXMC + 0x104U) /*!< EXMC SRAM/NOR flash write timing configuration register */
+
+/* bits definitions */
+/* EXMC_SNCTL */
+#define EXMC_SNCTL_NRBKEN BIT(0) /*!< NOR region enable */
+#define EXMC_SNCTL_NRMUX BIT(1) /*!< NOR region memory address/data multiplexing */
+#define EXMC_SNCTL_NRTP BITS(2,3) /*!< NOR region memory type */
+#define EXMC_SNCTL_NRW BITS(4,5) /*!< NOR region 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 */
+
+/* EXMC_SNTCFG */
+#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_SNWTCFG */
+#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 */
+
+/* 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, the value can be 1 ~ 16, can't be 0 */
+ uint32_t asyn_data_setuptime; /*!< configure the data setup time, the value can be 2 ~ 256, can't be 0 */
+ uint32_t asyn_address_holdtime; /*!< configure the address hold time, the value can be 2 ~ 16, can't be 0 */
+ uint32_t asyn_address_setuptime; /*!< configure the address setup time, the value can be 1 ~ 16, can't be 0 */
+} exmc_norsram_timing_parameter_struct;
+
+/* EXMC NOR/SRAM initialize struct */
+typedef struct {
+ 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 extended mode is not used or the timing
+ parameters for read if the extended mode is used */
+ exmc_norsram_timing_parameter_struct *write_timing; /*!< timing parameters for write when the extended mode is used */
+} exmc_norsram_parameter_struct;
+
+/* 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 region 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 region 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 */
+
+/* EXMC NOR/SRAM write mode */
+#define EXMC_ASYN_WRITE ((uint32_t)0x00000000U) /*!< asynchronous write mode */
+#define EXMC_SYN_WRITE EXMC_SNCTL_SYNCWR /*!< 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 EXMC_SNCTL_NRWTCFG /*!< 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 EXMC_SNCTL_NRWTPOL /*!< high level is active of NWAIT */
+
+/* function declarations */
+/* NOR/SRAM initializtion */
+/* deinitialize EXMC NOR/SRAM bank */
+void exmc_norsram_deinit(void);
+/* exmc_norsram_parameter_struct parameter initialize */
+void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct);
+/* initialize EXMC NOR/SRAM bank */
+void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct);
+
+/* NOR/SRAM enable */
+/* enable EXMC NOR/SRAM bank */
+void exmc_norsram_enable(void);
+/* disable EXMC NOR/SRAM bank */
+void exmc_norsram_disable(void);
+
+/* NOR/SRAM configuration */
+/* configure CRAM page size */
+void exmc_norsram_page_size_config(uint32_t page_size);
+
+#endif /* GD32E10X_EXMC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_exti.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_exti.h
new file mode 100644
index 0000000000..dc8602385c
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_exti.h
@@ -0,0 +1,246 @@
+/*!
+ \file gd32e10x_exti.h
+ \brief definitions for the EXTI
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_EXTI_H
+#define GD32E10X_EXTI_H
+
+#include "gd32e10x.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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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 */
+
+/* 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_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 interrupt pending flag */
+FlagStatus exti_interrupt_flag_get(exti_line_enum linex);
+/* clear EXTI lines interrupt pending flag */
+void exti_interrupt_flag_clear(exti_line_enum linex);
+/* enable the EXTI software interrupt */
+void exti_software_interrupt_enable(exti_line_enum linex);
+/* disable the EXTI software interrupt */
+void exti_software_interrupt_disable(exti_line_enum linex);
+
+#endif /* GD32E10X_EXTI_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_fmc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_fmc.h
new file mode 100644
index 0000000000..c20c04fd24
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_fmc.h
@@ -0,0 +1,337 @@
+/*!
+ \file gd32e10x_fmc.h
+ \brief definitions for the FMC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_FMC_H
+#define GD32E10X_FMC_H
+
+#include "gd32e10x.h"
+
+/* FMC and option bytes definition */
+#define FMC FMC_BASE /*!< FMC register base address */
+#define OB OB_BASE /*!< option bytes 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 bytes unlock key register */
+#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */
+#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */
+#define FMC_ADDR REG32((FMC) + 0x14U) /*!< FMC address register */
+#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */
+#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC erase/program protection register */
+#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */
+
+#define OB_SPC REG32((OB) + 0x00U) /*!< option bytes security protection register */
+#define OB_USER REG32((OB) + 0x02U) /*!< option bytes user register */
+#define OB_DATA0 REG16((OB) + 0x04U) /*!< option bytes data register 0 */
+#define OB_DATA1 REG16((OB) + 0x06U) /*!< option bytes data register 1 */
+#define OB_WP0 REG32((OB) + 0x08U) /*!< option bytes write protection register 0 */
+#define OB_WP1 REG32((OB) + 0x0AU) /*!< option bytes write protection register 1 */
+#define OB_WP2 REG32((OB) + 0x0CU) /*!< option bytes write protection register 2 */
+#define OB_WP3 REG32((OB) + 0x0EU) /*!< option bytes write protection register 3 */
+
+/* bits definitions */
+/* FMC_WS */
+#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */
+#define FMC_WS_PFEN BIT(4) /*!< pre-fetch enable */
+#define FMC_WS_ICEN BIT(9) /*!< IBUS cache enable */
+#define FMC_WS_DCEN BIT(10) /*!< DBUS cache enable */
+#define FMC_WS_ICRST BIT(11) /*!< IBUS cache reset */
+#define FMC_WS_DCRST BIT(12) /*!< DBUS cache reset */
+#define FMC_WS_PGW BIT(15) /*!< program width to flash memory */
+
+/* FMC_KEY */
+#define FMC_KEY_KEY BITS(0,31) /*!< FMC_CTL unlock key bits */
+
+/* FMC_OBKEY */
+#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */
+
+/* FMC_STAT */
+#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */
+#define FMC_STAT_PGERR BIT(2) /*!< flash program error flag bit */
+#define FMC_STAT_PGAERR BIT(3) /*!< flash program alignment error flag bit */
+#define FMC_STAT_WPERR BIT(4) /*!< erase/program protection error flag bit */
+#define FMC_STAT_ENDF BIT(5) /*!< end of operation flag bit */
+
+/* FMC_CTL */
+#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */
+#define FMC_CTL_PER BIT(1) /*!< main flash page erase command bit */
+#define FMC_CTL_MER BIT(2) /*!< main flash mass erase command bit */
+#define FMC_CTL_OBPG BIT(4) /*!< option bytes program command bit */
+#define FMC_CTL_OBER BIT(5) /*!< option bytes erase command bit */
+#define FMC_CTL_START BIT(6) /*!< send erase command to FMC bit */
+#define FMC_CTL_LK BIT(7) /*!< FMC_CTL lock bit */
+#define FMC_CTL_OBWEN BIT(9) /*!< option bytes erase/program enable bit */
+#define FMC_CTL_ERRIE BIT(10) /*!< error interrupt enable bit */
+#define FMC_CTL_ENDIE BIT(12) /*!< end of operation interrupt enable bit */
+
+/* FMC_ADDR */
+#define FMC_ADDR_ADDR BITS(0,31) /*!< flash erase/program command address bits */
+
+/* FMC_OBSTAT */
+#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit. */
+#define FMC_OBSTAT_SPC BIT(1) /*!< option bytes security protection code */
+#define FMC_OBSTAT_USER BITS(2,9) /*!< store USER of option bytes block after system reset */
+#define FMC_OBSTAT_DATA BITS(10,25) /*!< store DATA of option bytes block after system reset. */
+
+/* FMC_WP */
+#define FMC_WP_WP BITS(0,31) /*!< store WP of option bytes block after system reset */
+
+/* FMC_PID */
+#define FMC_PID_PID BITS(0,31) /*!< product ID bits */
+
+/* constants definitions */
+/* define the FMC bit position and its register index offset */
+#define FMC_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define FMC_REG_VAL(offset) (REG32(FMC + ((uint32_t)(offset) >> 6)))
+#define FMC_BIT_POS(val) ((uint32_t)(val) & 0x1FU)
+#define FMC_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1))
+#define FMC_REG_VALS(offset) (REG32(FMC + ((uint32_t)(offset) >> 12)))
+#define FMC_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU)
+#define FMC_BIT_POS1(val) ((uint32_t)(val) & 0x1FU)
+#define FMC_REG_OFFSET_GET(flag) ((uint32_t)(flag) >> 12)
+
+/* configuration register */
+#define FMC_STAT_REG_OFFSET 0x0CU /*!< status register offset */
+#define FMC_CTL_REG_OFFSET 0x10U /*!< control register offset */
+#define FMC_OBSTAT_REG_OFFSET 0x1CU /*!< option bytes status register offset */
+
+/* fmc state */
+typedef enum {
+ FMC_READY, /*!< the operation has been completed */
+ FMC_BUSY, /*!< the operation is in progress */
+ FMC_PGERR, /*!< program error */
+ FMC_PGAERR, /*!< program alignment error */
+ FMC_WPERR, /*!< erase/program protection error */
+ FMC_TOERR, /*!< timeout error */
+} fmc_state_enum;
+
+/* FMC interrupt enable */
+typedef enum {
+ FMC_INT_ERR = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 10U), /*!< enable FMC error interrupt */
+ FMC_INT_END = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 12U), /*!< enable FMC end of program interrupt */
+} fmc_int_enum;
+
+/* FMC flags */
+typedef enum {
+ FMC_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 0U), /*!< FMC busy flag */
+ FMC_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 2U), /*!< FMC operation error flag bit */
+ FMC_FLAG_PGAERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 3U), /*!< FMC program alignment error flag */
+ FMC_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 4U), /*!< FMC erase/program protection error flag bit */
+ FMC_FLAG_END = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 5U), /*!< FMC end of operation flag bit */
+ FMC_FLAG_OBERR = FMC_REGIDX_BIT(FMC_OBSTAT_REG_OFFSET, 0U), /*!< FMC option bytes read error flag */
+} fmc_flag_enum;
+
+/* FMC interrupt flags */
+typedef enum {
+ FMC_INT_FLAG_PGERR = FMC_REGIDX_BITS(FMC_STAT_REG_OFFSET, 2U, 10U), /*!< FMC operation error interrupt flag bit */
+ FMC_INT_FLAG_PGAERR = FMC_REGIDX_BITS(FMC_STAT_REG_OFFSET, 3U, 10U), /*!< FMC program alignment error interrupt flag bit */
+ FMC_INT_FLAG_WPERR = FMC_REGIDX_BITS(FMC_STAT_REG_OFFSET, 4U, 10U), /*!< FMC erase/program protection error interrupt flag bit */
+ FMC_INT_FLAG_END = FMC_REGIDX_BITS(FMC_STAT_REG_OFFSET, 5U, 12U), /*!< FMC end of operation interrupt flag bit */
+} fmc_interrupt_flag_enum;
+
+/* unlock key */
+#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */
+#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */
+
+/* FMC wait state counter */
+#define WS_WSCNT(regval) (BITS(0,2) & ((uint32_t)(regval)))
+#define FMC_WAIT_STATE_0 WS_WSCNT(0) /*!< FMC 0 wait */
+#define FMC_WAIT_STATE_1 WS_WSCNT(1) /*!< FMC 1 wait */
+#define FMC_WAIT_STATE_2 WS_WSCNT(2) /*!< FMC 2 wait */
+#define FMC_WAIT_STATE_3 WS_WSCNT(3) /*!< FMC 3 wait */
+
+/* adc_ctl1 register value */
+#define FMC_PROG_W_64B ((uint32_t)0x00000000U) /*!< LSB alignment */
+#define FMC_PROG_W_32B FMC_WS_PGW /*!< MSB alignment */
+
+#define OB_USER_MASK ((uint8_t)0xF8U) /*!< MASK value */
+
+/* read protect configure */
+#define FMC_NSPC ((uint8_t)0xA5U) /*!< no security protection */
+#define FMC_USPC ((uint8_t)0xBBU) /*!< under security protection */
+
+/* OB_SPC */
+#define OB_SPC_SPC ((uint32_t)0x000000FFU) /*!< option byte security protection value */
+#define OB_SPC_SPC_N ((uint32_t)0x0000FF00U) /*!< option byte security protection complement value */
+
+/* option bytes software/hardware free watch dog timer */
+#define OB_FWDGT_SOFTWARE ((uint8_t)0x01U) /*!< software free watchdog */
+#define OB_FWDGT_HARDWARE ((uint8_t)0x00U) /*!< hardware free watchdog */
+
+/* option bytes reset or not entering deep sleep mode */
+#define OB_DEEPSLEEP_NO_RST ((uint8_t)0x02U) /*!< no reset when entering deepsleep mode */
+#define OB_DEEPSLEEP_RST ((uint8_t)0x00U) /*!< generate a reset instead of entering deepsleep mode */
+
+/* option bytes reset or not entering standby mode */
+#define OB_STDBY_NO_RST ((uint8_t)0x04U) /*!< no reset when entering deepsleep mode */
+#define OB_STDBY_RST ((uint8_t)0x00U) /*!< generate a reset instead of entering standby mode */
+
+/* OB_USER */
+#define OB_USER_USER ((uint32_t)0x00FF0000U) /*!< user option value */
+#define OB_USER_USER_N ((uint32_t)0xFF000000U) /*!< user option complement value */
+
+/* option byte data address */
+#define OB_DATA_ADDR0 ((uint32_t)0x1FFFF804U) /*!< option byte data address 0 */
+#define OB_DATA_ADDR1 ((uint32_t)0x1FFFF806U) /*!< option byte data address 1 */
+
+/* OB_WP0 */
+#define OB_WP0_WP0 ((uint32_t)0x000000FFU) /*!< FMC write protection option value */
+
+/* OB_WP1 */
+#define OB_WP1_WP1 ((uint32_t)0x0000FF00U) /*!< FMC write protection option complement value */
+
+/* OB_WP2 */
+#define OB_WP2_WP2 ((uint32_t)0x00FF0000U) /*!< FMC write protection option value */
+
+/* OB_WP3 */
+#define OB_WP3_WP3 ((uint32_t)0xFF000000U) /*!< FMC write protection option complement value */
+
+/* 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)0x00001000U) /*!< erase/program protection of sector 12 */
+#define OB_WP_13 ((uint32_t)0x00002000U) /*!< erase/program protection of sector 13 */
+#define OB_WP_14 ((uint32_t)0x00004000U) /*!< erase/program protection of sector 14 */
+#define OB_WP_15 ((uint32_t)0x00008000U) /*!< erase/program protection of sector 15 */
+#define OB_WP_16 ((uint32_t)0x00010000U) /*!< erase/program protection of sector 16 */
+#define OB_WP_17 ((uint32_t)0x00020000U) /*!< erase/program protection of sector 17 */
+#define OB_WP_18 ((uint32_t)0x00040000U) /*!< erase/program protection of sector 18 */
+#define OB_WP_19 ((uint32_t)0x00080000U) /*!< erase/program protection of sector 19 */
+#define OB_WP_20 ((uint32_t)0x00100000U) /*!< erase/program protection of sector 20 */
+#define OB_WP_21 ((uint32_t)0x00200000U) /*!< erase/program protection of sector 21 */
+#define OB_WP_22 ((uint32_t)0x00400000U) /*!< erase/program protection of sector 22 */
+#define OB_WP_23 ((uint32_t)0x00800000U) /*!< erase/program protection of sector 23 */
+#define OB_WP_24 ((uint32_t)0x01000000U) /*!< erase/program protection of sector 24 */
+#define OB_WP_25 ((uint32_t)0x02000000U) /*!< erase/program protection of sector 25 */
+#define OB_WP_26 ((uint32_t)0x04000000U) /*!< erase/program protection of sector 26 */
+#define OB_WP_27 ((uint32_t)0x08000000U) /*!< erase/program protection of sector 27 */
+#define OB_WP_28 ((uint32_t)0x10000000U) /*!< erase/program protection of sector 28 */
+#define OB_WP_29 ((uint32_t)0x20000000U) /*!< erase/program protection of sector 29 */
+#define OB_WP_30 ((uint32_t)0x40000000U) /*!< erase/program protection of sector 30 */
+#define OB_WP_31 ((uint32_t)0x80000000U) /*!< erase/program protection of sector 31 */
+#define OB_WP_ALL ((uint32_t)0xFFFFFFFFU) /*!< erase/program protection of all sectors */
+
+/* FMC timeout */
+#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000U) /*!< FMC timeout count value */
+
+/* function declarations */
+/* FMC main memory programming functions */
+/* set the FMC wait state counter */
+void fmc_wscnt_set(uint32_t wscnt);
+/* enable pre-fetch */
+void fmc_prefetch_enable(void);
+/* disable pre-fetch */
+void fmc_prefetch_disable(void);
+/* enable IBUS cache */
+void fmc_ibus_enable(void);
+/* disable IBUS cache */
+void fmc_ibus_disable(void);
+/* enable DBUS cache */
+void fmc_dbus_enable(void);
+/* disable DBUS cache */
+void fmc_dbus_disable(void);
+/* reset IBUS cache */
+void fmc_ibus_reset(void);
+/* reset DBUS cache */
+void fmc_dbus_reset(void);
+/* set program width to flash memory */
+void fmc_program_width_set(uint32_t pgw);
+/* unlock the main FMC operation */
+void fmc_unlock(void);
+/* lock the main FMC operation */
+void fmc_lock(void);
+/* FMC erase page */
+fmc_state_enum fmc_page_erase(uint32_t page_address);
+/* FMC erase whole chip */
+fmc_state_enum fmc_mass_erase(void);
+/* FMC program a double word at the corresponding address */
+fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data);
+/* 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 option bytes programming functions */
+/* unlock the option bytes operation */
+void ob_unlock(void);
+/* lock the option bytes operation */
+void ob_lock(void);
+/* erase the option bytes */
+fmc_state_enum ob_erase(void);
+/* enable write protect */
+fmc_state_enum ob_write_protection_enable(uint32_t ob_wp);
+/* configure the option bytes security protection */
+fmc_state_enum ob_security_protection_config(uint8_t ob_spc);
+/* write the FMC option bytes */
+fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_stdby);
+/* program option bytes data */
+fmc_state_enum ob_data_program(uint32_t address, uint8_t data);
+/* get the FMC option bytes user */
+uint8_t ob_user_get(void);
+/* get OB_DATA in register FMC_OBSTAT */
+uint16_t ob_data_get(void);
+/* get the FMC option bytes write protection */
+uint32_t ob_write_protection_get(void);
+/* get option bytes security protection state */
+FlagStatus ob_security_protection_flag_get(void);
+
+/* FMC interrupts and flags management functions */
+/* enable FMC interrupt */
+void fmc_interrupt_enable(uint32_t interrupt);
+/* disable FMC interrupt */
+void fmc_interrupt_disable(uint32_t interrupt);
+/* check flag is set or not */
+FlagStatus fmc_flag_get(uint32_t flag);
+/* clear the FMC flag */
+void fmc_flag_clear(uint32_t flag);
+/* get FMC interrupt flag state */
+FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum flag);
+/* clear FMC interrupt flag state */
+void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag);
+
+#endif /* GD32E10X_FMC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_fwdgt.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_fwdgt.h
new file mode 100644
index 0000000000..6af57b8ef4
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_fwdgt.h
@@ -0,0 +1,107 @@
+/*!
+ \file gd32e10x_fwdgt.h
+ \brief definitions for the FWDGT
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_FWDGT_H
+#define GD32E10X_FWDGT_H
+
+#include "gd32e10x.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 */
+
+/* FWDGT flag definitions */
+#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< FWDGT prescaler divider value update flag */
+#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< FWDGT counter reload value update flag */
+
+/* function declarations */
+/* enable write access to FWDGT_PSC and FWDGT_RLD */
+void fwdgt_write_enable(void);
+/* 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 /* GD32E10X_FWDGT_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_gpio.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_gpio.h
new file mode 100644
index 0000000000..ffde7ebb95
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_gpio.h
@@ -0,0 +1,484 @@
+/*!
+ \file gd32e10x_gpio.h
+ \brief definitions for the GPIO
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_GPIO_H
+#define GD32E10X_GPIO_H
+
+#include "gd32e10x.h"
+
+/* GPIOx(x=A,B,C,D,E) 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)
+
+/* AFIO definitions */
+#define AFIO AFIO_BASE
+
+/* registers definitions */
+/* GPIO registers definitions */
+#define GPIO_CTL0(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register 0 */
+#define GPIO_CTL1(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port control register 1 */
+#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port input status register */
+#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port output control register */
+#define GPIO_BOP(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port bit operation register */
+#define GPIO_BC(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO bit clear register */
+#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port configuration lock register */
+#define GPIOx_SPD(gpiox) REG32((gpiox) + 0x3CU) /*!< GPIO port bit speed register */
+
+/* AFIO registers definitions */
+#define AFIO_EC REG32(AFIO + 0x00U) /*!< AFIO event control register */
+#define AFIO_PCF0 REG32(AFIO + 0x04U) /*!< AFIO port configuration register 0 */
+#define AFIO_EXTISS0 REG32(AFIO + 0x08U) /*!< AFIO port EXTI sources selection register 0 */
+#define AFIO_EXTISS1 REG32(AFIO + 0x0CU) /*!< AFIO port EXTI sources selection register 1 */
+#define AFIO_EXTISS2 REG32(AFIO + 0x10U) /*!< AFIO port EXTI sources selection register 2 */
+#define AFIO_EXTISS3 REG32(AFIO + 0x14U) /*!< AFIO port EXTI sources selection register 3 */
+#define AFIO_PCF1 REG32(AFIO + 0x1CU) /*!< AFIO port configuration register 1 */
+#define AFIO_CPSCTL REG32(AFIO + 0x20U) /*!< IO compensation control register */
+
+/* bits definitions */
+/* GPIO_CTL0 */
+#define GPIO_CTL0_MD0 BITS(0,1) /*!< port 0 mode bits */
+#define GPIO_CTL0_CTL0 BITS(2,3) /*!< pin 0 configuration bits */
+#define GPIO_CTL0_MD1 BITS(4,5) /*!< port 1 mode bits */
+#define GPIO_CTL0_CTL1 BITS(6,7) /*!< pin 1 configuration bits */
+#define GPIO_CTL0_MD2 BITS(8,9) /*!< port 2 mode bits */
+#define GPIO_CTL0_CTL2 BITS(10,11) /*!< pin 2 configuration bits */
+#define GPIO_CTL0_MD3 BITS(12,13) /*!< port 3 mode bits */
+#define GPIO_CTL0_CTL3 BITS(14,15) /*!< pin 3 configuration bits */
+#define GPIO_CTL0_MD4 BITS(16,17) /*!< port 4 mode bits */
+#define GPIO_CTL0_CTL4 BITS(18,19) /*!< pin 4 configuration bits */
+#define GPIO_CTL0_MD5 BITS(20,21) /*!< port 5 mode bits */
+#define GPIO_CTL0_CTL5 BITS(22,23) /*!< pin 5 configuration bits */
+#define GPIO_CTL0_MD6 BITS(24,25) /*!< port 6 mode bits */
+#define GPIO_CTL0_CTL6 BITS(26,27) /*!< pin 6 configuration bits */
+#define GPIO_CTL0_MD7 BITS(28,29) /*!< port 7 mode bits */
+#define GPIO_CTL0_CTL7 BITS(30,31) /*!< pin 7 configuration bits */
+
+/* GPIO_CTL1 */
+#define GPIO_CTL1_MD8 BITS(0,1) /*!< port 8 mode bits */
+#define GPIO_CTL1_CTL8 BITS(2,3) /*!< pin 8 configuration bits */
+#define GPIO_CTL1_MD9 BITS(4,5) /*!< port 9 mode bits */
+#define GPIO_CTL1_CTL9 BITS(6,7) /*!< pin 9 configuration bits */
+#define GPIO_CTL1_MD10 BITS(8,9) /*!< port 10 mode bits */
+#define GPIO_CTL1_CTL10 BITS(10,11) /*!< pin 10 configuration bits */
+#define GPIO_CTL1_MD11 BITS(12,13) /*!< port 11 mode bits */
+#define GPIO_CTL1_CTL11 BITS(14,15) /*!< pin 11 configuration bits */
+#define GPIO_CTL1_MD12 BITS(16,17) /*!< port 12 mode bits */
+#define GPIO_CTL1_CTL12 BITS(18,19) /*!< pin 12 configuration bits */
+#define GPIO_CTL1_MD13 BITS(20,21) /*!< port 13 mode bits */
+#define GPIO_CTL1_CTL13 BITS(22,23) /*!< pin 13 configuration bits */
+#define GPIO_CTL1_MD14 BITS(24,25) /*!< port 14 mode bits */
+#define GPIO_CTL1_CTL14 BITS(26,27) /*!< pin 14 configuration bits */
+#define GPIO_CTL1_MD15 BITS(28,29) /*!< port 15 mode bits */
+#define GPIO_CTL1_CTL15 BITS(30,31) /*!< pin 15 configuration 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_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_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_SPD */
+#define GPIO_SPD_SPD0 BIT(0) /*!< pin 0 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD1 BIT(1) /*!< pin 1 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD2 BIT(2) /*!< pin 2 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD3 BIT(3) /*!< pin 3 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD4 BIT(4) /*!< pin 4 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD5 BIT(5) /*!< pin 5 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD6 BIT(6) /*!< pin 6 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD7 BIT(7) /*!< pin 7 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD8 BIT(8) /*!< pin 8 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD9 BIT(9) /*!< pin 9 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD10 BIT(10) /*!< pin 10 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD11 BIT(11) /*!< pin 11 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD12 BIT(12) /*!< pin 12 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD13 BIT(13) /*!< pin 13 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD14 BIT(14) /*!< pin 14 set very high output speed when MDx is 0b11 */
+#define GPIO_SPD_SPD15 BIT(15) /*!< pin 15 set very high output speed when MDx is 0b11 */
+
+/* AFIO_EC */
+#define AFIO_EC_PIN BITS(0,3) /*!< event output pin selection */
+#define AFIO_EC_PORT BITS(4,6) /*!< event output port selection */
+#define AFIO_EC_EOE BIT(7) /*!< event output enable */
+
+/* AFIO_PCF0 */
+/* memory map and bit definitions */
+#define AFIO_PCF0_SPI0_REMAP BIT(0) /*!< SPI0 remapping */
+#define AFIO_PCF0_I2C0_REMAP BIT(1) /*!< I2C0 remapping */
+#define AFIO_PCF0_USART0_REMAP BIT(2) /*!< USART0 remapping */
+#define AFIO_PCF0_USART1_REMAP BIT(3) /*!< USART1 remapping */
+#define AFIO_PCF0_USART2_REMAP BITS(4,5) /*!< USART2 remapping */
+#define AFIO_PCF0_TIMER0_REMAP BITS(6,7) /*!< TIMER0 remapping */
+#define AFIO_PCF0_TIMER1_REMAP BITS(8,9) /*!< TIMER1 remapping */
+#define AFIO_PCF0_TIMER2_REMAP BITS(10,11) /*!< TIMER2 remapping */
+#define AFIO_PCF0_TIMER3_REMAP BIT(12) /*!< TIMER3 remapping */
+#define AFIO_PCF0_CAN0_REMAP BITS(13,14) /*!< CAN0 remapping */
+#define AFIO_PCF0_PD01_REMAP BIT(15) /*!< port D0/port D1 mapping on OSC_IN/OSC_OUT */
+#define AFIO_PCF0_TIMER4CH3_IREMAP BIT(16) /*!< TIMER4 channel3 internal remapping */
+#define AFIO_PCF0_ADC0_ETRGINS_REMAP BIT(17) /*!< ADC 0 external trigger inserted conversion remapping */
+#define AFIO_PCF0_ADC0_ETRGREG_REMAP BIT(18) /*!< ADC 0 external trigger regular conversion remapping */
+#define AFIO_PCF0_ADC1_ETRGINS_REMAP BIT(19) /*!< ADC 1 external trigger inserted conversion remapping */
+#define AFIO_PCF0_ADC1_ETRGREG_REMAP BIT(20) /*!< ADC 1 external trigger regular conversion remapping */
+#define AFIO_PCF0_CAN1_REMAP BIT(22) /*!< CAN1 remapping */
+#define AFIO_PCF0_SWJ_CFG BITS(24,26) /*!< serial wire JTAG configuration */
+#define AFIO_PCF0_SPI2_REMAP BIT(28) /*!< SPI2/I2S2 remapping */
+#define AFIO_PCF0_TIMER1ITR0_REMAP BIT(29) /*!< TIMER1 internal trigger 0 remapping */
+
+/* AFIO_EXTISS0 */
+#define AFIO_EXTI0_SS BITS(0,3) /*!< EXTI 0 sources selection */
+#define AFIO_EXTI1_SS BITS(4,7) /*!< EXTI 1 sources selection */
+#define AFIO_EXTI2_SS BITS(8,11) /*!< EXTI 2 sources selection */
+#define AFIO_EXTI3_SS BITS(12,15) /*!< EXTI 3 sources selection */
+
+/* AFIO_EXTISS1 */
+#define AFIO_EXTI4_SS BITS(0,3) /*!< EXTI 4 sources selection */
+#define AFIO_EXTI5_SS BITS(4,7) /*!< EXTI 5 sources selection */
+#define AFIO_EXTI6_SS BITS(8,11) /*!< EXTI 6 sources selection */
+#define AFIO_EXTI7_SS BITS(12,15) /*!< EXTI 7 sources selection */
+
+/* AFIO_EXTISS2 */
+#define AFIO_EXTI8_SS BITS(0,3) /*!< EXTI 8 sources selection */
+#define AFIO_EXTI9_SS BITS(4,7) /*!< EXTI 9 sources selection */
+#define AFIO_EXTI10_SS BITS(8,11) /*!< EXTI 10 sources selection */
+#define AFIO_EXTI11_SS BITS(12,15) /*!< EXTI 11 sources selection */
+
+/* AFIO_EXTISS3 */
+#define AFIO_EXTI12_SS BITS(0,3) /*!< EXTI 12 sources selection */
+#define AFIO_EXTI13_SS BITS(4,7) /*!< EXTI 13 sources selection */
+#define AFIO_EXTI14_SS BITS(8,11) /*!< EXTI 14 sources selection */
+#define AFIO_EXTI15_SS BITS(12,15) /*!< EXTI 15 sources selection */
+
+/* AFIO_PCF1 */
+#define AFIO_PCF1_TIMER8_REMAP BIT(5) /*!< TIMER8 remapping */
+#define AFIO_PCF1_EXMC_NADV BIT(10) /*!< EXMC_NADV connect/disconnect */
+#define AFIO_PCF1_CTC_REMAP BITS(11,12) /*!< CTC remapping */
+
+/* AFIO_CPSCTL */
+#define AFIO_CPSCTL_CPS_EN BIT(0) /*!< I/O compensation cell enable */
+#define AFIO_CPSCTL_CPS_RDY BIT(8) /*!< I/O compensation cell is ready or not */
+
+/* constants definitions */
+typedef FlagStatus bit_status;
+
+/* GPIO mode values set */
+#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (4U * (n))))
+#define GPIO_MODE_MASK(n) (0xFU << (4U * (n)))
+
+/* GPIO mode definitions */
+#define GPIO_MODE_AIN ((uint8_t)0x00U) /*!< analog input mode */
+#define GPIO_MODE_IN_FLOATING ((uint8_t)0x04U) /*!< floating input mode */
+#define GPIO_MODE_IPD ((uint8_t)0x28U) /*!< pull-down input mode */
+#define GPIO_MODE_IPU ((uint8_t)0x48U) /*!< pull-up input mode */
+#define GPIO_MODE_OUT_OD ((uint8_t)0x14U) /*!< GPIO output with open-drain */
+#define GPIO_MODE_OUT_PP ((uint8_t)0x10U) /*!< GPIO output with push-pull */
+#define GPIO_MODE_AF_OD ((uint8_t)0x1CU) /*!< AFIO output with open-drain */
+#define GPIO_MODE_AF_PP ((uint8_t)0x18U) /*!< AFIO output with push-pull */
+
+/* GPIO output max speed value */
+#define GPIO_OSPEED_10MHZ ((uint8_t)0x01U) /*!< output max speed 10MHz */
+#define GPIO_OSPEED_2MHZ ((uint8_t)0x02U) /*!< output max speed 2MHz */
+#define GPIO_OSPEED_50MHZ ((uint8_t)0x03U) /*!< output max speed 50MHz */
+#define GPIO_OSPEED_MAX ((uint8_t)0x04U) /*!< GPIO very high output speed, max speed more than 50MHz */
+
+/* GPIO event output port definitions */
+#define GPIO_EVENT_PORT_GPIOA ((uint8_t)0x00U) /*!< event output port A */
+#define GPIO_EVENT_PORT_GPIOB ((uint8_t)0x01U) /*!< event output port B */
+#define GPIO_EVENT_PORT_GPIOC ((uint8_t)0x02U) /*!< event output port C */
+#define GPIO_EVENT_PORT_GPIOD ((uint8_t)0x03U) /*!< event output port D */
+#define GPIO_EVENT_PORT_GPIOE ((uint8_t)0x04U) /*!< event output port E */
+
+/* GPIO output port source definitions */
+#define GPIO_PORT_SOURCE_GPIOA ((uint8_t)0x00U) /*!< output port source A */
+#define GPIO_PORT_SOURCE_GPIOB ((uint8_t)0x01U) /*!< output port source B */
+#define GPIO_PORT_SOURCE_GPIOC ((uint8_t)0x02U) /*!< output port source C */
+#define GPIO_PORT_SOURCE_GPIOD ((uint8_t)0x03U) /*!< output port source D */
+#define GPIO_PORT_SOURCE_GPIOE ((uint8_t)0x04U) /*!< output port source E */
+
+/* GPIO event output pin definitions */
+#define GPIO_EVENT_PIN_0 ((uint8_t)0x00U) /*!< GPIO event pin 0 */
+#define GPIO_EVENT_PIN_1 ((uint8_t)0x01U) /*!< GPIO event pin 1 */
+#define GPIO_EVENT_PIN_2 ((uint8_t)0x02U) /*!< GPIO event pin 2 */
+#define GPIO_EVENT_PIN_3 ((uint8_t)0x03U) /*!< GPIO event pin 3 */
+#define GPIO_EVENT_PIN_4 ((uint8_t)0x04U) /*!< GPIO event pin 4 */
+#define GPIO_EVENT_PIN_5 ((uint8_t)0x05U) /*!< GPIO event pin 5 */
+#define GPIO_EVENT_PIN_6 ((uint8_t)0x06U) /*!< GPIO event pin 6 */
+#define GPIO_EVENT_PIN_7 ((uint8_t)0x07U) /*!< GPIO event pin 7 */
+#define GPIO_EVENT_PIN_8 ((uint8_t)0x08U) /*!< GPIO event pin 8 */
+#define GPIO_EVENT_PIN_9 ((uint8_t)0x09U) /*!< GPIO event pin 9 */
+#define GPIO_EVENT_PIN_10 ((uint8_t)0x0AU) /*!< GPIO event pin 10 */
+#define GPIO_EVENT_PIN_11 ((uint8_t)0x0BU) /*!< GPIO event pin 11 */
+#define GPIO_EVENT_PIN_12 ((uint8_t)0x0CU) /*!< GPIO event pin 12 */
+#define GPIO_EVENT_PIN_13 ((uint8_t)0x0DU) /*!< GPIO event pin 13 */
+#define GPIO_EVENT_PIN_14 ((uint8_t)0x0EU) /*!< GPIO event pin 14 */
+#define GPIO_EVENT_PIN_15 ((uint8_t)0x0FU) /*!< GPIO event pin 15 */
+
+/* GPIO output pin source definitions */
+#define GPIO_PIN_SOURCE_0 ((uint8_t)0x00U) /*!< GPIO pin source 0 */
+#define GPIO_PIN_SOURCE_1 ((uint8_t)0x01U) /*!< GPIO pin source 1 */
+#define GPIO_PIN_SOURCE_2 ((uint8_t)0x02U) /*!< GPIO pin source 2 */
+#define GPIO_PIN_SOURCE_3 ((uint8_t)0x03U) /*!< GPIO pin source 3 */
+#define GPIO_PIN_SOURCE_4 ((uint8_t)0x04U) /*!< GPIO pin source 4 */
+#define GPIO_PIN_SOURCE_5 ((uint8_t)0x05U) /*!< GPIO pin source 5 */
+#define GPIO_PIN_SOURCE_6 ((uint8_t)0x06U) /*!< GPIO pin source 6 */
+#define GPIO_PIN_SOURCE_7 ((uint8_t)0x07U) /*!< GPIO pin source 7 */
+#define GPIO_PIN_SOURCE_8 ((uint8_t)0x08U) /*!< GPIO pin source 8 */
+#define GPIO_PIN_SOURCE_9 ((uint8_t)0x09U) /*!< GPIO pin source 9 */
+#define GPIO_PIN_SOURCE_10 ((uint8_t)0x0AU) /*!< GPIO pin source 10 */
+#define GPIO_PIN_SOURCE_11 ((uint8_t)0x0BU) /*!< GPIO pin source 11 */
+#define GPIO_PIN_SOURCE_12 ((uint8_t)0x0CU) /*!< GPIO pin source 12 */
+#define GPIO_PIN_SOURCE_13 ((uint8_t)0x0DU) /*!< GPIO pin source 13 */
+#define GPIO_PIN_SOURCE_14 ((uint8_t)0x0EU) /*!< GPIO pin source 14 */
+#define GPIO_PIN_SOURCE_15 ((uint8_t)0x0FU) /*!< GPIO pin source 15 */
+
+/* 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 BITS(0,15) /*!< GPIO pin all */
+
+/* AFIO remap */
+#define PCF0_USART2_REMAP(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) /*!< USART2 remapping */
+#define PCF0_TIMER0_REMAP(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) /*!< TIMER0 remapping */
+#define PCF0_TIMER1_REMAP(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) /*!< TIMER1 remapping */
+#define PCF0_TIMER2_REMAP(regval) (BITS(10,11) & ((uint32_t)(regval) << 10)) /*!< TIMER2 remapping */
+#define PCF0_CAN_REMAP(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) /*!< CAN remapping */
+#define PCF0_SWJ_CFG(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) /*!< serial wire JTAG configuration */
+#define PCF1_CTC_REMAP(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) /*!< CTC remapping */
+
+/* GPIO remap definitions */
+#define GPIO_SPI0_REMAP AFIO_PCF0_SPI0_REMAP /*!< SPI0 remapping */
+#define GPIO_I2C0_REMAP AFIO_PCF0_I2C0_REMAP /*!< I2C0 remapping */
+#define GPIO_USART0_REMAP AFIO_PCF0_USART0_REMAP /*!< USART0 remapping */
+#define GPIO_USART1_REMAP AFIO_PCF0_USART1_REMAP /*!< USART1 remapping */
+#define GPIO_USART2_PARTIAL_REMAP ((uint32_t)0x00140000U | PCF0_USART2_REMAP(1)) /*!< USART2 partial remapping */
+#define GPIO_USART2_FULL_REMAP ((uint32_t)0x00140000U | PCF0_USART2_REMAP(3)) /*!< USART2 full remapping */
+#define GPIO_TIMER0_PARTIAL_REMAP ((uint32_t)0x00160000U | PCF0_TIMER0_REMAP(1)) /*!< TIMER0 partial remapping */
+#define GPIO_TIMER0_FULL_REMAP ((uint32_t)0x00160000U | PCF0_TIMER0_REMAP(3)) /*!< TIMER0 full remapping */
+#define GPIO_TIMER1_PARTIAL_REMAP0 ((uint32_t)0x00180000U | PCF0_TIMER1_REMAP(1)) /*!< TIMER1 partial remapping */
+#define GPIO_TIMER1_PARTIAL_REMAP1 ((uint32_t)0x00180000U | PCF0_TIMER1_REMAP(2)) /*!< TIMER1 partial remapping */
+#define GPIO_TIMER1_FULL_REMAP ((uint32_t)0x00180000U | PCF0_TIMER1_REMAP(3)) /*!< TIMER1 full remapping */
+#define GPIO_TIMER2_PARTIAL_REMAP ((uint32_t)0x001A0000U | PCF0_TIMER2_REMAP(2)) /*!< TIMER2 partial remapping */
+#define GPIO_TIMER2_FULL_REMAP ((uint32_t)0x001A0000U | PCF0_TIMER2_REMAP(3)) /*!< TIMER2 full remapping */
+#define GPIO_TIMER3_REMAP AFIO_PCF0_TIMER3_REMAP /*!< TIMER3 remapping */
+#define GPIO_PD01_REMAP AFIO_PCF0_PD01_REMAP /*!< PD01 remapping */
+#define GPIO_TIMER4CH3_IREMAP ((uint32_t)0x00200000U | (AFIO_PCF0_TIMER4CH3_IREMAP >> 16)) /*!< TIMER4 channel3 internal remapping */
+#define GPIO_ADC0_ETRGINS_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_ADC0_ETRGINS_REMAP >> 16)) /*!< ADC 0 external trigger inserted conversion remapping */
+#define GPIO_ADC0_ETRGREG_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_ADC0_ETRGREG_REMAP >> 16)) /*!< ADC 0 external trigger regular conversion remapping */
+#define GPIO_ADC1_ETRGINS_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_ADC1_ETRGINS_REMAP >> 16)) /*!< ADC 1 external trigger inserted conversion remapping */
+#define GPIO_ADC1_ETRGREG_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_ADC1_ETRGREG_REMAP >> 16)) /*!< ADC 1 external trigger regular conversion remapping */
+#define GPIO_SWJ_NONJTRST_REMAP ((uint32_t)0x00300000U | (PCF0_SWJ_CFG(1) >> 16)) /*!< full SWJ(JTAG-DP + SW-DP),but without NJTRST */
+#define GPIO_SWJ_SWDPENABLE_REMAP ((uint32_t)0x00300000U | (PCF0_SWJ_CFG(2) >> 16)) /*!< JTAG-DP disabled and SW-DP enabled */
+#define GPIO_SWJ_DISABLE_REMAP ((uint32_t)0x00300000U | (PCF0_SWJ_CFG(4) >> 16)) /*!< JTAG-DP disabled and SW-DP disabled */
+#define GPIO_CAN0_PARTIAL_REMAP ((uint32_t)0x001D0000U | PCF0_CAN_REMAP(2)) /*!< CAN0 partial remapping */
+#define GPIO_CAN0_FULL_REMAP ((uint32_t)0x001D0000U | PCF0_CAN_REMAP(3)) /*!< CAN0 full remapping */
+#define GPIO_CAN1_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_CAN1_REMAP >> 16)) /*!< CAN1 remapping */
+#define GPIO_SPI2_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_SPI2_REMAP >> 16)) /*!< SPI2 remapping */
+#define GPIO_TIMER1ITR0_REMAP ((uint32_t)0x00200000U | (AFIO_PCF0_TIMER1ITR0_REMAP >> 16)) /*!< TIMER1 internal trigger 0 remapping */
+#define GPIO_TIMER8_REMAP ((uint32_t)0x80000000U | AFIO_PCF1_TIMER8_REMAP) /*!< TIMER8 remapping */
+#define GPIO_EXMC_NADV_REMAP ((uint32_t)0x80000000U | AFIO_PCF1_EXMC_NADV) /*!< EXMC_NADV connect/disconnect */
+#define GPIO_CTC_REMAP0 ((uint32_t)0x801B0000U | PCF1_CTC_REMAP(1)) /*!< CTC remapping(PD15)*/
+
+/* I/O compensation cell enable/disable */
+#define GPIO_COMPENSATION_ENABLE AFIO_CPSCTL_CPS_EN /*!< I/O compensation cell is enable */
+#define GPIO_COMPENSATION_DISABLE ((uint32_t)0x00000000U) /*!< I/O compensation cell is disable */
+
+/* function declarations */
+/* reset GPIO port */
+void gpio_deinit(uint32_t gpio_periph);
+/* reset alternate function I/O(AFIO) */
+void gpio_afio_deinit(void);
+/* GPIO parameter initialization */
+#ifdef GD_MBED_USED
+void gpio_para_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin);
+#else
+void gpio_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin);
+#endif
+/* 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);
+
+/* configure GPIO pin remap */
+void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue);
+
+/* select GPIO pin exti sources */
+void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin);
+/* configure GPIO pin event output */
+void gpio_event_output_config(uint8_t output_port, uint8_t output_pin);
+/* enable GPIO pin event output */
+void gpio_event_output_enable(void);
+/* disable GPIO pin event output */
+void gpio_event_output_disable(void);
+
+/* lock GPIO pin bit */
+void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin);
+
+/* configure the I/O compensation cell */
+void gpio_compensation_config(uint32_t compensation);
+/* check the I/O compensation cell is ready or not */
+FlagStatus gpio_compensation_flag_get(void);
+
+#endif /* GD32E10X_GPIO_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_i2c.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_i2c.h
new file mode 100644
index 0000000000..e54adf7519
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_i2c.h
@@ -0,0 +1,427 @@
+/*!
+ \file gd32e10x_i2c.h
+ \brief definitions for the I2C
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_I2C_H
+#define GD32E10X_I2C_H
+
+#include "gd32e10x.h"
+
+/* I2Cx(x=0,1) definitions */
+#define I2C0 I2C_BASE /*!< I2C0 base address */
+#define I2C1 (I2C_BASE + 0x00000400U) /*!< I2C1 base address */
+
+/* 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_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */
+#define I2C_FMPCFG(i2cx) REG32((i2cx) + 0x90U) /*!< I2C fast-mode-plus configure 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_SS 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_TR 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_PECV BITS(8,15) /*!< packet error checking value */
+
+/* I2Cx_CKCFG */
+#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode or fast mode plus(master mode) */
+#define I2C_CKCFG_DTCY BIT(14) /*!< duty cycle of fast mode or fast mode plus */
+#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 or fast mode plus(master mode) */
+
+/* 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 */
+#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag */
+#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag */
+#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag */
+
+/* I2Cx_FMPCFG */
+#define I2C_FMPCFG_FMPEN BIT(0) /*!< fast mode plus enable bit */
+
+/* constants definitions */
+/* define the I2C bit position and its register index offset */
+#define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0xFFFFU) >> 6)))
+#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x1FU)
+#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\
+ | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)))
+#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22)))
+#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16)
+
+/* register offset */
+#define I2C_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */
+#define I2C_STAT0_REG_OFFSET 0x14U /*!< STAT0 register offset */
+#define I2C_STAT1_REG_OFFSET 0x18U /*!< STAT1 register offset */
+#define I2C_SAMCS_REG_OFFSET 0x80U /*!< SAMCS register offset */
+
+/* I2C flags */
+typedef enum {
+ /* flags in STAT0 register */
+ I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode */
+ I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode */
+ I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */
+ I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode */
+ I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode */
+ I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving */
+ I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting */
+ I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */
+ I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode */
+ I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error */
+ I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode */
+ I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data */
+ I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode */
+ I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status */
+ /* flags in STAT1 register */
+ I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U), /*!< a flag indicating whether I2C block is in master or slave mode */
+ I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U), /*!< busy flag */
+ I2C_FLAG_TRS = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U), /*!< whether the I2C is a transmitter or a receiver */
+ I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U), /*!< general call address (00h) received */
+ I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U), /*!< default address of SMBus device */
+ I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U), /*!< SMBus host header detected in slave mode */
+ I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U), /*!< dual flag in slave mode indicating which address is matched in dual-address mode */
+ /* flags in SAMCS register */
+ I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall flag */
+ I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise flag */
+ I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall flag */
+ I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise flag */
+} i2c_flag_enum;
+
+/* I2C interrupt flags */
+typedef enum {
+ /* interrupt flags in CTL1 register */
+ I2C_INT_FLAG_SBSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode interrupt flag */
+ I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode interrupt flag */
+ I2C_INT_FLAG_BTC = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */
+ I2C_INT_FLAG_ADD10SEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode interrupt flag */
+ I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode interrupt flag */
+ I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving interrupt flag */
+ I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting interrupt flag */
+ I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */
+ I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode interrupt flag */
+ I2C_INT_FLAG_AERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error interrupt flag */
+ I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode interrupt flag */
+ I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data interrupt flag */
+ I2C_INT_FLAG_SMBTO = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode interrupt flag */
+ I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus Alert status interrupt flag */
+ /* interrupt flags in SAMCS register */
+ I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall interrupt flag */
+ I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise interrupt flag */
+ I2C_INT_FLAG_RFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 6U, I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall interrupt flag */
+ I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise interrupt flag */
+} i2c_interrupt_flag_enum;
+
+/* I2C interrupt enable or disable */
+typedef enum {
+ /* interrupt in CTL1 register */
+ I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt enable */
+ I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt enable */
+ I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt enable */
+ /* interrupt in SAMCS register */
+ I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt enable */
+ I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt enable */
+ I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt enable */
+ I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt enable */
+} i2c_interrupt_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_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */
+#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */
+
+/* whether or not to send an ACK */
+#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */
+#define I2C_ACK_ENABLE ((uint32_t)0x00000001U) /*!< ACK will be sent */
+
+/* I2C POAP position*/
+#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */
+#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */
+
+/* I2C dual-address mode switch */
+#define I2C_DUADEN_DISABLE ((uint32_t)0x00000000U) /*!< dual-address mode disabled */
+#define I2C_DUADEN_ENABLE ((uint32_t)0x00000001U) /*!< 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_SS /*!< 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 enable */
+#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP disable */
+
+/* fast mode plus enable */
+#define I2C_FAST_MODE_PLUS_ENABLE I2C_FMPCFG_FMPEN /*!< fast mode plus enable */
+#define I2C_FAST_MODE_PLUS_DISABLE ((uint32_t)0x00000000U) /*!< fast mode plus disable */
+
+/* transmit I2C data */
+#define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0))
+
+/* receive I2C data */
+#define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7)
+
+/* I2C duty cycle in fast mode or fast mode plus */
+#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 2 */
+#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 16/9 */
+
+/* address mode for the I2C slave */
+#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */
+#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */
+
+#ifdef GD_MBED_USED
+#define SLAVE10_FIRST_BYTE(addr10) ((0xF0) | (uint8_t)((addr10 & 0x0300)>>7))
+#define SLAVE10_SECOND_BYTE(addr10) ((uint8_t)(addr10 & 0x00FF))
+
+typedef enum {
+ I2C_MODE_NONE = 0x00U, /*!< I2C device is idle */
+ I2C_MODE_MASTER = 0x10U, /*!< I2C device is in Master Mode */
+ I2C_MODE_SLAVE = 0x20U /*!< I2C device is in Slave Mode */
+} i2c_mode_enum;
+
+/* I2C state definitions */
+#define I2C_STATE_MSK ((uint32_t)((OP_STATE_BUSY_TX | OP_STATE_BUSY_RX) & (~(uint32_t)OP_STATE_BUSY)))
+#define I2C_STATE_NONE ((uint32_t)(I2C_MODE_NONE))
+#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((OP_STATE_BUSY_TX & I2C_STATE_MSK) | I2C_MODE_MASTER))
+#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((OP_STATE_BUSY_RX & I2C_STATE_MSK) | I2C_MODE_MASTER))
+#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((OP_STATE_BUSY_TX & I2C_STATE_MSK) | I2C_MODE_SLAVE))
+#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((OP_STATE_BUSY_RX & I2C_STATE_MSK) | I2C_MODE_SLAVE))
+
+#define I2C_FIRST_FRAME 0x00000001U
+#define I2C_NEXT_FRAME 0x00000002U
+#define I2C_FIRST_AND_LAST_FRAME 0x00000004U
+#define I2C_LAST_FRAME 0x00000008U
+#define I2C_NO_OPTION_FRAME 0xFFFF0000U
+
+#define I2C_DIRECTION_RECEIVE 0x00000000U
+#define I2C_DIRECTION_TRANSMIT 0x00000001U
+
+#define I2C_ERROR_NONE 0x00000000U /*!< no error */
+#define I2C_ERROR_BERR 0x00000001U /*!< BERR error */
+#define I2C_ERROR_LOSTARB 0x00000002U /*!< LOSTARB error */
+#define I2C_ERROR_AERR 0x00000004U /*!< AERR error */
+#define I2C_ERROR_OUERR 0x00000008U /*!< OUERR error */
+#define I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#define I2C_ERROR_TIMEOUT 0x00000020U /*!< timeout Error */
+
+#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< timeout 25 ms */
+#endif
+
+/* function declarations */
+/* reset I2C */
+void i2c_deinit(uint32_t i2c_periph);
+/* configure I2C clock */
+void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc);
+/* configure I2C address */
+void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, 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, uint32_t ack);
+/* configure I2C POAP position */
+void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos);
+/* master sends slave address */
+void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection);
+/* dual-address mode switch */
+void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_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_data_transmit(uint32_t i2c_periph, uint8_t data);
+/* I2C receive data function */
+uint8_t i2c_data_receive(uint32_t i2c_periph);
+/* enable I2C DMA mode */
+void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate);
+/* configure whether next DMA EOT is DMA last transfer or not */
+void i2c_dma_last_transfer_config(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);
+
+/* 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_get(uint32_t i2c_periph);
+/* I2C issue alert through SMBA pin */
+void i2c_smbus_issue_alert(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);
+
+/* 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);
+
+/* check I2C flag is set or not */
+FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag);
+/* clear I2C flag */
+void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag);
+/* enable I2C interrupt */
+void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt);
+/* disable I2C interrupt */
+void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt);
+/* check I2C interrupt flag */
+FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag);
+/* clear I2C interrupt flag */
+void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag);
+
+#endif /* GD32E10X_I2C_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_misc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_misc.h
new file mode 100644
index 0000000000..f3eb78b311
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_misc.h
@@ -0,0 +1,94 @@
+/*!
+ \file gd32e10x_misc.h
+ \brief definitions for the MISC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_MISC_H
+#define GD32E10X_MISC_H
+
+#include "gd32e10x.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 /* GD32E10X_MISC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_pmu.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_pmu.h
new file mode 100644
index 0000000000..9ea9ccfc0a
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_pmu.h
@@ -0,0 +1,138 @@
+/*!
+ \file gd32e10x_pmu.h
+ \brief definitions for the PMU
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_PMU_H
+#define GD32E10X_PMU_H
+
+#include "gd32e10x.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_LDOVS BITS(14,15) /*!< LDO output voltage select */
+
+/* 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_WUPEN BIT(8) /*!< wakeup pin enable */
+
+/* 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.1V */
+#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.6V */
+#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.7V */
+#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.9V */
+#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 3.0V */
+#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 3.1V */
+
+/* PMU LDO output voltage select definitions */
+#define CTL_LDOVS(regval) (BITS(14,15)&((uint32_t)(regval)<<14))
+#define PMU_LDOVS_NORMAL CTL_LDOVS(1) /*!< LDO output voltage select normal mode */
+#define PMU_LDOVS_LOW CTL_LDOVS(3) /*!< LDO output voltage select low mode */
+
+/* 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 */
+
+/* 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 registers */
+void pmu_deinit(void);
+
+/* select low voltage detector threshold */
+void pmu_lvd_select(uint32_t lvdt_n);
+/* select LDO output voltage */
+void pmu_ldo_output_select(uint32_t ldo_output);
+/* disable PMU lvd */
+void pmu_lvd_disable(void);
+
+/* 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 ldo, uint8_t deepsleepmodecmd);
+/* PMU work at standby mode */
+void pmu_to_standbymode(uint8_t standbymodecmd);
+
+/* wakeup pin related functions */
+/* enable PMU wakeup pin */
+void pmu_wakeup_pin_enable(void);
+/* disable PMU wakeup pin */
+void pmu_wakeup_pin_disable(void);
+
+/* backup related functions */
+/* enable write access to the registers in backup domain */
+void pmu_backup_write_enable(void);
+/* disable write access to the registers in backup domain */
+void pmu_backup_write_disable(void);
+
+/* flag functions */
+/* clear flag bit */
+void pmu_flag_clear(uint32_t flag_reset);
+/* get flag state */
+FlagStatus pmu_flag_get(uint32_t flag);
+
+#endif /* GD32E10X_PMU_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_rcu.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_rcu.h
new file mode 100644
index 0000000000..492e20c067
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_rcu.h
@@ -0,0 +1,818 @@
+/*!
+ \file gd32e10x_rcu.h
+ \brief definitions for the RCU
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_RCU_H
+#define GD32E10X_RCU_H
+
+#include "gd32e10x.h"
+
+/* RCU definitions */
+#define RCU RCU_BASE
+
+/* registers definitions */
+#define RCU_CTL REG32(RCU + 0x00U) /*!< control register */
+#define RCU_CFG0 REG32(RCU + 0x04U) /*!< clock configuration register 0 */
+#define RCU_INT REG32(RCU + 0x08U) /*!< clock interrupt register */
+#define RCU_APB2RST REG32(RCU + 0x0CU) /*!< APB2 reset register */
+#define RCU_APB1RST REG32(RCU + 0x10U) /*!< APB1 reset register */
+#define RCU_AHBEN REG32(RCU + 0x14U) /*!< AHB1 enable register */
+#define RCU_APB2EN REG32(RCU + 0x18U) /*!< APB2 enable register */
+#define RCU_APB1EN REG32(RCU + 0x1CU) /*!< APB1 enable register */
+#define RCU_BDCTL REG32(RCU + 0x20U) /*!< backup domain control register */
+#define RCU_RSTSCK REG32(RCU + 0x24U) /*!< reset source / clock register */
+#define RCU_AHBRST REG32(RCU + 0x28U) /*!< AHB reset register */
+#define RCU_CFG1 REG32(RCU + 0x2CU) /*!< clock configuration register 1 */
+#define RCU_DSV REG32(RCU + 0x34U) /*!< deep-sleep mode voltage register */
+#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 */
+
+/* bits definitions */
+/* RCU_CTL */
+#define RCU_CTL_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */
+#define RCU_CTL_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */
+#define RCU_CTL_IRC8MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */
+#define RCU_CTL_IRC8MCALIB 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_PLL1EN BIT(26) /*!< PLL1 enable */
+#define RCU_CTL_PLL1STB BIT(27) /*!< PLL1 clock stabilization flag */
+#define RCU_CTL_PLL2EN BIT(28) /*!< PLL2 enable */
+#define RCU_CTL_PLL2STB BIT(29) /*!< PLL2 clock stabilization flag */
+
+/* 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(8,10) /*!< APB1 prescaler selection */
+#define RCU_CFG0_APB2PSC BITS(11,13) /*!< APB2 prescaler selection */
+#define RCU_CFG0_ADCPSC BITS(14,15) /*!< ADC prescaler selection */
+#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */
+#define RCU_CFG0_PREDV0_LSB BIT(17) /*!< the LSB of PREDV0 division factor */
+#define RCU_CFG0_PLLMF BITS(18,21) /*!< PLL clock multiplication factor */
+#define RCU_CFG0_USBFSPSC BITS(22,23) /*!< USBFS clock prescaler selection */
+#define RCU_CFG0_CKOUT0SEL BITS(24,27) /*!< CKOUT0 clock source selection */
+#define RCU_CFG0_ADCPSC_2 BIT(28) /*!< bit 2 of ADCPSC */
+#define RCU_CFG0_PLLMF_4 BIT(29) /*!< bit 4 of PLLMF */
+#define RCU_CFG0_USBFSPSC_2 BIT(31) /*!< bit 2 of USBFSPSC */
+
+/* RCU_INT */
+#define RCU_INT_IRC40KSTBIF BIT(0) /*!< IRC40K stabilization interrupt flag */
+#define RCU_INT_LXTALSTBIF BIT(1) /*!< LXTAL stabilization interrupt flag */
+#define RCU_INT_IRC8MSTBIF BIT(2) /*!< IRC8M 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_PLL1STBIF BIT(5) /*!< PLL1 stabilization interrupt flag */
+#define RCU_INT_PLL2STBIF BIT(6) /*!< PLL2 stabilization interrupt flag */
+#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */
+#define RCU_INT_IRC40KSTBIE BIT(8) /*!< IRC40K stabilization interrupt enable */
+#define RCU_INT_LXTALSTBIE BIT(9) /*!< LXTAL stabilization interrupt enable */
+#define RCU_INT_IRC8MSTBIE BIT(10) /*!< IRC8M 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_PLL1STBIE BIT(13) /*!< PLL1 stabilization interrupt enable */
+#define RCU_INT_PLL2STBIE BIT(14) /*!< PLL2 stabilization interrupt enable */
+#define RCU_INT_IRC40KSTBIC BIT(16) /*!< IRC40K stabilization interrupt clear */
+#define RCU_INT_LXTALSTBIC BIT(17) /*!< LXTAL stabilization interrupt clear */
+#define RCU_INT_IRC8MSTBIC BIT(18) /*!< IRC8M 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_PLL1STBIC BIT(21) /*!< PLL1 stabilization interrupt clear */
+#define RCU_INT_PLL2STBIC BIT(22) /*!< PLL2 stabilization interrupt clear */
+#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */
+
+/* RCU_APB2RST */
+#define RCU_APB2RST_AFRST BIT(0) /*!< alternate function I/O reset */
+#define RCU_APB2RST_PARST BIT(2) /*!< GPIO port A reset */
+#define RCU_APB2RST_PBRST BIT(3) /*!< GPIO port B reset */
+#define RCU_APB2RST_PCRST BIT(4) /*!< GPIO port C reset */
+#define RCU_APB2RST_PDRST BIT(5) /*!< GPIO port D reset */
+#define RCU_APB2RST_PERST BIT(6) /*!< GPIO port E reset */
+#define RCU_APB2RST_ADC0RST BIT(9) /*!< ADC0 reset */
+#define RCU_APB2RST_ADC1RST BIT(10) /*!< ADC1 reset */
+#define RCU_APB2RST_TIMER0RST BIT(11) /*!< TIMER0 reset */
+#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */
+#define RCU_APB2RST_TIMER7RST BIT(13) /*!< TIMER7 reset */
+#define RCU_APB2RST_USART0RST BIT(14) /*!< USART0 reset */
+#define RCU_APB2RST_TIMER8RST BIT(19) /*!< TIMER8 reset */
+#define RCU_APB2RST_TIMER9RST BIT(20) /*!< TIMER9 reset */
+#define RCU_APB2RST_TIMER10RST BIT(21) /*!< TIMER10 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_CAN0RST BIT(25) /*!< CAN0 reset */
+#define RCU_APB1RST_CAN1RST BIT(26) /*!< CAN1 reset */
+#define RCU_APB1RST_BKPIRST BIT(27) /*!< backup interface reset */
+#define RCU_APB1RST_PMURST BIT(28) /*!< PMU reset */
+#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */
+
+/* RCU_AHBEN */
+#define RCU_AHBEN_DMA0EN BIT(0) /*!< DMA0 clock enable */
+#define RCU_AHBEN_DMA1EN BIT(1) /*!< DMA1 clock enable */
+#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM clock enable when sleep mode */
+#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable when sleep mode */
+#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */
+#define RCU_AHBEN_EXMCEN BIT(8) /*!< EXMC clock enable */
+#define RCU_AHBEN_USBFSEN BIT(12) /*!< USBFS clock enable */
+
+/* RCU_APB2EN */
+#define RCU_APB2EN_AFEN BIT(0) /*!< alternate function IO clock enable */
+#define RCU_APB2EN_PAEN BIT(2) /*!< GPIO port A clock enable */
+#define RCU_APB2EN_PBEN BIT(3) /*!< GPIO port B clock enable */
+#define RCU_APB2EN_PCEN BIT(4) /*!< GPIO port C clock enable */
+#define RCU_APB2EN_PDEN BIT(5) /*!< GPIO port D clock enable */
+#define RCU_APB2EN_PEEN BIT(6) /*!< GPIO port E clock enable */
+#define RCU_APB2EN_ADC0EN BIT(9) /*!< ADC0 clock enable */
+#define RCU_APB2EN_ADC1EN BIT(10) /*!< ADC1 clock enable */
+#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 clock enable */
+#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */
+#define RCU_APB2EN_TIMER7EN BIT(13) /*!< TIMER7 clock enable */
+#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */
+#define RCU_APB2EN_TIMER8EN BIT(19) /*!< TIMER8 clock enable */
+#define RCU_APB2EN_TIMER9EN BIT(20) /*!< TIMER9 clock enable */
+#define RCU_APB2EN_TIMER10EN BIT(21) /*!< TIMER10 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_CAN0EN BIT(25) /*!< CAN0 clock enable */
+#define RCU_APB1EN_CAN1EN BIT(26) /*!< CAN1 clock enable */
+#define RCU_APB1EN_BKPIEN BIT(27) /*!< backup interface clock enable */
+#define RCU_APB1EN_PMUEN BIT(28) /*!< PMU clock enable */
+#define RCU_APB1EN_DACEN BIT(29) /*!< DAC clock enable */
+
+/* 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 BITS(3,4) /*!< 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_IRC40KEN BIT(0) /*!< IRC40K enable */
+#define RCU_RSTSCK_IRC40KSTB BIT(1) /*!< IRC40K stabilization flag */
+#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */
+#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_AHBRST */
+#define RCU_AHBRST_USBFSRST BIT(12) /*!< USBFS reset */
+
+/* RCU_CFG1 */
+#define RCU_CFG1_PREDV0 BITS(0,3) /*!< PREDV0 division factor */
+#define RCU_CFG1_PREDV1 BITS(4,7) /*!< PREDV1 division factor */
+#define RCU_CFG1_PLL1MF BITS(8,11) /*!< PLL1 clock multiplication factor */
+#define RCU_CFG1_PLL2MF BITS(12,15) /*!< PLL2 clock multiplication factor */
+#define RCU_CFG1_PREDV0SEL BIT(16) /*!< PREDV0 input clock source selection */
+#define RCU_CFG1_I2S1SEL BIT(17) /*!< I2S1 clock source selection */
+#define RCU_CFG1_I2S2SEL BIT(18) /*!< I2S2 clock source selection */
+#define RCU_CFG1_ADCPSC_3 BIT(29) /*!< bit 4 of ADCPSC */
+#define RCU_CFG1_PLLPRESEL BIT(30) /*!< PLL clock source selection */
+
+/* RCU_DSV */
+#define RCU_DSV_DSLPVS BITS(0,1) /*!< deep-sleep mode voltage select */
+
+/* RCU_ADDCTL */
+#define RCU_ADDCTL_CK48MSEL BIT(0) /*!< 48MHz 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 */
+
+/* RCU_ADDAPB1EN */
+#define RCU_ADDAPB1EN_CTCEN BIT(27) /*!< CTC clock enable */
+
+
+/* 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)
+
+/* register offset */
+/* peripherals enable */
+#define AHBEN_REG_OFFSET 0x14U /*!< AHB enable register offset */
+#define APB1EN_REG_OFFSET 0x1CU /*!< APB1 enable register offset */
+#define APB2EN_REG_OFFSET 0x18U /*!< APB2 enable register offset */
+#define ADD_APB1EN_REG_OFFSET 0xE4U /*!< APB1 additional enable register offset */
+
+/* peripherals reset */
+#define AHBRST_REG_OFFSET 0x28U /*!< AHB reset register offset */
+#define APB1RST_REG_OFFSET 0x10U /*!< APB1 reset register offset */
+#define APB2RST_REG_OFFSET 0x0CU /*!< APB2 reset register offset */
+#define ADD_APB1RST_REG_OFFSET 0xE0U /*!< APB1 additional reset register offset */
+#define RSTSCK_REG_OFFSET 0x24U /*!< reset source/clock register offset */
+
+/* clock control */
+#define CTL_REG_OFFSET 0x00U /*!< control register offset */
+#define BDCTL_REG_OFFSET 0x20U /*!< backup domain control register offset */
+#define ADDCTL_REG_OFFSET 0xC0U /*!< additional clock control register offset */
+
+/* clock stabilization and stuck interrupt */
+#define INT_REG_OFFSET 0x08U /*!< clock interrupt register offset */
+#define ADDINT_REG_OFFSET 0xCCU /*!< additional clock interrupt register offset */
+
+/* configuration register */
+#define CFG0_REG_OFFSET 0x04U /*!< clock configuration register 0 offset */
+#define CFG1_REG_OFFSET 0x2CU /*!< clock configuration register 1 offset */
+
+/* peripheral clock enable */
+typedef enum {
+ /* AHB peripherals */
+ RCU_DMA0 = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 0U), /*!< DMA0 clock */
+ RCU_DMA1 = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 1U), /*!< DMA1 clock */
+ RCU_CRC = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 6U), /*!< CRC clock */
+ RCU_EXMC = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 8U), /*!< EXMC clock */
+ RCU_USBFS = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 12U), /*!< USBFS 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_CAN0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 25U), /*!< CAN0 clock */
+ RCU_CAN1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 26U), /*!< CAN1 clock */
+ RCU_BKPI = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 27U), /*!< BKPI clock */
+ RCU_PMU = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U), /*!< PMU clock */
+ RCU_DAC = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 29U), /*!< DAC clock */
+ RCU_RTC = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U), /*!< RTC clock */
+ RCU_CTC = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 27U), /*!< CTC clock */
+
+ /* APB2 peripherals */
+ RCU_AF = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 0U), /*!< alternate function clock */
+ RCU_GPIOA = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 2U), /*!< GPIOA clock */
+ RCU_GPIOB = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 3U), /*!< GPIOB clock */
+ RCU_GPIOC = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 4U), /*!< GPIOC clock */
+ RCU_GPIOD = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 5U), /*!< GPIOD clock */
+ RCU_GPIOE = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 6U), /*!< GPIOE clock */
+ RCU_ADC0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 9U), /*!< ADC0 clock */
+ RCU_ADC1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 10U), /*!< ADC1 clock */
+ RCU_TIMER0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 11U), /*!< TIMER0 clock */
+ RCU_SPI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U), /*!< SPI0 clock */
+ RCU_TIMER7 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 13U), /*!< TIMER7 clock */
+ RCU_USART0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 14U), /*!< USART0 clock */
+
+ RCU_TIMER8 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 19U), /*!< TIMER8 clock */
+ RCU_TIMER9 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 20U), /*!< TIMER9 clock */
+ RCU_TIMER10 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 21U), /*!< TIMER10 clock */
+
+} rcu_periph_enum;
+
+/* peripheral clock enable when sleep mode*/
+typedef enum {
+ /* AHB peripherals */
+ RCU_SRAM_SLP = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 2U), /*!< SRAM clock */
+ RCU_FMC_SLP = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 4U), /*!< FMC clock */
+} rcu_periph_sleep_enum;
+
+/* peripherals reset */
+typedef enum {
+ /* AHB peripherals */
+ RCU_USBFSRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 12U), /*!< USBFS 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_CAN0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 25U), /*!< CAN0 clock reset */
+ RCU_CAN1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 26U), /*!< CAN1 clock reset */
+ RCU_BKPIRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 27U), /*!< BKPI 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_CTCRST = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 27U), /*!< RTC clock reset */
+
+ /* APB2 peripherals */
+ RCU_AFRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 0U), /*!< alternate function clock reset */
+ RCU_GPIOARST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 2U), /*!< GPIOA clock reset */
+ RCU_GPIOBRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 3U), /*!< GPIOB clock reset */
+ RCU_GPIOCRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 4U), /*!< GPIOC clock reset */
+ RCU_GPIODRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 5U), /*!< GPIOD clock reset */
+ RCU_GPIOERST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 6U), /*!< GPIOE clock reset */
+ RCU_ADC0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 9U), /*!< ADC0 clock reset */
+ RCU_ADC1RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 10U), /*!< ADC1 clock reset */
+ RCU_TIMER0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 11U), /*!< TIMER0 clock reset */
+ RCU_SPI0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 12U), /*!< SPI0 clock reset */
+ RCU_TIMER7RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 13U), /*!< TIMER7 clock reset */
+ RCU_USART0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 14U), /*!< USART0 clock reset */
+ RCU_TIMER8RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 19U), /*!< TIMER8 clock reset */
+ RCU_TIMER9RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 20U), /*!< TIMER9 clock reset */
+ RCU_TIMER10RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 21U), /*!< TIMER10 clock reset */
+
+} rcu_periph_reset_enum;
+
+/* clock stabilization and peripheral reset flags */
+typedef enum {
+ /* clock stabilization flags */
+ RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 1U), /*!< IRC8M 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_PLL1STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 27U), /*!< PLL1 stabilization flags */
+ RCU_FLAG_PLL2STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 29U), /*!< PLL2 stabilization flags */
+ RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 1U), /*!< LXTAL stabilization flags */
+ RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U), /*!< IRC40K stabilization flags */
+ RCU_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 17U), /*!< IRC48M stabilization flags */
+ /* reset source 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_IRC40KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 0U), /*!< IRC40K 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_PLL1STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U), /*!< PLL1 stabilization interrupt flag */
+ RCU_INT_FLAG_PLL2STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< PLL2 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_IRC40KSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 16U), /*!< IRC40K stabilization interrupt flags clear */
+ RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 17U), /*!< LXTAL stabilization interrupt flags clear */
+ RCU_INT_FLAG_IRC8MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC8M 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_PLL1STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U), /*!< PLL1 stabilization interrupt flags clear */
+ RCU_INT_FLAG_PLL2STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< PLL2 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_IRC40KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 8U), /*!< IRC40K stabilization interrupt */
+ RCU_INT_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 9U), /*!< LXTAL stabilization interrupt */
+ RCU_INT_IRC8MSTB = 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_PLL1STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U), /*!< PLL1 stabilization interrupt */
+ RCU_INT_PLL2STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U), /*!< PLL2 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_IRC8M = RCU_REGIDX_BIT(CTL_REG_OFFSET, 0U), /*!< IRC8M */
+ RCU_IRC48M = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 16U), /*!< IRC48M */
+ RCU_IRC40K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC40K */
+ RCU_PLL_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U), /*!< PLL */
+ RCU_PLL1_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 26U), /*!< PLL1 */
+ RCU_PLL2_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 28U), /*!< PLL2 */
+} 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_IRC8M CFG0_SCS(0) /*!< system clock source select IRC8M */
+#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */
+#define RCU_CKSYSSRC_PLL CFG0_SCS(2) /*!< system clock source select PLL */
+
+/* system clock source select status */
+#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define RCU_SCSS_IRC8M CFG0_SCSS(0) /*!< system clock source select IRC8M */
+#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */
+#define RCU_SCSS_PLL 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(8,10) & ((uint32_t)(regval) << 8))
+#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(11,13) & ((uint32_t)(regval) << 11))
+#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 */
+
+/* ADC prescaler select */
+#define RCU_CKADC_CKAPB2_DIV2 ((uint32_t)0x00000000U) /*!< ADC prescaler select CK_APB2/2 */
+#define RCU_CKADC_CKAPB2_DIV4 ((uint32_t)0x00000001U) /*!< ADC prescaler select CK_APB2/4 */
+#define RCU_CKADC_CKAPB2_DIV6 ((uint32_t)0x00000002U) /*!< ADC prescaler select CK_APB2/6 */
+#define RCU_CKADC_CKAPB2_DIV8 ((uint32_t)0x00000003U) /*!< ADC prescaler select CK_APB2/8 */
+#define RCU_CKADC_CKAPB2_DIV12 ((uint32_t)0x00000005U) /*!< ADC prescaler select CK_APB2/12 */
+#define RCU_CKADC_CKAPB2_DIV16 ((uint32_t)0x00000007U) /*!< ADC prescaler select CK_APB2/16 */
+#define RCU_CKADC_CKAHB_DIV3 ((uint32_t)0x00000008U) /*!< ADC prescaler select CK_AHB/3 */
+#define RCU_CKADC_CKAHB_DIV5 ((uint32_t)0x00000009U) /*!< ADC prescaler select CK_AHB/5 */
+#define RCU_CKADC_CKAHB_DIV7 ((uint32_t)0x0000000AU) /*!< ADC prescaler select CK_AHB/7 */
+#define RCU_CKADC_CKAHB_DIV9 ((uint32_t)0x0000000BU) /*!< ADC prescaler select CK_AHB/9 */
+
+/* PLL clock source selection */
+#define RCU_PLLSRC_IRC8M_DIV2 ((uint32_t)0x00000000U) /*!< IRC8M/2 clock selected as source clock of PLL */
+#define RCU_PLLSRC_HXTAL_IRC48M RCU_CFG0_PLLSEL /*!< HXTAL or IRC48M selected as source clock of PLL */
+
+/* PLL clock multiplication factor */
+#define PLLMF_4 RCU_CFG0_PLLMF_4 /* bit 4 of PLLMF */
+
+#define CFG0_PLLMF(regval) (BITS(18,21) & ((uint32_t)(regval) << 18))
+#define RCU_PLL_MUL2 CFG0_PLLMF(0) /*!< PLL source clock multiply by 2 */
+#define RCU_PLL_MUL3 CFG0_PLLMF(1) /*!< PLL source clock multiply by 3 */
+#define RCU_PLL_MUL4 CFG0_PLLMF(2) /*!< PLL source clock multiply by 4 */
+#define RCU_PLL_MUL5 CFG0_PLLMF(3) /*!< PLL source clock multiply by 5 */
+#define RCU_PLL_MUL6 CFG0_PLLMF(4) /*!< PLL source clock multiply by 6 */
+#define RCU_PLL_MUL7 CFG0_PLLMF(5) /*!< PLL source clock multiply by 7 */
+#define RCU_PLL_MUL8 CFG0_PLLMF(6) /*!< PLL source clock multiply by 8 */
+#define RCU_PLL_MUL9 CFG0_PLLMF(7) /*!< PLL source clock multiply by 9 */
+#define RCU_PLL_MUL10 CFG0_PLLMF(8) /*!< PLL source clock multiply by 10 */
+#define RCU_PLL_MUL11 CFG0_PLLMF(9) /*!< PLL source clock multiply by 11 */
+#define RCU_PLL_MUL12 CFG0_PLLMF(10) /*!< PLL source clock multiply by 12 */
+#define RCU_PLL_MUL13 CFG0_PLLMF(11) /*!< PLL source clock multiply by 13 */
+#define RCU_PLL_MUL14 CFG0_PLLMF(12) /*!< PLL source clock multiply by 14 */
+#define RCU_PLL_MUL6_5 CFG0_PLLMF(13) /*!< PLL source clock multiply by 6.5 */
+#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL source clock multiply by 16 */
+#define RCU_PLL_MUL17 (PLLMF_4 | CFG0_PLLMF(0)) /*!< PLL source clock multiply by 17 */
+#define RCU_PLL_MUL18 (PLLMF_4 | CFG0_PLLMF(1)) /*!< PLL source clock multiply by 18 */
+#define RCU_PLL_MUL19 (PLLMF_4 | CFG0_PLLMF(2)) /*!< PLL source clock multiply by 19 */
+#define RCU_PLL_MUL20 (PLLMF_4 | CFG0_PLLMF(3)) /*!< PLL source clock multiply by 20 */
+#define RCU_PLL_MUL21 (PLLMF_4 | CFG0_PLLMF(4)) /*!< PLL source clock multiply by 21 */
+#define RCU_PLL_MUL22 (PLLMF_4 | CFG0_PLLMF(5)) /*!< PLL source clock multiply by 22 */
+#define RCU_PLL_MUL23 (PLLMF_4 | CFG0_PLLMF(6)) /*!< PLL source clock multiply by 23 */
+#define RCU_PLL_MUL24 (PLLMF_4 | CFG0_PLLMF(7)) /*!< PLL source clock multiply by 24 */
+#define RCU_PLL_MUL25 (PLLMF_4 | CFG0_PLLMF(8)) /*!< PLL source clock multiply by 25 */
+#define RCU_PLL_MUL26 (PLLMF_4 | CFG0_PLLMF(9)) /*!< PLL source clock multiply by 26 */
+#define RCU_PLL_MUL27 (PLLMF_4 | CFG0_PLLMF(10)) /*!< PLL source clock multiply by 27 */
+#define RCU_PLL_MUL28 (PLLMF_4 | CFG0_PLLMF(11)) /*!< PLL source clock multiply by 28 */
+#define RCU_PLL_MUL29 (PLLMF_4 | CFG0_PLLMF(12)) /*!< PLL source clock multiply by 29 */
+#define RCU_PLL_MUL30 (PLLMF_4 | CFG0_PLLMF(13)) /*!< PLL source clock multiply by 30 */
+#define RCU_PLL_MUL31 (PLLMF_4 | CFG0_PLLMF(14)) /*!< PLL source clock multiply by 31 */
+
+#define USBPSC_2 RCU_CFG0_USBFSPSC_2
+
+/* USBD/USBFS prescaler select */
+#define CFG0_USBPSC(regval) (BITS(22,23) & ((uint32_t)(regval) << 22))
+#define RCU_CKUSB_CKPLL_DIV1_5 CFG0_USBPSC(0) /*!< USBFS prescaler select CK_PLL/1.5 */
+#define RCU_CKUSB_CKPLL_DIV1 CFG0_USBPSC(1) /*!< USBFS prescaler select CK_PLL/1 */
+#define RCU_CKUSB_CKPLL_DIV2_5 CFG0_USBPSC(2) /*!< USBFS prescaler select CK_PLL/2.5 */
+#define RCU_CKUSB_CKPLL_DIV2 CFG0_USBPSC(3) /*!< USBFS prescaler select CK_PLL/2 */
+#define RCU_CKUSB_CKPLL_DIV3 (USBPSC_2 |CFG0_USBPSC(0)) /*!< USBFS prescaler select CK_PLL/3.5 */
+#define RCU_CKUSB_CKPLL_DIV3_5 (USBPSC_2 |CFG0_USBPSC(1)) /*!< USBFS prescaler select CK_PLL/3 */
+#define RCU_CKUSB_CKPLL_DIV4 (USBPSC_2 |CFG0_USBPSC(2)) /*!< USBFS prescaler select CK_PLL/4 */
+
+/* CKOUT0 Clock source selection */
+#define CFG0_CKOUT0SEL(regval) (BITS(24,27) & ((uint32_t)(regval) << 24))
+#define RCU_CKOUT0SRC_NONE CFG0_CKOUT0SEL(0) /*!< no clock selected */
+#define RCU_CKOUT0SRC_CKSYS CFG0_CKOUT0SEL(4) /*!< system clock selected */
+#define RCU_CKOUT0SRC_IRC8M CFG0_CKOUT0SEL(5) /*!< internal 8M RC oscillator clock selected */
+#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(6) /*!< high speed crystal oscillator clock (HXTAL) selected */
+#define RCU_CKOUT0SRC_CKPLL_DIV2 CFG0_CKOUT0SEL(7) /*!< CK_PLL/2 clock selected */
+#define RCU_CKOUT0SRC_CKPLL1 CFG0_CKOUT0SEL(8) /*!< CK_PLL1 clock selected */
+#define RCU_CKOUT0SRC_CKPLL2_DIV2 CFG0_CKOUT0SEL(9) /*!< CK_PLL2/2 clock selected */
+#define RCU_CKOUT0SRC_CKPLL2 CFG0_CKOUT0SEL(11) /*!< CK_PLL2 clock selected */
+#define RCU_CKOUT0SRC_IRC48M CFG0_CKOUT0SEL(12) /*!< IRC48M clock selected */
+#define RCU_CKOUT0SRC_IRC48M_DIV8 CFG0_CKOUT0SEL(13) /*!< IRC48M/8 clock selected */
+
+/* LXTAL drive capability */
+#define BDCTL_LXTALDRI(regval) (BITS(3,4) & ((uint32_t)(regval) << 3))
+#define RCU_LXTAL_LOWDRI BDCTL_LXTALDRI(0) /*!< lower driving capability */
+#define RCU_LXTAL_MED_LOWDRI BDCTL_LXTALDRI(1) /*!< medium low driving capability */
+#define RCU_LXTAL_MED_HIGHDRI BDCTL_LXTALDRI(2) /*!< medium high driving capability */
+#define RCU_LXTAL_HIGHDRI BDCTL_LXTALDRI(3) /*!< higher driving capability */
+
+/* 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_IRC40K BDCTL_RTCSRC(2) /*!< RTC source clock select IRC40K */
+#define RCU_RTCSRC_HXTAL_DIV_128 BDCTL_RTCSRC(3) /*!< RTC source clock select HXTAL/128 */
+
+/* PREDV0 division factor */
+#define CFG1_PREDV0(regval) (BITS(0,3) & ((uint32_t)(regval) << 0))
+#define RCU_PREDV0_DIV1 CFG1_PREDV0(0) /*!< PREDV0 input source clock not divided */
+#define RCU_PREDV0_DIV2 CFG1_PREDV0(1) /*!< PREDV0 input source clock divided by 2 */
+#define RCU_PREDV0_DIV3 CFG1_PREDV0(2) /*!< PREDV0 input source clock divided by 3 */
+#define RCU_PREDV0_DIV4 CFG1_PREDV0(3) /*!< PREDV0 input source clock divided by 4 */
+#define RCU_PREDV0_DIV5 CFG1_PREDV0(4) /*!< PREDV0 input source clock divided by 5 */
+#define RCU_PREDV0_DIV6 CFG1_PREDV0(5) /*!< PREDV0 input source clock divided by 6 */
+#define RCU_PREDV0_DIV7 CFG1_PREDV0(6) /*!< PREDV0 input source clock divided by 7 */
+#define RCU_PREDV0_DIV8 CFG1_PREDV0(7) /*!< PREDV0 input source clock divided by 8 */
+#define RCU_PREDV0_DIV9 CFG1_PREDV0(8) /*!< PREDV0 input source clock divided by 9 */
+#define RCU_PREDV0_DIV10 CFG1_PREDV0(9) /*!< PREDV0 input source clock divided by 10 */
+#define RCU_PREDV0_DIV11 CFG1_PREDV0(10) /*!< PREDV0 input source clock divided by 11 */
+#define RCU_PREDV0_DIV12 CFG1_PREDV0(11) /*!< PREDV0 input source clock divided by 12 */
+#define RCU_PREDV0_DIV13 CFG1_PREDV0(12) /*!< PREDV0 input source clock divided by 13 */
+#define RCU_PREDV0_DIV14 CFG1_PREDV0(13) /*!< PREDV0 input source clock divided by 14 */
+#define RCU_PREDV0_DIV15 CFG1_PREDV0(14) /*!< PREDV0 input source clock divided by 15 */
+#define RCU_PREDV0_DIV16 CFG1_PREDV0(15) /*!< PREDV0 input source clock divided by 16 */
+
+/* PREDV1 division factor */
+#define CFG1_PREDV1(regval) (BITS(4,7) & ((uint32_t)(regval) << 4))
+#define RCU_PREDV1_DIV1 CFG1_PREDV1(0) /*!< PREDV1 input source clock not divided */
+#define RCU_PREDV1_DIV2 CFG1_PREDV1(1) /*!< PREDV1 input source clock divided by 2 */
+#define RCU_PREDV1_DIV3 CFG1_PREDV1(2) /*!< PREDV1 input source clock divided by 3 */
+#define RCU_PREDV1_DIV4 CFG1_PREDV1(3) /*!< PREDV1 input source clock divided by 4 */
+#define RCU_PREDV1_DIV5 CFG1_PREDV1(4) /*!< PREDV1 input source clock divided by 5 */
+#define RCU_PREDV1_DIV6 CFG1_PREDV1(5) /*!< PREDV1 input source clock divided by 6 */
+#define RCU_PREDV1_DIV7 CFG1_PREDV1(6) /*!< PREDV1 input source clock divided by 7 */
+#define RCU_PREDV1_DIV8 CFG1_PREDV1(7) /*!< PREDV1 input source clock divided by 8 */
+#define RCU_PREDV1_DIV9 CFG1_PREDV1(8) /*!< PREDV1 input source clock divided by 9 */
+#define RCU_PREDV1_DIV10 CFG1_PREDV1(9) /*!< PREDV1 input source clock divided by 10 */
+#define RCU_PREDV1_DIV11 CFG1_PREDV1(10) /*!< PREDV1 input source clock divided by 11 */
+#define RCU_PREDV1_DIV12 CFG1_PREDV1(11) /*!< PREDV1 input source clock divided by 12 */
+#define RCU_PREDV1_DIV13 CFG1_PREDV1(12) /*!< PREDV1 input source clock divided by 13 */
+#define RCU_PREDV1_DIV14 CFG1_PREDV1(13) /*!< PREDV1 input source clock divided by 14 */
+#define RCU_PREDV1_DIV15 CFG1_PREDV1(14) /*!< PREDV1 input source clock divided by 15 */
+#define RCU_PREDV1_DIV16 CFG1_PREDV1(15) /*!< PREDV1 input source clock divided by 16 */
+
+/* PLL1 clock multiplication factor */
+#define CFG1_PLL1MF(regval) (BITS(8,11) & ((uint32_t)(regval) << 8))
+#define RCU_PLL1_MUL8 CFG1_PLL1MF(6) /*!< PLL1 source clock multiply by 8 */
+#define RCU_PLL1_MUL9 CFG1_PLL1MF(7) /*!< PLL1 source clock multiply by 9 */
+#define RCU_PLL1_MUL10 CFG1_PLL1MF(8) /*!< PLL1 source clock multiply by 10 */
+#define RCU_PLL1_MUL11 CFG1_PLL1MF(9) /*!< PLL1 source clock multiply by 11 */
+#define RCU_PLL1_MUL12 CFG1_PLL1MF(10) /*!< PLL1 source clock multiply by 12 */
+#define RCU_PLL1_MUL13 CFG1_PLL1MF(11) /*!< PLL1 source clock multiply by 13 */
+#define RCU_PLL1_MUL14 CFG1_PLL1MF(12) /*!< PLL1 source clock multiply by 14 */
+#define RCU_PLL1_MUL16 CFG1_PLL1MF(14) /*!< PLL1 source clock multiply by 16 */
+#define RCU_PLL1_MUL20 CFG1_PLL1MF(15) /*!< PLL1 source clock multiply by 20 */
+
+/* PLL2 clock multiplication factor */
+#define CFG1_PLL2MF(regval) (BITS(12,15) & ((uint32_t)(regval) << 12))
+#define RCU_PLL2_MUL8 CFG1_PLL2MF(6) /*!< PLL2 source clock multiply by 8 */
+#define RCU_PLL2_MUL9 CFG1_PLL2MF(7) /*!< PLL2 source clock multiply by 9 */
+#define RCU_PLL2_MUL10 CFG1_PLL2MF(8) /*!< PLL2 source clock multiply by 10 */
+#define RCU_PLL2_MUL11 CFG1_PLL2MF(9) /*!< PLL2 source clock multiply by 11 */
+#define RCU_PLL2_MUL12 CFG1_PLL2MF(10) /*!< PLL2 source clock multiply by 12 */
+#define RCU_PLL2_MUL13 CFG1_PLL2MF(11) /*!< PLL2 source clock multiply by 13 */
+#define RCU_PLL2_MUL14 CFG1_PLL2MF(12) /*!< PLL2 source clock multiply by 14 */
+#define RCU_PLL2_MUL16 CFG1_PLL2MF(14) /*!< PLL2 source clock multiply by 16 */
+#define RCU_PLL2_MUL20 CFG1_PLL2MF(15) /*!< PLL2 source clock multiply by 20 */
+
+/* PREDV0 input clock source selection */
+#define RCU_PREDV0SRC_HXTAL_IRC48M ((uint32_t)0x00000000U) /*!< HXTAL or IRC48M selected as PREDV0 input source clock */
+#define RCU_PREDV0SRC_CKPLL1 RCU_CFG1_PREDV0SEL /*!< CK_PLL1 selected as PREDV0 input source clock */
+
+/* I2S1 clock source selection */
+#define RCU_I2S1SRC_CKSYS ((uint32_t)0x00000000U) /*!< system clock selected as I2S1 source clock */
+#define RCU_I2S1SRC_CKPLL2_MUL2 RCU_CFG1_I2S1SEL /*!< (CK_PLL2 x 2) selected as I2S1 source clock */
+
+/* I2S2 clock source selection */
+#define RCU_I2S2SRC_CKSYS ((uint32_t)0x00000000U) /*!< system clock selected as I2S2 source clock */
+#define RCU_I2S2SRC_CKPLL2_MUL2 RCU_CFG1_I2S2SEL /*!< (CK_PLL2 x 2) selected as I2S2 source clock */
+
+/* PLL input clock source selection */
+#define RCU_PLLPRESRC_HXTAL ((uint32_t)0x00000000U) /*!< HXTAL selected as PLL source clock */
+#define RCU_PLLPRESRC_IRC48M RCU_CFG1_PLLPRESEL /*!< CK_PLL selected as PREDV0 input source clock */
+
+/* deep-sleep mode voltage */
+#define DSV_DSLPVS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(0) /*!< core voltage is 1.0V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(1) /*!< core voltage is 0.9V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_0_8 DSV_DSLPVS(2) /*!< core voltage is 0.8V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(3) /*!< core voltage is 1.2V in deep-sleep mode */
+
+/* 48MHz clock selection */
+#define RCU_CK48MSRC_CKPLL ((uint32_t)0x00000000U) /*!< use CK_PLL clock */
+#define RCU_CK48MSRC_IRC48M RCU_ADDCTL_CK48MSEL /*!< select IRC48M clock */
+
+/* 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 domain */
+void rcu_bkp_reset_enable(void);
+/* disable the BKP domain 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);
+/* configure the PLL clock source selection and PLL multiply factor */
+void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul);
+/* configure the PLL clock source preselection */
+void rcu_pllpresel_config(uint32_t pll_presel);
+/* configure the PREDV0 division factor and clock source */
+void rcu_predv0_config(uint32_t predv0_source, uint32_t predv0_div);
+/* configure the PREDV1 division factor */
+void rcu_predv1_config(uint32_t predv1_div);
+/* configure the PLL1 clock */
+void rcu_pll1_config(uint32_t pll_mul);
+/* configure the PLL2 clock */
+void rcu_pll2_config(uint32_t pll_mul);
+
+/* configure the ADC division factor */
+void rcu_adc_clock_config(uint32_t adc_psc);
+/* configure the USBFS prescaler factor */
+void rcu_usb_clock_config(uint32_t usb_psc);
+/* configure the RTC clock source selection */
+void rcu_rtc_clock_config(uint32_t rtc_clock_source);
+/* configure the I2S1 clock source selection */
+void rcu_i2s1_clock_config(uint32_t i2s_clock_source);
+/* configure the I2S2 clock source selection */
+void rcu_i2s2_clock_config(uint32_t i2s_clock_source);
+/* configure the CK48M clock selection */
+void rcu_ck48m_clock_config(uint32_t ck48m_clock_source);
+
+
+/* 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 IRC8M adjust value */
+void rcu_irc8m_adjust_value_set(uint32_t irc8m_adjval);
+
+/* 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 /* GD32E10X_RCU_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_rtc.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_rtc.h
new file mode 100644
index 0000000000..5b29b24ec3
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_rtc.h
@@ -0,0 +1,151 @@
+/*!
+ \file gd32e10x_rtc.h
+ \brief definitions for the RTC
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_RTC_H
+#define GD32E10X_RTC_H
+
+#include "gd32e10x.h"
+
+/* RTC definitions */
+#define RTC RTC_BASE
+
+/* registers definitions */
+#define RTC_INTEN REG32(RTC + 0x00U) /*!< interrupt enable register */
+#define RTC_CTL REG32(RTC + 0x04U) /*!< control register */
+#define RTC_PSCH REG32(RTC + 0x08U) /*!< prescaler high register */
+#define RTC_PSCL REG32(RTC + 0x0CU) /*!< prescaler low register */
+#define RTC_DIVH REG32(RTC + 0x10U) /*!< divider high register */
+#define RTC_DIVL REG32(RTC + 0x14U) /*!< divider low register */
+#define RTC_CNTH REG32(RTC + 0x18U) /*!< counter high register */
+#define RTC_CNTL REG32(RTC + 0x1CU) /*!< counter low register */
+#define RTC_ALRMH REG32(RTC + 0x20U) /*!< alarm high register */
+#define RTC_ALRML REG32(RTC + 0x24U) /*!< alarm low register */
+
+/* bits definitions */
+/* RTC_INTEN */
+#define RTC_INTEN_SCIE BIT(0) /*!< second interrupt enable */
+#define RTC_INTEN_ALRMIE BIT(1) /*!< alarm interrupt enable */
+#define RTC_INTEN_OVIE BIT(2) /*!< overflow interrupt enable */
+
+/* RTC_CTL */
+#define RTC_CTL_SCIF BIT(0) /*!< second interrupt flag */
+#define RTC_CTL_ALRMIF BIT(1) /*!< alarm interrupt flag */
+#define RTC_CTL_OVIF BIT(2) /*!< overflow interrupt flag */
+#define RTC_CTL_RSYNF BIT(3) /*!< registers synchronized flag */
+#define RTC_CTL_CMF BIT(4) /*!< configuration mode flag */
+#define RTC_CTL_LWOFF BIT(5) /*!< last write operation finished flag */
+
+/* RTC_PSCH */
+#define RTC_PSCH_PSC BITS(0,3) /*!< prescaler high value */
+
+/* RTC_PSCL */
+#define RTC_PSCL_PSC BITS(0,15) /*!< prescaler low value */
+
+/* RTC_DIVH */
+#define RTC_DIVH_DIV BITS(0,3) /*!< divider high value */
+
+/* RTC_DIVL */
+#define RTC_DIVL_DIV BITS(0,15) /*!< divider low value */
+
+/* RTC_CNTH */
+#define RTC_CNTH_CNT BITS(0,15) /*!< counter high value */
+
+/* RTC_CNTL */
+#define RTC_CNTL_CNT BITS(0,15) /*!< counter low value */
+
+/* RTC_ALRMH */
+#define RTC_ALRMH_ALRM BITS(0,15) /*!< alarm high value */
+
+/* RTC_ALRML */
+#define RTC_ALRML_ALRM BITS(0,15) /*!< alarm low value */
+
+/* constants definitions */
+/* RTC interrupt enable or disable definitions */
+#define RTC_INT_SECOND RTC_INTEN_SCIE /*!< second interrupt enable */
+#define RTC_INT_ALARM RTC_INTEN_ALRMIE /*!< alarm interrupt enable */
+#define RTC_INT_OVERFLOW RTC_INTEN_OVIE /*!< overflow interrupt enable */
+
+/* RTC interrupt flag definitions */
+#define RTC_INT_FLAG_SECOND RTC_CTL_SCIF /*!< second interrupt flag */
+#define RTC_INT_FLAG_ALARM RTC_CTL_ALRMIF /*!< alarm interrupt flag */
+#define RTC_INT_FLAG_OVERFLOW RTC_CTL_OVIF /*!< overflow interrupt flag */
+
+/* RTC flag definitions */
+#define RTC_FLAG_SECOND RTC_CTL_SCIF /*!< second interrupt flag */
+#define RTC_FLAG_ALARM RTC_CTL_ALRMIF /*!< alarm interrupt flag */
+#define RTC_FLAG_OVERFLOW RTC_CTL_OVIF /*!< overflow interrupt flag */
+#define RTC_FLAG_RSYN RTC_CTL_RSYNF /*!< registers synchronized flag */
+#define RTC_FLAG_LWOF RTC_CTL_LWOFF /*!< last write operation finished flag */
+
+/* function declarations */
+/* initialization functions */
+/* enter RTC configuration mode */
+void rtc_configuration_mode_enter(void);
+/* exit RTC configuration mode */
+void rtc_configuration_mode_exit(void);
+/* set RTC counter value */
+void rtc_counter_set(uint32_t cnt);
+/* set RTC prescaler value */
+void rtc_prescaler_set(uint32_t psc);
+
+/* operation functions */
+/* wait RTC last write operation finished flag set */
+void rtc_lwoff_wait(void);
+/* wait RTC registers synchronized flag set */
+void rtc_register_sync_wait(void);
+/* set RTC alarm value */
+void rtc_alarm_config(uint32_t alarm);
+/* get RTC counter value */
+uint32_t rtc_counter_get(void);
+/* get RTC divider value */
+uint32_t rtc_divider_get(void);
+
+/* flag & interrupt functions */
+/* get RTC flag status */
+FlagStatus rtc_flag_get(uint32_t flag);
+/* clear RTC flag status */
+void rtc_flag_clear(uint32_t flag);
+/* get RTC interrupt flag status */
+FlagStatus rtc_interrupt_flag_get(uint32_t flag);
+/* clear RTC interrupt flag status */
+void rtc_interrupt_flag_clear(uint32_t flag);
+/* enable RTC interrupt */
+void rtc_interrupt_enable(uint32_t interrupt);
+/* disable RTC interrupt */
+void rtc_interrupt_disable(uint32_t interrupt);
+
+#endif /* GD32E10X_RTC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_spi.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_spi.h
new file mode 100644
index 0000000000..edbe9db9b1
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_spi.h
@@ -0,0 +1,366 @@
+/*!
+ \file gd32e10x_spi.h
+ \brief definitions for the SPI
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_SPI_H
+#define GD32E10X_SPI_H
+
+#include "gd32e10x.h"
+
+/* SPIx(x=0,1,2) definitions */
+#define SPI0 (SPI_BASE + 0x0000F800U)
+#define SPI1 SPI_BASE
+#define SPI2 (SPI_BASE + 0x00000400U)
+
+/* 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(only SPI1) */
+
+/* bits definitions */
+/* SPI_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 */
+
+/* SPI_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_NSSP BIT(3) /*!< SPI NSS pulse mode enable */
+#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 */
+
+/* SPI_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 bit */
+#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 bit */
+
+/* SPI_DATA */
+#define SPI_DATA_DATA BITS(0,15) /*!< data transfer register */
+
+/* SPI_CRCPOLY */
+#define SPI_CRCPOLY_CRCPOLY BITS(0,15) /*!< CRC polynomial value */
+
+/* SPI_RCRC */
+#define SPI_RCRC_RCRC BITS(0,15) /*!< RX CRC value */
+
+/* SPI_TCRC */
+#define SPI_TCRC_TCRC BITS(0,15) /*!< TX CRC value */
+
+/* SPI_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 */
+
+/* SPI_I2SPSC */
+#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 */
+
+/* SPI_QCTL(only for SPI1) */
+#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 mode definitions */
+#define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */
+#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */
+
+/* SPI bidirectional transfer direction */
+#define SPI_BIDIRECTIONAL_TRANSMIT SPI_CTL0_BDOEN /*!< SPI work in transmit-only mode */
+#define SPI_BIDIRECTIONAL_RECEIVE (~SPI_CTL0_BDOEN) /*!< SPI work in receive-only mode */
+
+/* SPI transmit type */
+#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*/
+
+/* SPI frame size */
+#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 */
+
+/* SPI NSS control mode */
+#define SPI_NSS_SOFT SPI_CTL0_SWNSSEN /*!< SPI NSS control by sofrware */
+#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI NSS control by hardware */
+
+/* SPI transmit way */
+#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 */
+
+/* SPI clock phase and polarity */
+#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 */
+
+/* SPI clock prescale factor */
+#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 audio sample rate */
+#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 */
+
+/* I2S frame format */
+#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 */
+
+/* I2S master clock output */
+#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */
+#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */
+
+/* I2S operation mode */
+#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 */
+
+/* I2S standard */
+#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 */
+
+/* I2S clock polarity */
+#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 use DMA */
+#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use 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/I2S interrupt enable/disable 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_ERR ((uint8_t)0x02U) /*!< error interrupt */
+
+/* SPI/I2S interrupt flag constants definitions */
+#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt flag */
+#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt flag */
+#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt flag */
+#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt flag */
+#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt flag */
+#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */
+#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */
+
+/* SPI/I2S 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 error 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 /*!< channel side flag */
+#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */
+#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error 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/I2S deinitialization and initialization functions */
+/* reset SPI and I2S */
+void spi_i2s_deinit(uint32_t spi_periph);
+/* initialize the parameters of SPI struct with the default values */
+void spi_struct_para_init(spi_parameter_struct *spi_struct);
+/* initialize SPI parameter */
+#ifdef GD_MBED_USED
+void spi_para_init(uint32_t spi_periph, spi_parameter_struct *spi_struct);
+#else
+void spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct);
+#endif
+/* enable SPI */
+void spi_enable(uint32_t spi_periph);
+/* disable SPI */
+void spi_disable(uint32_t spi_periph);
+
+/* initialize I2S parameter */
+void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl);
+/* configure I2S prescaler */
+void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout);
+/* enable I2S */
+void i2s_enable(uint32_t spi_periph);
+/* disable I2S */
+void i2s_disable(uint32_t spi_periph);
+
+/* NSS functions */
+/* enable SPI NSS output */
+void spi_nss_output_enable(uint32_t spi_periph);
+/* disable SPI NSS output */
+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);
+
+/* enable SPI DMA */
+void spi_dma_enable(uint32_t spi_periph, uint8_t dma);
+/* disable SPI DMA */
+void spi_dma_disable(uint32_t spi_periph, uint8_t dma);
+
+/* configure SPI/I2S data frame format */
+void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format);
+/* SPI transmit data */
+void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data);
+/* SPI 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);
+
+/* SPI CRC functions */
+/* set SPI CRC polynomial */
+void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly);
+/* get SPI CRC polynomial */
+uint16_t spi_crc_polynomial_get(uint32_t spi_periph);
+/* turn on SPI CRC function */
+void spi_crc_on(uint32_t spi_periph);
+/* turn off SPI CRC function */
+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 crc);
+
+/* SPI TI mode functions */
+/* enable SPI TI mode */
+void spi_ti_mode_enable(uint32_t spi_periph);
+/* disable SPI TI mode */
+void spi_ti_mode_disable(uint32_t spi_periph);
+
+/* SPI NSS pulse mode functions */
+/* enable SPI NSS pulse mode */
+void spi_nssp_mode_enable(uint32_t spi_periph);
+/* disable SPI NSS pulse mode */
+void spi_nssp_mode_disable(uint32_t spi_periph);
+
+/* quad wire SPI functions */
+/* enable quad wire SPI */
+void qspi_enable(uint32_t spi_periph);
+/* disable quad wire SPI */
+void qspi_disable(uint32_t spi_periph);
+/* enable quad wire SPI write */
+void qspi_write_enable(uint32_t spi_periph);
+/* enable quad wire SPI read */
+void qspi_read_enable(uint32_t spi_periph);
+/* enable quad wire SPI_IO2 and SPI_IO3 pin output */
+void qspi_io23_output_enable(uint32_t spi_periph);
+/* disable quad wire SPI_IO2 and SPI_IO3 pin output */
+void qspi_io23_output_disable(uint32_t spi_periph);
+
+/* flag and interrupt functions */
+/* enable SPI and I2S interrupt */
+void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt);
+/* disable SPI and I2S interrupt */
+void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt);
+/* get SPI and I2S interrupt status */
+FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt);
+/* get SPI and I2S flag status */
+FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag);
+/* clear SPI CRC error flag status */
+void spi_crc_error_clear(uint32_t spi_periph);
+
+#endif /* GD32E10X_SPI_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_timer.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_timer.h
new file mode 100644
index 0000000000..2385b59661
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_timer.h
@@ -0,0 +1,743 @@
+/*!
+ \file gd32e10x_timer.h
+ \brief definitions for the TIMER
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_TIMER_H
+#define GD32E10X_TIMER_H
+
+#include "gd32e10x.h"
+
+/* TIMERx(x=0..13) definitions */
+#define TIMER0 (TIMER_BASE + 0x00012C00U)
+#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 + 0x00013400U)
+#define TIMER8 (TIMER_BASE + 0x00014C00U)
+#define TIMER9 (TIMER_BASE + 0x00015000U)
+#define TIMER10 (TIMER_BASE + 0x00015400U)
+#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 channel complementary 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_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) /*!< commutation control shadow enable */
+#define TIMER_CTL1_CCUC BIT(2) /*!< commutation 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 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation interrupt 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(9) /*!< channel 0 capture/compare DMA request enable */
+#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 capture/compare DMA request enable */
+#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 capture/compare DMA request enable */
+#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 capture/compare DMA request enable */
+#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< commutation 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 capture/compare interrupt flag */
+#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 capture/compare interrupt flag */
+#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 capture/compare interrupt flag */
+#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 capture/compare 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 over capture flag */
+#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 over capture flag */
+#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 over capture flag */
+#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 over capture 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 control */
+#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 control */
+#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 control */
+#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 control */
+#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 capture/compare function enable */
+#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 capture/compare function 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 capture/compare function enable */
+#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 capture/compare function 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 capture/compare function enable */
+#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 capture/compare function 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 capture/compare function enable */
+#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 capture/compare function polarity */
+
+/* TIMER_CNT */
+#define TIMER_CNT_CNT BITS(0,15) /*!< 16 bit timer counter */
+
+/* TIMER_PSC */
+#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */
+
+/* TIMER_CAR */
+#define TIMER_CAR_CARL BITS(0,15) /*!< 16 bit counter auto reload value */
+
+/* TIMER_CREP */
+#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */
+
+/* TIMER_CH0CV */
+#define TIMER_CH0CV_CH0VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 0 */
+
+/* TIMER_CH1CV */
+#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */
+
+/* TIMER_CH2CV */
+#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */
+
+/* TIMER_CH3CV */
+#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< 16 bit 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_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 */
+ uint16_t ideloffstate; /*!< idle mode off-state */
+ uint16_t deadtime; /*!< dead time */
+ 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 {
+ uint16_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 enable or disable */
+#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */
+#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */
+#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */
+#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */
+#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 interrupt */
+#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */
+#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */
+#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */
+
+/* TIMER interrupt flag */
+#define TIMER_INT_FLAG_UP TIMER_INT_UP /*!< update interrupt */
+#define TIMER_INT_FLAG_CH0 TIMER_INT_CH0 /*!< channel 0 interrupt */
+#define TIMER_INT_FLAG_CH1 TIMER_INT_CH1 /*!< channel 1 interrupt */
+#define TIMER_INT_FLAG_CH2 TIMER_INT_CH2 /*!< channel 2 interrupt */
+#define TIMER_INT_FLAG_CH3 TIMER_INT_CH3 /*!< channel 3 interrupt */
+#define TIMER_INT_FLAG_CMT TIMER_INT_CMT /*!< channel commutation interrupt flag */
+#define TIMER_INT_FLAG_TRG TIMER_INT_TRG /*!< trigger interrupt */
+#define TIMER_INT_FLAG_BRK TIMER_INT_BRK
+
+/* TIMER flag */
+#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */
+#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 flag */
+#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 flag */
+#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 flag */
+#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 flag */
+#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel control update flag */
+#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */
+#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break flag */
+#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */
+#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */
+#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */
+#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */
+
+/* TIMER DMA source enable */
+#define TIMER_DMA_UPD ((uint16_t)TIMER_DMAINTEN_UPDEN) /*!< update DMA enable */
+#define TIMER_DMA_CH0D ((uint16_t)TIMER_DMAINTEN_CH0DEN) /*!< channel 0 DMA enable */
+#define TIMER_DMA_CH1D ((uint16_t)TIMER_DMAINTEN_CH1DEN) /*!< channel 1 DMA enable */
+#define TIMER_DMA_CH2D ((uint16_t)TIMER_DMAINTEN_CH2DEN) /*!< channel 2 DMA enable */
+#define TIMER_DMA_CH3D ((uint16_t)TIMER_DMAINTEN_CH3DEN) /*!< channel 3 DMA enable */
+#define TIMER_DMA_CMTD ((uint16_t)TIMER_DMAINTEN_CMTDEN) /*!< commutation DMA request enable */
+#define TIMER_DMA_TRGD ((uint16_t)TIMER_DMAINTEN_TRGDEN) /*!< trigger DMA enable */
+
+/* channel DMA request source selection */
+#define TIMER_DMAREQUEST_UPDATEEVENT TIMER_CTL1_DMAS /*!< DMA request of channel n is sent when update event occurs */
+#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000000U) /*!< DMA request of channel n is sent when channel n 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 */
+
+/* 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 TIMER_SWEVG_UPG /*!< the prescaler is loaded right now */
+#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000000U) /*!< 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)TIMER_CTL0_DIR) /*!< 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 TIMER_CTL0_SPM /*!< single pulse mode */
+#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000000U) /*!< repetitive pulse mode */
+
+/* update source */
+#define TIMER_UPDATE_SRC_REGULAR TIMER_CTL0_UPS /*!< update generate only by counter overflow/underflow */
+#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000000U) /*!< 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 ((uint16_t)TIMER_CCHP_ROS) /*!< 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 ((uint16_t)0x0000U) /*!< 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)TIMER_CCHP_IOS) /*!< 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)TIMER_CCHP_BRKP) /*!< break input polarity is high */
+
+/* output automatic enable */
+#define TIMER_OUTAUTO_ENABLE ((uint16_t)TIMER_CCHP_OAEN) /*!< 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)TIMER_CCHP_BRKEN) /*!< break input enable */
+#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */
+
+/* TIMER channel n(n=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 ((uint16_t)0x0001U) /*!< channel enable */
+#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< 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 ((uint32_t)0x00000000U) /*!< the shadow registers update by when CMTG bit is set */
+#define TIMER_UPDATECTL_CCUTRI TIMER_CTL1_CCUC /*!< 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(only for TIMER1~TIMER8) */
+
+/* TIMER input capture selection */
+#define TIMER_IC_SELECTION_DIRECTTI ((uint16_t)0x0001U) /*!< channel n is configured as input and icy is mapped on CIy */
+#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel n is configured as input and icy is mapped on opposite input */
+#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel n 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) /*!< filtered external trigger input */
+
+/* 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_CH0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channel 0 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 TIMER_SMCFG_MSM /*!< master slave mode enable */
+#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000000U) /*!< 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 TIMER_CTL1_TI0S /*!< TIMER hall sensor mode enable */
+#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode disable */
+
+/* TIMERx(x=0..4,7..13) write CHxVAL register selection */
+#define TIMER_CHVSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< write CHxVAL register selection enable */
+#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */
+
+/* TIMERx(x=0,7) output value selection */
+#define TIMER_OUTSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< output value selection enable */
+#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */
+
+/* function declarations */
+/* TIMER timebase */
+/* deinit a timer */
+void timer_deinit(uint32_t timer_periph);
+/* initialize TIMER init parameter struct */
+void timer_struct_para_init(timer_parameter_struct *initpara);
+/* initialize TIMER counter */
+void timer_init(uint32_t timer_periph, timer_parameter_struct *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 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 prescaler, uint32_t pscreload);
+/* configure TIMER repetition register value */
+void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition);
+/* configure TIMER autoreload register value */
+void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload);
+/* configure TIMER counter register value */
+void timer_counter_value_config(uint32_t timer_periph, uint16_t 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, uint32_t spmode);
+/* configure TIMER update source */
+void timer_update_source_config(uint32_t timer_periph, uint32_t update);
+
+/* TIMER DMA and event */
+/* enable the TIMER DMA */
+void timer_dma_enable(uint32_t timer_periph, uint16_t dma);
+/* disable the TIMER DMA */
+void timer_dma_disable(uint32_t timer_periph, uint16_t dma);
+/* channel DMA request source selection */
+void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_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 event);
+
+/* TIMER channel complementary protection */
+/* initialize TIMER break parameter struct */
+void timer_break_struct_para_init(timer_break_parameter_struct *breakpara);
+/* configure TIMER break function */
+void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara);
+/* 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);
+/* enable or disable TIMER primary output function */
+void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue);
+/* enable or disable channel capture/compare control shadow register */
+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, uint32_t ccuctl);
+
+/* TIMER channel output */
+/* initialize TIMER channel output parameter struct */
+void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara);
+/* configure TIMER channel output function */
+void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara);
+/* configure TIMER channel output compare mode */
+void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode);
+/* configure TIMER channel output pulse value */
+void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse);
+/* configure TIMER channel output shadow function */
+void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow);
+/* configure TIMER channel output fast function */
+void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast);
+/* configure TIMER channel output clear function */
+void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear);
+/* configure TIMER channel output polarity */
+void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity);
+/* configure TIMER channel complementary output polarity */
+void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity);
+/* configure TIMER channel enable state */
+void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state);
+/* configure TIMER channel complementary output enable state */
+void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate);
+
+/* TIMER channel input */
+/* initialize TIMER channel input parameter struct */
+void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara);
+/* configure TIMER input capture parameter */
+void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpara);
+/* configure TIMER channel input capture prescaler value */
+void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler);
+/* read TIMER channel capture compare register value */
+uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel);
+/* configure TIMER input pwm capture function */
+void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpwm);
+/* configure TIMER hall sensor mode */
+void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode);
+
+/* TIMER master and slave mode */
+/* select TIMER input trigger source */
+void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger);
+/* select TIMER master mode output trigger source */
+void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger);
+/* select TIMER slave mode */
+void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode);
+/* configure TIMER master slave mode */
+void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave);
+/* configure TIMER external trigger input */
+void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter);
+/* configure TIMER quadrature decoder mode */
+void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t 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 intrigger);
+/* configure TIMER the external trigger as external clock input */
+void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter);
+/* configure TIMER the external clock mode 0 */
+void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter);
+/* configure TIMER the external clock mode 1 */
+void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter);
+/* disable TIMER the external clock mode 1 */
+void timer_external_clock_mode1_disable(uint32_t timer_periph);
+
+/* TIMER configure */
+/* configure TIMER write CHxVAL register selection */
+void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel);
+/* configure TIMER output value selection */
+void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel);
+
+/* TIMER interrupt and flag */
+/* enable the TIMER interrupt */
+void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt);
+/* disable the TIMER interrupt */
+void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt);
+/* get TIMER interrupt flag */
+FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt);
+/* clear TIMER interrupt flag */
+void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt);
+/* get TIMER flag */
+FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag);
+/* clear TIMER flag */
+void timer_flag_clear(uint32_t timer_periph, uint32_t flag);
+
+#endif /* GD32E10X_TIMER_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_usart.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_usart.h
new file mode 100644
index 0000000000..084c004890
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_usart.h
@@ -0,0 +1,470 @@
+/*!
+ \file gd32e10x_usart.h
+ \brief definitions for the USART
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_USART_H
+#define GD32E10X_USART_H
+
+#include "gd32e10x.h"
+
+/* USARTx(x=0,1,2)/UARTx(x=3,4) definitions */
+#define USART1 USART_BASE /*!< USART1 base address */
+#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 USART0 (USART_BASE+0x0000F400U) /*!< USART0 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 */
+
+/* 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 */
+
+/* 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_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) & 0xFFFFU) >> 6)))
+#define USART_BIT_POS(val) ((uint32_t)(val) & 0x1FU)
+#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\
+ | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)))
+#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22)))
+#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16)
+
+/* register offset */
+#define USART_STAT0_REG_OFFSET 0x00U /*!< STAT0 register offset */
+#define USART_STAT1_REG_OFFSET 0x88U /*!< STAT1 register offset */
+#define USART_CTL0_REG_OFFSET 0x0CU /*!< CTL0 register offset */
+#define USART_CTL1_REG_OFFSET 0x10U /*!< CTL1 register offset */
+#define USART_CTL2_REG_OFFSET 0x14U /*!< CTL2 register offset */
+#define USART_CTL3_REG_OFFSET 0x80U /*!< CTL3 register offset */
+#define USART_CHC_REG_OFFSET 0xC0U /*!< CHC register offset */
+
+/* USART flags */
+typedef enum {
+ /* flags in STAT0 register */
+ USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 9U), /*!< CTS change flag */
+ USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 8U), /*!< LIN break detected flag */
+ USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 7U), /*!< transmit data buffer empty */
+ USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 6U), /*!< transmission complete */
+ USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 5U), /*!< read data buffer not empty */
+ USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 4U), /*!< IDLE frame detected flag */
+ USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 3U), /*!< overrun error */
+ USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 2U), /*!< noise error flag */
+ USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 1U), /*!< frame error flag */
+ USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 0U), /*!< parity error flag */
+ /* flags in STAT1 register */
+ USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 16U), /*!< busy flag */
+ USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 12U), /*!< end of block flag */
+ USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 11U), /*!< receiver timeout flag */
+ /* flags in CHC register */
+ USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */
+} usart_flag_enum;
+
+/* USART interrupt flags */
+typedef enum {
+ /* interrupt flags in CTL0 register */
+ USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT0_REG_OFFSET, 0U), /*!< parity error interrupt and flag */
+ USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */
+ USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT0_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */
+ USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag */
+ USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT0_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */
+ USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt and flag */
+ /* interrupt flags in CTL1 register */
+ USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT0_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */
+ /* interrupt flags in CTL2 register */
+ USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT0_REG_OFFSET, 9U), /*!< CTS interrupt and flag */
+ USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT0_REG_OFFSET, 3U), /*!< error interrupt and overrun error */
+ USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT0_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */
+ USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT0_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */
+ /* interrupt flags in CTL3 register */
+ USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL3_REG_OFFSET, 5U, USART_STAT1_REG_OFFSET, 12U), /*!< interrupt enable bit of end of block event and flag */
+ USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL3_REG_OFFSET, 4U, USART_STAT1_REG_OFFSET, 11U), /*!< interrupt enable bit of receive timeout event and flag */
+} usart_interrupt_flag_enum;
+
+/* USART interrupt enable or disable */
+typedef enum {
+ /* interrupt in CTL0 register */
+ USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */
+ USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */
+ USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */
+ USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt */
+ USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */
+ /* interrupt in CTL1 register */
+ USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */
+ /* interrupt in CTL2 register */
+ USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */
+ USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */
+ /* interrupt in CTL3 register */
+ USART_INT_EB = USART_REGIDX_BIT(USART_CTL3_REG_OFFSET, 5U), /*!< end of block interrupt */
+ USART_INT_RT = USART_REGIDX_BIT(USART_CTL3_REG_OFFSET, 4U), /*!< receive timeout interrupt */
+} usart_interrupt_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_EVEN CTL0_PM(2) /*!< even parity */
+#define USART_PM_ODD CTL0_PM(3) /*!< odd 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 match */
+
+/* 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 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 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 USART_MSBF_LSB ((uint32_t)0x00000000U) /*!< LSB first */
+#define USART_MSBF_MSB USART_CTL3_MSBF /*!< MSB first */
+
+/* USART hardware flow control coherence mode */
+#define USART_RTS_NONE_COHERENCE ((uint32_t)0x00000000U) /*!< nRTS signal equals to the RBNE bit in USART_STAT0 */
+#define USART_RTS_COHERENCE USART_CHC_HCM /*!< nRTS signal is set when the last data bit has been sampled */
+
+#ifdef GD_MBED_USED
+/* USART error code */
+#define USART_ERROR_CODE_NONE 0U /*!< no error */
+#define USART_ERROR_CODE_PERR BIT(0) /*!< parity error */
+#define USART_ERROR_CODE_NERR BIT(1) /*!< noise error */
+#define USART_ERROR_CODE_FERR BIT(2) /*!< frame error */
+#define USART_ERROR_CODE_ORERR BIT(3) /*!< overrun error */
+
+/* USART hardware control configuration */
+#define USART_HWCONTROL_NONE 0U
+#define USART_HWCONTROL_RTS USART_RTS_ENABLE
+#define USART_HWCONTROL_CTS USART_CTS_ENABLE
+#define USART_HWCONTROL_RTS_CTS (USART_RTS_ENABLE | USART_CTS_ENABLE)
+#endif
+
+/* 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);
+/* 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);
+
+/* USART normal mode communication */
+/* 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);
+/* 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 wmethod);
+
+/* LIN mode communication */
+/* enable LIN mode */
+void usart_lin_mode_enable(uint32_t usart_periph);
+/* disable LIN mode */
+void usart_lin_mode_disable(uint32_t usart_periph);
+/* LIN break detection length */
+void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen);
+/* send break frame */
+void usart_send_break(uint32_t usart_periph);
+
+/* half-duplex communication */
+/* enable half-duplex mode */
+void usart_halfduplex_enable(uint32_t usart_periph);
+/* disable half-duplex mode */
+void usart_halfduplex_disable(uint32_t usart_periph);
+
+/* synchronous communication */
+/* enable CK pin in synchronous mode */
+void usart_synchronous_clock_enable(uint32_t usart_periph);
+/* disable CK pin in synchronous mode */
+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 */
+/* configure guard time value in smartcard mode */
+void usart_guard_time_config(uint32_t usart_periph, uint32_t guat);
+/* enable smartcard mode */
+void usart_smartcard_mode_enable(uint32_t usart_periph);
+/* disable smartcard mode */
+void usart_smartcard_mode_disable(uint32_t usart_periph);
+/* enable NACK in smartcard mode */
+void usart_smartcard_mode_nack_enable(uint32_t usart_periph);
+/* disable NACK in smartcard mode */
+void usart_smartcard_mode_nack_disable(uint32_t usart_periph);
+/* configure smartcard auto-retry number */
+void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum);
+/* configure block length */
+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, uint8_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);
+
+/* DMA communication */
+/* 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);
+
+/* coherence control */
+/* configure hardware flow control coherence mode */
+void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm);
+
+/* flag & interrupt functions */
+/* get flag in STAT0/STAT1 register */
+FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag);
+/* clear flag in STAT0/STAT1 register */
+void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag);
+/* enable USART interrupt */
+void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt);
+/* disable USART interrupt */
+void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt);
+/* get USART interrupt and flag status */
+FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag);
+/* clear interrupt flag in STAT0/STAT1 register */
+void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag);
+
+#endif /* GD32E10X_USART_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_wwdgt.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_wwdgt.h
new file mode 100644
index 0000000000..9dd8340f32
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Include/gd32e10x_wwdgt.h
@@ -0,0 +1,89 @@
+/*!
+ \file gd32e10x_wwdgt.h
+ \brief definitions for the WWDGT
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_WWDGT_H
+#define GD32E10X_WWDGT_H
+
+#include "gd32e10x.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 /* GD32E10X_WWDGT_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_adc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_adc.c
new file mode 100644
index 0000000000..7dce2fcd29
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_adc.c
@@ -0,0 +1,994 @@
+/*!
+ \file gd32e10x_adc.c
+ \brief ADC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_adc.h"
+
+/* discontinuous mode macro*/
+#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U)
+
+/* ADC regular channel macro */
+#define ADC_REGULAR_CHANNEL_RANK_SIX ((uint8_t)6U)
+#define ADC_REGULAR_CHANNEL_RANK_TWELVE ((uint8_t)12U)
+#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U)
+#define ADC_REGULAR_CHANNEL_RANK_LENGTH ((uint8_t)5U)
+
+/* ADC sampling time macro */
+#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U)
+#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U)
+#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U)
+
+/* ADC inserted channel macro */
+#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U)
+#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U)
+
+/* ADC inserted channel offset macro */
+#define ADC_OFFSET_LENGTH ((uint8_t)3U)
+#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U)
+
+/*!
+ \brief reset ADC
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_deinit(uint32_t adc_periph)
+{
+ switch (adc_periph) {
+ case ADC0:
+ /* reset ADC0 */
+ rcu_periph_reset_enable(RCU_ADC0RST);
+ rcu_periph_reset_disable(RCU_ADC0RST);
+ break;
+ case ADC1:
+ /* reset ADC1 */
+ rcu_periph_reset_enable(RCU_ADC1RST);
+ rcu_periph_reset_disable(RCU_ADC1RST);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure the ADC sync mode
+ \param[in] mode: ADC mode
+ only one parameter can be selected which is shown as below:
+ \arg ADC_MODE_FREE: 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_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode
+ \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode
+ \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode only
+ \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode only
+ \arg ADC_DAUL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in follow-up fast mode only
+ \arg ADC_DAUL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in follow-up slow mode only
+ \arg ADC_DAUL_INSERTED_TRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode only
+ \param[out] none
+ \retval none
+*/
+void adc_mode_config(uint32_t mode)
+{
+ ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM);
+ ADC_CTL0(ADC0) |= mode;
+}
+
+/*!
+ \brief enable or disable ADC special function
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] function: the function to config
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t function, ControlStatus newvalue)
+{
+ if (newvalue) {
+ if (0U != (function & ADC_SCAN_MODE)) {
+ /* enable scan mode */
+ ADC_CTL0(adc_periph) |= ADC_SCAN_MODE;
+ }
+ if (0U != (function & ADC_INSERTED_CHANNEL_AUTO)) {
+ /* enable inserted channel group convert automatically */
+ ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO;
+ }
+ if (0U != (function & ADC_CONTINUOUS_MODE)) {
+ /* enable continuous mode */
+ ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE;
+ }
+ } else {
+ if (0U != (function & ADC_SCAN_MODE)) {
+ /* disable scan mode */
+ ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE;
+ }
+ if (0U != (function & ADC_INSERTED_CHANNEL_AUTO)) {
+ /* disable inserted channel group convert automatically */
+ ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO;
+ }
+ if (0U != (function & ADC_CONTINUOUS_MODE)) {
+ /* disable continuous mode */
+ ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE;
+ }
+ }
+}
+
+/*!
+ \brief configure ADC data alignment
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] data_alignment: data alignment select
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t data_alignment)
+{
+ if (ADC_DATAALIGN_RIGHT != data_alignment) {
+ /* MSB alignment */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_DAL;
+ } else {
+ /* LSB alignment */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL);
+ }
+}
+
+/*!
+ \brief enable ADC interface
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_enable(uint32_t adc_periph)
+{
+ if (RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)) {
+ /* enable ADC */
+ ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON;
+ }
+}
+
+/*!
+ \brief disable ADC interface
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_disable(uint32_t adc_periph)
+{
+ /* disable ADC */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON);
+}
+
+/*!
+ \brief ADC calibration and reset calibration
+ \param[in] adc_periph: ADCx,x=0,1
+ \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 (RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) {
+ }
+ /* enable ADC calibration process */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_CLB;
+ /* check the CLB bit state */
+ while (RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) {
+ }
+}
+
+/*!
+ \brief enable the temperature sensor and Vrefint channel
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void adc_tempsensor_vrefint_enable(void)
+{
+ /* enable the temperature sensor and Vrefint channel */
+ ADC_CTL1(ADC0) |= ADC_CTL1_TSVREN;
+}
+
+/*!
+ \brief disable the temperature sensor and Vrefint channel
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void adc_tempsensor_vrefint_disable(void)
+{
+ /* disable the temperature sensor and Vrefint channel */
+ ADC_CTL1(ADC0) &= ~ADC_CTL1_TSVREN;
+}
+
+/*!
+ \brief configure ADC resolution
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] resolution: ADC resolution
+ only one parameter can be selected which is shown as below:
+ \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_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_DRES);
+ ADC_OVSAMPCTL(adc_periph) |= (uint32_t)resolution;
+}
+
+/*!
+ \brief configure ADC oversample mode
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] mode: ADC oversampling mode
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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, uint32_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 enable ADC oversample mode
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_oversample_mode_enable(uint32_t adc_periph)
+{
+ ADC_OVSAMPCTL(adc_periph) |= ADC_OVSAMPCTL_OVSEN;
+}
+
+/*!
+ \brief disable ADC oversample mode
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_oversample_mode_disable(uint32_t adc_periph)
+{
+ ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
+}
+
+/*!
+ \brief enable DMA request
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_dma_mode_enable(uint32_t adc_periph)
+{
+ /* enable DMA request */
+ ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA);
+}
+
+/*!
+ \brief disable DMA request
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_dma_mode_disable(uint32_t adc_periph)
+{
+ /* disable DMA request */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA);
+}
+
+/*!
+ \brief configure ADC discontinuous mode
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel_group: select the channel group
+ only one parameter can be selected which is shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel
+ \param[in] length: number of conversions in discontinuous mode,the number can be 1..8
+ for regular channel ,the number has 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)
+{
+ /* disable discontinuous mode of regular & inserted channel */
+ 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);
+ ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
+ /* enable regular channel group discontinuous mode */
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC;
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* enable inserted channel group discontinuous mode */
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC;
+ break;
+ case ADC_CHANNEL_DISCON_DISABLE:
+ /* disable discontinuous mode of regular & inserted channel */
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure the length of regular channel group or inserted channel group
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel_group: select the channel group
+ only one parameter can be selected which is shown as below:
+ \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:
+ /* configure the length of regular channel group */
+ ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL);
+ ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* configure the length of inserted channel group */
+ ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL);
+ ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure ADC regular channel
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] rank: the regular group sequence rank,this parameter must be between 0 to 15
+ \param[in] adc_channel: the selected ADC channel
+ only one parameter can be selected which is shown as below:
+ \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx
+ \param[in] sample_time: the sample time value
+ only one parameter can be selected which is shown as below:
+ \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
+ \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
+ \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
+ \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
+ \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
+ \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
+ \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
+ \arg ADC_SAMPLETIME_239POINT5: 239.5 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 < ADC_REGULAR_CHANNEL_RANK_SIX) {
+ /* the regular group sequence rank is smaller than six */
+ rsq = ADC_RSQ2(adc_periph);
+ rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank)));
+ /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
+ rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank));
+ ADC_RSQ2(adc_periph) = rsq;
+ } else if (rank < ADC_REGULAR_CHANNEL_RANK_TWELVE) {
+ /* the regular group sequence rank is smaller than twelve */
+ rsq = ADC_RSQ1(adc_periph);
+ rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX))));
+ /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
+ rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX)));
+ ADC_RSQ1(adc_periph) = rsq;
+ } else if (rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN) {
+ /* the regular group sequence rank is smaller than sixteen */
+ rsq = ADC_RSQ0(adc_periph);
+ rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE))));
+ /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
+ rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE)));
+ ADC_RSQ0(adc_periph) = rsq;
+ } else {
+ }
+
+ /* ADC sampling time config */
+ if (adc_channel < ADC_CHANNEL_SAMPLE_TEN) {
+ /* the regular group sequence rank is smaller than ten */
+ sampt = ADC_SAMPT1(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)));
+ /* channel sample time set*/
+ sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel));
+ ADC_SAMPT1(adc_periph) = sampt;
+ } else if (adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN) {
+ /* the regular group sequence rank is smaller than eighteen */
+ sampt = ADC_SAMPT0(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))));
+ /* channel sample time set*/
+ sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)));
+ ADC_SAMPT0(adc_periph) = sampt;
+ } else {
+ }
+}
+
+/*!
+ \brief configure ADC inserted channel
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3
+ \param[in] adc_channel: the selected ADC channel
+ only one parameter can be selected which is shown as below:
+ \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx
+ \param[in] sample_time: The sample time value
+ only one parameter can be selected which is shown as below:
+ \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
+ \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
+ \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
+ \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
+ \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
+ \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
+ \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
+ \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
+ \param[out] none
+ \retval none
+*/
+void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time)
+{
+ uint8_t inserted_length;
+ uint32_t isq, sampt;
+ /* get inserted channel group length */
+ inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U);
+ /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */
+ isq = ADC_ISQ(adc_periph);
+ isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)));
+ isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH));
+ ADC_ISQ(adc_periph) = isq;
+
+ /* ADC sampling time config */
+ if (adc_channel < ADC_CHANNEL_SAMPLE_TEN) {
+ /* the inserted group sequence rank is smaller than ten */
+ sampt = ADC_SAMPT1(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)));
+ /* channel sample time set*/
+ sampt |= (uint32_t) sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel);
+ ADC_SAMPT1(adc_periph) = sampt;
+ } else if (adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN) {
+ /* the inserted group sequence rank is smaller than eighteen */
+ sampt = ADC_SAMPT0(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))));
+ /* channel sample time set*/
+ sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)));
+ ADC_SAMPT0(adc_periph) = sampt;
+ } else {
+ }
+}
+
+/*!
+ \brief configure ADC inserted channel offset
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] inserted_channel : insert channel select
+ only one parameter can be selected which is shown as below:
+ \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 none
+*/
+void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset)
+{
+ uint8_t inserted_length;
+ uint32_t num = 0U;
+
+ inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U);
+ num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel));
+
+ if (num <= ADC_OFFSET_LENGTH) {
+ /* calculate the offset of the register */
+ num = num * ADC_OFFSET_SHIFT_LENGTH;
+ /* config the offset of the selected channels */
+ REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
+ }
+}
+
+/*!
+ \brief configure ADC external trigger source
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel_group: select the channel group
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ for regular channel:
+ \arg ADC0_1_EXTTRIG_REGULAR_T0_CH0: timer 0 CC0 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T0_CH1: timer 0 CC1 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T0_CH2: timer 0 CC2 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T1_CH1: timer 1 CC1 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T2_TRGO: timer 2 TRGO event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T3_CH3: timer 3 CC3 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T7_TRGO: timer 7 TRGO event select
+ \arg ADC0_1_EXTTRIG_REGULAR_EXTI_11 : external interrupt line 11
+ \arg ADC0_1_EXTTRIG_REGULAR_NONE: software trigger
+ for inserted channel:
+ \arg ADC0_1_EXTTRIG_INSERTED_T0_TRGO: timer 0 TRGO event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T0_CH3: timer 0 CC3 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T1_TRGO: timer 1 TRGO event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T1_CH0: timer 1 CC0 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T2_CH3: timer 2 CC3 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T3_TRGO: timer 3 TRGO event select
+ \arg ADC0_1_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15
+ \arg ADC0_1_EXTTRIG_INSERTED_T7_CH3: timer 7 CC3 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_NONE: software trigger
+ \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:
+ /* configure ADC regular group external trigger source */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC);
+ ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* configure ADC inserted group external trigger source */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC);
+ ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief enable ADC external trigger
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel_group: select the channel group
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \param[in] newvalue: ENABLE or DISABLE
+ \param[out] none
+ \retval none
+*/
+void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue)
+{
+ if (newvalue) {
+ if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) {
+ /* enable ADC regular channel group external trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_ETERC;
+ }
+ if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) {
+ /* enable ADC inserted channel group external trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_ETEIC;
+ }
+ } else {
+ if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) {
+ /* disable ADC regular channel group external trigger */
+ ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETERC;
+ }
+ if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) {
+ /* disable ADC regular channel group external trigger */
+ ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETEIC;
+ }
+ }
+}
+
+/*!
+ \brief enable ADC software trigger
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel_group: select the channel group
+ one or more parameters can be selected which are shown as below:
+ \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)
+{
+ if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) {
+ /* enable ADC regular channel group software trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_SWRCST;
+ }
+ if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) {
+ /* enable ADC inserted channel group software trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_SWICST;
+ }
+}
+
+/*!
+ \brief read ADC regular group data register
+ \param[in] adc_periph: ADCx,x=0,1
+ \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 read ADC inserted group data register
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] inserted_channel : insert channel select
+ only one parameter can be selected which is shown as below:
+ \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:
+ /* read the data of channel 0 */
+ idata = ADC_IDATA0(adc_periph);
+ break;
+ case ADC_INSERTED_CHANNEL_1:
+ /* read the data of channel 1 */
+ idata = ADC_IDATA1(adc_periph);
+ break;
+ case ADC_INSERTED_CHANNEL_2:
+ /* read the data of channel 2 */
+ idata = ADC_IDATA2(adc_periph);
+ break;
+ case ADC_INSERTED_CHANNEL_3:
+ /* read the data of channel 3 */
+ idata = ADC_IDATA3(adc_periph);
+ break;
+ default:
+ idata = 0U;
+ break;
+ }
+ return (uint16_t)idata;
+}
+
+/*!
+ \brief read the last ADC0 and ADC1 conversion result data in sync mode
+ \param[in] none
+ \param[out] none
+ \retval the conversion value
+*/
+uint32_t adc_sync_mode_convert_value_read(void)
+{
+ /* return conversion value */
+ return ADC_RDATA(ADC0);
+}
+
+/*!
+ \brief configure ADC analog watchdog single channel
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel: the selected ADC channel
+ only one parameter can be selected which is shown as below:
+ \arg ADC_CHANNEL_x: ADC Channelx(x=0..17)(x=16 and x=17 are only for ADC0)
+ \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_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
+ /* analog watchdog channel select */
+ ADC_CTL0(adc_periph) |= (uint32_t)adc_channel;
+ ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
+}
+
+/*!
+ \brief configure ADC analog watchdog group channel
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_channel_group: the channel group use analog watchdog
+ only one parameter can be selected which is shown as below:
+ \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_group_channel_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:
+ /* regular channel analog watchdog enable */
+ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN;
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* inserted channel analog watchdog enable */
+ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN;
+ break;
+ case ADC_REGULAR_INSERTED_CHANNEL:
+ /* regular and inserted channel analog watchdog enable */
+ ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief disable ADC analog watchdog
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_watchdog_disable(uint32_t adc_periph)
+{
+ ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
+}
+
+/*!
+ \brief configure ADC analog watchdog threshold
+ \param[in] adc_periph: ADCx,x=0,1
+ \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)WDLT_WDLT(low_threshold);
+ ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold);
+}
+
+/*!
+ \brief get the ADC flag bits
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_flag: the adc flag bits
+ only one parameter can be selected which is shown as below:
+ \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
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag)
+{
+ FlagStatus reval = RESET;
+ if (ADC_STAT(adc_periph) & adc_flag) {
+ reval = SET;
+ }
+ return reval;
+}
+
+/*!
+ \brief clear the ADC flag bits
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_flag: the adc flag bits
+ one or more parameters can be selected which are shown as below:
+ \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
+ \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 bit state of ADCx software start conversion
+ \param[in] adc_periph: ADCx, x=0,1, only one among these parameters can be selected
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph)
+{
+ FlagStatus reval = RESET;
+ if ((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STRC)) {
+ reval = SET;
+ }
+ return reval;
+}
+
+/*!
+ \brief get the bit state of ADCx software inserted channel start conversion
+ \param[in] adc_periph: ADCx, x=0,1 only one among these parameters can be selected
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph)
+{
+ FlagStatus reval = RESET;
+ if ((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STIC)) {
+ reval = SET;
+ }
+ return reval;
+}
+
+/*!
+ \brief get the ADC interrupt bits
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_interrupt: the adc interrupt bits
+ only one parameter can be selected which is shown as below:
+ \arg ADC_INT_FLAG_WDE: analog watchdog interrupt
+ \arg ADC_INT_FLAG_EOC: end of group conversion interrupt
+ \arg ADC_INT_FLAG_EOIC: end of inserted group conversion 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_FLAG_WDE:
+ /* get the ADC analog watchdog interrupt bits */
+ state = ADC_STAT(adc_periph) & ADC_STAT_WDE;
+ if ((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state) {
+ interrupt_flag = SET;
+ }
+ break;
+ case ADC_INT_FLAG_EOC:
+ /* get the ADC end of group conversion interrupt bits */
+ state = ADC_STAT(adc_periph) & ADC_STAT_EOC;
+ if ((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) {
+ interrupt_flag = SET;
+ }
+ break;
+ case ADC_INT_FLAG_EOIC:
+ /* get the ADC end of inserted group conversion interrupt bits */
+ state = ADC_STAT(adc_periph) & ADC_STAT_EOIC;
+ if ((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) {
+ interrupt_flag = SET;
+ }
+ break;
+ default:
+ break;
+ }
+ return interrupt_flag;
+}
+
+/*!
+ \brief clear the ADC flag
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_interrupt: the adc status flag
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_INT_FLAG_WDE: analog watchdog interrupt
+ \arg ADC_INT_FLAG_EOC: end of group conversion interrupt
+ \arg ADC_INT_FLAG_EOIC: end of inserted group conversion 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 enable ADC interrupt
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_interrupt: the adc interrupt
+ one or more parameters can be selected which are shown as below:
+ \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
+ \param[out] none
+ \retval none
+*/
+void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt)
+{
+ /* enable ADC analog watchdog interrupt */
+ if (0U != (adc_interrupt & ADC_INT_WDE)) {
+ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE;
+ }
+ /* enable ADC end of group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOC)) {
+ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE;
+ }
+ /* enable ADC end of inserted group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOIC)) {
+ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE;
+ }
+}
+
+/*!
+ \brief disable ADC interrupt
+ \param[in] adc_periph: ADCx,x=0,1
+ \param[in] adc_interrupt: the adc interrupt flag
+ one or more parameters can be selected which are shown as below:
+ \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
+ \param[out] none
+ \retval none
+*/
+void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt)
+{
+ /* disable ADC analog watchdog interrupt */
+ if (0U != (adc_interrupt & ADC_INT_WDE)) {
+ ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_WDEIE;
+ }
+ /* disable ADC end of group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOC)) {
+ ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_EOCIE;
+ }
+ /* disable ADC end of inserted group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOIC)) {
+ ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_EOICIE;
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_bkp.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_bkp.c
new file mode 100644
index 0000000000..e35b2e75eb
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_bkp.c
@@ -0,0 +1,335 @@
+/*!
+ \file gd32e10x_bkp.c
+ \brief BKP driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_bkp.h"
+
+/* BKP register bits offset */
+#define BKP_TAMPER_BITS_OFFSET ((uint32_t)8U)
+
+/*!
+ \brief reset BKP registers
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_deinit(void)
+{
+ /* reset BKP domain register*/
+ rcu_bkp_reset_enable();
+ rcu_bkp_reset_disable();
+}
+
+/*!
+ \brief write BKP data register
+ \param[in] register_number: refer to bkp_data_register_enum
+ only one parameter can be selected which is shown as below:
+ \arg BKP_DATA_x(x = 0..41): bkp data register number x
+ \param[in] data: the data to be write in BKP data register
+ \param[out] none
+ \retval none
+*/
+void bkp_data_write(bkp_data_register_enum register_number, uint16_t data)
+{
+ if ((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)) {
+ BKP_DATA10_41(register_number - 1U) = data;
+ } else if ((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)) {
+ BKP_DATA0_9(register_number - 1U) = data;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief read BKP data register
+ \param[in] register_number: refer to bkp_data_register_enum
+ only one parameter can be selected which is shown as below:
+ \arg BKP_DATA_x(x = 0..41): bkp data register number x
+ \param[out] none
+ \retval data of BKP data register
+*/
+uint16_t bkp_data_read(bkp_data_register_enum register_number)
+{
+ uint16_t data = 0U;
+
+ /* get the data from the BKP data register */
+ if ((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)) {
+ data = BKP_DATA10_41(register_number - 1U);
+ } else if ((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)) {
+ data = BKP_DATA0_9(register_number - 1U);
+ } else {
+ /* illegal parameters */
+ }
+ return data;
+}
+
+/*!
+ \brief enable RTC clock calibration output
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_calibration_output_enable(void)
+{
+ BKP_OCTL |= (uint16_t)BKP_OCTL_COEN;
+}
+
+/*!
+ \brief disable RTC clock calibration output
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_calibration_output_disable(void)
+{
+ BKP_OCTL &= (uint16_t)~BKP_OCTL_COEN;
+}
+
+/*!
+ \brief enable RTC alarm or second signal output
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_signal_output_enable(void)
+{
+ BKP_OCTL |= (uint16_t)BKP_OCTL_ASOEN;
+}
+
+/*!
+ \brief disable RTC alarm or second signal output
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_signal_output_disable(void)
+{
+ BKP_OCTL &= (uint16_t)~BKP_OCTL_ASOEN;
+}
+
+/*!
+ \brief select RTC output
+ \param[in] outputsel: RTC output selection
+ only one parameter can be selected which is shown as below:
+ \arg RTC_OUTPUT_ALARM_PULSE: RTC alarm pulse is selected as the RTC output
+ \arg RTC_OUTPUT_SECOND_PULSE: RTC second pulse is selected as the RTC output
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_output_select(uint16_t outputsel)
+{
+ uint16_t ctl = 0U;
+
+ /* configure BKP_OCTL_ROSEL with outputsel */
+ ctl = BKP_OCTL;
+ ctl &= (uint16_t)~BKP_OCTL_ROSEL;
+ ctl |= outputsel;
+ BKP_OCTL = ctl;
+}
+
+/*!
+ \brief select RTC clock output
+ \param[in] clocksel: RTC clock output selection
+ only one parameter can be selected which is shown as below:
+ \arg RTC_CLOCK_DIV_64: RTC clock div 64
+ \arg RTC_CLOCK_DIV_1: RTC clock
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_clock_output_select(uint16_t clocksel)
+{
+ uint16_t ctl = 0U;
+
+ /* configure BKP_OCTL_CCOSEL with clocksel */
+ ctl = BKP_OCTL;
+ ctl &= (uint16_t)~BKP_OCTL_CCOSEL;
+ ctl |= clocksel;
+ BKP_OCTL = ctl;
+}
+
+/*!
+ \brief select RTC clock calibration direction
+ \param[in] direction: RTC clock calibration direction
+ only one parameter can be selected which is shown as below:
+ \arg RTC_CLOCK_SLOWED_DOWN: RTC clock slow down
+ \arg RTC_CLOCK_SPEED_UP: RTC clock speed up
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_clock_calibration_direction_select(uint16_t direction)
+{
+ uint16_t ctl = 0U;
+
+ /* configure BKP_OCTL_CALDIR with direction */
+ ctl = BKP_OCTL;
+ ctl &= (uint16_t)~BKP_OCTL_CALDIR;
+ ctl |= direction;
+ BKP_OCTL = ctl;
+}
+
+/*!
+ \brief set RTC clock calibration value
+ \param[in] value: RTC clock calibration value
+ \arg 0x00 - 0x7F
+ \param[out] none
+ \retval none
+*/
+void bkp_rtc_calibration_value_set(uint8_t value)
+{
+ uint16_t ctl;
+
+ /* configure BKP_OCTL_RCCV with value */
+ ctl = BKP_OCTL;
+ ctl &= (uint16_t)~BKP_OCTL_RCCV;
+ ctl |= (uint16_t)OCTL_RCCV(value);
+ BKP_OCTL = ctl;
+}
+
+/*!
+ \brief enable tamper detection
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_tamper_detection_enable(void)
+{
+ BKP_TPCTL |= (uint16_t)BKP_TPCTL_TPEN;
+}
+
+/*!
+ \brief disable tamper detection
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_tamper_detection_disable(void)
+{
+ BKP_TPCTL &= (uint16_t)~BKP_TPCTL_TPEN;
+}
+
+/*!
+ \brief set tamper pin active level
+ \param[in] level: tamper active level
+ only one parameter can be selected which is shown as below:
+ \arg TAMPER_PIN_ACTIVE_HIGH: the tamper pin is active high
+ \arg TAMPER_PIN_ACTIVE_LOW: the tamper pin is active low
+ \param[out] none
+ \retval none
+*/
+void bkp_tamper_active_level_set(uint16_t level)
+{
+ uint16_t ctl = 0U;
+
+ /* configure BKP_TPCTL_TPAL with level */
+ ctl = BKP_TPCTL;
+ ctl &= (uint16_t)~BKP_TPCTL_TPAL;
+ ctl |= level;
+ BKP_TPCTL = ctl;
+}
+
+/*!
+ \brief enable tamper interrupt
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_interrupt_enable(void)
+{
+ BKP_TPCS |= (uint16_t)BKP_TPCS_TPIE;
+}
+
+/*!
+ \brief disable tamper interrupt
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_interrupt_disable(void)
+{
+ BKP_TPCS &= (uint16_t)~BKP_TPCS_TPIE;
+}
+
+/*!
+ \brief get tamper flag state
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus bkp_flag_get(void)
+{
+ if (RESET != (BKP_TPCS & BKP_FLAG_TAMPER)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear tamper flag state
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_flag_clear(void)
+{
+ BKP_TPCS |= (uint16_t)(BKP_FLAG_TAMPER >> BKP_TAMPER_BITS_OFFSET);
+}
+
+/*!
+ \brief get tamper interrupt flag state
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus bkp_interrupt_flag_get(void)
+{
+ if (RESET != (BKP_TPCS & BKP_INT_FLAG_TAMPER)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear tamper interrupt flag state
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void bkp_interrupt_flag_clear(void)
+{
+ BKP_TPCS |= (uint16_t)(BKP_INT_FLAG_TAMPER >> BKP_TAMPER_BITS_OFFSET);
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_can.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_can.c
new file mode 100644
index 0000000000..6af479a9b8
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_can.c
@@ -0,0 +1,1502 @@
+/*!
+ \file gd32e10x_can.c
+ \brief CAN driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_can.h"
+
+#define CAN_ERROR_HANDLE(s) do{}while(1)
+
+/* BS1[3:0] + 1 + BS2[2:0] + 1 */
+#define DEV_CAN_BT_SEG_MAX 24u
+#define DEV_CAN_BT_SEG_MIN 4u
+
+/* CAN related register mask */
+#define DEV_CAN_BS1_MASK 0x000F0000U
+#define DEV_CAN_BS2_MASK 0x00700000U
+#define DEV_CAN_BAUDPSC_MASK 0x000003FFU
+#define DEV_CAN_SJW_MASK 0x03000000U
+/* This table can be used to calculate data length in FD mode */
+const uint8_t g_can_fdlength_table[] = {12, 16, 20, 24, 32, 48, 64};
+/* This table can be used to calculate bit time: timing_pts{BS1[3:0], BS2[2:0]} */
+static const uint32_t timing_pts[23][2] = {
+ {0x0, 0x0}, /* 2, 50% */
+ {0x1, 0x0}, /* 3, 67% */
+ {0x2, 0x0}, /* 4, 75% */
+ {0x3, 0x0}, /* 5, 80% */
+ {0x3, 0x1}, /* 6, 67% */
+ {0x4, 0x1}, /* 7, 71% */
+ {0x5, 0x1}, /* 8, 75% */
+ {0x6, 0x1}, /* 9, 78% */
+ {0x6, 0x2}, /* 10, 70% */
+ {0x7, 0x2}, /* 11, 73% */
+ {0x8, 0x2}, /* 12, 75% */
+ {0x9, 0x2}, /* 13, 77% */
+ {0x9, 0x3}, /* 14, 71% */
+ {0xA, 0x3}, /* 15, 73% */
+ {0xB, 0x3}, /* 16, 75% */
+ {0xC, 0x3}, /* 17, 76% */
+ {0xD, 0x3}, /* 18, 78% */
+ {0xD, 0x4}, /* 19, 74% */
+ {0xE, 0x4}, /* 20, 75% */
+ {0xF, 0x4}, /* 21, 76% */
+ {0xF, 0x5}, /* 22, 73% */
+ {0xF, 0x6}, /* 23, 70% */
+ {0xF, 0x7}, /* 24, 67% */
+};
+
+static unsigned int dev_can_baudrate_set(uint32_t freq);
+
+/*!
+ \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 parameter struct with a default value
+ \param[in] type: the type of CAN parameter struct
+ only one parameter can be selected which is shown as below:
+ \arg CAN_INIT_STRUCT: the CAN initial struct
+ \arg CAN_FILTER_STRUCT: the CAN filter struct
+ \arg CAN_FD_FRAME_STRUCT: the CAN FD initial struct
+ \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct
+ \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct
+ \param[in] p_struct: the pointer of the specific struct
+ \param[out] none
+ \retval none
+*/
+void can_struct_para_init(can_struct_type_enum type, void *p_struct)
+{
+ uint8_t i;
+
+ /* get type of the struct */
+ switch (type) {
+ /* used for can_init() */
+ case CAN_INIT_STRUCT:
+ ((can_parameter_struct *)p_struct)->auto_bus_off_recovery = DISABLE;
+ ((can_parameter_struct *)p_struct)->auto_retrans = DISABLE;
+ ((can_parameter_struct *)p_struct)->auto_wake_up = DISABLE;
+ ((can_parameter_struct *)p_struct)->prescaler = 0x03FFU;
+ ((can_parameter_struct *)p_struct)->rec_fifo_overwrite = DISABLE;
+ ((can_parameter_struct *)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ;
+ ((can_parameter_struct *)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ;
+ ((can_parameter_struct *)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ;
+ ((can_parameter_struct *)p_struct)->time_triggered = DISABLE;
+ ((can_parameter_struct *)p_struct)->trans_fifo_order = DISABLE;
+ ((can_parameter_struct *)p_struct)->working_mode = CAN_NORMAL_MODE;
+
+ break;
+ /* used for can_filter_init() */
+ case CAN_FILTER_STRUCT:
+ ((can_filter_parameter_struct *)p_struct)->filter_bits = CAN_FILTERBITS_32BIT;
+ ((can_filter_parameter_struct *)p_struct)->filter_enable = DISABLE;
+ ((can_filter_parameter_struct *)p_struct)->filter_fifo_number = CAN_FIFO0;
+ ((can_filter_parameter_struct *)p_struct)->filter_list_high = 0x0000U;
+ ((can_filter_parameter_struct *)p_struct)->filter_list_low = 0x0000U;
+ ((can_filter_parameter_struct *)p_struct)->filter_mask_high = 0x0000U;
+ ((can_filter_parameter_struct *)p_struct)->filter_mask_low = 0x0000U;
+ ((can_filter_parameter_struct *)p_struct)->filter_mode = CAN_FILTERMODE_MASK;
+ ((can_filter_parameter_struct *)p_struct)->filter_number = 0U;
+
+ break;
+ /* used for can_fd_init() */
+ case CAN_FD_FRAME_STRUCT:
+ ((can_fdframe_struct *)p_struct)->data_prescaler = 0x03FFU;
+ ((can_fdframe_struct *)p_struct)->data_resync_jump_width = 1U - 1U;
+ ((can_fdframe_struct *)p_struct)->data_time_segment_1 = 3U - 1U;
+ ((can_fdframe_struct *)p_struct)->data_time_segment_2 = 2U - 1U;
+ ((can_fdframe_struct *)p_struct)->delay_compensation = DISABLE;
+ ((can_fdframe_struct *)p_struct)->esi_mode = CAN_ESIMOD_HARDWARE;
+ ((can_fdframe_struct *)p_struct)->excp_event_detect = ENABLE;
+ ((can_fdframe_struct *)p_struct)->fd_frame = DISABLE;
+ ((can_fdframe_struct *)p_struct)->iso_bosch = CAN_FDMOD_ISO;
+ ((can_fdframe_struct *)p_struct)->p_delay_compensation = 0U;
+
+ break;
+ /* used for can_message_transmit() */
+ case CAN_TX_MESSAGE_STRUCT:
+ ((can_trasnmit_message_struct *)p_struct)->fd_brs = CAN_BRS_DISABLE;
+ ((can_trasnmit_message_struct *)p_struct)->fd_esi = CAN_ESI_DOMINANT;
+ ((can_trasnmit_message_struct *)p_struct)->fd_flag = CAN_FDF_CLASSIC;
+
+ for (i = 0U; i < 64U; i++) {
+ ((can_trasnmit_message_struct *)p_struct)->tx_data[i] = 0U;
+ }
+
+ ((can_trasnmit_message_struct *)p_struct)->tx_dlen = 0u;
+ ((can_trasnmit_message_struct *)p_struct)->tx_efid = 0U;
+ ((can_trasnmit_message_struct *)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD;
+ ((can_trasnmit_message_struct *)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA;
+ ((can_trasnmit_message_struct *)p_struct)->tx_sfid = 0U;
+
+ break;
+ /* used for can_message_receive() */
+ case CAN_RX_MESSAGE_STRUCT:
+ ((can_receive_message_struct *)p_struct)->fd_brs = CAN_BRS_DISABLE;
+ ((can_receive_message_struct *)p_struct)->fd_esi = CAN_ESI_DOMINANT;
+ ((can_receive_message_struct *)p_struct)->fd_flag = CAN_FDF_CLASSIC;
+
+ for (i = 0U; i < 64U; i++) {
+ ((can_receive_message_struct *)p_struct)->rx_data[i] = 0U;
+ }
+
+ ((can_receive_message_struct *)p_struct)->rx_dlen = 0U;
+ ((can_receive_message_struct *)p_struct)->rx_efid = 0U;
+ ((can_receive_message_struct *)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD;
+ ((can_receive_message_struct *)p_struct)->rx_fi = 0U;
+ ((can_receive_message_struct *)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA;
+ ((can_receive_message_struct *)p_struct)->rx_sfid = 0U;
+
+ break;
+
+ default:
+ CAN_ERROR_HANDLE("parameter is invalid \r\n");
+ }
+}
+
+/*!
+ \brief initialize CAN
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] can_parameter_init: parameters for CAN initializtion
+ \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
+ \arg resync_jump_width: 0x00 - 0x07
+ \arg time_segment_1: 0x00 - 0x7F
+ \arg time_segment_2: 0x00 - 0x1F
+ \arg time_triggered: ENABLE or DISABLE
+ \arg auto_bus_off_recovery: ENABLE or DISABLE
+ \arg auto_wake_up: ENABLE or DISABLE
+ \arg auto_retrans: ENABLE or DISABLE
+ \arg rec_fifo_overwrite: ENABLE or DISABLE
+ \arg trans_fifo_order: ENABLE or DISABLE
+ \arg prescaler: 0x0000 - 0x03FF
+ \param[out] none
+ \retval ErrStatus: SUCCESS or ERROR
+*/
+#ifdef GD_MBED_USED
+ErrStatus can_para_init(uint32_t can_periph, can_parameter_struct *can_parameter_init)
+#else
+ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init)
+#endif
+{
+ 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)) && (0U != 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)) && (0U != timeout)) {
+ timeout--;
+ }
+ /* check exit initialize mode */
+ if (0U != timeout) {
+ flag = SUCCESS;
+ }
+ }
+ return flag;
+}
+
+/*!
+ \brief initialize CAN FD function
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] can_fdframe_init: parameters for CAN FD initializtion
+ \arg fd_frame: ENABLE or DISABLE
+ \arg excp_event_detect: ENABLE or DISABLE
+ \arg delay_compensation: ENABLE or DISABLE
+ \arg p_delay_compensation: the pointer of tdc struct
+ can_fd_tdc_struct:
+ tdc_mode: CAN_TDCMOD_CALC_AND_OFFSET or CAN_TDCMOD_OFFSET
+ tdc_filter: 0x00 - 0x07
+ tdc_offset: 0x00 - 0x07
+ \arg iso_bosch: CAN_FDMOD_ISO or CAN_FDMOD_BOSCH
+ \arg esi_mode: CAN_ESIMOD_HARDWARE or CAN_ESIMOD_SOFTWARE
+ \arg data_resync_jump_width: 0x00 - 0x07
+ \arg data_time_segment_1: 0x00 - 0x0F
+ \arg data_time_segment_2: 0x00 - 0x07
+ \arg data_prescaler: 0x0000 - 0x03FF
+ \param[out] none
+ \retval ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_fd_init(uint32_t can_periph, can_fdframe_struct *can_fdframe_init)
+{
+ uint32_t timeout = CAN_TIMEOUT;
+ uint32_t tempreg = 0U;
+
+ /* check null pointer */
+ if (0 == can_fdframe_init) {
+ return 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)) && (0U != timeout)) {
+ timeout--;
+ }
+ /* check initialize working success */
+ if (CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) {
+ return ERROR;
+ } else {
+ /* set the data bit timing register */
+ CAN_DBT(can_periph) = (BT_DSJW((uint32_t)can_fdframe_init->data_resync_jump_width) | \
+ BT_DBS1((uint32_t)can_fdframe_init->data_time_segment_1) | \
+ BT_DBS2((uint32_t)can_fdframe_init->data_time_segment_2) | \
+ BT_BAUDPSC(((uint32_t)can_fdframe_init->data_prescaler - 1U)));
+
+ tempreg = can_fdframe_init->esi_mode | can_fdframe_init->iso_bosch;
+
+ /* Protocol exception event detection */
+ if (ENABLE == can_fdframe_init->excp_event_detect) {
+ tempreg &= ~CAN_FDCTL_PRED;
+ } else {
+ tempreg |= CAN_FDCTL_PRED;
+ }
+
+ /* Transmitter delay compensation mode */
+ if (ENABLE == can_fdframe_init->delay_compensation) {
+ tempreg |= CAN_FDCTL_TDCEN;
+ /* p_delay_compensation pointer should be config when TDC mode is enabled */
+ if (0 != can_fdframe_init->p_delay_compensation) {
+ tempreg |= (can_fdframe_init->p_delay_compensation->tdc_mode & CAN_FDCTL_TDCMOD);
+ CAN_FDTDC(can_periph) = (FDTDC_TDCF(can_fdframe_init->p_delay_compensation->tdc_filter) | FDTDC_TDCO(can_fdframe_init->p_delay_compensation->tdc_offset));
+ } else {
+ return ERROR;
+ }
+ } else {
+ /* Transmitter delay compensation mode is disabled */
+ tempreg &= ~CAN_FDCTL_TDCEN;
+ }
+
+ /* FD operation mode */
+ if (ENABLE == can_fdframe_init->fd_frame) {
+ tempreg |= CAN_FDCTL_FDEN;
+ } else {
+ tempreg &= ~CAN_FDCTL_FDEN;
+ }
+ CAN_FDCTL(can_periph) = tempreg;
+
+ /* 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)) && (0U != timeout)) {
+ timeout--;
+ }
+ /* check exit initialize mode */
+ if (0U == timeout) {
+ return ERROR;
+ }
+ }
+
+ return SUCCESS;
+}
+
+/*!
+ \brief initialize CAN filter
+ \param[in] can_filter_parameter_init: struct for CAN filter initialization
+ \arg filter_list_high: 0x0000 - 0xFFFF
+ \arg filter_list_low: 0x0000 - 0xFFFF
+ \arg filter_mask_high: 0x0000 - 0xFFFF
+ \arg filter_mask_low: 0x0000 - 0xFFFF
+ \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1
+ \arg filter_number: 0 - 27
+ \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
+ \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
+ \arg 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;
+ } else {
+ /* 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 CAN filter mask mode initialization
+ \param[in] id: extended(11-bits) or standard(29-bits) identifier
+ \arg 0x00000000 - 0x1FFFFFFF
+ \param[in] mask: extended(11-bits) or standard(29-bits) identifier mask
+ \arg 0x00000000 - 0x1FFFFFFF
+ \param[in] format_fifo: format and fifo states
+ only one parameter can be selected which is shown as below:
+ \arg CAN_STANDARD_FIFO0
+ \arg CAN_STANDARD_FIFO1
+ \arg CAN_EXTENDED_FIFO0
+ \arg CAN_EXTENDED_FIFO1
+ \param[in] filter_number: filter sequence number
+ \arg 0x00 - 0x1C
+ \param[out] none
+ \retval none
+*/
+void can_filter_mask_mode_init(uint32_t id, uint32_t mask, can_format_fifo_enum format_fifo, uint16_t filter_number)
+{
+ can_filter_parameter_struct can_filter;
+
+ /* Initialize the filter structure */
+ can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);
+
+ /* filter config */
+ can_filter.filter_number = filter_number;
+ can_filter.filter_mode = CAN_FILTERMODE_MASK;
+ can_filter.filter_bits = CAN_FILTERBITS_32BIT;
+ can_filter.filter_enable = ENABLE;
+
+ switch (format_fifo) {
+ /* standard FIFO 0 */
+ case CAN_STANDARD_FIFO0:
+ can_filter.filter_fifo_number = CAN_FIFO0;
+ /* configure SFID[10:0] */
+ can_filter.filter_list_high = (uint16_t)id << 5;
+ can_filter.filter_list_low = 0x0000U;
+ /* configure SFID[10:0] mask */
+ can_filter.filter_mask_high = (uint16_t)mask << 5;
+ /* both data and remote frames can be received */
+ can_filter.filter_mask_low = 0x0000U;
+
+ break;
+ /* standard FIFO 1 */
+ case CAN_STANDARD_FIFO1:
+ can_filter.filter_fifo_number = CAN_FIFO1;
+ /* configure SFID[10:0] */
+ can_filter.filter_list_high = (uint16_t)id << 5;
+ can_filter.filter_list_low = 0x0000U;
+ /* configure SFID[10:0] mask */
+ can_filter.filter_mask_high = (uint16_t)mask << 5;
+ /* both data and remote frames can be received */
+ can_filter.filter_mask_low = 0x0000U;
+
+ break;
+ /* extended FIFO 0 */
+ case CAN_EXTENDED_FIFO0:
+ can_filter.filter_fifo_number = CAN_FIFO0;
+ /* configure EFID[28:13] */
+ can_filter.filter_list_high = (uint16_t)id >> 13;
+ /* configure EFID[12:0] and frame format bit set */
+ can_filter.filter_list_low = (0x00FFU & (uint16_t)(id << 3)) | (1U << 2);
+ /* configure EFID[28:13] mask */
+ can_filter.filter_mask_high = (uint16_t)mask >> 13;
+ /* configure EFID[12:0] and frame format bit mask */
+ /* both data and remote frames can be received */
+ can_filter.filter_mask_low = (0x00FFU & (uint16_t)(mask << 3)) | (1U << 2);
+
+ break;
+ /* extended FIFO 1 */
+ case CAN_EXTENDED_FIFO1:
+ can_filter.filter_fifo_number = CAN_FIFO1;
+ /* configure EFID[28:13] */
+ can_filter.filter_list_high = (uint16_t)id >> 13;
+ /* configure EFID[12:0] and frame format bit set */
+ can_filter.filter_list_low = (0x00FFU & (uint16_t)(id << 3)) | (1U << 2);
+ /* configure EFID[28:13] mask */
+ can_filter.filter_mask_high = (uint16_t)mask >> 13;
+ /* configure EFID[12:0] and frame format bit mask */
+ /* both data and remote frames can be received */
+ can_filter.filter_mask_low = (0x00FFU & (uint16_t)(mask << 3)) | (1U << 2);
+
+ break;
+ default:
+ CAN_ERROR_HANDLE("parameter is invalid \r\n");
+ }
+
+ can_filter_init(&can_filter);
+}
+
+/*!
+ \brief CAN baud rate configure in classic mode
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] hz: frequency, range from 1 to 1000000 Hz
+ \param[out] none
+ \retval ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_frequency_set(uint32_t can_periph, uint32_t hz)
+{
+ ErrStatus reval = SUCCESS;
+ uint32_t reg_temp;
+ /* The maximum baud rate support to 1M */
+ if (hz <= 1000000U) {
+ if (SUCCESS == can_working_mode_set(can_periph, CAN_MODE_INITIALIZE)) {
+ reg_temp = CAN_BT(can_periph);
+ reg_temp &= (CAN_BT_LCMOD | CAN_BT_SCMOD);
+ CAN_BT(can_periph) = reg_temp | dev_can_baudrate_set(hz);
+ } else {
+ reval = ERROR;
+ }
+
+ if (SUCCESS != can_working_mode_set(can_periph, CAN_MODE_NORMAL)) {
+ reval = ERROR;
+ }
+ } else {
+ reval = ERROR;
+ }
+
+ return reval;
+}
+
+/*!
+ \brief CAN baud rate configure in FD mode
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] hz: frequency
+ \param[out] none
+ \retval ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_fd_frequency_set(uint32_t can_periph, uint32_t hz)
+{
+ ErrStatus reval = SUCCESS;
+
+ if (SUCCESS == can_working_mode_set(can_periph, CAN_MODE_INITIALIZE)) {
+ CAN_DBT(can_periph) = dev_can_baudrate_set(hz);
+ } else {
+ reval = ERROR;
+ }
+
+ if (SUCCESS != can_working_mode_set(can_periph, CAN_MODE_NORMAL)) {
+ reval = ERROR;
+ }
+
+ return reval;
+}
+
+/*!
+ \brief CAN communication mode configure
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] mode: communication mode
+ only one parameter can be selected which is shown as below:
+ \arg CAN_NORMAL_MODE
+ \arg CAN_LOOPBACK_MODE
+ \arg CAN_SILENT_MODE
+ \arg CAN_SILENT_LOOPBACK_MODE
+ \param[out] none
+ \retval ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus can_monitor_mode_set(uint32_t can_periph, uint8_t mode)
+{
+ ErrStatus reval = SUCCESS;
+ uint32_t timeout = CAN_TIMEOUT;
+
+ if (mode == (mode & CAN_SILENT_LOOPBACK_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 */
+ timeout = CAN_TIMEOUT;
+ while ((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
+ timeout--;
+ }
+
+ if (CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) {
+ reval = ERROR;
+ } else {
+ CAN_BT(can_periph) &= ~BT_MODE(3);
+ CAN_BT(can_periph) |= BT_MODE(mode);
+
+ timeout = CAN_TIMEOUT;
+ /* 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))) && (0U != timeout)) {
+ timeout--;
+ }
+ if (0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) {
+ reval = ERROR;
+ }
+ }
+ } else {
+ reval = ERROR;
+ }
+
+ return reval;
+}
+
+/*!
+ \brief CAN FD frame function enable
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[out] none
+ \retval none
+*/
+void can_fd_function_enable(uint32_t can_periph)
+{
+ CAN_FDCTL(can_periph) |= CAN_FDCTL_FDEN;
+}
+
+/*!
+ \brief CAN FD frame function disable
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[out] none
+ \retval none
+*/
+void can_fd_function_disable(uint32_t can_periph)
+{
+ CAN_FDCTL(can_periph) &= ~CAN_FDCTL_FDEN;
+}
+
+/*!
+ \brief set CAN1 fliter start bank number
+ \param[in] start_bank: CAN1 start bank number
+ only one parameter can be selected which is shown as below:
+ \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)
+{
+ /* set DFZ bit */
+ 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)
+{
+ /* set DFZ bit */
+ CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
+
+ if (CAN0 == can_periph) {
+ dbg_periph_disable(DBG_CAN0_HOLD);
+ } else {
+ dbg_periph_disable(DBG_CAN1_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 transmit CAN message
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] transmit_message: struct for CAN transmit message
+ \arg tx_sfid: 0x00000000 - 0x000007FF
+ \arg tx_efid: 0x00000000 - 0x1FFFFFFF
+ \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
+ \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
+ \arg tx_dlenc: 1 - 7
+ \arg tx_data[]: 0x00 - 0xFF
+ \param[out] none
+ \retval mailbox_number
+*/
+uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message)
+{
+ uint8_t mailbox_number = CAN_MAILBOX0;
+ uint8_t i = 0U;
+ uint8_t hit = 0U;
+ uint32_t canfd_en = 0U;
+ volatile uint32_t p_temp;
+ uint32_t reg_temp = 0U;
+
+ /* 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;
+ }
+ /* return no mailbox empty */
+ 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);
+ }
+
+ if (CAN_FDF_CLASSIC == transmit_message->fd_flag) {
+ /* set the data length */
+ CAN_TMP(can_periph, mailbox_number) &= ~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]);
+ } else {
+ canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
+ /* check FD funciton has been enabled */
+ if (canfd_en) {
+ if (transmit_message->tx_dlen <= 8U) {
+ /* set the data length */
+ reg_temp |= transmit_message->tx_dlen;
+ } else {
+ /* data length greater than 8 */
+ for (i = 0U; i < 7U; i++) {
+ if (transmit_message->tx_dlen == g_can_fdlength_table[i]) {
+ hit = 1U;
+ break;
+ }
+ }
+ /* data length is valid */
+ if (1U == hit) {
+ reg_temp |= 9U + i;
+ } else {
+ CAN_ERROR_HANDLE("dlen is invalid \r\n");
+ }
+ }
+ reg_temp |= (((uint32_t)transmit_message->fd_brs << 5U) | ((uint32_t)transmit_message->fd_esi << 4U) | ((uint32_t)transmit_message->fd_flag << 7U));
+ CAN_TMP(can_periph, mailbox_number) = reg_temp;
+ /* set the data */
+ i = transmit_message->tx_dlen / 4U;
+ p_temp = (uint32_t)transmit_message->tx_data;
+ if (0U == i) {
+ CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
+ } else {
+ for (; i > 0U; i--) {
+ CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
+ p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
+ }
+ }
+ } else {
+ CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
+ }
+ }
+
+ /* enable transmission */
+ CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
+
+ return mailbox_number;
+}
+
+/*!
+ \brief get CAN transmit state
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] mailbox_number
+ only one parameter can be selected which is shown as below:
+ \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;
+
+ /* check selected mailbox state */
+ switch (mailbox_number) {
+ /* mailbox0 */
+ case CAN_MAILBOX0:
+ val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
+ break;
+ /* mailbox1 */
+ case CAN_MAILBOX1:
+ val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
+ break;
+ /* mailbox2 */
+ 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;
+ /* mailbox0 transmit succeeded */
+ case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
+ state = CAN_TRANSMIT_OK;
+ break;
+ /* mailbox1 transmit succeeded */
+ case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
+ state = CAN_TRANSMIT_OK;
+ break;
+ /* mailbox2 transmit succeeded */
+ case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
+ state = CAN_TRANSMIT_OK;
+ break;
+ /* transmit failed */
+ default:
+ state = CAN_TRANSMIT_FAILED;
+ break;
+ }
+ return state;
+}
+
+/*!
+ \brief stop CAN transmission
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] mailbox_number
+ only one parameter can be selected which is shown as below:
+ \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;
+ while (CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) {
+ }
+ } else if (CAN_MAILBOX1 == mailbox_number) {
+ CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
+ while (CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)) {
+ }
+ } else if (CAN_MAILBOX2 == mailbox_number) {
+ CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
+ while (CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)) {
+ }
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief CAN receive message
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] fifo_number
+ \arg CAN_FIFOx(x=0,1)
+ \param[out] receive_message: struct for CAN receive message
+ \arg rx_sfid: 0x00000000 - 0x000007FF
+ \arg rx_efid: 0x00000000 - 0x1FFFFFFF
+ \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
+ \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
+ \arg rx_dlenc: 1 - 7
+ \arg rx_data[]: 0x00 - 0xFF
+ \arg rx_fi: 0 - 27
+ \retval none
+*/
+void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message)
+{
+ uint32_t canfd_en = 0U;
+ volatile uint32_t p_temp;
+ uint32_t data_temp;
+ uint8_t canfd_recv_cnt = 0U;
+ uint8_t i;
+
+ /* 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)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
+ } else {
+ /* get extended identifier */
+ receive_message->rx_efid = (uint32_t)(GET_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));
+ /* filtering index */
+ receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
+ receive_message->fd_flag = (uint8_t)(CAN_RFIFOMP_FDF & CAN_RFIFOMP(can_periph, fifo_number));
+
+ if (CAN_FDF_CLASSIC == receive_message->fd_flag) {
+ /* get recevie data length */
+ receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
+ /* receive data */
+ receive_message->rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+ receive_message->rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+ receive_message->rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+ receive_message->rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
+ receive_message->rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+ receive_message->rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+ receive_message->rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+ receive_message->rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
+ } else {
+ canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
+ /* check FD funciton has been enabled */
+ if (canfd_en) {
+ /* get recevie data length */
+ canfd_recv_cnt = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
+
+ if (canfd_recv_cnt <= 8U) {
+ /* set the data length */
+ receive_message->rx_dlen = canfd_recv_cnt;
+ } else {
+ receive_message->rx_dlen = g_can_fdlength_table[canfd_recv_cnt - 9U];
+ }
+
+ receive_message->fd_brs = (uint8_t)((CAN_RFIFOMP(can_periph, fifo_number) & CAN_RFIFOMP_BRS) >> 5);
+ receive_message->fd_esi = (uint8_t)((CAN_RFIFOMP(can_periph, fifo_number) & CAN_RFIFOMP_ESI) >> 4);
+
+ /* get the data */
+ i = receive_message->rx_dlen / 4U;
+ p_temp = (uint32_t)(uint32_t)receive_message->rx_data;
+ if (0U == i) {
+ data_temp = CAN_RFIFOMDATA0(can_periph, fifo_number);
+ *(uint32_t *)p_temp = data_temp;
+ } else {
+ /* get the data by reading from CAN_RFIFOMDATA0 register*/
+ for (; i > 0U; i--) {
+ data_temp = CAN_RFIFOMDATA0(can_periph, fifo_number);
+ *(uint32_t *)p_temp = data_temp;
+ p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
+ }
+ }
+ } else {
+ CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
+ }
+ }
+
+ /* 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)
+ \param[in] fifo_number
+ only one parameter can be selected which is shown as below:
+ \arg CAN_FIFOx(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 parameters */
+ CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n");
+ }
+}
+
+/*!
+ \brief CAN receive message length
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] fifo_number
+ only one parameter can be selected which is shown as below:
+ \arg CAN_FIFOx(x=0,1)
+ \param[out] none
+ \retval message length
+*/
+uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number)
+{
+ uint8_t val = 0U;
+
+ if (CAN_FIFO0 == fifo_number) {
+ /* FIFO0 */
+ val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK);
+ } else if (CAN_FIFO1 == fifo_number) {
+ /* FIFO1 */
+ val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK);
+ } else {
+ /* illegal parameters */
+ }
+ return val;
+}
+
+/*!
+ \brief set CAN working mode
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] can_working_mode
+ only one parameter can be selected which is shown as below:
+ \arg CAN_MODE_INITIALIZE
+ \arg CAN_MODE_NORMAL
+ \arg CAN_MODE_SLEEP
+ \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)) && (0U != timeout)) {
+ 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))) && (0U != timeout)) {
+ 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)) && (0U != timeout)) {
+ 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)) && (0x00U != timeout)) {
+ timeout--;
+ }
+ /* check state */
+ 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
+ \arg CAN_ERROR_NONE: no error
+ \arg CAN_ERROR_FILL: fill error
+ \arg CAN_ERROR_FORMATE: format error
+ \arg CAN_ERROR_ACK: ACK error
+ \arg CAN_ERROR_BITRECESSIVE: bit recessive
+ \arg CAN_ERROR_BITDOMINANTER: bit dominant error
+ \arg CAN_ERROR_CRC: CRC error
+ \arg CAN_ERROR_SOFTWARECFG: software configure
+*/
+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)(GET_ERR_ERRN(CAN_ERR(can_periph)));
+ return error;
+}
+
+/*!
+ \brief get 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_get(uint32_t can_periph)
+{
+ uint8_t val;
+
+ /* get error count */
+ val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph)));
+ return val;
+}
+
+/*!
+ \brief get 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_get(uint32_t can_periph)
+{
+ uint8_t val;
+
+ val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph)));
+ return val;
+}
+
+/*!
+ \brief enable CAN interrupt
+ \param[in] can_periph
+ \arg CANx(x=0,1)
+ \param[in] interrupt
+ one or more parameters can be selected which are shown as below:
+ \arg CAN_INT_TME: transmit mailbox empty interrupt enable
+ \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
+ \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
+ \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
+ \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
+ \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
+ \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
+ \arg CAN_INT_WERR: warning error interrupt enable
+ \arg CAN_INT_PERR: passive error interrupt enable
+ \arg CAN_INT_BO: bus-off interrupt enable
+ \arg CAN_INT_ERRN: error number interrupt enable
+ \arg CAN_INT_ERR: error interrupt enable
+ \arg CAN_INT_WU: wakeup interrupt enable
+ \arg CAN_INT_SLPW: sleep working interrupt enable
+ \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
+ one or more parameters can be selected which are shown as below:
+ \arg CAN_INT_TME: transmit mailbox empty interrupt enable
+ \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
+ \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
+ \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
+ \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
+ \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
+ \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
+ \arg CAN_INT_WERR: warning error interrupt enable
+ \arg CAN_INT_PERR: passive error interrupt enable
+ \arg CAN_INT_BO: bus-off interrupt enable
+ \arg CAN_INT_ERRN: error number interrupt enable
+ \arg CAN_INT_ERR: error interrupt enable
+ \arg CAN_INT_WU: wakeup interrupt enable
+ \arg CAN_INT_SLPW: sleep working interrupt enable
+ \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: mailbox 2 transmit error
+ \arg CAN_FLAG_MTE1: mailbox 1 transmit error
+ \arg CAN_FLAG_MTE0: mailbox 0 transmit error
+ \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
+ \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
+ \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
+ \arg CAN_FLAG_RFO0: receive FIFO0 overfull
+ \arg CAN_FLAG_RFF0: receive FIFO0 full
+ \arg CAN_FLAG_RFO1: receive FIFO1 overfull
+ \arg CAN_FLAG_RFF1: receive FIFO1 full
+ \arg CAN_FLAG_BOERR: bus-off error
+ \arg CAN_FLAG_PERR: passive error
+ \arg CAN_FLAG_WERR: warning error
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
+{
+ /* get flag and interrupt enable state */
+ 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: mailbox 2 transmit error
+ \arg CAN_FLAG_MTE1: mailbox 1 transmit error
+ \arg CAN_FLAG_MTE0: mailbox 0 transmit error
+ \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
+ \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
+ \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
+ \arg CAN_FLAG_RFO0: receive FIFO0 overfull
+ \arg CAN_FLAG_RFF0: receive FIFO0 full
+ \arg CAN_FLAG_RFO1: receive FIFO1 overfull
+ \arg CAN_FLAG_RFF1: receive FIFO1 full
+ \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_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
+ \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
+ \arg CAN_INT_FLAG_ERRIF: error interrupt flag
+ \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
+ \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
+ \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
+ \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
+ \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
+ \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
+ \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
+{
+ uint32_t ret1 = RESET;
+ uint32_t ret2 = RESET;
+
+ /* get the staus of interrupt flag */
+ ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag));
+ /* get the staus of interrupt enale bit */
+ ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag));
+ if (ret1 && ret2) {
+ 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_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
+ \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
+ \arg CAN_INT_FLAG_ERRIF: error interrupt flag
+ \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
+ \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
+ \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
+ \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
+ \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
+ \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
+ \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
+ \param[out] none
+ \retval none
+*/
+void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag)
+{
+ CAN_REG_VALS(can_periph, flag) |= BIT(CAN_BIT_POS0(flag));
+}
+
+/*!
+ \brief auto config can baud rate by frequency
+ \param[in] freq: the frequency of the baud rate
+ \param[out] none
+ \retval none
+*/
+static unsigned int dev_can_baudrate_set(uint32_t freq)
+{
+ uint32_t reval;
+ uint32_t baud_psc;
+ uint32_t baud_psc_max;
+ uint32_t temp;
+ uint32_t bt_reg_config;
+ uint8_t flag;
+ uint32_t bits;
+
+ flag = 0U;
+ /* computes the value that the CAN_BT register needs to be configured */
+ /* (BAUDPSC[9:0] + 1) * ((BS1[3:0] + 1) + (BS2[2:0] + 1) + SJW(always 1)) */
+ bt_reg_config = (rcu_clock_freq_get(CK_APB1) / freq);
+ /* BAUDPSC[9:0] minimum value */
+ baud_psc = bt_reg_config / DEV_CAN_BT_SEG_MAX;
+ /* BAUDPSC[9:0] maximum value */
+ baud_psc_max = bt_reg_config / DEV_CAN_BT_SEG_MIN;
+
+ while ((!flag) && (baud_psc < baud_psc_max)) {
+ baud_psc++;
+ for (bits = 22u; bits > 0u; bits--) {
+ temp = (bits + 3U) * (baud_psc + 1U);
+ if (temp == bt_reg_config) {
+ flag = 1U;
+ break;
+ }
+ }
+ }
+
+ if (flag) {
+ reval = ((timing_pts[bits][1] << 20) & DEV_CAN_BS2_MASK)
+ | ((timing_pts[bits][0] << 16) & DEV_CAN_BS1_MASK)
+ | ((0U << 24) & DEV_CAN_SJW_MASK)
+ | ((baud_psc) & DEV_CAN_BAUDPSC_MASK);
+ } else {
+ /* CAN_BT register reset value */
+ reval = 0x01230000U;
+ CAN_ERROR_HANDLE("CAN baud rate config fail!! \r\n");
+ }
+
+ return reval;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_crc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_crc.c
new file mode 100644
index 0000000000..661b076924
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_crc.c
@@ -0,0 +1,130 @@
+/*!
+ \file gd32e10x_crc.c
+ \brief CRC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_crc.h"
+
+#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU)
+#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U)
+
+/*!
+ \brief deinit CRC calculation unit
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void crc_deinit(void)
+{
+ CRC_DATA = CRC_DATA_RESET_VALUE;
+ CRC_FDATA = CRC_FDATA_RESET_VALUE;
+ CRC_CTL = (uint32_t)CRC_CTL_RST;
+}
+
+/*!
+ \brief reset data register(CRC_DATA) to the value of 0xFFFFFFFF
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void crc_data_register_reset(void)
+{
+ CRC_CTL |= (uint32_t)CRC_CTL_RST;
+}
+
+/*!
+ \brief read the value of 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 value of 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 data to 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 calculate the CRC value of a 32-bit data
+ \param[in] sdata: specified 32-bit data
+ \param[out] none
+ \retval 32-bit value calculated by CRC
+*/
+uint32_t crc_single_data_calculate(uint32_t sdata)
+{
+ CRC_DATA = sdata;
+ return (CRC_DATA);
+}
+
+/*!
+ \brief calculate the CRC value of an array of 32-bit values
+ \param[in] array: pointer to an array of 32-bit values
+ \param[in] size: size of the array
+ \param[out] none
+ \retval 32-bit value calculated by CRC
+*/
+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);
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_ctc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_ctc.c
new file mode 100644
index 0000000000..ce9d8aad59
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_ctc.c
@@ -0,0 +1,392 @@
+/*!
+ \file gd32e10x_ctc.c
+ \brief CTC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_ctc.h"
+
+#define CTC_FLAG_MASK ((uint32_t)0x00000700U)
+
+/* CTC register bit offset */
+#define CTC_TRIMVALUE_OFFSET ((uint32_t)8U)
+#define CTC_TRIM_VALUE_OFFSET ((uint32_t)8U)
+#define CTC_REFCAP_OFFSET ((uint32_t)16U)
+#define CTC_LIMIT_VALUE_OFFSET ((uint32_t)16U)
+
+/*!
+ \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 enable CTC trim counter
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ctc_counter_enable(void)
+{
+ CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN;
+}
+
+/*!
+ \brief disable CTC trim counter
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ctc_counter_disable(void)
+{
+ CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN);
+}
+
+/*!
+ \brief configure the IRC48M trim value
+ \param[in] ctc_trim_value: 8-bit IRC48M trim value
+ \arg 0x00 - 0x3F
+ \param[out] none
+ \retval none
+*/
+void ctc_irc48m_trim_value_config(uint8_t trim_value)
+{
+ /* clear TRIMVALUE bits */
+ CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE);
+ /* set TRIMVALUE bits */
+ CTC_CTL0 |= ((uint32_t)trim_value << CTC_TRIM_VALUE_OFFSET);
+}
+
+/*!
+ \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] hardmode:
+ only one parameter can be selected which is shown as below:
+ \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 hardmode)
+{
+ CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM);
+ CTC_CTL0 |= (uint32_t)hardmode;
+}
+
+/*!
+ \brief configure reference signal source polarity
+ \param[in] polarity:
+ only one parameter can be selected which is shown as below:
+ \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 polarity)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL);
+ CTC_CTL1 |= (uint32_t)polarity;
+}
+
+/*!
+ \brief select reference signal source
+ \param[in] refs:
+ only one parameter can be selected which is shown as below:
+ \arg CTC_REFSOURCE_GPIO: GPIO is selected
+ \arg CTC_REFSOURCE_LXTAL: LXTAL is selected
+ \arg CTC_REFSOURCE_USBSOF: USBFS_SOF is selected
+ \param[out] none
+ \retval none
+*/
+void ctc_refsource_signal_select(uint32_t refs)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
+ CTC_CTL1 |= (uint32_t)refs;
+}
+
+/*!
+ \brief configure reference signal source prescaler
+ \param[in] prescaler:
+ only one parameter can be selected which is shown as below:
+ \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 prescaler)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
+ CTC_CTL1 |= (uint32_t)prescaler;
+}
+
+/*!
+ \brief configure clock trim base limit value
+ \param[in] limit_value: 8-bit clock trim base limit value
+ \arg 0x00 - 0xFF
+ \param[out] none
+ \retval none
+*/
+void ctc_clock_limit_value_config(uint8_t limit_value)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
+ CTC_CTL1 |= (uint32_t)((uint32_t)limit_value << CTC_LIMIT_VALUE_OFFSET);
+}
+
+/*!
+ \brief configure CTC counter reload value
+ \param[in] reload_value: 16-bit CTC counter reload value
+ \arg 0x0000 - 0xFFFF
+ \param[out] none
+ \retval none
+*/
+void ctc_counter_reload_value_config(uint16_t reload_value)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
+ CTC_CTL1 |= (uint32_t)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) >> CTC_REFCAP_OFFSET);
+ 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) >> CTC_TRIMVALUE_OFFSET);
+ return (trim_value);
+}
+
+/*!
+ \brief enable the CTC interrupt
+ \param[in] interrupt: CTC interrupt enable
+ one or more parameters can be selected which are shown as below:
+ \arg CTC_INT_CKOK: clock trim OK interrupt enable
+ \arg CTC_INT_CKWARN: clock trim warning interrupt enable
+ \arg CTC_INT_ERR: error interrupt enable
+ \arg CTC_INT_EREF: expect reference interrupt enable
+ \param[out] none
+ \retval none
+*/
+void ctc_interrupt_enable(uint32_t interrupt)
+{
+ CTC_CTL0 |= (uint32_t)interrupt;
+}
+
+/*!
+ \brief disable the CTC interrupt
+ \param[in] interrupt: CTC interrupt enable source
+ one or more parameters can be selected which are shown as below:
+ \arg CTC_INT_CKOK: clock trim OK interrupt enable
+ \arg CTC_INT_CKWARN: clock trim warning interrupt enable
+ \arg CTC_INT_ERR: error interrupt enable
+ \arg CTC_INT_EREF: expect reference interrupt enable
+ \param[out] none
+ \retval none
+*/
+void ctc_interrupt_disable(uint32_t interrupt)
+{
+ CTC_CTL0 &= (uint32_t)(~interrupt);
+}
+
+/*!
+ \brief get CTC interrupt flag
+ \param[in] interrupt: the CTC interrupt flag
+ only one parameter can be selected which is shown as below:
+ \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
+ \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
+ \arg CTC_INT_FLAG_ERR: error interrupt
+ \arg CTC_INT_FLAG_EREF: expect reference interrupt
+ \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
+ \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
+ \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus ctc_interrupt_flag_get(uint32_t interrupt)
+{
+ uint32_t intflag = 0U, intenable = 0U;
+
+ /* check whether the interrupt is enabled */
+ if (RESET != (interrupt & CTC_FLAG_MASK)) {
+ intenable = CTC_CTL0 & CTC_CTL0_ERRIE;
+ } else {
+ intenable = CTC_CTL0 & interrupt;
+ }
+
+ /* get interrupt flag status */
+ intflag = CTC_STAT & interrupt;
+
+ if (intflag && intenable) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear CTC interrupt flag
+ \param[in] interrupt: the CTC interrupt flag
+ only one parameter can be selected which is shown as below:
+ \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
+ \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
+ \arg CTC_INT_FLAG_ERR: error interrupt
+ \arg CTC_INT_FLAG_EREF: expect reference interrupt
+ \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
+ \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
+ \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
+ \param[out] none
+ \retval none
+*/
+void ctc_interrupt_flag_clear(uint32_t interrupt)
+{
+ if (RESET != (interrupt & CTC_FLAG_MASK)) {
+ CTC_INTC |= CTC_INTC_ERRIC;
+ } else {
+ CTC_INTC |= interrupt;
+ }
+}
+
+/*!
+ \brief get CTC flag
+ \param[in] flag: the CTC flag
+ only one parameter can be selected which is shown as below:
+ \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 flag)
+{
+ if (RESET != (CTC_STAT & flag)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear CTC flag
+ \param[in] flag: the CTC flag
+ only one parameter can be selected which is shown as below:
+ \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 flag)
+{
+ if (RESET != (flag & CTC_FLAG_MASK)) {
+ CTC_INTC |= CTC_INTC_ERRIC;
+ } else {
+ CTC_INTC |= flag;
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dac.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dac.c
new file mode 100644
index 0000000000..eb2eef5a2e
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dac.c
@@ -0,0 +1,557 @@
+/*!
+ \file gd32e10x_dac.c
+ \brief DAC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_dac.h"
+
+/* DAC register bit offset */
+#define DAC1_REG_OFFSET ((uint32_t)16U)
+#define DH_12BIT_OFFSET ((uint32_t)16U)
+#define DH_8BIT_OFFSET ((uint32_t)8U)
+
+/*!
+ \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 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) {
+ /* store the DAC0 output value */
+ data = (uint16_t)DAC0_DO;
+ } else {
+ /* store the DAC1 output value */
+ data = (uint16_t)DAC1_DO;
+ }
+ return data;
+}
+
+/*!
+ \brief set the DAC specified data holding register value
+ \param[in] dac_periph
+ \arg DACx(x=0,1)
+ \param[in] dac_align
+ only one parameter can be selected which is shown as below:
+ \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 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 set DAC trigger source
+ \param[in] dac_periph
+ \arg DACx(x=0,1)
+ \param[in] triggersource: external triggers of DAC
+ only one parameter can be selected which is shown as below:
+ \arg DAC_TRIGGER_T1_TRGO: TIMER1 TRGO
+ \arg DAC_TRIGGER_T2_TRGO: TIMER2 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_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) {
+ /* configure DAC0 trigger source */
+ DAC_CTL &= ~DAC_CTL_DTSEL0;
+ DAC_CTL |= triggersource;
+ } else {
+ /* configure DAC1 trigger source */
+ DAC_CTL &= ~DAC_CTL_DTSEL1;
+ DAC_CTL |= (triggersource << DAC1_REG_OFFSET);
+ }
+}
+
+/*!
+ \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 configure DAC wave mode
+ \param[in] dac_periph
+ \arg DACx(x=0,1)
+ \param[in] wave_mode
+ only one parameter can be selected which is shown as below:
+ \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) {
+ /* configure DAC0 wave mode */
+ DAC_CTL &= ~DAC_CTL_DWM0;
+ DAC_CTL |= wave_mode;
+ } else {
+ /* configure DAC1 wave mode */
+ DAC_CTL &= ~DAC_CTL_DWM1;
+ DAC_CTL |= (wave_mode << DAC1_REG_OFFSET);
+ }
+}
+
+/*!
+ \brief configure DAC wave bit width
+ \param[in] dac_periph
+ \arg DACx(x=0,1)
+ \param[in] bit_width
+ only one parameter can be selected which is shown as below:
+ \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) {
+ /* configure DAC0 wave bit width */
+ DAC_CTL &= ~DAC_CTL_DWBW0;
+ DAC_CTL |= bit_width;
+ } else {
+ /* configure DAC1 wave bit width */
+ DAC_CTL &= ~DAC_CTL_DWBW1;
+ DAC_CTL |= (bit_width << DAC1_REG_OFFSET);
+ }
+}
+
+/*!
+ \brief configure DAC LFSR noise mode
+ \param[in] dac_periph
+ \arg DACx(x=0,1)
+ \param[in] unmask_bits
+ only one parameter can be selected which is shown as below:
+ \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) {
+ /* configure DAC0 LFSR noise mode */
+ DAC_CTL &= ~DAC_CTL_DWBW0;
+ DAC_CTL |= unmask_bits;
+ } else {
+ /* configure DAC1 LFSR noise mode */
+ DAC_CTL &= ~DAC_CTL_DWBW1;
+ DAC_CTL |= (unmask_bits << DAC1_REG_OFFSET);
+ }
+}
+
+/*!
+ \brief configure DAC triangle noise mode
+ \param[in] dac_periph
+ \arg DACx(x=0,1)
+ \param[in] amplitude
+ only one parameter can be selected which is shown as below:
+ \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) {
+ /* configure DAC0 triangle noise mode */
+ DAC_CTL &= ~DAC_CTL_DWBW0;
+ DAC_CTL |= amplitude;
+ } else {
+ /* configure DAC1 triangle noise mode */
+ DAC_CTL &= ~DAC_CTL_DWBW1;
+ DAC_CTL |= (amplitude << DAC1_REG_OFFSET);
+ }
+}
+
+/*!
+ \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 set DAC concurrent mode data holding register value
+ \param[in] dac_align
+ only one parameter can be selected which is shown as below:
+ \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 << DH_12BIT_OFFSET) | data0;
+ DACC_R12DH = data;
+ break;
+ /* data left 12b alignment */
+ case DAC_ALIGN_12B_L:
+ data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0;
+ DACC_L12DH = data;
+ break;
+ /* data right 8b alignment */
+ case DAC_ALIGN_8B_R:
+ data = ((uint32_t)data1 << DH_8BIT_OFFSET) | data0;
+ DACC_R8DH = data;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dbg.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dbg.c
new file mode 100644
index 0000000000..2863553dad
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dbg.c
@@ -0,0 +1,152 @@
+/*!
+ \file gd32e10x_dbg.c
+ \brief DBG driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_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:
+ one or more parameters can be selected which are shown as below:
+ \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_CTL |= dbg_low_power;
+}
+
+/*!
+ \brief disable low power behavior when the mcu is in debug mode
+ \param[in] dbg_low_power:
+ one or more parameters can be selected which are shown as below:
+ \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_CTL &= ~dbg_low_power;
+}
+
+/*!
+ \brief enable peripheral behavior when the mcu is in debug mode
+ \param[in] dbg_periph: refer to dbg_periph_enum
+ one or more parameters can be selected which are shown as below:
+ \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted
+ \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted
+ \arg DBG_CANx_HOLD (x=0,1,CAN1 is only available for CL series): hold CANx counter when core is halted
+ \arg DBG_I2Cx_HOLD (x=0,1): hold I2Cx smbus when core is halted
+ \arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13,TIMER8..13 are not available for HD series): hold TIMERx counter when core is halted
+ \param[out] none
+ \retval none
+*/
+void dbg_periph_enable(dbg_periph_enum dbg_periph)
+{
+ DBG_CTL |= (uint32_t)dbg_periph;
+}
+
+/*!
+ \brief disable peripheral behavior when the mcu is in debug mode
+ \param[in] dbg_periph: refer to dbg_periph_enum
+ one or more parameters can be selected which are shown as below:
+ \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted
+ \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted
+ \arg DBG_CANx_HOLD (x=0,1,CAN1 is only available for CL series): hold CAN0 counter when core is halted
+ \arg DBG_I2Cx_HOLD (x=0,1): hold I2Cx smbus when core is halted
+ \arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): hold TIMERx counter when core is halted
+ \param[out] none
+ \retval none
+*/
+void dbg_periph_disable(dbg_periph_enum dbg_periph)
+{
+ DBG_CTL &= ~(uint32_t)dbg_periph;
+}
+
+/*!
+ \brief enable trace pin assignment
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dbg_trace_pin_enable(void)
+{
+ DBG_CTL |= DBG_CTL_TRACE_IOEN;
+}
+
+/*!
+ \brief disable trace pin assignment
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dbg_trace_pin_disable(void)
+{
+ DBG_CTL &= ~DBG_CTL_TRACE_IOEN;
+}
+
+/*!
+ \brief trace pin mode selection
+ \param[in] trace_mode:
+ only one parameter can be selected which is shown as below:
+ \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_CTL &= ~DBG_CTL_TRACE_MODE;
+ DBG_CTL |= trace_mode;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dma.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dma.c
new file mode 100644
index 0000000000..cbd3de72b6
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_dma.c
@@ -0,0 +1,739 @@
+/*!
+ \file gd32e10x_dma.c
+ \brief DMA driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_dma.h"
+
+#define DMA_WRONG_HANDLE while(1){}
+
+/* check whether peripheral matches channels or not */
+static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx);
+
+/*!
+ \brief deinitialize DMA a channel registers
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel is deinitialized
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ /* disable the DMA 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_CHMADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE;
+ DMA_INTC(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
+}
+
+/*!
+ \brief initialize the parameters of DMA struct with the default values
+ \param[in] init_struct: the initialization data needed to initialize DMA channel
+ \param[out] none
+ \retval none
+*/
+void dma_struct_para_init(dma_parameter_struct *init_struct)
+{
+ /* set the DMA struct with the default values */
+ init_struct->periph_addr = 0U;
+ init_struct->periph_width = 0U;
+ init_struct->periph_inc = DMA_PERIPH_INCREASE_DISABLE;
+ init_struct->memory_addr = 0U;
+ init_struct->memory_width = 0U;
+ init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE;
+ init_struct->number = 0U;
+ init_struct->direction = DMA_PERIPHERAL_TO_MEMORY;
+ init_struct->priority = DMA_PRIORITY_LOW;
+}
+
+/*!
+ \brief initialize DMA channel
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel is initialized
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] init_struct: the data needed to initialize DMA channel
+ periph_addr: peripheral base address
+ periph_width: DMA_PERIPHERAL_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_16BIT, DMA_PERIPHERAL_WIDTH_32BIT
+ periph_inc: DMA_PERIPH_INCREASE_ENABLE, DMA_PERIPH_INCREASE_DISABLE
+ memory_addr: memory 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_PERIPHERAL_TO_MEMORY, DMA_MEMORY_TO_PERIPHERAL
+ 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
+ \param[out] none
+ \retval none
+*/
+#ifdef GD_MBED_USED
+void dma_para_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct *init_struct)
+#else
+void dma_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct *init_struct)
+#endif
+{
+ uint32_t ctl;
+
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ /* configure peripheral base address */
+ DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr;
+
+ /* configure memory base address */
+ DMA_CHMADDR(dma_periph, channelx) = init_struct->memory_addr;
+
+ /* configure the number of remaining data to be transferred */
+ DMA_CHCNT(dma_periph, channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK);
+
+ /* configure peripheral transfer width,memory transfer width and priority */
+ ctl = DMA_CHCTL(dma_periph, channelx);
+ ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO);
+ ctl |= (init_struct->periph_width | init_struct->memory_width | init_struct->priority);
+ 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 {
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
+ }
+
+ /* 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 the direction of data transfer */
+ if (DMA_PERIPHERAL_TO_MEMORY == init_struct->direction) {
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR;
+ } else {
+ DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR;
+ }
+}
+
+/*!
+ \brief enable DMA circulation mode
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ 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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN;
+}
+
+/*!
+ \brief enable memory to memory mode
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_M2M;
+}
+
+/*!
+ \brief disable memory to memory mode
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_M2M;
+}
+
+/*!
+ \brief enable DMA channel
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ 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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
+}
+
+/*!
+ \brief set DMA peripheral base address
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \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)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHPADDR(dma_periph, channelx) = address;
+}
+
+/*!
+ \brief set DMA memory base address
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] address: memory base address
+ \param[out] none
+ \retval none
+*/
+void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHMADDR(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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] number: the number of remaining data to be transferred by the DMA
+ \arg 0x0000-0xFFFF
+ \param[out] none
+ \retval none
+*/
+void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCNT(dma_periph, channelx) = (number & DMA_CHANNEL_CNT_MASK);
+}
+
+/*!
+ \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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \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)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ 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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] priority: priority level of this channel
+ only one parameter can be selected which is shown as below:
+ \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;
+
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ /* 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 data size of memory
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] mwidth: transfer data width of memory
+ only one parameter can be selected which is shown as below:
+ \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit
+ \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit
+ \arg DMA_MEMORY_WIDTH_32BIT: transfer data width 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 mwidth)
+{
+ uint32_t ctl;
+
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ /* acquire DMA_CHxCTL register */
+ ctl = DMA_CHCTL(dma_periph, channelx);
+ /* assign regiser */
+ ctl &= ~DMA_CHXCTL_MWIDTH;
+ ctl |= mwidth;
+ 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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] pwidth: transfer data width of peripheral
+ only one parameter can be selected which is shown as below:
+ \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit
+ \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit
+ \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width 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 pwidth)
+{
+ uint32_t ctl;
+
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ /* acquire DMA_CHxCTL register */
+ ctl = DMA_CHCTL(dma_periph, channelx);
+ /* assign regiser */
+ ctl &= ~DMA_CHXCTL_PWIDTH;
+ ctl |= pwidth;
+ DMA_CHCTL(dma_periph, channelx) = ctl;
+}
+
+/*!
+ \brief enable next address increasement algorithm of memory
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
+}
+
+/*!
+ \brief disable next address increasement algorithm of memory
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
+}
+
+/*!
+ \brief enable next address increasement algorithm of peripheral
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
+}
+
+/*!
+ \brief disable next address increasement algorithm of peripheral
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[out] none
+ \retval none
+*/
+void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
+}
+
+/*!
+ \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: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] direction: specify the direction of data transfer
+ only one parameter can be selected which is shown as below:
+ \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory
+ \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral
+ \param[out] none
+ \retval none
+*/
+void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ if (DMA_PERIPHERAL_TO_MEMORY == direction) {
+ DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR;
+ } else {
+ DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR;
+ }
+}
+
+/*!
+ \brief check DMA flag is set or not
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel to get flag
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] flag: specify get which flag
+ only one parameter can be selected which is shown as below:
+ \arg DMA_FLAG_G: global interrupt flag of channel
+ \arg DMA_FLAG_FTF: full transfer finish flag of channel
+ \arg DMA_FLAG_HTF: half transfer finish flag of channel
+ \arg DMA_FLAG_ERR: error flag of channel
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
+{
+ FlagStatus reval;
+
+ /* check whether the flag is set or not */
+ if (RESET != (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx))) {
+ reval = SET;
+ } else {
+ reval = RESET;
+ }
+
+ return reval;
+}
+
+/*!
+ \brief clear the flag of a DMA channel
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel to clear flag
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] flag: specify get which flag
+ only one parameter can be selected which is shown as below:
+ \arg DMA_FLAG_G: global interrupt flag of channel
+ \arg DMA_FLAG_FTF: full transfer finish flag of channel
+ \arg DMA_FLAG_HTF: half transfer finish flag of channel
+ \arg DMA_FLAG_ERR: error flag of channel
+ \param[out] none
+ \retval none
+*/
+void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
+{
+ DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
+}
+
+/*!
+ \brief check DMA flag and interrupt enable bit is set or not
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel to get flag
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] flag: specify get which flag
+ only one parameter can be selected which is shown as below:
+ \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
+ \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
+ \arg DMA_INT_FLAG_ERR: error interrupt flag of channel
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
+{
+ uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
+
+ switch (flag) {
+ case DMA_INT_FLAG_FTF:
+ /* check whether the full transfer finish interrupt flag is set and enabled */
+ interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
+ interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
+ break;
+ case DMA_INT_FLAG_HTF:
+ /* check whether the half transfer finish interrupt flag is set and enabled */
+ interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
+ interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
+ break;
+ case DMA_INT_FLAG_ERR:
+ /* check whether the error interrupt flag is set and enabled */
+ interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
+ interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE;
+ break;
+ default:
+ DMA_WRONG_HANDLE
+ }
+
+ /* when the interrupt flag is set and enabled, return SET */
+ if ((0U != interrupt_flag) && (0U != interrupt_enable)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear the interrupt flag of a DMA channel
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] flag: specify get which flag
+ only one parameter can be selected which is shown as below:
+ \arg DMA_INT_FLAG_G: global interrupt flag of channel
+ \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
+ \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
+ \arg DMA_INT_FLAG_ERR: error interrupt flag of channel
+ \param[out] none
+ \retval none
+*/
+void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
+{
+ DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
+}
+
+/*!
+ \brief enable DMA interrupt
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] source: specify which interrupt to enbale
+ one or more parameters can be selected which are shown as below
+ \arg DMA_INT_FTF: channel full transfer finish interrupt
+ \arg DMA_INT_HTF: channel half transfer finish interrupt
+ \arg DMA_INT_ERR: channel error interrupt
+ \param[out] none
+ \retval none
+*/
+void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) |= source;
+}
+
+/*!
+ \brief disable DMA interrupt
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
+ \param[in] source: specify which interrupt to disbale
+ one or more parameters can be selected which are shown as below
+ \arg DMA_INT_FTF: channel full transfer finish interrupt
+ \arg DMA_INT_HTF: channel half transfer finish interrupt
+ \arg DMA_INT_ERR: channel error interrupt
+ \param[out] none
+ \retval none
+*/
+void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
+{
+ if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
+ DMA_WRONG_HANDLE
+ }
+
+ DMA_CHCTL(dma_periph, channelx) &= ~source;
+}
+
+/*!
+ \brief check whether peripheral matches channels or not
+ \param[in] dma_periph: DMAx(x=0,1)
+ \arg DMAx(x=0,1)
+ \param[in] channelx: specified DMA channel
+ only one parameter can be selected which is shown as below:
+ \arg DMA_CHx(x=0..6)
+ \param[out] none
+ \retval ErrStatus: SUCCESS or ERROR
+*/
+static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx)
+{
+ ErrStatus val = SUCCESS;
+
+ if (DMA1 == dma_periph) {
+ /* for DMA1, the channel is from DMA_CH0 to DMA_CH4 */
+ if (channelx > DMA_CH4) {
+ val = ERROR;
+ }
+ }
+
+ return val;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_exmc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_exmc.c
new file mode 100644
index 0000000000..6efd98608b
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_exmc.c
@@ -0,0 +1,232 @@
+/*!
+ \file gd32e10x_exmc.c
+ \brief EXMC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_exmc.h"
+
+/* EXMC bank0 register reset value */
+#define BANK0_SNCTL_RESET ((uint32_t)0x000030DBU)
+#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
+#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU)
+
+/* 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 SNWTCFG_WAHLD_OFFSET ((uint32_t)4U)
+#define SNWTCFG_WDSET_OFFSET ((uint32_t)8U)
+#define SNWTCFG_WBUSLAT_OFFSET ((uint32_t)16U)
+
+/*!
+ \brief deinitialize EXMC NOR/SRAM bank
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void exmc_norsram_deinit(void)
+{
+ /* reset the registers */
+ EXMC_SNCTL = BANK0_SNCTL_RESET;
+
+ EXMC_SNTCFG = BANK0_SNTCFG_RESET;
+ EXMC_SNWTCFG = BANK0_SNWTCFG_RESET;
+}
+
+/*!
+ \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_struct_para_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct)
+{
+ /* configure the structure with default value */
+ exmc_norsram_init_struct->address_data_mux = ENABLE;
+ exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_NOR;
+ exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
+ 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 initialize EXMC NOR/SRAM bank
+ \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
+ 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;
+
+ /* clear relative bits */
+ snctl &= ((uint32_t)~(EXMC_SNCTL_NRMUX | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
+ EXMC_SNCTL_NREN | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG |
+ EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT |
+ EXMC_SNCTL_SYNCWR));
+
+ 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 - 1U) & EXMC_SNTCFG_ASET) |
+ (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U) << SNTCFG_AHLD_OFFSET) & EXMC_SNTCFG_AHLD) |
+ (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U) << SNTCFG_DSET_OFFSET) & EXMC_SNTCFG_DSET) |
+ (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U) << SNTCFG_BUSLAT_OFFSET) & EXMC_SNTCFG_BUSLAT) |
+ 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 - 1U) & EXMC_SNWTCFG_WASET) |
+ (((exmc_norsram_init_struct->write_timing->asyn_address_holdtime - 1U) << SNWTCFG_WAHLD_OFFSET) & EXMC_SNWTCFG_WAHLD) |
+ (((exmc_norsram_init_struct->write_timing->asyn_data_setuptime - 1U) << SNWTCFG_WDSET_OFFSET) & EXMC_SNWTCFG_WDSET) |
+ (((exmc_norsram_init_struct->write_timing->bus_latency - 1U) << SNWTCFG_WBUSLAT_OFFSET) & EXMC_SNWTCFG_WBUSLAT) |
+ exmc_norsram_init_struct->write_timing->asyn_access_mode;
+ } else {
+ snwtcfg = BANK0_SNWTCFG_RESET;
+ }
+
+ /* configure the registers */
+ EXMC_SNCTL = snctl;
+ EXMC_SNTCFG = sntcfg;
+ EXMC_SNWTCFG = snwtcfg;
+}
+
+/*!
+ \brief enable EXMC NOR/PSRAM bank
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void exmc_norsram_enable(void)
+{
+ EXMC_SNCTL |= (uint32_t)EXMC_SNCTL_NRBKEN;
+}
+
+/*!
+ \brief disable EXMC NOR/PSRAM bank
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void exmc_norsram_disable(void)
+{
+ EXMC_SNCTL &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
+}
+
+/*!
+ \brief configure CRAM page size
+ \param[in] page_size: CRAM page size
+ only one parameter can be selected which is shown as below:
+ \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_SNCTL_CPS;
+ /* set the CPS bits */
+ EXMC_SNCTL |= page_size;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_exti.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_exti.c
new file mode 100644
index 0000000000..4be4c233c1
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_exti.c
@@ -0,0 +1,253 @@
+/*!
+ \file gd32e10x_exti.c
+ \brief EXTI driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_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..18): 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..18): 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..18): 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..18): 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..18): 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..18): EXTI line x
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+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..18): 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 interrupt 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..18): EXTI line x
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+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..18): 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..18): 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..18): EXTI line x
+ \param[out] none
+ \retval none
+*/
+void exti_software_interrupt_disable(exti_line_enum linex)
+{
+ EXTI_SWIEV &= ~(uint32_t)linex;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_fmc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_fmc.c
new file mode 100644
index 0000000000..7b8501515f
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_fmc.c
@@ -0,0 +1,865 @@
+/*!
+ \file gd32e10x_fmc.c
+ \brief FMC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_fmc.h"
+
+/* FMC register bit offset */
+#define OB_WP1_WP1_OFFSET ((uint32_t)8U)
+#define OB_WP2_WP2_OFFSET ((uint32_t)16U)
+#define OB_WP3_WP3_OFFSET ((uint32_t)24U)
+#define FMC_OBSTAT_USER_OFFSET ((uint32_t)2U)
+#define FMC_OBSTAT_DATA_OFFSET ((uint32_t)10U)
+
+/* return the FMC state */
+static fmc_state_enum fmc_state_get(void);
+/* check FMC ready or not */
+static fmc_state_enum fmc_ready_wait(uint32_t timeout);
+
+/*!
+ \brief set the wait state counter value
+ \param[in] wscnt:wait state counter value
+ only one parameter can be selected which is shown as below:
+ \arg FMC_WAIT_STATE_0: FMC 0 wait
+ \arg FMC_WAIT_STATE_1: FMC 1 wait
+ \arg FMC_WAIT_STATE_2: FMC 2 wait
+ \arg FMC_WAIT_STATE_3: FMC 3 wait
+ \param[out] none
+ \retval none
+*/
+void fmc_wscnt_set(uint32_t wscnt)
+{
+ uint32_t ws;
+
+ ws = FMC_WS;
+ /* set the wait state counter value */
+ ws &= ~FMC_WS_WSCNT;
+ FMC_WS = (ws | wscnt);
+}
+
+/*!
+ \brief enable pre-fetch
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_prefetch_enable(void)
+{
+ FMC_WS |= FMC_WS_PFEN;
+}
+
+/*!
+ \brief disable pre-fetch
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_prefetch_disable(void)
+{
+ FMC_WS &= ~FMC_WS_PFEN;
+}
+
+/*!
+ \brief enable IBUS cache
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_ibus_enable(void)
+{
+ FMC_WS |= FMC_WS_ICEN;
+}
+
+/*!
+ \brief disable IBUS cache
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_ibus_disable(void)
+{
+ FMC_WS &= ~FMC_WS_ICEN;
+}
+
+/*!
+ \brief enable DBUS cache
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_dbus_enable(void)
+{
+ FMC_WS |= FMC_WS_DCEN;
+}
+
+/*!
+ \brief disable DBUS cache
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_dbus_disable(void)
+{
+ FMC_WS &= ~FMC_WS_DCEN;
+}
+
+/*!
+ \brief reset IBUS cache
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_ibus_reset(void)
+{
+ FMC_WS |= FMC_WS_ICRST;
+}
+
+/*!
+ \brief reset DBUS cache
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_dbus_reset(void)
+{
+ FMC_WS |= FMC_WS_DCRST;
+}
+
+/*!
+ \brief set program width to flash memory
+ \param[in] pgw
+ only one parameter can be selected which is shown as below:
+ \arg FMC_PROG_W_32B: 32-bit program width to flash memory
+ \arg FMC_PROG_W_64B: 64-bit program width to flash memory
+ \param[out] none
+ \retval none
+*/
+void fmc_program_width_set(uint32_t pgw)
+{
+ uint32_t ws = 0U;
+
+ /* configure program width to flash memory */
+ ws = FMC_WS;
+ ws &= ~FMC_WS_PGW;
+ ws |= pgw;
+ FMC_WS = ws;
+}
+
+/*!
+ \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 unlock 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 page
+ \param[in] page_address: the page address to be erased
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum fmc_page_erase(uint32_t page_address)
+{
+ fmc_state_enum fmc_state;
+
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ /* if the last operation is completed, start page erase */
+ if (FMC_READY == fmc_state) {
+ FMC_CTL |= FMC_CTL_PER;
+ FMC_ADDR = page_address;
+ FMC_CTL |= FMC_CTL_START;
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ /* reset the PER bit */
+ FMC_CTL &= ~FMC_CTL_PER;
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief erase whole chip
+ \param[in] none
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum fmc_mass_erase(void)
+{
+ fmc_state_enum fmc_state;
+
+ /* 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_MER;
+ FMC_CTL |= FMC_CTL_START;
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ /* reset the MER bit */
+ FMC_CTL &= ~FMC_CTL_MER;
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief program a double word at the corresponding address
+ \param[in] address: address to program
+ \param[in] data: double word to program
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data)
+{
+ fmc_state_enum fmc_state = 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_PG;
+ *(__IO uint64_t *)(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 word at the corresponding address
+ \param[in] address: address to program
+ \param[in] data: word to program
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum fmc_word_program(uint32_t address, uint32_t data)
+{
+ fmc_state_enum fmc_state = 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_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 state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data)
+{
+ fmc_state_enum fmc_state = 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_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 unlock the option bytes operation
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ob_unlock(void)
+{
+ if (RESET == (FMC_CTL & FMC_CTL_OBWEN)) {
+ /* write the FMC key */
+ FMC_OBKEY = UNLOCK_KEY0;
+ FMC_OBKEY = UNLOCK_KEY1;
+ }
+}
+
+/*!
+ \brief lock the option bytes operation
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ob_lock(void)
+{
+ /* reset the OBWEN bit */
+ FMC_CTL &= ~FMC_CTL_OBWEN;
+}
+
+/*!
+ \brief erase the FMC option bytes
+ unlock the FMC_CTL and option bytes before calling this function
+ \param[in] none
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum ob_erase(void)
+{
+ uint16_t temp_spc = FMC_NSPC;
+ uint32_t temp;
+
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ /* check the option bytes security protection value */
+ if (RESET != ob_security_protection_flag_get()) {
+ temp_spc = FMC_USPC;
+ }
+
+ if (FMC_READY == fmc_state) {
+
+ /* start erase the option bytes */
+ FMC_CTL |= FMC_CTL_OBER;
+ FMC_CTL |= FMC_CTL_START;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_READY == fmc_state) {
+ /* reset the OBER bit */
+ FMC_CTL &= ~FMC_CTL_OBER;
+ /* set the OBPG bit */
+ FMC_CTL |= FMC_CTL_OBPG;
+ temp = ((uint32_t)temp_spc) | 0xffff0000;
+ /* no security protection */
+ OB_SPC = temp;
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBPG bit */
+ FMC_CTL &= ~FMC_CTL_OBPG;
+ }
+ } else {
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBPG bit */
+ FMC_CTL &= ~FMC_CTL_OBPG;
+ }
+ }
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief enable write protection
+ \param[in] ob_wp: specify sector to be write protected
+ one or more parameters can be selected which are shown as below:
+ \arg OB_WP_ALL: write protect all sector
+ \arg OB_WPx(x=0..31): write protect specify sector
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum ob_write_protection_enable(uint32_t ob_wp)
+{
+ uint16_t temp_wp0, temp_wp1, temp_wp2, temp_wp3;
+ uint32_t temp1, temp2;
+
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ ob_wp = (uint32_t)(~ob_wp);
+ temp_wp0 = (uint16_t)(ob_wp & OB_WP0_WP0);
+ temp_wp1 = (uint16_t)((ob_wp & OB_WP1_WP1) >> OB_WP1_WP1_OFFSET);
+ temp_wp2 = (uint16_t)((ob_wp & OB_WP2_WP2) >> OB_WP2_WP2_OFFSET);
+ temp_wp3 = (uint16_t)((ob_wp & OB_WP3_WP3) >> OB_WP3_WP3_OFFSET);
+
+ temp1 = (((uint32_t)temp_wp1) << 16) | ((uint32_t)temp_wp0);
+ temp2 = (((uint32_t)temp_wp3) << 16) | ((uint32_t)temp_wp2);
+
+ if (FMC_READY == fmc_state) {
+
+ /* set the OBPG bit*/
+ FMC_CTL |= FMC_CTL_OBPG;
+
+ if (0xFFFFU != temp1) {
+ OB_WP0 = temp1;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ }
+ if (0xFFFFU != temp2) {
+ OB_WP2 = temp2;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ }
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBPG bit */
+ FMC_CTL &= ~FMC_CTL_OBPG;
+ }
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief configure security protection
+ \param[in] ob_spc: specify security protection
+ only one parameter can be selected which is shown as below:
+ \arg FMC_NSPC: no security protection
+ \arg FMC_USPC: under security protection
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum ob_security_protection_config(uint8_t ob_spc)
+{
+ uint16_t temp_spc;
+ uint32_t temp;
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_READY == fmc_state) {
+ FMC_CTL |= FMC_CTL_OBER;
+ FMC_CTL |= FMC_CTL_START;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_READY == fmc_state) {
+ /* reset the OBER bit */
+ FMC_CTL &= ~FMC_CTL_OBER;
+
+ /* start the option bytes program */
+ FMC_CTL |= FMC_CTL_OBPG;
+ temp_spc = (uint16_t)ob_spc;
+ temp = ((uint32_t)temp_spc) | 0xffff0000;
+ /* config security protection */
+ OB_SPC = temp;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBPG bit */
+ FMC_CTL &= ~FMC_CTL_OBPG;
+ }
+ } else {
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBER bit */
+ FMC_CTL &= ~FMC_CTL_OBER;
+ }
+ }
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief program the FMC user option bytes
+ \param[in] ob_fwdgt: option bytes free watchdog value
+ only one parameter can be selected which is shown as below:
+ \arg OB_FWDGT_SOFTWARE: software free watchdog
+ \arg OB_FWDGT_HARDWARE: hardware free watchdog
+ \param[in] ob_deepsleep: option bytes deepsleep reset value
+ only one parameter can be selected which is shown as below:
+ \arg OB_DEEPSLEEP_NO_RST: no reset when entering deepsleep mode
+ \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode
+ \param[in] ob_stdby:option bytes standby reset value
+ only one parameter can be selected which is shown as below:
+ \arg OB_STDBY_NO_RST: no reset when entering standby mode
+ \arg OB_STDBY_RST: generate a reset instead of entering standby mode
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_stdby)
+{
+ fmc_state_enum fmc_state = FMC_READY;
+ uint8_t temp;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_READY == fmc_state) {
+ /* set the OBPG bit*/
+ FMC_CTL |= FMC_CTL_OBPG;
+
+ temp = ((uint8_t)((uint8_t)((uint8_t)(ob_fwdgt) | ob_deepsleep) | ob_stdby) | (OB_USER_MASK));
+ OB_USER = temp;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBPG bit */
+ FMC_CTL &= ~FMC_CTL_OBPG;
+ }
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief program option bytes data
+ \param[in] address: the option bytes address to be programmed
+ \param[in] data: the byte to be programmed
+ \param[out] none
+ \retval state of FMC
+ \arg FMC_READY: the operation has been completed
+ \arg FMC_BUSY: the operation is in progress
+ \arg FMC_PGERR: program error
+ \arg FMC_PGAERR: program alignment error
+ \arg FMC_WPERR: erase/program protection error
+ \arg FMC_TOERR: timeout error
+*/
+fmc_state_enum ob_data_program(uint32_t address, uint8_t data)
+{
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_READY == fmc_state) {
+ /* set the OBPG bit */
+ FMC_CTL |= FMC_CTL_OBPG;
+ REG16(address) = data;
+
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ if (FMC_TOERR != fmc_state) {
+ /* reset the OBPG bit */
+ FMC_CTL &= ~FMC_CTL_OBPG;
+ }
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief get the FMC user option bytes
+ \param[in] none
+ \param[out] none
+ \retval the FMC user option bytes values
+*/
+uint8_t ob_user_get(void)
+{
+ /* return the FMC user option bytes value */
+ return (uint8_t)(FMC_OBSTAT >> FMC_OBSTAT_USER_OFFSET);
+}
+
+/*!
+ \brief get OB_DATA in register FMC_OBSTAT
+ \param[in] none
+ \param[out] none
+ \retval ob_data
+*/
+uint16_t ob_data_get(void)
+{
+ return (uint16_t)(FMC_OBSTAT >> FMC_OBSTAT_DATA_OFFSET);
+}
+
+/*!
+ \brief get the FMC option bytes write protection
+ \param[in] none
+ \param[out] none
+ \retval the FMC write protection option bytes value
+*/
+uint32_t ob_write_protection_get(void)
+{
+ /* return the FMC write protection option bytes value */
+ return FMC_WP;
+}
+
+/*!
+ \brief get the FMC option bytes security protection
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus ob_security_protection_flag_get(void)
+{
+ FlagStatus spc_state = RESET;
+
+ if (RESET != (FMC_OBSTAT & FMC_OBSTAT_SPC)) {
+ spc_state = SET;
+ } else {
+ spc_state = RESET;
+ }
+ return spc_state;
+}
+
+/*!
+ \brief enable FMC interrupt
+ \param[in] interrupt: the FMC interrupt source
+ only one parameter can be selected which is shown as below:
+ \arg FMC_INT_BANK_END: enable FMC end of program interrupt
+ \arg FMC_INT_BANK_ERR: enable FMC error interrupt
+ \param[out] none
+ \retval none
+*/
+void fmc_interrupt_enable(uint32_t interrupt)
+{
+ FMC_REG_VAL(interrupt) |= BIT(FMC_BIT_POS(interrupt));
+}
+
+/*!
+ \brief disable FMC interrupt
+ \param[in] interrupt: the FMC interrupt source
+ only one parameter can be selected which is shown as below:
+ \arg FMC_INT_END: enable FMC end of program interrupt
+ \arg FMC_INT_ERR: enable FMC error interrupt
+ \param[out] none
+ \retval none
+*/
+void fmc_interrupt_disable(uint32_t interrupt)
+{
+ FMC_REG_VAL(interrupt) &= ~BIT(FMC_BIT_POS(interrupt));
+}
+
+/*!
+ \brief check flag is set or not
+ \param[in] flag: check FMC flag
+ only one parameter can be selected which is shown as below:
+ \arg FMC_FLAG_BUSY: FMC busy flag bit
+ \arg FMC_FLAG_PGERR: FMC operation error flag bit
+ \arg FMC_FLAG_PGAERR: FMC program alignment error flag bit
+ \arg FMC_FLAG_WPERR: FMC erase/program protection 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 flag)
+{
+ if (RESET != (FMC_REG_VAL(flag) & BIT(FMC_BIT_POS(flag)))) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear the FMC flag
+ \param[in] flag: clear FMC flag
+ only one parameter can be selected which is shown as below:
+ \arg FMC_FLAG_PGERR: FMC operation error flag bit
+ \arg FMC_FLAG_PGAERR: FMC program alignment error flag bit
+ \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit
+ \arg FMC_FLAG_END: FMC end of operation flag bit
+ \param[out] none
+ \retval none
+*/
+void fmc_flag_clear(uint32_t flag)
+{
+ FMC_REG_VAL(flag) |= BIT(FMC_BIT_POS(flag));
+}
+
+/*!
+ \brief get FMC interrupt flag state
+ \param[in] flag: FMC interrupt flags, refer to fmc_interrupt_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag bit
+ \arg FMC_FLAG_PGAERR: FMC program alignment error flag bit
+ \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag bit
+ \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag bit
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum flag)
+{
+ FlagStatus ret1 = RESET;
+ FlagStatus ret2 = RESET;
+
+ if (FMC_STAT_REG_OFFSET == FMC_REG_OFFSET_GET(flag)) {
+ /* get the staus of interrupt flag */
+ ret1 = (FlagStatus)(FMC_REG_VALS(flag) & BIT(FMC_BIT_POS0(flag)));
+ /* get the staus of interrupt enale bit */
+ ret2 = (FlagStatus)(FMC_CTL & BIT(FMC_BIT_POS1(flag)));
+ }
+
+ if (ret1 && ret2) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear FMC interrupt flag state
+ \param[in] flag: FMC interrupt flags, refer to can_interrupt_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag bit
+ \arg FMC_FLAG_PGAERR: FMC program alignment error flag bit
+ \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag bit
+ \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag bit
+ \param[out] none
+ \retval none
+*/
+void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag)
+{
+ FMC_REG_VALS(flag) |= BIT(FMC_BIT_POS0(flag));
+}
+
+/*!
+ \brief get the FMC state
+ \param[in] none
+ \param[out] none
+ \retval state of FMC, refer to fmc_state_enum
+*/
+static fmc_state_enum fmc_state_get(void)
+{
+ fmc_state_enum fmc_state = FMC_READY;
+
+ if ((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)) {
+ fmc_state = FMC_BUSY;
+ } else {
+ if ((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)) {
+ fmc_state = FMC_WPERR;
+ } else {
+ if ((uint32_t)0x00U != (FMC_STAT & (FMC_STAT_PGERR))) {
+ fmc_state = FMC_PGERR;
+ } else {
+ if ((uint32_t)0x00U != (FMC_STAT & (FMC_STAT_PGAERR))) {
+ fmc_state = FMC_PGAERR;
+ }
+ }
+ }
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
+
+/*!
+ \brief check whether FMC is ready or not
+ \param[in] timeout: count of loop
+ \param[out] none
+ \retval state of FMC, refer to fmc_state_enum
+*/
+static fmc_state_enum fmc_ready_wait(uint32_t timeout)
+{
+ fmc_state_enum fmc_state = FMC_BUSY;
+
+ /* wait for FMC ready */
+ do {
+ /* get FMC state */
+ fmc_state = fmc_state_get();
+ timeout--;
+ } while ((FMC_BUSY == fmc_state) && (0x00U != timeout));
+
+ if (FMC_BUSY == fmc_state) {
+ fmc_state = FMC_TOERR;
+ }
+ /* return the FMC state */
+ return fmc_state;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_fwdgt.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_fwdgt.c
new file mode 100644
index 0000000000..b062532c88
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_fwdgt.c
@@ -0,0 +1,158 @@
+/*!
+ \file gd32e10x_fwdgt.c
+ \brief FWDGT driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_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 enable write access to FWDGT_PSC and FWDGT_RLD
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fwdgt_write_enable(void)
+{
+ FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+}
+
+/*!
+ \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 start the free watchdog timer counter
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fwdgt_enable(void)
+{
+ FWDGT_CTL = FWDGT_KEY_ENABLE;
+}
+
+/*!
+ \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 configure counter reload value, and prescaler divider value
+ \param[in] reload_value: specify reload value(0x0000 - 0x0FFF)
+ \param[in] prescaler_div: FWDGT prescaler value
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going
+ \arg FWDGT_FLAG_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 (RESET != (FWDGT_STAT & flag)) {
+ return SET;
+ }
+
+ return RESET;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_gpio.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_gpio.c
new file mode 100644
index 0000000000..61ec2277ef
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_gpio.c
@@ -0,0 +1,547 @@
+/*!
+ \file gd32e10x_gpio.c
+ \brief GPIO driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_gpio.h"
+
+#define AFIO_EXTI_SOURCE_MASK ((uint8_t)0x03U) /*!< AFIO exti source selection mask*/
+#define AFIO_EXTI_SOURCE_FIELDS ((uint8_t)0x04U) /*!< select AFIO exti source registers */
+#define LSB_16BIT_MASK ((uint16_t)0xFFFFU) /*!< LSB 16-bit mask */
+#define PCF_POSITION_MASK ((uint32_t)0x000F0000U) /*!< AFIO_PCF register position mask */
+#define PCF_SWJCFG_MASK ((uint32_t)0xF8FFFFFFU) /*!< AFIO_PCF register SWJCFG mask */
+#define PCF_LOCATION1_MASK ((uint32_t)0x00200000U) /*!< AFIO_PCF register location1 mask */
+#define PCF_LOCATION2_MASK ((uint32_t)0x00100000U) /*!< AFIO_PCF register location2 mask */
+#define AFIO_PCF1_FIELDS ((uint32_t)0x80000000U) /*!< select AFIO_PCF1 register */
+#define GPIO_OUTPUT_PORT_OFFSET ((uint32_t)4U) /*!< GPIO event output port offset*/
+
+/*!
+ \brief reset GPIO port
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,E)
+ \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;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief reset alternate function I/O(AFIO)
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void gpio_afio_deinit(void)
+{
+ rcu_periph_reset_enable(RCU_AFRST);
+ rcu_periph_reset_disable(RCU_AFRST);
+}
+
+/*!
+ \brief GPIO parameter initialization
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,E)
+ \param[in] mode: gpio pin mode
+ only one parameter can be selected which is shown as below:
+ \arg GPIO_MODE_AIN: analog input mode
+ \arg GPIO_MODE_IN_FLOATING: floating input mode
+ \arg GPIO_MODE_IPD: pull-down input mode
+ \arg GPIO_MODE_IPU: pull-up input mode
+ \arg GPIO_MODE_OUT_OD: GPIO output with open-drain
+ \arg GPIO_MODE_OUT_PP: GPIO output with push-pull
+ \arg GPIO_MODE_AF_OD: AFIO output with open-drain
+ \arg GPIO_MODE_AF_PP: AFIO output with push-pull
+ \param[in] speed: gpio output max speed value
+ only one parameter can be selected which is shown as below:
+ \arg GPIO_OSPEED_10MHZ: output max speed 10MHz
+ \arg GPIO_OSPEED_2MHZ: output max speed 2MHz
+ \arg GPIO_OSPEED_50MHZ: output max speed 50MHz
+ \arg GPIO_OSPEED_MAX: output max speed more than 50MHz
+ \param[in] pin: GPIO pin
+ one or more parameters can be selected which are shown as below:
+ \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+ \param[out] none
+ \retval none
+*/
+#ifdef GD_MBED_USED
+void gpio_para_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin)
+#else
+void gpio_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin)
+#endif
+{
+ uint16_t i;
+ uint32_t temp_mode = 0U;
+ uint32_t reg = 0U;
+
+ /* GPIO mode configuration */
+ temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
+
+ /* GPIO speed configuration */
+ if (((uint32_t)0x00U) != ((uint32_t)mode & ((uint32_t)0x10U))) {
+ /* output mode max speed */
+ if (GPIO_OSPEED_MAX == (uint32_t)speed) {
+ temp_mode |= (uint32_t)0x03U;
+ /* set the corresponding SPD bit */
+ GPIOx_SPD(gpio_periph) |= (uint32_t)pin ;
+ } else {
+ /* output mode max speed:10MHz,2MHz,50MHz */
+ temp_mode |= (uint32_t)speed;
+ }
+ }
+
+ /* configure the eight low port pins with GPIO_CTL0 */
+ for (i = 0U; i < 8U; i++) {
+ if ((1U << i) & pin) {
+ reg = GPIO_CTL0(gpio_periph);
+
+ /* clear the specified pin mode bits */
+ reg &= ~GPIO_MODE_MASK(i);
+ /* set the specified pin mode bits */
+ reg |= GPIO_MODE_SET(i, temp_mode);
+
+ /* set IPD or IPU */
+ if (GPIO_MODE_IPD == mode) {
+ /* reset the corresponding OCTL bit */
+ GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
+ } else {
+ /* set the corresponding OCTL bit */
+ if (GPIO_MODE_IPU == mode) {
+ GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
+ }
+ }
+ /* set GPIO_CTL0 register */
+ GPIO_CTL0(gpio_periph) = reg;
+ }
+ }
+ /* configure the eight high port pins with GPIO_CTL1 */
+ for (i = 8U; i < 16U; i++) {
+ if ((1U << i) & pin) {
+ reg = GPIO_CTL1(gpio_periph);
+
+ /* clear the specified pin mode bits */
+ reg &= ~GPIO_MODE_MASK(i - 8U);
+ /* set the specified pin mode bits */
+ reg |= GPIO_MODE_SET(i - 8U, temp_mode);
+
+ /* set IPD or IPU */
+ if (GPIO_MODE_IPD == mode) {
+ /* reset the corresponding OCTL bit */
+ GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
+ } else {
+ /* set the corresponding OCTL bit */
+ if (GPIO_MODE_IPU == mode) {
+ GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
+ }
+ }
+ /* set GPIO_CTL1 register */
+ GPIO_CTL1(gpio_periph) = reg;
+ }
+ }
+}
+
+/*!
+ \brief set GPIO pin
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,E)
+ \param[in] pin: GPIO pin
+ one or more parameters can be selected which are shown as below:
+ \arg 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)
+ \param[in] pin: GPIO pin
+ one or more parameters can be selected which are shown as below:
+ \arg 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)
+ \param[in] pin: GPIO pin
+ one or more parameters can be selected which are shown as below:
+ \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+ \param[in] bit_value: 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)
+ \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)
+ \param[in] pin: GPIO pin
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+ \param[out] none
+ \retval input status 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 port input status
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,E)
+ \param[out] none
+ \retval input status 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)
+ \param[in] pin: GPIO pin
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+ \param[out] none
+ \retval output status 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 port output status
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,E)
+ \param[out] none
+ \retval output status of gpio all pins
+*/
+uint16_t gpio_output_port_get(uint32_t gpio_periph)
+{
+ return ((uint16_t)GPIO_OCTL(gpio_periph));
+}
+
+/*!
+ \brief configure GPIO pin remap
+ \param[in] gpio_remap: select the pin to remap
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_SPI0_REMAP: SPI0 remapping
+ \arg GPIO_I2C0_REMAP: I2C0 remapping
+ \arg GPIO_USART0_REMAP: USART0 remapping
+ \arg GPIO_USART1_REMAP: USART1 remapping
+ \arg GPIO_USART2_PARTIAL_REMAP: USART2 partial remapping
+ \arg GPIO_USART2_FULL_REMAP: USART2 full remapping
+ \arg GPIO_TIMER0_PARTIAL_REMAP: TIMER0 partial remapping
+ \arg GPIO_TIMER0_FULL_REMAP: TIMER0 full remapping
+ \arg GPIO_TIMER1_PARTIAL_REMAP0: TIMER1 partial remapping
+ \arg GPIO_TIMER1_PARTIAL_REMAP1: TIMER1 partial remapping
+ \arg GPIO_TIMER1_FULL_REMAP: TIMER1 full remapping
+ \arg GPIO_TIMER2_PARTIAL_REMAP: TIMER2 partial remapping
+ \arg GPIO_TIMER2_FULL_REMAP: TIMER2 full remapping
+ \arg GPIO_TIMER3_REMAP: TIMER3 remapping
+ \arg GPIO_CAN0_PARTIAL_REMAP: CAN0 partial remapping
+ \arg GPIO_CAN0_FULL_REMAP: CAN0 full remapping
+ \arg GPIO_PD01_REMAP: PD01 remapping
+ \arg GPIO_TIMER4CH3_IREMAP: TIMER4 channel3 internal remapping
+ \arg GPIO_ADC0_ETRGINS_REMAP: ADC0 external trigger inserted conversion remapping
+ \arg GPIO_ADC0_ETRGREG_REMAP: ADC0 external trigger regular conversion remapping
+ \arg GPIO_ADC1_ETRGINS_REMAP: ADC1 external trigger inserted conversion remapping
+ \arg GPIO_ADC1_ETRGREG_REMAP: ADC1 external trigger regular conversion remapping
+ \arg GPIO_CAN1_REMAP: CAN1 remapping
+ \arg GPIO_SWJ_NONJTRST_REMAP: full SWJ(JTAG-DP + SW-DP),but without NJTRST
+ \arg GPIO_SWJ_SWDPENABLE_REMAP: JTAG-DP disabled and SW-DP enabled
+ \arg GPIO_SWJ_DISABLE_REMAP: JTAG-DP disabled and SW-DP disabled
+ \arg GPIO_SPI2_REMAP: SPI2 remapping
+ \arg GPIO_TIMER1ITR0_REMAP: TIMER1 internal trigger 0 remapping
+ \arg GPIO_TIMER8_REMAP: TIMER8 remapping
+ \arg GPIO_EXMC_NADV_REMAP: EXMC_NADV connect/disconnect
+ \arg GPIO_CTC_REMAP0: CTC remapping(PD15)
+ \param[in] newvalue: ENABLE or DISABLE
+ \param[out] none
+ \retval none
+*/
+void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue)
+{
+ uint32_t remap1 = 0U, remap2 = 0U, temp_reg = 0U, temp_mask = 0U;
+
+ if (((uint32_t)0x80000000U) == (remap & 0x80000000U)) {
+ /* get AFIO_PCF1 regiter value */
+ temp_reg = AFIO_PCF1;
+ } else {
+ /* get AFIO_PCF0 regiter value */
+ temp_reg = AFIO_PCF0;
+ }
+
+ temp_mask = (remap & PCF_POSITION_MASK) >> 0x10U;
+ remap1 = remap & LSB_16BIT_MASK;
+
+ /* judge pin remap type */
+ if ((PCF_LOCATION1_MASK | PCF_LOCATION2_MASK) == (remap & (PCF_LOCATION1_MASK | PCF_LOCATION2_MASK))) {
+ temp_reg &= PCF_SWJCFG_MASK;
+ AFIO_PCF0 &= PCF_SWJCFG_MASK;
+ } else if (PCF_LOCATION2_MASK == (remap & PCF_LOCATION2_MASK)) {
+ remap2 = ((uint32_t)0x03U) << temp_mask;
+ temp_reg &= ~remap2;
+ temp_reg |= ~PCF_SWJCFG_MASK;
+ } else {
+ temp_reg &= ~(remap1 << ((remap >> 0x15U) * 0x10U));
+ temp_reg |= ~PCF_SWJCFG_MASK;
+ }
+
+ /* set pin remap value */
+ if (DISABLE != newvalue) {
+ temp_reg |= (remap1 << ((remap >> 0x15U) * 0x10U));
+ }
+
+ if (AFIO_PCF1_FIELDS == (remap & AFIO_PCF1_FIELDS)) {
+ /* set AFIO_PCF1 regiter value */
+ AFIO_PCF1 = temp_reg;
+ } else {
+ /* set AFIO_PCF0 regiter value */
+ AFIO_PCF0 = temp_reg;
+ }
+}
+
+/*!
+ \brief select GPIO pin exti sources
+ \param[in] output_port: gpio event output port
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_PORT_SOURCE_GPIOA: output port source A
+ \arg GPIO_PORT_SOURCE_GPIOB: output port source B
+ \arg GPIO_PORT_SOURCE_GPIOC: output port source C
+ \arg GPIO_PORT_SOURCE_GPIOD: output port source D
+ \arg GPIO_PORT_SOURCE_GPIOE: output port source E
+ \param[in] output_pin:
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_PIN_SOURCE_x(x=0..15)
+ \param[out] none
+ \retval none
+*/
+void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin)
+{
+ uint32_t source = 0U;
+ source = ((uint32_t)0x0FU) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK));
+
+ /* select EXTI sources */
+ if (GPIO_PIN_SOURCE_4 > output_pin) {
+ /* select EXTI0/EXTI1/EXTI2/EXTI3 */
+ AFIO_EXTISS0 &= ~source;
+ AFIO_EXTISS0 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
+ } else if (GPIO_PIN_SOURCE_8 > output_pin) {
+ /* select EXTI4/EXTI5/EXTI6/EXTI7 */
+ AFIO_EXTISS1 &= ~source;
+ AFIO_EXTISS1 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
+ } else if (GPIO_PIN_SOURCE_12 > output_pin) {
+ /* select EXTI8/EXTI9/EXTI10/EXTI11 */
+ AFIO_EXTISS2 &= ~source;
+ AFIO_EXTISS2 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
+ } else {
+ /* select EXTI12/EXTI13/EXTI14/EXTI15 */
+ AFIO_EXTISS3 &= ~source;
+ AFIO_EXTISS3 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
+ }
+}
+
+/*!
+ \brief configure GPIO pin event output
+ \param[in] output_port: gpio event output port
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_EVENT_PORT_GPIOA: event output port A
+ \arg GPIO_EVENT_PORT_GPIOB: event output port B
+ \arg GPIO_EVENT_PORT_GPIOC: event output port C
+ \arg GPIO_EVENT_PORT_GPIOD: event output port D
+ \arg GPIO_EVENT_PORT_GPIOE: event output port E
+ \param[in] output_pin:
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_EVENT_PIN_x(x=0..15)
+ \param[out] none
+ \retval none
+*/
+void gpio_event_output_config(uint8_t output_port, uint8_t output_pin)
+{
+ uint32_t reg = 0U;
+ reg = AFIO_EC;
+
+ /* clear AFIO_EC_PORT and AFIO_EC_PIN bits */
+ reg &= (uint32_t)(~(AFIO_EC_PORT | AFIO_EC_PIN));
+
+ reg |= (uint32_t)((uint32_t)output_port << GPIO_OUTPUT_PORT_OFFSET);
+ reg |= (uint32_t)output_pin;
+
+ AFIO_EC = reg;
+}
+
+/*!
+ \brief enable GPIO pin event output
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void gpio_event_output_enable(void)
+{
+ AFIO_EC |= AFIO_EC_EOE;
+}
+
+/*!
+ \brief disable GPIO pin event output
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void gpio_event_output_disable(void)
+{
+ AFIO_EC &= (uint32_t)(~AFIO_EC_EOE);
+}
+
+/*!
+ \brief lock GPIO pin
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,E)
+ \param[in] pin: GPIO pin
+ one or more parameters can be selected which are shown as below:
+ \arg 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 configure the I/O compensation cell
+ \param[in] compensation: specifies the I/O compensation cell mode
+ only one parameter can be selected which are shown as below:
+ \arg GPIO_COMPENSATION_ENABLE: I/O compensation cell is enabled
+ \arg GPIO_COMPENSATION_DISABLE: I/O compensation cell is disabled
+ \param[out] none
+ \retval none
+*/
+void gpio_compensation_config(uint32_t compensation)
+{
+ uint32_t reg;
+ reg = AFIO_CPSCTL;
+
+ /* reset the AFIO_CPSCTL_CPS_EN bit and set according to gpio_compensation */
+ reg &= ~AFIO_CPSCTL_CPS_EN;
+ AFIO_CPSCTL = (reg | compensation);
+}
+
+/*!
+ \brief check the I/O compensation cell is ready or not
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+ */
+FlagStatus gpio_compensation_flag_get(void)
+{
+ if (((uint32_t)RESET) != (AFIO_CPSCTL & AFIO_CPSCTL_CPS_RDY)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_i2c.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_i2c.c
new file mode 100644
index 0000000000..580c14771a
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_i2c.c
@@ -0,0 +1,791 @@
+/*!
+ \file gd32e10x_i2c.c
+ \brief I2C driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_i2c.h"
+
+/* I2C register bit mask */
+#define I2CCLK_MAX ((uint32_t)0x0000003FU) /*!< i2cclk maximum value */
+#define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */
+#define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag mask */
+#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */
+
+/* I2C register bit offset */
+#define STAT1_PECV_OFFSET ((uint32_t)8U) /* bit offset of PECV in I2C_STAT1 */
+
+/*!
+ \brief reset I2C
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[out] none
+ \retval none
+*/
+void i2c_deinit(uint32_t i2c_periph)
+{
+ switch (i2c_periph) {
+ case I2C0:
+ /* reset I2C0 */
+ rcu_periph_reset_enable(RCU_I2C0RST);
+ rcu_periph_reset_disable(RCU_I2C0RST);
+ break;
+ case I2C1:
+ /* reset I2C1 */
+ rcu_periph_reset_enable(RCU_I2C1RST);
+ rcu_periph_reset_disable(RCU_I2C1RST);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure I2C clock
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
+ and fast mode plus (up to 1MHz)
+ \param[in] dutycyc: duty cycle in fast mode or fast mode plus
+ only one parameter can be selected which is shown as below:
+ \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, freq, risetime;
+ uint32_t temp;
+
+ pclk1 = rcu_clock_freq_get(CK_APB1);
+ /* I2C peripheral clock frequency */
+ freq = (uint32_t)(pclk1 / 1000000U);
+ if (freq >= I2CCLK_MAX) {
+ freq = I2CCLK_MAX;
+ }
+ temp = I2C_CTL1(i2c_periph);
+ temp &= ~I2C_CTL1_I2CCLK;
+ temp |= freq;
+
+ I2C_CTL1(i2c_periph) = temp;
+
+ if (100000U >= clkspeed) {
+ /* the maximum SCL rise time is 1000ns in standard mode */
+ risetime = (uint32_t)((pclk1 / 1000000U) + 1U);
+ if (risetime >= I2CCLK_MAX) {
+ I2C_RT(i2c_periph) = I2CCLK_MAX;
+ } else if (risetime <= I2CCLK_MIN) {
+ I2C_RT(i2c_periph) = I2CCLK_MIN;
+ } else {
+ I2C_RT(i2c_periph) = risetime;
+ }
+ 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 if (400000U >= clkspeed) {
+ /* the maximum SCL rise time is 300ns in fast mode */
+ I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)300U) / (uint32_t)1000U) + (uint32_t)1U);
+ if (I2C_DTCY_2 == dutycyc) {
+ /* I2C duty cycle is 2 */
+ clkc = (uint32_t)(pclk1 / (clkspeed * 3U));
+ I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
+ } else {
+ /* I2C duty cycle is 16/9 */
+ clkc = (uint32_t)(pclk1 / (clkspeed * 25U));
+ I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
+ }
+ if (0U == (clkc & I2C_CKCFG_CLKC)) {
+ /* the CLKC in fast mode minmum value is 1 */
+ clkc |= 0x0001U;
+ }
+ I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
+ I2C_CKCFG(i2c_periph) |= clkc;
+ } else {
+ /* fast mode plus, the maximum SCL rise time is 120ns */
+ I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)120U) / (uint32_t)1000U) + (uint32_t)1U);
+ if (I2C_DTCY_2 == dutycyc) {
+ /* I2C duty cycle is 2 */
+ clkc = (uint32_t)(pclk1 / (clkspeed * 3U));
+ I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
+ } else {
+ /* I2C duty cycle is 16/9 */
+ clkc = (uint32_t)(pclk1 / (clkspeed * 25U));
+ I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
+ }
+ /* enable fast mode */
+ I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
+ I2C_CKCFG(i2c_periph) |= clkc;
+ /* enable I2C fast mode plus */
+ I2C_FMPCFG(i2c_periph) = I2C_FMPCFG_FMPEN;
+ }
+}
+
+/*!
+ \brief configure I2C address
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] mode:
+ only one parameter can be selected which is shown as below:
+ \arg I2C_I2CMODE_ENABLE: I2C mode
+ \arg I2C_SMBUSMODE_ENABLE: SMBus mode
+ \param[in] addformat: 7bits or 10bits
+ only one parameter can be selected which is shown as below:
+ \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 mode, uint32_t addformat, uint32_t addr)
+{
+ /* SMBus/I2C mode selected */
+ uint32_t ctl = 0U;
+
+ ctl = I2C_CTL0(i2c_periph);
+ ctl &= ~(I2C_CTL0_SMBEN);
+ ctl |= mode;
+ I2C_CTL0(i2c_periph) = ctl;
+ /* configure address */
+ addr = addr & I2C_ADDRESS_MASK;
+ I2C_SADDR0(i2c_periph) = (addformat | addr);
+}
+
+/*!
+ \brief SMBus type selection
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] type:
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] ack:
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t ack)
+{
+ if (I2C_ACK_ENABLE == ack) {
+ I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN;
+ } else {
+ I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN);
+ }
+}
+
+/*!
+ \brief configure I2C POAP position
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] pos:
+ only one parameter can be selected which is shown as below:
+ \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current
+ \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte
+ \param[out] none
+ \retval none
+*/
+void i2c_ackpos_config(uint32_t i2c_periph, uint32_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 sends slave address
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] addr: slave address
+ \param[in] trandirection: transmitter or receiver
+ only one parameter can be selected which is shown as below:
+ \arg I2C_TRANSMITTER: transmitter
+ \arg I2C_RECEIVER: receiver
+ \param[out] none
+ \retval none
+*/
+void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection)
+{
+ /* master is a transmitter or a receiver */
+ if (I2C_TRANSMITTER == trandirection) {
+ addr = addr & I2C_TRANSMITTER;
+ } else {
+ addr = addr | I2C_RECEIVER;
+ }
+ /* send slave address */
+ I2C_DATA(i2c_periph) = addr;
+}
+
+/*!
+ \brief dual-address mode switch
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] dualaddr:
+ only one parameter can be selected which is shown as below:
+ \arg I2C_DUADEN_DISABLE: disable dual-address mode
+ \arg I2C_DUADEN_ENABLE: enable dual-address mode
+ \param[out] none
+ \retval none
+*/
+void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_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)
+ \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)
+ \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)
+ \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)
+ \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)
+ \param[in] data: data of transmission
+ \param[out] none
+ \retval none
+*/
+void i2c_data_transmit(uint32_t i2c_periph, uint8_t data)
+{
+ I2C_DATA(i2c_periph) = DATA_TRANS(data);
+}
+
+/*!
+ \brief I2C receive data function
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[out] none
+ \retval data of received
+*/
+uint8_t i2c_data_receive(uint32_t i2c_periph)
+{
+ return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph));
+}
+
+/*!
+ \brief enable I2C DMA mode
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] dmastate:
+ only one parameter can be selected which is shown as below:
+ \arg I2C_DMA_ON: DMA mode enable
+ \arg I2C_DMA_OFF: DMA mode disable
+ \param[out] none
+ \retval none
+*/
+void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate)
+{
+ /* configure I2C DMA function */
+ uint32_t ctl = 0U;
+
+ ctl = I2C_CTL1(i2c_periph);
+ ctl &= ~(I2C_CTL1_DMAON);
+ ctl |= dmastate;
+ I2C_CTL1(i2c_periph) = ctl;
+}
+
+/*!
+ \brief configure whether next DMA EOT is DMA last transfer or not
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] dmalast:
+ only one parameter can be selected which is shown as below:
+ \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_config(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)
+ \param[in] stretchpara:
+ only one parameter can be selected which is shown as below:
+ \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_SS);
+ ctl |= stretchpara;
+ I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+ \brief whether or not to response to a general call
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] gcallpara:
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] sreset:
+ only one parameter can be selected which is shown as below:
+ \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 I2C PEC calculation on or off
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] pecpara:
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] pecpara:
+ only one parameter can be selected which is shown as below:
+ \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 get packet error checking value
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[out] none
+ \retval PEC value
+*/
+uint8_t i2c_pec_value_get(uint32_t i2c_periph)
+{
+ return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV) >> STAT1_PECV_OFFSET);
+}
+
+/*!
+ \brief I2C issue alert through SMBA pin
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] smbuspara:
+ only one parameter can be selected which is shown as below:
+ \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_issue_alert(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 enable or disable I2C ARP protocol in SMBus switch
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] smbuspara:
+ only one parameter can be selected which is shown as below:
+ \arg I2C_ARP_ENABLE: enable ARP
+ \arg I2C_ARP_DISABLE: disable ARP
+ \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 enable SAM_V interface
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \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)
+ \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)
+ \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)
+ \param[out] none
+ \retval none
+*/
+void i2c_sam_timeout_disable(uint32_t i2c_periph)
+{
+ I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN);
+}
+
+/*!
+ \brief check I2C flag is set or not
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] flag: I2C flags, refer to i2c_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg I2C_FLAG_SBSEND: start condition send out
+ \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
+ \arg I2C_FLAG_BTC: byte transmission finishes
+ \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode
+ \arg I2C_FLAG_STPDET: stop condition detected in slave mode
+ \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving
+ \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting
+ \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
+ \arg I2C_FLAG_LOSTARB: arbitration lost in master mode
+ \arg I2C_FLAG_AERR: acknowledge error
+ \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode
+ \arg I2C_FLAG_PECERR: PEC error when receiving data
+ \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
+ \arg I2C_FLAG_SMBALT: SMBus alert status
+ \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode
+ \arg I2C_FLAG_I2CBSY: busy flag
+ \arg I2C_FLAG_TRS: whether the I2C is a transmitter or a receiver
+ \arg I2C_FLAG_RXGC: general call address (00h) received
+ \arg I2C_FLAG_DEFSMB: default address of SMBus device
+ \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode
+ \arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode
+ \arg I2C_FLAG_TFF: txframe fall flag
+ \arg I2C_FLAG_TFR: txframe rise flag
+ \arg I2C_FLAG_RFF: rxframe fall flag
+ \arg I2C_FLAG_RFR: rxframe rise flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag)
+{
+ if (RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear I2C flag
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] flag: I2C flags, refer to i2c_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg I2C_FLAG_SMBALT: SMBus Alert status
+ \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
+ \arg I2C_FLAG_PECERR: PEC error when receiving data
+ \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
+ \arg I2C_FLAG_AERR: acknowledge error
+ \arg I2C_FLAG_LOSTARB: arbitration lost in master mode
+ \arg I2C_FLAG_BERR: a bus error
+ \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1
+ \arg I2C_FLAG_TFF: txframe fall flag
+ \arg I2C_FLAG_TFR: txframe rise flag
+ \arg I2C_FLAG_RFF: rxframe fall flag
+ \arg I2C_FLAG_RFR: rxframe rise flag
+ \param[out] none
+ \retval none
+*/
+void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag)
+{
+ if (I2C_FLAG_ADDSEND == flag) {
+ /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
+ I2C_STAT0(i2c_periph);
+ I2C_STAT1(i2c_periph);
+ } else {
+ I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag));
+ }
+}
+
+/*!
+ \brief enable I2C interrupt
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum
+ only one parameter can be selected which is shown as below:
+ \arg I2C_INT_ERR: error interrupt enable
+ \arg I2C_INT_EV: event interrupt enable
+ \arg I2C_INT_BUF: buffer interrupt enable
+ \arg I2C_INT_TFF: txframe fall interrupt enable
+ \arg I2C_INT_TFR: txframe rise interrupt enable
+ \arg I2C_INT_RFF: rxframe fall interrupt enable
+ \arg I2C_INT_RFR: rxframe rise interrupt enable
+ \param[out] none
+ \retval none
+*/
+void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
+{
+ I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt));
+}
+
+/*!
+ \brief disable I2C interrupt
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] interrupt: I2C interrupts, refer to i2c_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg I2C_INT_ERR: error interrupt enable
+ \arg I2C_INT_EV: event interrupt enable
+ \arg I2C_INT_BUF: buffer interrupt enable
+ \arg I2C_INT_TFF: txframe fall interrupt enable
+ \arg I2C_INT_TFR: txframe rise interrupt enable
+ \arg I2C_INT_RFF: rxframe fall interrupt enable
+ \arg I2C_INT_RFR: rxframe rise interrupt enable
+ \param[out] none
+ \retval none
+*/
+void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
+{
+ I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt));
+}
+
+/*!
+ \brief check I2C interrupt flag
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag
+ \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
+ \arg I2C_INT_FLAG_BTC: byte transmission finishes
+ \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
+ \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag
+ \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
+ \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
+ \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
+ \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
+ \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
+ \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
+ \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
+ \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
+ \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
+ \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag
+ \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag
+ \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag
+ \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag
+ \param[out] none
+ \retval none
+*/
+FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
+{
+ uint32_t intenable = 0U, flagstatus = 0U, bufie;
+
+ /* check BUFIE */
+ bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
+
+ /* get the interrupt enable bit status */
+ intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
+ /* get the corresponding flag bit status */
+ flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));
+
+ if ((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)) {
+ if (intenable && bufie) {
+ intenable = 1U;
+ } else {
+ intenable = 0U;
+ }
+ }
+ if ((0U != flagstatus) && (0U != intenable)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear I2C interrupt flag
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] intflag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
+ \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
+ \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
+ \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
+ \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
+ \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
+ \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
+ \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
+ \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag
+ \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag
+ \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag
+ \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag
+ \param[out] none
+ \retval none
+*/
+void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
+{
+ if (I2C_INT_FLAG_ADDSEND == int_flag) {
+ /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
+ I2C_STAT0(i2c_periph);
+ I2C_STAT1(i2c_periph);
+ } else {
+ I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag));
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_misc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_misc.c
new file mode 100644
index 0000000000..c575eaff88
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_misc.c
@@ -0,0 +1,186 @@
+/*!
+ \file gd32e10x_misc.c
+ \brief MISC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_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 */
+ switch ((SCB->AIRCR) & (uint32_t)0x700U) {
+ case NVIC_PRIGROUP_PRE0_SUB4:
+ temp_pre = 0U;
+ temp_sub = 0x4U;
+ break;
+ case NVIC_PRIGROUP_PRE1_SUB3:
+ temp_pre = 1U;
+ temp_sub = 0x3U;
+ break;
+ case NVIC_PRIGROUP_PRE2_SUB2:
+ temp_pre = 2U;
+ temp_sub = 0x2U;
+ break;
+ case NVIC_PRIGROUP_PRE3_SUB1:
+ temp_pre = 3U;
+ temp_sub = 0x1U;
+ break;
+ case NVIC_PRIGROUP_PRE4_SUB0:
+ temp_pre = 4U;
+ temp_sub = 0x0U;
+ break;
+ default:
+ nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
+ temp_pre = 2U;
+ temp_sub = 0x2U;
+ break;
+ }
+
+ /* 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 >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
+}
+
+/*!
+ \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;
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_pmu.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_pmu.c
new file mode 100644
index 0000000000..1549b85fd2
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_pmu.c
@@ -0,0 +1,280 @@
+/*!
+ \file gd32e10x_pmu.c
+ \brief PMU driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_pmu.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] lvdt_n:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_LVDT_0: voltage threshold is 2.1V
+ \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.6V
+ \arg PMU_LVDT_4: voltage threshold is 2.7V
+ \arg PMU_LVDT_5: voltage threshold is 2.9V
+ \arg PMU_LVDT_6: voltage threshold is 3.0V
+ \arg PMU_LVDT_7: voltage threshold is 3.1V
+ \param[out] none
+ \retval none
+*/
+void pmu_lvd_select(uint32_t lvdt_n)
+{
+ /* disable LVD */
+ PMU_CTL &= ~PMU_CTL_LVDEN;
+ /* clear LVDT bits */
+ PMU_CTL &= ~PMU_CTL_LVDT;
+ /* set LVDT bits according to lvdt_n */
+ PMU_CTL |= lvdt_n;
+ /* enable LVD */
+ PMU_CTL |= PMU_CTL_LVDEN;
+}
+
+/*!
+ \brief select LDO output voltage
+ 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:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_LDOVS_LOW: LDO output voltage select low mode
+ \arg PMU_LDOVS_NORMAL: LDO output voltage select normal 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 disable PMU lvd
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_lvd_disable(void)
+{
+ /* disable LVD */
+ PMU_CTL &= ~PMU_CTL_LVDEN;
+}
+
+/*!
+ \brief PMU work at sleep mode
+ \param[in] sleepmodecmd:
+ only one parameter can be selected which is shown as below:
+ \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] ldo:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_LDO_NORMAL: LDO work at normal power mode when pmu enter deepsleep mode
+ \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
+ \param[in] deepsleepmodecmd:
+ only one parameter can be selected which is shown as below:
+ \arg WFI_CMD: use WFI command
+ \arg WFE_CMD: use WFE command
+ \param[out] none
+ \retval none
+*/
+void pmu_to_deepsleepmode(uint32_t 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 |= 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:
+ only one parameter can be selected which is shown as below:
+ \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 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;
+}
+
+/*!
+ \brief enable write access to the registers in backup domain
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_backup_write_enable(void)
+{
+ PMU_CTL |= PMU_CTL_BKPWEN;
+}
+
+/*!
+ \brief disable write access to the registers in backup domain
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_backup_write_disable(void)
+{
+ PMU_CTL &= ~PMU_CTL_BKPWEN;
+}
+
+/*!
+ \brief clear flag bit
+ \param[in] flag_reset:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag
+ \arg PMU_FLAG_RESET_STANDBY: reset standby flag
+ \param[out] none
+ \retval none
+*/
+void pmu_flag_clear(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 state
+ \param[in] flag:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_FLAG_WAKEUP: wakeup flag
+ \arg PMU_FLAG_STANDBY: standby flag
+ \arg PMU_FLAG_LVD: lvd flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus pmu_flag_get(uint32_t flag)
+{
+ if (RESET != (PMU_CS & flag)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_rcu.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_rcu.c
new file mode 100644
index 0000000000..d8bb5bcfde
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_rcu.c
@@ -0,0 +1,1248 @@
+/*!
+ \file gd32e10x_rcu.c
+ \brief RCU driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_rcu.h"
+
+/* define clock source */
+#define SEL_IRC8M ((uint16_t)0U) /* IRC8M is selected as CK_SYS */
+#define SEL_HXTAL ((uint16_t)1U) /* HXTAL is selected as CK_SYS */
+#define SEL_PLL ((uint16_t)2U) /* PLL is selected as CK_SYS */
+
+/* define startup timeout count */
+#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000FFFFFU)
+#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x03FFFFFFU)
+
+/* ADC clock prescaler offset */
+#define RCU_ADC_PSC_OFFSET ((uint32_t)14U)
+
+/* RCU IRC8M adjust value mask and offset*/
+#define RCU_IRC8M_ADJUST_MASK ((uint8_t)0x1FU)
+#define RCU_IRC8M_ADJUST_OFFSET ((uint32_t)3U)
+
+/* RCU PLL1 clock multiplication factor offset */
+#define RCU_CFG1_PLL1MF_OFFSET ((uint32_t)8U)
+/* RCU PREDV1 division factor offset*/
+#define RCU_CFG1_PREDV1_OFFSET ((uint32_t)4U)
+
+
+/*!
+ \brief deinitialize the RCU
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void rcu_deinit(void)
+{
+ /* enable IRC8M */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+ rcu_osci_stab_wait(RCU_IRC8M);
+
+ /* reset CFG0 register */
+ RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |
+ RCU_CFG0_ADCPSC | RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF |
+ RCU_CFG0_USBFSPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_ADCPSC_2 | RCU_CFG0_PLLMF_4 | RCU_CFG0_USBFSPSC_2);
+ /* reset CTL register */
+ RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);
+ RCU_CTL &= ~RCU_CTL_HXTALBPS;
+ RCU_CTL &= ~(RCU_CTL_PLL1EN | RCU_CTL_PLL2EN);
+
+ /* reset INT and CFG1 register */
+
+ RCU_INT = 0x00ff0000U;
+ RCU_CFG1 &= ~(RCU_CFG1_PREDV0 | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PLL2MF |
+ RCU_CFG1_PREDV0SEL | RCU_CFG1_I2S1SEL | RCU_CFG1_I2S2SEL | RCU_CFG1_ADCPSC_3 |
+ RCU_CFG1_PLLPRESEL);
+}
+
+/*!
+ \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): GPIO ports clock
+ \arg RCU_AF : alternate function clock
+ \arg RCU_CRC: CRC clock
+ \arg RCU_DMAx (x=0,1): DMA 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): SPI clock
+ \arg RCU_USARTx (x=0,1,2): USART clock
+ \arg RCU_UARTx (x=3,4): UART clock
+ \arg RCU_I2Cx (x=0,1): 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): ADC clock
+ \arg RCU_CTC: CTC clock
+ \arg RCU_BKPI: BKP interface 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): GPIO ports clock
+ \arg RCU_AF: alternate function clock
+ \arg RCU_CRC: CRC clock
+ \arg RCU_DMAx (x=0,1): DMA 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): SPI clock
+ \arg RCU_USARTx (x=0,1,2): USART clock
+ \arg RCU_UARTx (x=3,4): UART clock
+ \arg RCU_I2Cx (x=0,1): 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): ADC clock
+ \arg RCU_CTC: CTC clock
+ \arg RCU_BKPI: BKP interface 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_FMC_SLP: FMC clock
+ \arg RCU_SRAM_SLP: SRAM 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_FMC_SLP: FMC clock
+ \arg RCU_SRAM_SLP: SRAM 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): reset GPIO ports
+ \arg RCU_AFRST : reset alternate function clock
+ \arg RCU_USBFSRST: reset USBFS
+ \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): reset SPI
+ \arg RCU_USARTxRST (x=0,1,2): reset USART
+ \arg RCU_UARTxRST (x=3,4): reset UART
+ \arg RCU_I2CxRST (x=0,1): reset I2C
+ \arg RCU_CANxRST (x=0,1): reset CAN
+ \arg RCU_PMURST: reset PMU
+ \arg RCU_DACRST: reset DAC
+ \arg RCU_ADCxRST (x=0,1): reset ADC
+ \arg RCU_CTCRST: reset CTC
+ \arg RCU_BKPIRST: reset BKPI
+ \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): reset GPIO ports
+ \arg RCU_AFRST : reset alternate function clock
+ \arg RCU_USBFSRST: reset USBFS
+ \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): reset SPI
+ \arg RCU_USARTxRST (x=0,1,2): reset USART
+ \arg RCU_UARTxRST (x=3,4): reset UART
+ \arg RCU_I2CxRST (x=0,1): reset I2C
+ \arg RCU_CANxRST (x=0,1): reset CAN
+ \arg RCU_PMURST: reset PMU
+ \arg RCU_DACRST: reset DAC
+ \arg RCU_ADCxRST (x=0,1): reset ADC
+ \arg RCU_CTCRST: reset CTC
+ \arg RCU_BKPIRST: reset BKPI
+ \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 domain
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void rcu_bkp_reset_enable(void)
+{
+ RCU_BDCTL |= RCU_BDCTL_BKPRST;
+}
+
+/*!
+ \brief disable the BKP domain 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_IRC8M: select CK_IRC8M as the CK_SYS source
+ \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source
+ \arg RCU_CKSYSSRC_PLL: select CK_PLL 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_IRC8M: CK_IRC8M is selected as the CK_SYS source
+ \arg RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source
+ \arg RCU_SCSS_PLL: CK_PLL 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 AHBPSC 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 APB1PSC 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 APB2PSC and set according to ck_apb2 */
+ reg &= ~RCU_CFG0_APB2PSC;
+ RCU_CFG0 = (reg | ck_apb2);
+}
+
+/*!
+ \brief configure the CK_OUT0 clock source
+ \param[in] ckout0_src: CK_OUT0 clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_CKOUT0SRC_NONE: no clock selected
+ \arg RCU_CKOUT0SRC_CKSYS: system clock selected
+ \arg RCU_CKOUT0SRC_IRC8M: high speed 8M internal oscillator clock selected
+ \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected
+ \arg RCU_CKOUT0SRC_CKPLL_DIV2: CK_PLL/2 selected
+ \arg RCU_CKOUT0SRC_CKPLL1: CK_PLL1 selected
+ \arg RCU_CKOUT0SRC_CKPLL2_DIV2: CK_PLL2/2 selected
+ \arg RCU_CKOUT0SRC_CKPLL2: PLL2 selected
+ \arg RCU_CKOUT0SRC_IRC48M: IRC48M selected
+ \arg RCU_CKOUT0SRC_IRC48M_DIV8: IRC48M/8 selected
+ \param[out] none
+ \retval none
+*/
+void rcu_ckout0_config(uint32_t ckout0_src)
+{
+ uint32_t reg;
+
+ reg = RCU_CFG0;
+
+ /* reset the CKOUT0SRC, set according to ckout0_src */
+ reg &= ~RCU_CFG0_CKOUT0SEL;
+ RCU_CFG0 = (reg | ckout0_src);
+}
+
+/*!
+ \brief configure the main PLL clock
+ \param[in] pll_src: PLL clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PLLSRC_IRC8M_DIV2: IRC8M/2 clock selected as source clock of PLL
+ \arg RCU_PLLSRC_HXTAL_IRC48M: HXTAL or IRC48M selected as source clock of PLL
+ \param[in] pll_mul: PLL clock multiplication factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PLL_MULx (x = 2..14, 16..31, 6.5)
+ \param[out] none
+ \retval none
+*/
+void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul)
+{
+ uint32_t reg = 0U;
+
+ reg = RCU_CFG0;
+
+ /* PLL clock source and multiplication factor configuration */
+ reg &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ reg |= (pll_src | pll_mul);
+
+ RCU_CFG0 = reg;
+}
+
+/*!
+ \brief configure the PLL clock source preselection
+ \param[in] pll_presel: PLL clock source preselection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PLLPRESRC_HXTAL: HXTAL selected as PLL source clock
+ \arg RCU_PLLPRESRC_IRC48M: CK_PLL selected as PREDV0 input source clock
+ \param[out] none
+ \retval none
+*/
+void rcu_pllpresel_config(uint32_t pll_presel)
+{
+ uint32_t reg = 0U;
+
+ reg = RCU_CFG1;
+
+ /* PLL clock source preselection */
+ reg &= ~RCU_CFG1_PLLPRESEL;
+ reg |= pll_presel;
+
+ RCU_CFG1 = reg;
+}
+
+/*!
+ \brief configure the PREDV0 division factor and clock source
+ \param[in] predv0_source: PREDV0 input clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PREDV0SRC_HXTAL_IRC48M: HXTAL or IRC48M selected as PREDV0 input source clock
+ \arg RCU_PREDV0SRC_CKPLL1: CK_PLL1 selected as PREDV0 input source clock
+ \param[in] predv0_div: PREDV0 division factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PREDV0_DIVx, x = 1..16
+ \param[out] none
+ \retval none
+*/
+void rcu_predv0_config(uint32_t predv0_source, uint32_t predv0_div)
+{
+ uint32_t reg = 0U;
+
+ reg = RCU_CFG1;
+ /* reset PREDV0SEL and PREDV0 bits */
+ reg &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV0);
+ /* set the PREDV0SEL and PREDV0 division factor */
+ reg |= (predv0_source | predv0_div);
+
+ RCU_CFG1 = reg;
+}
+
+/*!
+ \brief configure the PREDV1 division factor
+ \param[in] predv1_div: PREDV1 division factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PREDV1_DIVx, x = 1..16
+ \param[out] none
+ \retval none
+*/
+void rcu_predv1_config(uint32_t predv1_div)
+{
+ uint32_t reg = 0U;
+
+ reg = RCU_CFG1;
+ /* reset the PREDV1 bits */
+ reg &= ~RCU_CFG1_PREDV1;
+ /* set the PREDV1 division factor */
+ reg |= predv1_div;
+
+ RCU_CFG1 = reg;
+}
+
+/*!
+ \brief configure the PLL1 clock
+ \param[in] pll_mul: PLL clock multiplication factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PLL1_MULx (x = 8..16, 20)
+ \param[out] none
+ \retval none
+*/
+void rcu_pll1_config(uint32_t pll_mul)
+{
+ RCU_CFG1 &= ~RCU_CFG1_PLL1MF;
+ RCU_CFG1 |= pll_mul;
+}
+
+/*!
+ \brief configure the PLL2 clock
+ \param[in] pll_mul: PLL clock multiplication factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PLL2_MULx (x = 8..16, 20)
+ \param[out] none
+ \retval none
+*/
+void rcu_pll2_config(uint32_t pll_mul)
+{
+ RCU_CFG1 &= ~RCU_CFG1_PLL2MF;
+ RCU_CFG1 |= pll_mul;
+}
+
+/*!
+ \brief configure the ADC prescaler factor
+ \param[in] adc_psc: ADC prescaler factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_CKADC_CKAPB2_DIV2: ADC prescaler select CK_APB2/2
+ \arg RCU_CKADC_CKAPB2_DIV4: ADC prescaler select CK_APB2/4
+ \arg RCU_CKADC_CKAPB2_DIV6: ADC prescaler select CK_APB2/6
+ \arg RCU_CKADC_CKAPB2_DIV8: ADC prescaler select CK_APB2/8
+ \arg RCU_CKADC_CKAPB2_DIV12: ADC prescaler select CK_APB2/12
+ \arg RCU_CKADC_CKAPB2_DIV16: ADC prescaler select CK_APB2/16
+ \arg RCU_CKADC_CKAHB_DIV3: ADC prescaler select CK_AHB/3
+ \arg RCU_CKADC_CKAHB_DIV5: ADC prescaler select CK_AHB/5
+ \arg RCU_CKADC_CKAHB_DIV7: ADC prescaler select CK_AHB/7
+ \arg RCU_CKADC_CKAHB_DIV9: ADC prescaler select CK_AHB/9
+ \param[out] none
+ \retval none
+*/
+void rcu_adc_clock_config(uint32_t adc_psc)
+{
+ uint32_t reg0, reg1;
+
+ /* reset the ADCPSC bits */
+ reg0 = RCU_CFG0;
+ reg0 &= ~(RCU_CFG0_ADCPSC_2 | RCU_CFG0_ADCPSC);
+ reg1 = RCU_CFG1;
+ reg1 &= ~RCU_CFG1_ADCPSC_3;
+
+ /* set the ADC prescaler factor */
+ switch (adc_psc) {
+ case RCU_CKADC_CKAPB2_DIV2:
+ case RCU_CKADC_CKAPB2_DIV4:
+ case RCU_CKADC_CKAPB2_DIV6:
+ case RCU_CKADC_CKAPB2_DIV8:
+ reg0 |= (adc_psc << RCU_ADC_PSC_OFFSET);
+ break;
+
+ case RCU_CKADC_CKAPB2_DIV12:
+ case RCU_CKADC_CKAPB2_DIV16:
+ adc_psc &= ~BIT(2);
+ reg0 |= ((adc_psc << RCU_ADC_PSC_OFFSET) | RCU_CFG0_ADCPSC_2);
+ break;
+
+ case RCU_CKADC_CKAHB_DIV3:
+ case RCU_CKADC_CKAHB_DIV5:
+ case RCU_CKADC_CKAHB_DIV7:
+ case RCU_CKADC_CKAHB_DIV9:
+ adc_psc &= ~BITS(2, 3);
+ reg0 |= (adc_psc << RCU_ADC_PSC_OFFSET);
+ reg1 |= RCU_CFG1_ADCPSC_3;
+ break;
+
+ default:
+ break;
+ }
+
+ /* set the register */
+ RCU_CFG0 = reg0;
+ RCU_CFG1 = reg1;
+}
+
+/*!
+ \brief configure the USBFS prescaler factor
+ \param[in] adc_div: USB prescaler factor
+ only one parameter can be selected which is shown as below:
+ \arg RCU_CKUSB_CKPLL_DIV1_5: USBFS prescaler select CK_PLL/1.5
+ \arg RCU_CKUSB_CKPLL_DIV1: USBFS prescaler select CK_PLL/1
+ \arg RCU_CKUSB_CKPLL_DIV2_5: USBFS prescaler select CK_PLL/2.5
+ \arg RCU_CKUSB_CKPLL_DIV2: USBFS prescaler select CK_PLL/2
+ \arg RCU_CKUSB_CKPLL_DIV3: USBFS prescaler select CK_PLL/3
+ \arg RCU_CKUSB_CKPLL_DIV3_5: USBFS prescaler select CK_PLL/3.5
+ \arg RCU_CKUSB_CKPLL_DIV4: USBFS prescaler select CK_PLL/4
+ \param[out] none
+ \retval none
+*/
+void rcu_usb_clock_config(uint32_t usb_psc)
+{
+ uint32_t reg;
+
+ reg = RCU_CFG0;
+
+ /* configure the USBFS prescaler factor */
+ reg &= ~RCU_CFG0_USBFSPSC;
+
+ RCU_CFG0 = (reg | usb_psc);
+}
+
+/*!
+ \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_IRC40K: CK_IRC40K selected as RTC source clock
+ \arg RCU_RTCSRC_HXTAL_DIV_128: CK_HXTAL/128 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 I2S1 clock source selection
+ \param[in] i2s_clock_source: I2S1 clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_I2S1SRC_CKSYS: system clock selected as I2S1 source clock
+ \arg RCU_I2S1SRC_CKPLL2_MUL2: CK_PLL2x2 selected as I2S1 source clock
+ \param[out] none
+ \retval none
+*/
+void rcu_i2s1_clock_config(uint32_t i2s_clock_source)
+{
+ uint32_t reg;
+
+ reg = RCU_CFG1;
+ /* reset the I2S1SEL bit and set according to i2s_clock_source */
+ reg &= ~RCU_CFG1_I2S1SEL;
+ RCU_CFG1 = (reg | i2s_clock_source);
+}
+
+/*!
+ \brief configure the I2S2 clock source selection
+ \param[in] i2s_clock_source: I2S2 clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_I2S2SRC_CKSYS: system clock selected as I2S2 source clock
+ \arg RCU_I2S2SRC_CKPLL2_MUL2: CK_PLL2x2 selected as I2S2 source clock
+ \param[out] none
+ \retval none
+*/
+void rcu_i2s2_clock_config(uint32_t i2s_clock_source)
+{
+ uint32_t reg;
+
+ reg = RCU_CFG1;
+ /* reset the I2S2SEL bit and set according to i2s_clock_source */
+ reg &= ~RCU_CFG1_I2S2SEL;
+ RCU_CFG1 = (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_CKPLL: CK_PLL 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 CK48MSEL bit and set according to ck48m_clock_source */
+ reg &= ~RCU_ADDCTL_CK48MSEL;
+ RCU_ADDCTL = (reg | ck48m_clock_source);
+}
+
+/*!
+ \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_IRC8MSTB: IRC8M stabilization flag
+ \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag
+ \arg RCU_FLAG_PLLSTB: PLL stabilization flag
+ \arg RCU_FLAG_PLL1STB: PLL1 stabilization flag
+ \arg RCU_FLAG_PLL2STB: PLL2 stabilization flag
+ \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag
+ \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag
+ \arg RCU_FLAG_IRC48MSTB: IRC48M stabilization flag
+ \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_IRC40KSTB: 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_PLL1STB: PLL1 stabilization interrupt flag
+ \arg RCU_INT_FLAG_PLL2STB: PLL2 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_IRC40KSTB_CLR: IRC40K stabilization interrupt flag clear
+ \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear
+ \arg RCU_INT_FLAG_IRC8MSTB_CLR: IRC8M 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_PLL1STB_CLR: PLL1 stabilization interrupt flag clear
+ \arg RCU_INT_FLAG_PLL2STB_CLR: PLL2 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_IRC40KSTB: IRC40K stabilization interrupt enable
+ \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable
+ \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable
+ \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable
+ \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable
+ \arg RCU_INT_PLL1STB: PLL1 stabilization interrupt enable
+ \arg RCU_INT_PLL2STB: PLL2 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_IRC40KSTB: IRC40K stabilization interrupt enable
+ \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable
+ \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable
+ \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable
+ \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable
+ \arg RCU_INT_PLL1STB: PLL1 stabilization interrupt enable
+ \arg RCU_INT_PLL2STB: PLL2 stabilization interrupt enable
+ \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt enable
+ \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_LXTAL_LOWDRI: lower driving capability
+ \arg RCU_LXTAL_MED_LOWDRI: medium low driving capability
+ \arg RCU_LXTAL_MED_HIGHDRI: medium high driving capability
+ \arg RCU_LXTAL_HIGHDRI: 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: high speed crystal oscillator(HXTAL)
+ \arg RCU_LXTAL: low speed crystal oscillator(LXTAL)
+ \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M)
+ \arg RCU_IRC48M: internal 48M RC oscillators(IRC48M)
+ \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K)
+ \arg RCU_PLL_CK: phase locked loop(PLL)
+ \arg RCU_PLL1_CK: phase locked loop 1
+ \arg RCU_PLL2_CK: phase locked loop 2
+ \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 or not */
+ 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 or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)) {
+ reval = SUCCESS;
+ }
+ break;
+
+ /* wait IRC8M stable */
+ case RCU_IRC8M:
+ while ((RESET == osci_stat) && (IRC8M_STARTUP_TIMEOUT != stb_cnt)) {
+ osci_stat = rcu_flag_get(RCU_FLAG_IRC8MSTB);
+ stb_cnt++;
+ }
+
+ /* check whether flag is set or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_IRC8MSTB)) {
+ 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 or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)) {
+ reval = SUCCESS;
+ }
+ break;
+
+ /* wait IRC40K stable */
+ case RCU_IRC40K:
+ while ((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) {
+ osci_stat = rcu_flag_get(RCU_FLAG_IRC40KSTB);
+ stb_cnt++;
+ }
+
+ /* check whether flag is set or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_IRC40KSTB)) {
+ 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 or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_PLLSTB)) {
+ reval = SUCCESS;
+ }
+ break;
+
+ /* wait PLL1 stable */
+ case RCU_PLL1_CK:
+ while ((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) {
+ osci_stat = rcu_flag_get(RCU_FLAG_PLL1STB);
+ stb_cnt++;
+ }
+
+ /* check whether flag is set or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_PLL1STB)) {
+ reval = SUCCESS;
+ }
+ break;
+ /* wait PLL2 stable */
+ case RCU_PLL2_CK:
+ while ((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) {
+ osci_stat = rcu_flag_get(RCU_FLAG_PLL2STB);
+ stb_cnt++;
+ }
+
+ /* check whether flag is set or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_PLL2STB)) {
+ 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: high speed crystal oscillator(HXTAL)
+ \arg RCU_LXTAL: low speed crystal oscillator(LXTAL)
+ \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M)
+ \arg RCU_IRC48M: internal 48M RC oscillators(IRC48M)
+ \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K)
+ \arg RCU_PLL_CK: phase locked loop(PLL)
+ \arg RCU_PLL1_CK: phase locked loop 1
+ \arg RCU_PLL2_CK: phase locked loop 2
+ \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: high speed crystal oscillator(HXTAL)
+ \arg RCU_LXTAL: low speed crystal oscillator(LXTAL)
+ \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M)
+ \arg RCU_IRC48M: internal 48M RC oscillators(IRC48M)
+ \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K)
+ \arg RCU_PLL_CK: phase locked loop(PLL)
+ \arg RCU_PLL1_CK: phase locked loop 1
+ \arg RCU_PLL2_CK: phase locked loop 2
+ \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: high speed crystal oscillator(HXTAL)
+ \arg RCU_LXTAL: low speed crystal oscillator(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_IRC8M:
+ case RCU_IRC48M:
+ case RCU_IRC40K:
+ case RCU_PLL_CK:
+ case RCU_PLL1_CK:
+ case RCU_PLL2_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: high speed crystal oscillator(HXTAL)
+ \arg RCU_LXTAL: low speed crystal oscillator(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_IRC8M:
+ case RCU_IRC48M:
+ case RCU_IRC40K:
+ case RCU_PLL_CK:
+ case RCU_PLL1_CK:
+ case RCU_PLL2_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 IRC8M adjust value
+ \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F
+ \arg 0x00 - 0x1F
+ \param[out] none
+ \retval none
+*/
+void rcu_irc8m_adjust_value_set(uint32_t irc8m_adjval)
+{
+ uint32_t reg;
+
+ reg = RCU_CTL;
+ /* reset the IRC8MADJ bits and set according to irc8m_adjval */
+ reg &= ~RCU_CTL_IRC8MADJ;
+ RCU_CTL = (reg | ((irc8m_adjval & RCU_IRC8M_ADJUST_MASK) << RCU_IRC8M_ADJUST_OFFSET));
+}
+
+/*!
+ \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_0: the core voltage is 1.0V
+ \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V
+ \arg RCU_DEEPSLEEP_V_0_8: the core voltage is 0.8V
+ \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V
+ \param[out] none
+ \retval none
+*/
+void rcu_deepsleep_voltage_set(uint32_t dsvol)
+{
+ dsvol &= RCU_DSV_DSLPVS;
+ RCU_DSV = dsvol;
+}
+
+/*!
+ \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 pllsel, pllpresel, predv0sel, pllmf, ck_src, idx, clk_exp;
+ uint32_t predv0, predv1, pll1mf;
+
+ /* exponent of AHB, APB1 and APB2 clock divider */
+ uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+ uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+ uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+ sws = GET_BITS(RCU_CFG0, 2, 3);
+ switch (sws) {
+ /* IRC8M is selected as CK_SYS */
+ case SEL_IRC8M:
+ cksys_freq = IRC8M_VALUE;
+ break;
+ /* HXTAL is selected as CK_SYS */
+ case SEL_HXTAL:
+ cksys_freq = HXTAL_VALUE;
+ break;
+ /* PLL is selected as CK_SYS */
+ case SEL_PLL:
+ /* PLL clock source selection, HXTAL, IRC48M or IRC8M/2 */
+ pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL);
+
+ if (RCU_PLLSRC_HXTAL_IRC48M == pllsel) {
+ /* PLL clock source is HXTAL or IRC48M */
+ pllpresel = (RCU_CFG1 & RCU_CFG1_PLLPRESEL);
+
+ if (RCU_PLLPRESRC_HXTAL == pllpresel) {
+ /* PLL clock source is HXTAL */
+ ck_src = HXTAL_VALUE;
+ } else {
+ /* PLL clock source is IRC48 */
+ ck_src = IRC48M_VALUE;
+ }
+
+ predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL);
+ /* source clock use PLL1 */
+ if (RCU_PREDV0SRC_CKPLL1 == predv0sel) {
+ predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> RCU_CFG1_PREDV1_OFFSET) + 1U;
+ pll1mf = (uint32_t)((RCU_CFG1 & RCU_CFG1_PLL1MF) >> RCU_CFG1_PLL1MF_OFFSET) + 2U;
+ if (17U == pll1mf) {
+ pll1mf = 20U;
+ }
+ ck_src = (ck_src / predv1) * pll1mf;
+ }
+ predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U;
+ ck_src /= predv0;
+ } else {
+ /* PLL clock source is IRC8M/2 */
+ ck_src = IRC8M_VALUE / 2U;
+ }
+
+ /* PLL multiplication factor */
+ pllmf = GET_BITS(RCU_CFG0, 18, 21);
+ if ((RCU_CFG0 & RCU_CFG0_PLLMF_4)) {
+ pllmf |= 0x10U;
+ }
+ if (pllmf < 15U) {
+ pllmf += 2U;
+ } else {
+ pllmf += 1U;
+ }
+ cksys_freq = ck_src * pllmf;
+ if (15U == pllmf) {
+ cksys_freq = ck_src * 6U + ck_src / 2U;
+ }
+
+ break;
+ /* IRC8M is selected as CK_SYS */
+ default:
+ cksys_freq = IRC8M_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, 8, 10);
+ clk_exp = apb1_exp[idx];
+ apb1_freq = ahb_freq >> clk_exp;
+
+ /* calculate APB2 clock frequency */
+ idx = GET_BITS(RCU_CFG0, 11, 13);
+ 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;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_rtc.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_rtc.c
new file mode 100644
index 0000000000..d3a66310e2
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_rtc.c
@@ -0,0 +1,276 @@
+/*!
+ \file gd32e10x_rtc.c
+ \brief RTC driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_rtc.h"
+
+/* RTC register high / low bits mask */
+#define RTC_HIGH_BITS_MASK ((uint32_t)0x000F0000U) /* RTC high bits mask */
+#define RTC_LOW_BITS_MASK ((uint32_t)0x0000FFFFU) /* RTC low bits mask */
+
+/* RTC register high bits offset */
+#define RTC_HIGH_BITS_OFFSET ((uint32_t)16U)
+
+/*!
+ \brief enter RTC configuration mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void rtc_configuration_mode_enter(void)
+{
+ RTC_CTL |= RTC_CTL_CMF;
+}
+
+/*!
+ \brief exit RTC configuration mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void rtc_configuration_mode_exit(void)
+{
+ RTC_CTL &= ~RTC_CTL_CMF;
+}
+
+/*!
+ \brief set RTC counter value
+ \param[in] cnt: RTC counter value
+ \param[out] none
+ \retval none
+*/
+void rtc_counter_set(uint32_t cnt)
+{
+ rtc_configuration_mode_enter();
+ /* set the RTC counter high bits */
+ RTC_CNTH = (cnt >> RTC_HIGH_BITS_OFFSET);
+ /* set the RTC counter low bits */
+ RTC_CNTL = (cnt & RTC_LOW_BITS_MASK);
+ rtc_configuration_mode_exit();
+}
+
+/*!
+ \brief set RTC prescaler value
+ \param[in] psc: RTC prescaler value
+ \param[out] none
+ \retval none
+*/
+void rtc_prescaler_set(uint32_t psc)
+{
+ rtc_configuration_mode_enter();
+ /* set the RTC prescaler high bits */
+ RTC_PSCH = ((psc & RTC_HIGH_BITS_MASK) >> RTC_HIGH_BITS_OFFSET);
+ /* set the RTC prescaler low bits */
+ RTC_PSCL = (psc & RTC_LOW_BITS_MASK);
+ rtc_configuration_mode_exit();
+}
+
+/*!
+ \brief wait RTC last write operation finished flag set
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void rtc_lwoff_wait(void)
+{
+ /* loop until LWOFF flag is set */
+ while (RESET == (RTC_CTL & RTC_CTL_LWOFF)) {
+ }
+}
+
+/*!
+ \brief wait RTC registers synchronized flag set
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void rtc_register_sync_wait(void)
+{
+ /* clear RSYNF flag */
+ RTC_CTL &= ~RTC_CTL_RSYNF;
+ /* loop until RSYNF flag is set */
+ while (RESET == (RTC_CTL & RTC_CTL_RSYNF)) {
+ }
+}
+
+/*!
+ \brief set RTC alarm value
+ \param[in] alarm: RTC alarm value
+ \param[out] none
+ \retval none
+*/
+void rtc_alarm_config(uint32_t alarm)
+{
+ rtc_configuration_mode_enter();
+ /* set the alarm high bits */
+ RTC_ALRMH = (alarm >> RTC_HIGH_BITS_OFFSET);
+ /* set the alarm low bits */
+ RTC_ALRML = (alarm & RTC_LOW_BITS_MASK);
+ rtc_configuration_mode_exit();
+}
+
+/*!
+ \brief get RTC counter value
+ \param[in] none
+ \param[out] none
+ \retval RTC counter value
+*/
+uint32_t rtc_counter_get(void)
+{
+ uint32_t temp = 0x0U;
+
+ temp = RTC_CNTL;
+ temp |= (RTC_CNTH << RTC_HIGH_BITS_OFFSET);
+ return temp;
+}
+
+/*!
+ \brief get RTC divider value
+ \param[in] none
+ \param[out] none
+ \retval RTC divider value
+*/
+uint32_t rtc_divider_get(void)
+{
+ uint32_t temp = 0x00U;
+
+ temp = ((RTC_DIVH & RTC_DIVH_DIV) << RTC_HIGH_BITS_OFFSET);
+ temp |= RTC_DIVL;
+ return temp;
+}
+
+/*!
+ \brief get RTC flag status
+ \param[in] flag: specify which flag status to get
+ only one parameter can be selected which is shown as below:
+ \arg RTC_FLAG_SECOND: second interrupt flag
+ \arg RTC_FLAG_ALARM: alarm interrupt flag
+ \arg RTC_FLAG_OVERFLOW: overflow interrupt flag
+ \arg RTC_FLAG_RSYN: registers synchronized flag
+ \arg RTC_FLAG_LWOF: last write operation finished flag
+ \param[out] none
+ \retval SET or RESET
+*/
+FlagStatus rtc_flag_get(uint32_t flag)
+{
+ if (RESET != (RTC_CTL & flag)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear RTC flag status
+ \param[in] flag: specify which flag status to clear
+ one or more parameters can be selected which are shown as below:
+ \arg RTC_FLAG_SECOND: second interrupt flag
+ \arg RTC_FLAG_ALARM: alarm interrupt flag
+ \arg RTC_FLAG_OVERFLOW: overflow interrupt flag
+ \arg RTC_FLAG_RSYN: registers synchronized flag
+ \param[out] none
+ \retval none
+*/
+void rtc_flag_clear(uint32_t flag)
+{
+ /* clear RTC flag */
+ RTC_CTL &= ~flag;
+}
+
+/*!
+ \brief get RTC interrupt flag status
+ \param[in] flag: specify which flag status to get
+ only one parameter can be selected which is shown as below:
+ \arg RTC_INT_FLAG_SECOND: second interrupt flag
+ \arg RTC_INT_FLAG_ALARM: alarm interrupt flag
+ \arg RTC_INT_FLAG_OVERFLOW: overflow interrupt flag
+ \param[out] none
+ \retval SET or RESET
+*/
+FlagStatus rtc_interrupt_flag_get(uint32_t flag)
+{
+ if (RESET != (RTC_CTL & flag)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear RTC interrupt flag status
+ \param[in] flag: specify which flag status to clear
+ one or more parameters can be selected which are shown as below:
+ \arg RTC_INT_FLAG_SECOND: second interrupt flag
+ \arg RTC_INT_FLAG_ALARM: alarm interrupt flag
+ \arg RTC_INT_FLAG_OVERFLOW: overflow interrupt flag
+ \param[out] none
+ \retval none
+*/
+void rtc_interrupt_flag_clear(uint32_t flag)
+{
+ /* clear RTC interrupt flag */
+ RTC_CTL &= ~flag;
+}
+
+/*!
+ \brief enable RTC interrupt
+ \param[in] interrupt: specify which interrupt to enbale
+ one or more parameters can be selected which are shown as below:
+ \arg RTC_INT_SECOND: second interrupt
+ \arg RTC_INT_ALARM: alarm interrupt
+ \arg RTC_INT_OVERFLOW: overflow interrupt
+ \param[out] none
+ \retval none
+*/
+void rtc_interrupt_enable(uint32_t interrupt)
+{
+ RTC_INTEN |= interrupt;
+}
+
+/*!
+ \brief disable RTC interrupt
+ \param[in] interrupt: specify which interrupt to disbale
+ one or more parameters can be selected which are shown as below:
+ \arg RTC_INT_SECOND: second interrupt
+ \arg RTC_INT_ALARM: alarm interrupt
+ \arg RTC_INT_OVERFLOW: overflow interrupt
+ \param[out] none
+ \retval none
+*/
+void rtc_interrupt_disable(uint32_t interrupt)
+{
+ RTC_INTEN &= ~interrupt;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_spi.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_spi.c
new file mode 100644
index 0000000000..963526f71c
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_spi.c
@@ -0,0 +1,843 @@
+/*!
+ \file gd32e10x_spi.c
+ \brief SPI driver
+
+ \version 2017-12-26, V1.0.1, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_spi.h"
+
+/* SPI/I2S parameter initialization mask */
+#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */
+#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */
+
+/* I2S clock source selection, multiplication and division mask */
+#define I2S1_CLOCK_SEL ((uint32_t)0x00020000U) /* I2S1 clock source selection */
+#define I2S2_CLOCK_SEL ((uint32_t)0x00040000U) /* I2S2 clock source selection */
+#define I2S_CLOCK_MUL_MASK ((uint32_t)0x0000F000U) /* I2S clock multiplication mask */
+#define I2S_CLOCK_DIV_MASK ((uint32_t)0x000000F0U) /* I2S clock division mask */
+
+/* default value and offset */
+#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /* default value of SPI_I2SPSC register */
+#define RCU_CFG1_PREDV1_OFFSET 4U /* PREDV1 offset in RCU_CFG1 */
+#define RCU_CFG1_PLL2MF_OFFSET 12U /* PLL2MF offset in RCU_CFG1 */
+
+/*!
+ \brief reset SPI and I2S
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_i2s_deinit(uint32_t spi_periph)
+{
+ switch (spi_periph) {
+ case SPI0:
+ /* reset SPI0 */
+ rcu_periph_reset_enable(RCU_SPI0RST);
+ rcu_periph_reset_disable(RCU_SPI0RST);
+ break;
+ case SPI1:
+ /* reset SPI1 and I2S1 */
+ rcu_periph_reset_enable(RCU_SPI1RST);
+ rcu_periph_reset_disable(RCU_SPI1RST);
+ break;
+ case SPI2:
+ /* reset SPI2 and I2S2 */
+ rcu_periph_reset_enable(RCU_SPI2RST);
+ rcu_periph_reset_disable(RCU_SPI2RST);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief initialize the parameters of SPI struct with the default values
+ \param[in] spi_struct: SPI parameter stuct
+ \param[out] none
+ \retval none
+*/
+void spi_struct_para_init(spi_parameter_struct *spi_struct)
+{
+ /* set the SPI struct with the default values */
+ spi_struct->device_mode = SPI_SLAVE;
+ spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX;
+ spi_struct->frame_size = SPI_FRAMESIZE_8BIT;
+ spi_struct->nss = SPI_NSS_HARD;
+ spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
+ spi_struct->prescale = SPI_PSC_2;
+}
+
+/*!
+ \brief initialize SPI parameter
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \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
+*/
+#ifdef GD_MBED_USED
+void spi_para_init(uint32_t spi_periph, spi_parameter_struct *spi_struct)
+#else
+void spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct)
+#endif
+{
+ uint32_t reg = 0U;
+ reg = SPI_CTL0(spi_periph);
+ reg &= SPI_INIT_MASK;
+
+ /* select SPI as master or slave */
+ reg |= spi_struct->device_mode;
+ /* select SPI transfer mode */
+ reg |= spi_struct->trans_mode;
+ /* select SPI frame size */
+ reg |= spi_struct->frame_size;
+ /* select SPI NSS use hardware or software */
+ reg |= spi_struct->nss;
+ /* select SPI LSB or MSB */
+ reg |= spi_struct->endian;
+ /* select SPI polarity and phase */
+ reg |= spi_struct->clock_polarity_phase;
+ /* 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 enable SPI
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_enable(uint32_t spi_periph)
+{
+ SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN;
+}
+
+/*!
+ \brief disable SPI
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_disable(uint32_t spi_periph)
+{
+ SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
+}
+
+/*!
+ \brief initialize I2S parameter
+ \param[in] spi_periph: SPIx(x=1,2)
+ \param[in] mode: I2S operation mode
+ only one parameter can be selected which is shown as below:
+ \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] standard: I2S standard
+ only one parameter can be selected which is shown as below:
+ \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] ckpl: I2S idle state clock polarity
+ only one parameter can be selected which is shown as below:
+ \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 mode, uint32_t standard, uint32_t 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)mode;
+ /* select I2S standard */
+ reg |= (uint32_t)standard;
+ /* select I2S polarity */
+ reg |= (uint32_t)ckpl;
+
+ /* write to SPI_I2SCTL register */
+ SPI_I2SCTL(spi_periph) = (uint32_t)reg;
+}
+
+/*!
+ \brief configure I2S prescaler
+ \param[in] spi_periph: SPIx(x=1,2)
+ \param[in] audiosample: I2S audio sample rate
+ only one parameter can be selected which is shown as below:
+ \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: I2S data length and channel length
+ only one parameter can be selected which is shown as below:
+ \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: I2S master clock output
+ only one parameter can be selected which is shown as below:
+ \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 audiosample, uint32_t frameformat, uint32_t mckout)
+{
+ uint32_t i2sdiv = 2U, i2sof = 0U;
+ uint32_t clks = 0U;
+ uint32_t i2sclock = 0U;
+
+ /* deinit SPI_I2SPSC register */
+ SPI_I2SPSC(spi_periph) = SPI_I2SPSC_DEFAULT_VALUE;
+
+ /* get the I2S clock source */
+ if (SPI1 == ((uint32_t)spi_periph)) {
+ /* I2S1 clock source selection */
+ clks = I2S1_CLOCK_SEL;
+ } else {
+ /* I2S2 clock source selection */
+ clks = I2S2_CLOCK_SEL;
+ }
+
+ if (0U != (RCU_CFG1 & clks)) {
+ /* get RCU PLL2 clock multiplication factor */
+ clks = (uint32_t)((RCU_CFG1 & I2S_CLOCK_MUL_MASK) >> RCU_CFG1_PLL2MF_OFFSET);
+
+ if ((clks > 5U) && (clks < 15U)) {
+ /* multiplier is between 8 and 16 */
+ clks += 2U;
+ } else {
+ if (15U == clks) {
+ /* multiplier is 20 */
+ clks = 20U;
+ }
+ }
+
+ /* get the PREDV1 value */
+ i2sclock = (uint32_t)(((RCU_CFG1 & I2S_CLOCK_DIV_MASK) >> RCU_CFG1_PREDV1_OFFSET) + 1U);
+ /* calculate I2S clock based on PLL2 and PREDV1 */
+ if (0U != (RCU_CFG1_PLLPRESEL & RCU_CFG1)) {
+ i2sclock = (uint32_t)((IRC48M_VALUE / i2sclock) * clks * 2U);
+ } else {
+ i2sclock = (uint32_t)((HXTAL_VALUE / i2sclock) * clks * 2U);
+ }
+ } else {
+ /* get system clock */
+ i2sclock = rcu_clock_freq_get(CK_SYS);
+ }
+
+ /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
+ if (I2S_MCKOUT_ENABLE == mckout) {
+ clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample);
+ } else {
+ if (I2S_FRAMEFORMAT_DT16B_CH16B == frameformat) {
+ clks = (uint32_t)(((i2sclock / 32U) * 10U) / audiosample);
+ } else {
+ clks = (uint32_t)(((i2sclock / 64U) * 10U) / audiosample);
+ }
+ }
+
+ /* remove the floating point */
+ clks = (clks + 5U) / 10U;
+ i2sof = (clks & 0x00000001U);
+ i2sdiv = ((clks - i2sof) / 2U);
+ i2sof = (i2sof << 8U);
+
+ /* set the default values */
+ if ((i2sdiv < 2U) || (i2sdiv > 255U)) {
+ i2sdiv = 2U;
+ i2sof = 0U;
+ }
+
+ /* configure SPI_I2SPSC */
+ SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | 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)frameformat;
+}
+
+/*!
+ \brief enable I2S
+ \param[in] spi_periph: SPIx(x=1,2)
+ \param[out] none
+ \retval none
+*/
+void i2s_enable(uint32_t spi_periph)
+{
+ SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
+}
+
+/*!
+ \brief disable I2S
+ \param[in] spi_periph: SPIx(x=1,2)
+ \param[out] none
+ \retval none
+*/
+void i2s_disable(uint32_t spi_periph)
+{
+ SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
+}
+
+/*!
+ \brief enable SPI NSS output
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_nss_output_enable(uint32_t spi_periph)
+{
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
+}
+
+/*!
+ \brief disable SPI NSS output
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \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)
+ \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)
+ \param[out] none
+ \retval none
+*/
+void spi_nss_internal_low(uint32_t spi_periph)
+{
+ SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS);
+}
+
+/*!
+ \brief enable SPI DMA send or receive
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[in] dma: SPI DMA mode
+ only one parameter can be selected which is shown as below:
+ \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA
+ \arg SPI_DMA_RECEIVE: SPI receive data using DMA
+ \param[out] none
+ \retval none
+*/
+void spi_dma_enable(uint32_t spi_periph, uint8_t dma)
+{
+ if (SPI_DMA_TRANSMIT == dma) {
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
+ } else {
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
+ }
+}
+
+/*!
+ \brief disable SPI DMA send or receive
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[in] dma: SPI DMA mode
+ only one parameter can be selected which is shown as below:
+ \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA
+ \arg SPI_DMA_RECEIVE: SPI receive data using DMA
+ \param[out] none
+ \retval none
+*/
+void spi_dma_disable(uint32_t spi_periph, uint8_t dma)
+{
+ if (SPI_DMA_TRANSMIT == 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)
+ \param[in] frame_format: SPI frame size
+ only one parameter can be selected which is shown as below:
+ \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);
+ /* configure 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)
+ \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 SPI receive data
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \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)
+ \param[in] transfer_direction: SPI transfer direction
+ only one parameter can be selected which is shown as below:
+ \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode
+ \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode
+ \param[out] none
+ \retval none
+*/
+void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction)
+{
+ if (SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction) {
+ /* set the transmit-only mode */
+ SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT;
+ } else {
+ /* set the receive-only mode */
+ SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE;
+ }
+}
+
+/*!
+ \brief set SPI CRC polynomial
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \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)
+ \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 turn on CRC function
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_crc_on(uint32_t spi_periph)
+{
+ SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
+}
+
+/*!
+ \brief turn off CRC function
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_crc_off(uint32_t spi_periph)
+{
+ SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
+}
+
+/*!
+ \brief SPI next data is CRC value
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \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)
+ \param[in] crc: SPI crc value
+ only one parameter can be selected which is shown as below:
+ \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 crc)
+{
+ if (SPI_CRC_TX == 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)
+ \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)
+ \param[out] none
+ \retval none
+*/
+void spi_ti_mode_disable(uint32_t spi_periph)
+{
+ SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD);
+}
+
+/*!
+ \brief enable SPI NSS pulse mode
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_nssp_mode_enable(uint32_t spi_periph)
+{
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSP;
+}
+
+/*!
+ \brief disable SPI NSS pulse mode
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_nssp_mode_disable(uint32_t spi_periph)
+{
+ SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSP);
+}
+
+/*!
+ \brief enable quad wire SPI
+ \param[in] spi_periph: SPIx(only x=0)
+ \param[out] none
+ \retval none
+*/
+void qspi_enable(uint32_t spi_periph)
+{
+ SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD;
+}
+
+/*!
+ \brief disable quad wire SPI
+ \param[in] spi_periph: SPIx(only x=0)
+ \param[out] none
+ \retval none
+*/
+void qspi_disable(uint32_t spi_periph)
+{
+ SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD);
+}
+
+/*!
+ \brief enable quad wire SPI write
+ \param[in] spi_periph: SPIx(only x=0)
+ \param[out] none
+ \retval none
+*/
+void qspi_write_enable(uint32_t spi_periph)
+{
+ SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD);
+}
+
+/*!
+ \brief enable quad wire SPI read
+ \param[in] spi_periph: SPIx(only x=0)
+ \param[out] none
+ \retval none
+*/
+void qspi_read_enable(uint32_t spi_periph)
+{
+ SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD;
+}
+
+/*!
+ \brief enable SPI_IO2 and SPI_IO3 pin output
+ \param[in] spi_periph: SPIx(only x=0)
+ \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 disable SPI_IO2 and SPI_IO3 pin output
+ \param[in] spi_periph: SPIx(only x=0)
+ \param[out] none
+ \retval none
+*/
+void qspi_io23_output_disable(uint32_t spi_periph)
+{
+ SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
+}
+
+/*!
+ \brief enable SPI and I2S interrupt
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[in] interrupt: SPI/I2S interrupt
+ only one parameter can be selected which is shown as below:
+ \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 interrupt)
+{
+ switch (interrupt) {
+ /* SPI/I2S transmit buffer empty interrupt */
+ case SPI_I2S_INT_TBE:
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE;
+ break;
+ /* SPI/I2S receive buffer not empty interrupt */
+ case SPI_I2S_INT_RBNE:
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE;
+ break;
+ /* SPI/I2S error */
+ case SPI_I2S_INT_ERR:
+ SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief disable SPI and I2S interrupt
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[in] interrupt: SPI/I2S interrupt
+ only one parameter can be selected which is shown as below:
+ \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 interrupt)
+{
+ switch (interrupt) {
+ /* SPI/I2S transmit buffer empty interrupt */
+ case SPI_I2S_INT_TBE:
+ SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE);
+ break;
+ /* SPI/I2S receive buffer not empty interrupt */
+ case SPI_I2S_INT_RBNE:
+ SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE);
+ break;
+ /* SPI/I2S error */
+ case SPI_I2S_INT_ERR:
+ SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief get SPI and I2S interrupt flag status
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[in] interrupt: SPI/I2S interrupt flag status
+ only one parameter can be selected which is shown as below:
+ \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag
+ \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag
+ \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag
+ \arg SPI_INT_FLAG_CONFERR: config error interrupt flag
+ \arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag
+ \arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag
+ \arg SPI_I2S_INT_FLAG_FERR: format error interrupt flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt)
+{
+ uint32_t reg1 = SPI_STAT(spi_periph);
+ uint32_t reg2 = SPI_CTL1(spi_periph);
+
+ switch (interrupt) {
+ /* SPI/I2S transmit buffer empty interrupt */
+ case SPI_I2S_INT_FLAG_TBE:
+ reg1 = reg1 & SPI_STAT_TBE;
+ reg2 = reg2 & SPI_CTL1_TBEIE;
+ break;
+ /* SPI/I2S receive buffer not empty interrupt */
+ case SPI_I2S_INT_FLAG_RBNE:
+ reg1 = reg1 & SPI_STAT_RBNE;
+ reg2 = reg2 & SPI_CTL1_RBNEIE;
+ break;
+ /* SPI/I2S overrun interrupt */
+ case SPI_I2S_INT_FLAG_RXORERR:
+ reg1 = reg1 & SPI_STAT_RXORERR;
+ reg2 = reg2 & SPI_CTL1_ERRIE;
+ break;
+ /* SPI config error interrupt */
+ case SPI_INT_FLAG_CONFERR:
+ reg1 = reg1 & SPI_STAT_CONFERR;
+ reg2 = reg2 & SPI_CTL1_ERRIE;
+ break;
+ /* SPI CRC error interrupt */
+ case SPI_INT_FLAG_CRCERR:
+ reg1 = reg1 & SPI_STAT_CRCERR;
+ reg2 = reg2 & SPI_CTL1_ERRIE;
+ break;
+ /* I2S underrun error interrupt */
+ case I2S_INT_FLAG_TXURERR:
+ reg1 = reg1 & SPI_STAT_TXURERR;
+ reg2 = reg2 & SPI_CTL1_ERRIE;
+ break;
+ /* SPI/I2S format error interrupt */
+ case SPI_I2S_INT_FLAG_FERR:
+ reg1 = reg1 & SPI_STAT_FERR;
+ reg2 = reg2 & SPI_CTL1_ERRIE;
+ break;
+ default:
+ break;
+ }
+ /* get SPI/I2S interrupt flag status */
+ if ((0U != reg1) && (0U != reg2)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief get SPI and I2S flag status
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[in] flag: SPI/I2S flag status
+ one or more parameters can be selected which are shown as below:
+ \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 error 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 error 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 flag)
+{
+ if (RESET != (SPI_STAT(spi_periph) & flag)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear SPI CRC error flag status
+ \param[in] spi_periph: SPIx(x=0,1,2)
+ \param[out] none
+ \retval none
+*/
+void spi_crc_error_clear(uint32_t spi_periph)
+{
+ SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR);
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_timer.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_timer.c
new file mode 100644
index 0000000000..6416f492d6
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_timer.c
@@ -0,0 +1,2045 @@
+/*!
+ \file gd32e10x_timer.c
+ \brief TIMER driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_timer.h"
+
+/* TIMER init parameter mask */
+#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */
+#define COUNTERDIRECTION_MASK ((uint32_t)0x00000010U) /*!< TIMER init parameter counter direction mask */
+#define CLOCKDIVISION_MASK ((uint32_t)0x00000300U) /*!< TIMER init parameter clock division value mask */
+
+/*!
+ \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 init parameter struct with a default value
+ \param[in] initpara: init parameter struct
+ \param[out] none
+ \retval none
+*/
+void timer_struct_para_init(timer_parameter_struct *initpara)
+{
+ /* initialize the init parameter struct member with the default value */
+ initpara->prescaler = 0U;
+ initpara->alignedmode = TIMER_COUNTER_EDGE;
+ initpara->counterdirection = TIMER_COUNTER_UP;
+ initpara->period = 65535U;
+ initpara->clockdivision = TIMER_CKDIV_DIV1;
+ initpara->repetitioncounter = 0U;
+}
+
+/*!
+ \brief initialize TIMER counter
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] 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, 0~65535
+ 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 *initpara)
+{
+ /* configure the counter prescaler value */
+ TIMER_PSC(timer_periph) = (uint16_t)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)(initpara->alignedmode & ALIGNEDMODE_MASK);
+ TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->counterdirection & COUNTERDIRECTION_MASK);
+ } else {
+ TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR);
+ TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->counterdirection & COUNTERDIRECTION_MASK);
+ }
+
+ /* configure the autoreload value */
+ TIMER_CAR(timer_periph) = (uint32_t)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)(initpara->clockdivision & CLOCKDIVISION_MASK);
+ }
+
+ if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) {
+ /* configure the repetition counter value */
+ TIMER_CREP(timer_periph) = (uint32_t)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] aligned:
+ only one parameter can be selected which is shown as below:
+ \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 aligned)
+{
+ TIMER_CTL0(timer_periph) &= (uint32_t)(~TIMER_CTL0_CAM);
+ TIMER_CTL0(timer_periph) |= (uint32_t)aligned;
+}
+
+/*!
+ \brief set TIMER counter up direction
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \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] prescaler: prescaler value
+ \param[in] pscreload: prescaler reload mode
+ only one parameter can be selected which is shown as below:
+ \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 prescaler, uint32_t pscreload)
+{
+ TIMER_PSC(timer_periph) = (uint32_t)prescaler;
+
+ if (TIMER_PSC_RELOAD_NOW == 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] repetition: the counter repetition value, 0~255
+ \param[out] none
+ \retval none
+*/
+void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition)
+{
+ TIMER_CREP(timer_periph) = (uint32_t)repetition;
+}
+
+/*!
+ \brief configure TIMER autoreload register value
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] autoreload: the counter auto-reload value
+ \param[out] none
+ \retval none
+*/
+void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload)
+{
+ TIMER_CAR(timer_periph) = (uint32_t)autoreload;
+}
+
+/*!
+ \brief configure TIMER counter register value
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] counter: the counter value
+ \param[out] none
+ \retval none
+*/
+void timer_counter_value_config(uint32_t timer_periph, uint16_t counter)
+{
+ TIMER_CNT(timer_periph) = (uint32_t)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_PSC(timer_periph));
+ return (prescaler_value);
+}
+
+/*!
+ \brief configure TIMER single pulse mode
+ \param[in] timer_periph: TIMERx(x=0..8,11)
+ \param[in] spmode:
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t spmode)
+{
+ if (TIMER_SP_MODE_SINGLE == spmode) {
+ TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM;
+ } else if (TIMER_SP_MODE_REPETITIVE == spmode) {
+ TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM);
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief configure TIMER update source
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] update:
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t update)
+{
+ if (TIMER_UPDATE_SRC_REGULAR == update) {
+ TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS;
+ } else if (TIMER_UPDATE_SRC_GLOBAL == update) {
+ TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief enable the TIMER DMA
+ \param[in] timer_periph: TIMERx(x=0..7)
+ \param[in] dma: specify which DMA to enable
+ one or more parameters can be selected which are shown as below:
+ \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: channel 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 dma)
+{
+ TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma;
+}
+
+/*!
+ \brief disable the TIMER DMA
+ \param[in] timer_periph: TIMERxTIMERx(x=0..7)
+ \param[in] dma: specify which DMA to disbale
+ one or more parameters can be selected which are shown as below:
+ \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: channel 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 dma)
+{
+ TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(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
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel n is sent when channel n event occurs
+ \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel n is sent when update event occurs
+ \param[out] none
+ \retval none
+*/
+void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_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 {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief configure the TIMER DMA transfer
+ \param[in] timer_periph: TIMERx(x=0..4,7)
+ \param[in] dma_baseaddr:
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] dma_lenth:
+ only one parameter can be selected which is shown as below:
+ \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: TIMERx(x=0..4,7)
+ \param[in] event: the timer software event generation sources
+ one or more parameters can be selected which are shown as below:
+ \arg TIMER_EVENT_SRC_UPG: update event generation, 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 event)
+{
+ TIMER_SWEVG(timer_periph) |= (uint32_t)event;
+}
+
+/*!
+ \brief initialize TIMER break parameter struct with a default value
+ \param[in] breakpara: TIMER break parameter struct
+ \param[out] none
+ \retval none
+*/
+void timer_break_struct_para_init(timer_break_parameter_struct *breakpara)
+{
+ /* initialize the break parameter struct member with the default value */
+ breakpara->runoffstate = TIMER_ROS_STATE_DISABLE;
+ breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE;
+ breakpara->deadtime = 0U;
+ breakpara->breakpolarity = TIMER_BREAK_POLARITY_LOW;
+ breakpara->outputautostate = TIMER_OUTAUTO_DISABLE;
+ breakpara->protectmode = TIMER_CCHP_PROT_OFF;
+ breakpara->breakstate = TIMER_BREAK_DISABLE;
+}
+
+/*!
+ \brief configure TIMER break function
+ \param[in] timer_periph: TIMERx(x=0,7)
+ \param[in] breakpara: 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 *breakpara)
+{
+ TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) |
+ ((uint32_t)(breakpara->ideloffstate)) |
+ ((uint32_t)(breakpara->deadtime)) |
+ ((uint32_t)(breakpara->breakpolarity)) |
+ ((uint32_t)(breakpara->outputautostate)) |
+ ((uint32_t)(breakpara->protectmode)) |
+ ((uint32_t)(breakpara->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 enable or disable 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 enable or disable channel capture/compare control shadow register
+ \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] ccuctl: channel control shadow register update control
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t ccuctl)
+{
+ if (TIMER_UPDATECTL_CCU == ccuctl) {
+ TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC);
+ } else if (TIMER_UPDATECTL_CCUTRI == ccuctl) {
+ TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief initialize TIMER channel output parameter struct with a default value
+ \param[in] ocpara: TIMER channel n output parameter struct
+ \param[out] none
+ \retval none
+*/
+void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara)
+{
+ /* initialize the channel output parameter struct member with the default value */
+ ocpara->outputstate = TIMER_CCX_DISABLE;
+ ocpara->outputnstate = TIMER_CCXN_DISABLE;
+ ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH;
+ ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH;
+ ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW;
+ ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
+}
+
+/*!
+ \brief configure TIMER channel output function
+ \param[in] timer_periph: TIMERx(x=0..4,7)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] 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 channel, timer_oc_parameter_struct *ocpara)
+{
+ switch (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)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)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)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)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)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)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)((uint32_t)(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)(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)(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)(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)(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)(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)((uint32_t)(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)(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)(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)(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)(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)(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)((uint32_t)(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)(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)(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: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] ocmode: channel output compare mode
+ only one parameter can be selected which is shown as below:
+ \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: PWM mode 0
+ \arg TIMER_OC_MODE_PWM1: PWM mode 1
+ \param[out] none
+ \retval none
+*/
+void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)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)(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)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)(ocmode) << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel output pulse value
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] pulse: channel output pulse value
+ \param[out] none
+ \retval none
+*/
+void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CH0CV(timer_periph) = (uint32_t)pulse;
+ break;
+ /* configure TIMER_CH_1 */
+ case TIMER_CH_1:
+ TIMER_CH1CV(timer_periph) = (uint32_t)pulse;
+ break;
+ /* configure TIMER_CH_2 */
+ case TIMER_CH_2:
+ TIMER_CH2CV(timer_periph) = (uint32_t)pulse;
+ break;
+ /* configure TIMER_CH_3 */
+ case TIMER_CH_3:
+ TIMER_CH3CV(timer_periph) = (uint32_t)pulse;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel output shadow function
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] ocshadow: channel output shadow state
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t ocshadow)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)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)(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)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)(ocshadow) << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel output fast function
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] ocfast: channel output fast function
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t ocfast)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)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)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)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)ocfast << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel output clear function
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] occlear: channel output clear function
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t occlear)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)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)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)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)occlear << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel output polarity
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] ocpolarity: channel output polarity
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t ocpolarity)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P);
+ TIMER_CHCTL2(timer_periph) |= (uint32_t)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)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)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)ocpolarity << 12U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel complementary output polarity
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,7..13))
+ \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,7,8,11))
+ \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,7))
+ \param[in] ocnpolarity: channel complementary output polarity
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t ocnpolarity)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP);
+ TIMER_CHCTL2(timer_periph) |= (uint32_t)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)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)ocnpolarity << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel enable state
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] state: TIMER channel enable state
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint32_t state)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+ TIMER_CHCTL2(timer_periph) |= (uint32_t)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)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)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)state << 12U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure TIMER channel complementary output enable state
+ \param[in] timer_periph: TIMERx(x=0,7)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,7))
+ \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,7))
+ \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,7))
+ \param[in] ocnstate: TIMER channel complementary output enable state
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t ocnstate)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN);
+ TIMER_CHCTL2(timer_periph) |= (uint32_t)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)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)ocnstate << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief initialize TIMER channel input parameter struct with a default value
+ \param[in] icpara: TIMER channel intput parameter struct
+ \param[out] none
+ \retval none
+*/
+void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara)
+{
+ /* initialize the channel input parameter struct member with the default value */
+ icpara->icpolarity = TIMER_IC_POLARITY_RISING;
+ icpara->icselection = TIMER_IC_SELECTION_DIRECTTI;
+ icpara->icprescaler = TIMER_IC_PSC_DIV1;
+ icpara->icfilter = 0U;
+}
+
+/*!
+ \brief configure TIMER input capture parameter
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] icpara: TIMER channel intput parameter struct
+ icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING,
+ TIMER_IC_POLARITY_BOTH_EDGE(only for TIMER1~TIMER8)
+ 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 channel, timer_ic_parameter_struct *icpara)
+{
+ switch (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)(icpara->icpolarity);
+ /* reset the CH0MS bit */
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection);
+ /* reset the CH0CAPFLT bit */
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(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)(icpara->icpolarity) << 4U);
+ /* reset the CH1MS bit */
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U);
+ /* reset the CH1CAPFLT bit */
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(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)(icpara->icpolarity) << 8U);
+
+ /* reset the CH2MS bit */
+ TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS);
+ TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection));
+
+ /* reset the CH2CAPFLT bit */
+ TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT);
+ TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(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)(icpara->icpolarity) << 12U);
+
+ /* reset the CH3MS bit */
+ TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS);
+ TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U);
+
+ /* reset the CH3CAPFLT bit */
+ TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT);
+ TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(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, channel, (uint16_t)(icpara->icprescaler));
+}
+
+/*!
+ \brief configure TIMER channel input capture prescaler value
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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] prescaler: channel input capture prescaler value
+ only one parameter can be selected which is shown as below:
+ \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 channel, uint16_t prescaler)
+{
+ switch (channel) {
+ /* configure TIMER_CH_0 */
+ case TIMER_CH_0:
+ TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC);
+ TIMER_CHCTL0(timer_periph) |= (uint32_t)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)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)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)prescaler << 8U);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief read TIMER channel capture compare register value
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] channel:
+ only one parameter can be selected which is shown as below:
+ \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[out] none
+ \retval channel capture compare register value
+*/
+uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel)
+{
+ uint32_t count_value = 0U;
+
+ switch (channel) {
+ case TIMER_CH_0:
+ /* read TIMER channel 0 capture compare register value */
+ count_value = TIMER_CH0CV(timer_periph);
+ break;
+ case TIMER_CH_1:
+ /* read TIMER channel 1 capture compare register value */
+ count_value = TIMER_CH1CV(timer_periph);
+ break;
+ case TIMER_CH_2:
+ /* read TIMER channel 2 capture compare register value */
+ count_value = TIMER_CH2CV(timer_periph);
+ break;
+ case TIMER_CH_3:
+ /* read TIMER channel 3 capture compare register value */
+ 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] channel:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_CH_0: TIMER channel 0
+ \arg TIMER_CH_1: TIMER channel 1
+ \param[in] 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 channel, timer_ic_parameter_struct *icpwm)
+{
+ uint16_t icpolarity = 0x0U;
+ uint16_t icselection = 0x0U;
+
+ /* Set channel input polarity */
+ if (TIMER_IC_POLARITY_RISING == icpwm->icpolarity) {
+ icpolarity = TIMER_IC_POLARITY_FALLING;
+ } else {
+ icpolarity = TIMER_IC_POLARITY_RISING;
+ }
+ /* Set channel input mode selection */
+ if (TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection) {
+ icselection = TIMER_IC_SELECTION_INDIRECTTI;
+ } else {
+ icselection = TIMER_IC_SELECTION_DIRECTTI;
+ }
+
+ if (TIMER_CH_0 == 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)(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)(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)(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)(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)(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)(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)(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)(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)(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)(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)(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)(icpwm->icprescaler));
+ }
+}
+
+/*!
+ \brief configure TIMER hall sensor mode
+ \param[in] timer_periph: TIMERx(x=0..4,7)
+ \param[in] hallmode:
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t hallmode)
+{
+ if (TIMER_HALLINTERFACE_ENABLE == hallmode) {
+ TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S;
+ } else if (TIMER_HALLINTERFACE_DISABLE == hallmode) {
+ TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief select TIMER input trigger source
+ \param[in] timer_periph: TIMERx(x=0..4,7,8,11)
+ \param[in] intrigger:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1(TIMERx(x=0..4,7,8,11))
+ \arg TIMER_SMCFG_TRGSEL_ETIFP: filtered external trigger input(TIMERx(x=0..4,7))
+ \param[out] none
+ \retval none
+*/
+void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger)
+{
+ TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS);
+ TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger;
+}
+
+/*!
+ \brief select TIMER master mode output trigger source
+ \param[in] timer_periph: TIMERx(x=0..7)
+ \param[in] outrigger:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output(TIMERx(x=0..7))
+ \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0..7))
+ \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0..7))
+ \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channel 0 as trigger output TRGO(TIMERx(x=0..4,7))
+ \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0..4,7))
+ \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0..4,7))
+ \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0..4,7))
+ \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0..4,7))
+ \param[out] none
+ \retval none
+*/
+void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger)
+{
+ TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC);
+ TIMER_CTL1(timer_periph) |= (uint32_t)outrigger;
+}
+
+/*!
+ \brief select TIMER slave mode
+ \param[in] timer_periph: TIMERx(x=0..4,7,8,11)
+ \param[in] slavemode:
+ only one parameter can be selected which is shown as below:
+ \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 slavemode)
+{
+ TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+ TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode;
+}
+
+/*!
+ \brief configure TIMER master slave mode
+ \param[in] timer_periph: TIMERx(x=0..4,7,8,11)
+ \param[in] masterslave:
+ only one parameter can be selected which is shown as below:
+ \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, uint32_t masterslave)
+{
+ if (TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave) {
+ TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM;
+ } else if (TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave) {
+ TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief configure TIMER external trigger input
+ \param[in] timer_periph: TIMERx(x=0..4,7)
+ \param[in] extprescaler:
+ only one parameter can be selected which is shown as below:
+ \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] extpolarity:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_ETP_FALLING: active low or falling edge active
+ \arg TIMER_ETP_RISING: active high or rising edge active
+ \param[in] extfilter: a value between 0 and 15
+ \param[out] none
+ \retval none
+*/
+void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter)
+{
+ TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC));
+ TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity);
+ TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U);
+}
+
+/*!
+ \brief configure TIMER quadrature decoder mode
+ \param[in] timer_periph: TIMERx(x=0..4,7)
+ \param[in] decomode:
+ only one parameter can be selected which is shown as below:
+ \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] ic0polarity:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_IC_POLARITY_RISING: capture rising edge
+ \arg TIMER_IC_POLARITY_FALLING: capture falling edge
+ \param[in] ic1polarity:
+ only one parameter can be selected which is shown as below:
+ \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 decomode, uint16_t ic0polarity, uint16_t ic1polarity)
+{
+ /* configure the quadrature decoder mode */
+ TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+ TIMER_SMCFG(timer_periph) |= (uint32_t)decomode;
+ /* configure input capture selection */
+ 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));
+ /* configure channel input capture polarity */
+ 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)ic0polarity | ((uint32_t)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] intrigger:
+ only one parameter can be selected which is shown as below:
+ \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 intrigger)
+{
+ timer_input_trigger_source_select(timer_periph, 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] extrigger:
+ only one parameter can be selected which is shown as below:
+ \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] extpolarity:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_IC_POLARITY_RISING: active low or falling edge active
+ \arg TIMER_IC_POLARITY_FALLING: active high or rising edge active
+ \param[in] 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 extrigger, uint16_t extpolarity, uint32_t extfilter)
+{
+ if (TIMER_SMCFG_TRGSEL_CI1FE1 == 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)extpolarity << 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)(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)extpolarity;
+ /* 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)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, 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] extprescaler:
+ only one parameter can be selected which is shown as below:
+ \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] extpolarity:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_ETP_FALLING: active low or falling edge active
+ \arg TIMER_ETP_RISING: active high or rising edge active
+ \param[in] extfilter: a value between 0 and 15
+ \param[out] none
+ \retval none
+*/
+void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter)
+{
+ /* configure TIMER external trigger input */
+ timer_external_trigger_config(timer_periph, extprescaler, extpolarity, 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] extprescaler:
+ only one parameter can be selected which is shown as below:
+ \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] extpolarity:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_ETP_FALLING: active low or falling edge active
+ \arg TIMER_ETP_RISING: active high or rising edge active
+ \param[in] extfilter: a value between 0 and 15
+ \param[out] none
+ \retval none
+*/
+void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter)
+{
+ /* configure TIMER external trigger input */
+ timer_external_trigger_config(timer_periph, extprescaler, extpolarity, 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 TIMER write CHxVAL register selection
+ \param[in] timer_periph: TIMERx(x=0..4,7..13)
+ \param[in] ccsel:
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_CHVSEL_DISABLE: no effect
+ \arg TIMER_CHVSEL_ENABLE: when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored
+ \param[out] none
+ \retval none
+*/
+void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel)
+{
+ if (TIMER_CHVSEL_ENABLE == ccsel) {
+ TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL;
+ } else if (TIMER_CHVSEL_DISABLE == ccsel) {
+ TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief configure TIMER output value selection
+ \param[in] timer_periph: TIMERx(x=0,7)
+ \param[in] outsel:
+ only one parameter can be selected which is shown as below:
+ \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 outsel)
+{
+ if (TIMER_OUTSEL_ENABLE == outsel) {
+ TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL;
+ } else if (TIMER_OUTSEL_DISABLE == outsel) {
+ TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL;
+ } else {
+ /* illegal parameters */
+ }
+}
+
+/*!
+ \brief enable the TIMER interrupt
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] interrupt: specify which interrupt to enable
+ one or more parameters can be selected which are shown as below:
+ \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 interrupt)
+{
+ TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt;
+}
+
+/*!
+ \brief disable the TIMER interrupt
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] interrupt: specify which interrupt to disbale
+ one or more parameters can be selected which are shown as below:
+ \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 interrupt)
+{
+ TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt);
+}
+
+/*!
+ \brief get timer interrupt flag
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] interrupt: the timer interrupt bits
+ only one parameter can be selected which is shown as below:
+ \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0..13)
+ \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0..4,7..13)
+ \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0..4,7,8,11)
+ \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0..4,7)
+ \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0..4,7)
+ \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,7)
+ \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,7,8,11)
+ \arg TIMER_INT_FLAG_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 interrupt)
+{
+ uint32_t val;
+ val = (TIMER_DMAINTEN(timer_periph) & interrupt);
+ if ((RESET != (TIMER_INTF(timer_periph) & interrupt)) && (RESET != val)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear TIMER interrupt flag
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] interrupt: the timer interrupt bits
+ one or more parameters can be selected which are shown as below:
+ \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0..13)
+ \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0..4,7..13)
+ \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0..4,7,8,11)
+ \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0..4,7)
+ \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0..4,7)
+ \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,7)
+ \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,7,8,11)
+ \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0,7)
+ \param[out] none
+ \retval none
+*/
+void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt)
+{
+ TIMER_INTF(timer_periph) &= (~(uint32_t)interrupt);
+}
+
+/*!
+ \brief get TIMER flags
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] flag: the timer interrupt flags
+ only one parameter can be selected which is shown as below:
+ \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 commutation 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_CH0O: channel 0 overcapture flag, TIMERx(x=0..4,7..11)
+ \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0..4,7,8,11)
+ \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0..4,7)
+ \arg TIMER_FLAG_CH3O: 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 flag)
+{
+ if (RESET != (TIMER_INTF(timer_periph) & flag)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear TIMER flags
+ \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] flag: the timer interrupt flags
+ one or more parameters can be selected which are shown as below:
+ \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 commutation 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_CH0O: channel 0 overcapture flag, TIMERx(x=0..4,7..11)
+ \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0..4,7,8,11)
+ \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0..4,7)
+ \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0..4,7)
+ \param[out] none
+ \retval none
+*/
+void timer_flag_clear(uint32_t timer_periph, uint32_t flag)
+{
+ TIMER_INTF(timer_periph) &= (~(uint32_t)flag);
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_usart.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_usart.c
new file mode 100644
index 0000000000..a43c1a4b0a
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_usart.c
@@ -0,0 +1,931 @@
+/*!
+ \file gd32e10x_usart.c
+ \brief USART driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_usart.h"
+
+/* USART register bit offset */
+#define GP_GUAT_OFFSET ((uint32_t)8U) /* bit offset of GUAT in USART_GP */
+#define CTL3_SCRTNUM_OFFSET ((uint32_t)1U) /* bit offset of SCRTNUM in USART_CTL3 */
+#define RT_BL_OFFSET ((uint32_t)24U) /* bit offset of BL in USART_RT */
+
+/*!
+ \brief reset USART/UART
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[out] none
+ \retval none
+*/
+void usart_deinit(uint32_t usart_periph)
+{
+ switch (usart_periph) {
+ case USART0:
+ /* reset USART0 */
+ rcu_periph_reset_enable(RCU_USART0RST);
+ rcu_periph_reset_disable(RCU_USART0RST);
+ break;
+ case USART1:
+ /* reset USART1 */
+ rcu_periph_reset_enable(RCU_USART1RST);
+ rcu_periph_reset_disable(RCU_USART1RST);
+ break;
+ case USART2:
+ /* reset USART2 */
+ rcu_periph_reset_enable(RCU_USART2RST);
+ rcu_periph_reset_disable(RCU_USART2RST);
+ break;
+ case UART3:
+ /* reset UART3 */
+ rcu_periph_reset_enable(RCU_UART3RST);
+ rcu_periph_reset_disable(RCU_UART3RST);
+ break;
+ case UART4:
+ /* reset UART4 */
+ rcu_periph_reset_enable(RCU_UART4RST);
+ rcu_periph_reset_disable(RCU_UART4RST);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure USART baud rate value
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \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:
+ /* get USART0 clock */
+ uclk = rcu_clock_freq_get(CK_APB2);
+ break;
+ case USART1:
+ /* get USART1 clock */
+ uclk = rcu_clock_freq_get(CK_APB1);
+ break;
+ case USART2:
+ /* get USART2 clock */
+ uclk = rcu_clock_freq_get(CK_APB1);
+ break;
+ case UART3:
+ /* get UART3 clock */
+ uclk = rcu_clock_freq_get(CK_APB1);
+ break;
+ case UART4:
+ /* get UART4 clock */
+ uclk = rcu_clock_freq_get(CK_APB1);
+ break;
+ default:
+ break;
+ }
+ /* 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
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[in] paritycfg: configure USART parity
+ only one parameter can be selected which is shown as below:
+ \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)/UARTx(x=3,4)
+ \param[in] wlen: USART word length configure
+ only one parameter can be selected which is shown as below:
+ \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)/UARTx(x=3,4)
+ \param[in] stblen: USART stop bit configure
+ only one parameter can be selected which is shown as below:
+ \arg USART_STB_1BIT: 1 bit
+ \arg USART_STB_0_5BIT: 0.5 bit, not available for UARTx(x=3,4)
+ \arg USART_STB_2BIT: 2 bits
+ \arg USART_STB_1_5BIT: 1.5 bits, not available for UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \param[in] txconfig: enable or disable USART transmitter
+ only one parameter can be selected which is shown as below:
+ \arg USART_TRANSMIT_ENABLE: enable USART transmission
+ \arg USART_TRANSMIT_DISABLE: disable 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)/UARTx(x=3,4)
+ \param[in] rxconfig: enable or disable USART receiver
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] msbf: LSB/MSB
+ only one parameter can be selected which is shown as below:
+ \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)
+{
+ uint32_t ctl = 0U;
+
+ ctl = USART_CTL3(usart_periph);
+ ctl &= ~(USART_CTL3_MSBF);
+ ctl |= msbf;
+ /* configure data transmitted/received mode */
+ USART_CTL3(usart_periph) = ctl;
+}
+
+/*!
+ \brief configure USART inversion
+ \param[in] usart_periph: USARTx(x=0,1,2)
+ \param[in] invertpara: refer to enum usart_invert_enum
+ only one parameter can be selected which is shown as below:
+ \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:
+ /* data bit level inversion */
+ USART_CTL3(usart_periph) |= USART_CTL3_DINV;
+ break;
+ case USART_TXPIN_ENABLE:
+ /* TX pin level inversion */
+ USART_CTL3(usart_periph) |= USART_CTL3_TINV;
+ break;
+ case USART_RXPIN_ENABLE:
+ /* RX pin level inversion */
+ USART_CTL3(usart_periph) |= USART_CTL3_RINV;
+ break;
+ case USART_DINV_DISABLE:
+ /* data bit level not inversion */
+ USART_CTL3(usart_periph) &= ~(USART_CTL3_DINV);
+ break;
+ case USART_TXPIN_DISABLE:
+ /* TX pin level not inversion */
+ USART_CTL3(usart_periph) &= ~(USART_CTL3_TINV);
+ break;
+ case USART_RXPIN_DISABLE:
+ /* RX pin level not inversion */
+ USART_CTL3(usart_periph) &= ~(USART_CTL3_RINV);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief enable receiver timeout of USART
+ \param[in] usart_periph: USARTx(x=0,1,2)
+ \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)
+ \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)
+ \param[in] rtimeout: 0-0xFFFFFF
+ \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)/UARTx(x=3,4)
+ \param[in] data: data to be transmitted
+ \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)/UARTx(x=3,4)
+ \param[out] none
+ \retval data of received
+*/
+uint16_t usart_data_receive(uint32_t usart_periph)
+{
+ return (uint16_t)(GET_BITS(USART_DATA(usart_periph), 0U, 8U));
+}
+
+/*!
+ \brief configure the address of the USART in wake up by address match mode
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \param[in] wmethod: two methods be used to enter or exit the mute mode
+ only one parameter can be selected which is shown as below:
+ \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 wmethod)
+{
+ USART_CTL0(usart_periph) &= ~(USART_CTL0_WM);
+ USART_CTL0(usart_periph) |= wmethod;
+}
+
+/*!
+ \brief enable LIN mode
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \param[in] lblen: lin break frame length
+ only one parameter can be selected which is shown as below:
+ \arg USART_LBLEN_10B: 10 bits
+ \arg USART_LBLEN_11B: 11 bits
+ \param[out] none
+ \retval none
+*/
+void usart_lin_break_detection_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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)
+ \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)
+ \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)
+ \param[in] clen: CK length
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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);
+ ctl &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL);
+ /* 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)
+ \param[in] guat: guard time value, 0-0xFF
+ \param[out] none
+ \retval none
+*/
+void usart_guard_time_config(uint32_t usart_periph, uint32_t guat)
+{
+ USART_GP(usart_periph) &= ~(USART_GP_GUAT);
+ USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << GP_GUAT_OFFSET));
+}
+
+/*!
+ \brief enable smartcard mode
+ \param[in] usart_periph: USARTx(x=0,1,2)
+ \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)
+ \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)
+ \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)
+ \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)
+ \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) << CTL3_SCRTNUM_OFFSET));
+}
+
+/*!
+ \brief configure block length in Smartcard T=1 reception
+ \param[in] usart_periph: USARTx(x=0,1,2)
+ \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) << RT_BL_OFFSET));
+}
+
+/*!
+ \brief enable IrDA mode
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \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)/UARTx(x=3,4)
+ \param[in] psc: 0x00-0xFF
+ \param[out] none
+ \retval none
+*/
+void usart_prescaler_config(uint32_t usart_periph, uint8_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)/UARTx(x=3,4)
+ \param[in] irlp: IrDA low-power or normal
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] rtsconfig: enable or disable RTS
+ only one parameter can be selected which is shown as below:
+ \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)
+ \param[in] ctsconfig: enable or disable CTS
+ only one parameter can be selected which is shown as below:
+ \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 USART DMA reception
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3)
+ \param[in] dmacmd: enable or disable DMA for reception
+ only one parameter can be selected which is shown as below:
+ \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)/UARTx(x=3)
+ \param[in] dmacmd: enable or disable DMA for transmission
+ only one parameter can be selected which is shown as below:
+ \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 configure hardware flow control coherence mode
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3)
+ \param[in] hcm:
+ \arg USART_RTS_NONE_COHERENCE: nRTS signal equals to the rxne status register
+ \arg USART_RTS_COHERENCE: 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 get flag in STAT0/STAT1 register
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[in] flag: USART flags, refer to usart_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg USART_FLAG_CTS: CTS change flag
+ \arg USART_FLAG_LBD: 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_IDLE: 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_EB: end of block flag
+ \arg USART_FLAG_RT: 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 register
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[in] flag: USART flags, refer to usart_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg USART_FLAG_CTS: CTS change flag
+ \arg USART_FLAG_LBD: LIN break detected flag
+ \arg USART_FLAG_TC: transmission complete
+ \arg USART_FLAG_RBNE: read data buffer not empty
+ \arg USART_FLAG_EB: end of block flag
+ \arg USART_FLAG_RT: 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)/UARTx(x=3,4)
+ \param[in] interrupt: USART interrupts, refer to usart_interrupt_enum
+ only one parameter can be selected which is shown as below:
+ \arg USART_INT_PERR: parity error interrupt
+ \arg USART_INT_TBE: transmitter buffer empty interrupt
+ \arg USART_INT_TC: transmission complete interrupt
+ \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
+ \arg USART_INT_IDLE: IDLE line detected interrupt
+ \arg USART_INT_LBD: LIN break detected interrupt
+ \arg USART_INT_ERR: error interrupt
+ \arg USART_INT_CTS: CTS interrupt
+ \arg USART_INT_RT: interrupt enable bit of receive timeout event
+ \arg USART_INT_EB: interrupt enable bit of end of block event
+ \param[out] none
+ \retval none
+*/
+void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt)
+{
+ USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt));
+}
+
+/*!
+ \brief disable USART interrupt
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[in] interrupt: USART interrupts, refer to usart_interrupt_enum
+ only one parameter can be selected which is shown as below:
+ \arg USART_INT_PERR: parity error interrupt
+ \arg USART_INT_TBE: transmitter buffer empty interrupt
+ \arg USART_INT_TC: transmission complete interrupt
+ \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
+ \arg USART_INT_IDLE: IDLE line detected interrupt
+ \arg USART_INT_LBD: LIN break detected interrupt
+ \arg USART_INT_ERR: error interrupt
+ \arg USART_INT_CTS: CTS interrupt
+ \arg USART_INT_RT: interrupt enable bit of receive timeout event
+ \arg USART_INT_EB: interrupt enable bit of end of block event
+ \param[out] none
+ \retval none
+*/
+void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt)
+{
+ USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt));
+}
+
+/*!
+ \brief get USART interrupt and flag status
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[in] int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg USART_INT_FLAG_PERR: parity error interrupt and flag
+ \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag
+ \arg USART_INT_FLAG_TC: transmission complete interrupt and flag
+ \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag
+ \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag
+ \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag
+ \arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag
+ \arg USART_INT_FLAG_CTS: CTS interrupt and flag
+ \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error
+ \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag
+ \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag
+ \arg USART_INT_FLAG_EB: interrupt enable bit of end of block event and flag
+ \arg USART_INT_FLAG_RT: interrupt enable bit of receive timeout event and flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
+{
+ uint32_t intenable = 0U, flagstatus = 0U;
+ /* get the interrupt enable bit status */
+ intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
+ /* get the corresponding flag bit status */
+ flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));
+
+ if ((0U != flagstatus) && (0U != intenable)) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear USART interrupt flag in STAT0/STAT1 register
+ \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
+ \param[in] int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum
+ only one parameter can be selected which is shown as below:
+ \arg USART_INT_FLAG_CTS: CTS change flag
+ \arg USART_INT_FLAG_LBD: LIN break detected flag
+ \arg USART_INT_FLAG_TC: transmission complete
+ \arg USART_INT_FLAG_RBNE: read data buffer not empty
+ \arg USART_INT_FLAG_EB: end of block flag
+ \arg USART_INT_FLAG_RT: receiver timeout flag
+ \param[out] none
+ \retval none
+*/
+void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
+{
+ USART_REG_VAL2(usart_periph, int_flag) &= ~BIT(USART_BIT_POS2(int_flag));
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_wwdgt.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_wwdgt.c
new file mode 100644
index 0000000000..737f5489db
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/GD32E10x_standard_peripheral/Source/gd32e10x_wwdgt.c
@@ -0,0 +1,149 @@
+/*!
+ \file gd32e10x_wwdgt.c
+ \brief WWDGT driver
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+*/
+
+#include "gd32e10x_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 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 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 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
+ only one parameter can be selected which is shown as below:
+ \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 (RESET != (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);
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/PeripheralPins.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/PeripheralPins.h
new file mode 100644
index 0000000000..14fe0e8621
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/PeripheralPins.h
@@ -0,0 +1,74 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBED_PERIPHERALPINS_H
+#define MBED_PERIPHERALPINS_H
+
+#include "pinmap.h"
+#include "PeripheralNames.h"
+
+extern const int GD_GPIO_REMAP[];
+extern const int GD_GPIO_MODE[];
+extern const int GD_GPIO_SPEED[];
+
+/* ADC */
+#ifdef DEVICE_ANALOGIN
+extern const PinMap PinMap_ADC[];
+#endif
+
+/* DAC */
+#ifdef DEVICE_ANALOGOUT
+extern const PinMap PinMap_DAC[];
+#endif
+
+/* I2C */
+#if DEVICE_I2C
+extern const PinMap PinMap_I2C_SDA[];
+extern const PinMap PinMap_I2C_SCL[];
+#endif
+
+/* PWM */
+#if DEVICE_PWMOUT
+extern const PinMap PinMap_PWM[];
+#endif
+
+/* SERIAL */
+#ifdef DEVICE_SERIAL
+extern const PinMap PinMap_UART_TX[];
+extern const PinMap PinMap_UART_RX[];
+#ifdef DEVICE_SERIAL_FC
+extern const PinMap PinMap_UART_RTS[];
+extern const PinMap PinMap_UART_CTS[];
+#endif
+#endif
+
+/* SPI */
+#ifdef DEVICE_SPI
+extern const PinMap PinMap_SPI_MOSI[];
+extern const PinMap PinMap_SPI_MISO[];
+extern const PinMap PinMap_SPI_SCLK[];
+extern const PinMap PinMap_SPI_SSEL[];
+#endif
+
+/* CAN */
+#ifdef DEVICE_CAN
+extern const PinMap PinMap_CAN_RD[];
+extern const PinMap PinMap_CAN_TD[];
+#endif
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/PortNames.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/PortNames.h
new file mode 100644
index 0000000000..773bed473d
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/PortNames.h
@@ -0,0 +1,36 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_PORTNAMES_H
+#define MBED_PORTNAMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ PORTA = 0,
+ PORTB = 1,
+ PORTC = 2,
+ PORTD = 3,
+ PORTE = 4,
+} PortName;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PeripheralNames.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PeripheralNames.h
new file mode 100644
index 0000000000..6788b0158e
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PeripheralNames.h
@@ -0,0 +1,84 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBED_PERIPHERALNAMES_H
+#define MBED_PERIPHERALNAMES_H
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ADC_0 = (int)ADC0,
+ ADC_1 = (int)ADC1
+} ADCName;
+
+typedef enum {
+ DAC_0 = (int)DAC,
+} DACName;
+
+typedef enum {
+ UART_0 = (int)USART0,
+ UART_1 = (int)USART1,
+ UART_2 = (int)USART2,
+ UART_3 = (int)UART3,
+ UART_4 = (int)UART4
+} UARTName;
+
+#define STDIO_UART_TX PORTA_2
+#define STDIO_UART_RX PORTA_3
+#define STDIO_UART UART_1
+
+typedef enum {
+ SPI_0 = (int)SPI0,
+ SPI_1 = (int)SPI1,
+ SPI_2 = (int)SPI2
+} SPIName;
+
+typedef enum {
+ I2C_0 = (int)I2C0,
+ I2C_1 = (int)I2C1
+} I2CName;
+
+typedef enum {
+ PWM_0 = (int)TIMER0,
+ PWM_1 = (int)TIMER1,
+ PWM_2 = (int)TIMER2,
+ PWM_3 = (int)TIMER3,
+ PWM_4 = (int)TIMER4,
+ PWM_5 = (int)TIMER7,
+ PWM_6 = (int)TIMER8,
+ PWM_7 = (int)TIMER9,
+ PWM_8 = (int)TIMER10,
+ PWM_9 = (int)TIMER11,
+ PWM_10 = (int)TIMER12,
+ PWM_11 = (int)TIMER13
+} PWMName;
+
+typedef enum {
+ CAN_0 = (int)CAN0,
+ CAN_1 = (int)CAN1
+} CANName;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PeripheralPins.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PeripheralPins.c
new file mode 100644
index 0000000000..c4d98941c9
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PeripheralPins.c
@@ -0,0 +1,316 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PeripheralPins.h"
+
+
+/* void pin_function(PinName pin, int function);
+ configure the speed, mode,and remap function of pins
+ the parameter function contains the configuration information,show as below
+ bit 0:2 gpio mode
+ bit 3:8 remap
+ bit 9:10 gpio speed
+ bit 11:15 adc /timer channel
+*/
+const int GD_GPIO_REMAP[] = {
+ 0x00000000,
+ GPIO_SPI0_REMAP, /* 1 */
+ GPIO_I2C0_REMAP, /* 2 */
+ GPIO_USART0_REMAP, /* 3 */
+ GPIO_USART1_REMAP, /* 4 */
+ GPIO_USART2_PARTIAL_REMAP, /* 5 */
+ GPIO_USART2_FULL_REMAP, /* 6 */
+ GPIO_TIMER0_PARTIAL_REMAP, /* 7 */
+ GPIO_TIMER0_FULL_REMAP, /* 8 */
+ GPIO_TIMER1_PARTIAL_REMAP0, /* 9 */
+ GPIO_TIMER1_PARTIAL_REMAP1, /* 10 */
+ GPIO_TIMER1_FULL_REMAP, /* 11 */
+ GPIO_TIMER2_PARTIAL_REMAP, /* 12 */
+ GPIO_TIMER2_FULL_REMAP, /* 13 */
+ GPIO_TIMER3_REMAP, /* 14 */
+ GPIO_PD01_REMAP, /* 15 */
+ GPIO_TIMER4CH3_IREMAP, /* 16 */
+ GPIO_ADC0_ETRGINS_REMAP, /* 17 */
+ GPIO_ADC0_ETRGREG_REMAP, /* 18 */
+ GPIO_ADC1_ETRGINS_REMAP, /* 19 */
+ GPIO_ADC1_ETRGREG_REMAP, /* 20 */
+ GPIO_SWJ_NONJTRST_REMAP, /* 21 */
+ GPIO_SWJ_SWDPENABLE_REMAP, /* 22 */
+ GPIO_SWJ_DISABLE_REMAP, /* 23 */
+ GPIO_CAN0_PARTIAL_REMAP, /* 24 */
+ GPIO_CAN0_FULL_REMAP, /* 25 */
+ GPIO_CAN1_REMAP, /* 26 */
+ GPIO_SPI2_REMAP, /* 27 */
+ GPIO_TIMER1ITR0_REMAP, /* 28 */
+ GPIO_TIMER8_REMAP, /* 29 */
+ GPIO_EXMC_NADV_REMAP, /* 30 */
+ GPIO_CTC_REMAP0, /* 31 */
+};
+
+/* GPIO MODE */
+const int GD_GPIO_MODE[] = {
+ GPIO_MODE_AIN, /* 0 */
+ GPIO_MODE_IN_FLOATING, /* 1 */
+ GPIO_MODE_IPD, /* 2 */
+ GPIO_MODE_IPU, /* 3 */
+ GPIO_MODE_OUT_OD, /* 4 */
+ GPIO_MODE_OUT_PP, /* 5 */
+ GPIO_MODE_AF_OD, /* 6 */
+ GPIO_MODE_AF_PP, /* 7 */
+};
+
+/* GPIO SPEED */
+const int GD_GPIO_SPEED[] = {
+ GPIO_OSPEED_50MHZ, /* 0 */
+ GPIO_OSPEED_10MHZ, /* 1 */
+ GPIO_OSPEED_2MHZ, /* 2 */
+};
+
+/* ADC PinMap */
+const PinMap PinMap_ADC[] = {
+ {PORTA_0, ADC_0, 0 | (0 << 11)}, /* ADC0_IN0 */
+ {PORTA_1, ADC_0, 0 | (1 << 11)}, /* ADC0_IN1 */
+ {PORTA_2, ADC_0, 0 | (2 << 11)}, /* ADC0_IN2 */
+ {PORTA_3, ADC_0, 0 | (3 << 11)}, /* ADC0_IN3 */
+ {PORTA_4, ADC_0, 0 | (4 << 11)}, /* ADC0_IN4 */
+ {PORTA_5, ADC_0, 0 | (5 << 11)}, /* ADC0_IN5 */
+ {PORTA_6, ADC_0, 0 | (6 << 11)}, /* ADC0_IN6 */
+ {PORTA_7, ADC_0, 0 | (7 << 11)}, /* ADC0_IN7 */
+ {PORTB_0, ADC_0, 0 | (8 << 11)}, /* ADC0_IN8 */
+ {PORTB_1, ADC_0, 0 | (9 << 11)}, /* ADC0_IN9 */
+ {PORTC_0, ADC_0, 0 | (10 << 11)}, /* ADC0_IN10 */
+ {PORTC_1, ADC_0, 0 | (11 << 11)}, /* ADC0_IN11 */
+ {PORTC_2, ADC_0, 0 | (12 << 11)}, /* ADC0_IN12 */
+ {PORTC_3, ADC_0, 0 | (13 << 11)}, /* ADC0_IN13 */
+ {PORTC_4, ADC_0, 0 | (14 << 11)}, /* ADC0_IN14 */
+ {PORTC_5, ADC_0, 0 | (15 << 11)}, /* ADC0_IN15 */
+ {ADC_TEMP, ADC_0, 0 | (16 << 11)}, /* ADC0_IN16 */
+ {ADC_VREF, ADC_0, 0 | (17 << 11)}, /* ADC0_IN17 */
+
+ {PORTA_0_MUL0, ADC_1, 0 | (0 << 11)}, /* ADC1_IN0 */
+ {PORTA_1_MUL0, ADC_1, 0 | (1 << 11)}, /* ADC1_IN1 */
+ {PORTA_2_MUL0, ADC_1, 0 | (2 << 11)}, /* ADC1_IN2 */
+ {PORTA_3_MUL0, ADC_1, 0 | (3 << 11)}, /* ADC1_IN3 */
+ {PORTA_4_MUL0, ADC_1, 0 | (4 << 11)}, /* ADC1_IN4 */
+ {PORTA_5_MUL0, ADC_1, 0 | (5 << 11)}, /* ADC1_IN5 */
+ {PORTA_6_MUL0, ADC_1, 0 | (6 << 11)}, /* ADC1_IN6 */
+ {PORTA_7_MUL0, ADC_1, 0 | (7 << 11)}, /* ADC1_IN7 */
+ {PORTB_0_MUL0, ADC_1, 0 | (8 << 11)}, /* ADC1_IN8 */
+ {PORTB_1_MUL0, ADC_1, 0 | (9 << 11)}, /* ADC1_IN9 */
+ {PORTC_0_MUL0, ADC_1, 0 | (10 << 11)}, /* ADC1_IN10 */
+ {PORTC_1_MUL0, ADC_1, 0 | (11 << 11)}, /* ADC1_IN11 */
+ {PORTC_2_MUL0, ADC_1, 0 | (12 << 11)}, /* ADC1_IN12 */
+ {PORTC_3_MUL0, ADC_1, 0 | (13 << 11)}, /* ADC1_IN13 */
+ {PORTC_4_MUL0, ADC_1, 0 | (14 << 11)}, /* ADC1_IN14 */
+ {PORTC_5_MUL0, ADC_1, 0 | (15 << 11)}, /* ADC1_IN15 */
+ {NC, NC, 0}
+};
+
+/* DAC PinMap */
+const PinMap PinMap_DAC[] = {
+ {PORTA_4, DAC_0, 0 | (0 << 11)}, /* DAC_OUT0 */
+ {PORTA_5, DAC_0, 0 | (1 << 11)}, /* DAC_OUT1 */
+ {NC, NC, 0}
+};
+
+
+/* I2C PinMap */
+const PinMap PinMap_I2C_SDA[] = {
+ {PORTB_7, I2C_0, 6},
+ {PORTB_9, I2C_0, 6 | (2 << 3)}, /* GPIO_I2C0_REMAP */
+ {PORTB_11, I2C_1, 6},
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_I2C_SCL[] = {
+ {PORTB_6, I2C_0, 6},
+ {PORTB_8, I2C_0, 6 | (2 << 3)}, /* GPIO_I2C0_REMAP */
+ {PORTB_10, I2C_1, 6},
+ {NC, NC, 0}
+};
+
+/* PWM PinMap */
+const PinMap PinMap_PWM[] = {
+ {PORTA_8, PWM_0, 7 | (0 << 11)}, /* TIMER0_CH0 - Default */
+ {PORTA_9, PWM_0, 7 | (1 << 11)}, /* TIMER0_CH1 - Default */
+ {PORTA_10, PWM_0, 7 | (2 << 11)}, /* TIMER0_CH2 - Default */
+ {PORTA_11, PWM_0, 7 | (3 << 11)}, /* TIMER0_CH3 - Default */
+ {PORTE_9, PWM_0, 7 | (8 << 3) | (0 << 11)}, /* TIMER0_CH0 - GPIO_TIMER0_FULL_REMAP */
+ {PORTE_11, PWM_0, 7 | (8 << 3) | (1 << 11)}, /* TIMER0_CH1 - GPIO_TIMER0_FULL_REMAP */
+ {PORTE_13, PWM_0, 7 | (8 << 3) | (2 << 11)}, /* TIMER0_CH2 - GPIO_TIMER0_FULL_REMAP */
+ {PORTE_14, PWM_0, 7 | (8 << 3) | (3 << 11)}, /* TIMER0_CH3 - GPIO_TIMER0_FULL_REMAP */
+
+ {PORTA_0, PWM_1, 7 | (0 << 11)}, /* TIMER1_CH0_ETI - Default */
+ {PORTA_1, PWM_1, 7 | (1 << 11)}, /* TIMER1_CH1_ETI - Default */
+ {PORTA_2, PWM_1, 7 | (2 << 11)}, /* TIMER1_CH2_ETI - Default */
+ {PORTA_3, PWM_1, 7 | (3 << 11)}, /* TIMER1_CH3_ETI - Default */
+ {PORTA_15, PWM_1, 7 | (9 << 3) | (0 << 11)}, /* TIMER1_CH0_ETI- GPIO_TIMER1_PARTIAL_REMAP0 */
+ {PORTB_3, PWM_1, 7 | (9 << 3) | (1 << 11)}, /* TIMER1_CH1 - GPIO_TIMER1_PARTIAL_REMAP0 */
+ {PORTB_10, PWM_1, 7 | (10 << 3) | (2 << 11)}, /* TIMER1_CH2 - GPIO_TIMER1_PARTIAL_REMAP1 */
+ {PORTB_11, PWM_1, 7 | (10 << 3) | (3 << 11)}, /* TIMER1_CH3 - GPIO_TIMER1_PARTIAL_REMAP1 */
+ {PORTA_15, PWM_1, 7 | (11 << 3) | (0 << 11)}, /* TIMER1_CH0_ETI - GPIO_TIMER1_FULL_REMAP */
+ {PORTB_3, PWM_1, 7 | (11 << 3) | (1 << 11)}, /* TIMER1_CH1 - GPIO_TIMER1_FULL_REMAP */
+ {PORTB_10, PWM_1, 7 | (11 << 3) | (2 << 11)}, /* TIMER1_CH2 - GPIO_TIMER1_FULL_REMAP */
+ {PORTB_11, PWM_1, 7 | (11 << 3) | (3 << 11)}, /* TIMER1_CH3 - GPIO_TIMER1_FULL_REMAP */
+
+ {PORTA_6, PWM_2, 7 | (0 << 11)}, /* TIMER2_CH0 - Default */
+ {PORTA_7, PWM_2, 7 | (1 << 11)}, /* TIMER2_CH1 - Default */
+ {PORTB_0, PWM_2, 7 | (2 << 11)}, /* TIMER2_CH2 - Default */
+ {PORTB_1, PWM_2, 7 | (3 << 11)}, /* TIMER2_CH3 - Default */
+ {PORTB_4, PWM_2, 7 | (12 << 3) | (0 << 11)}, /* TIMER2_CH0 - GPIO_TIMER2_PARTIAL_REMAP */
+ {PORTB_5, PWM_2, 7 | (12 << 3) | (1 << 11)}, /* TIMER2_CH1 - GPIO_TIMER2_PARTIAL_REMAP */
+ {PORTC_6, PWM_2, 7 | (13 << 3) | (0 << 11)}, /* TIMER2_CH0 - GPIO_TIMER2_FULL_REMAP */
+ {PORTC_7, PWM_2, 7 | (13 << 3) | (1 << 11)}, /* TIMER2_CH1 - GPIO_TIMER2_FULL_REMAP */
+ {PORTC_8, PWM_2, 7 | (13 << 3) | (2 << 11)}, /* TIMER2_CH2 - GPIO_TIMER2_FULL_REMAP */
+ {PORTC_9, PWM_2, 7 | (13 << 3) | (3 << 11)}, /* TIMER2_CH3 - GPIO_TIMER2_FULL_REMAP */
+
+ {PORTB_6, PWM_3, 7 | (0 << 11)}, /* TIMER3_CH0 - Default */
+ {PORTB_7, PWM_3, 7 | (1 << 11)}, /* TIMER3_CH1 - Default */
+ {PORTB_8, PWM_3, 7 | (2 << 11)}, /* TIMER3_CH2 - Default */
+ {PORTB_9, PWM_3, 7 | (3 << 11)}, /* TIMER3_CH3 - Default */
+ {PORTD_12, PWM_3, 7 | (14 << 3) | (0 << 11)}, /* TIMER3_CH0 - GPIO_TIMER3_REMAP */
+ {PORTD_13, PWM_3, 7 | (14 << 3) | (1 << 11)}, /* TIMER3_CH1 - GPIO_TIMER3_REMAP */
+ {PORTD_14, PWM_3, 7 | (14 << 3) | (2 << 11)}, /* TIMER3_CH2 - GPIO_TIMER3_REMAP */
+ {PORTD_15, PWM_3, 7 | (14 << 3) | (3 << 11)}, /* TIMER3_CH3 - GPIO_TIMER3_REMAP */
+
+ {PORTA_0_MUL0, PWM_4, 7 | (0 << 11)}, /* TIMER4_CH0 - Default */
+ {PORTA_1_MUL0, PWM_4, 7 | (1 << 11)}, /* TIMER4_CH1 - Default */
+ {PORTA_2_MUL0, PWM_4, 7 | (2 << 11)}, /* TIMER4_CH2 - Default */
+ {PORTA_3_MUL0, PWM_4, 7 | (3 << 11)}, /* TIMER4_CH3 - Default */
+
+ {PORTC_6_MUL0, PWM_5, 7 | (0 << 11)}, /* TIMER7_CH0 - Default */
+ {PORTC_7_MUL0, PWM_5, 7 | (1 << 11)}, /* TIMER7_CH1 - Default */
+ {PORTC_8_MUL0, PWM_5, 7 | (2 << 11)}, /* TIMER7_CH2 - Default */
+ {PORTC_9_MUL0, PWM_5, 7 | (3 << 11)}, /* TIMER7_CH3 - Default */
+
+ {PORTA_2_MUL1, PWM_6, 7 | (0 << 11)}, /* TIMER8_CH0 - Default */
+ {PORTA_3_MUL1, PWM_6, 7 | (1 << 11)}, /* TIMER8_CH1 - Default */
+ {PORTE_5, PWM_6, 7 | (29 << 3) | (0 << 11)}, /* TIMER8_CH0 - GPIO_TIMER8_REMAP */
+ {PORTE_6, PWM_6, 7 | (29 << 3) | (1 << 11)}, /* TIMER8_CH1 - GPIO_TIMER8_REMAP */
+
+ {PORTB_8_MUL0, PWM_7, 7 | (0 << 11)}, /* TIMER9_CH0 - Default */
+
+ {PORTB_9_MUL0, PWM_8, 7 | (0 << 11)}, /* TIMER10_CH0 - Default */
+
+ {PORTB_14, PWM_9, 7 | (0 << 11)}, /* TIMER11_CH0 - Default */
+ {PORTB_15, PWM_9, 7 | (1 << 11)}, /* TIMER11_CH1 - Default */
+
+ {PORTA_6_MUL0, PWM_10, 7 | (0 << 11)}, /* TIMER12_CH0 - Default */
+
+ {PORTA_7_MUL0, PWM_11, 7 | (0 << 11)}, /* TIMER13_CH0 - Default */
+
+ {NC, NC, 0}
+};
+
+/* USART PinMap */
+const PinMap PinMap_UART_TX[] = {
+ {PORTA_9, UART_0, 7},
+ {PORTB_6, UART_0, 7 | (3 << 3)}, /* GPIO_USART0_TX_REMAP */
+ {PORTA_2, UART_1, 7},
+ {PORTD_5, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_TX_REMAP */
+ {PORTB_10, UART_2, 7},
+ {PORTC_10, UART_2, 7 | (5 << 3)}, /* GPIO_USART2_TX_PARTIAL_REMAP */
+ {PORTD_8, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_TX_FULL_REMAP */
+ {PORTC_10_MUL0, UART_3, 7},
+ {PORTC_12, UART_4, 7},
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_UART_RX[] = {
+ {PORTA_10, UART_0, 1},
+ {PORTB_7, UART_0, 1 | (3 << 3)}, /* GPIO_USART0_RX_REMAP */
+ {PORTA_3, UART_1, 1},
+ {PORTD_6, UART_1, 1 | (4 << 3)}, /* GPIO_USART1_RX_REMAP */
+ {PORTB_11, UART_2, 1},
+ {PORTC_11, UART_2, 1 | (5 << 3)}, /* GPIO_USART2_RX_PARTIAL_REMAP */
+ {PORTD_9, UART_2, 1 | (6 << 3)}, /* GPIO_USART2_RX_FULL_REMAP */
+ {PORTC_11_MUL0, UART_3, 1},
+ {PORTD_2, UART_4, 1},
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_UART_RTS[] = {
+ {PORTA_12, UART_0, 7},
+ {PORTA_1, UART_1, 7},
+ {PORTD_4, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_RTS_REMAP */
+ {PORTB_14, UART_2, 7},
+ {PORTD_12, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_RTS_FULL_REMAP */
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_UART_CTS[] = {
+ {PORTA_11, UART_0, 7},
+ {PORTA_0, UART_1, 7},
+ {PORTD_3, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_CTS_REMAP */
+ {PORTB_13, UART_2, 7},
+ {PORTD_11, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_CTS_FULL_REMAP */
+ {NC, NC, 0}
+};
+
+/* SPI PinMap */
+const PinMap PinMap_SPI_MOSI[] = {
+ {PORTA_7, SPI_0, 7},
+ {PORTB_5, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
+ {PORTB_15, SPI_1, 7},
+ {PORTC_12, SPI_2, 7 | (27 << 3)}, /* GPIO_SPI2_REMAP */
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_SPI_MISO[] = {
+ {PORTA_6, SPI_0, 7},
+ {PORTB_4, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
+ {PORTB_14, SPI_1, 7},
+ {PORTC_11, SPI_2, 7 | (27 << 3)}, /* GPIO_SPI2_REMAP */
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_SPI_SCLK[] = {
+ {PORTA_5, SPI_0, 7},
+ {PORTB_3, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
+ {PORTB_13, SPI_1, 7},
+ {PORTC_10, SPI_2, 7 | (27 << 3)}, /* GPIO_SPI2_REMAP */
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_SPI_SSEL[] = {
+ {PORTA_4, SPI_0, 7},
+ {PORTA_15, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
+ {PORTB_12, SPI_1, 7},
+ {PORTA_4_MUL0, SPI_2, 7 | (27 << 3)}, /* GPIO_SPI2_REMAP */
+ {NC, NC, 0}
+};
+
+/* CAN PinMap */
+const PinMap PinMap_CAN_RD[] = {
+ {PORTA_11, CAN_0, 3},
+ {PORTB_8, CAN_0, 3 | (24 << 3)}, /* GPIO_CAN0_PARTIAL_REMAP */
+ {PORTD_0, CAN_0, 3 | (25 << 3)}, /* GPIO_CAN0_FULL_REMAP */
+ {PORTB_12, CAN_1, 3},
+ {PORTB_5, CAN_1, 3 | (26 << 3)}, /* GPIO_CAN1_REMAP */
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_CAN_TD[] = {
+ {PORTA_12, CAN_0, 7},
+ {PORTB_9, CAN_0, 7 | (24 << 3)}, /* GPIO_CAN0_PARTIAL_REMAP */
+ {PORTD_1, CAN_0, 7 | (25 << 3)}, /* GPIO_CAN0_FULL_REMAP */
+ {PORTB_13, CAN_1, 7},
+ {PORTB_6, CAN_1, 7 | (26 << 3)}, /* GPIO_CAN1_REMAP */
+ {NC, NC, 0}
+};
+
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PinNames.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PinNames.h
new file mode 100644
index 0000000000..2d3da010f0
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/TARGET_GD32E103VB/PinNames.h
@@ -0,0 +1,245 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_PINNAMES_H
+#define MBED_PINNAMES_H
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Multiplex GPIO flag*/
+typedef enum {
+ MUL0 = 0x100,
+ MUL1 = 0x200,
+ MUL2 = 0x300,
+ MUL3 = 0x400
+} MULx;
+
+typedef enum {
+ PORTA_0 = 0x00,
+ PORTA_0_MUL0 = PORTA_0 | MUL0,
+ PORTA_1 = 0x01,
+ PORTA_1_MUL0 = PORTA_1 | MUL0,
+ PORTA_2 = 0x02,
+ PORTA_2_MUL0 = PORTA_2 | MUL0,
+ PORTA_2_MUL1 = PORTA_2 | MUL1,
+ PORTA_3 = 0x03,
+ PORTA_3_MUL0 = PORTA_3 | MUL0,
+ PORTA_3_MUL1 = PORTA_3 | MUL1,
+ PORTA_4 = 0x04,
+ PORTA_4_MUL0 = PORTA_4 | MUL0,
+ PORTA_4_MUL1 = PORTA_4 | MUL1,
+ PORTA_5 = 0x05,
+ PORTA_5_MUL0 = PORTA_5 | MUL0,
+ PORTA_6 = 0x06,
+ PORTA_6_MUL0 = PORTA_6 | MUL0,
+ PORTA_7 = 0x07,
+ PORTA_7_MUL0 = PORTA_7 | MUL0,
+ PORTA_8 = 0x08,
+ PORTA_9 = 0x09,
+ PORTA_10 = 0x0A,
+ PORTA_11 = 0x0B,
+ PORTA_12 = 0x0C,
+ PORTA_13 = 0x0D,
+ PORTA_14 = 0x0E,
+ PORTA_15 = 0x0F,
+
+ PORTB_0 = 0x10,
+ PORTB_0_MUL0 = PORTB_0 | MUL0,
+ PORTB_1 = 0x11,
+ PORTB_1_MUL0 = PORTB_1 | MUL0,
+ PORTB_2 = 0x12,
+ PORTB_3 = 0x13,
+ PORTB_4 = 0x14,
+ PORTB_5 = 0x15,
+ PORTB_6 = 0x16,
+ PORTB_7 = 0x17,
+ PORTB_8 = 0x18,
+ PORTB_8_MUL0 = PORTB_8 | MUL0,
+ PORTB_9 = 0x19,
+ PORTB_9_MUL0 = PORTB_9 | MUL0,
+ PORTB_10 = 0x1A,
+ PORTB_11 = 0x1B,
+ PORTB_12 = 0x1C,
+ PORTB_13 = 0x1D,
+ PORTB_14 = 0x1E,
+ PORTB_15 = 0x1F,
+
+ PORTC_0 = 0x20,
+ PORTC_0_MUL0 = PORTC_0 | MUL0,
+ PORTC_1 = 0x21,
+ PORTC_1_MUL0 = PORTC_1 | MUL0,
+ PORTC_2 = 0x22,
+ PORTC_2_MUL0 = PORTC_2 | MUL0,
+ PORTC_3 = 0x23,
+ PORTC_3_MUL0 = PORTC_3 | MUL0,
+ PORTC_4 = 0x24,
+ PORTC_4_MUL0 = PORTC_4 | MUL0,
+ PORTC_5 = 0x25,
+ PORTC_5_MUL0 = PORTC_5 | MUL0,
+ PORTC_6 = 0x26,
+ PORTC_6_MUL0 = PORTC_6 | MUL0,
+ PORTC_7 = 0x27,
+ PORTC_7_MUL0 = PORTC_7 | MUL0,
+ PORTC_8 = 0x28,
+ PORTC_8_MUL0 = PORTC_8 | MUL0,
+ PORTC_9 = 0x29,
+ PORTC_9_MUL0 = PORTC_9 | MUL0,
+ PORTC_10 = 0x2A,
+ PORTC_10_MUL0 = PORTC_10 | MUL0,
+ PORTC_11 = 0x2B,
+ PORTC_11_MUL0 = PORTC_11 | MUL0,
+ PORTC_12 = 0x2C,
+ PORTC_13 = 0x2D,
+ PORTC_14 = 0x2E,
+ PORTC_15 = 0x2F,
+
+ PORTD_0 = 0x30,
+ PORTD_1 = 0x31,
+ PORTD_2 = 0x32,
+ PORTD_3 = 0x33,
+ PORTD_4 = 0x34,
+ PORTD_5 = 0x35,
+ PORTD_6 = 0x36,
+ PORTD_7 = 0x37,
+ PORTD_8 = 0x38,
+ PORTD_9 = 0x39,
+ PORTD_10 = 0x3A,
+ PORTD_11 = 0x3B,
+ PORTD_12 = 0x3C,
+ PORTD_13 = 0x3D,
+ PORTD_14 = 0x3E,
+ PORTD_15 = 0x3F,
+
+ PORTE_0 = 0x40,
+ PORTE_1 = 0x41,
+ PORTE_2 = 0x42,
+ PORTE_3 = 0x43,
+ PORTE_4 = 0x44,
+ PORTE_5 = 0x45,
+ PORTE_6 = 0x46,
+ PORTE_7 = 0x47,
+ PORTE_8 = 0x48,
+ PORTE_9 = 0x49,
+ PORTE_10 = 0x4A,
+ PORTE_11 = 0x4B,
+ PORTE_12 = 0x4C,
+ PORTE_13 = 0x4D,
+ PORTE_14 = 0x4E,
+ PORTE_15 = 0x4F,
+
+ /* ADC internal channels */
+ ADC_TEMP = 0xF0,
+ ADC_VREF = 0xF1,
+
+
+ /* Arduino connector namings */
+ A0 = PORTC_0,
+ A1 = PORTC_1,
+ A2 = PORTC_2,
+ A3 = PORTC_3,
+ A4 = PORTC_4,
+ A5 = PORTC_5,
+ D0 = PORTC_11,
+ D1 = PORTC_10,
+ D2 = PORTB_12,
+ D3 = PORTD_12,
+ D4 = PORTC_8,
+ D5 = PORTC_7,
+ D6 = PORTB_0,
+ D7 = PORTC_12,
+ D8 = PORTD_13,
+ D9 = PORTA_8,
+ D10 = PORTA_1,
+ D11 = PORTB_15,
+ D12 = PORTB_14,
+ D13 = PORTB_13,
+ D14 = PORTB_9,
+ D15 = PORTB_8,
+
+ LED1 = PORTA_0,
+ LED2 = PORTB_1,
+ LED3 = PORTE_6,
+
+ KEY1 = PORTE_0,
+ KEY2 = PORTE_1,
+
+ BUTTON1 = KEY1,
+ BUTTON2 = KEY2,
+
+ SERIAL_TX = PORTA_2,
+ SERIAL_RX = PORTA_3,
+ USBTX = SERIAL_TX,
+ USBRX = SERIAL_RX,
+
+ I2C_SCL = D15,
+ I2C_SDA = D14,
+ SPI_MOSI = D11,
+ SPI_MISO = D12,
+ SPI_SCK = D13,
+ SPI_CS = D10,
+ PWM_OUT = D9,
+
+ USB_FS_DM = PORTA_11,
+ USB_FS_DP = PORTA_12,
+ USB_FS_ID = PORTA_10,
+ USB_FS_VBUS = PORTA_9,
+
+ NC = (int)0xFFFFFFFF
+} PinName;
+
+/* BIT[7:4] port number (0=PORTA, 1=PORTB, 2=PORTC, 3=PORTD, 4=PORTE)
+ BIT[3:0] pin number */
+#define GD_PORT_GET(X) (((uint32_t)(X) >> 4) & 0xF)
+#define GD_PIN_GET(X) (((uint32_t)(X) & 0xF))
+
+/* Get mode,speed,remap function,channel of GPIO pin */
+#define GD_PIN_MODE_GET(X) (X & 0x07)
+#define GD_PIN_SPEED_GET(X) ((X >> 9) & 0x03)
+#define GD_PIN_REMAP_GET(X) ((X >> 3) & 0x3F)
+#define GD_PIN_CHANNEL_GET(X) ((X >> 11) & 0x1F)
+
+/* Defines GPIO pin direction */
+typedef enum {
+ PIN_INPUT = 0,
+ PIN_OUTPUT
+} PinDirection;
+
+/* Defines mode types of GPIO pin */
+typedef enum {
+ MODE_AIN = 0,
+ MODE_IN_FLOATING,
+ MODE_IPD,
+ MODE_IPU,
+ MODE_OUT_OD,
+ MODE_OUT_PP,
+ MODE_AF_OD,
+ MODE_AF_PP,
+ PullDefault = MODE_IN_FLOATING,
+ PullUp = MODE_IPU,
+ PullDown = MODE_IPD,
+ PullNone = 11
+} PinMode;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/analogin_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/analogin_api.c
new file mode 100644
index 0000000000..82596013cc
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/analogin_api.c
@@ -0,0 +1,175 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "analogin_api.h"
+
+#if DEVICE_ANALOGIN
+
+#include "cmsis.h"
+#include "pinmap.h"
+#include "PeripheralPins.h"
+#include "mbed_error.h"
+
+#define DEV_ADC_ACCURACY_12BIT 0xFFF
+#define DEV_ADC_PRECISION_12TO16(val) ((val << 4)| ((val >> 8) & (uint16_t)0x000F))
+#define AND_NUMBER (0xFF)
+
+FlagStatus temperature_sample_flag = RESET;
+
+/** software delay
+ *
+ * @param time The time need to delay
+ */
+static void _delay(uint16_t time)
+{
+ uint16_t i;
+ for (i = 0; i < time; i++) {
+ }
+}
+
+/** Initialize the analogin peripheral
+ *
+ * Configures the pin used by analogin.
+ * @param obj The analogin object to initialize
+ * @param pin The analogin pin name
+ */
+void analogin_init(analogin_t *obj, PinName pin)
+{
+ uint32_t periph;
+
+ MBED_ASSERT(obj);
+
+ obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
+ MBED_ASSERT(obj->adc != (ADCName)NC);
+
+ uint32_t function = pinmap_function(pin, PinMap_ADC);
+ MBED_ASSERT(function != (uint32_t)NC);
+
+ obj->channel = GD_PIN_CHANNEL_GET(function);
+ MBED_ASSERT(obj->channel <= ADC_CHANNEL_17);
+
+ periph = obj->adc;
+ /* save the pin for future use */
+ obj->pin = pin;
+
+ /* ADC clock enable and pin number reset */
+ switch (periph) {
+ case ADC0:
+ rcu_periph_clock_enable(RCU_ADC0);
+ break;
+
+ case ADC1:
+ rcu_periph_clock_enable(RCU_ADC1);
+ /* reset pin number */
+ pin = (PinName)(pin & AND_NUMBER);
+ break;
+ }
+
+ /* ADC clock cannot be greater than 40M */
+ rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
+
+ if ((ADC_CHANNEL_16 == obj->channel)) {
+ /* ADC Vrefint enable */
+ adc_tempsensor_vrefint_enable();
+ /* set temperature sample flag */
+ temperature_sample_flag = SET;
+ }
+ if ((ADC_CHANNEL_17 == obj->channel)) {
+ /* ADC Vrefint enable */
+ adc_tempsensor_vrefint_enable();
+ }
+
+ /* when pin >= ADC_TEMP, it indicates that the channel has no external pins */
+ if (pin < ADC_TEMP) {
+ pinmap_pinout(pin, PinMap_ADC);
+ }
+
+ /* ADC configuration */
+ adc_special_function_config(obj->adc, ADC_SCAN_MODE, DISABLE);
+ adc_special_function_config(obj->adc, ADC_CONTINUOUS_MODE, DISABLE);
+ /* ADC trigger config */
+ adc_external_trigger_source_config(obj->adc, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);
+ /* ADC mode config */
+ adc_mode_config(ADC_MODE_FREE);
+ /* ADC data alignment config */
+ adc_data_alignment_config(obj->adc, ADC_DATAALIGN_RIGHT);
+ /* ADC channel length config */
+ adc_channel_length_config(obj->adc, ADC_REGULAR_CHANNEL, 1);
+
+ if (temperature_sample_flag == SET) {
+ /* sample temperature needs more time */
+ adc_regular_channel_config(obj->adc, 0, obj->channel, ADC_SAMPLETIME_239POINT5);
+ /* clear temperature sample flag */
+ temperature_sample_flag = RESET;
+ } else {
+ adc_regular_channel_config(obj->adc, 0, obj->channel, ADC_SAMPLETIME_28POINT5);
+ }
+ adc_external_trigger_config(obj->adc, ADC_REGULAR_CHANNEL, ENABLE);
+
+ /* ADC enable */
+ adc_enable(obj->adc);
+ /* wait for ADC to stabilize */
+ _delay(500);
+ adc_calibration_enable(obj->adc);
+}
+
+/** Read the value from analogin pin, represented as an unsigned 16bit value
+ *
+ * @param obj The analogin object
+ * @return An unsigned 16bit value representing the current input voltage
+ */
+uint16_t analogin_read_u16(analogin_t *obj)
+{
+ uint16_t reval;
+
+ adc_flag_clear(obj->adc, ADC_FLAG_EOC);
+ /* start Conversion */
+ adc_software_trigger_enable(obj->adc, ADC_REGULAR_CHANNEL);
+
+ while (SET != adc_flag_get(obj->adc, ADC_FLAG_EOC)) {
+ }
+ /* ADC actual accuracy is 12 bits */
+ reval = adc_regular_data_read(obj->adc);
+
+ reval = DEV_ADC_PRECISION_12TO16(reval);
+
+ return reval;
+}
+
+/** Read the input voltage, represented as a float in the range [0.0, 1.0]
+ *
+ * @param obj The analogin object
+ * @return A floating value representing the current input voltage
+ */
+float analogin_read(analogin_t *obj)
+{
+ uint16_t reval;
+
+ adc_flag_clear(obj->adc, ADC_FLAG_EOC);
+ /* start Conversion */
+ adc_software_trigger_enable(obj->adc, ADC_REGULAR_CHANNEL);
+ /* wait for conversion to complete */
+ while (SET != adc_flag_get(obj->adc, ADC_FLAG_EOC)) {
+ }
+ /* ADC actual accuracy is 12 bits */
+ reval = adc_regular_data_read(obj->adc);
+
+ return (float)reval * (1.0f / (float)DEV_ADC_ACCURACY_12BIT);
+}
+
+#endif /* DEVICE_ANALOGIN */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/analogout_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/analogout_api.c
new file mode 100644
index 0000000000..e07f2ad3ec
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/analogout_api.c
@@ -0,0 +1,161 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "analogout_api.h"
+#include "mbed_assert.h"
+
+#if DEVICE_ANALOGOUT
+
+#include "cmsis.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+#include "PeripheralPins.h"
+
+/* 12bit */
+#define DEV_DAC_ACCURACY_12BIT (0xFFF)
+#define DEV_DAC_BITS (12)
+
+/** Initialize the analogout peripheral
+ *
+ * Configures the pin used by analogout.
+ * @param obj The analogout object to initialize
+ * @param pin The analogout pin name
+ */
+void analogout_init(dac_t *obj, PinName pin)
+{
+ /* get the peripheral name from the pin and assign it to the object */
+ obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
+ MBED_ASSERT(obj->dac != (DACName)NC);
+
+ /* get the pin function and assign the used channel to the object */
+ uint32_t function = pinmap_function(pin, PinMap_DAC);
+ MBED_ASSERT(function != (uint32_t)NC);
+
+ obj->channel = GD_PIN_CHANNEL_GET(function);
+ MBED_ASSERT(obj->channel <= DAC1);
+
+ /* configure GPIO */
+ pinmap_pinout(pin, PinMap_DAC);
+
+ /* save the pin for future use */
+ obj->pin = pin;
+
+ /* enable DAC clock */
+ rcu_periph_clock_enable(RCU_DAC);
+
+ /* configure DAC */
+ dac_wave_mode_config(obj->channel, DAC_WAVE_DISABLE);
+ dac_trigger_disable(obj->channel);
+ dac_output_buffer_enable(obj->channel);
+ analogout_write_u16(obj, 0);
+}
+
+/** Release the analogout object
+ *
+ * Note: This is not currently used in the mbed-drivers
+ * @param obj The analogout object
+ */
+void analogout_free(dac_t *obj)
+{
+ /* Reset DAC and disable clock */
+ dac_deinit();
+ rcu_periph_clock_disable(RCU_DAC);
+
+ /* configure GPIO */
+ /* get the pin function and assign the used channel to the object */
+ uint32_t function = pinmap_function(obj->pin, PinMap_DAC);
+ MBED_ASSERT(function != (uint32_t)NC);
+
+ pin_function(obj->pin, function);
+}
+
+/** set the output voltage with specified as a integer
+ *
+ * @param obj The analogin object
+ * @param value The integer-point output voltage to be set
+ */
+static inline void dev_dac_data_set(dac_t *obj, int value)
+{
+ dac_data_set(obj->channel, DAC_ALIGN_12B_R, (value & DEV_DAC_ACCURACY_12BIT));
+
+ dac_enable(obj->channel);
+
+ dac_software_trigger_enable(obj->channel);
+}
+
+/** get the current DAC data
+ *
+ * @param obj The analogin object
+ * @return DAC data
+ */
+static inline int dev_dac_data_get(dac_t *obj)
+{
+ return (int)dac_output_value_get(obj->channel);
+}
+
+/** Set the output voltage, specified as a percentage (float)
+ *
+ * @param obj The analogin object
+ * @param value The floating-point output voltage to be set
+ */
+void analogout_write(dac_t *obj, float value)
+{
+ if (value < 0.0f) {
+ /* when the value is less than 0.0, set DAC output date to 0 */
+ dev_dac_data_set(obj, 0);
+ } else if (value > 1.0f) {
+ /* when the value is more than 1.0, set DAC output date to 0xFFF */
+ dev_dac_data_set(obj, (int)DEV_DAC_ACCURACY_12BIT);
+ } else {
+ dev_dac_data_set(obj, (int)(value * (float)DEV_DAC_ACCURACY_12BIT));
+ }
+}
+
+/** Set the output voltage, specified as unsigned 16-bit
+ *
+ * @param obj The analogin object
+ * @param value The unsigned 16-bit output voltage to be set
+ */
+void analogout_write_u16(dac_t *obj, uint16_t value)
+{
+ dev_dac_data_set(obj, value >> (16 - DEV_DAC_BITS));
+}
+
+/** Read the current voltage value on the pin
+ *
+ * @param obj The analogin object
+ * @return A floating-point value representing the current voltage on the pin,
+ * measured as a percentage
+ */
+float analogout_read(dac_t *obj)
+{
+ uint32_t ret_val = dev_dac_data_get(obj);
+ return (float)ret_val * (1.0f / (float)DEV_DAC_ACCURACY_12BIT);
+}
+
+/** Read the current voltage value on the pin, as a normalized unsigned 16bit value
+ *
+ * @param obj The analogin object
+ * @return An unsigned 16-bit value representing the current voltage on the pin
+ */
+uint16_t analogout_read_u16(dac_t *obj)
+{
+ uint32_t ret_val = dev_dac_data_get(obj);
+ return (ret_val << 4) | ((ret_val >> 8) & 0x000F);
+}
+
+#endif /* DEVICE_ANALOGOUT */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/can_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/can_api.c
new file mode 100644
index 0000000000..2c79789307
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/can_api.c
@@ -0,0 +1,633 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "can_api.h"
+#include "pinmap.h"
+#include "PeripheralPins.h"
+#include "mbed_error.h"
+
+#if DEVICE_CAN
+
+/* BS1[3:0] + 1 + BS2[2:0] + 1 */
+#define DEV_CAN_BT_SEG_MAX 24
+#define DEV_CAN_BT_SEG_MIN 4
+
+/* CAN related register mask */
+#define DEV_CAN_BS1_MASK 0x000F0000
+#define DEV_CAN_BS2_MASK 0x00700000
+#define DEV_CAN_BAUDPSC_MASK 0x000003FF
+#define DEV_CAN_SJW_MASK 0x03000000
+/* CAN0 interrupt vector number */
+#define CAN0_IRQ_BASE_NUM 19
+
+/* CAN1 interrupt vector number */
+#define CAN1_IRQ_BASE_NUM 63
+
+static uint32_t can_irq_ids[2] = {0};
+static can_irq_handler irq_callback;
+
+/** CAN interrupt handle .
+ *
+ * @param can_periph CAN0 or CAN1.
+ * @param id the CANx index .
+ */
+static void dev_can_irq_handle(uint32_t periph, int id)
+{
+ uint32_t flag0 = 0, flag1 = 0, flag2 = 0;
+
+ flag0 = can_interrupt_flag_get(periph, CAN_INT_FLAG_MTF0);
+ flag1 = can_interrupt_flag_get(periph, CAN_INT_FLAG_MTF1);
+ flag2 = can_interrupt_flag_get(periph, CAN_INT_FLAG_MTF2);
+
+ if (flag0) {
+ can_flag_clear(periph, CAN_FLAG_MTF0);
+ }
+ if (flag1) {
+ can_flag_clear(periph, CAN_FLAG_MTF1);
+ }
+ if (flag2) {
+ can_flag_clear(periph, CAN_FLAG_MTF2);
+ }
+
+ /* CAN transmit complete interrupt handle */
+ if (flag0 || flag1 || flag2) {
+ irq_callback(can_irq_ids[id], IRQ_TX);
+ }
+
+ /* CAN receive complete interrupt handle */
+ if (CAN_INTEN_RFNEIE0 == (CAN_INTEN(periph) & CAN_INTEN_RFNEIE0)) {
+ if (0 != can_receive_message_length_get(periph, CAN_FIFO0)) {
+ irq_callback(can_irq_ids[id], IRQ_RX);
+ }
+ }
+
+ /* CAN error interrupt handle */
+ if (SET == can_interrupt_flag_get(periph, CAN_INT_FLAG_ERRIF)) {
+ /* passive error interrupt handle */
+ if (CAN_INTEN_PERRIE == (CAN_INTEN(periph) & CAN_INTEN_PERRIE)) {
+ if (SET == can_flag_get(periph, CAN_FLAG_PERR)) {
+ irq_callback(can_irq_ids[id], IRQ_PASSIVE);
+ }
+ }
+
+ /* bus-off interrupt handle */
+ if (CAN_INTEN_BOIE == (CAN_INTEN(periph) & CAN_INTEN_BOIE)) {
+ if (SET == can_flag_get(periph, CAN_FLAG_BOERR)) {
+ irq_callback(can_irq_ids[id], IRQ_BUS);
+ }
+ }
+
+ irq_callback(can_irq_ids[id], IRQ_ERROR);
+ }
+}
+
+/** CAN1 Interrupt Request entry .
+ *
+ */
+static void dev_can0_irq_entry(void)
+{
+ dev_can_irq_handle(CAN0, 0);
+}
+
+/** CAN1 Interrupt Request entry .
+ *
+ */
+static void dev_can1_irq_entry(void)
+{
+ dev_can_irq_handle(CAN1, 1);
+}
+
+/** Config the CAN mode .
+ *
+ * @param can_periph CAN0 or CAN1.
+ * @param mode the mode to be set.
+ */
+static void dev_can_mode_config(uint32_t can_periph, uint32_t mode)
+{
+ /* enter the initialization mode, only in initialization mode CAN register can be configured */
+ can_working_mode_set(can_periph, CAN_MODE_INITIALIZE);
+
+ CAN_BT(can_periph) &= ~BT_MODE(3);
+ CAN_BT(can_periph) |= BT_MODE(mode);
+
+ /* enter the normal mode */
+ can_working_mode_set(can_periph, CAN_MODE_NORMAL);
+}
+
+/** Config the interrupt .
+ *
+ * @param can_periph CAN0 or CAN1.
+ * @param interrupt The interrupt type.
+ * @param enable enable or disable.
+ */
+static void dev_can_interrupt_config(uint32_t can_periph, uint32_t interrupt, uint32_t enable)
+{
+ if (enable) {
+ can_interrupt_enable(can_periph, interrupt);
+ } else {
+ can_interrupt_disable(can_periph, interrupt);
+ }
+}
+
+/* This table can be used to calculate bit time
+The first value is bit segment 1(BS1[3:0]), the second is bit segment 2(BS2[2:0]) */
+static const int sampling_points[23][2] = {
+ {0x0, 0x0}, /* 2, 50% */
+ {0x1, 0x0}, /* 3, 67% */
+ {0x2, 0x0}, /* 4, 75% */
+ {0x3, 0x0}, /* 5, 80% */
+ {0x3, 0x1}, /* 6, 67% */
+ {0x4, 0x1}, /* 7, 71% */
+ {0x5, 0x1}, /* 8, 75% */
+ {0x6, 0x1}, /* 9, 78% */
+ {0x6, 0x2}, /* 10, 70% */
+ {0x7, 0x2}, /* 11, 73% */
+ {0x8, 0x2}, /* 12, 75% */
+ {0x9, 0x2}, /* 13, 77% */
+ {0x9, 0x3}, /* 14, 71% */
+ {0xA, 0x3}, /* 15, 73% */
+ {0xB, 0x3}, /* 16, 75% */
+ {0xC, 0x3}, /* 17, 76% */
+ {0xD, 0x3}, /* 18, 78% */
+ {0xD, 0x4}, /* 19, 74% */
+ {0xE, 0x4}, /* 20, 75% */
+ {0xF, 0x4}, /* 21, 76% */
+ {0xF, 0x5}, /* 22, 73% */
+ {0xF, 0x6}, /* 23, 70% */
+ {0xF, 0x7}, /* 24, 67% */
+};
+
+/** Set the baudrate.
+ *
+ * @param freq The frequency value to be set.
+ *
+ * @returns
+ * CAN_BT register value
+ */
+static unsigned int dev_can_baudrate_set(int freq)
+{
+ uint32_t reval;
+ uint16_t baud_psc;
+ uint16_t baud_psc_max;
+ uint32_t temp;
+ uint32_t bt_reg_config;
+ uint8_t flag;
+ int bits;
+
+ flag = 0;
+
+ /* computes the value that the CAN_BT register needs to be configured */
+ /* (BAUDPSC[9:0] + 1) * ((BS1[3:0] + 1) + (BS2[2:0] + 1) + SJW(always 1)) */
+ bt_reg_config = (rcu_clock_freq_get(CK_APB1) / freq);
+ /* BAUDPSC[9:0] minimum value */
+ baud_psc = bt_reg_config / DEV_CAN_BT_SEG_MAX;
+ /* BAUDPSC[9:0] maximum value */
+ baud_psc_max = bt_reg_config / DEV_CAN_BT_SEG_MIN;
+
+ while ((!flag) && (baud_psc < baud_psc_max)) {
+ baud_psc++;
+ for (bits = 22; bits > 0; bits--) {
+ temp = (bits + 3) * (baud_psc + 1);
+ if (temp == bt_reg_config) {
+ flag = 1;
+ break;
+ }
+ }
+ }
+
+ if (flag) {
+ reval = ((sampling_points[bits][1] << 20) & DEV_CAN_BS2_MASK)
+ | ((sampling_points[bits][0] << 16) & DEV_CAN_BS1_MASK)
+ | ((1 << 24) & DEV_CAN_SJW_MASK)
+ | ((baud_psc << 0) & DEV_CAN_BAUDPSC_MASK);
+ } else {
+ /* CAN_BT register reset value */
+ reval = 0x01230000;
+ }
+
+ return reval;
+}
+
+/** init the CAN.
+ *
+ */
+void can_init(can_t *obj, PinName rd, PinName td)
+{
+ can_init_freq(obj, rd, td, 500000);
+}
+
+/** init the CAN frequency.
+ *
+ * @param rd receive pin.
+ * @param td transmit pin.
+ * @param hz The bus frequency in hertz.
+ */
+void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
+{
+ CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
+ CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
+ obj->can = (CANName)pinmap_merge(can_rd, can_td);
+
+ MBED_ASSERT((int)obj->can != NC);
+
+ if (obj->can == CAN_0) {
+ rcu_periph_clock_enable(RCU_CAN0);
+ can_deinit(obj->can);
+ obj->index = 0;
+ } else if (obj->can == CAN_1) {
+ rcu_periph_clock_enable(RCU_CAN0);
+ rcu_periph_clock_enable(RCU_CAN1);
+ can_deinit(obj->can);
+ obj->index = 1;
+ } else {
+ return;
+ }
+
+ /* Configure the CAN pins */
+ pinmap_pinout(rd, PinMap_CAN_RD);
+ pinmap_pinout(td, PinMap_CAN_TD);
+ if (rd != NC) {
+ pin_mode(rd, PullUp);
+ }
+ if (td != NC) {
+ pin_mode(td, PullUp);
+ }
+
+ dev_can_mode_config(obj->can, CAN_NORMAL_MODE);
+
+ can_frequency(obj, hz);
+
+ if (obj->can == CAN_0) {
+ can_filter(obj, 0, 0, CANStandard, 0);
+ } else {
+ can_filter(obj, 0, 0, CANStandard, 14);
+ }
+}
+
+/** disable CAN.
+ *
+ */
+void can_free(can_t *obj)
+{
+ can_deinit(obj->can);
+
+ if (obj->can == CAN0) {
+ rcu_periph_clock_disable(RCU_CAN0);
+ }
+
+ if (obj->can == CAN1) {
+ rcu_periph_clock_disable(RCU_CAN1);
+ }
+}
+
+/** Set the frequency of the CAN interface.
+ *
+ * @param hz The bus frequency in hertz.
+ *
+ * @returns
+ * 1 if successful,
+ * 0 otherwise
+ */
+int can_frequency(can_t *obj, int hz)
+{
+ int reval;
+
+ /* The maximum baud rate support to 1M */
+ if (hz <= 1000000) {
+ if (SUCCESS == can_working_mode_set(obj->can, CAN_MODE_INITIALIZE)) {
+ CAN_BT(obj->can) = dev_can_baudrate_set(hz);
+ } else {
+ error("the configuration of can frequency is out of range \r\n");
+ }
+
+ if (SUCCESS == can_working_mode_set(obj->can, CAN_MODE_NORMAL)) {
+ reval = 1;
+ } else {
+ reval = 0;
+ }
+ }
+
+ return reval;
+}
+
+/** init the interrupt.
+ *
+ * @param handler the interrupt callback.
+ * @param id the CANx index.
+ */
+void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
+{
+ irq_callback = handler;
+ can_irq_ids[obj->index] = id;
+}
+
+/** disable the interrupt.
+ *
+ */
+void can_irq_free(can_t *obj)
+{
+ if (CAN0 == obj->can) {
+ can_interrupt_disable(obj->can, CAN_INTEN_TMEIE | CAN_INTEN_RFNEIE0 | CAN_INTEN_RFNEIE1 | \
+ CAN_INTEN_PERRIE | CAN_INTEN_BOIE | CAN_INTEN_ERRIE);
+ }
+
+ if (CAN1 == obj->can) {
+ can_interrupt_disable(obj->can, CAN_INTEN_TMEIE | CAN_INTEN_RFNEIE0 | CAN_INTEN_RFNEIE1 | \
+ CAN_INTEN_PERRIE | CAN_INTEN_BOIE | CAN_INTEN_ERRIE);
+ }
+
+ can_irq_ids[obj->index] = 0;
+}
+
+/** Set the interrupt handle.
+ *
+ * @param type The interrupt type.
+ * @param enable enable or disable.
+ */
+void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
+{
+ uint32_t irq_num;
+ uint32_t vector = 0;
+
+ if (obj->can == CAN_0) {
+ vector = (uint32_t)dev_can0_irq_entry;
+ irq_num = CAN0_IRQ_BASE_NUM;
+ }
+
+ else if (obj->can == CAN_1) {
+ vector = (uint32_t)dev_can1_irq_entry;
+ irq_num = CAN1_IRQ_BASE_NUM;
+ }
+
+ switch (type) {
+ case IRQ_RX:
+ dev_can_interrupt_config(obj->can, CAN_INT_RFNE0, enable);
+ break;
+ case IRQ_TX:
+ dev_can_interrupt_config(obj->can, CAN_INT_TME, enable);
+ irq_num += 1;
+ break;
+ case IRQ_ERROR:
+ dev_can_interrupt_config(obj->can, CAN_INT_ERR | CAN_INT_ERRN, enable);
+ irq_num += 3;
+ break;
+ case IRQ_PASSIVE:
+ dev_can_interrupt_config(obj->can, CAN_INT_ERR | CAN_INT_PERR, enable);
+ irq_num += 3;
+ break;
+ case IRQ_BUS:
+ dev_can_interrupt_config(obj->can, CAN_INT_ERR | CAN_INT_BO, enable);
+ irq_num += 3;
+ break;
+ default:
+ return;
+ }
+
+ NVIC_SetVector((IRQn_Type)irq_num, vector);
+ NVIC_EnableIRQ((IRQn_Type)irq_num);
+}
+
+/** Write a CANMessage to the bus.
+ *
+ * @param msg The CANMessage to write.
+ *
+ * @returns
+ * 0 if write failed,
+ * 1 if write was successful
+ */
+int can_write(can_t *obj, CAN_Message msg, int cc)
+{
+ can_trasnmit_message_struct transmit_message;
+ uint32_t i;
+
+ can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
+ /* configure frame type: data or remote */
+ if (CANData == msg.type) {
+ transmit_message.tx_ft = CAN_FT_DATA;
+ } else if (CANRemote == msg.type) {
+ transmit_message.tx_ft = CAN_FT_REMOTE;
+ } else {
+ error("frame type of transmit message is invalid \r\n");
+ }
+
+ /* configure frame format: standard or extended */
+ if (CANStandard == msg.format) {
+ transmit_message.tx_ff = CAN_FF_STANDARD;
+ transmit_message.tx_sfid = msg.id;
+ } else if (CANExtended == msg.format) {
+ transmit_message.tx_ff = CAN_FF_EXTENDED;
+ transmit_message.tx_efid = msg.id;
+ } else {
+ error("frame format of transmit message is invalid \r\n");
+ }
+
+ transmit_message.tx_dlen = msg.len;
+
+ for (i = 0; i < msg.len; i++) {
+ transmit_message.tx_data[i] = msg.data[i];
+ }
+
+ can_message_transmit(obj->can, &transmit_message);
+
+ return 1;
+}
+
+/** Read a CANMessage from the bus.
+ *
+ * @param msg A CANMessage to read to.
+ * @param handle message filter handle (0 for any message).
+ *
+ * @returns
+ * 0 if no message arrived,
+ * 1 if message arrived
+ */
+int can_read(can_t *obj, CAN_Message *msg, int handle)
+{
+ uint8_t i;
+ uint8_t fifo_number;
+
+ fifo_number = (uint8_t)handle;
+ can_receive_message_struct receive_message;
+
+ /* if the frame is not received, retrun 0 */
+ if (0 == can_receive_message_length_get(obj->can, CAN_FIFO0)) {
+ return 0;
+ }
+
+ can_message_receive(obj->can, fifo_number, &receive_message);
+
+ if (receive_message.rx_ff == CAN_RFIFOMI_FF) {
+ msg->format = CANExtended;
+ } else {
+ msg->format = CANStandard;
+ }
+
+ if (0 == msg->format) {
+ msg->id = (uint32_t)0x000007FF & (receive_message.rx_sfid);
+ } else {
+ msg->id = (uint32_t)0x1FFFFFFF & (receive_message.rx_efid);
+ }
+
+ if (receive_message.rx_ft == CAN_RFIFOMI_FT) {
+ msg->type = CANRemote;
+ } else {
+ msg->type = CANData;
+ }
+
+ msg->len = (uint8_t)receive_message.rx_dlen;
+
+ for (i = 0; i < msg->len; i++) {
+ msg->data[i] = (uint8_t)receive_message.rx_data[i];
+ }
+ /* If the frame is received successfully, retrun 1 */
+ return 1;
+}
+
+/** Change CAN operation to the specified mode.
+ *
+ * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest).
+ *
+ * @returns
+ * 0 if mode change failed or unsupported,
+ * 1 if mode change was successful
+ */
+int can_mode(can_t *obj, CanMode mode)
+{
+ switch (mode) {
+ case MODE_NORMAL:
+ dev_can_mode_config(obj->can, CAN_NORMAL_MODE);
+ break;
+ case MODE_SILENT:
+ dev_can_mode_config(obj->can, CAN_SILENT_MODE);
+ break;
+ case MODE_TEST_GLOBAL:
+ case MODE_TEST_LOCAL:
+ dev_can_mode_config(obj->can, CAN_LOOPBACK_MODE);
+ break;
+ case MODE_TEST_SILENT:
+ dev_can_mode_config(obj->can, CAN_SILENT_LOOPBACK_MODE);
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/** Filter out incomming messages.
+ *
+ * @param id the id to filter on.
+ * @param mask the mask applied to the id.
+ * @param format format to filter on (Default CANAny).
+ * @param handle message filter handle (Optional).
+ *
+ * @returns
+ * 0 if filter change failed or unsupported,
+ * new filter handle if successful
+ */
+int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
+{
+ can_filter_parameter_struct can_filter;
+
+ can_filter.filter_number = handle;
+ can_filter.filter_mode = CAN_FILTERMODE_MASK;
+ can_filter.filter_bits = CAN_FILTERBITS_32BIT;
+ can_filter.filter_fifo_number = CAN_FIFO0;
+ can_filter.filter_enable = ENABLE;
+
+ switch (format) {
+ case CANStandard:
+ /* configure SFID[10:0] */
+ can_filter.filter_list_high = id << 5;
+ can_filter.filter_list_low = 0x0;
+ /* configure SFID[10:0] mask */
+ can_filter.filter_mask_high = mask << 5;
+ /* both data and remote frames can be received */
+ can_filter.filter_mask_low = 0x0;
+
+ break;
+
+ case CANExtended:
+ /* configure EFID[28:13] */
+ can_filter.filter_list_high = id >> 13;
+ /* configure EFID[12:0] and frame format bit set */
+ can_filter.filter_list_low = (id << 3) | (1 << 2);
+ /* configure EFID[28:13] mask */
+ can_filter.filter_mask_high = mask >> 13;
+ /* configure EFID[12:0] and frame format bit mask */
+ /* both data and remote frames can be received */
+ can_filter.filter_mask_low = (mask << 3) | (1 << 2);
+
+ break;
+
+ case CANAny:
+ error("CANAny mode is not supported \r\n");
+ return 0;
+
+ default:
+ error("parameter is not supported \r\n");
+ return 0;
+ }
+
+ can_filter_init(&can_filter);
+ can1_filter_start_bank(handle);
+
+ return handle;
+}
+
+/** Reset CAN interface.
+ *
+ * To use after error overflow.
+ */
+void can_reset(can_t *obj)
+{
+ can_deinit(obj->can);
+}
+
+/** Detects read errors - Used to detect read overflow errors.
+ *
+ * @returns number of read errors
+ */
+unsigned char can_rderror(can_t *obj)
+{
+ return can_receive_error_number_get(obj->can);
+}
+
+/** Detects write errors - Used to detect write overflow errors.
+ *
+ * @returns number of write errors
+ */
+unsigned char can_tderror(can_t *obj)
+{
+ return can_transmit_error_number_get(obj->can);
+}
+
+/** Puts or removes the CAN interface into silent monitoring mode.
+ *
+ * @param silent boolean indicating whether to go into silent mode or not.
+ */
+void can_monitor(can_t *obj, int silent)
+{
+ if (silent) {
+ dev_can_mode_config(obj->can, CAN_SILENT_MODE);
+ } else {
+ dev_can_mode_config(obj->can, CAN_NORMAL_MODE);
+ }
+}
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device.h
new file mode 100644
index 0000000000..ceedbdd746
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device.h
@@ -0,0 +1,27 @@
+/* The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. */
+/* Check the 'features' section of the target description in 'targets.json' for more details. */
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2018 ARM Limited
+*
+* SPDX-License-Identifier: Apache-2.0
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef MBED_DEVICE_H
+#define MBED_DEVICE_H
+
+#define DEVICE_ID_LENGTH 24
+
+#include "objects.h"
+
+#endif /* MBED_DEVICE_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_MICRO/gd32e103vb.sct b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_MICRO/gd32e103vb.sct
new file mode 100644
index 0000000000..44243e7961
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_MICRO/gd32e103vb.sct
@@ -0,0 +1,27 @@
+#! armcc -E
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *****
+
+#if !defined(MBED_APP_START)
+ #define MBED_APP_START 0x08000000
+#endif
+
+#if !defined(MBED_APP_SIZE)
+ #define MBED_APP_SIZE 0x20000
+#endif
+
+LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region (1024K)
+
+ ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address
+ *.o (RESET, +First)
+ *(InRoot$$Sections)
+ .ANY (+RO)
+ }
+
+ ; 84 vectors (16 core + 68 peripheral) * 4 bytes = 336 bytes to reserve (0x150)
+ RW_IRAM1 (0x20000000+0x150) (0x8000-0x150) { ; RW data
+ .ANY (+RW +ZI)
+ }
+}
+
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_MICRO/startup_gd32e10x.S b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_MICRO/startup_gd32e10x.S
new file mode 100644
index 0000000000..164bd83204
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_MICRO/startup_gd32e10x.S
@@ -0,0 +1,359 @@
+;/*!
+; \file startup_gd32f30x_cl.S
+; \brief start up file
+;
+; \version 2017-12-26, V1.0.0, firmware for GD32E10x
+; \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+;*/
+;
+;/*
+; Copyright (c) 2018, GigaDevice Semiconductor Inc.
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+;are permitted provided that the following conditions are met:
+;
+; 1. Redistributions of source code must retain the above copyright notice, this
+; list of conditions and the following disclaimer.
+; 2. 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.
+; 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+;*/
+
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+ EXPORT __initial_sp
+Stack_Mem SPACE Stack_Size
+__initial_sp EQU 0x20008000 ; Top of RAM
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000400
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+ EXPORT __heap_base
+ EXPORT __heap_limit
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit EQU (__initial_sp - Stack_Size)
+
+ 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_IRQHandler ; 18:Tamper through EXTI Line detect
+ DCD RTC_IRQHandler ; 19:RTC 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 ADC0_1_IRQHandler ; 34:ADC0 and ADC1
+ 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_Channel_IRQHandler ; 43:TIMER0 Channel 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_Channel_IRQHandler ; 62:TIMER7 Channel Capture Compare
+ DCD 0 ; Reserved
+ DCD EXMC_IRQHandler ; 64:EXMC
+ DCD 0 ; Reserved
+ DCD TIMER4_IRQHandler ; 66:TIMER4
+ DCD SPI2_IRQHandler ; 67:SPI2
+ DCD UART3_IRQHandler ; 68:UART3
+ DCD UART4_IRQHandler ; 69:UART4
+ DCD TIMER5_IRQHandler ; 70:TIMER5
+ 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 0 ; 77:Reserved
+ DCD 0 ; 78:Reserved
+ 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
+
+__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_IRQHandler [WEAK]
+ EXPORT RTC_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 ADC0_1_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_Channel_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_Channel_IRQHandler [WEAK]
+ EXPORT EXMC_IRQHandler [WEAK]
+ EXPORT TIMER4_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT UART3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT TIMER5_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 CAN1_TX_IRQHandler [WEAK]
+ EXPORT CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_EWMC_IRQHandler [WEAK]
+ EXPORT USBFS_IRQHandler [WEAK]
+
+;/* external interrupts handler */
+WWDGT_IRQHandler
+LVD_IRQHandler
+TAMPER_IRQHandler
+RTC_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
+ADC0_1_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_Channel_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_Channel_IRQHandler
+EXMC_IRQHandler
+TIMER4_IRQHandler
+SPI2_IRQHandler
+UART3_IRQHandler
+UART4_IRQHandler
+TIMER5_IRQHandler
+TIMER6_IRQHandler
+DMA1_Channel0_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+CAN1_TX_IRQHandler
+CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_EWMC_IRQHandler
+USBFS_IRQHandler
+
+ B .
+ ENDP
+
+ ALIGN
+
+ END
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_STD/gd32e103vb.sct b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_STD/gd32e103vb.sct
new file mode 100644
index 0000000000..e65ee253f7
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_STD/gd32e103vb.sct
@@ -0,0 +1,36 @@
+#! armcc -E
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *****
+
+#if !defined(MBED_APP_START)
+ #define MBED_APP_START 0x08000000
+#endif
+
+#if !defined(MBED_APP_SIZE)
+ #define MBED_APP_SIZE 0x20000
+#endif
+
+#if !defined(MBED_BOOT_STACK_SIZE)
+ #define MBED_BOOT_STACK_SIZE 0x400
+#endif
+
+#define Stack_Size MBED_BOOT_STACK_SIZE
+
+LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region (1024K)
+
+ ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address
+ *.o (RESET, +First)
+ *(InRoot$$Sections)
+ .ANY (+RO)
+ }
+
+ ; 84 vectors (16 core + 68 peripheral) * 4 bytes = 336 bytes to reserve (0x150)
+ RW_IRAM1 (0x20000000+0x150) (0x8000-0x150-Stack_Size) { ; RW data
+ .ANY (+RW +ZI)
+ }
+
+ ARM_LIB_STACK 0x20000000+0x8000 EMPTY -Stack_Size { ; Stack region growing down
+ }
+}
+
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_STD/startup_gd32e10x.S b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_STD/startup_gd32e10x.S
new file mode 100644
index 0000000000..478598c7aa
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_ARM_STD/startup_gd32e10x.S
@@ -0,0 +1,356 @@
+;/*!
+; \file startup_gd32e10x.s
+; \brief start up file
+;
+; \version 2017-12-26, V1.0.0, firmware for GD32E10x
+; \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+;*/
+;
+;/*
+; Copyright (c) 2018, GigaDevice Semiconductor Inc.
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+;are permitted provided that the following conditions are met:
+;
+; 1. Redistributions of source code must retain the above copyright notice, this
+; list of conditions and the following disclaimer.
+; 2. 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.
+; 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+;*/
+
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp EQU 0x20008000
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+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_IRQHandler ; 18:Tamper through EXTI Line detect
+ DCD RTC_IRQHandler ; 19:RTC 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 ADC0_1_IRQHandler ; 34:ADC0 and ADC1
+ 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_Channel_IRQHandler ; 43:TIMER0 Channel 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_Channel_IRQHandler ; 62:TIMER7 Channel Capture Compare
+ DCD 0 ; Reserved
+ DCD EXMC_IRQHandler ; 64:EXMC
+ DCD 0 ; Reserved
+ DCD TIMER4_IRQHandler ; 66:TIMER4
+ DCD SPI2_IRQHandler ; 67:SPI2
+ DCD UART3_IRQHandler ; 68:UART3
+ DCD UART4_IRQHandler ; 69:UART4
+ DCD TIMER5_IRQHandler ; 70:TIMER5
+ 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 0 ; 77:Reserved
+ DCD 0 ; 78:Reserved
+ 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
+
+__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_IRQHandler [WEAK]
+ EXPORT RTC_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 ADC0_1_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_Channel_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_Channel_IRQHandler [WEAK]
+ EXPORT EXMC_IRQHandler [WEAK]
+ EXPORT TIMER4_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT UART3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT TIMER5_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 CAN1_TX_IRQHandler [WEAK]
+ EXPORT CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_EWMC_IRQHandler [WEAK]
+ EXPORT USBFS_IRQHandler [WEAK]
+
+;/* external interrupts handler */
+WWDGT_IRQHandler
+LVD_IRQHandler
+TAMPER_IRQHandler
+RTC_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
+ADC0_1_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_Channel_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_Channel_IRQHandler
+EXMC_IRQHandler
+TIMER4_IRQHandler
+SPI2_IRQHandler
+UART3_IRQHandler
+UART4_IRQHandler
+TIMER5_IRQHandler
+TIMER6_IRQHandler
+DMA1_Channel0_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+CAN1_TX_IRQHandler
+CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_EWMC_IRQHandler
+USBFS_IRQHandler
+
+ B .
+ ENDP
+
+ ALIGN
+
+ END
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_GCC_ARM/GD32E103xB.ld b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_GCC_ARM/GD32E103xB.ld
new file mode 100644
index 0000000000..6a01b089bd
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_GCC_ARM/GD32E103xB.ld
@@ -0,0 +1,136 @@
+#if !defined(MBED_APP_START)
+ #define MBED_APP_START 0x08000000
+#endif
+
+#if !defined(MBED_APP_SIZE)
+ #define MBED_APP_SIZE 128K
+#endif
+
+#if !defined(MBED_BOOT_STACK_SIZE)
+ #define MBED_BOOT_STACK_SIZE 0x400
+#endif
+
+/* specify memory regions */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
+ RAM (rwx) : ORIGIN = 0x20000150, LENGTH = 32K - 0x150
+}
+
+/* define output sections */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .text :
+ {
+ KEEP(*(.isr_vector))
+ *(.text*)
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* .ctors */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+ /* .dtors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.rodata*)
+
+ KEEP(*(.eh_frame*))
+ } > FLASH
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH
+ __exidx_end = .;
+
+ __etext = .;
+ _sidata = .;
+
+ .data : AT (__etext)
+ {
+ __data_start__ = .;
+ _sdata = .;
+ *(vtable)
+ *(.data*)
+
+ . = ALIGN(8);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(8);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+
+ . = ALIGN(8);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ KEEP(*(.jcr*))
+ . = ALIGN(8);
+ /* All data end */
+ __data_end__ = .;
+ _edata = .;
+
+ } > RAM
+
+ .bss :
+ {
+ . = ALIGN(8);
+ __bss_start__ = .;
+ _sbss = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(8);
+ __bss_end__ = .;
+ _ebss = .;
+ } > RAM
+
+ .heap (COPY):
+ {
+ __end__ = .;
+ end = __end__;
+ *(.heap*)
+ . = ORIGIN(RAM) + LENGTH(RAM) - MBED_BOOT_STACK_SIZE;
+ __HeapLimit = .;
+ } > RAM
+
+ .stack_dummy (COPY):
+ {
+ *(.stack*)
+ } > RAM
+
+ /* initializes stack on the end of block */
+ __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+ _estack = __StackTop;
+ __StackLimit = __StackTop - MBED_BOOT_STACK_SIZE;
+ PROVIDE(__stack = __StackTop);
+
+ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+}
+
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_GCC_ARM/startup_gd32e10x.S b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_GCC_ARM/startup_gd32e10x.S
new file mode 100644
index 0000000000..0ed7d02d56
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_GCC_ARM/startup_gd32e10x.S
@@ -0,0 +1,408 @@
+;/*!
+; \file startup_gd32e10x_cl.S
+; \brief start up file
+;
+; \version 2017-12-26, V1.0.0, firmware for GD32E10x
+; \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+;*/
+;
+;/*
+; Copyright (c) 2018, GigaDevice Semiconductor Inc.
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+;are permitted provided that the following conditions are met:
+;
+; 1. Redistributions of source code must retain the above copyright notice, this
+; list of conditions and the following disclaimer.
+; 2. 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.
+; 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+;*/
+
+.syntax unified
+.cpu cortex-m4
+.fpu softvfp
+.thumb
+
+.global VecTab
+.global Default_Handler
+
+/* start address of the initialization .data */
+.word _sidata
+/* start address of the .data section */
+.word _sdata
+/* end address of the .data section */
+.word _edata
+
+/* reset Handler */
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr r0, =_estack
+ mov sp, r0 /* set stack pointer */
+
+/* copy the data segment into RAM */
+ movs r1, #0
+ b DataInit
+
+CopyData:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+DataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyData
+
+/* system clock intitialization*/
+ bl SystemInit
+/* static constructors */
+// bl __libc_init_array
+/* jump to application's entry point */
+// bl main
+ bl _start
+/* infinite loop */
+ b .
+
+
+.size Reset_Handler, .-Reset_Handler
+
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+/* infinite loop */
+ b .
+ .size Default_Handler, .-Default_Handler
+
+ .section .isr_vector,"a",%progbits
+ .type VecTab, %object
+ .size VecTab, .-VecTab
+
+
+VecTab:
+
+ .word _estack /* Top of Stack */
+ .word Reset_Handler /* 1,Reset Handler */
+ .word NMI_Handler /* 2,NMI Handler */
+ .word HardFault_Handler /* 3,Hard Fault Handler */
+ .word MemManage_Handler /* 4,MPU Fault Handler */
+ .word BusFault_Handler /* 5,Bus Fault Handler */
+ .word UsageFault_Handler /* 6,Usage Fault Handler */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word SVC_Handler /* 11,SVCall Handler */
+ .word DebugMon_Handler /* 12,Debug Monitor Handler */
+ .word 0 /* Reserved */
+ .word PendSV_Handler /* 14,PendSV Handler */
+ .word SysTick_Handler /* 15,SysTick Handler */
+ /* External Interrupts */
+ .word WWDGT_IRQHandler /* 16,Window Watchdog Timer */
+ .word LVD_IRQHandler /* 17,LVD through EXTI Line detect */
+ .word TAMPER_IRQHandler /* 18,Tamper through EXTI Line detect */
+ .word RTC_IRQHandler /* 19,RTC through EXTI Line */
+ .word FMC_IRQHandler /* 20,FMC */
+ .word RCU_CTC_IRQHandler /* 21,RCU and CTC */
+ .word EXTI0_IRQHandler /* 22,EXTI Line 0 */
+ .word EXTI1_IRQHandler /* 23,EXTI Line 1 */
+ .word EXTI2_IRQHandler /* 24,EXTI Line 2 */
+ .word EXTI3_IRQHandler /* 25,EXTI Line 3 */
+ .word EXTI4_IRQHandler /* 26,EXTI Line 4 */
+ .word DMA0_Channel0_IRQHandler /* 27,DMA0 Channel 0 */
+ .word DMA0_Channel1_IRQHandler /* 28,DMA0 Channel 1 */
+ .word DMA0_Channel2_IRQHandler /* 29,DMA0 Channel 2 */
+ .word DMA0_Channel3_IRQHandler /* 30,DMA0 Channel 3 */
+ .word DMA0_Channel4_IRQHandler /* 31,DMA0 Channel 4 */
+ .word DMA0_Channel5_IRQHandler /* 32,DMA0 Channel 5 */
+ .word DMA0_Channel6_IRQHandler /* 33,DMA0 Channel 6 */
+ .word ADC0_1_IRQHandler /* 34,ADC0 and ADC1 */
+ .word CAN0_TX_IRQHandler /* 35,CAN0 TX */
+ .word CAN0_RX0_IRQHandler /* 36,CAN0 RX0 */
+ .word CAN0_RX1_IRQHandler /* 37,CAN0 RX1 */
+ .word CAN0_EWMC_IRQHandler /* 38,CAN0 EWMC */
+ .word EXTI5_9_IRQHandler /* 39,EXTI5 to EXTI9 */
+ .word TIMER0_BRK_TIMER8_IRQHandler /* 40,TIMER0 Break and TIMER8 */
+ .word TIMER0_UP_TIMER9_IRQHandler /* 41,TIMER0 Update and TIMER9 */
+ .word TIMER0_TRG_CMT_TIMER10_IRQHandler /* 42,TIMER0 Trigger and Commutation and TIMER10 */
+ .word TIMER0_Channel_IRQHandler /* 43,TIMER0 Channel Capture Compare */
+ .word TIMER1_IRQHandler /* 44,TIMER4 */
+ .word TIMER2_IRQHandler /* 45,TIMER2 */
+ .word TIMER3_IRQHandler /* 46,TIMER3 */
+ .word I2C0_EV_IRQHandler /* 47,I2C0 Event */
+ .word I2C0_ER_IRQHandler /* 48,I2C0 Error */
+ .word I2C1_EV_IRQHandler /* 49,I2C1 Event */
+ .word I2C1_ER_IRQHandler /* 50,I2C1 Error */
+ .word SPI0_IRQHandler /* 51,SPI0 */
+ .word SPI1_IRQHandler /* 52,SPI1 */
+ .word USART0_IRQHandler /* 53,USART0 */
+ .word USART1_IRQHandler /* 54,USART1 */
+ .word USART2_IRQHandler /* 55,USART2 */
+ .word EXTI10_15_IRQHandler /* 56,EXTI10 to EXTI15 */
+ .word RTC_Alarm_IRQHandler /* 57,RTC Alarm */
+ .word USBFS_WKUP_IRQHandler /* 58,USBFS Wakeup */
+ .word TIMER7_BRK_TIMER11_IRQHandler /* 59,TIMER7 Break and TIMER11 */
+ .word TIMER7_UP_TIMER12_IRQHandler /* 60:TIMER7 Update and TIMER12 */
+ .word TIMER7_TRG_CMT_TIMER13_IRQHandler /* 61:TIMER7 Trigger and Commutation and TIMER13 */
+ .word TIMER7_Channel_IRQHandler /* 62,TIMER7 Capture Compare */
+ .word 0 /* Reserved */
+ .word EXMC_IRQHandler /* 64,EXMC */
+ .word 0 /* Reserved */
+ .word TIMER4_IRQHandler /* 66,TIMER4 */
+ .word SPI2_IRQHandler /* 67,SPI2 */
+ .word UART3_IRQHandler /* 68,UART3 */
+ .word UART4_IRQHandler /* 69,UART4 */
+ .word TIMER5_IRQHandler /* 70,TIMER5 */
+ .word TIMER6_IRQHandler /* 71,TIMER6 */
+ .word DMA1_Channel0_IRQHandler /* 72,DMA1 Channel0 */
+ .word DMA1_Channel1_IRQHandler /* 73,DMA1 Channel1 */
+ .word DMA1_Channel2_IRQHandler /* 74,DMA1 Channel2 */
+ .word DMA1_Channel3_IRQHandler /* 75,DMA1 Channel3 */
+ .word DMA1_Channel4_IRQHandler /* 76,DMA1 Channel4 */
+ .word 0 /* 77,Reserved */
+ .word 0 /* 78,Reserved */
+ .word CAN1_TX_IRQHandler /* 79,CAN1 TX */
+ .word CAN1_RX0_IRQHandler /* 80,CAN1 RX0 */
+ .word CAN1_RX1_IRQHandler /* 81,CAN1 RX1 */
+ .word CAN1_EWMC_IRQHandler /* 82,CAN1 EWMC */
+ .word USBFS_IRQHandler /* 83,USBFS */
+
+/* dummy Exception Handlers */
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDGT_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak LVD_IRQHandler
+ .thumb_set LVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FMC_IRQHandler
+ .thumb_set FMC_IRQHandler,Default_Handler
+
+ .weak RCU_CTC_IRQHandler
+ .thumb_set RCU_CTC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel0_IRQHandler
+ .thumb_set DMA0_Channel0_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel1_IRQHandler
+ .thumb_set DMA0_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel2_IRQHandler
+ .thumb_set DMA0_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel3_IRQHandler
+ .thumb_set DMA0_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel4_IRQHandler
+ .thumb_set DMA0_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel5_IRQHandler
+ .thumb_set DMA0_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA0_Channel6_IRQHandler
+ .thumb_set DMA0_Channel6_IRQHandler,Default_Handler
+
+ .weak ADC0_1_IRQHandler
+ .thumb_set ADC0_1_IRQHandler,Default_Handler
+
+ .weak CAN0_TX_IRQHandler
+ .thumb_set CAN0_TX_IRQHandler,Default_Handler
+
+ .weak CAN0_RX0_IRQHandler
+ .thumb_set CAN0_RX0_IRQHandler,Default_Handler
+
+ .weak CAN0_RX1_IRQHandler
+ .thumb_set CAN0_RX1_IRQHandler,Default_Handler
+
+ .weak CAN0_EWMC_IRQHandler
+ .thumb_set CAN0_EWMC_IRQHandler,Default_Handler
+
+ .weak EXTI5_9_IRQHandler
+ .thumb_set EXTI5_9_IRQHandler,Default_Handler
+
+ .weak TIMER0_BRK_TIMER8_IRQHandler
+ .thumb_set TIMER0_BRK_TIMER8_IRQHandler,Default_Handler
+
+ .weak TIMER0_UP_TIMER9_IRQHandler
+ .thumb_set TIMER0_UP_TIMER9_IRQHandler,Default_Handler
+
+ .weak TIMER0_TRG_CMT_TIMER10_IRQHandler
+ .thumb_set TIMER0_TRG_CMT_TIMER10_IRQHandler,Default_Handler
+
+ .weak TIMER0_Channel_IRQHandler
+ .thumb_set TIMER0_Channel_IRQHandler,Default_Handler
+
+ .weak TIMER1_IRQHandler
+ .thumb_set TIMER1_IRQHandler,Default_Handler
+
+ .weak TIMER2_IRQHandler
+ .thumb_set TIMER2_IRQHandler,Default_Handler
+
+ .weak TIMER3_IRQHandler
+ .thumb_set TIMER3_IRQHandler,Default_Handler
+
+ .weak I2C0_EV_IRQHandler
+ .thumb_set I2C0_EV_IRQHandler,Default_Handler
+
+ .weak I2C0_ER_IRQHandler
+ .thumb_set I2C0_ER_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak SPI0_IRQHandler
+ .thumb_set SPI0_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak USART0_IRQHandler
+ .thumb_set USART0_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak EXTI10_15_IRQHandler
+ .thumb_set EXTI10_15_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBFS_WKUP_IRQHandler
+ .thumb_set USBFS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIMER7_BRK_TIMER11_IRQHandler
+ .thumb_set TIMER7_BRK_TIMER11_IRQHandler,Default_Handler
+
+ .weak TIMER7_UP_TIMER12_IRQHandler
+ .thumb_set TIMER7_UP_TIMER12_IRQHandler,Default_Handler
+
+ .weak TIMER7_TRG_CMT_TIMER13_IRQHandler
+ .thumb_set TIMER7_TRG_CMT_TIMER13_IRQHandler,Default_Handler
+
+ .weak TIMER7_Channel_IRQHandler
+ .thumb_set TIMER7_Channel_IRQHandler,Default_Handler
+
+ .weak EXMC_IRQHandler
+ .thumb_set EXMC_IRQHandler,Default_Handler
+
+ .weak TIMER4_IRQHandler
+ .thumb_set TIMER4_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak UART3_IRQHandler
+ .thumb_set UART3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak TIMER5_IRQHandler
+ .thumb_set TIMER5_IRQHandler,Default_Handler
+
+ .weak TIMER6_IRQHandler
+ .thumb_set TIMER6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel0_IRQHandler
+ .thumb_set DMA1_Channel0_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_EWMC_IRQHandler
+ .thumb_set CAN1_EWMC_IRQHandler,Default_Handler
+
+ .weak USBFS_IRQHandler
+ .thumb_set USBFS_IRQHandler,Default_Handler
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_IAR/gd32e103vb.icf b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_IAR/gd32e103vb.icf
new file mode 100644
index 0000000000..b92876d0e1
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_IAR/gd32e103vb.icf
@@ -0,0 +1,37 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+
+if (!isdefinedsymbol(MBED_APP_START)) { define symbol MBED_APP_START = 0x08000000; }
+if (!isdefinedsymbol(MBED_APP_SIZE)) { define symbol MBED_APP_SIZE = 0x20000; }
+if (!isdefinedsymbol(MBED_BOOT_STACK_SIZE)) { define symbol MBED_BOOT_STACK_SIZE = 0x400; }
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = MBED_APP_START;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START;
+define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1;
+define symbol __ICFEDIT_region_NVIC_start__ = 0x20000000;
+define symbol __ICFEDIT_region_NVIC_end__ = 0x2000014F;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000150;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
+/*-Sizes-*/
+/*Heap 1/4 of ram and stack 1/8*/
+define symbol __ICFEDIT_size_cstack__ = MBED_BOOT_STACK_SIZE;
+define symbol __ICFEDIT_size_heap__ = 0x2000;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block HEAP, block CSTACK };
\ No newline at end of file
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_IAR/startup_gd32e10x.S b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_IAR/startup_gd32e10x.S
new file mode 100644
index 0000000000..9bbc5e7ae3
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/TOOLCHAIN_IAR/startup_gd32e10x.S
@@ -0,0 +1,517 @@
+;/*!
+; \file startup_gd32f30x_cl.S
+; \brief start up file
+;
+; \version 2017-12-26, V1.0.0, firmware for GD32E10x
+; \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+;*/
+;
+;/*
+; Copyright (c) 2018, GigaDevice Semiconductor Inc.
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+;are permitted provided that the following conditions are met:
+;
+; 1. Redistributions of source code must retain the above copyright notice, this
+; list of conditions and the following disclaimer.
+; 2. 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.
+; 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
+;*/
+
+ 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_IRQHandler ; 18:Tamper through EXTI Line detect
+ DCD RTC_IRQHandler ; 19:RTC 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 ADC0_1_IRQHandler ; 34:ADC0 and ADC1
+ 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_Channel_IRQHandler ; 43:TIMER0 Channel 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_Channel_IRQHandler ; 62:TIMER7 Channel Capture Compare
+ DCD 0 ; 63:Reserved
+ DCD EXMC_IRQHandler ; 64:EXMC
+ DCD 0 ; 65:Reserved
+ DCD TIMER4_IRQHandler ; 66:TIMER4
+ DCD SPI2_IRQHandler ; 67:SPI2
+ DCD UART3_IRQHandler ; 68:UART3
+ DCD UART4_IRQHandler ; 69:UART4
+ DCD TIMER5_IRQHandler ; 70:TIMER5
+ 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 0 ; 77:Reserved
+ DCD 0 ; 78:Reserved
+ 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
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; 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_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+RTC_IRQHandler
+ B RTC_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 ADC0_1_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+ADC0_1_IRQHandler
+ B ADC0_1_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_Channel_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_Channel_IRQHandler
+ B TIMER0_Channel_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_Channel_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER7_Channel_IRQHandler
+ B TIMER7_Channel_IRQHandler
+
+ PUBWEAK EXMC_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+EXMC_IRQHandler
+ B EXMC_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_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER5_IRQHandler
+ B TIMER5_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 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
+ END
\ No newline at end of file
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/cmsis.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/cmsis.h
new file mode 100644
index 0000000000..2b920cabeb
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/cmsis.h
@@ -0,0 +1,38 @@
+/* mbed Microcontroller Library
+ * A generic CMSIS include header
+
+ Copyright (c) 2018, GigaDevice Semiconductor Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 MBED_CMSIS_H
+#define MBED_CMSIS_H
+
+#include "gd32e10x.h"
+#include "cmsis_nvic.h"
+
+#endif /* MBED_CMSIS_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/cmsis_nvic.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/cmsis_nvic.h
new file mode 100644
index 0000000000..3cea459539
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/cmsis_nvic.h
@@ -0,0 +1,41 @@
+/* mbed Microcontroller Library
+ * CMSIS-style functionality to support dynamic vectors
+ *******************************************************************************
+ * Copyright (c) 2011 ARM Limited. All rights reserved.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of ARM Limited 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 THE COPYRIGHT HOLDER OR 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 MBED_CMSIS_NVIC_H
+#define MBED_CMSIS_NVIC_H
+
+#define NVIC_NUM_VECTORS (16 + 68) /* ARM CORE:16 Vectors; MCU Peripherals:68 Vectors */
+#define NVIC_RAM_VECTOR_ADDRESS 0x20000000
+
+
+#endif /* MBED_CMSIS_NVIC_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/gd32e10x.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/gd32e10x.h
new file mode 100644
index 0000000000..ec94545ff4
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/gd32e10x.h
@@ -0,0 +1,283 @@
+/*!
+ \file gd32e10x.h
+ \brief general definitions for GD32E10x
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_H
+#define GD32E10X_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* define GD32E10X */
+#if !defined (GD32E10X)
+#define GD32E10X
+#endif /* define GD32E10x */
+#if !defined (GD32E10X)
+#error "Please select the target GD32E10X device used in your application (in gd32e10x.h file)"
+#endif /* undefine GD32E10X tip */
+
+/* define value of high speed crystal oscillator (HXTAL) in Hz */
+#if !defined HXTAL_VALUE
+#define HXTAL_VALUE ((uint32_t)8000000) /*!< value of the external oscillator in Hz */
+#define HXTAL_VALUE_8M HXTAL_VALUE
+#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 48MHz RC oscillator (IRC48M) in Hz */
+#if !defined (IRC48M_VALUE)
+#define IRC48M_VALUE ((uint32_t)48000000)
+#endif /* internal 48MHz RC oscillator value */
+
+/* define value of internal 8MHz RC oscillator (IRC8M) in Hz */
+#if !defined (IRC8M_VALUE)
+#define IRC8M_VALUE ((uint32_t)8000000)
+#endif /* internal 8MHz RC oscillator value */
+
+/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */
+#if !defined (IRC8M_STARTUP_TIMEOUT)
+#define IRC8M_STARTUP_TIMEOUT ((uint16_t)0x0500)
+#endif /* internal 8MHz RC oscillator startup timeout */
+
+/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */
+#if !defined (IRC40K_VALUE)
+#define IRC40K_VALUE ((uint32_t)40000)
+#endif /* internal 40KHz 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 */
+
+/* GD32E10x firmware library version number V1.0 */
+#define __GD32E10x_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */
+#define __GD32E10x_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
+#define __GD32E10x_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
+#define __GD32E10x_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __GD32E10x_STDPERIPH_VERSION ((__GD32E10x_STDPERIPH_VERSION_MAIN << 24)\
+ |(__GD32E10x_STDPERIPH_VERSION_SUB1 << 16)\
+ |(__GD32E10x_STDPERIPH_VERSION_SUB2 << 8)\
+ |(__GD32E10x_STDPERIPH_VERSION_RC))
+
+/* configuration of the Cortex-M4 processor and core peripherals */
+#define __CM4_REV 0x0001 /*!< Core revision r0p1 */
+#define __MPU_PRESENT 0 /*!< GD32E10x do not provide MPU */
+#define __NVIC_PRIO_BITS 4 /*!< GD32E10x 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_IRQn = 2, /*!< tamper through EXTI line detect */
+ RTC_IRQn = 3, /*!< RTC 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 */
+ ADC0_1_IRQn = 18, /*!< ADC0 and ADC1 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_Channel_IRQn = 27, /*!< TIMER0 channel 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_Channel_IRQn = 46, /*!< TIMER7 channel capture compare interrupts */
+ EXMC_IRQn = 48, /*!< EXMC global interrupt */
+ TIMER4_IRQn = 50, /*!< TIMER4 global interrupt */
+ SPI2_IRQn = 51, /*!< SPI2 global interrupt */
+ UART3_IRQn = 52, /*!< UART3 global interrupt */
+ UART4_IRQn = 53, /*!< UART4 global interrupt */
+ TIMER5_IRQn = 54, /*!< TIMER5 global interrupt */
+ TIMER6_IRQn = 55, /*!< TIMER6 global interrupt */
+ DMA1_Channel0_IRQn = 56, /*!< DMA1 channel0 global interrupt */
+ DMA1_Channel1_IRQn = 57, /*!< DMA1 channel1 global interrupt */
+ DMA1_Channel2_IRQn = 58, /*!< DMA1 channel2 global interrupt */
+ DMA1_Channel3_IRQn = 59, /*!< DMA1 channel3 global interrupt */
+ DMA1_Channel4_IRQn = 60, /*!< DMA1 channel3 global 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 global interrupt */
+
+} IRQn_Type;
+
+/* includes */
+#include "core_cm4.h"
+#include "system_gd32e10x.h"
+#include
+
+#define GD_MBED_USED
+
+#ifdef GD_MBED_USED
+typedef enum {
+ GD_OK = 0x00U,
+ GD_ERROR = 0x01U,
+ GD_BUSY = 0x02U,
+ GD_TIMEOUT = 0x03U
+} gd_status_enum;
+
+typedef enum {
+ OP_STATE_RESET = 0x00U,
+ OP_STATE_READY = 0x01U,
+ OP_STATE_BUSY = 0x02U,
+ OP_STATE_TIMEOUT = 0x03U,
+ OP_STATE_ERROR = 0x04U,
+ OP_STATE_ABORT = 0x05U,
+ OP_STATE_LISTEN = 0x06U,
+
+ OP_STATE_BUSY_TX = 0x21U, /* (OP_STATE_BUSY << 4) + 1 */
+ OP_STATE_BUSY_RX = 0x22U, /* (OP_STATE_BUSY << 4) + 2 */
+
+ OP_STATE_BUSY_TX_LISTEN = 0x61U, /* (OP_STATE_LISTEN << 4) + 1 */
+ OP_STATE_BUSY_RX_LISTEN = 0x62U, /* (OP_STATE_LISTEN << 4) + 2 */
+
+ OP_STATE_BUTT
+} operation_state_enum;
+#endif
+
+/* enum definitions */
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
+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 SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM0 base address */
+#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */
+#define DBG_BASE ((uint32_t)0xE0042000U) /*!< DBG base address */
+#define EXMC_BASE ((uint32_t)0xA0000000U) /*!< EXMC register 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)0x40018000U) /*!< ahb1 base address */
+#define AHB3_BUS_BASE ((uint32_t)0x60000000U) /*!< ahb3 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 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 USBD_BASE (APB1_BUS_BASE + 0x00005C00U) /*!< USBD base address */
+#define CAN_BASE (APB1_BUS_BASE + 0x00006400U) /*!< CAN base address */
+#define BKP_BASE (APB1_BUS_BASE + 0x00006C00U) /*!< BKP base address */
+#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */
+#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */
+#define CTC_BASE (APB1_BUS_BASE + 0x0000C800U) /*!< CTC base address */
+
+/* advanced peripheral bus 2 memory map */
+#define AFIO_BASE (APB2_BUS_BASE + 0x00000000U) /*!< AFIO base address */
+#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */
+#define GPIO_BASE (APB2_BUS_BASE + 0x00000800U) /*!< GPIO base address */
+#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */
+
+/* advanced high performance bus 1 memory map */
+#define DMA_BASE (AHB1_BUS_BASE + 0x00008000U) /*!< DMA base address */
+#define RCU_BASE (AHB1_BUS_BASE + 0x00009000U) /*!< RCU base address */
+#define FMC_BASE (AHB1_BUS_BASE + 0x0000A000U) /*!< FMC base address */
+#define CRC_BASE (AHB1_BUS_BASE + 0x0000B000U) /*!< CRC base address */
+#define USBFS_BASE (AHB1_BUS_BASE + 0x0FFE8000U) /*!< USBFS base address */
+
+/* define marco USE_STDPERIPH_DRIVER */
+#if !defined USE_STDPERIPH_DRIVER
+#define USE_STDPERIPH_DRIVER
+#endif
+#ifdef USE_STDPERIPH_DRIVER
+#include "gd32e10x_libopt.h"
+#endif /* USE_STDPERIPH_DRIVER */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/gd32e10x_libopt.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/gd32e10x_libopt.h
new file mode 100644
index 0000000000..73750c46b1
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/gd32e10x_libopt.h
@@ -0,0 +1,64 @@
+/*!
+ \file gd32e10x_libopt.h
+ \brief library optional for gd32e10x
+
+ \version 2017-12-26, V1.0.0, firmware for GD32E10x
+ \version 2018-12-20, V1.1.0, firmware for GD32E10x(The version is for mbed)
+*/
+
+/*
+ Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 GD32E10X_LIBOPT_H
+#define GD32E10X_LIBOPT_H
+
+#include "gd32e10x_rcu.h"
+#include "gd32e10x_adc.h"
+#include "gd32e10x_can.h"
+#include "gd32e10x_crc.h"
+#include "gd32e10x_ctc.h"
+#include "gd32e10x_dac.h"
+#include "gd32e10x_dbg.h"
+#include "gd32e10x_dma.h"
+#include "gd32e10x_exti.h"
+#include "gd32e10x_fmc.h"
+#include "gd32e10x_fwdgt.h"
+#include "gd32e10x_gpio.h"
+#include "gd32e10x_i2c.h"
+#include "gd32e10x_pmu.h"
+#include "gd32e10x_bkp.h"
+#include "gd32e10x_rtc.h"
+#include "gd32e10x_spi.h"
+#include "gd32e10x_timer.h"
+#include "gd32e10x_usart.h"
+#include "gd32e10x_wwdgt.h"
+#include "gd32e10x_misc.h"
+#include "gd32e10x_exmc.h"
+
+#endif /* GD32E10X_LIBOPT_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/hal_tick.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/hal_tick.h
new file mode 100644
index 0000000000..047174ccde
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/hal_tick.h
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __HAL_TICK_H
+#define __HAL_TICK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gd32e10x.h"
+#include "cmsis_nvic.h"
+
+#define TICKER_TIMER TIMER2
+#define TICKER_TIMER_IRQ TIMER2_IRQn
+#define TICKER_TIMER_RCU_CLOCK_ENABLE rcu_periph_clock_enable(RCU_TIMER2);
+#define TICKER_TIMER_DEBUG_STOP dbg_periph_enable(DBG_TIMER2_HOLD);
+
+#define TICKER_TIMER_RESET_ENABLE rcu_periph_reset_enable(RCU_TIMER2RST)
+#define TICKER_TIMER_RESET_DISABLE rcu_periph_reset_disable(RCU_TIMER2RST)
+
+/* 16 for 16-bit timer, 32 for 32-bit timer */
+#define TICKER_TIMER_WIDTH_BIT 16
+
+/* 0 for CK_APB1, 1 for CK_APB2 */
+#define TICKER_TIMER_CKAPB 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HAL_TICK_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/system_gd32e10x.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/system_gd32e10x.c
new file mode 100644
index 0000000000..d5f61a82bf
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/system_gd32e10x.c
@@ -0,0 +1,847 @@
+/*!
+ \file system_gd32e10x.c
+ \brief CMSIS Cortex-M4 Device Peripheral Access Layer Source File for
+ GD32E10x 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:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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 "gd32e10x.h"
+
+/* system frequency define */
+#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */
+#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
+#define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */
+
+/* Vector Table base offset */
+#define VECT_TAB_OFFSET 0x00 /* This value must be a multiple of 0x200. */
+
+/* select a system clock by uncommenting the following line */
+/* use IRC8M */
+//#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M)
+//#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000)
+//#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000)
+//#define __SYSTEM_CLOCK_108M_PLL_IRC8M (uint32_t)(108000000)
+//#define __SYSTEM_CLOCK_120M_PLL_IRC8M (uint32_t)(120000000)
+
+/* use HXTAL(CK_HXTAL = 8M) */
+//#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL)
+//#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000)
+//#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
+//#define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000)
+#define __SYSTEM_CLOCK_120M_PLL_HXTAL (uint32_t)(120000000)
+
+#define SEL_IRC8M 0x00U
+#define SEL_HXTAL 0x01U
+#define SEL_PLL 0x02U
+
+/* set the system clock frequency and declare the system clock configuration function */
+#ifdef __SYSTEM_CLOCK_IRC8M
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC8M;
+static void system_clock_8m_irc8m(void);
+#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_IRC8M;
+static void system_clock_48m_irc8m(void);
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M;
+static void system_clock_72m_irc8m(void);
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_IRC8M;
+static void system_clock_108m_irc8m(void);
+#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_IRC8M;
+static void system_clock_120m_irc8m(void);
+
+#elif defined (__SYSTEM_CLOCK_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
+static void system_clock_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_HXTAL;
+static void system_clock_48m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL;
+static void system_clock_72m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_HXTAL;
+static void system_clock_108m_hxtal(void);
+#elif defined (__SYSTEM_CLOCK_120M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_HXTAL;
+static void system_clock_120m_hxtal(void);
+#endif /* __SYSTEM_CLOCK_IRC8M */
+
+/* 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 RCU clock configuration to the default reset state */
+ /* Set IRC8MEN bit */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+
+ /* Reset CFG0 and CFG1 registers */
+ RCU_CFG0 = 0x00000000U;
+ RCU_CFG1 = 0x00000000U;
+
+ /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
+ RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
+ /* disable all interrupts */
+ RCU_INT = 0x00ff0000U;
+
+ /* reset HXTALBPS bit */
+ RCU_CTL &= ~(RCU_CTL_HXTALBPS);
+
+ /* configure the system clock source, PLL Multiplier, 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_IRC8M
+ system_clock_8m_irc8m();
+#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
+ system_clock_48m_irc8m();
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
+ system_clock_72m_irc8m();
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
+ system_clock_108m_irc8m();
+#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
+ system_clock_120m_irc8m();
+
+#elif defined (__SYSTEM_CLOCK_HXTAL)
+ system_clock_hxtal();
+#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
+ system_clock_48m_hxtal();
+#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
+ system_clock_72m_hxtal();
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+ system_clock_108m_hxtal();
+#elif defined (__SYSTEM_CLOCK_120M_PLL_HXTAL)
+ system_clock_120m_hxtal();
+#endif /* __SYSTEM_CLOCK_IRC8M */
+}
+
+#ifdef __SYSTEM_CLOCK_IRC8M
+/*!
+ \brief configure the system clock to 8M by IRC8M
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_8m_irc8m(void)
+{
+ uint32_t timeout = 0U;
+ uint32_t stab_flag = 0U;
+
+ /* enable IRC8M */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+
+ /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
+ do {
+ timeout++;
+ stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
+ } while ((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
+
+ /* if fail */
+ if (0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
+ while (1) {
+ }
+ }
+
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* select IRC8M as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_IRC8M;
+
+ /* wait until IRC8M is selected as system clock */
+ while (0U != (RCU_CFG0 & RCU_SCSS_IRC8M)) {
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
+/*!
+ \brief configure the system clock to 48M by PLL which selects IRC8M as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_48m_irc8m(void)
+{
+ uint32_t timeout = 0U;
+ uint32_t stab_flag = 0U;
+
+ /* enable IRC8M */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+
+ /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
+ do {
+ timeout++;
+ stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
+ } while ((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
+
+ /* if fail */
+ if (0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
+ while (1) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_1;
+
+ /* IRC8M is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_IRC8M/2) * 12 = 48 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= RCU_PLL_MUL12;
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
+/*!
+ \brief configure the system clock to 72M by PLL which selects IRC8M as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_72m_irc8m(void)
+{
+ uint32_t timeout = 0U;
+ uint32_t stab_flag = 0U;
+
+ /* enable IRC8M */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+
+ /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
+ do {
+ timeout++;
+ stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
+ } while ((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
+
+ /* if fail */
+ if (0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
+ while (1) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_2;
+
+ /* IRC8M is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_IRC8M/2) * 18 = 72 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= RCU_PLL_MUL18;
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
+/*!
+ \brief configure the system clock to 108M by PLL which selects IRC8M as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_108m_irc8m(void)
+{
+ uint32_t timeout = 0U;
+ uint32_t stab_flag = 0U;
+
+ /* enable IRC8M */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+
+ /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
+ do {
+ timeout++;
+ stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
+ } while ((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
+
+ /* if fail */
+ if (0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
+ while (1) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_3;
+
+ /* IRC8M is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_IRC8M/2) * 27 = 108 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= RCU_PLL_MUL27;
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
+/*!
+ \brief configure the system clock to 120M by PLL which selects IRC8M as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_120m_irc8m(void)
+{
+ uint32_t timeout = 0U;
+ uint32_t stab_flag = 0U;
+
+ /* enable IRC8M */
+ RCU_CTL |= RCU_CTL_IRC8MEN;
+
+ /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
+ do {
+ timeout++;
+ stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
+ } while ((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
+
+ /* if fail */
+ if (0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
+ while (1) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_3;
+
+ /* IRC8M is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_IRC8M/2) * 30 = 120 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= RCU_PLL_MUL30;
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+#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/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* 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_48M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 48M by PLL which selects HXTAL(8M) as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_48m_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) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_1;
+
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_PREDIV0) * 12 = 48 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL12);
+
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
+#ifdef HXTAL_VALUE_8M
+ /* CK_PREDIV0 = (CK_HXTAL)/2 *10 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL10 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV10);
+#elif defined (HXTAL_VALUE_25M)
+ /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
+#endif
+
+ /* enable PLL1 */
+ RCU_CTL |= RCU_CTL_PLL1EN;
+ /* wait till PLL1 is ready */
+ while ((RCU_CTL & RCU_CTL_PLL1STB) == 0) {
+ }
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 72M by PLL which selects HXTAL(8M) as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_72m_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) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_2;
+
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL18);
+
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
+#ifdef HXTAL_VALUE_8M
+ /* CK_PREDIV0 = (CK_HXTAL)/2 *10 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL10 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV10);
+#elif defined (HXTAL_VALUE_25M)
+ /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
+#endif
+
+ /* enable PLL1 */
+ RCU_CTL |= RCU_CTL_PLL1EN;
+ /* wait till PLL1 is ready */
+ while ((RCU_CTL & RCU_CTL_PLL1STB) == 0) {
+ }
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 108M by PLL which selects HXTAL(8M) as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_108m_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) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_3;
+
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_PREDIV0) * 27 = 108 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL27);
+
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
+#ifdef HXTAL_VALUE_8M
+ /* CK_PREDIV0 = (CK_HXTAL)/2 *10 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL10 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV10);
+#elif defined (HXTAL_VALUE_25M)
+ /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
+#endif
+ /* enable PLL1 */
+ RCU_CTL |= RCU_CTL_PLL1EN;
+ /* wait till PLL1 is ready */
+ while ((RCU_CTL & RCU_CTL_PLL1STB) == 0) {
+ }
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_120M_PLL_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_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) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_3;
+
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
+
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
+#ifdef HXTAL_VALUE_8M
+ /* CK_PREDIV0 = (CK_HXTAL)/2 *10 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL10 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV10);
+#elif defined (HXTAL_VALUE_25M)
+ /* CK_PREDIV0 = (CK_HXTAL)/5 *8/10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
+#endif
+
+ /* enable PLL1 */
+ RCU_CTL |= RCU_CTL_PLL1EN;
+ /* wait till PLL1 is ready */
+ while ((RCU_CTL & RCU_CTL_PLL1STB) == 0U) {
+ }
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+#endif /* __SYSTEM_CLOCK_IRC8M */
+
+/*!
+ \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 pllsel, pllpresel, predv0sel, pllmf, ck_src;
+ uint32_t predv0, predv1, pll1mf;
+
+ sws = GET_BITS(RCU_CFG0, 2, 3);
+ switch (sws) {
+ /* IRC8M is selected as CK_SYS */
+ case SEL_IRC8M:
+ SystemCoreClock = IRC8M_VALUE;
+ break;
+ /* HXTAL is selected as CK_SYS */
+ case SEL_HXTAL:
+ SystemCoreClock = HXTAL_VALUE;
+ break;
+ /* PLL is selected as CK_SYS */
+ case SEL_PLL:
+ /* PLL clock source selection, HXTAL, IRC48M or IRC8M/2 */
+ pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL);
+
+ if (RCU_PLLSRC_HXTAL_IRC48M == pllsel) {
+ /* PLL clock source is HXTAL or IRC48M */
+ pllpresel = (RCU_CFG1 & RCU_CFG1_PLLPRESEL);
+
+ if (RCU_PLLPRESRC_HXTAL == pllpresel) {
+ /* PLL clock source is HXTAL */
+ ck_src = HXTAL_VALUE;
+ } else {
+ /* PLL clock source is IRC48 */
+ ck_src = IRC48M_VALUE;
+ }
+
+ predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL);
+ /* source clock use PLL1 */
+ if (RCU_PREDV0SRC_CKPLL1 == predv0sel) {
+ predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> 4) + 1U;
+ pll1mf = ((RCU_CFG1 & RCU_CFG1_PLL1MF) >> 8) + 2U;
+ if (17U == pll1mf) {
+ pll1mf = 20U;
+ }
+ ck_src = (ck_src / predv1) * pll1mf;
+ }
+ predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U;
+ ck_src /= predv0;
+ } else {
+ /* PLL clock source is IRC8M/2 */
+ ck_src = IRC8M_VALUE / 2U;
+ }
+
+ /* PLL multiplication factor */
+ pllmf = GET_BITS(RCU_CFG0, 18, 21);
+ if ((RCU_CFG0 & RCU_CFG0_PLLMF_4)) {
+ pllmf |= 0x10U;
+ }
+ if (pllmf < 15U) {
+ pllmf += 2U;
+ } else {
+ pllmf += 1U;
+ }
+ SystemCoreClock = ck_src * pllmf;
+ if (15U == pllmf) {
+ SystemCoreClock = ck_src * 6U + ck_src / 2U;
+ }
+
+ break;
+ /* IRC8M is selected as CK_SYS */
+ default:
+ SystemCoreClock = IRC8M_VALUE;
+ break;
+ }
+
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/system_gd32e10x.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/system_gd32e10x.h
new file mode 100644
index 0000000000..3d37795f6d
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/device/system_gd32e10x.h
@@ -0,0 +1,58 @@
+/*!
+ \file system_gd32e10x.h
+ \brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for
+ GD32E10x 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_GD32E10X_H
+#define SYSTEM_GD32E10X_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+/* 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_GD32E10X_H */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/flash_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/flash_api.c
new file mode 100644
index 0000000000..eca873bb13
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/flash_api.c
@@ -0,0 +1,200 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flash_api.h"
+#include "mbed_critical.h"
+
+#if DEVICE_FLASH
+#include "cmsis.h"
+
+#define FLASH_SIZE (0x00020000U)
+#define FLASH_PAGE_SIZE (0x00000400U)
+#define FLASH_START_ADDR (0X08000000U)
+#define FLASH_END_ADDR (0x0801FFFFU)
+#define WORD_SIZE (4U)
+
+/* unlock the main FLASH operation
+ *
+ * @return 0 for success, -1 for error
+*/
+static int32_t flash_unlock(void)
+{
+ fmc_unlock();
+ if (RESET != (FMC_CTL & FMC_CTL_LK)) {
+ return -1;
+ }
+ return 0;
+}
+
+/* lock the main FLASH operation
+ *
+ * @return 0 for success, -1 for error
+*/
+static int32_t flash_lock(void)
+{
+ fmc_lock();
+ if (RESET == (FMC_CTL & FMC_CTL_LK)) {
+ return -1;
+ }
+ return 0;
+}
+
+/** Initialize the flash peripheral and the flash_t object
+ *
+ * @param obj The flash object
+ * @return 0 for success, -1 for error
+ */
+int32_t flash_init(flash_t *obj)
+{
+ return 0;
+}
+
+/** Uninitialize the flash peripheral and the flash_t object
+ *
+ * @param obj The flash object
+ * @return 0 for success, -1 for error
+ */
+int32_t flash_free(flash_t *obj)
+{
+ return 0;
+}
+
+/** Erase one sector starting at defined address
+ *
+ * The address should be at sector boundary. This function does not do any check for address alignments
+ * @param obj The flash object
+ * @param address The sector starting address
+ * @return 0 for success, -1 for error
+ */
+int32_t flash_erase_sector(flash_t *obj, uint32_t address)
+{
+ int32_t flash_state = 0;
+ flash_unlock();
+
+ /* clear FLASH flag */
+ fmc_flag_clear(FMC_FLAG_PGERR);
+ fmc_flag_clear(FMC_FLAG_PGAERR);
+ fmc_flag_clear(FMC_FLAG_WPERR);
+ fmc_flag_clear(FMC_FLAG_END);
+
+ /* make sure the address is a right page address */
+ if (FMC_READY != fmc_page_erase(address)) {
+ flash_state = -1;
+ }
+
+ flash_lock();
+ return flash_state;
+}
+
+/** Program pages starting at defined address
+ *
+ * The pages should not cross multiple sectors.
+ * This function does not do any check for address alignments or if size is aligned to a page size.
+ * @param obj The flash object
+ * @param address The sector starting address
+ * @param data The data buffer to be programmed
+ * @param size The number of bytes to program
+ * @return 0 for success, -1 for error
+ */
+int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
+{
+ uint32_t *p_data;
+ p_data = (uint32_t *)data;
+ uint32_t num = 0;
+ int32_t flash_state = 0;
+ flash_unlock();
+
+ /* clear FLASH flag */
+ fmc_flag_clear(FMC_FLAG_PGERR);
+ fmc_flag_clear(FMC_FLAG_PGAERR);
+ fmc_flag_clear(FMC_FLAG_WPERR);
+ fmc_flag_clear(FMC_FLAG_END);
+
+ if (size % 4) {
+ num = size / 4 + 1;
+ } else {
+ num = size / 4;
+ }
+ for (uint32_t i = 0; i < num; i++) {
+
+ if (FMC_READY != fmc_word_program(address, *(p_data + i))) {
+ flash_state = -1;
+ break;
+ }
+ address += 4;
+ }
+ flash_lock();
+ return flash_state;
+}
+
+/** Get sector size
+ *
+ * @param obj The flash object
+ * @param address The sector starting address
+ * @return The size of a sector
+ */
+uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
+{
+ if ((FLASH_START_ADDR > address) || (FLASH_END_ADDR < address)) {
+ return MBED_FLASH_INVALID_SIZE;
+ }
+ return FLASH_PAGE_SIZE;
+}
+
+/** Get page size
+ *
+ * The page size defines the writable page size
+ * @param obj The flash object
+ * @return The size of a page
+ */
+uint32_t flash_get_page_size(const flash_t *obj)
+{
+ return WORD_SIZE;
+}
+
+/** Get start address for the flash region
+ *
+ * @param obj The flash object
+ * @return The start address for the flash region
+ */
+uint32_t flash_get_start_address(const flash_t *obj)
+{
+ return FLASH_START_ADDR;
+}
+
+/** Get the flash region size
+ *
+ * @param obj The flash object
+ * @return The flash region size
+ */
+uint32_t flash_get_size(const flash_t *obj)
+{
+ return FLASH_SIZE;
+}
+
+/** Get the flash erase value
+ *
+ * @param obj The flash object
+ * @return The flash erase value
+ */
+uint8_t flash_get_erase_value(const flash_t *obj)
+{
+ return 0xFF;
+}
+
+#endif /* DEVICE_FLASH */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/gpio_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/gpio_api.c
new file mode 100644
index 0000000000..c31a160629
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/gpio_api.c
@@ -0,0 +1,151 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "gd32e10x_gpio.h"
+#include "mbed_assert.h"
+#include "gpio_api.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+
+extern const int GD_GPIO_REMAP[];
+extern const int GD_GPIO_SPEED[];
+extern const int GD_GPIO_MODE[];
+
+/* Enable GPIO clock and return GPIO base address */
+uint32_t gpio_clock_enable(uint32_t port_idx)
+{
+ uint32_t gpio_add = 0;
+ switch (port_idx) {
+ case PORTA:
+ gpio_add = GPIOA;
+ rcu_periph_clock_enable(RCU_GPIOA);
+ break;
+ case PORTB:
+ gpio_add = GPIOB;
+ rcu_periph_clock_enable(RCU_GPIOB);
+ break;
+ case PORTC:
+ gpio_add = GPIOC;
+ rcu_periph_clock_enable(RCU_GPIOC);
+ break;
+ case PORTD:
+ gpio_add = GPIOD;
+ rcu_periph_clock_enable(RCU_GPIOD);
+ break;
+ case PORTE:
+ gpio_add = GPIOE;
+ rcu_periph_clock_enable(RCU_GPIOE);
+ break;
+ default:
+ error("port number not exist");
+ break;
+ }
+ return gpio_add;
+}
+
+/** Set the given pin as GPIO
+ *
+ * @param pin The pin to be set as GPIO
+ * @return The GPIO port mask for this pin
+ */
+uint32_t gpio_set(PinName pin)
+{
+
+ MBED_ASSERT(pin != (PinName)NC);
+ pin_function(pin, MODE_IN_FLOATING);
+ /* return pin mask */
+ return (uint32_t)(1 << ((uint32_t)pin & 0xF));
+}
+
+/** Initialize the GPIO pin
+ *
+ * @param obj The GPIO object to initialize
+ * @param pin The GPIO pin to initialize
+ */
+void gpio_init(gpio_t *obj, PinName pin)
+{
+ obj->pin = pin;
+ if (pin == (PinName)NC) {
+ return;
+ }
+ /* fill struct parameter for future use */
+ uint32_t port_index = GD_PORT_GET(pin);
+ uint32_t gpio = gpio_clock_enable(port_index);
+ obj->mask = gpio_set(pin);
+ obj->gpio_periph = gpio;
+}
+
+/** Set the input pin mode
+ *
+ * @param obj The GPIO object
+ * @param mode The pin mode to be set
+ */
+void gpio_mode(gpio_t *obj, PinMode mode)
+{
+ pin_mode(obj->pin, mode);
+}
+
+/** Set the output value
+ *
+ * @param obj The GPIO object
+ * @param value The value to be set
+ */
+void gpio_write(gpio_t *obj, int value)
+{
+ /* set or reset GPIO pin */
+ if (value) {
+ GPIO_BOP(obj->gpio_periph) = (1 << (uint32_t)GD_PIN_GET(obj->pin));
+ } else {
+ GPIO_BC(obj->gpio_periph) = (1 << (uint32_t)GD_PIN_GET(obj->pin));
+ }
+}
+
+/** Read the input value
+ *
+ * @param obj The GPIO object
+ * @return An integer value 1 or 0
+ */
+int gpio_read(gpio_t *obj)
+{
+ /* return state of GPIO pin */
+ return ((GPIO_ISTAT(obj->gpio_periph) & obj->mask) ? 1 : 0);
+}
+
+/* Checks if gpio object is connected (pin was not initialized with NC)
+ * @param pin The pin to be set as GPIO
+ * @return 0 if port is initialized with NC
+ **/
+int gpio_is_connected(const gpio_t *obj)
+{
+ return obj->pin != (PinName)NC;
+}
+
+/** Set the pin direction
+ *
+ * @param obj The GPIO object
+ * @param direction The pin direction to be set
+ */
+void gpio_dir(gpio_t *obj, PinDirection direction)
+{
+
+ /* config GPIO pin as input or output */
+ if (direction == PIN_INPUT) {
+ gpio_para_init(obj->gpio_periph, GD_GPIO_MODE[MODE_IN_FLOATING], GD_GPIO_SPEED[0], (1 << (uint32_t)GD_PIN_GET(obj->pin)));
+ } else {
+ gpio_para_init(obj->gpio_periph, GD_GPIO_MODE[MODE_OUT_PP], GD_GPIO_SPEED[0], (1 << (uint32_t)GD_PIN_GET(obj->pin)));
+ }
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/gpio_irq_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/gpio_irq_api.c
new file mode 100644
index 0000000000..c48633977e
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/gpio_irq_api.c
@@ -0,0 +1,330 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include "cmsis.h"
+#include "gpio_irq_api.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+
+#define EDGE_NONE (0)
+#define EDGE_RISE (1)
+#define EDGE_FALL (2)
+
+extern uint32_t gpio_clock_enable(uint32_t port_idx);
+static gpio_irq_handler irq_handler;
+
+typedef struct {
+ uint32_t exti_idx;
+ uint32_t exti_gpiox; /* base address of gpio */
+ uint32_t exti_pinx; /* pin number */
+} gpio_exti_info_struct;
+
+/* EXTI0...EXTI15 */
+static gpio_exti_info_struct exti_info_array[16] = {0};
+
+/** handle EXTI interrupt in EXTI0 to EXTI15
+
+ * @param irq_index the line of EXTI(0~15)
+ */
+static void exti_handle_interrupt(uint32_t irq_index)
+{
+ gpio_exti_info_struct *gpio_exti = &exti_info_array[irq_index];
+
+ /* get the port and pin of EXTI */
+ uint32_t gpio = (uint32_t)(gpio_exti->exti_gpiox);
+ uint32_t pin = (uint32_t)(1 << (gpio_exti->exti_pinx));
+
+ /* clear interrupt flag */
+ if (exti_interrupt_flag_get((exti_line_enum)pin) != RESET) {
+ exti_interrupt_flag_clear((exti_line_enum)pin);
+ /* check which edge has generated the irq */
+ if ((GPIO_ISTAT(gpio) & pin) == 0) {
+ irq_handler(gpio_exti->exti_idx, IRQ_FALL);
+ } else {
+ irq_handler(gpio_exti->exti_idx, IRQ_RISE);
+ }
+ }
+
+}
+
+/* EXTI0 interrupt handler */
+static void gpio_irq_exti0(void)
+{
+ exti_handle_interrupt(0);
+}
+/* EXTI1 interrupt handler */
+static void gpio_irq_exti1(void)
+{
+ exti_handle_interrupt(1);
+}
+/* EXTI2 interrupt handler */
+static void gpio_irq_exti2(void)
+{
+ exti_handle_interrupt(2);
+}
+/* EXTI3 interrupt handler */
+static void gpio_irq_exti3(void)
+{
+ exti_handle_interrupt(3);
+}
+/* EXTI4 interrupt handler */
+static void gpio_irq_exti4(void)
+{
+ exti_handle_interrupt(4);
+}
+/* EXTI5 interrupt handler */
+static void gpio_irq_exti5(void)
+{
+ exti_handle_interrupt(5);
+}
+/* EXTI6 interrupt handler */
+static void gpio_irq_exti6(void)
+{
+ exti_handle_interrupt(6);
+}
+/* EXTI7 interrupt handler */
+static void gpio_irq_exti7(void)
+{
+ exti_handle_interrupt(7);
+}
+/* EXTI8 interrupt handler */
+static void gpio_irq_exti8(void)
+{
+ exti_handle_interrupt(8);
+}
+/* EXTI9 interrupt handler */
+static void gpio_irq_exti9(void)
+{
+ exti_handle_interrupt(9);
+}
+/* EXTI10 interrupt handler */
+static void gpio_irq_exti10(void)
+{
+ exti_handle_interrupt(10);
+}
+/* EXTI11 interrupt handler */
+static void gpio_irq_exti11(void)
+{
+ exti_handle_interrupt(11);
+}
+/* EXTI12 interrupt handler */
+static void gpio_irq_exti12(void)
+{
+ exti_handle_interrupt(12);
+}
+/* EXTI13 interrupt handler */
+static void gpio_irq_exti13(void)
+{
+ exti_handle_interrupt(13);
+}
+/* EXTI14 interrupt handler */
+static void gpio_irq_exti14(void)
+{
+ exti_handle_interrupt(14);
+}
+/* EXTI15 interrupt handler */
+static void gpio_irq_exti15(void)
+{
+ exti_handle_interrupt(15);
+}
+
+/** Initialize the GPIO IRQ pin
+ *
+ * @param obj The GPIO object to initialize
+ * @param pin The GPIO pin name
+ * @param handler The handler to be attached to GPIO IRQ
+ * @param id The object ID (id != 0, 0 is reserved)
+ * @return -1 if pin is NC, 0 otherwise
+ */
+int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
+{
+ uint32_t vector = 0;
+ gpio_exti_info_struct *gpio_exti;
+ if (pin == NC) {
+ return -1;
+ }
+
+ /* Enable AF Clock */
+ rcu_periph_clock_enable(RCU_AF);
+
+ uint32_t port_index = GD_PORT_GET(pin);
+ uint32_t pin_index = GD_PIN_GET(pin);
+ /* Enable GPIO clock */
+ uint32_t gpio_add = gpio_clock_enable(port_index);
+
+ /* fill EXTI information according to pin_index .
+ eg. use PORTE_9 as EXTI interrupt, the irq type is EXTI5_9_IRQn */
+ if (pin_index == 0) {
+ vector = (uint32_t)&gpio_irq_exti0;
+ obj->irq_index = 0;
+ obj->irq_n = EXTI0_IRQn;
+ } else if (pin_index == 1) {
+ vector = (uint32_t)&gpio_irq_exti1;
+ obj->irq_index = 1;
+ obj->irq_n = EXTI1_IRQn;
+ } else if (pin_index == 2) {
+ vector = (uint32_t)&gpio_irq_exti2;
+ obj->irq_index = 2;
+ obj->irq_n = EXTI2_IRQn;
+ } else if (pin_index == 3) {
+ vector = (uint32_t)&gpio_irq_exti3;
+ obj->irq_index = 3;
+ obj->irq_n = EXTI3_IRQn;
+ } else if (pin_index == 4) {
+ vector = (uint32_t)&gpio_irq_exti4;
+ obj->irq_index = 4;
+ obj->irq_n = EXTI4_IRQn;
+ } else if (pin_index == 5) {
+ vector = (uint32_t)&gpio_irq_exti5;
+ obj->irq_index = 5;
+ obj->irq_n = EXTI5_9_IRQn;
+ } else if (pin_index == 6) {
+ vector = (uint32_t)&gpio_irq_exti6;
+ obj->irq_index = 6;
+ obj->irq_n = EXTI5_9_IRQn;
+ } else if (pin_index == 7) {
+ vector = (uint32_t)&gpio_irq_exti7;
+ obj->irq_index = 7;
+ obj->irq_n = EXTI5_9_IRQn;
+ } else if (pin_index == 8) {
+ vector = (uint32_t)&gpio_irq_exti8;
+ obj->irq_index = 8;
+ obj->irq_n = EXTI5_9_IRQn;
+ } else if (pin_index == 9) {
+ vector = (uint32_t)&gpio_irq_exti9;
+ obj->irq_index = 9;
+ obj->irq_n = EXTI5_9_IRQn;
+ } else if (pin_index == 10) {
+ vector = (uint32_t)&gpio_irq_exti10;
+ obj->irq_index = 10;
+ obj->irq_n = EXTI10_15_IRQn;
+ } else if (pin_index == 11) {
+ vector = (uint32_t)&gpio_irq_exti11;
+ obj->irq_index = 11;
+ obj->irq_n = EXTI10_15_IRQn;
+ } else if (pin_index == 12) {
+ vector = (uint32_t)&gpio_irq_exti12;
+ obj->irq_index = 12;
+ obj->irq_n = EXTI10_15_IRQn;
+ } else if (pin_index == 13) {
+ vector = (uint32_t)&gpio_irq_exti13;
+ obj->irq_index = 13;
+ obj->irq_n = EXTI10_15_IRQn;
+ } else if (pin_index == 14) {
+ vector = (uint32_t)&gpio_irq_exti14;
+ obj->irq_index = 14;
+ obj->irq_n = EXTI10_15_IRQn;
+ } else if (pin_index == 15) {
+ vector = (uint32_t)&gpio_irq_exti15;
+ obj->irq_index = 15;
+ obj->irq_n = EXTI10_15_IRQn;
+ } else {
+ error("pin not supported for interrupt in.\n");
+ return -1;
+ }
+
+ /* Save informations for future use */
+ obj->event = EDGE_NONE;
+ obj->pin = pin;
+
+ gpio_exti = &exti_info_array[obj->irq_index];
+ gpio_exti->exti_idx = id;
+ gpio_exti->exti_gpiox = gpio_add;
+ gpio_exti->exti_pinx = pin_index;
+
+ irq_handler = handler;
+
+ /* Enable EXTI interrupt */
+ NVIC_SetVector(obj->irq_n, vector);
+ gpio_irq_enable(obj);
+
+ return 0;
+}
+
+/** Release the GPIO IRQ PIN
+ *
+ * @param obj The gpio object
+ */
+void gpio_irq_free(gpio_irq_t *obj)
+{
+ gpio_exti_info_struct *gpio_exti = &exti_info_array[obj->irq_index];
+
+ /* Disable EXTI interrupt */
+ gpio_irq_disable(obj);
+ /* Reset struct of exti information */
+ gpio_exti->exti_idx = 0;
+ gpio_exti->exti_gpiox = 0;
+ gpio_exti->exti_pinx = 0;
+}
+
+/** Enable/disable pin IRQ event
+ *
+ * @param obj The GPIO object
+ * @param event The GPIO IRQ event
+ * @param enable The enable flag
+ */
+void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
+{
+ if (event == IRQ_RISE) {
+ if (enable) {
+ exti_init((exti_line_enum)(1 << GD_PIN_GET(obj->pin)), EXTI_INTERRUPT, EXTI_TRIG_RISING);
+ /* Clear interrupt enable bit, rising/falling bit */
+ } else {
+ EXTI_INTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
+ EXTI_RTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
+ EXTI_FTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
+ }
+ }
+ if (event == IRQ_FALL) {
+ if (enable) {
+ exti_init((exti_line_enum)(1 << (GD_PIN_GET(obj->pin))), EXTI_INTERRUPT, EXTI_TRIG_FALLING);
+ /* Clear interrupt enable bit, rising/falling bit */
+ } else {
+ EXTI_INTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
+ EXTI_RTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
+ EXTI_FTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
+ }
+ }
+}
+
+/** Enable GPIO IRQ
+ *
+ * This is target dependent, as it might enable the entire port or just a pin
+ * @param obj The GPIO object
+ */
+void gpio_irq_enable(gpio_irq_t *obj)
+{
+ /* Select EXTI Source */
+ gpio_exti_source_select(GD_PORT_GET(obj->pin), GD_PIN_GET(obj->pin));
+ exti_interrupt_enable((exti_line_enum)(1 << GD_PIN_GET(obj->pin)));
+ NVIC_EnableIRQ(obj->irq_n);
+}
+
+/** Disable GPIO IRQ
+ *
+ * This is target dependent, as it might disable the entire port or just a pin
+ * @param obj The GPIO object
+ */
+void gpio_irq_disable(gpio_irq_t *obj)
+{
+ /* Clear EXTI line configuration */
+ exti_interrupt_disable((exti_line_enum)(1 << GD_PIN_GET(obj->pin)));
+ NVIC_DisableIRQ(obj->irq_n);
+ NVIC_ClearPendingIRQ(obj->irq_n);
+ obj->event = EDGE_NONE;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/i2c_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/i2c_api.c
new file mode 100644
index 0000000000..4ecdb15438
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/i2c_api.c
@@ -0,0 +1,657 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed_assert.h"
+#include "i2c_api.h"
+
+#if DEVICE_I2C
+
+#include "cmsis.h"
+#include "pinmap.h"
+#include "PeripheralPins.h"
+
+#if DEVICE_I2C_ASYNCH
+#define I2C_S(obj) (struct i2c_s *) (&((obj)->i2c))
+#else
+#define I2C_S(obj) (struct i2c_s *) (obj)
+#endif
+
+#define BUSY_TIMEOUT ((SystemCoreClock / obj_s->freq) * 2 * 10)
+#define FLAG_TIMEOUT (0xF0000U)
+
+/** Reset I2C peripheral by hardware method. Most of the implementation enable RCU reset.
+ *
+ * @param obj The I2C object
+ */
+static void i2c_hw_reset(i2c_t *obj)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ switch (obj_s->i2c) {
+ case I2C_0:
+ rcu_periph_reset_enable(RCU_I2C0RST);
+ rcu_periph_reset_disable(RCU_I2C0RST);
+ break;
+
+ case I2C_1:
+ rcu_periph_reset_enable(RCU_I2C1RST);
+ rcu_periph_reset_disable(RCU_I2C1RST);
+ break;
+ }
+}
+
+/** Initialize the I2C peripheral. It sets the default parameters for I2C
+ * peripheral, and configures its specifieds pins.
+ *
+ * @param obj The I2C object
+ * @param sda The sda pin
+ * @param scl The scl pin
+ */
+void i2c_init(i2c_t *obj, PinName sda, PinName scl)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ /* find the I2C by pins */
+ uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
+ uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
+
+ obj_s->sda = sda;
+ obj_s->scl = scl;
+ obj_s->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
+ MBED_ASSERT(obj_s->i2c != (I2CName)NC);
+
+ switch (obj_s->i2c) {
+ case I2C_0:
+ /* enable I2C0 clock and configure the pins of I2C0 */
+ obj_s->index = 0;
+ rcu_periph_clock_enable(RCU_I2C0);
+
+ break;
+
+ case I2C_1:
+ /* enable I2C1 clock and configure the pins of I2C1 */
+ obj_s->index = 1;
+ rcu_periph_clock_enable(RCU_I2C1);
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* configure the pins of I2C */
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+
+ /* 100 KHz as the default I2C frequence */
+ i2c_frequency(obj, 100000);
+
+ obj_s->state = (operation_state_enum)I2C_STATE_NONE;
+ obj_s->previous_state_mode = I2C_STATE_NONE;
+ obj_s->global_trans_option = I2C_FIRST_AND_LAST_FRAME;
+
+#if DEVICE_I2CSLAVE
+ /* I2C master by default */
+ obj_s->slave = 0;
+#endif
+}
+
+/** Configure the I2C frequency
+ *
+ * @param obj The I2C object
+ * @param hz Frequency in Hz
+ */
+void i2c_frequency(i2c_t *obj, int hz)
+{
+ int timeout;
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ /* wait until I2C_FLAG_I2CBSY flag is reset */
+ timeout = BUSY_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) && (--timeout != 0));
+
+ /* reset to clear pending flags */
+ i2c_hw_reset(obj);
+
+ /* disable I2C peripheral */
+ i2c_disable(obj_s->i2c);
+
+ /* configure I2C frequence */
+ i2c_clock_config(obj_s->i2c, hz, I2C_DTCY_2);
+
+ /* configure I2C address mode and slave address */
+ i2c_mode_addr_config(obj_s->i2c, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0);
+
+ /* enable I2C peripheral */
+ i2c_enable(obj_s->i2c);
+}
+
+/** Reset I2C peripheral. TODO: The action here. Most of the implementation sends stop()
+ *
+ * @param obj The I2C object
+ */
+void i2c_reset(i2c_t *obj)
+{
+ i2c_stop(obj);
+}
+
+/** Send START command
+ *
+ * @param obj The I2C object
+ */
+int i2c_start(i2c_t *obj)
+{
+ int timeout;
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ /* clear I2C_FLAG_AERR Flag */
+ i2c_flag_clear(obj_s->i2c, I2C_FLAG_AERR);
+
+ /* wait until I2C_FLAG_I2CBSY flag is reset */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) == SET) {
+ if ((timeout--) == 0) {
+ return (int)GD_BUSY;
+ }
+ }
+
+ /* ensure the i2c has been stopped */
+ timeout = FLAG_TIMEOUT;
+ while ((I2C_CTL0(obj_s->i2c) & I2C_CTL0_STOP) == I2C_CTL0_STOP) {
+ if ((timeout--) == 0) {
+ return (int)GD_ERROR;
+ }
+ }
+
+ /* generate a START condition */
+ i2c_start_on_bus(obj_s->i2c);
+
+ /* ensure the i2c has been started successfully */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_SBSEND)) == RESET) {
+ if ((timeout--) == 0) {
+ return (int)GD_ERROR;
+ }
+ }
+
+ return (int)GD_OK;
+}
+
+/** Send STOP command
+ *
+ * @param obj The I2C object
+ */
+int i2c_stop(i2c_t *obj)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ /* generate a STOP condition */
+ i2c_stop_on_bus(obj_s->i2c);
+
+ /* wait for STOP bit reset */
+ while ((I2C_CTL0(obj_s->i2c) & I2C_CTL0_STOP));
+
+ return 0;
+}
+
+/** Read one byte
+ *
+ * @param obj The I2C object
+ * @param last Acknoledge
+ * @return The read byte
+ */
+int i2c_byte_read(i2c_t *obj, int last)
+{
+ int timeout;
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ if (last) {
+ /* disable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
+ } else {
+ /* enable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+ }
+
+ /* wait until the byte is received */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE)) == RESET) {
+ if ((timeout--) == 0) {
+ return -1;
+ }
+ }
+
+ return (int)I2C_DATA(obj_s->i2c);
+}
+
+/** Write one byte
+ *
+ * @param obj The I2C object
+ * @param data Byte to be written
+ * @return 0 if NAK was received, 1 if ACK was received, 2 for timeout.
+ */
+int i2c_byte_write(i2c_t *obj, int data)
+{
+ int timeout;
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ I2C_DATA(obj_s->i2c) = (uint8_t)data;
+
+ /* wait until the byte is transmitted */
+ timeout = FLAG_TIMEOUT;
+ while (((i2c_flag_get(obj_s->i2c, I2C_FLAG_TBE)) == RESET) &&
+ ((i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC)) == RESET)) {
+ if ((timeout--) == 0) {
+ return 2;
+ }
+ }
+
+ return 1;
+}
+
+/** Blocking reading data
+ *
+ * @param obj The I2C object
+ * @param address 7-bit address (last bit is 1)
+ * @param data The buffer for receiving
+ * @param length Number of bytes to read
+ * @param stop Stop to be generated after the transfer is done
+ * @return Number of read bytes
+ */
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+ uint32_t count = 0U;
+ int timeout = 0;
+
+ if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME ||
+ obj_s->global_trans_option == I2C_LAST_FRAME) {
+ if (stop) {
+ obj_s->global_trans_option = I2C_FIRST_AND_LAST_FRAME;
+ } else {
+ obj_s->global_trans_option = I2C_FIRST_FRAME;
+ }
+ } else if (obj_s->global_trans_option == I2C_FIRST_FRAME ||
+ obj_s->global_trans_option == I2C_NEXT_FRAME) {
+ if (stop) {
+ obj_s->global_trans_option = I2C_LAST_FRAME;
+ } else {
+ obj_s->global_trans_option = I2C_NEXT_FRAME;
+ }
+ }
+
+ if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME) {
+ /* wait until I2C_FLAG_I2CBSY flag is reset */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) == SET) {
+ if ((timeout--) == 0) {
+ i2c_stop(obj);
+ return I2C_ERROR_BUS_BUSY;
+ }
+ }
+ }
+
+ if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME ||
+ obj_s->previous_state_mode != I2C_STATE_MASTER_BUSY_RX) {
+ /* generate a START condition */
+ i2c_start_on_bus(obj_s->i2c);
+
+ /* ensure the i2c has been started successfully */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_SBSEND)) == RESET) {
+ if ((timeout--) == 0) {
+ i2c_stop(obj);
+ return I2C_ERROR_BUS_BUSY;
+ }
+ }
+
+ /* send slave address */
+ i2c_master_addressing(obj_s->i2c, address, I2C_RECEIVER);
+
+ if (1 == length) {
+ /* disable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
+ /* send a stop condition to I2C bus*/
+ } else if (2 == length) {
+ /* send a NACK for the next data byte which will be received into the shift register */
+ i2c_ackpos_config(obj_s->i2c, I2C_ACKPOS_NEXT);
+ /* disable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
+ } else {
+ /* enable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+ }
+
+ timeout = 0;
+ /* wait until I2C_FLAG_ADDSEND flag is set */
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
+ timeout++;
+ if (timeout > 100000) {
+ i2c_stop(obj);
+ return I2C_ERROR_NO_SLAVE;
+ }
+ }
+
+ /* clear ADDSEND */
+ i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
+ }
+
+ obj_s->state = (operation_state_enum)I2C_STATE_MASTER_BUSY_RX;
+
+ for (count = 0; count < length; count++) {
+ if (length > 2 && count == length - 3) {
+ while (RESET == i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC));
+ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
+ } else if (2 == length && count == 0) {
+ while (RESET == i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC));
+ }
+
+ while (RESET == i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE));
+ data[count] = i2c_data_receive(obj_s->i2c);
+ }
+
+ obj_s->previous_state_mode = obj_s->state;
+
+ /* if not sequential read, then send stop */
+ if (stop) {
+ i2c_stop(obj);
+ }
+
+ return count;
+}
+
+/** Blocking sending data
+ *
+ * @param obj The I2C object
+ * @param address 7-bit address (last bit is 0)
+ * @param data The buffer for sending
+ * @param length Number of bytes to write
+ * @param stop Stop to be generated after the transfer is done
+ * @return
+ * zero or non-zero - Number of written bytes
+ * negative - I2C_ERROR_XXX status
+ */
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+ gd_status_enum status = GD_OK;
+ uint32_t count = 0;
+ int timeout = 0;
+
+ if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME ||
+ obj_s->global_trans_option == I2C_LAST_FRAME) {
+ if (stop) {
+ obj_s->global_trans_option = I2C_FIRST_AND_LAST_FRAME;
+ } else {
+ obj_s->global_trans_option = I2C_FIRST_FRAME;
+ }
+ } else if (obj_s->global_trans_option == I2C_FIRST_FRAME ||
+ obj_s->global_trans_option == I2C_NEXT_FRAME) {
+ if (stop) {
+ obj_s->global_trans_option = I2C_LAST_FRAME;
+ } else {
+ obj_s->global_trans_option = I2C_NEXT_FRAME;
+ }
+ }
+
+ if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME) {
+ /* wait until I2C_FLAG_I2CBSY flag is reset */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) == SET) {
+ if ((timeout--) == 0) {
+ i2c_stop(obj);
+ return I2C_ERROR_BUS_BUSY;
+ }
+ }
+ }
+
+ if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME ||
+ obj_s->previous_state_mode != I2C_STATE_MASTER_BUSY_TX) {
+ /* generate a START condition */
+ i2c_start_on_bus(obj_s->i2c);
+
+ /* ensure the i2c has been started successfully */
+ timeout = FLAG_TIMEOUT;
+ while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_SBSEND)) == RESET) {
+ if ((timeout--) == 0) {
+ i2c_stop(obj);
+ return I2C_ERROR_BUS_BUSY;
+ }
+ }
+
+ /* send slave address */
+ i2c_master_addressing(obj_s->i2c, address, I2C_TRANSMITTER);
+
+ timeout = 0;
+ /* wait until I2C_FLAG_ADDSEND flag is set */
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
+ timeout++;
+ if (timeout > 100000) {
+ i2c_stop(obj);
+ return I2C_ERROR_NO_SLAVE;
+ }
+ }
+
+ /* clear ADDSEND */
+ i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
+ }
+
+ obj_s->state = (operation_state_enum)I2C_STATE_MASTER_BUSY_TX;
+
+ for (count = 0; count < length; count++) {
+ status = (gd_status_enum)i2c_byte_write(obj, data[count]);
+ if (status != 1) {
+ i2c_stop(obj);
+ return count;
+ }
+ }
+
+ obj_s->previous_state_mode = obj_s->state;
+
+ /* if not sequential write, then send stop */
+ if (stop) {
+ i2c_stop(obj);
+ }
+
+ return count;
+}
+
+#if DEVICE_I2CSLAVE
+
+/** Configure I2C address.
+ * @param obj The I2C object
+ * @param idx Currently not used
+ * @param address The address to be set
+ * @param mask Currently not used
+ */
+void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ /* disable I2C peripheral */
+ i2c_disable(obj_s->i2c);
+ /* I2C clock configure */
+ i2c_clock_config(obj_s->i2c, 100000, I2C_DTCY_2);
+ /* I2C address configure */
+ i2c_mode_addr_config(obj_s->i2c, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, address);
+ /* enable I2C0 */
+ i2c_enable(obj_s->i2c);
+ /* enable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+}
+
+/** Configure I2C as slave or master.
+ * @param obj The I2C object
+ * @param enable_slave Enable i2c hardware so you can receive events with ::i2c_slave_receive
+ * @return non-zero if a value is available
+ */
+void i2c_slave_mode(i2c_t *obj, int enable_slave)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+
+ if (enable_slave) {
+ obj_s->slave = 1;
+ } else {
+ obj_s->slave = 0;
+ }
+}
+
+/* the same as the definition in I2CSlave.h class I2CSlave */
+#define NoData 0 /* the slave has not been addressed */
+#define ReadAddressed 1 /* the master has requested a read from this slave (slave as transmitter) */
+#define WriteGeneral 2 /* the master is writing to all slave */
+#define WriteAddressed 3 /* the master is writing to this slave (slave as receiver) */
+
+/** Check to see if the I2C slave has been addressed.
+ * @param obj The I2C object
+ * @return The status - 1 - read addresses, 2 - write to all slaves,
+ * 3 write addressed, 0 - the slave has not been addressed
+ */
+int i2c_slave_receive(i2c_t *obj)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+ int ret = NoData;
+
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+
+ if (i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+ if (i2c_flag_get(obj_s->i2c, I2C_FLAG_RXGC)) {
+ ret = WriteGeneral;
+ }
+
+ if (i2c_flag_get(obj_s->i2c, I2C_FLAG_TRS)) {
+ ret = ReadAddressed;
+ } else {
+ ret = WriteAddressed;
+ }
+ }
+
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+
+ return (ret);
+}
+
+/** Configure I2C as slave or master.
+ * @param obj The I2C object
+ * @param data The buffer for receiving
+ * @param length Number of bytes to read
+ * @return non-zero if a value is available
+ */
+int i2c_slave_read(i2c_t *obj, char *data, int length)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+ int count = 0;
+ int timeout = 0;
+
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+
+ /* wait until ADDSEND bit is set */
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
+ timeout++;
+ if (timeout > 100000) {
+ return -1;
+ }
+ }
+ /* clear ADDSEND bit */
+ i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
+
+ while (0 < length) {
+ /* wait until the RBNE bit is set */
+ timeout = 0;
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE)) {
+ timeout++;
+ if (timeout > 100000) {
+ return -1;
+ }
+ }
+ *data = i2c_data_receive(obj_s->i2c);
+ data++;
+ length--;
+ count++;
+ }
+ /* wait until the STPDET bit is set */
+ timeout = 0;
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_STPDET)) {
+ timeout++;
+ if (timeout > 100) {
+ return count;
+ }
+ }
+ /* clear the STPDET bit */
+ i2c_enable(obj_s->i2c);
+
+ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
+
+ return count;
+}
+
+/** Configure I2C as slave or master.
+ * @param obj The I2C object
+ * @param data The buffer for sending
+ * @param length Number of bytes to write
+ * @return non-zero if a value is available
+ */
+int i2c_slave_write(i2c_t *obj, const char *data, int length)
+{
+ struct i2c_s *obj_s = I2C_S(obj);
+ int count = 0;
+ int timeout = 0;
+
+ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
+ /* wait until ADDSEND bit is set */
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
+ timeout++;
+ if (timeout > 100000) {
+ return -1;
+ }
+ }
+ /* clear ADDSEND bit */
+ i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
+ while (length > 0) {
+ /* wait until the TBE bit is set */
+ timeout = 0;
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_TBE)) {
+ timeout++;
+ if (timeout > 100000) {
+ return -1;
+ }
+ }
+ i2c_data_transmit(obj_s->i2c, *data);
+ data++;
+ length--;
+ count++;
+ }
+ /* the master doesn't acknowledge for the last byte */
+ timeout = 0;
+ while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_AERR)) {
+ timeout++;
+ if (timeout > 100000) {
+ return -1;
+ }
+ }
+ /* clear the bit of AERR */
+ i2c_flag_clear(obj_s->i2c, I2C_FLAG_AERR);
+ /* disable acknowledge */
+ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
+
+ return count;
+}
+#endif /* DEVICE_I2CSLAVE */
+
+#endif /* DEVICE_I2C */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/mbed_overrides.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/mbed_overrides.c
new file mode 100644
index 0000000000..7182028b13
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/mbed_overrides.c
@@ -0,0 +1,62 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "gd32e10x.h"
+#include "cmsis.h"
+#include "hal_tick.h"
+
+int mbed_sdk_inited = 0;
+
+/*!
+ \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
+*/
+#if TICKER_TIMER_WIDTH_BIT == 16
+extern void ticker_16bits_timer_init(void);
+#else
+extern void ticker_32bits_timer_init(void);
+#endif
+
+/**
+ * SDK hook for running code before ctors or OS
+ *
+ * This is a weak function which can be overridden by a target's
+ * SDK to allow code to run after ram is initialized but before
+ * the OS has been started or constructors have run.
+ *
+ * Preconditions:
+ * - Ram is initialized
+ * - NVIC is setup
+ */
+/**
+ * This function is called after RAM initialization and before main.
+ */
+void mbed_sdk_init()
+{
+ nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
+
+ /* configure 1ms tick */
+#if TICKER_TIMER_WIDTH_BIT == 16
+ ticker_16bits_timer_init();
+#else
+ ticker_32bits_timer_init();
+#endif
+
+ mbed_sdk_inited = 1;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/objects.h b/targets/TARGET_GigaDevice/TARGET_GD32E10X/objects.h
new file mode 100644
index 0000000000..f2ed68a521
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/objects.h
@@ -0,0 +1,183 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_OBJECTS_H
+#define MBED_OBJECTS_H
+
+#include "cmsis.h"
+#include "PortNames.h"
+#include "PeripheralNames.h"
+#include "PinNames.h"
+#include "mbed_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct gpio_s gpio_t;
+
+struct gpio_s {
+ uint32_t mask;
+ PinName pin;
+ __IO uint32_t gpio_periph;
+};
+
+struct gpio_irq_s {
+ IRQn_Type irq_n;
+ uint32_t irq_index;
+ uint32_t event;
+ PinName pin;
+};
+
+struct port_s {
+ PortName port;
+ uint32_t mask;
+ PinDirection direction;
+ __IO uint32_t *reg_in;
+ __IO uint32_t *reg_out;
+};
+
+struct analogin_s {
+ ADCName adc;
+ PinName pin;
+ uint8_t channel;
+};
+
+#if DEVICE_ANALOGOUT
+struct dac_s {
+ DACName dac;
+ PinName pin;
+ uint32_t channel;
+};
+#endif
+
+struct can_s {
+ CANName can;
+ int index;
+};
+
+struct pwmout_s {
+ PWMName pwm;
+ uint32_t cnt_unit;
+ uint8_t ch;
+};
+
+struct serial_s {
+ /* basic information */
+ UARTName uart;
+ int index;
+ PinName pin_tx;
+ PinName pin_rx;
+
+ /* configure information */
+ uint32_t baudrate;
+ uint32_t databits;
+ uint32_t stopbits;
+ uint32_t parity;
+
+ /* operating parameters */
+ uint16_t rx_size;
+ uint8_t *tx_buffer_ptr;
+ uint8_t *rx_buffer_ptr;
+ __IO uint16_t tx_count;
+ __IO uint16_t rx_count;
+
+ __IO uint32_t error_code;
+ __IO operation_state_enum tx_state;
+ __IO operation_state_enum rx_state;
+
+#if DEVICE_SERIAL_ASYNCH
+ uint32_t events;
+#endif
+#if DEVICE_SERIAL_FC
+ uint32_t hw_flow_ctl;
+ PinName pin_rts;
+ PinName pin_cts;
+#endif
+};
+
+struct spi_s {
+ spi_parameter_struct spi_struct;
+ IRQn_Type spi_irq;
+ SPIName spi;
+ PinName pin_miso;
+ PinName pin_mosi;
+ PinName pin_sclk;
+ PinName pin_ssel;
+};
+
+struct i2c_s {
+ /* basic information */
+ I2CName i2c;
+ uint8_t index;
+ PinName sda;
+ PinName scl;
+ int i2c_inited; /* flag used to indicate whether the i2c has been initialized */
+
+ /* configure information */
+ int freq; /* i2c frequence */
+ uint32_t addr_bit_mode; /* 7 bits or 10 bits */
+ uint32_t slave_addr0;
+ uint32_t slave_addr1;
+ uint16_t transfer_size;
+ uint8_t *buffer_pointer;
+
+ /* operating parameters */
+ __IO operation_state_enum state;
+ __IO i2c_mode_enum mode;
+ __IO uint32_t previous_state_mode;
+ __IO uint32_t i2c_target_dev_addr;
+ __IO uint32_t event_count;
+ __IO uint32_t transfer_count;
+ __IO uint32_t transfer_option;
+ __IO uint32_t error_code;
+
+ /* I2C DMA information */
+ uint32_t tx_dma_periph;
+ dma_channel_enum tx_dma_channel;
+ uint32_t rx_dma_periph;
+ dma_channel_enum rx_dma_channel;
+
+ IRQn_Type event_i2cIRQ;
+ IRQn_Type error_i2cIRQ;
+ uint32_t global_trans_option;
+ volatile uint8_t event;
+
+#if DEVICE_I2CSLAVE
+ uint8_t slave;
+ volatile uint8_t pending_slave_tx_master_rx;
+ volatile uint8_t pending_slave_rx_maxter_tx;
+#endif
+
+#if DEVICE_I2C_ASYNCH
+ uint32_t address;
+ uint8_t stop;
+ uint8_t available_events;
+#endif
+
+};
+#if DEVICE_FLASH
+struct flash_s {
+ /* nothing to be stored for now */
+ uint32_t dummy;
+};
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/pinmap.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/pinmap.c
new file mode 100644
index 0000000000..eeed668420
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/pinmap.c
@@ -0,0 +1,135 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "pinmap.h"
+#include "PortNames.h"
+#include "mbed_error.h"
+
+extern uint32_t gpio_clock_enable(uint32_t port_idx);
+
+extern const int GD_GPIO_REMAP[];
+extern const int GD_GPIO_MODE[];
+extern const int GD_GPIO_SPEED[];
+
+static void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pin);
+
+/** Configure pin (mode, speed, reamp function )
+ *
+ * @param pin gpio pin name
+ * @param function gpio pin mode, speed, remap function
+ */
+void pin_function(PinName pin, int function)
+{
+ MBED_ASSERT(pin != (PinName)NC);
+
+ uint32_t mode = GD_PIN_MODE_GET(function);
+ uint32_t remap = GD_PIN_REMAP_GET(function);
+ uint32_t speed = GD_PIN_SPEED_GET(function);
+ uint32_t port = GD_PORT_GET(pin);
+ uint32_t gd_pin = 1 << GD_PIN_GET(pin);
+
+ uint32_t gpio = gpio_clock_enable(port);
+ gpio_para_init(gpio, GD_GPIO_MODE[mode], GD_GPIO_SPEED[speed], gd_pin);
+
+ if (remap != 0) {
+ rcu_periph_clock_enable(RCU_AF);
+ gpio_pin_remap_config(GD_GPIO_REMAP[remap], ENABLE);
+ }
+}
+
+/** Only configure pin mode
+ *
+ * @param pin gpio pin name
+ * @param function gpio pin mode
+ */
+void pin_mode(PinName pin, PinMode mode)
+{
+ MBED_ASSERT(pin != (PinName)NC);
+ uint32_t port = GD_PORT_GET(pin);
+ uint32_t gd_pin = 1 << GD_PIN_GET(pin);
+
+ uint32_t gpio = gpio_clock_enable(port);
+ if (mode != PullNone) {
+ gpio_mode_set(gpio, GD_GPIO_MODE[mode], gd_pin);
+ }
+}
+
+/** configure gpio pin mode
+ *
+ * @param gpio_periph gpio port name
+ * @param mode gpio pin mode
+ * @param pin gpio pin number
+ */
+static void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pin)
+{
+ uint16_t i;
+ uint32_t temp_mode = 0U;
+ uint32_t reg = 0U;
+
+ /* GPIO mode configuration */
+ temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
+
+ /* configure the eight low port pins with GPIO_CTL0 */
+ for (i = 0U; i < 8U; i++) {
+ if ((1U << i) & pin) {
+ reg = GPIO_CTL0(gpio_periph);
+
+ /* set the specified pin mode bits */
+ reg |= GPIO_MODE_SET(i, temp_mode);
+
+ /* set IPD or IPU */
+ if (GPIO_MODE_IPD == mode) {
+ /* reset the corresponding OCTL bit */
+ GPIO_BC(gpio_periph) = (uint32_t)pin;
+ } else {
+ /* set the corresponding OCTL bit */
+ if (GPIO_MODE_IPU == mode) {
+ GPIO_BOP(gpio_periph) = (uint32_t)pin;
+ }
+ }
+
+ /* set GPIO_CTL0 register */
+ GPIO_CTL0(gpio_periph) = reg;
+ }
+ }
+ /* configure the eight high port pins with GPIO_CTL1 */
+ for (i = 8U; i < 16U; i++) {
+ if ((1U << i) & pin) {
+ reg = GPIO_CTL1(gpio_periph);
+
+ /* set the specified pin mode bits */
+ reg |= GPIO_MODE_SET(i - 8U, temp_mode);
+
+ /* set IPD or IPU */
+ if (GPIO_MODE_IPD == mode) {
+ /* reset the corresponding OCTL bit */
+ GPIO_BC(gpio_periph) = (uint32_t)pin;
+ } else {
+ /* set the corresponding OCTL bit */
+ if (GPIO_MODE_IPU == mode) {
+ GPIO_BOP(gpio_periph) = (uint32_t)pin;
+ }
+ }
+
+ /* set GPIO_CTL1 register */
+ GPIO_CTL1(gpio_periph) = reg;
+ }
+ }
+}
+
+
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/port_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/port_api.c
new file mode 100644
index 0000000000..75f959be15
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/port_api.c
@@ -0,0 +1,120 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "port_api.h"
+#include "pinmap.h"
+#include "gpio_api.h"
+#include "mbed_error.h"
+
+#if DEVICE_PORTIN || DEVICE_PORTOUT
+
+extern uint32_t gpio_clock_enable(uint32_t port_idx);
+
+/** Get the pin name from the port's pin number
+ *
+ * @param port The port name
+ * @param pin_n The pin number within the specified port
+ * @return The pin name for the port's pin number
+ * BIT[7:4] port number
+ BIT[3:0] pin number
+ */
+PinName port_pin(PortName port, int pin_n)
+{
+ return (PinName)(pin_n + (port << 4));
+}
+
+/** Initilize the port
+ *
+ * @param obj The port object to initialize
+ * @param port The port name
+ * @param mask The bitmask to identify which bits in the port should be included (0 - ignore)
+ * @param dir The port direction
+ */
+void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
+{
+ uint32_t port_index = (uint32_t)port;
+ uint32_t gpio = gpio_clock_enable(port_index);
+
+ obj->port = port;
+ obj->mask = mask;
+ obj->direction = dir;
+ obj->reg_in = &GPIO_ISTAT(gpio);
+ obj->reg_out = &GPIO_OCTL(gpio);
+
+ port_dir(obj, dir);
+}
+
+/** Set port direction (in/out)
+ *
+ * @param obj The port object
+ * @param dir The port direction to be set
+ */
+void port_dir(port_t *obj, PinDirection dir)
+{
+ uint32_t i;
+ obj->direction = dir;
+ for (i = 0; i < 16; i++) {
+ if (obj->mask & (1 << i)) {
+ if (dir == PIN_OUTPUT) {
+ pin_function(port_pin(obj->port, i), MODE_OUT_PP);
+ } else {
+ pin_function(port_pin(obj->port, i), MODE_IN_FLOATING);
+ }
+ }
+ }
+}
+
+/** Set the input port mode
+ *
+ * @param obj The port object
+ * @param mode THe port mode to be set
+ */
+void port_mode(port_t *obj, PinMode mode)
+{
+ uint32_t i;
+ for (i = 0; i < 16; i++) {
+ if (obj->mask & (1 << i)) {
+ pin_mode(port_pin(obj->port, i), mode);
+ }
+ }
+}
+
+/** Write value to the port
+ *
+ * @param obj The port object
+ * @param value The value to be set
+ */
+void port_write(port_t *obj, int value)
+{
+ *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask);
+}
+
+/** Read the current value on the port
+ *
+ * @param obj The port object
+ * @return An integer with each bit corresponding to an associated port pin setting
+ */
+int port_read(port_t *obj)
+{
+ if (obj->direction == PIN_OUTPUT) {
+ return (*obj->reg_out & obj->mask);
+ } else {
+ return (*obj->reg_in & obj->mask);
+ }
+}
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/pwmout_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/pwmout_api.c
new file mode 100644
index 0000000000..af380c2974
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/pwmout_api.c
@@ -0,0 +1,299 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "pwmout_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+#include "PeripheralPins.h"
+
+#define DEV_PWMOUT_APB_MASK 0x00010000U
+#define DEV_PWMOUT_APB1 0U
+#define DEV_PWMOUT_APB2 1U
+
+static uint32_t timer_get_clock(uint32_t timer_periph);
+
+static void dev_pwmout_init(pwmout_t *obj)
+{
+ timer_oc_parameter_struct timer_ocintpara;
+ timer_parameter_struct timer_initpara;
+
+ MBED_ASSERT(obj);
+ uint32_t periph = obj->pwm;
+
+ switch (periph) {
+ case TIMER0:
+ rcu_periph_clock_enable(RCU_TIMER0);
+ break;
+
+ case TIMER1:
+ rcu_periph_clock_enable(RCU_TIMER1);
+ break;
+
+ case TIMER2:
+ rcu_periph_clock_enable(RCU_TIMER2);
+ break;
+
+ case TIMER3:
+ rcu_periph_clock_enable(RCU_TIMER3);
+ break;
+
+ case TIMER4:
+ rcu_periph_clock_enable(RCU_TIMER4);
+ break;
+
+ case TIMER7:
+ rcu_periph_clock_enable(RCU_TIMER7);
+ break;
+ case TIMER8:
+ rcu_periph_clock_enable(RCU_TIMER8);
+ break;
+
+ case TIMER9:
+ rcu_periph_clock_enable(RCU_TIMER9);
+ break;
+
+ case TIMER10:
+ rcu_periph_clock_enable(RCU_TIMER10);
+ break;
+
+ case TIMER11:
+ rcu_periph_clock_enable(RCU_TIMER11);
+ break;
+
+ case TIMER12:
+ rcu_periph_clock_enable(RCU_TIMER12);
+ break;
+
+ case TIMER13:
+ rcu_periph_clock_enable(RCU_TIMER13);
+ break;
+ }
+ /* configure TIMER base function */
+ timer_initpara.prescaler = 119;
+ timer_initpara.period = 9999;
+ timer_initpara.clockdivision = 0;
+ timer_initpara.counterdirection = TIMER_COUNTER_UP;
+ timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
+
+ timer_init(obj->pwm, &timer_initpara);
+
+ /* configure TIMER channel output function */
+ timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
+ timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
+ timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
+ timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
+ timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
+ timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
+ timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
+ timer_channel_output_config(obj->pwm, obj->ch, &timer_ocintpara);
+ timer_channel_output_mode_config(obj->pwm, obj->ch, TIMER_OC_MODE_PWM0);
+ timer_channel_output_fast_config(obj->pwm, obj->ch, TIMER_OC_FAST_DISABLE);
+
+ timer_primary_output_config(obj->pwm, ENABLE);
+}
+
+static uint8_t dev_pwmout_apb_check(uint32_t periph)
+{
+ uint8_t reval = DEV_PWMOUT_APB1;
+
+ /* check peripherals belongs to APB1 or APB2 */
+ if (DEV_PWMOUT_APB_MASK == (periph & DEV_PWMOUT_APB_MASK)) {
+ reval = DEV_PWMOUT_APB2;
+ }
+
+ return reval;
+}
+
+void pwmout_init(pwmout_t *obj, PinName pin)
+{
+ MBED_ASSERT(obj);
+
+ obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
+ MBED_ASSERT(obj->pwm != (PWMName)NC);
+
+ uint32_t function = pinmap_function(pin, PinMap_PWM);
+ MBED_ASSERT(function != (uint32_t)NC);
+ obj->ch = GD_PIN_CHANNEL_GET(function);
+ /* Peripheral initialization */
+ dev_pwmout_init(obj);
+ /* pin function initialization */
+ pinmap_pinout(pin, PinMap_PWM);
+}
+
+void pwmout_free(pwmout_t *obj)
+{
+ timer_channel_output_state_config(obj->pwm, obj->ch, TIMER_CCX_DISABLE);
+}
+
+void pwmout_write(pwmout_t *obj, float value)
+{
+ uint16_t period;
+ uint16_t pulse;
+
+ timer_disable(obj->pwm);
+ /* overflow protection */
+ if (value < (float)0.0) {
+ value = 0.0;
+ } else if (value > (float)1.0) {
+ value = 1.0;
+ }
+
+ period = TIMER_CAR(obj->pwm);
+ pulse = (uint16_t)(period * value);
+
+ timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
+
+ timer_enable(obj->pwm);
+}
+
+float pwmout_read(pwmout_t *obj)
+{
+ float value = 0;
+ uint16_t period;
+ uint16_t pulse;
+
+ period = TIMER_CAR(obj->pwm);
+
+ switch (obj->ch) {
+ case TIMER_CH_0:
+ pulse = TIMER_CH0CV(obj->pwm);
+ break;
+
+ case TIMER_CH_1:
+ pulse = TIMER_CH1CV(obj->pwm);
+ break;
+
+ case TIMER_CH_2:
+ pulse = TIMER_CH2CV(obj->pwm);
+ break;
+
+ case TIMER_CH_3:
+ pulse = TIMER_CH3CV(obj->pwm);
+ break;
+
+ default:
+ error("Error: pwm channel error! \r\n");
+ }
+
+ /* calculated waveform duty ratio */
+ value = (float)(pulse) / (float)(period);
+
+ if (value > (float)1.0) {
+ value = (float)1.0;
+ }
+
+ return value;
+}
+
+void pwmout_period(pwmout_t *obj, float seconds)
+{
+ pwmout_period_us(obj, seconds * 1000000.0f);
+}
+
+void pwmout_period_ms(pwmout_t *obj, int ms)
+{
+ pwmout_period_us(obj, ms * 1000);
+}
+
+void pwmout_period_us(pwmout_t *obj, int us)
+{
+
+ uint32_t ultemp = 0;
+ uint32_t timer_clk = 0;
+ uint32_t period = us - 1;
+ uint32_t prescaler;
+ float duty_ratio;
+
+ duty_ratio = pwmout_read(obj);
+
+ timer_disable(obj->pwm);
+
+ timer_clk = timer_get_clock(obj->pwm);
+
+ ultemp = (timer_clk / 1000000);
+ prescaler = ultemp;
+ obj->cnt_unit = 1;
+
+ while (period > 0xFFFF) {
+ obj->cnt_unit = obj->cnt_unit << 1;
+ period = period >> 1;
+ prescaler = ultemp * obj->cnt_unit;
+ }
+
+ if (prescaler > 0xFFFF) {
+ error("Error: TIMER prescaler value is overflow \r\n");
+ }
+
+ timer_autoreload_value_config(obj->pwm, period);
+ timer_prescaler_config(obj->pwm, prescaler - 1, TIMER_PSC_RELOAD_NOW);
+
+ ultemp = duty_ratio * us;
+
+ pwmout_pulsewidth_us(obj, ultemp);
+
+ timer_enable(obj->pwm);
+}
+
+void pwmout_pulsewidth(pwmout_t *obj, float seconds)
+{
+ pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
+}
+
+void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
+{
+ pwmout_pulsewidth_us(obj, ms * 1000);
+}
+
+void pwmout_pulsewidth_us(pwmout_t *obj, int us)
+{
+ uint32_t pulse;
+ uint32_t period;
+
+ period = TIMER_CAR(obj->pwm);
+ pulse = us / obj->cnt_unit;
+
+ if (pulse > period) {
+ pulse = period;
+ }
+
+ timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
+}
+
+static uint32_t timer_get_clock(uint32_t timer_periph)
+{
+ uint32_t timerclk;
+
+ if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph) ||
+ (TIMER8 == timer_periph) || (TIMER9 == timer_periph) || (TIMER10 == timer_periph)) {
+ /* get the current APB2 TIMER clock source */
+ if (RCU_APB2_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB2PSC)) {
+ timerclk = rcu_clock_freq_get(CK_APB2);
+ } else {
+ timerclk = rcu_clock_freq_get(CK_APB2) * 2;
+ }
+ } else {
+ /* get the current APB1 TIMER clock source */
+ if (RCU_APB1_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB1PSC)) {
+ timerclk = rcu_clock_freq_get(CK_APB1);
+ } else {
+ timerclk = rcu_clock_freq_get(CK_APB1) * 2;
+ }
+ }
+
+ return timerclk;
+}
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/rtc_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/rtc_api.c
new file mode 100644
index 0000000000..9300125759
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/rtc_api.c
@@ -0,0 +1,114 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if DEVICE_RTC
+
+#include "rtc_api.h"
+
+static uint8_t rtc_init_flag = 0;
+
+/** Initialize the RTC peripheral
+ *
+ * Powerup the RTC in perpetration for access. This function must be called
+ * before any other RTC functions ares called. This does not change the state
+ * of the RTC. It just enables access to it.
+ *
+ * @note This function is safe to call repeatedly - Tested by ::rtc_init_test
+ */
+void rtc_init(void)
+{
+ /* make sure RTC only init once */
+ if (rtc_init_flag) {
+ return;
+ }
+ rtc_init_flag = 1;
+
+ /* enable PMU and BKPI clocks */
+ rcu_periph_clock_enable(RCU_BKPI);
+ rcu_periph_clock_enable(RCU_PMU);
+ /* allow access to BKP domain */
+ pmu_backup_write_enable();
+
+ /* enable LXTAL */
+ rcu_osci_on(RCU_LXTAL);
+ /* wait till LXTAL is ready */
+ rcu_osci_stab_wait(RCU_LXTAL);
+ /* select RCU_LXTAL as RTC clock source */
+ rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
+ /* enable RTC Clock */
+ rcu_periph_clock_enable(RCU_RTC);
+
+ /* wait for RTC registers synchronization */
+ rtc_register_sync_wait();
+ /* wait until last write operation on RTC registers has finished */
+ rtc_lwoff_wait();
+ /* set RTC prescaler: set RTC period to 1s */
+ rtc_prescaler_set(32767);
+ /* wait until last write operation on RTC registers has finished */
+ rtc_lwoff_wait();
+}
+
+/** Deinitialize RTC
+ *
+ * Powerdown the RTC in preparation for sleep, powerdown or reset. That should only
+ * affect the CPU domain and not the time keeping logic.
+ * After this function is called no other RTC functions should be called
+ * except for ::rtc_init.
+ */
+void rtc_free(void)
+{
+}
+
+/** Check if the RTC has the time set and is counting
+ *
+ * @retval 0 The time reported by the RTC is not valid
+ * @retval 1 The time has been set the RTC is counting
+ */
+int rtc_isenabled(void)
+{
+ if (RESET == (RTC_CTL & RTC_CTL_RSYNF)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/** Get the current time from the RTC peripheral
+ *
+ * @return The current time in seconds
+ *
+ * @note Some RTCs are not synchronized with the main clock. If
+ * this is the case with your RTC then you must read the RTC time
+ * in a loop to prevent reading the wrong time due to a glitch.
+ * The test ::rtc_glitch_test is intended to catch this bug.
+ */
+time_t rtc_read(void)
+{
+ return (rtc_counter_get());
+}
+
+/** Write the current time in seconds to the RTC peripheral
+ *
+ * @param t The current time to be set in seconds.
+ */
+void rtc_write(time_t t)
+{
+ rtc_counter_set((uint32_t)t);
+ rtc_lwoff_wait();
+}
+
+#endif /* DEVICE_RTC */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/serial_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/serial_api.c
new file mode 100644
index 0000000000..8dfa7ec3ac
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/serial_api.c
@@ -0,0 +1,1072 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "serial_api.h"
+
+#if DEVICE_SERIAL
+
+#include "cmsis.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+#include
+#include "PeripheralPins.h"
+
+#define USART_NUM (5)
+
+static uint32_t serial_irq_ids[USART_NUM] = {0};
+static rcu_periph_enum usart_clk[USART_NUM] = {RCU_USART0, RCU_USART1, RCU_USART2, RCU_UART3, RCU_UART4};
+static IRQn_Type usart_irq_n[USART_NUM] = {USART0_IRQn, USART1_IRQn, USART2_IRQn, UART3_IRQn, UART4_IRQn};
+
+static uart_irq_handler irq_handler;
+
+int stdio_uart_inited = 0;
+serial_t stdio_uart;
+
+#if DEVICE_SERIAL_ASYNCH
+#define GET_SERIAL_S(obj) (&((obj)->serial))
+#else
+#define GET_SERIAL_S(obj) (obj)
+#endif /* DEVICE_SERIAL_ASYNCH */
+
+/** Initialize the USART peripheral.
+ *
+ * @param obj_s The serial object
+ */
+static void usart_init(struct serial_s *obj_s)
+{
+ if (obj_s->index >= USART_NUM) {
+ return;
+ }
+
+ /* USART configuration */
+ usart_deinit(obj_s->uart);
+ usart_word_length_set(obj_s->uart, obj_s->databits);
+ usart_baudrate_set(obj_s->uart, obj_s->baudrate);
+ usart_stop_bit_set(obj_s->uart, obj_s->stopbits);
+ usart_parity_config(obj_s->uart, obj_s->parity);
+#if DEVICE_SERIAL_FC
+ if (obj_s->hw_flow_ctl == USART_HWCONTROL_NONE) {
+ usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_DISABLE);
+ usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_DISABLE);
+ } else if (obj_s->hw_flow_ctl == USART_HWCONTROL_RTS) {
+ usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_DISABLE);
+ usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_ENABLE);
+ } else if (obj_s->hw_flow_ctl == USART_HWCONTROL_CTS) {
+ usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_ENABLE);
+ usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_DISABLE);
+ } else if (obj_s->hw_flow_ctl == USART_HWCONTROL_RTS_CTS) {
+ usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_ENABLE);
+ usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_ENABLE);
+ }
+#endif /* DEVICE_SERIAL_FC */
+ usart_receive_config(obj_s->uart, USART_RECEIVE_ENABLE);
+ usart_transmit_config(obj_s->uart, USART_TRANSMIT_ENABLE);
+ usart_enable(obj_s->uart);
+}
+
+/** Initialize the serial peripheral. It sets the default parameters for serial
+ * peripheral, and configures its specifieds pins.
+ *
+ * @param obj The serial object
+ * @param tx The TX pin name
+ * @param rx The RX pin name
+ */
+void serial_init(serial_t *obj, PinName tx, PinName rx)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
+ UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
+
+ p_obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
+ MBED_ASSERT(p_obj->uart != (UARTName)NC);
+
+ /* enable UART peripheral clock */
+ if (p_obj->uart == UART_0) {
+ p_obj->index = 0;
+ rcu_periph_clock_enable(usart_clk[p_obj->index]);
+ } else if (p_obj->uart == UART_1) {
+ p_obj->index = 1;
+ rcu_periph_clock_enable(usart_clk[p_obj->index]);
+ } else if (p_obj->uart == UART_2) {
+ p_obj->index = 2;
+ rcu_periph_clock_enable(usart_clk[p_obj->index]);
+ } else if (p_obj->uart == UART_3) {
+ p_obj->index = 3;
+ rcu_periph_clock_enable(usart_clk[p_obj->index]);
+ } else if (p_obj->uart == UART_4) {
+ p_obj->index = 4;
+ rcu_periph_clock_enable(usart_clk[p_obj->index]);
+ }
+
+ /* configurte the pins */
+ pinmap_pinout(tx, PinMap_UART_TX);
+ pinmap_pinout(rx, PinMap_UART_RX);
+
+ /* default UART parameters */
+ p_obj->baudrate = 9600U;
+ p_obj->databits = USART_WL_8BIT;
+ p_obj->stopbits = USART_STB_1BIT;
+ p_obj->parity = USART_PM_NONE;
+
+#if DEVICE_SERIAL_FC
+ p_obj->hw_flow_ctl = USART_HWCONTROL_NONE;
+#endif /* DEVICE_SERIAL_FC */
+
+ p_obj->pin_tx = tx;
+ p_obj->pin_rx = rx;
+
+ p_obj->tx_state = OP_STATE_BUSY;
+ p_obj->rx_state = OP_STATE_BUSY;
+
+ usart_init(p_obj);
+
+ p_obj->tx_state = OP_STATE_READY;
+ p_obj->rx_state = OP_STATE_READY;
+
+ if (p_obj->uart == STDIO_UART) {
+ stdio_uart_inited = 1;
+ memcpy(&stdio_uart, obj, sizeof(serial_t));
+ }
+}
+
+/** Release the serial peripheral, not currently invoked. It requires further
+ * resource management.
+ *
+ * @param obj The serial object
+ */
+void serial_free(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+ rcu_periph_enum rcu_periph = usart_clk[p_obj->index];
+
+ /* reset USART and disable clock */
+ usart_deinit(p_obj->uart);
+ rcu_periph_clock_disable(rcu_periph);
+
+ serial_irq_ids[p_obj->index] = 0;
+
+ /* reset the GPIO state */
+ pin_function(p_obj->pin_tx, MODE_IN_FLOATING);
+ pin_function(p_obj->pin_rx, MODE_IN_FLOATING);
+}
+
+/** Configure the baud rate
+ *
+ * @param obj The serial object
+ * @param baudrate The baud rate to be configured
+ */
+void serial_baud(serial_t *obj, int baudrate)
+{
+ uint16_t uen_flag = 0U;
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ /* store the UEN flag */
+ uen_flag = USART_CTL0(p_obj->uart) & USART_CTL0_UEN;
+
+ /* disable the USART first */
+ usart_disable(p_obj->uart);
+
+ usart_baudrate_set(p_obj->uart, baudrate);
+
+ p_obj->baudrate = baudrate;
+
+ /* restore the UEN flag */
+ if (RESET != uen_flag) {
+ usart_enable(p_obj->uart);
+ }
+}
+
+/** Configure the format. Set the number of bits, parity and the number of stop bits
+ *
+ * @param obj The serial object
+ * @param data_bits The number of data bits
+ * @param parity The parity
+ * @param stop_bits The number of stop bits
+ */
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
+{
+ uint16_t uen_flag = 0U;
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ /* store the UEN flag */
+ uen_flag = USART_CTL0(p_obj->uart) & USART_CTL0_UEN;
+
+ /* disable the UART clock first */
+ usart_disable(p_obj->uart);
+
+ /* configurate the UART parity */
+ switch (parity) {
+ case ParityOdd:
+ p_obj->parity = USART_PM_ODD;
+ usart_parity_config(p_obj->uart, USART_PM_ODD);
+ break;
+
+ case ParityEven:
+ p_obj->parity = USART_PM_EVEN;
+ usart_parity_config(p_obj->uart, USART_PM_EVEN);
+ break;
+
+ case ParityForced0:
+ case ParityForced1:
+ default:
+ p_obj->parity = USART_PM_NONE;
+ usart_parity_config(p_obj->uart, USART_PM_NONE);
+ break;
+ }
+
+ if (p_obj->parity == USART_PM_NONE) {
+ if (data_bits == 9) {
+ usart_word_length_set(p_obj->uart, USART_WL_9BIT);
+ } else if (data_bits == 8) {
+ usart_word_length_set(p_obj->uart, USART_WL_8BIT);
+ } else if (data_bits == 7) {
+ return;
+ }
+ } else {
+ if (data_bits == 9) {
+ return;
+ } else if (data_bits == 8) {
+ usart_word_length_set(p_obj->uart, USART_WL_9BIT);
+ } else if (data_bits == 7) {
+ usart_word_length_set(p_obj->uart, USART_WL_8BIT);
+ }
+ }
+
+ if (stop_bits == 2) {
+ usart_stop_bit_set(p_obj->uart, USART_STB_2BIT);
+ } else {
+ usart_stop_bit_set(p_obj->uart, USART_STB_1BIT);
+ }
+
+ /* restore the UEN flag */
+ if (RESET != uen_flag) {
+ usart_enable(p_obj->uart);
+ }
+}
+
+/** The serial interrupt handler registration
+ *
+ * @param obj The serial object
+ * @param handler The interrupt handler which will be invoked when the interrupt fires
+ * @param id The SerialBase object
+ */
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ irq_handler = handler;
+ serial_irq_ids[p_obj->index] = id;
+}
+
+/** This function handles USART interrupt handler
+ *
+ * @param usart_index The index of UART
+ * @param usart_periph The UART peripheral
+ */
+static void usart_irq(int usart_index, uint32_t usart_periph)
+{
+ if (serial_irq_ids[usart_index] != 0) {
+ if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_TC) != RESET) {
+ usart_interrupt_flag_clear(usart_periph, USART_INT_FLAG_TC);
+ irq_handler(serial_irq_ids[usart_index], TxIrq);
+ }
+
+ if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_RBNE) != RESET) {
+ usart_interrupt_flag_clear(usart_periph, USART_INT_FLAG_RBNE);
+ irq_handler(serial_irq_ids[usart_index], RxIrq);
+ }
+
+ if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_ORERR) != RESET) {
+ /* clear ORERR error flag by reading USART DATA register */
+ USART_DATA(usart_periph);
+ }
+
+ if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_NERR) != RESET) {
+ /* clear NERR error flag by reading USART DATA register */
+ USART_DATA(usart_periph);
+ }
+
+ if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_FERR) != RESET) {
+ /* clear FERR error flag by reading USART DATA register */
+ USART_DATA(usart_periph);
+ }
+
+ if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_PERR) != RESET) {
+ /* clear PERR error flag by reading USART DATA register */
+ USART_DATA(usart_periph);
+ }
+ }
+}
+
+/** This function handles USART0 interrupt handler
+ *
+ */
+static void usart0_irq(void)
+{
+ usart_irq(0, USART0);
+}
+
+/** This function handles USART1 interrupt handler
+ *
+ */
+static void usart1_irq(void)
+{
+ usart_irq(1, USART1);
+}
+
+/** This function handles USART2 interrupt handler
+ *
+ */
+static void usart2_irq(void)
+{
+ usart_irq(2, USART2);
+}
+
+/** This function handles USART3 interrupt handler
+ *
+ */
+static void uart3_irq(void)
+{
+ usart_irq(3, UART3);
+}
+
+/** This function handles USART4 interrupt handler
+ *
+ */
+static void uart4_irq(void)
+{
+ usart_irq(4, UART4);
+}
+
+/** Configure serial interrupt. This function is used for word-approach
+ *
+ * @param obj The serial object
+ * @param irq The serial IRQ type (RX or TX)
+ * @param enable Set to non-zero to enable events, or zero to disable them
+ */
+void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+ IRQn_Type irq_n = (IRQn_Type)0;
+ uint32_t vector = 0;
+
+ if (p_obj->uart == USART0) {
+ irq_n = USART0_IRQn;
+ vector = (uint32_t)&usart0_irq;
+ } else if (p_obj->uart == USART1) {
+ irq_n = USART1_IRQn;
+ vector = (uint32_t)&usart1_irq;
+ } else if (p_obj->uart == USART2) {
+ irq_n = USART2_IRQn;
+ vector = (uint32_t)&usart2_irq;
+ } else if (p_obj->uart == UART3) {
+ irq_n = UART3_IRQn;
+ vector = (uint32_t)&uart3_irq;
+ } else if (p_obj->uart == UART4) {
+ irq_n = UART4_IRQn;
+ vector = (uint32_t)&uart4_irq;
+ }
+
+ if (enable) {
+ if (irq == RxIrq) {
+ /* Rx IRQ */
+ usart_interrupt_enable(p_obj->uart, USART_INT_RBNE);
+ } else {
+ /* Tx IRQ */
+ usart_interrupt_enable(p_obj->uart, USART_INT_TBE);
+ }
+
+ NVIC_SetVector(irq_n, vector);
+ NVIC_EnableIRQ(irq_n);
+ } else {
+ if (irq == RxIrq) {
+ /* Rx IRQ */
+ usart_interrupt_disable(p_obj->uart, USART_INT_RBNE);
+ } else {
+ /* Tx IRQ */
+ usart_interrupt_disable(p_obj->uart, USART_INT_TBE);
+ }
+ }
+}
+
+/** Get character. This is a blocking call, waiting for a character
+ *
+ * @param obj The serial object
+ */
+int serial_getc(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ while (!serial_readable(obj));
+ return (int)(usart_data_receive(p_obj->uart) & BITS(0, 7 + (p_obj->databits >> 12)));
+}
+
+/** Send a character. This is a blocking call, waiting for a peripheral to be available
+ * for writing
+ *
+ * @param obj The serial object
+ * @param c The character to be sent
+ */
+void serial_putc(serial_t *obj, int c)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ while (!serial_writable(obj));
+ usart_data_transmit(p_obj->uart, (int)((c) & BITS(0, 7 + (p_obj->databits >> 12))));
+}
+
+/** Check if the serial peripheral is readable
+ *
+ * @param obj The serial object
+ * @return Non-zero value if a character can be read, 0 if nothing to read
+ */
+int serial_readable(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ return (usart_flag_get(p_obj->uart, USART_FLAG_RBNE) != RESET) ? 1 : 0;
+}
+
+/** Check if the serial peripheral is writable
+ *
+ * @param obj The serial object
+ * @return Non-zero value if a character can be written, 0 otherwise.
+ */
+int serial_writable(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ return (usart_flag_get(p_obj->uart, USART_FLAG_TBE) != RESET) ? 1 : 0;
+}
+
+/** Clear the serial peripheral
+ *
+ * @param obj The serial object
+ */
+void serial_clear(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ p_obj->tx_count = 0U;
+ p_obj->rx_count = 0U;
+}
+
+/** Set the break
+ *
+ * @param obj The serial object
+ */
+void serial_break_set(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ usart_send_break(p_obj->uart);
+}
+
+/** Clear the break
+ *
+ * @param obj The serial object
+ */
+void serial_break_clear(serial_t *obj)
+{
+ /* do nothing */
+}
+
+/** Configure the TX pin for UART function.
+ *
+ * @param tx The pin name used for TX
+ */
+void serial_pinout_tx(PinName tx)
+{
+ pinmap_pinout(tx, PinMap_UART_TX);
+}
+
+#if DEVICE_SERIAL_ASYNCH
+/**
+ * Enable the serial events
+ *
+ * @param obj The serial object
+ * @param event The events to be configured
+ */
+static void serial_event_enable(serial_t *obj, int event)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ p_obj->events |= event;
+
+}
+
+/**
+ * Disable the serial events
+ *
+ * @param obj The serial object
+ * @param event The events to be configured
+ */
+static void serial_event_disable(serial_t *obj, int event)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ p_obj->events &= ~event;
+}
+
+/**
+ * Preprocess the USART tx interrupt
+ *
+ * @param obj_s The serial object
+ * @param pData Pointer to tx buffer
+ * @param Size Size of tx buffer
+ * @return Returns the status
+ */
+static gd_status_enum usart_tx_interrupt_preprocess(struct serial_s *obj_s, uint8_t *pData, uint16_t Size)
+{
+ if (obj_s->tx_state == OP_STATE_READY) {
+ if ((pData == NULL) || (Size == 0U)) {
+ return GD_ERROR;
+ }
+
+ obj_s->tx_buffer_ptr = pData;
+ obj_s->tx_count = Size;
+ obj_s->error_code = USART_ERROR_CODE_NONE;
+ obj_s->tx_state = OP_STATE_BUSY_TX;
+
+ usart_interrupt_enable(obj_s->uart, USART_INT_TBE);
+
+ return GD_OK;
+ } else {
+ return GD_BUSY;
+ }
+}
+
+/**
+ * Preprocess the USART rx interrupt
+ *
+ * @param obj_s The serial object
+ * @param pData Pointer to rx buffer
+ * @param Size Size of rx buffer
+ * @return Returns the status
+ */
+static gd_status_enum usart_rx_interrupt_preprocess(struct serial_s *obj_s, uint8_t *pData, uint16_t Size)
+{
+ if (obj_s->rx_state == OP_STATE_READY) {
+ if ((pData == NULL) || (Size == 0U)) {
+ return GD_ERROR;
+ }
+
+ obj_s->rx_buffer_ptr = pData;
+ obj_s->rx_size = Size;
+ obj_s->rx_count = Size;
+ obj_s->error_code = USART_ERROR_CODE_NONE;
+ obj_s->rx_state = OP_STATE_BUSY_RX;
+
+ usart_interrupt_enable(obj_s->uart, USART_INT_PERR);
+ usart_interrupt_enable(obj_s->uart, USART_INT_ERR);
+ usart_interrupt_enable(obj_s->uart, USART_INT_RBNE);
+
+ return GD_OK;
+ } else {
+ return GD_BUSY;
+ }
+}
+
+/** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
+ * tx_buff
+ *
+ * @param obj The serial object
+ * @param tx The transmit buffer
+ * @param tx_length The number of bytes to transmit
+ * @param tx_width Deprecated argument
+ * @param handler The serial handler
+ * @param event The logical OR of events to be registered
+ * @param hint A suggestion for how to use DMA with this transfer
+ * @return Returns number of data transfered, otherwise returns 0
+ */
+int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+ IRQn_Type irq = usart_irq_n[p_obj->index];
+
+ if ((tx_length == 0) || (tx_width != 8)) {
+ return 0;
+ }
+
+ if (serial_tx_active(obj)) {
+ /* some transmit is in progress */
+ return 0;
+ }
+
+ obj->tx_buff.buffer = (void *)tx;
+ obj->tx_buff.length = tx_length;
+ obj->tx_buff.pos = 0;
+
+ /* disable all events first */
+ serial_event_disable(obj, SERIAL_EVENT_TX_ALL);
+ /* enable the specific event */
+ serial_event_enable(obj, event);
+
+ /* enable interrupt */
+ /* clear pending IRQ */
+ NVIC_ClearPendingIRQ(irq);
+ /* disable the IRQ first */
+ NVIC_DisableIRQ(irq);
+ /* set the priority and vector */
+ NVIC_SetPriority(irq, 1);
+ NVIC_SetVector(irq, (uint32_t)handler);
+ /* enable IRQ */
+ NVIC_EnableIRQ(irq);
+
+ if (usart_tx_interrupt_preprocess(p_obj, (uint8_t *)tx, tx_length) != GD_OK) {
+ return 0;
+ }
+
+ return tx_length;
+}
+
+/** Begin asynchronous RX transfer (enable interrupt for data collecting)
+ * The used buffer is specified in the serial object - rx_buff
+ *
+ * @param obj The serial object
+ * @param rx The receive buffer
+ * @param rx_length The number of bytes to receive
+ * @param rx_width Deprecated argument
+ * @param handler The serial handler
+ * @param event The logical OR of events to be registered
+ * @param handler The serial handler
+ * @param char_match A character in range 0-254 to be matched
+ * @param hint A suggestion for how to use DMA with this transfer
+ */
+void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+ IRQn_Type irq = usart_irq_n[p_obj->index];
+
+ if ((rx_length == 0) || (rx_width != 8)) {
+ return;
+ }
+
+ /* disable all events first */
+ serial_event_disable(obj, SERIAL_EVENT_RX_ALL);
+ /* enable the specific event */
+ serial_event_enable(obj, event);
+
+ obj->char_match = char_match;
+
+ if (serial_rx_active(obj)) {
+ /* some reception is in progress */
+ return;
+ }
+
+ obj->rx_buff.buffer = rx;
+ obj->rx_buff.length = rx_length;
+ obj->rx_buff.pos = 0;
+
+ /* enable interrupt */
+ /* clear pending IRQ */
+ NVIC_ClearPendingIRQ(irq);
+ /* disable the IRQ first */
+ NVIC_DisableIRQ(irq);
+ /* set the priority(higher than Tx) and vector */
+ NVIC_SetPriority(irq, 0);
+ NVIC_SetVector(irq, (uint32_t)handler);
+ /* enable IRQ */
+ NVIC_EnableIRQ(irq);
+
+ usart_rx_interrupt_preprocess(p_obj, (uint8_t *)rx, rx_length);
+}
+
+/** Attempts to determine if the serial peripheral is already in use for TX
+ *
+ * @param obj The serial object
+ * @return Non-zero if the RX transaction is ongoing, 0 otherwise
+ */
+uint8_t serial_tx_active(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ return ((p_obj->tx_state == OP_STATE_BUSY_TX) ? 1 : 0);
+}
+
+/** Attempts to determine if the serial peripheral is already in use for RX
+ *
+ * @param obj The serial object
+ * @return Non-zero if the RX transaction is ongoing, 0 otherwise
+ */
+uint8_t serial_rx_active(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ return ((p_obj->rx_state == OP_STATE_BUSY_RX) ? 1 : 0);
+}
+
+/** Handle the serial rx interrupt
+ *
+ * @param obj_s The serial object
+ * @return Returns the status
+ */
+static gd_status_enum usart_rx_interrupt(struct serial_s *obj_s)
+{
+ uint16_t *temp;
+
+ if (obj_s->rx_state == OP_STATE_BUSY_RX) {
+ if (obj_s->databits == USART_WL_9BIT) {
+ temp = (uint16_t *) obj_s->rx_buffer_ptr;
+ if (obj_s->parity == USART_PM_NONE) {
+ /* 9-bit data, none parity bit */
+ *temp = (uint16_t)(USART_DATA(obj_s->uart) & (uint16_t)0x01FF);
+ obj_s->rx_buffer_ptr += 2U;
+ } else {
+ /* 9-bit data, with parity bit */
+ *temp = (uint16_t)(USART_DATA(obj_s->uart) & (uint16_t)0x00FF);
+ obj_s->rx_buffer_ptr += 1U;
+ }
+ } else {
+ if (obj_s->parity == USART_PM_NONE) {
+ /* 8-bit data, none parity bit */
+ *obj_s->rx_buffer_ptr++ = (uint8_t)(USART_DATA(obj_s->uart) & (uint8_t)0x00FF);
+ } else {
+ /* 8-bit data, with parity bit */
+ *obj_s->rx_buffer_ptr++ = (uint8_t)(USART_DATA(obj_s->uart) & (uint8_t)0x007F);
+ }
+ }
+
+ if (--obj_s->rx_count == 0U) {
+ usart_interrupt_disable(obj_s->uart, USART_INT_RBNE);
+ usart_interrupt_disable(obj_s->uart, USART_INT_PERR);
+ usart_interrupt_disable(obj_s->uart, USART_INT_ERR);
+
+ obj_s->rx_state = OP_STATE_READY;
+ }
+
+ return GD_OK;
+ } else {
+ return GD_BUSY;
+ }
+}
+
+/** Handle the serial tx interrupt
+ *
+ * @param obj_s The serial object
+ * @return Returns the status
+ */
+static gd_status_enum usart_tx_interrupt(struct serial_s *obj_s)
+{
+ uint16_t *temp;
+
+ if (obj_s->tx_state == OP_STATE_BUSY_TX) {
+ if (obj_s->databits == USART_WL_9BIT) {
+ temp = (uint16_t *) obj_s->tx_buffer_ptr;
+ USART_DATA(obj_s->uart) = (uint16_t)(*temp & (uint16_t)0x01FF);
+ if (obj_s->parity == USART_PM_NONE) {
+ obj_s->tx_buffer_ptr += 2U;
+ } else {
+ obj_s->tx_buffer_ptr += 1U;
+ }
+ } else {
+ USART_DATA(obj_s->uart) = (uint8_t)(*obj_s->tx_buffer_ptr++ & (uint8_t)0x00FF);
+ }
+
+ if (--obj_s->tx_count == 0U) {
+ /* disable USART_INT_TBE interrupt */
+ usart_interrupt_disable(obj_s->uart, USART_INT_TBE);
+
+ /* enable USART_INT_TC interrupt */
+ usart_interrupt_enable(obj_s->uart, USART_INT_TC);
+ }
+
+ return GD_OK;
+ } else {
+ return GD_BUSY;
+ }
+}
+
+/** Handle the serial tx complete interrupt
+ *
+ * @param obj_s The serial object
+ */
+static void usart_tx_complete_interrupt(struct serial_s *obj_s)
+{
+ usart_interrupt_disable(obj_s->uart, USART_INT_TC);
+
+ obj_s->tx_state = OP_STATE_READY;
+}
+
+/** Handle all the serial interrupt request
+ *
+ * @param obj_s The serial object
+ */
+static void usart_irq_handler(struct serial_s *obj_s)
+{
+ uint32_t err_flags = 0U;
+
+ /* no error occurs */
+ err_flags = (USART_STAT0(obj_s->uart) & (uint32_t)(USART_FLAG_PERR | USART_FLAG_FERR | USART_FLAG_ORERR | USART_FLAG_NERR));
+ if (err_flags == RESET) {
+ /* check whether USART is in receiver mode or not */
+ if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_RBNE) != RESET) {
+ usart_rx_interrupt(obj_s);
+
+ return;
+ }
+ }
+
+ if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_TBE) != RESET) {
+ usart_tx_interrupt(obj_s);
+ return;
+ }
+
+ if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_TC) != RESET) {
+ usart_tx_complete_interrupt(obj_s);
+ return;
+ }
+}
+
+/** The asynchronous TX and RX handler.
+ *
+ * @param obj The serial object
+ * @return Returns event flags if an RX transfer termination condition was met; otherwise returns 0
+ */
+int serial_irq_handler_asynch(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+ volatile uint8_t i = 0;
+ volatile int return_val = 0;
+ uint8_t *p_buf = (uint8_t *)(obj->rx_buff.buffer);
+
+ if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_PERR) != RESET) {
+ /* clear PERR error flag by reading USART DATA register */
+ USART_DATA(p_obj->uart);
+
+ return_val |= (SERIAL_EVENT_RX_PARITY_ERROR & p_obj->events);
+ p_obj->error_code |= USART_ERROR_CODE_PERR;
+ }
+
+ if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_ERR_FERR) != RESET) {
+ /* clear FERR error flag by reading USART DATA register */
+ USART_DATA(p_obj->uart);
+
+ return_val |= (SERIAL_EVENT_RX_FRAMING_ERROR & p_obj->events);
+ p_obj->error_code |= USART_ERROR_CODE_FERR;
+ }
+
+ if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_ERR_ORERR) != RESET) {
+ /* clear ORERR error flag by reading USART DATA register */
+ USART_DATA(p_obj->uart);
+
+ return_val |= (SERIAL_EVENT_RX_OVERRUN_ERROR & p_obj->events);
+ p_obj->error_code |= USART_ERROR_CODE_ORERR;
+ }
+
+ if (return_val & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR |
+ SERIAL_EVENT_RX_OVERRUN_ERROR)) {
+ return return_val;
+ }
+
+ if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_TC) != RESET) {
+ if ((p_obj->events & SERIAL_EVENT_TX_COMPLETE) != 0) {
+ return_val |= (SERIAL_EVENT_TX_COMPLETE & p_obj->events);
+ }
+ }
+
+ usart_irq_handler(p_obj);
+
+ if (p_obj->rx_size != 0) {
+ obj->rx_buff.pos = p_obj->rx_size - p_obj->rx_count;
+ }
+
+ if ((p_obj->rx_count == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
+ return_val |= (SERIAL_EVENT_RX_COMPLETE & p_obj->events);
+ }
+
+ if (p_obj->events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
+ if (p_buf != NULL) {
+ for (i = 0; i < obj->rx_buff.pos; i++) {
+ if (p_buf[i] == obj->char_match) {
+ obj->rx_buff.pos = i;
+ return_val |= (SERIAL_EVENT_RX_CHARACTER_MATCH & p_obj->events);
+ serial_rx_abort_asynch(obj);
+ break;
+ }
+ }
+ }
+ }
+
+ return return_val;
+}
+
+/** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
+ * flushes the TX hardware buffer if TX FIFO is used
+ *
+ * @param obj The serial object
+ */
+void serial_tx_abort_asynch(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ usart_interrupt_disable(p_obj->uart, USART_INT_TC);
+ usart_interrupt_disable(p_obj->uart, USART_INT_TBE);
+
+ usart_flag_clear(p_obj->uart, USART_FLAG_TC);
+
+ p_obj->tx_count = 0;
+ p_obj->tx_state = OP_STATE_READY;
+}
+
+/** Abort the ongoing RX transaction. It disables the enabled interrupt for RX and
+ * flushes the RX hardware buffer if RX FIFO is used
+ *
+ * @param obj The serial object
+ */
+void serial_rx_abort_asynch(serial_t *obj)
+{
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ /* disable interrupts */
+ usart_interrupt_disable(p_obj->uart, USART_INT_RBNE);
+ usart_interrupt_disable(p_obj->uart, USART_INT_PERR);
+ usart_interrupt_disable(p_obj->uart, USART_INT_ERR);
+
+ /* clear USART_FLAG_RBNE flag */
+ usart_flag_clear(p_obj->uart, USART_FLAG_RBNE);
+
+ /* clear errors flag by reading USART STATx register and then USART DATA register */
+ usart_flag_get(p_obj->uart, USART_FLAG_PERR);
+ usart_flag_get(p_obj->uart, USART_FLAG_FERR);
+ usart_flag_get(p_obj->uart, USART_FLAG_ORERR);
+ USART_DATA(p_obj->uart);
+
+ /* reset rx transfer count */
+ p_obj->rx_count = 0;
+
+ /* reset rx state */
+ p_obj->rx_state = OP_STATE_READY;
+}
+
+#endif /* DEVICE_SERIAL_ASYNCH */
+
+#if DEVICE_SERIAL_FC
+/** Configure the serial for the flow control. It sets flow control in the hardware
+ * if a serial peripheral supports it, otherwise software emulation is used.
+ *
+ * @param obj The serial object
+ * @param type The type of the flow control. Look at the available FlowControl types.
+ * @param rxflow The TX pin name
+ * @param txflow The RX pin name
+ */
+void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
+{
+ uint16_t uen_flag = 0U;
+ struct serial_s *p_obj = GET_SERIAL_S(obj);
+
+ /* store the UEN flag */
+ uen_flag = USART_CTL0(p_obj->uart) & USART_CTL0_UEN;
+
+ UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
+ UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
+
+ p_obj->uart = (UARTName)pinmap_merge(uart_cts, uart_rts);
+ MBED_ASSERT(p_obj->uart != (UARTName)NC);
+
+ /* disable USART to modify CTS/RTS configuration */
+ usart_disable(p_obj->uart);
+
+ if (type == FlowControlNone) {
+ p_obj->hw_flow_ctl = USART_HWCONTROL_NONE;
+ usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_DISABLE);
+ usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_DISABLE);
+ }
+
+ if (type == FlowControlRTS) {
+ MBED_ASSERT(uart_rts != (UARTName)NC);
+ p_obj->hw_flow_ctl = USART_HWCONTROL_RTS;
+ p_obj->pin_rts = rxflow;
+ pinmap_pinout(rxflow, PinMap_UART_RTS);
+ usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_DISABLE);
+ usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_ENABLE);
+ }
+
+ if (type == FlowControlCTS) {
+ MBED_ASSERT(uart_cts != (UARTName)NC);
+ p_obj->hw_flow_ctl = USART_HWCONTROL_CTS;
+ p_obj->pin_cts = txflow;
+ pinmap_pinout(txflow, PinMap_UART_CTS);
+ usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_DISABLE);
+ usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_ENABLE);
+ }
+
+ if (type == FlowControlRTSCTS) {
+ MBED_ASSERT(uart_rts != (UARTName)NC);
+ MBED_ASSERT(uart_cts != (UARTName)NC);
+ p_obj->hw_flow_ctl = USART_HWCONTROL_RTS_CTS;
+ p_obj->pin_rts = rxflow;
+ p_obj->pin_cts = txflow;
+ pinmap_pinout(txflow, PinMap_UART_CTS);
+ pinmap_pinout(rxflow, PinMap_UART_RTS);
+ usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_ENABLE);
+ usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_ENABLE);
+ }
+
+ /* restore the UEN flag */
+ if (RESET != uen_flag) {
+ usart_enable(p_obj->uart);
+ }
+}
+
+#endif /* DEVICE_SERIAL_FC */
+
+#if DEVICE_SLEEP
+/** Check whether the serial is in busy state
+ *
+ * @return 0: all the serial is free to use, 1: some serial is in busy in transfer
+ */
+int serial_busy_state_check(void)
+{
+#if defined(USART0)
+ if ((USART_CTL0(USART0) & USART_CTL0_UEN) && !(USART_STAT0(USART0) & USART_STAT0_TC)) {
+ return 1;
+ }
+#endif
+
+#if defined(USART1)
+ if ((USART_CTL0(USART1) & USART_CTL0_UEN) && !(USART_STAT0(USART1) & USART_STAT0_TC)) {
+ return 1;
+ }
+#endif
+
+#if defined(USART2)
+ if ((USART_CTL0(USART2) & USART_CTL0_UEN) && !(USART_STAT0(USART2) & USART_STAT0_TC)) {
+ return 1;
+ }
+#endif
+
+#if defined(UART3)
+ if ((USART_CTL0(UART3) & USART_CTL0_UEN) && !(USART_STAT0(UART3) & USART_STAT0_TC)) {
+ return 1;
+ }
+#endif
+
+#if defined(UART4)
+ if ((USART_CTL0(UART4) & USART_CTL0_UEN) && !(USART_STAT0(UART4) & USART_STAT0_TC)) {
+ return 1;
+ }
+#endif
+
+ /* no serial is in busy state */
+ return 0;
+}
+#endif /* DEVICE_SLEEP */
+
+#endif /* DEVICE_SERIAL */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/sleep.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/sleep.c
new file mode 100644
index 0000000000..41f1e66e78
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/sleep.c
@@ -0,0 +1,160 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if DEVICE_SLEEP
+
+#include "sleep_api.h"
+#include "us_ticker_api.h"
+#include "mbed_critical.h"
+#include "mbed_error.h"
+
+extern void ticker_timer_data_save(void);
+extern void ticker_timer_data_restore(void);
+extern int serial_busy_state_check(void);
+
+/*!
+ \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_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) {
+ }
+ }
+
+ FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_3;
+
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/1 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
+
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
+#ifdef HXTAL_VALUE_8M
+ /* CK_PREDIV0 = (CK_HXTAL)/2 *10 /10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL10 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV10);
+#elif defined (HXTAL_VALUE_25M)
+ /* CK_PREDIV0 = (CK_HXTAL)/5 *8/10 = 4 MHz */
+ RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
+#endif
+
+ /* enable PLL1 */
+ RCU_CTL |= RCU_CTL_PLL1EN;
+ /* wait till PLL1 is ready */
+ while ((RCU_CTL & RCU_CTL_PLL1STB) == 0U) {
+ }
+
+ /* enable PLL */
+ RCU_CTL |= RCU_CTL_PLLEN;
+
+ /* wait until PLL is stable */
+ while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
+ }
+
+ /* select PLL as system clock */
+ RCU_CFG0 &= ~RCU_CFG0_SCS;
+ RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+ /* wait until PLL is selected as system clock */
+ while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
+ }
+}
+
+
+/** Send the microcontroller to sleep
+ *
+ * The processor is setup ready for sleep, and sent to sleep. In this mode, the
+ * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
+ * dynamic power used by the processor, memory systems and buses. The processor, peripheral and
+ * memory state are maintained, and the peripherals continue to work and can generate interrupts.
+ *
+ * The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
+ *
+ * The wake-up time shall be less than 10 us.
+ *
+ */
+void hal_sleep(void)
+{
+ /* Disable Interrupts */
+ core_util_critical_section_enter();
+
+ /* Enter SLEEP mode */
+ pmu_to_sleepmode(WFI_CMD);
+
+ /* Enable Interrupts */
+ core_util_critical_section_exit();
+}
+
+
+/** Send the microcontroller to deep sleep
+ *
+ * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode
+ * has the same sleep features as sleep plus it powers down peripherals and high frequency clocks.
+ * All state is still maintained.
+ *
+ * The processor can only be woken up by low power ticker, RTC, an external interrupt on a pin or a watchdog timer.
+ *
+ * The wake-up time shall be less than 10 ms.
+ */
+void hal_deepsleep(void)
+{
+ if (0 != serial_busy_state_check()) {
+ return;
+ }
+
+ /* Disable Interrupts */
+ core_util_critical_section_enter();
+
+ ticker_timer_data_save();
+
+ /* Enter DEEP SLEEP mode */
+ rcu_periph_clock_enable(RCU_PMU);
+ pmu_to_deepsleepmode(PMU_LDO_NORMAL, WFI_CMD);
+
+ /* Reconfigure the PLL after weak up */
+ system_clock_120m_hxtal();
+
+ ticker_timer_data_restore();
+
+ /* Enable Interrupts */
+ core_util_critical_section_exit();
+}
+
+#endif /* DEVICE_SLEEP */
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/spi_api.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/spi_api.c
new file mode 100644
index 0000000000..50a121c59c
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/spi_api.c
@@ -0,0 +1,378 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "mbed_error.h"
+#include "spi_api.h"
+
+#if DEVICE_SPI
+#include "cmsis.h"
+#include "pinmap.h"
+#include "PeripheralPins.h"
+
+#define SPI_S(obj) (( struct spi_s *)(obj))
+
+/** Get the frequency of SPI clock source
+ *
+ * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
+ * @param[out] spi_freq The SPI clock source freguency
+ * @param[in] obj The SPI object
+ */
+static int dev_spi_clock_source_frequency_get(spi_t *obj)
+{
+ int spi_freq = 0;
+ struct spi_s *spiobj = SPI_S(obj);
+
+ switch ((int)spiobj->spi) {
+ case SPI0:
+ /* clock source is APB2 */
+ spi_freq = rcu_clock_freq_get(CK_APB2);
+ break;
+ case SPI1:
+ /* clock source is APB1 */
+ spi_freq = rcu_clock_freq_get(CK_APB1);
+ break;
+ case SPI2:
+ /* clock source is APB1 */
+ spi_freq = rcu_clock_freq_get(CK_APB1);
+ break;
+ default:
+ error("SPI clock source frequency get error");
+ break;
+ }
+ return spi_freq;
+}
+
+/** Initialize the SPI structure
+ *
+ * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
+ * @param[out] obj The SPI object to initialize
+ */
+static void dev_spi_struct_init(spi_t *obj)
+{
+ struct spi_s *spiobj = SPI_S(obj);
+
+ spi_disable(spiobj->spi);
+ spi_para_init(spiobj->spi, &obj->spi_struct);
+ spi_enable(spiobj->spi);
+}
+
+/** Initialize the SPI peripheral
+ *
+ * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
+ * @param[out] obj The SPI object to initialize
+ * @param[in] mosi The pin to use for MOSI
+ * @param[in] miso The pin to use for MISO
+ * @param[in] sclk The pin to use for SCLK
+ * @param[in] ssel The pin to use for SSEL
+ */
+void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
+{
+ struct spi_s *spiobj = SPI_S(obj);
+
+ SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
+ SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
+ SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
+ SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
+
+ /* return SPIName according to PinName */
+ SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
+ SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
+
+ spiobj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
+ MBED_ASSERT(spiobj->spi != (SPIName)NC);
+
+ /* Set iqr type */
+ if (spiobj->spi == SPI0) {
+ rcu_periph_clock_enable(RCU_SPI0);
+ spiobj->spi_irq = SPI0_IRQn;
+ }
+ if (spiobj->spi == SPI1) {
+ rcu_periph_clock_enable(RCU_SPI1);
+ spiobj->spi_irq = SPI1_IRQn;
+ }
+ if (spiobj->spi == SPI2) {
+ rcu_periph_clock_enable(RCU_SPI2);
+ spiobj->spi_irq = SPI2_IRQn;
+ }
+
+ /* config GPIO mode of SPI pins */
+ pinmap_pinout(mosi, PinMap_SPI_MOSI);
+ pinmap_pinout(miso, PinMap_SPI_MISO);
+ pinmap_pinout(sclk, PinMap_SPI_SCLK);
+ spiobj->pin_miso = miso;
+ spiobj->pin_mosi = mosi;
+ spiobj->pin_sclk = sclk;
+ spiobj->pin_ssel = ssel;
+ if (ssel != NC) {
+ pinmap_pinout(ssel, PinMap_SPI_SSEL);
+ spiobj->spi_struct.nss = SPI_NSS_HARD;
+ spi_nss_output_enable(spiobj->spi);
+ } else {
+ spiobj->spi_struct.nss = SPI_NSS_SOFT;
+ }
+
+ spiobj->spi_struct.device_mode = SPI_MASTER;
+ spiobj->spi_struct.prescale = SPI_PSC_256;
+ spiobj->spi_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
+ spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
+ spiobj->spi_struct.frame_size = SPI_FRAMESIZE_8BIT;
+ spiobj->spi_struct.endian = SPI_ENDIAN_MSB;
+
+ dev_spi_struct_init(obj);
+}
+
+/** Release a SPI object
+ *
+ * TODO: spi_free is currently unimplemented
+ * This will require reference counting at the C++ level to be safe
+ *
+ * Return the pins owned by the SPI object to their reset state
+ * Disable the SPI peripheral
+ * Disable the SPI clock
+ * @param[in] obj The SPI object to deinitialize
+ */
+void spi_free(spi_t *obj)
+{
+ struct spi_s *spiobj = SPI_S(obj);
+ spi_disable(spiobj->spi);
+
+ /* Disable and deinit SPI */
+ if (spiobj->spi == SPI0) {
+ spi_i2s_deinit(SPI0);
+ rcu_periph_clock_disable(RCU_SPI0);
+ }
+ if (spiobj->spi == SPI1) {
+ spi_i2s_deinit(SPI1);
+ rcu_periph_clock_disable(RCU_SPI1);
+ }
+ if (spiobj->spi == SPI2) {
+ spi_i2s_deinit(SPI2);
+ rcu_periph_clock_disable(RCU_SPI2);
+ }
+ /* Deinit GPIO mode of SPI pins */
+ pin_function(spiobj->pin_miso, MODE_IN_FLOATING);
+ pin_function(spiobj->pin_mosi, MODE_IN_FLOATING);
+ pin_function(spiobj->pin_sclk, MODE_IN_FLOATING);
+ if (spiobj->spi_struct.nss != SPI_NSS_SOFT) {
+ pin_function(spiobj->pin_ssel, MODE_IN_FLOATING);
+ }
+}
+
+/** Configure the SPI format
+ *
+ * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
+ * The default bit order is MSB.
+ * @param[in,out] obj The SPI object to configure
+ * @param[in] bits The number of bits per frame
+ * @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
+ * @param[in] slave Zero for master mode or non-zero for slave mode
+ */
+void spi_format(spi_t *obj, int bits, int mode, int slave)
+{
+ struct spi_s *spiobj = SPI_S(obj);
+
+ spiobj->spi_struct.frame_size = (bits == 16) ? SPI_FRAMESIZE_16BIT : SPI_FRAMESIZE_8BIT;
+ /* Config polarity and phase of SPI */
+ switch (mode) {
+ case 0:
+ spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
+ break;
+ case 1:
+ spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
+ break;
+ case 2:
+ spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
+ break;
+ default:
+ spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
+
+ break;
+ }
+
+ if (spiobj->spi_struct.nss != SPI_NSS_SOFT) {
+ if (slave) {
+ pin_function(spiobj->pin_mosi, MODE_IN_FLOATING);
+ pin_function(spiobj->pin_sclk, MODE_IN_FLOATING);
+ pin_function(spiobj->pin_ssel, MODE_IN_FLOATING);
+ spi_nss_output_disable(spiobj->spi);
+ }
+ }
+ /* Select SPI as master or slave */
+ spiobj->spi_struct.device_mode = (slave) ? SPI_SLAVE : SPI_MASTER;
+
+ dev_spi_struct_init(obj);
+}
+
+static const uint16_t baudrate_prescaler_table[] = {SPI_PSC_2,
+ SPI_PSC_4,
+ SPI_PSC_8,
+ SPI_PSC_16,
+ SPI_PSC_32,
+ SPI_PSC_64,
+ SPI_PSC_128,
+ SPI_PSC_256
+ };
+
+/** Set the SPI baud rate
+ *
+ * Actual frequency may differ from the desired frequency due to available dividers and bus clock
+ * Configures the SPI peripheral's baud rate
+ * @param[in,out] obj The SPI object to configure
+ * @param[in] hz The baud rate in Hz
+ */
+void spi_frequency(spi_t *obj, int hz)
+{
+ struct spi_s *spiobj = SPI_S(obj);
+ int spi_hz = 0;
+ uint8_t prescaler_rank = 0;
+ uint8_t last_index = (sizeof(baudrate_prescaler_table) / sizeof(baudrate_prescaler_table[0])) - 1;
+
+ spi_hz = dev_spi_clock_source_frequency_get(obj) / 2;
+
+ /* Config SPI prescaler according to input frequency*/
+ while ((spi_hz > hz) && (prescaler_rank < last_index)) {
+ spi_hz = spi_hz / 2;
+ prescaler_rank++;
+ }
+
+ spiobj->spi_struct.prescale = baudrate_prescaler_table[prescaler_rank];
+ dev_spi_struct_init(obj);
+}
+
+/** Write a block out in master mode and receive a value
+ *
+ * The total number of bytes sent and received will be the maximum of
+ * tx_length and rx_length. The bytes written will be padded with the
+ * value 0xff.
+ *
+ * @param[in] obj The SPI peripheral to use for sending
+ * @param[in] tx_buffer Pointer to the byte-array of data to write to the device
+ * @param[in] tx_length Number of bytes to write, may be zero
+ * @param[in] rx_buffer Pointer to the byte-array of data to read from the device
+ * @param[in] rx_length Number of bytes to read, may be zero
+ * @param[in] write_fill Default data transmitted while performing a read
+ * @returns
+ * The number of bytes written and read from the device. This is
+ * maximum of tx_length and rx_length.
+ */
+int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill)
+{
+ int total = (tx_length > rx_length) ? tx_length : rx_length;
+
+ for (int i = 0; i < total; i++) {
+ char out = (i < tx_length) ? tx_buffer[i] : write_fill;
+ char in = spi_master_write(obj, out);
+ if (i < rx_length) {
+ rx_buffer[i] = in;
+ }
+ }
+ return total;
+}
+
+/** Write a byte out in master mode and receive a value
+ *
+ * @param[in] obj The SPI peripheral to use for sending
+ * @param[in] value The value to send
+ * @return Returns the value received during send
+ */
+int spi_master_write(spi_t *obj, int value)
+{
+ int count = 0;
+ struct spi_s *spiobj = SPI_S(obj);
+
+ /* wait the SPI transmit buffer is empty */
+ while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE)) && (count++ < 1000));
+ if (count >= 1000) {
+ return -1;
+ } else {
+ spi_i2s_data_transmit(spiobj->spi, value);
+ }
+
+ count = 0;
+ /* wait the SPI receive buffer is not empty */
+ while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000));
+ if (count >= 1000) {
+ return -1;
+ } else {
+ return spi_i2s_data_receive(spiobj->spi);
+ }
+
+}
+
+/** Check if a value is available to read
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return non-zero if a value is available
+ */
+int spi_slave_receive(spi_t *obj)
+{
+ int status;
+ struct spi_s *spiobj = SPI_S(obj);
+ /* check whether or not the SPI receive buffer is empty */
+ status = ((spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE) != RESET) ? 1 : 0);
+ return status;
+}
+
+/** Get a received value out of the SPI receive buffer in slave mode
+ *
+ * Blocks until a value is available
+ * @param[in] obj The SPI peripheral to read
+ * @return The value received
+ */
+int spi_slave_read(spi_t *obj)
+{
+ int count = 0;
+ struct spi_s *spiobj = SPI_S(obj);
+ /* wait the SPI receive buffer is not empty */
+ while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000));
+ if (count >= 1000) {
+ return -1;
+ } else {
+ return spi_i2s_data_receive(spiobj->spi);
+ }
+}
+
+/** Write a value to the SPI peripheral in slave mode
+ *
+ * Blocks until the SPI peripheral can be written to
+ * @param[in] obj The SPI peripheral to write
+ * @param[in] value The value to write
+ */
+void spi_slave_write(spi_t *obj, int value)
+{
+ struct spi_s *spiobj = SPI_S(obj);
+ /* wait the SPI transmit buffer is empty */
+ while (RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE));
+ spi_i2s_data_transmit(spiobj->spi, value);
+}
+
+/** Checks if the specified SPI peripheral is in use
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return non-zero if the peripheral is currently transmitting
+ */
+int spi_busy(spi_t *obj)
+{
+ int status;
+ struct spi_s *spiobj = SPI_S(obj);
+ /* check whether or not the SPI is busy */
+ status = ((spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TRANS) != RESET) ? 1 : 0);
+ return status;
+}
+
+#endif
diff --git a/targets/TARGET_GigaDevice/TARGET_GD32E10X/us_ticker.c b/targets/TARGET_GigaDevice/TARGET_GD32E10X/us_ticker.c
new file mode 100644
index 0000000000..57dce4d758
--- /dev/null
+++ b/targets/TARGET_GigaDevice/TARGET_GD32E10X/us_ticker.c
@@ -0,0 +1,388 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 GigaDevice Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "gd32e10x.h"
+#include "us_ticker_api.h"
+#include "PeripheralNames.h"
+#include "hal_tick.h"
+
+#if TICKER_TIMER_WIDTH_BIT == 16
+uint32_t time_before;
+uint32_t total_elapsed_time;
+#endif
+
+/* this variable is set to 1 at the end of mbed_sdk_init function.
+the ticker_read_us() function must not be called until the mbed_sdk_init is terminated */
+extern int mbed_sdk_inited;
+uint32_t ticker_timer_cnt;
+uint32_t ticker_timer_ch0cv;
+uint32_t ticker_timer_dmainten;
+
+void ticker_timer_init(void);
+#if TICKER_TIMER_WIDTH_BIT == 16
+void ticker_16bits_timer_init(void);
+#else
+void ticker_32bits_timer_init(void);
+#endif
+void ticker_timer_irq_handler(void);
+/* get TIMER clock */
+static uint32_t timer_get_clock(uint32_t timer_periph);
+uint32_t ticker_tick_get(void);
+void ticker_timer_data_save(void);
+void ticker_timer_data_save(void);
+void ticker_timer_data_restore(void);
+
+void ticker_timer_init(void)
+{
+#if TICKER_TIMER_WIDTH_BIT == 16
+ ticker_16bits_timer_init();
+#else
+ ticker_32bits_timer_init();
+#endif
+}
+
+/** get tick
+ *
+ * @return the tick
+ */
+uint32_t ticker_tick_get(void)
+{
+#if TICKER_TIMER_WIDTH_BIT == 16
+ uint32_t new_time;
+ if (mbed_sdk_inited) {
+ /* Apply the latest time recorded just before the sdk is inited */
+ new_time = ticker_read_us(get_us_ticker_data()) + time_before;
+ time_before = 0;
+ return (new_time / 1000);
+ } else {
+ /* Prevent small values from subtracting large ones
+ example:
+ 0x0010-0xFFEE=FFFF0022 , (0xFFFF-0xFFEE+0x10+1=0x22,1 mean CNT=0 tick)
+ FFFF0022 & 0xFFFF = 0022
+ */
+ new_time = us_ticker_read();
+ total_elapsed_time += (new_time - time_before) & 0xFFFF;
+ time_before = new_time;
+ return (total_elapsed_time / 1000);
+ }
+#else // 32-bit timer
+ if (mbed_sdk_inited) {
+ return (ticker_read_us(get_us_ticker_data()) / 1000);
+ } else {
+ return (us_ticker_read() / 1000);
+ }
+#endif
+}
+
+/** Get frequency and counter bits of this ticker.
+ */
+const ticker_info_t *us_ticker_get_info()
+{
+ static const ticker_info_t info = {
+ 1000000,
+ TICKER_TIMER_WIDTH_BIT
+ };
+ return &info;
+}
+
+
+
+/* config for 32bits TIMER */
+#if TICKER_TIMER_WIDTH_BIT == 16
+/** config the interrupt handler
+ */
+void ticker_timer_irq_handler(void)
+{
+ if (SET == timer_interrupt_flag_get(TICKER_TIMER, TIMER_INT_FLAG_CH0)) {
+ timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
+ us_ticker_irq_handler();
+ }
+}
+
+/** initialize the TIMER
+ */
+void ticker_16bits_timer_init(void)
+{
+ timer_parameter_struct timer_initpara;
+ uint32_t timer_clk = timer_get_clock(TICKER_TIMER);
+
+ /* enable ticker timer clock */
+ TICKER_TIMER_RCU_CLOCK_ENABLE;
+
+ /* reset ticker timer peripheral */
+ TICKER_TIMER_RESET_ENABLE;
+ TICKER_TIMER_RESET_DISABLE;
+
+ /* TICKER_TIMER configuration */
+ timer_initpara.prescaler = (uint32_t)(timer_clk / 1000000) - 1;;
+ timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
+ timer_initpara.counterdirection = TIMER_COUNTER_UP;
+ timer_initpara.period = 0xFFFF;
+ timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
+ timer_initpara.repetitioncounter = 0;
+ timer_init(TICKER_TIMER, &timer_initpara);
+
+ /* auto-reload preload disable */
+ timer_auto_reload_shadow_disable(TICKER_TIMER);
+
+ /* configure TIMER channel enable state */
+ timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
+
+ /* configure TIMER primary output function */
+ timer_primary_output_config(TICKER_TIMER, ENABLE);
+
+ timer_enable(TICKER_TIMER);
+
+ /* Output compare channel 0 interrupt for mbed timeout */
+ NVIC_SetVector(TICKER_TIMER_IRQ, (uint32_t)ticker_timer_irq_handler);
+ NVIC_EnableIRQ(TICKER_TIMER_IRQ);
+
+ /* if define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json or other file,
+ hold the TICKER_TIMER counter for debug when core halted
+ */
+#if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TICKER_TIMER_DEBUG_STOP)
+ TICKER_TIMER_DEBUG_STOP;
+#endif
+
+ timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
+
+ /* used by ticker_tick_get() */
+ time_before = 0;
+ total_elapsed_time = 0;
+}
+/* config for 32bits TIMER */
+#else
+/** config the interrupt handler
+ */
+void ticker_timer_irq_handler(void)
+{
+ if (SET == timer_interrupt_flag_get(TICKER_TIMER, TIMER_INT_FLAG_CH0)) {
+ timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
+ us_ticker_irq_handler();
+ }
+}
+
+/** initialize the TIMER
+ */
+void ticker_32bits_timer_init(void)
+{
+ timer_parameter_struct timer_initpara;
+ uint32_t timer_clk = timer_get_clock(TICKER_TIMER);
+
+ /* enable ticker timer clock */
+ TICKER_TIMER_RCU_CLOCK_ENABLE;
+
+ /* reset ticker timer peripheral */
+ TICKER_TIMER_RESET_ENABLE;
+ TICKER_TIMER_RESET_DISABLE;
+
+ /* TICKER_TIMER configuration */
+ timer_initpara.prescaler = (uint32_t)(timer_clk / 1000000) - 1;;
+ timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
+ timer_initpara.counterdirection = TIMER_COUNTER_UP;
+ timer_initpara.period = 0xFFFFFFFF;
+ timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
+ timer_initpara.repetitioncounter = 0;
+ timer_init(TICKER_TIMER, &timer_initpara);
+
+ /* auto-reload preload disable */
+ timer_auto_reload_shadow_disable(TICKER_TIMER);
+
+ /* configure TIMER channel enable state */
+ timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
+
+ /* configure TIMER primary output function */
+ timer_primary_output_config(TICKER_TIMER, ENABLE);
+
+ timer_enable(TICKER_TIMER);
+
+ /* Output compare channel 0 interrupt for mbed timeout */
+ NVIC_SetVector(TICKER_TIMER_IRQ, (uint32_t)ticker_timer_irq_handler);
+ NVIC_EnableIRQ(TICKER_TIMER_IRQ);
+
+ /* if define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json or other file,
+ hold the TICKER_TIMER counter for debug when core halted
+ */
+#if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TICKER_TIMER_DEBUG_STOP)
+ TICKER_TIMER_DEBUG_STOP;
+#endif
+
+ timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
+}
+
+#endif /* 16-bit/32-bit timer init */
+
+/** Initialize the ticker
+ *
+ * Initialize or re-initialize the ticker. This resets all the
+ * clocking and prescaler registers, along with disabling
+ * the compare interrupt.
+ *
+ * @note Initialization properties tested by ::ticker_init_test
+ */
+void us_ticker_init(void)
+{
+ /* TIMER is already initialized in ticker_timer_init() */
+ /* disable the TIMER interrupt */
+ timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
+ /* configure TIMER channel enable state */
+ timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
+
+ /* configure TIMER primary output function */
+ timer_primary_output_config(TICKER_TIMER, ENABLE);
+
+ timer_enable(TICKER_TIMER);
+
+}
+
+/** Read the current counter
+ *
+ * Read the current counter value without performing frequency conversions.
+ * If no rollover has occurred, the seconds passed since us_ticker_init()
+ * was called can be found by dividing the ticks returned by this function
+ * by the frequency returned by ::us_ticker_get_info.
+ *
+ * @return The current timer's counter value in ticks
+ */
+uint32_t us_ticker_read()
+{
+ /* read TIMER counter value */
+ uint32_t count_value = 0U;
+ count_value = TIMER_CNT(TICKER_TIMER);
+ return (count_value);
+}
+
+/** Set interrupt for specified timestamp
+ *
+ * @param timestamp The time in ticks to be set
+ *
+ * @note no special handling needs to be done for times in the past
+ * as the common timer code will detect this and call
+ * us_ticker_fire_interrupt() if this is the case
+ *
+ * @note calling this function with timestamp of more than the supported
+ * number of bits returned by ::us_ticker_get_info results in undefined
+ * behavior.
+ */
+void us_ticker_set_interrupt(timestamp_t timestamp)
+{
+ /* configure TIMER channel output pulse value.Only set this value when you interrupt disabled */
+ timer_channel_output_pulse_value_config(TICKER_TIMER, TIMER_CH_0, (uint32_t)timestamp);
+ /* clear TIMER interrupt flag,enable the TIMER interrupt */
+ timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
+ timer_interrupt_enable(TICKER_TIMER, TIMER_INT_CH0);
+}
+
+/** Set pending interrupt that should be fired right away.
+ *
+ * The ticker should be initialized prior calling this function.
+ */
+void us_ticker_fire_interrupt(void)
+{
+ /* clear TIMER interrupt flag */
+ timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
+ /* channel 0 capture or compare event generation immediately,so CH0IF set for interrupt */
+ timer_event_software_generate(TICKER_TIMER, TIMER_EVENT_SRC_CH0G);
+ /* enable the TIMER interrupt */
+ timer_interrupt_enable(TICKER_TIMER, TIMER_INT_CH0);
+}
+
+/** Disable us ticker interrupt
+ */
+void us_ticker_disable_interrupt(void)
+{
+ /* disable the TIMER interrupt */
+ timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
+}
+
+/** Clear us ticker interrupt
+ * note: must be called with interrupts disabled function
+ */
+void us_ticker_clear_interrupt(void)
+{
+ /* clear TIMER interrupt flag */
+ timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
+}
+
+/** save ticker TIMER data when MCU go to deepsleep
+*/
+void ticker_timer_data_save(void)
+{
+ ticker_timer_cnt = TIMER_CNT(TICKER_TIMER);
+ ticker_timer_ch0cv = TIMER_CH0CV(TICKER_TIMER);
+ ticker_timer_dmainten = TIMER_DMAINTEN(TICKER_TIMER);
+}
+
+/** restore ticker TIMER data when MCU go out deepsleep
+*/
+void ticker_timer_data_restore(void)
+{
+ TIMER_CNT(TICKER_TIMER) = ticker_timer_cnt;
+ TIMER_CH0CV(TICKER_TIMER) = ticker_timer_ch0cv;
+ TIMER_DMAINTEN(TICKER_TIMER) = ticker_timer_dmainten;
+}
+
+/** Deinitialize the us ticker
+ *
+ * Powerdown the us ticker in preparation for sleep, powerdown, or reset.
+ *
+ * After this function is called, no other ticker functions should be called
+ * except us_ticker_init(), calling any function other than init is undefined.
+ *
+ * @note This function stops the ticker from counting.
+ */
+void us_ticker_free(void)
+{
+ /* configure TIMER channel enable state */
+ timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_DISABLE);
+ /* configure TIMER primary output function */
+ timer_primary_output_config(TICKER_TIMER, DISABLE);
+ /* disable a TIMER */
+ timer_disable(TICKER_TIMER);
+
+ us_ticker_disable_interrupt();
+}
+
+/** get TIMER clock
+ * @param timer_dev: TIMER device information structrue
+ the structure is not necessary to be reconfigured after structrue initialization,
+ the structure parameters altering is automatically configured by core
+ * @return TIMER clock
+*/
+static uint32_t timer_get_clock(uint32_t timer_periph)
+{
+ uint32_t timerclk;
+
+ if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph) ||
+ (TIMER8 == timer_periph) || (TIMER9 == timer_periph) || (TIMER10 == timer_periph)) {
+ /* get the current APB2 TIMER clock source */
+ if (RCU_APB2_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB2PSC)) {
+ timerclk = rcu_clock_freq_get(CK_APB2);
+ } else {
+ timerclk = rcu_clock_freq_get(CK_APB2) * 2;
+ }
+ } else {
+ /* get the current APB1 TIMER clock source */
+ if (RCU_APB1_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB1PSC)) {
+ timerclk = rcu_clock_freq_get(CK_APB1);
+ } else {
+ timerclk = rcu_clock_freq_get(CK_APB1) * 2;
+ }
+ }
+
+ return timerclk;
+}
diff --git a/targets/targets.json b/targets/targets.json
index e1fa4bdfdb..fb42d06f9a 100644
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -8042,5 +8042,27 @@
"overrides": {
"network-default-interface-type": "ETHERNET"
}
+ },
+ "GD32_E103VB": {
+ "inherits": ["GD32_Target"],
+ "supported_form_factors": ["ARDUINO"],
+ "core": "Cortex-M4",
+ "extra_labels_add": ["GD32E10X", "GD32E103VB"],
+ "device_has_add": [
+ "RTC",
+ "I2C",
+ "CAN",
+ "I2CSLAVE",
+ "ANALOGOUT",
+ "SPI",
+ "SPISLAVE",
+ "SERIAL_ASYNCH",
+ "SERIAL_FC",
+ "FLASH",
+ "SLEEP"
+ ],
+ "detect_code": ["1703"],
+ "macros_add": ["GD32E10X"],
+ "release_versions": ["5"]
}
}