1 /*!
2     \file    gd32e50x_gpio.c
3     \brief   GPIO driver
4 
5     \version 2020-03-10, V1.0.0, firmware for GD32E50x
6     \version 2020-08-26, V1.1.0, firmware for GD32E50x
7     \version 2021-03-23, V1.2.0, firmware for GD32E50x
8 */
9 
10 /*
11     Copyright (c) 2021, GigaDevice Semiconductor Inc.
12 
13     Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15 
16     1. Redistributions of source code must retain the above copyright notice, this
17        list of conditions and the following disclaimer.
18     2. Redistributions in binary form must reproduce the above copyright notice,
19        this list of conditions and the following disclaimer in the documentation
20        and/or other materials provided with the distribution.
21     3. Neither the name of the copyright holder nor the names of its contributors
22        may be used to endorse or promote products derived from this software without
23        specific prior written permission.
24 
25     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36 
37 #include "gd32e50x_gpio.h"
38 
39 #define AFIO_EXTI_SOURCE_MASK              ((uint8_t)0x03U)         /*!< AFIO exti source selection mask*/
40 #define AFIO_EXTI_SOURCE_FIELDS            ((uint8_t)0x04U)         /*!< select AFIO exti source registers */
41 #define LSB_16BIT_MASK                     ((uint16_t)0xFFFFU)      /*!< LSB 16-bit mask */
42 #define PCF_POSITION_MASK                  ((uint32_t)0x000F0000U)  /*!< AFIO_PCF register position mask */
43 #define PCF_SWJCFG_MASK                    ((uint32_t)0xF8FFFFFFU)  /*!< AFIO_PCF register SWJCFG mask */
44 #define PCF_LOCATION1_MASK                 ((uint32_t)0x00200000U)  /*!< AFIO_PCF register location1 mask */
45 #define PCF_LOCATION2_MASK                 ((uint32_t)0x00100000U)  /*!< AFIO_PCF register location2 mask */
46 #define AFIO_PCF1_FIELDS                   ((uint32_t)0x80000000U)  /*!< select AFIO_PCF1 register */
47 #define GPIO_OUTPUT_PORT_OFFSET            ((uint32_t)4U)           /*!< GPIO event output port offset*/
48 
49 /*!
50     \brief      reset GPIO port
51     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
52     \param[out] none
53     \retval     none
54 */
gpio_deinit(uint32_t gpio_periph)55 void gpio_deinit(uint32_t gpio_periph)
56 {
57     switch(gpio_periph){
58     case GPIOA:
59         /* reset GPIOA */
60         rcu_periph_reset_enable(RCU_GPIOARST);
61         rcu_periph_reset_disable(RCU_GPIOARST);
62         break;
63     case GPIOB:
64         /* reset GPIOB */
65         rcu_periph_reset_enable(RCU_GPIOBRST);
66         rcu_periph_reset_disable(RCU_GPIOBRST);
67         break;
68     case GPIOC:
69         /* reset GPIOC */
70         rcu_periph_reset_enable(RCU_GPIOCRST);
71         rcu_periph_reset_disable(RCU_GPIOCRST);
72         break;
73     case GPIOD:
74         /* reset GPIOD */
75         rcu_periph_reset_enable(RCU_GPIODRST);
76         rcu_periph_reset_disable(RCU_GPIODRST);
77         break;
78     case GPIOE:
79         /* reset GPIOE */
80         rcu_periph_reset_enable(RCU_GPIOERST);
81         rcu_periph_reset_disable(RCU_GPIOERST);
82         break;
83     case GPIOF:
84         /* reset GPIOF */
85         rcu_periph_reset_enable(RCU_GPIOFRST);
86         rcu_periph_reset_disable(RCU_GPIOFRST);
87         break;
88     case GPIOG:
89         /* reset GPIOG */
90         rcu_periph_reset_enable(RCU_GPIOGRST);
91         rcu_periph_reset_disable(RCU_GPIOGRST);
92         break;
93     default:
94         break;
95     }
96 }
97 
98 /*!
99     \brief      reset alternate function I/O(AFIO)
100     \param[in]  none
101     \param[out] none
102     \retval     none
103 */
gpio_afio_deinit(void)104 void gpio_afio_deinit(void)
105 {
106     rcu_periph_reset_enable(RCU_AFRST);
107     rcu_periph_reset_disable(RCU_AFRST);
108 }
109 
110 /*!
111     \brief      GPIO parameter initialization
112     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
113     \param[in]  mode: gpio pin mode
114                 only one parameter can be selected which is shown as below:
115       \arg        GPIO_MODE_AIN: analog input mode
116       \arg        GPIO_MODE_IN_FLOATING: floating input mode
117       \arg        GPIO_MODE_IPD: pull-down input mode
118       \arg        GPIO_MODE_IPU: pull-up input mode
119       \arg        GPIO_MODE_OUT_OD: GPIO output with open-drain
120       \arg        GPIO_MODE_OUT_PP: GPIO output with push-pull
121       \arg        GPIO_MODE_AF_OD: AFIO output with open-drain
122       \arg        GPIO_MODE_AF_PP: AFIO output with push-pull
123     \param[in]  speed: gpio output max speed value
124                 only one parameter can be selected which is shown as below:
125       \arg        GPIO_OSPEED_10MHZ: output max speed 10MHz
126       \arg        GPIO_OSPEED_2MHZ: output max speed 2MHz
127       \arg        GPIO_OSPEED_50MHZ: output max speed 50MHz
128       \arg        GPIO_OSPEED_MAX: output max speed more than 50MHz
129     \param[in]  pin: GPIO pin
130                 one or more parameters can be selected which are shown as below:
131       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
132     \param[out] none
133     \retval     none
134 */
gpio_init(uint32_t gpio_periph,uint32_t mode,uint32_t speed,uint32_t pin)135 void gpio_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin)
136 {
137     uint16_t i;
138     uint32_t temp_mode = 0U;
139     uint32_t reg = 0U;
140 
141     /* GPIO mode configuration */
142     temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
143 
144     /* GPIO speed configuration */
145     if(((uint32_t)0x00U) != ((uint32_t)mode & ((uint32_t)0x10U))){
146         /* output mode max speed */
147         if(GPIO_OSPEED_MAX == (uint32_t)speed){
148             temp_mode |= (uint32_t)0x03U;
149             /* set the corresponding SPD bit */
150             GPIOx_SPD(gpio_periph) |= (uint32_t)pin ;
151         }else{
152             /* output mode max speed:10MHz,2MHz,50MHz */
153             temp_mode |= (uint32_t)speed;
154         }
155     }
156 
157     /* configure the eight low port pins with GPIO_CTL0 */
158     for(i = 0U;i < 8U;i++){
159         if((1U << i) & pin){
160             reg = GPIO_CTL0(gpio_periph);
161 
162             /* clear the specified pin mode bits */
163             reg &= ~GPIO_MODE_MASK(i);
164             /* set the specified pin mode bits */
165             reg |= GPIO_MODE_SET(i, temp_mode);
166 
167             /* set IPD or IPU */
168             if(GPIO_MODE_IPD == mode){
169                 /* reset the corresponding OCTL bit */
170                 GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
171             }else{
172                 /* set the corresponding OCTL bit */
173                 if(GPIO_MODE_IPU == mode){
174                     GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
175                 }
176             }
177             /* set GPIO_CTL0 register */
178             GPIO_CTL0(gpio_periph) = reg;
179         }
180     }
181     /* configure the eight high port pins with GPIO_CTL1 */
182     for(i = 8U;i < 16U;i++){
183         if((1U << i) & pin){
184             reg = GPIO_CTL1(gpio_periph);
185 
186             /* clear the specified pin mode bits */
187             reg &= ~GPIO_MODE_MASK(i - 8U);
188             /* set the specified pin mode bits */
189             reg |= GPIO_MODE_SET(i - 8U, temp_mode);
190 
191             /* set IPD or IPU */
192             if(GPIO_MODE_IPD == mode){
193                 /* reset the corresponding OCTL bit */
194                 GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
195             }else{
196                 /* set the corresponding OCTL bit */
197                 if(GPIO_MODE_IPU == mode){
198                     GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
199                 }
200             }
201             /* set GPIO_CTL1 register */
202             GPIO_CTL1(gpio_periph) = reg;
203         }
204     }
205 }
206 
207 /*!
208     \brief      set GPIO pin bit
209     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
210     \param[in]  pin: GPIO pin
211                 one or more parameters can be selected which are shown as below:
212       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
213     \param[out] none
214     \retval     none
215 */
gpio_bit_set(uint32_t gpio_periph,uint32_t pin)216 void gpio_bit_set(uint32_t gpio_periph,uint32_t pin)
217 {
218     GPIO_BOP(gpio_periph) = (uint32_t)pin;
219 }
220 
221 /*!
222     \brief      reset GPIO pin bit
223     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
224     \param[in]  pin: GPIO pin
225                 one or more parameters can be selected which are shown as below:
226       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
227     \param[out] none
228     \retval     none
229 */
gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)230 void gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)
231 {
232     GPIO_BC(gpio_periph) = (uint32_t)pin;
233 }
234 
235 /*!
236     \brief      write data to the specified GPIO pin
237     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
238     \param[in]  pin: GPIO pin
239                 one or more parameters can be selected which are shown as below:
240       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
241     \param[in]  bit_value: SET or RESET
242       \arg        RESET: clear the port pin
243       \arg        SET: set the port pin
244     \param[out] none
245     \retval     none
246 */
gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value)247 void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value)
248 {
249     if(RESET != bit_value){
250         GPIO_BOP(gpio_periph) = (uint32_t)pin;
251     }else{
252         GPIO_BC(gpio_periph) = (uint32_t)pin;
253     }
254 }
255 
256 /*!
257     \brief      write data to the specified GPIO port
258     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
259     \param[in]  data: specify the value to be written to the port output data register
260     \param[out] none
261     \retval     none
262 */
gpio_port_write(uint32_t gpio_periph,uint16_t data)263 void gpio_port_write(uint32_t gpio_periph,uint16_t data)
264 {
265     GPIO_OCTL(gpio_periph) = (uint32_t)data;
266 }
267 
268 /*!
269     \brief      get GPIO pin input status
270     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
271     \param[in]  pin: GPIO pin
272                 only one parameter can be selected which are shown as below:
273       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
274     \param[out] none
275     \retval     input status of gpio pin: SET or RESET
276 */
gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)277 FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
278 {
279     if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
280         return SET;
281     }else{
282         return RESET;
283     }
284 }
285 
286 /*!
287     \brief      get GPIO port input status
288     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
289     \param[out] none
290     \retval     input status of gpio all pins
291 */
gpio_input_port_get(uint32_t gpio_periph)292 uint16_t gpio_input_port_get(uint32_t gpio_periph)
293 {
294     return (uint16_t)(GPIO_ISTAT(gpio_periph));
295 }
296 
297 /*!
298     \brief      get GPIO pin output status
299     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
300     \param[in]  pin: GPIO pin
301                 only one parameter can be selected which are shown as below:
302       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
303     \param[out] none
304     \retval     output status of gpio pin: SET or RESET
305 */
gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin)306 FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin)
307 {
308     if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
309         return SET;
310     }else{
311         return RESET;
312     }
313 }
314 
315 /*!
316     \brief      get GPIO port output status
317     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
318     \param[out] none
319     \retval     output status of gpio all pins
320 */
gpio_output_port_get(uint32_t gpio_periph)321 uint16_t gpio_output_port_get(uint32_t gpio_periph)
322 {
323     return ((uint16_t)GPIO_OCTL(gpio_periph));
324 }
325 
326 /*!
327     \brief      configure GPIO pin remap
328     \param[in]  gpio_remap: select the pin to remap
329                 only one parameter can be selected which are shown as below:
330       \arg        GPIO_SPI0_REMAP: SPI0 remapping
331       \arg        GPIO_I2C0_REMAP: I2C0 remapping
332       \arg        GPIO_USART0_REMAP: USART0 remapping
333       \arg        GPIO_USART1_REMAP: USART1 remapping
334       \arg        GPIO_USART2_PARTIAL_REMAP: USART2 partial remapping
335       \arg        GPIO_USART2_FULL_REMAP: USART2 full remapping
336       \arg        GPIO_TIMER0_PARTIAL_REMAP: TIMER0 partial remapping
337       \arg        GPIO_TIMER0_FULL_REMAP: TIMER0 full remapping
338       \arg        GPIO_TIMER1_PARTIAL_REMAP0: TIMER1 partial remapping
339       \arg        GPIO_TIMER1_PARTIAL_REMAP1: TIMER1 partial remapping
340       \arg        GPIO_TIMER1_FULL_REMAP: TIMER1 full remapping
341       \arg        GPIO_TIMER2_PARTIAL_REMAP: TIMER2 partial remapping
342       \arg        GPIO_TIMER2_FULL_REMAP: TIMER2 full remapping
343       \arg        GPIO_TIMER3_REMAP: TIMER3 remapping
344       \arg        GPIO_CAN0_PARTIAL_REMAP: CAN0 partial remapping(not support on GD32EPRT devices)
345       \arg        GPIO_CAN0_FULL_REMAP: CAN0 full remapping(not support on GD32EPRT devices)
346       \arg        GPIO_PD01_REMAP: PD01 remapping
347       \arg        GPIO_TIMER4CH3_IREMAP: TIMER4 channel3 internal remapping
348       \arg        GPIO_ADC0_ETRGINS_REMAP: ADC0 external trigger inserted conversion remapping(only for GD32E50X_HD devices and GD32E50X_XD devices)
349       \arg        GPIO_ADC0_ETRGREG_REMAP: ADC0 external trigger regular conversion remapping(only for GD32E50X_HD devices and GD32E50X_XD devices)
350       \arg        GPIO_ADC1_ETRGINS_REMAP: ADC1 external trigger inserted conversion remapping(only for GD32E50X_HD devices and GD32E50X_XD devices)
351       \arg        GPIO_ADC1_ETRGREG_REMAP: ADC1 external trigger regular conversion remapping(only for GD32E50X_HD devices and GD32E50X_XD devices)
352       \arg        GPIO_ENET_REMAP: ENET remapping(only for GD32E50X_CL devices)
353       \arg        GPIO_CAN1_REMAP: CAN1 remapping(not support on GD32EPRT devices)
354       \arg        GPIO_SWJ_NONJTRST_REMAP: full SWJ(JTAG-DP + SW-DP),but without NJTRST
355       \arg        GPIO_SWJ_SWDPENABLE_REMAP: JTAG-DP disabled and SW-DP enabled
356       \arg        GPIO_SWJ_DISABLE_REMAP: JTAG-DP disabled and SW-DP disabled
357       \arg        GPIO_SPI2_REMAP: SPI2 remapping
358       \arg        GPIO_TIMER1ITR0_REMAP: TIMER1 internal trigger 0 remapping(only for GD32E50X_CL devices)
359       \arg        GPIO_PTP_PPS_REMAP: ethernet PTP PPS remapping(only for GD32E50X_CL devices)
360       \arg        GPIO_TIMER8_REMAP: TIMER8 remapping(not support on GD32EPRT devices)
361       \arg        GPIO_TIMER9_REMAP: TIMER9 remapping(not support on GD32EPRT devices)
362       \arg        GPIO_TIMER10_REMAP: TIMER10 remapping(not support on GD32EPRT devices)
363       \arg        GPIO_TIMER12_REMAP: TIMER12 remapping(not support on GD32EPRT devices)
364       \arg        GPIO_TIMER13_REMAP: TIMER13 remapping(not support on GD32EPRT devices)
365       \arg        GPIO_EXMC_NADV_REMAP: EXMC_NADV connect/disconnect
366       \arg        GPIO_CTC_REMAP0: CTC remapping(PD15)
367       \arg        GPIO_CTC_REMAP1: CTC remapping(PF0)
368     \param[in]  newvalue: ENABLE or DISABLE
369     \param[out] none
370     \retval     none
371 */
gpio_pin_remap_config(uint32_t remap,ControlStatus newvalue)372 void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue)
373 {
374     uint32_t remap1 = 0U, remap2 = 0U, temp_reg = 0U, temp_mask = 0U;
375 
376     if(((uint32_t)0x80000000U) == (remap & 0x80000000U)){
377         /* get AFIO_PCF1 regiter value */
378         temp_reg = AFIO_PCF1;
379     }else{
380         /* get AFIO_PCF0 regiter value */
381         temp_reg = AFIO_PCF0;
382     }
383 
384     temp_mask = (remap & PCF_POSITION_MASK) >> 0x10U;
385     remap1 = remap & LSB_16BIT_MASK;
386 
387     /* judge pin remap type */
388     if((PCF_LOCATION1_MASK | PCF_LOCATION2_MASK) == (remap & (PCF_LOCATION1_MASK | PCF_LOCATION2_MASK))){
389         temp_reg &= PCF_SWJCFG_MASK;
390         AFIO_PCF0 &= PCF_SWJCFG_MASK;
391     }else if(PCF_LOCATION2_MASK == (remap & PCF_LOCATION2_MASK)){
392         remap2 = ((uint32_t)0x03U) << temp_mask;
393         temp_reg &= ~remap2;
394         temp_reg |= ~PCF_SWJCFG_MASK;
395     }else{
396         temp_reg &= ~(remap1 << ((remap >> 0x15U)*0x10U));
397         temp_reg |= ~PCF_SWJCFG_MASK;
398     }
399 
400     /* set pin remap value */
401     if(DISABLE != newvalue){
402         temp_reg |= (remap1 << ((remap >> 0x15U)*0x10U));
403     }
404 
405     if(AFIO_PCF1_FIELDS == (remap & AFIO_PCF1_FIELDS)){
406         /* set AFIO_PCF1 regiter value */
407         AFIO_PCF1 = temp_reg;
408     }else{
409         /* set AFIO_PCF0 regiter value */
410         AFIO_PCF0 = temp_reg;
411     }
412 }
413 
414 /*!
415     \brief      configure AFIO port alternate function
416     \param[in]  afio_function: select the port AFIO function(SHRTIMER not support on GD32EPRT devices)
417                 only one parameter can be selected which are shown as below:
418       \arg        AFIO_PA2_CMP1_CFG: configure PA2 alternate function to CMP1
419       \arg        AFIO_PA3_USBHS_CFG: configure PA3 alternate function to USBHS
420       \arg        AFIO_PA5_USBHS_CFG: configure PA5 alternate function to USBHS
421       \arg        AFIO_PA8_I2C2_CFG: configure PA8 alternate function to I2C2
422       \arg        AFIO_PA8_SHRTIMER_CFG: configure PA8 alternate function to SHRTIMER
423       \arg        AFIO_PA9_CAN2_CFG: configure PA9 alternate function to CAN2(not support on GD32EPRT devices)
424       \arg        AFIO_PA9_I2C2_CFG: configure PA9 alternate function to I2C2
425       \arg        AFIO_PA9_SHRTIMER_CFG: configure PA9 alternate function to SHRTIMER
426       \arg        AFIO_PA10_CAN2_CFG: configure PA10 alternate function to CAN2(not support on GD32EPRT devices)
427       \arg        AFIO_PA10_CMP5_CFG: configure PA10 alternate function to CMP5
428       \arg        AFIO_PA10_SHRTIMER_CFG: configure PA10 alternate function to SHRTIMER
429       \arg        AFIO_PA11_USART5_CFG: configure PA11 alternate function to USART5
430       \arg        AFIO_PA11_SHRTIMER_CFG: configure PA11 alternate function to SHRTIMER
431       \arg        AFIO_PA12_CMP1_CFG: configure PA12 alternate function to CMP1
432       \arg        AFIO_PA12_USART5_CFG: configure PA12 alternate function to USART5
433       \arg        AFIO_PA12_SHRTIMER_CFG: configure PA12 alternate function to SHRTIMER
434       \arg        AFIO_PA15_SHRTIMER_CFG: configure PA15 alternate function to SHRTIMER
435       \arg        AFIO_PB0_USBHS_CFG: configure PB0 alternate function to USBHS
436       \arg        AFIO_PB1_CMP3_CFG: configure PB1 alternate function to CMP3
437       \arg        AFIO_PB1_USBHS_CFG: configure PB1 alternate function to USBHS
438       \arg        AFIO_PB1_SHRTIMER_CFG: configure PB1 alternate function to SHRTIMER
439       \arg        AFIO_PB2_USBHS_CFG: configure PB2 alternate function to USBHS
440       \arg        AFIO_PB2_SHRTIMER_CFG: configure PB2 alternate function to SHRTIMER
441       \arg        AFIO_PB3_SHRTIMER_CFG: configure PB3 alternate function to SHRTIMER
442       \arg        AFIO_PB4_I2S2_CFG: configure PB4 alternate function to I2S2
443       \arg        AFIO_PB4_I2C2_CFG: configure PB4 alternate function to I2C2
444       \arg        AFIO_PB4_SHRTIMER_CFG: configure PB4 alternate function to SHRTIMER
445       \arg        AFIO_PB5_I2C2_CFG: configure PB5 alternate function to I2C2
446       \arg        AFIO_PB5_USBHS_CFG: configure PB5 alternate function to USBHS
447       \arg        AFIO_PB5_SHRTIMER_CFG: configure PB5 alternate function to SHRTIMER
448       \arg        AFIO_PB6_SHRTIMER_CFG: configure PB6 alternate function to SHRTIMER
449       \arg        AFIO_PB7_SHRTIMER_CFG: configure PB7 alternate function to SHRTIMER
450       \arg        AFIO_PB8_I2C2_CFG: configure PB8 alternate function to I2C2
451       \arg        AFIO_PB8_SHRTIMER_CFG: configure PB8 alternate function to SHRTIMER
452       \arg        AFIO_PB9_CMP1_CFG: configure PB9 alternate function to CMP1
453       \arg        AFIO_PB9_SHRTIMER_CFG: configure PB9 alternate function to SHRTIMER
454       \arg        AFIO_PB10_CAN2_CFG: configure PB10 alternate function to CAN2(not support on GD32EPRT devices)
455       \arg        AFIO_PB10_USBHS_CFG: configure PB10 alternate function to USBHS
456       \arg        AFIO_PB10_SHRTIMER_CFG: configure PB10 alternate function to SHRTIMER
457       \arg        AFIO_PB11_CAN2_CFG: configure PB11 alternate function to CAN2(not support on GD32EPRT devices)
458       \arg        AFIO_PB11_USBHS_CFG: configure PB11 alternate function to USBHS
459       \arg        AFIO_PB11_SHRTIMER_CFG: configure PB11 alternate function to SHRTIMER
460       \arg        AFIO_PB12_USBHS_CFG: configure PB12 alternate function to USBHS
461       \arg        AFIO_PB12_SHRTIMER_CFG: configure PB12 alternate function to SHRTIMER
462       \arg        AFIO_PB13_USBHS_CFG: configure PB13 alternate function to USBHS
463       \arg        AFIO_PB13_SHRTIMER_CFG: configure PB13 alternate function to SHRTIMER
464       \arg        AFIO_PB14_I2S1_CFG: configure PB14 alternate function to I2S1
465       \arg        AFIO_PB14_SHRTIMER_CFG: configure PB14 alternate function to SHRTIMER
466       \arg        AFIO_PB15_SHRTIMER_CFG: configure PB15 alternate function to SHRTIMER
467       \arg        AFIO_PC0_USBHS_CFG: configure PC0 alternate function to USBHS
468       \arg        AFIO_PC2_I2S1_CFG: configure PC2 alternate function to I2S1
469       \arg        AFIO_PC2_USBHS_CFG: configure PC2 alternate function to USBHS
470       \arg        AFIO_PC3_USBHS_CFG: configure PC3 alternate function to USBHS
471       \arg        AFIO_PC6_CMP5_CFG: configure PC6 alternate function to CMP5
472       \arg        AFIO_PC6_USART5_CFG: configure PC6 alternate function to USART5
473       \arg        AFIO_PC6_SHRTIMER_CFG: configure PC6 alternate function to SHRTIMER
474       \arg        AFIO_PC7_USART5_CFG: configure PC7 alternate function to USART5
475       \arg        AFIO_PC7_SHRTIMER_CFG: configure PC7 alternate function to SHRTIMER
476       \arg        AFIO_PC8_USART5_CFG: configure PC8 alternate function to USART5
477       \arg        AFIO_PC8_SHRTIMER_CFG: configure PC8 alternate function to SHRTIMER
478       \arg        AFIO_PC9_I2C2_CFG: configure PC9 alternate function to I2C2
479       \arg        AFIO_PC9_SHRTIMER_CFG: configure PC9 alternate function to SHRTIMER
480       \arg        AFIO_PC10_I2C2_CFG: configure PC10 alternate function to I2C2
481       \arg        AFIO_PC11_I2S2_CFG: configure PC11 alternate function to I2S2
482       \arg        AFIO_PC11_SHRTIMER_CFG: configure PC11 alternate function to SHRTIMER
483       \arg        AFIO_PC12_SHRTIMER_CFG: configure PC12 alternate function to SHRTIMER
484       \arg        AFIO_PD4_SHRTIMER_CFG: configure PD4 alternate function to SHRTIMER
485       \arg        AFIO_PD5_SHRTIMER_CFG: configure PD5 alternate function to SHRTIMER
486       \arg        AFIO_PE0_CAN2_CFG: configure PE0 alternate function to CAN2(not support on GD32EPRT devices)
487       \arg        AFIO_PE0_SHRTIMER_CFG: configure PE0 alternate function to SHRTIMER
488       \arg        AFIO_PE1_CAN2_CFG: configure PE1 alternate function to CAN2(not support on GD32EPRT devices)
489       \arg        AFIO_PE1_SHRTIMER_CFG: configure PE1 alternate function to SHRTIMER
490       \arg        AFIO_PE8_CMP1_CFG: configure PE8 alternate function to CMP1
491       \arg        AFIO_PE9_CMP3_CFG: configure PE9 alternate function to CMP3
492       \arg        AFIO_PE10_CMP5_CFG: configure PE10 alternate function to CMP5
493       \arg        AFIO_PE11_CMP5_CFG: configure PE11 alternate function to CMP5
494       \arg        AFIO_PE12_CMP3_CFG: configure PE12 alternate function to CMP3
495       \arg        AFIO_PE13_CMP1_CFG: configure PE13 alternate function to CMP1
496       \arg        AFIO_PG6_SHRTIMER_CFG: configure PG6 alternate function to SHRTIMER
497       \arg        AFIO_PG7_USART5_CFG: configure PG7 alternate function to USART5
498       \arg        AFIO_PG7_SHRTIMER_CFG: configure PG7 alternate function to SHRTIMER
499       \arg        AFIO_PG9_USART5_CFG: configure PG9 alternate function to USART5
500       \arg        AFIO_PG10_SHRTIMER_CFG: configure PG10 alternate function to SHRTIMER
501       \arg        AFIO_PG11_SHRTIMER_CFG: configure PG11 alternate function to SHRTIMER
502       \arg        AFIO_PG12_SHRTIMER_CFG: configure PG12 alternate function to SHRTIMER
503       \arg        AFIO_PG13_SHRTIMER_CFG: configure PG13 alternate function to SHRTIMER
504       \arg        AFIO_PG14_USART5_CFG: configure PG14 alternate function to USART5
505     \param[in]  newvalue: ENABLE or DISABLE
506     \param[out] none
507     \retval     none
508 */
gpio_afio_port_config(uint32_t afio_function,ControlStatus newvalue)509 void gpio_afio_port_config(uint32_t afio_function, ControlStatus newvalue)
510 {
511     uint32_t remap1 = 0U, remap2 = 0U, temp_reg = 0U, temp_mask = 0U;
512 
513     /* get AFIO_PCFx(x=A,B,C,D,E,G) regiter value */
514     temp_reg = REG32(AFIO+0x0000003CU+((afio_function>>24)<<2));
515 
516     temp_mask = (afio_function & PCF_POSITION_MASK) >> 0x10U;
517     remap1 = afio_function & LSB_16BIT_MASK;
518 
519     /* judge port function select type */
520     if(afio_function & PCF_LOCATION2_MASK){
521         remap2 = ((uint32_t)0x03U) << temp_mask;
522         remap2 = (remap2 << (((afio_function & PCF_LOCATION1_MASK) >> 0x15U)*0x10U));
523         temp_reg &= ~remap2;
524     }else{
525         temp_reg &= ~(remap1 << (((afio_function & PCF_LOCATION1_MASK) >> 0x15U)*0x10U));
526     }
527 
528     /* set pin remap value */
529     if(DISABLE != newvalue){
530         temp_reg |= (remap1 << (((afio_function & PCF_LOCATION1_MASK) >> 0x15U)*0x10U));
531     }
532 
533     /* set AFIO_PCFx(x=A,B,C,D,E,G) regiter value */
534     REG32(AFIO+0x0000003CU+((afio_function>>24)<<2)) = temp_reg;
535 }
536 
537 #if (defined(GD32E50X_CL) || defined(GD32EPRT))
538 /*!
539     \brief      select ethernet MII or RMII PHY
540     \param[in]  enet_sel: ethernet MII or RMII PHY selection
541       \arg        GPIO_ENET_PHY_MII: configure ethernet MAC for connection with an MII PHY
542       \arg        GPIO_ENET_PHY_RMII: configure ethernet MAC for connection with an RMII PHY
543     \param[out] none
544     \retval     none
545 */
gpio_ethernet_phy_select(uint32_t enet_sel)546 void gpio_ethernet_phy_select(uint32_t enet_sel)
547 {
548     /* clear AFIO_PCF0_ENET_PHY_SEL bit */
549     AFIO_PCF0 &= (uint32_t)(~AFIO_PCF0_ENET_PHY_SEL);
550 
551     /* select MII or RMII PHY */
552     AFIO_PCF0 |= (uint32_t)enet_sel;
553 }
554 #endif /* GD32E50X_CL||GD32EPRT */
555 
556 /*!
557     \brief      select GPIO pin exti sources
558     \param[in]  output_port: gpio event output port
559                 only one parameter can be selected which are shown as below:
560       \arg        GPIO_PORT_SOURCE_GPIOA: output port source A
561       \arg        GPIO_PORT_SOURCE_GPIOB: output port source B
562       \arg        GPIO_PORT_SOURCE_GPIOC: output port source C
563       \arg        GPIO_PORT_SOURCE_GPIOD: output port source D
564       \arg        GPIO_PORT_SOURCE_GPIOE: output port source E
565       \arg        GPIO_PORT_SOURCE_GPIOF: output port source F
566       \arg        GPIO_PORT_SOURCE_GPIOG: output port source G
567     \param[in]  output_pin: GPIO output pin source
568                 only one parameter can be selected which are shown as below:
569       \arg        GPIO_PIN_SOURCE_x(x=0..15)
570     \param[out] none
571     \retval     none
572 */
gpio_exti_source_select(uint8_t output_port,uint8_t output_pin)573 void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin)
574 {
575     uint32_t source = 0U;
576     source = ((uint32_t)0x0FU) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK));
577 
578     /* select EXTI sources */
579     if(GPIO_PIN_SOURCE_4 > output_pin){
580         /* select EXTI0/EXTI1/EXTI2/EXTI3 */
581         AFIO_EXTISS0 &= ~source;
582         AFIO_EXTISS0 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
583     }else if(GPIO_PIN_SOURCE_8 > output_pin){
584         /* select EXTI4/EXTI5/EXTI6/EXTI7 */
585         AFIO_EXTISS1 &= ~source;
586         AFIO_EXTISS1 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
587     }else if(GPIO_PIN_SOURCE_12 > output_pin){
588         /* select EXTI8/EXTI9/EXTI10/EXTI11 */
589         AFIO_EXTISS2 &= ~source;
590         AFIO_EXTISS2 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
591     }else{
592         /* select EXTI12/EXTI13/EXTI14/EXTI15 */
593         AFIO_EXTISS3 &= ~source;
594         AFIO_EXTISS3 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
595     }
596 }
597 
598 /*!
599     \brief      configure GPIO pin event output
600     \param[in]  output_port: gpio event output port
601                 only one parameter can be selected which are shown as below:
602       \arg        GPIO_EVENT_PORT_GPIOA: event output port A
603       \arg        GPIO_EVENT_PORT_GPIOB: event output port B
604       \arg        GPIO_EVENT_PORT_GPIOC: event output port C
605       \arg        GPIO_EVENT_PORT_GPIOD: event output port D
606       \arg        GPIO_EVENT_PORT_GPIOE: event output port E
607     \param[in]  output_pin: GPIO event output pin
608                 only one parameter can be selected which are shown as below:
609       \arg        GPIO_EVENT_PIN_x(x=0..15)
610     \param[out] none
611     \retval     none
612 */
gpio_event_output_config(uint8_t output_port,uint8_t output_pin)613 void gpio_event_output_config(uint8_t output_port, uint8_t output_pin)
614 {
615     uint32_t reg = 0U;
616     reg = AFIO_EC;
617 
618     /* clear AFIO_EC_PORT and AFIO_EC_PIN bits */
619     reg &= (uint32_t)(~(AFIO_EC_PORT|AFIO_EC_PIN));
620 
621     reg |= (uint32_t)((uint32_t)output_port << GPIO_OUTPUT_PORT_OFFSET);
622     reg |= (uint32_t)output_pin;
623 
624     AFIO_EC = reg;
625 }
626 
627 /*!
628     \brief      enable GPIO pin event output
629     \param[in]  none
630     \param[out] none
631     \retval     none
632 */
gpio_event_output_enable(void)633 void gpio_event_output_enable(void)
634 {
635     AFIO_EC |= AFIO_EC_EOE;
636 }
637 
638 /*!
639     \brief      disable GPIO pin event output
640     \param[in]  none
641     \param[out] none
642     \retval     none
643 */
gpio_event_output_disable(void)644 void gpio_event_output_disable(void)
645 {
646     AFIO_EC &= (uint32_t)(~AFIO_EC_EOE);
647 }
648 
649 /*!
650     \brief      lock GPIO pin bit
651     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
652     \param[in]  pin: GPIO pin
653                 one or more parameters can be selected which are shown as below:
654       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
655     \param[out] none
656     \retval     none
657 */
gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)658 void gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)
659 {
660     uint32_t lock = 0x00010000U;
661     lock |= pin;
662 
663     /* lock key writing sequence: write 1 -> write 0 -> write 1 -> read 0 -> read 1 */
664     GPIO_LOCK(gpio_periph) = (uint32_t)lock;
665     GPIO_LOCK(gpio_periph) = (uint32_t)pin;
666     GPIO_LOCK(gpio_periph) = (uint32_t)lock;
667     lock = GPIO_LOCK(gpio_periph);
668     lock = GPIO_LOCK(gpio_periph);
669 }
670 
671 /*!
672     \brief      configure the I/O compensation cell
673     \param[in]  compensation: specifies the I/O compensation cell mode
674                 only one parameter can be selected which are shown as below:
675       \arg        GPIO_COMPENSATION_ENABLE: I/O compensation cell is enabled
676       \arg        GPIO_COMPENSATION_DISABLE: I/O compensation cell is disabled
677     \param[out] none
678     \retval     none
679 */
gpio_compensation_config(uint32_t compensation)680 void gpio_compensation_config(uint32_t compensation)
681 {
682     uint32_t reg;
683     reg = AFIO_CPSCTL;
684 
685     /* reset the AFIO_CPSCTL_CPS_EN bit and set according to gpio_compensation */
686     reg &= ~AFIO_CPSCTL_CPS_EN;
687     AFIO_CPSCTL = (reg | compensation);
688 }
689 
690 /*!
691     \brief      check the I/O compensation cell is ready or not
692     \param[in]  none
693     \param[out] none
694     \retval     FlagStatus: SET or RESET
695   */
gpio_compensation_flag_get(void)696 FlagStatus gpio_compensation_flag_get(void)
697 {
698     if(((uint32_t)RESET) != (AFIO_CPSCTL & AFIO_CPSCTL_CPS_RDY)){
699         return SET;
700     }else{
701         return RESET;
702     }
703 }
704