1 /*!
2 \file gd32a50x_gpio.c
3 \brief GPIO driver
4
5 \version 2022-01-30, V1.0.0, firmware for GD32A50x
6 */
7
8 /*
9 Copyright (c) 2022, GigaDevice Semiconductor Inc.
10
11 Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13
14 1. Redistributions of source code must retain the above copyright notice, this
15 list of conditions and the following disclaimer.
16 2. Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 3. Neither the name of the copyright holder nor the names of its contributors
20 may be used to endorse or promote products derived from this software without
21 specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34
35 #include "gd32a50x_gpio.h"
36
37 /*!
38 \brief reset GPIO port
39 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
40 only one parameter can be selected which is shown as below:
41 \arg GPIOx(x = A,B,C,D,E,F)
42 \param[out] none
43 \retval none
44 */
gpio_deinit(uint32_t gpio_periph)45 void gpio_deinit(uint32_t gpio_periph)
46 {
47 switch(gpio_periph){
48 case GPIOA:
49 /* reset GPIOA */
50 rcu_periph_reset_enable(RCU_GPIOARST);
51 rcu_periph_reset_disable(RCU_GPIOARST);
52 break;
53 case GPIOB:
54 /* reset GPIOB */
55 rcu_periph_reset_enable(RCU_GPIOBRST);
56 rcu_periph_reset_disable(RCU_GPIOBRST);
57 break;
58 case GPIOC:
59 /* reset GPIOC */
60 rcu_periph_reset_enable(RCU_GPIOCRST);
61 rcu_periph_reset_disable(RCU_GPIOCRST);
62 break;
63 case GPIOD:
64 /* reset GPIOD */
65 rcu_periph_reset_enable(RCU_GPIODRST);
66 rcu_periph_reset_disable(RCU_GPIODRST);
67 break;
68 case GPIOE:
69 /* reset GPIOE */
70 rcu_periph_reset_enable(RCU_GPIOERST);
71 rcu_periph_reset_disable(RCU_GPIOERST);
72 break;
73 case GPIOF:
74 /* reset GPIOF */
75 rcu_periph_reset_enable(RCU_GPIOFRST);
76 rcu_periph_reset_disable(RCU_GPIOFRST);
77 break;
78 default:
79 break;
80 }
81 }
82
83 /*!
84 \brief set GPIO mode
85 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
86 only one parameter can be selected which is shown as below:
87 \arg GPIOx(x = A,B,C,D,E,F)
88 \param[in] mode: gpio pin mode
89 only one parameter can be selected which is shown as below:
90 \arg GPIO_MODE_INPUT: input mode
91 \arg GPIO_MODE_OUTPUT: output mode
92 \arg GPIO_MODE_AF: alternate function mode
93 \arg GPIO_MODE_ANALOG: analog mode
94 \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor
95 only one parameter can be selected which is shown as below:
96 \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors
97 \arg GPIO_PUPD_PULLUP: with pull-up resistor
98 \arg GPIO_PUPD_PULLDOWN:with pull-down resistor
99 \param[in] pin: GPIO pin
100 one or more parameters can be selected which are shown as below:
101 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
102 \param[out] none
103 \retval none
104 */
gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin)105 void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
106 {
107 uint16_t i;
108 uint32_t ctl, pupd;
109
110 ctl = GPIO_CTL(gpio_periph);
111 pupd = GPIO_PUD(gpio_periph);
112
113 for(i = 0U;i < 16U;i++){
114 if((((uint32_t)1U << i)) & pin){
115 /* clear the specified pin mode bits */
116 ctl &= ~GPIO_MODE_MASK(i);
117 /* set the specified pin mode bits */
118 ctl |= GPIO_MODE_SET(i, mode);
119
120 /* clear the specified pin pupd bits */
121 pupd &= ~GPIO_PUPD_MASK(i);
122 /* set the specified pin pupd bits */
123 pupd |= GPIO_PUPD_SET(i, pull_up_down);
124 }
125 }
126
127 GPIO_CTL(gpio_periph) = ctl;
128 GPIO_PUD(gpio_periph) = pupd;
129 }
130
131 /*!
132 \brief set GPIO output type and speed
133 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
134 only one parameter can be selected which is shown as below:
135 \arg GPIOx(x = A,B,C,D,E,F)
136 \param[in] otype: gpio pin output mode
137 only one parameter can be selected which is shown as below:
138 \arg GPIO_OTYPE_PP: push pull mode
139 \arg GPIO_OTYPE_OD: open drain mode
140 \param[in] speed: gpio pin output max speed
141 only one parameter can be selected which is shown as below:
142 \arg GPIO_OSPEED_2MHZ: output max speed 2MHz
143 \arg GPIO_OSPEED_10MHZ: output max speed 10MHz
144 \arg GPIO_OSPEED_50MHZ: output max speed 50MHz
145 \param[in] pin: GPIO pin
146 one or more parameters can be selected which are shown as below:
147 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
148 \param[out] none
149 \retval none
150 */
gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin)151 void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)
152 {
153 uint16_t i;
154 uint32_t ospeed;
155
156 if(GPIO_OTYPE_OD == otype){
157 GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
158 }else{
159 GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
160 }
161
162 /* get the specified pin output speed bits value */
163 ospeed = GPIO_OSPD(gpio_periph);
164
165 for(i = 0U;i < 16U;i++){
166 if(((uint32_t)1U << i) & pin){
167 /* clear the specified pin output speed bits */
168 ospeed &= ~GPIO_OSPEED_MASK(i);
169 /* set the specified pin output speed bits */
170 ospeed |= GPIO_OSPEED_SET(i,speed);
171 }
172 }
173 GPIO_OSPD(gpio_periph) = ospeed;
174 }
175
176 /*!
177 \brief set GPIO pin bit
178 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
179 only one parameter can be selected which is shown as below:
180 \arg GPIOx(x = A,B,C,D,E,F)
181 \param[in] pin: GPIO pin
182 one or more parameters can be selected which are shown as below:
183 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
184 \param[out] none
185 \retval none
186 */
gpio_bit_set(uint32_t gpio_periph,uint32_t pin)187 void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
188 {
189 GPIO_BOP(gpio_periph) = (uint32_t)pin;
190 }
191
192 /*!
193 \brief reset GPIO pin bit
194 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
195 only one parameter can be selected which is shown as below:
196 \arg GPIOx(x = A,B,C,D,E,F)
197 \param[in] pin: GPIO pin
198 one or more parameters can be selected which are shown as below:
199 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
200 \param[out] none
201 \retval none
202 */
gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)203 void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
204 {
205 GPIO_BC(gpio_periph) = (uint32_t)pin;
206 }
207
208 /*!
209 \brief write data to the specified GPIO pin
210 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
211 only one parameter can be selected which is shown as below:
212 \arg GPIOx(x = A,B,C,D,E,F)
213 \param[in] pin: GPIO pin
214 one or more parameters can be selected which are shown as below:
215 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
216 \param[in] bit_value: SET or RESET
217 only one parameter can be selected which is shown as below:
218 \arg RESET: clear the port pin
219 \arg SET: set the port pin
220 \param[out] none
221 \retval none
222 */
gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value)223 void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
224 {
225 if(RESET != bit_value){
226 GPIO_BOP(gpio_periph) = (uint32_t)pin;
227 }else{
228 GPIO_BC(gpio_periph) = (uint32_t)pin;
229 }
230 }
231
232 /*!
233 \brief write data to the specified GPIO port
234 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
235 only one parameter can be selected which is shown as below:
236 \arg GPIOx(x = A,B,C,D,E,F)
237 \param[in] data: specify the value to be written to the port output control register
238 \param[out] none
239 \retval none
240 */
gpio_port_write(uint32_t gpio_periph,uint16_t data)241 void gpio_port_write(uint32_t gpio_periph, uint16_t data)
242 {
243 GPIO_OCTL(gpio_periph) = (uint32_t)data;
244 }
245
246 /*!
247 \brief get GPIO pin input status
248 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
249 only one parameter can be selected which is shown as below:
250 \arg GPIOx(x = A,B,C,D,E,F)
251 \param[in] pin: GPIO pin
252 one or more parameters can be selected which are shown as below:
253 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
254 \param[out] none
255 \retval SET or RESET
256 */
gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)257 FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin)
258 {
259 if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
260 return SET;
261 }else{
262 return RESET;
263 }
264 }
265
266 /*!
267 \brief get GPIO port input status
268 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
269 only one parameter can be selected which is shown as below:
270 \arg GPIOx(x = A,B,C,D,E,F)
271 \param[out] none
272 \retval state of GPIO all pins
273 */
gpio_input_port_get(uint32_t gpio_periph)274 uint16_t gpio_input_port_get(uint32_t gpio_periph)
275 {
276 return ((uint16_t)GPIO_ISTAT(gpio_periph));
277 }
278
279 /*!
280 \brief get GPIO pin output status
281 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
282 only one parameter can be selected which is shown as below:
283 \arg GPIOx(x = A,B,C,D,E,F)
284 \param[in] pin: GPIO pin
285 one or more parameters can be selected which are shown as below:
286 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
287 \param[out] none
288 \retval SET or RESET
289 */
gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin)290 FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
291 {
292 if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){
293 return SET;
294 }else{
295 return RESET;
296 }
297 }
298
299 /*!
300 \brief get GPIO port output status
301 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
302 only one parameter can be selected which is shown as below:
303 \arg GPIOx(x = A,B,C,D,E,F)
304 \param[out] none
305 \retval state of GPIO all pins
306 */
gpio_output_port_get(uint32_t gpio_periph)307 uint16_t gpio_output_port_get(uint32_t gpio_periph)
308 {
309 return ((uint16_t)GPIO_OCTL(gpio_periph));
310 }
311
312 /*!
313 \brief set GPIO alternate function
314 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
315 only one parameter can be selected which is shown as below:
316 \arg GPIOx(x = A,B,C,D,E,F)
317 \param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet
318 only one parameter can be selected which is shown as below:
319 \arg GPIO_AF_0: SYSTEM
320 \arg GPIO_AF_1: TIMER0, TIMER1, TIMER7, TIMER19, TIMER20
321 \arg GPIO_AF_2: TIMER0, TIMER1, TIMER7, TIMER19, TIMER20
322 \arg GPIO_AF_3: TIMER7, TIMER19, I2C0
323 \arg GPIO_AF_4: SPI0, SPI1, I2S1, USART1
324 \arg GPIO_AF_5: USART0, USART2, MFCOM, SPI1, I2C1
325 \arg GPIO_AF_6: CAN0, CAN1, MFCOM, TRIGSEL
326 \arg GPIO_AF_7: TRIGSEL, CMP, MFCOM
327 \arg GPIO_AF_8:
328 \arg GPIO_AF_9: EVENTOUT
329 \param[in] pin: GPIO pin
330 one or more parameters can be selected which are shown as below:
331 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
332 \param[out] none
333 \retval none
334 */
gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin)335 void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin)
336 {
337 uint16_t i;
338 uint32_t afrl, afrh;
339
340 afrl = GPIO_AFSEL0(gpio_periph);
341 afrh = GPIO_AFSEL1(gpio_periph);
342
343 for(i = 0U;i < 8U;i++){
344 if(((uint32_t)1U << i) & pin){
345 /* clear the specified pin alternate function bits */
346 afrl &= ~GPIO_AFR_MASK(i);
347 afrl |= GPIO_AFR_SET(i,alt_func_num);
348 }
349 }
350
351 for(i = 8U;i < 16U;i++){
352 if(((uint32_t)1U << i) & pin){
353 /* clear the specified pin alternate function bits */
354 afrh &= ~GPIO_AFR_MASK(i - 8U);
355 afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
356 }
357 }
358
359 GPIO_AFSEL0(gpio_periph) = afrl;
360 GPIO_AFSEL1(gpio_periph) = afrh;
361 }
362
363 /*!
364 \brief lock GPIO pin bit
365 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
366 only one parameter can be selected which is shown as below:
367 \arg GPIOx(x = A,B,C,D,E,F)
368 \param[in] pin: GPIO pin
369 one or more parameters can be selected which are shown as below:
370 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
371 \param[out] none
372 \retval none
373 */
gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)374 void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
375 {
376 uint32_t lock = 0x00010000U;
377 lock |= pin;
378
379 /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */
380 GPIO_LOCK(gpio_periph) = (uint32_t)lock;
381 GPIO_LOCK(gpio_periph) = (uint32_t)pin;
382 GPIO_LOCK(gpio_periph) = (uint32_t)lock;
383 lock = GPIO_LOCK(gpio_periph);
384 lock = GPIO_LOCK(gpio_periph);
385 }
386
387 /*!
388 \brief toggle GPIO pin status
389 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
390 only one parameter can be selected which is shown as below:
391 \arg GPIOx(x = A,B,C,D,E,F)
392 \param[in] pin: GPIO pin
393 one or more parameters can be selected which are shown as below:
394 \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
395 \param[out] none
396 \retval none
397 */
gpio_bit_toggle(uint32_t gpio_periph,uint32_t pin)398 void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin)
399 {
400 GPIO_TG(gpio_periph) = (uint32_t)pin;
401 }
402
403 /*!
404 \brief toggle GPIO port status
405 \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F)
406 only one parameter can be selected which is shown as below:
407 \arg GPIOx(x = A,B,C,D,E,F)
408 \param[out] none
409 \retval none
410 */
gpio_port_toggle(uint32_t gpio_periph)411 void gpio_port_toggle(uint32_t gpio_periph)
412 {
413 GPIO_TG(gpio_periph) = 0x0000FFFFU;
414 }
415