1 /*!
2     \file    gd32e10x_gpio.c
3     \brief   GPIO driver
4 
5     \version 2017-12-26, V1.0.0, firmware for GD32E10x
6     \version 2020-09-30, V1.1.0, firmware for GD32E10x
7     \version 2020-12-31, V1.2.0, firmware for GD32E10x
8     \version 2022-06-30, V1.3.0, firmware for GD32E10x
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32e10x_gpio.h"
39 
40 #define AFIO_EXTI_SOURCE_MASK              ((uint8_t)0x03U)         /*!< AFIO exti source selection mask*/
41 #define AFIO_EXTI_SOURCE_FIELDS            ((uint8_t)0x04U)         /*!< select AFIO exti source registers */
42 #define LSB_16BIT_MASK                     ((uint16_t)0xFFFFU)      /*!< LSB 16-bit mask */
43 #define PCF_POSITION_MASK                  ((uint32_t)0x000F0000U)  /*!< AFIO_PCF register position mask */
44 #define PCF_SWJCFG_MASK                    ((uint32_t)0xF8FFFFFFU)  /*!< AFIO_PCF register SWJCFG mask */
45 #define PCF_LOCATION1_MASK                 ((uint32_t)0x00200000U)  /*!< AFIO_PCF register location1 mask */
46 #define PCF_LOCATION2_MASK                 ((uint32_t)0x00100000U)  /*!< AFIO_PCF register location2 mask */
47 #define AFIO_PCF1_FIELDS                   ((uint32_t)0x80000000U)  /*!< select AFIO_PCF1 register */
48 #define GPIO_OUTPUT_PORT_OFFSET            ((uint32_t)4U)           /*!< GPIO event output port offset*/
49 
50 /*!
51     \brief      reset GPIO port
52     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
53     \param[out] none
54     \retval     none
55 */
gpio_deinit(uint32_t gpio_periph)56 void gpio_deinit(uint32_t gpio_periph)
57 {
58     switch(gpio_periph){
59     case GPIOA:
60         /* reset GPIOA */
61         rcu_periph_reset_enable(RCU_GPIOARST);
62         rcu_periph_reset_disable(RCU_GPIOARST);
63         break;
64     case GPIOB:
65         /* reset GPIOB */
66         rcu_periph_reset_enable(RCU_GPIOBRST);
67         rcu_periph_reset_disable(RCU_GPIOBRST);
68         break;
69     case GPIOC:
70         /* reset GPIOC */
71         rcu_periph_reset_enable(RCU_GPIOCRST);
72         rcu_periph_reset_disable(RCU_GPIOCRST);
73         break;
74     case GPIOD:
75         /* reset GPIOD */
76         rcu_periph_reset_enable(RCU_GPIODRST);
77         rcu_periph_reset_disable(RCU_GPIODRST);
78         break;
79     case GPIOE:
80         /* reset GPIOE */
81         rcu_periph_reset_enable(RCU_GPIOERST);
82         rcu_periph_reset_disable(RCU_GPIOERST);
83         break;
84     default:
85         break;
86     }
87 }
88 
89 /*!
90     \brief      reset alternate function I/O(AFIO)
91     \param[in]  none
92     \param[out] none
93     \retval     none
94 */
gpio_afio_deinit(void)95 void gpio_afio_deinit(void)
96 {
97     rcu_periph_reset_enable(RCU_AFRST);
98     rcu_periph_reset_disable(RCU_AFRST);
99 }
100 
101 /*!
102     \brief      GPIO parameter initialization
103     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
104     \param[in]  mode: gpio pin mode
105                 only one parameter can be selected which is shown as below:
106       \arg        GPIO_MODE_AIN: analog input mode
107       \arg        GPIO_MODE_IN_FLOATING: floating input mode
108       \arg        GPIO_MODE_IPD: pull-down input mode
109       \arg        GPIO_MODE_IPU: pull-up input mode
110       \arg        GPIO_MODE_OUT_OD: GPIO output with open-drain
111       \arg        GPIO_MODE_OUT_PP: GPIO output with push-pull
112       \arg        GPIO_MODE_AF_OD: AFIO output with open-drain
113       \arg        GPIO_MODE_AF_PP: AFIO output with push-pull
114     \param[in]  speed: gpio output max speed value
115                 only one parameter can be selected which is shown as below:
116       \arg        GPIO_OSPEED_10MHZ: output max speed 10MHz
117       \arg        GPIO_OSPEED_2MHZ: output max speed 2MHz
118       \arg        GPIO_OSPEED_50MHZ: output max speed 50MHz
119       \arg        GPIO_OSPEED_MAX: output max speed more than 50MHz
120     \param[in]  pin: GPIO pin
121                 one or more parameters can be selected which are shown as below:
122       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
123     \param[out] none
124     \retval     none
125 */
gpio_init(uint32_t gpio_periph,uint32_t mode,uint32_t speed,uint32_t pin)126 void gpio_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin)
127 {
128     uint16_t i;
129     uint32_t temp_mode = 0U;
130     uint32_t reg = 0U;
131 
132     /* GPIO mode configuration */
133     temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
134 
135     /* GPIO speed configuration */
136     if(((uint32_t)0x00U) != ((uint32_t)mode & ((uint32_t)0x10U))){
137         /* output mode max speed */
138         if(GPIO_OSPEED_MAX == (uint32_t)speed){
139             temp_mode |= (uint32_t)0x03U;
140             /* set the corresponding SPD bit */
141             GPIOx_SPD(gpio_periph) |= (uint32_t)pin ;
142         }else{
143             /* output mode max speed:10MHz,2MHz,50MHz */
144             temp_mode |= (uint32_t)speed;
145         }
146     }
147 
148     /* configure the eight low port pins with GPIO_CTL0 */
149     for(i = 0U;i < 8U;i++){
150         if((1U << i) & pin){
151             reg = GPIO_CTL0(gpio_periph);
152 
153             /* clear the specified pin mode bits */
154             reg &= ~GPIO_MODE_MASK(i);
155             /* set the specified pin mode bits */
156             reg |= GPIO_MODE_SET(i, temp_mode);
157 
158             /* set IPD or IPU */
159             if(GPIO_MODE_IPD == mode){
160                 /* reset the corresponding OCTL bit */
161                 GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
162             }else{
163                 /* set the corresponding OCTL bit */
164                 if(GPIO_MODE_IPU == mode){
165                     GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
166                 }
167             }
168             /* set GPIO_CTL0 register */
169             GPIO_CTL0(gpio_periph) = reg;
170         }
171     }
172     /* configure the eight high port pins with GPIO_CTL1 */
173     for(i = 8U;i < 16U;i++){
174         if((1U << i) & pin){
175             reg = GPIO_CTL1(gpio_periph);
176 
177             /* clear the specified pin mode bits */
178             reg &= ~GPIO_MODE_MASK(i - 8U);
179             /* set the specified pin mode bits */
180             reg |= GPIO_MODE_SET(i - 8U, temp_mode);
181 
182             /* set IPD or IPU */
183             if(GPIO_MODE_IPD == mode){
184                 /* reset the corresponding OCTL bit */
185                 GPIO_BC(gpio_periph) = (uint32_t)((1U << i) & pin);
186             }else{
187                 /* set the corresponding OCTL bit */
188                 if(GPIO_MODE_IPU == mode){
189                     GPIO_BOP(gpio_periph) = (uint32_t)((1U << i) & pin);
190                 }
191             }
192             /* set GPIO_CTL1 register */
193             GPIO_CTL1(gpio_periph) = reg;
194         }
195     }
196 }
197 
198 /*!
199     \brief      set GPIO pin
200     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
201     \param[in]  pin: GPIO pin
202                 one or more parameters can be selected which are shown as below:
203       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
204     \param[out] none
205     \retval     none
206 */
gpio_bit_set(uint32_t gpio_periph,uint32_t pin)207 void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
208 {
209     GPIO_BOP(gpio_periph) = (uint32_t)pin;
210 }
211 
212 /*!
213     \brief      reset GPIO pin
214     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
215     \param[in]  pin: GPIO pin
216                 one or more parameters can be selected which are shown as below:
217       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
218     \param[out] none
219     \retval     none
220 */
gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)221 void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
222 {
223     GPIO_BC(gpio_periph) = (uint32_t)pin;
224 }
225 
226 /*!
227     \brief      write data to the specified GPIO pin
228     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
229     \param[in]  pin: GPIO pin
230                 one or more parameters can be selected which are shown as below:
231       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
232     \param[in]  bit_value: SET or RESET
233       \arg        RESET: clear the port pin
234       \arg        SET: set the port pin
235     \param[out] none
236     \retval     none
237 */
gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value)238 void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
239 {
240     if(RESET != bit_value){
241         GPIO_BOP(gpio_periph) = (uint32_t)pin;
242     }else{
243         GPIO_BC(gpio_periph) = (uint32_t)pin;
244     }
245 }
246 
247 /*!
248     \brief      write data to the specified GPIO port
249     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
250     \param[in]  data: specify the value to be written to the port output data register
251     \param[out] none
252     \retval     none
253 */
gpio_port_write(uint32_t gpio_periph,uint16_t data)254 void gpio_port_write(uint32_t gpio_periph,uint16_t data)
255 {
256     GPIO_OCTL(gpio_periph) = (uint32_t)data;
257 }
258 
259 /*!
260     \brief      get GPIO pin input status
261     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
262     \param[in]  pin: GPIO pin
263                 only one parameter can be selected which are shown as below:
264       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
265     \param[out] none
266     \retval     input status of gpio pin: SET or RESET
267 */
gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)268 FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
269 {
270     if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
271         return SET;
272     }else{
273         return RESET;
274     }
275 }
276 
277 /*!
278     \brief      get GPIO port input status
279     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
280     \param[out] none
281     \retval     input status of gpio all pins
282 */
gpio_input_port_get(uint32_t gpio_periph)283 uint16_t gpio_input_port_get(uint32_t gpio_periph)
284 {
285     return (uint16_t)(GPIO_ISTAT(gpio_periph));
286 }
287 
288 /*!
289     \brief      get GPIO pin output status
290     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
291     \param[in]  pin: GPIO pin
292                 only one parameter can be selected which are shown as below:
293       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
294     \param[out] none
295     \retval     output status of gpio pin: SET or RESET
296 */
gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin)297 FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
298 {
299     if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
300         return SET;
301     }else{
302         return RESET;
303     }
304 }
305 
306 /*!
307     \brief      get GPIO port output status
308     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
309     \param[out] none
310     \retval     output status of gpio all pins
311 */
gpio_output_port_get(uint32_t gpio_periph)312 uint16_t gpio_output_port_get(uint32_t gpio_periph)
313 {
314     return ((uint16_t)GPIO_OCTL(gpio_periph));
315 }
316 
317 /*!
318     \brief      configure GPIO pin remap
319     \param[in]  gpio_remap: select the pin to remap
320                 only one parameter can be selected which are shown as below:
321       \arg        GPIO_SPI0_REMAP: SPI0 remapping
322       \arg        GPIO_I2C0_REMAP: I2C0 remapping
323       \arg        GPIO_USART0_REMAP: USART0 remapping
324       \arg        GPIO_USART1_REMAP: USART1 remapping
325       \arg        GPIO_USART2_PARTIAL_REMAP: USART2 partial remapping
326       \arg        GPIO_USART2_FULL_REMAP: USART2 full remapping
327       \arg        GPIO_TIMER0_PARTIAL_REMAP: TIMER0 partial remapping
328       \arg        GPIO_TIMER0_FULL_REMAP: TIMER0 full remapping
329       \arg        GPIO_TIMER1_PARTIAL_REMAP0: TIMER1 partial remapping
330       \arg        GPIO_TIMER1_PARTIAL_REMAP1: TIMER1 partial remapping
331       \arg        GPIO_TIMER1_FULL_REMAP: TIMER1 full remapping
332       \arg        GPIO_TIMER2_PARTIAL_REMAP: TIMER2 partial remapping
333       \arg        GPIO_TIMER2_FULL_REMAP: TIMER2 full remapping
334       \arg        GPIO_TIMER3_REMAP: TIMER3 remapping
335       \arg        GPIO_CAN0_PARTIAL_REMAP: CAN0 partial remapping
336       \arg        GPIO_CAN0_FULL_REMAP: CAN0 full remapping
337       \arg        GPIO_PD01_REMAP: PD01 remapping
338       \arg        GPIO_TIMER4CH3_IREMAP: TIMER4 channel3 internal remapping
339       \arg        GPIO_ADC0_ETRGRT_REMAP: ADC0 external trigger routine conversion remapping
340       \arg        GPIO_ADC1_ETRGRT_REMAP: ADC1 external trigger routine conversion remapping
341       \arg        GPIO_CAN1_REMAP: CAN1 remapping
342       \arg        GPIO_SWJ_NONJTRST_REMAP: full SWJ(JTAG-DP + SW-DP),but without NJTRST
343       \arg        GPIO_SWJ_SWDPENABLE_REMAP: JTAG-DP disabled and SW-DP enabled
344       \arg        GPIO_SWJ_DISABLE_REMAP: JTAG-DP disabled and SW-DP disabled
345       \arg        GPIO_SPI2_REMAP: SPI2 remapping
346       \arg        GPIO_TIMER1ITI1_REMAP: TIMER1 internal trigger 1 remapping
347       \arg        GPIO_TIMER8_REMAP: TIMER8 remapping
348       \arg        GPIO_EXMC_NADV_REMAP: EXMC_NADV connect/disconnect
349       \arg        GPIO_CTC_REMAP0: CTC remapping(PD15)
350     \param[in]  newvalue: ENABLE or DISABLE
351     \param[out] none
352     \retval     none
353 */
gpio_pin_remap_config(uint32_t remap,ControlStatus newvalue)354 void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue)
355 {
356     uint32_t remap1 = 0U, remap2 = 0U, temp_reg = 0U, temp_mask = 0U;
357 
358     if(((uint32_t)0x80000000U) == (remap & 0x80000000U)){
359         /* get AFIO_PCF1 regiter value */
360         temp_reg = AFIO_PCF1;
361     }else{
362         /* get AFIO_PCF0 regiter value */
363         temp_reg = AFIO_PCF0;
364     }
365 
366     temp_mask = (remap & PCF_POSITION_MASK) >> 0x10U;
367     remap1 = remap & LSB_16BIT_MASK;
368 
369     /* judge pin remap type */
370     if((PCF_LOCATION1_MASK | PCF_LOCATION2_MASK) == (remap & (PCF_LOCATION1_MASK | PCF_LOCATION2_MASK))){
371         temp_reg &= PCF_SWJCFG_MASK;
372         AFIO_PCF0 &= PCF_SWJCFG_MASK;
373     }else if(PCF_LOCATION2_MASK == (remap & PCF_LOCATION2_MASK)){
374         remap2 = ((uint32_t)0x03U) << temp_mask;
375         temp_reg &= ~remap2;
376         temp_reg |= ~PCF_SWJCFG_MASK;
377     }else{
378         temp_reg &= ~(remap1 << ((remap >> 0x15U)*0x10U));
379         temp_reg |= ~PCF_SWJCFG_MASK;
380     }
381 
382     /* set pin remap value */
383     if(DISABLE != newvalue){
384         temp_reg |= (remap1 << ((remap >> 0x15U)*0x10U));
385     }
386 
387     if(AFIO_PCF1_FIELDS == (remap & AFIO_PCF1_FIELDS)){
388         /* set AFIO_PCF1 regiter value */
389         AFIO_PCF1 = temp_reg;
390     }else{
391         /* set AFIO_PCF0 regiter value */
392         AFIO_PCF0 = temp_reg;
393     }
394 }
395 
396 /*!
397     \brief      select GPIO pin exti sources
398     \param[in]  output_port: gpio event output port
399                 only one parameter can be selected which are shown as below:
400       \arg        GPIO_PORT_SOURCE_GPIOA: output port source A
401       \arg        GPIO_PORT_SOURCE_GPIOB: output port source B
402       \arg        GPIO_PORT_SOURCE_GPIOC: output port source C
403       \arg        GPIO_PORT_SOURCE_GPIOD: output port source D
404       \arg        GPIO_PORT_SOURCE_GPIOE: output port source E
405     \param[in]  output_pin:
406                 only one parameter can be selected which are shown as below:
407       \arg        GPIO_PIN_SOURCE_x(x=0..15)
408     \param[out] none
409     \retval     none
410 */
gpio_exti_source_select(uint8_t output_port,uint8_t output_pin)411 void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin)
412 {
413     uint32_t source = 0U;
414     source = ((uint32_t)0x0FU) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK));
415 
416     /* select EXTI sources */
417     if(GPIO_PIN_SOURCE_4 > output_pin){
418         /* select EXTI0/EXTI1/EXTI2/EXTI3 */
419         AFIO_EXTISS0 &= ~source;
420         AFIO_EXTISS0 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
421     }else if(GPIO_PIN_SOURCE_8 > output_pin){
422         /* select EXTI4/EXTI5/EXTI6/EXTI7 */
423         AFIO_EXTISS1 &= ~source;
424         AFIO_EXTISS1 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
425     }else if(GPIO_PIN_SOURCE_12 > output_pin){
426         /* select EXTI8/EXTI9/EXTI10/EXTI11 */
427         AFIO_EXTISS2 &= ~source;
428         AFIO_EXTISS2 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
429     }else{
430         /* select EXTI12/EXTI13/EXTI14/EXTI15 */
431         AFIO_EXTISS3 &= ~source;
432         AFIO_EXTISS3 |= (((uint32_t)output_port) << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)));
433     }
434 }
435 
436 /*!
437     \brief      configure GPIO pin event output
438     \param[in]  output_port: gpio event output port
439                 only one parameter can be selected which are shown as below:
440       \arg        GPIO_EVENT_PORT_GPIOA: event output port A
441       \arg        GPIO_EVENT_PORT_GPIOB: event output port B
442       \arg        GPIO_EVENT_PORT_GPIOC: event output port C
443       \arg        GPIO_EVENT_PORT_GPIOD: event output port D
444       \arg        GPIO_EVENT_PORT_GPIOE: event output port E
445     \param[in]  output_pin:
446                 only one parameter can be selected which are shown as below:
447       \arg        GPIO_EVENT_PIN_x(x=0..15)
448     \param[out] none
449     \retval     none
450 */
gpio_event_output_config(uint8_t output_port,uint8_t output_pin)451 void gpio_event_output_config(uint8_t output_port, uint8_t output_pin)
452 {
453     uint32_t reg = 0U;
454     reg = AFIO_EC;
455 
456     /* clear AFIO_EC_PORT and AFIO_EC_PIN bits */
457     reg &= (uint32_t)(~(AFIO_EC_PORT|AFIO_EC_PIN));
458 
459     reg |= (uint32_t)((uint32_t)output_port << GPIO_OUTPUT_PORT_OFFSET);
460     reg |= (uint32_t)output_pin;
461 
462     AFIO_EC = reg;
463 }
464 
465 /*!
466     \brief      enable GPIO pin event output
467     \param[in]  none
468     \param[out] none
469     \retval     none
470 */
gpio_event_output_enable(void)471 void gpio_event_output_enable(void)
472 {
473     AFIO_EC |= AFIO_EC_EOE;
474 }
475 
476 /*!
477     \brief      disable GPIO pin event output
478     \param[in]  none
479     \param[out] none
480     \retval     none
481 */
gpio_event_output_disable(void)482 void gpio_event_output_disable(void)
483 {
484     AFIO_EC &= (uint32_t)(~AFIO_EC_EOE);
485 }
486 
487 /*!
488     \brief      lock GPIO pin
489     \param[in]  gpio_periph: GPIOx(x = A,B,C,D,E)
490     \param[in]  pin: GPIO pin
491                 one or more parameters can be selected which are shown as below:
492       \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
493     \param[out] none
494     \retval     none
495 */
gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)496 void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
497 {
498     uint32_t lock = 0x00010000U;
499     lock |= pin;
500 
501     /* lock key writing sequence: write 1 -> write 0 -> write 1 -> read 0 -> read 1 */
502     GPIO_LOCK(gpio_periph) = (uint32_t)lock;
503     GPIO_LOCK(gpio_periph) = (uint32_t)pin;
504     GPIO_LOCK(gpio_periph) = (uint32_t)lock;
505     lock = GPIO_LOCK(gpio_periph);
506     lock = GPIO_LOCK(gpio_periph);
507 }
508 
509 /*!
510     \brief      configure the I/O compensation cell
511     \param[in]  compensation: specifies the I/O compensation cell mode
512                 only one parameter can be selected which are shown as below:
513       \arg        GPIO_COMPENSATION_ENABLE: I/O compensation cell is enabled
514       \arg        GPIO_COMPENSATION_DISABLE: I/O compensation cell is disabled
515     \param[out] none
516     \retval     none
517 */
gpio_compensation_config(uint32_t compensation)518 void gpio_compensation_config(uint32_t compensation)
519 {
520     uint32_t reg;
521     reg = AFIO_CPSCTL;
522 
523     /* reset the AFIO_CPSCTL_CPS_EN bit and set according to gpio_compensation */
524     reg &= ~AFIO_CPSCTL_CPS_EN;
525     AFIO_CPSCTL = (reg | compensation);
526 }
527 
528 /*!
529     \brief      check the I/O compensation cell is ready or not
530     \param[in]  none
531     \param[out] none
532     \retval     FlagStatus: SET or RESET
533   */
gpio_compensation_flag_get(void)534 FlagStatus gpio_compensation_flag_get(void)
535 {
536     if(((uint32_t)RESET) != (AFIO_CPSCTL & AFIO_CPSCTL_CPS_RDY)){
537         return SET;
538     }else{
539         return RESET;
540     }
541 }
542