1 /*!
2     \file    gd32f403_gpio.c
3     \brief   GPIO driver
4 
5     \version 2017-02-10, V1.0.0, firmware for GD32F403
6     \version 2018-12-25, V2.0.0, firmware for GD32F403
7     \version 2020-09-30, V2.1.0, firmware for GD32F403
8 */
9 
10 /*
11     Copyright (c) 2020, 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 "gd32f403_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
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
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_TIMER2_PARTIAL_REMAP: TIMER2 partial remapping
339       \arg        GPIO_TIMER2_FULL_REMAP: TIMER2 full remapping
340       \arg        GPIO_TIMER3_REMAP: TIMER3 remapping
341       \arg        GPIO_CAN0_PARTIAL_REMAP: CAN0 partial remapping
342       \arg        GPIO_CAN0_FULL_REMAP: CAN0 full remapping
343       \arg        GPIO_PD01_REMAP: PD01 remapping
344       \arg        GPIO_ADC0_ETRGINS_REMAP: ADC0 external trigger inserted conversion remapping
345       \arg        GPIO_ADC0_ETRGREG_REMAP: ADC0 external trigger regular conversion remapping
346       \arg        GPIO_ADC1_ETRGINS_REMAP: ADC1 external trigger inserted conversion remapping
347       \arg        GPIO_ADC1_ETRGREG_REMAP: ADC1 external trigger regular conversion remapping
348       \arg        GPIO_CAN1_REMAP: CAN1 remapping
349       \arg        GPIO_SWJ_NONJTRST_REMAP: full SWJ(JTAG-DP + SW-DP),but without NJTRST
350       \arg        GPIO_SWJ_SWDPENABLE_REMAP: JTAG-DP disabled and SW-DP enabled
351       \arg        GPIO_SWJ_DISABLE_REMAP: JTAG-DP disabled and SW-DP disabled
352       \arg        GPIO_SPI2_REMAP: SPI2 remapping
353       \arg        GPIO_TIMER8_REMAP: TIMER8 remapping
354       \arg        GPIO_TIMER9_REMAP: TIMER9 remapping
355       \arg        GPIO_TIMER10_REMAP: TIMER10 remapping
356       \arg        GPIO_TIMER12_REMAP: TIMER12 remapping
357       \arg        GPIO_TIMER13_REMAP: TIMER13 remapping
358       \arg        GPIO_EXMC_NADV_REMAP: EXMC_NADV connect/disconnect
359       \arg        GPIO_CTC_REMAP0: CTC remapping(PD15)
360       \arg        GPIO_CTC_REMAP1: CTC remapping(PF0)
361     \param[in]  newvalue: ENABLE or DISABLE
362     \param[out] none
363     \retval     none
364 */
gpio_pin_remap_config(uint32_t remap,ControlStatus newvalue)365 void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue)
366 {
367     uint32_t remap1 = 0U, remap2 = 0U, temp_reg = 0U, temp_mask = 0U;
368 
369     if(((uint32_t)0x80000000U) == (remap & 0x80000000U)){
370         /* get AFIO_PCF1 regiter value */
371         temp_reg = AFIO_PCF1;
372     }else{
373         /* get AFIO_PCF0 regiter value */
374         temp_reg = AFIO_PCF0;
375     }
376 
377     temp_mask = (remap & PCF_POSITION_MASK) >> 0x10U;
378     remap1 = remap & LSB_16BIT_MASK;
379 
380     /* judge pin remap type */
381     if((PCF_LOCATION1_MASK | PCF_LOCATION2_MASK) == (remap & (PCF_LOCATION1_MASK | PCF_LOCATION2_MASK))){
382         temp_reg &= PCF_SWJCFG_MASK;
383         AFIO_PCF0 &= PCF_SWJCFG_MASK;
384     }else if(PCF_LOCATION2_MASK == (remap & PCF_LOCATION2_MASK)){
385         remap2 = ((uint32_t)0x03U) << temp_mask;
386         temp_reg &= ~remap2;
387         temp_reg |= ~PCF_SWJCFG_MASK;
388     }else{
389         temp_reg &= ~(remap1 << ((remap >> 0x15U)*0x10U));
390         temp_reg |= ~PCF_SWJCFG_MASK;
391     }
392 
393     /* set pin remap value */
394     if(DISABLE != newvalue){
395         temp_reg |= (remap1 << ((remap >> 0x15U)*0x10U));
396     }
397 
398     if(AFIO_PCF1_FIELDS == (remap & AFIO_PCF1_FIELDS)){
399         /* set AFIO_PCF1 regiter value */
400         AFIO_PCF1 = temp_reg;
401     }else{
402         /* set AFIO_PCF0 regiter value */
403         AFIO_PCF0 = temp_reg;
404     }
405 }
406 
407 /*!
408     \brief      select GPIO pin exti sources
409     \param[in]  output_port: gpio event output port
410                 only one parameter can be selected which are shown as below:
411       \arg        GPIO_PORT_SOURCE_GPIOA: output port source A
412       \arg        GPIO_PORT_SOURCE_GPIOB: output port source B
413       \arg        GPIO_PORT_SOURCE_GPIOC: output port source C
414       \arg        GPIO_PORT_SOURCE_GPIOD: output port source D
415       \arg        GPIO_PORT_SOURCE_GPIOE: output port source E
416       \arg        GPIO_PORT_SOURCE_GPIOF: output port source F
417       \arg        GPIO_PORT_SOURCE_GPIOG: output port source G
418     \param[in]  output_pin: GPIO output pin source
419                 only one parameter can be selected which are shown as below:
420       \arg        GPIO_PIN_SOURCE_x(x=0..15)
421     \param[out] none
422     \retval     none
423 */
gpio_exti_source_select(uint8_t output_port,uint8_t output_pin)424 void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin)
425 {
426     uint32_t source = 0U;
427     source = ((uint32_t)0x0FU) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK));
428 
429     /* select EXTI sources */
430     if(GPIO_PIN_SOURCE_4 > output_pin){
431         /* select EXTI0/EXTI1/EXTI2/EXTI3 */
432         AFIO_EXTISS0 &= ~source;
433         AFIO_EXTISS0 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
434     }else if(GPIO_PIN_SOURCE_8 > output_pin){
435         /* select EXTI4/EXTI5/EXTI6/EXTI7 */
436         AFIO_EXTISS1 &= ~source;
437         AFIO_EXTISS1 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
438     }else if(GPIO_PIN_SOURCE_12 > output_pin){
439         /* select EXTI8/EXTI9/EXTI10/EXTI11 */
440         AFIO_EXTISS2 &= ~source;
441         AFIO_EXTISS2 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
442     }else{
443         /* select EXTI12/EXTI13/EXTI14/EXTI15 */
444         AFIO_EXTISS3 &= ~source;
445         AFIO_EXTISS3 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
446     }
447 }
448 
449 /*!
450     \brief      configure GPIO pin event output
451     \param[in]  output_port: gpio event output port
452                 only one parameter can be selected which are shown as below:
453       \arg        GPIO_EVENT_PORT_GPIOA: event output port A
454       \arg        GPIO_EVENT_PORT_GPIOB: event output port B
455       \arg        GPIO_EVENT_PORT_GPIOC: event output port C
456       \arg        GPIO_EVENT_PORT_GPIOD: event output port D
457       \arg        GPIO_EVENT_PORT_GPIOE: event output port E
458     \param[in]  output_pin: GPIO event output pin
459                 only one parameter can be selected which are shown as below:
460       \arg        GPIO_EVENT_PIN_x(x=0..15)
461     \param[out] none
462     \retval     none
463 */
gpio_event_output_config(uint8_t output_port,uint8_t output_pin)464 void gpio_event_output_config(uint8_t output_port, uint8_t output_pin)
465 {
466     uint32_t reg = 0U;
467     reg = AFIO_EC;
468 
469     /* clear AFIO_EC_PORT and AFIO_EC_PIN bits */
470     reg &= (uint32_t)(~(AFIO_EC_PORT|AFIO_EC_PIN));
471 
472     reg |= (uint32_t)((uint32_t)output_port << GPIO_OUTPUT_PORT_OFFSET);
473     reg |= (uint32_t)output_pin;
474 
475     AFIO_EC = reg;
476 }
477 
478 /*!
479     \brief      enable GPIO pin event output
480     \param[in]  none
481     \param[out] none
482     \retval     none
483 */
gpio_event_output_enable(void)484 void gpio_event_output_enable(void)
485 {
486     AFIO_EC |= AFIO_EC_EOE;
487 }
488 
489 /*!
490     \brief      disable GPIO pin event output
491     \param[in]  none
492     \param[out] none
493     \retval     none
494 */
gpio_event_output_disable(void)495 void gpio_event_output_disable(void)
496 {
497     AFIO_EC &= (uint32_t)(~AFIO_EC_EOE);
498 }
499 
500 /*!
501     \brief      lock GPIO pin
502     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E,F,G)
503     \param[in]  pin: GPIO pin
504                 one or more parameters can be selected which are shown as below:
505       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
506     \param[out] none
507     \retval     none
508 */
gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)509 void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
510 {
511     uint32_t lock = 0x00010000U;
512     lock |= pin;
513 
514     /* lock key writing sequence: write 1 -> write 0 -> write 1 -> read 0 -> read 1 */
515     GPIO_LOCK(gpio_periph) = (uint32_t)lock;
516     GPIO_LOCK(gpio_periph) = (uint32_t)pin;
517     GPIO_LOCK(gpio_periph) = (uint32_t)lock;
518     lock = GPIO_LOCK(gpio_periph);
519     lock = GPIO_LOCK(gpio_periph);
520 }
521 
522 /*!
523     \brief      configure the I/O compensation cell
524     \param[in]  compensation: specifies the I/O compensation cell mode
525                 only one parameter can be selected which are shown as below:
526       \arg        GPIO_COMPENSATION_ENABLE: I/O compensation cell is enabled
527       \arg        GPIO_COMPENSATION_DISABLE: I/O compensation cell is disabled
528     \param[out] none
529     \retval     none
530 */
gpio_compensation_config(uint32_t compensation)531 void gpio_compensation_config(uint32_t compensation)
532 {
533     uint32_t reg;
534     reg = AFIO_CPSCTL;
535 
536     /* reset the AFIO_CPSCTL_CPS_EN bit and set according to gpio_compensation */
537     reg &= ~AFIO_CPSCTL_CPS_EN;
538     AFIO_CPSCTL = (reg | compensation);
539 }
540 
541 /*!
542     \brief      check the I/O compensation cell is ready or not
543     \param[in]  none
544     \param[out] none
545     \retval     FlagStatus: SET or RESET
546   */
gpio_compensation_flag_get(void)547 FlagStatus gpio_compensation_flag_get(void)
548 {
549     if(((uint32_t)RESET) != (AFIO_CPSCTL & AFIO_CPSCTL_CPS_RDY)){
550         return SET;
551     }else{
552         return RESET;
553     }
554 }
555