1 /*****************************************************************************
2 *
3 * \file
4 *
5 * \brief GPIO software driver interface for AVR UC3.
6 *
7 * Copyright (c) 2010-2018 Microchip Technology Inc. and its subsidiaries.
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Subject to your compliance with these terms, you may use Microchip
14 * software and any derivatives exclusively with Microchip products.
15 * It is your responsibility to comply with third party license terms applicable
16 * to your use of third party software (including open source software) that
17 * may accompany Microchip software.
18 *
19 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
21 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
22 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
23 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
24 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
25 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
26 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
27 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
28 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
29 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
30 *
31 * \asf_license_stop
32 *
33 *****************************************************************************/
34 /*
35 * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
36 */
37
38 #include "gpio.h"
39
40 /** \name Peripheral Bus Interface
41 *
42 * @{
43 */
44
45 /** \brief Enables specific module modes for a set of pins.
46 *
47 * \param gpiomap The pin map.
48 * \param size The number of pins in \a gpiomap.
49 *
50 * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
51 */
gpio_enable_module(const gpio_map_t gpiomap,uint32_t size)52 uint32_t gpio_enable_module(const gpio_map_t gpiomap, uint32_t size)
53 {
54 uint32_t status = GPIO_SUCCESS;
55 uint32_t i;
56
57 for (i = 0; i < size; i++) {
58 status |= gpio_enable_module_pin(gpiomap->pin, gpiomap->function);
59 gpiomap++;
60 }
61
62 return status;
63 }
64
65 /** \brief Enables a specific module mode for a pin.
66 *
67 * \note A pin and pin function index can be found in the device part header
68 * file. The \c AVR32_*_PIN constants map a GPIO number from the device
69 * datasheet to the appropriate pin function, while the corresponding
70 * \c AVR32_*_FUNCTION macro contains the appropriate function index.
71 * \n\n
72 * For example, the constants \c AVR32_PWM_3_PIN and
73 * \c AVR32_PWM_3_FUNCTION contain the pin and function index of the PWM
74 * module, channel 3, for the current device (if available).
75 *
76 * \param pin The pin number.
77 * \param function The pin function.
78 *
79 * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
80 */
gpio_enable_module_pin(uint32_t pin,uint32_t function)81 uint32_t gpio_enable_module_pin(uint32_t pin, uint32_t function)
82 {
83 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
84
85 /* Enable the correct function. */
86 switch (function) {
87 case 0: /* A function. */
88 gpio_port->pmr0c = 1 << (pin & 0x1F);
89 gpio_port->pmr1c = 1 << (pin & 0x1F);
90 #if (AVR32_GPIO_H_VERSION >= 210)
91 gpio_port->pmr2c = 1 << (pin & 0x1F);
92 #endif
93 break;
94
95 case 1: /* B function. */
96 gpio_port->pmr0s = 1 << (pin & 0x1F);
97 gpio_port->pmr1c = 1 << (pin & 0x1F);
98 #if (AVR32_GPIO_H_VERSION >= 210)
99 gpio_port->pmr2c = 1 << (pin & 0x1F);
100 #endif
101 break;
102
103 case 2: /* C function. */
104 gpio_port->pmr0c = 1 << (pin & 0x1F);
105 gpio_port->pmr1s = 1 << (pin & 0x1F);
106 #if (AVR32_GPIO_H_VERSION >= 210)
107 gpio_port->pmr2c = 1 << (pin & 0x1F);
108 #endif
109 break;
110
111 case 3: /* D function. */
112 gpio_port->pmr0s = 1 << (pin & 0x1F);
113 gpio_port->pmr1s = 1 << (pin & 0x1F);
114 #if (AVR32_GPIO_H_VERSION >= 210)
115 gpio_port->pmr2c = 1 << (pin & 0x1F);
116 #endif
117 break;
118
119 #if (AVR32_GPIO_H_VERSION >= 210)
120 case 4: /* E function. */
121 gpio_port->pmr0c = 1 << (pin & 0x1F);
122 gpio_port->pmr1c = 1 << (pin & 0x1F);
123 gpio_port->pmr2s = 1 << (pin & 0x1F);
124 break;
125
126 case 5: /* F function. */
127 gpio_port->pmr0s = 1 << (pin & 0x1F);
128 gpio_port->pmr1c = 1 << (pin & 0x1F);
129 gpio_port->pmr2s = 1 << (pin & 0x1F);
130 break;
131
132 case 6: /* G function. */
133 gpio_port->pmr0c = 1 << (pin & 0x1F);
134 gpio_port->pmr1s = 1 << (pin & 0x1F);
135 gpio_port->pmr2s = 1 << (pin & 0x1F);
136 break;
137
138 case 7: /* H function. */
139 gpio_port->pmr0s = 1 << (pin & 0x1F);
140 gpio_port->pmr1s = 1 << (pin & 0x1F);
141 gpio_port->pmr2s = 1 << (pin & 0x1F);
142 break;
143 #endif
144
145 default:
146 return GPIO_INVALID_ARGUMENT;
147 }
148
149 /* Disable GPIO control. */
150 gpio_port->gperc = 1 << (pin & 0x1F);
151
152 return GPIO_SUCCESS;
153 }
154
155 /** \brief Enables the GPIO mode of a set of pins.
156 *
157 * \param gpiomap The pin map.
158 * \param size The number of pins in \a gpiomap.
159 */
gpio_enable_gpio(const gpio_map_t gpiomap,uint32_t size)160 void gpio_enable_gpio(const gpio_map_t gpiomap, uint32_t size)
161 {
162 uint32_t i;
163
164 for (i = 0; i < size; i++) {
165 gpio_enable_gpio_pin(gpiomap->pin);
166 gpiomap++;
167 }
168 }
169
170 /** \brief Enables the GPIO mode of a pin.
171 *
172 * \param pin The pin number.\n
173 * Refer to the product header file `uc3x.h' (where x is the part
174 * number; e.g. x = a0512) for pin definitions. E.g., to enable the
175 * GPIO mode of PX21, AVR32_PIN_PX21 can be used. Module pins such as
176 * AVR32_PWM_3_PIN for PWM channel 3 can also be used to release
177 * module pins for GPIO.
178 */
gpio_enable_gpio_pin(uint32_t pin)179 void gpio_enable_gpio_pin(uint32_t pin)
180 {
181 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
182
183 gpio_port->oderc = 1 << (pin & 0x1F);
184 gpio_port->gpers = 1 << (pin & 0x1F);
185 }
186
187 /** \brief Enables the pull-up resistor of a pin.
188 *
189 * \param pin The pin number.
190 */
gpio_enable_pin_pull_up(uint32_t pin)191 void gpio_enable_pin_pull_up(uint32_t pin)
192 {
193 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
194
195 gpio_port->puers = 1 << (pin & 0x1F);
196 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
197 defined(AVR32_GPIO_212_H_INCLUDED)
198 gpio_port->pderc = 1 << (pin & 0x1F);
199 #endif
200 }
201
202 /** \brief Disables the pull-up resistor of a pin.
203 *
204 * \param pin The pin number.
205 */
gpio_disable_pin_pull_up(uint32_t pin)206 void gpio_disable_pin_pull_up(uint32_t pin)
207 {
208 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
209
210 gpio_port->puerc = 1 << (pin & 0x1F);
211 }
212
213 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
214 defined(AVR32_GPIO_212_H_INCLUDED)
215 /* Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control. */
216
217 /** \brief Enables the pull-down resistor of a pin.
218 *
219 * \param pin The pin number.
220 */
gpio_enable_pin_pull_down(uint32_t pin)221 void gpio_enable_pin_pull_down(uint32_t pin)
222 {
223 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
224
225 gpio_port->puerc = 1 << (pin & 0x1F);
226 gpio_port->pders = 1 << (pin & 0x1F);
227 }
228
229 /** \brief Disables the pull-down resistor of a pin.
230 *
231 * \param pin The pin number.
232 */
gpio_disable_pin_pull_down(uint32_t pin)233 void gpio_disable_pin_pull_down(uint32_t pin)
234 {
235 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
236
237 gpio_port->pderc = 1 << (pin & 0x1F);
238 }
239
240 /** \brief Enables the buskeeper functionality on a pin.
241 *
242 * \param pin The pin number.
243 */
gpio_enable_pin_buskeeper(uint32_t pin)244 void gpio_enable_pin_buskeeper(uint32_t pin)
245 {
246 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
247
248 gpio_port->puers = 1 << (pin & 0x1F);
249 gpio_port->pders = 1 << (pin & 0x1F);
250 }
251
252 /** \brief Disables the buskeeper functionality on a pin.
253 *
254 * \param pin The pin number.
255 */
gpio_disable_pin_buskeeper(uint32_t pin)256 void gpio_disable_pin_buskeeper(uint32_t pin)
257 {
258 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
259
260 gpio_port->puerc = 1 << (pin & 0x1F);
261 gpio_port->pderc = 1 << (pin & 0x1F);
262 }
263
264 #endif
265
266 /** \brief Configuration functionality on a pin.
267 *
268 * \param pin The pin number.
269 * \param flags The configuration.
270 */
gpio_configure_pin(uint32_t pin,uint32_t flags)271 void gpio_configure_pin(uint32_t pin, uint32_t flags)
272 {
273 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
274
275 /* Both pull-up and pull-down set means buskeeper */
276 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
277 defined(AVR32_GPIO_212_H_INCLUDED)
278 if (flags & GPIO_PULL_DOWN) {
279 gpio_port->pders = 1 << (pin & 0x1F);
280 } else {
281 gpio_port->pderc = 1 << (pin & 0x1F);
282 }
283
284 #endif
285 if (flags & GPIO_PULL_UP) {
286 gpio_port->puers = 1 << (pin & 0x1F);
287 } else {
288 gpio_port->puerc = 1 << (pin & 0x1F);
289 }
290
291 /* Enable open-drain mode if requested */
292 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
293 defined(AVR32_GPIO_212_H_INCLUDED)
294 if (flags & GPIO_OPEN_DRAIN) {
295 gpio_port->odmers = 1 << (pin & 0x1F);
296 } else {
297 gpio_port->odmerc = 1 << (pin & 0x1F);
298 }
299
300 #endif
301
302 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
303 defined(AVR32_GPIO_212_H_INCLUDED)
304 /* Select drive strength */
305 if (flags & GPIO_DRIVE_LOW) {
306 gpio_port->odcr0s = 1 << (pin & 0x1F);
307 } else {
308 gpio_port->odcr0c = 1 << (pin & 0x1F);
309 }
310
311 if (flags & GPIO_DRIVE_HIGH) {
312 gpio_port->odcr1s = 1 << (pin & 0x1F);
313 } else {
314 gpio_port->odcr1c = 1 << (pin & 0x1F);
315 }
316
317 #endif
318
319 /* Select interrupt level for group */
320 if (flags & GPIO_INTERRUPT) {
321 if (flags & GPIO_BOTHEDGES) {
322 gpio_port->imr0c = 1 << (pin & 0x1F);
323 gpio_port->imr1c = 1 << (pin & 0x1F);
324 } else if (flags & GPIO_RISING) {
325 gpio_port->imr0s = 1 << (pin & 0x1F);
326 gpio_port->imr1c = 1 << (pin & 0x1F);
327 } else if (flags & GPIO_FALLING) {
328 gpio_port->imr0c = 1 << (pin & 0x1F);
329 gpio_port->imr1s = 1 << (pin & 0x1F);
330 }
331 }
332
333 /* Select direction and initial pin state */
334 if (flags & GPIO_DIR_OUTPUT) {
335 if (flags & GPIO_INIT_HIGH) {
336 gpio_port->ovrs = 1 << (pin & 0x1F);
337 } else {
338 gpio_port->ovrc = 1 << (pin & 0x1F);
339 }
340
341 gpio_port->oders = 1 << (pin & 0x1F);
342 } else {
343 gpio_port->oderc = 1 << (pin & 0x1F);
344 }
345
346 /* Enable GPIO */
347 gpio_port->gpers = 1 << (pin & 0x1F);
348 }
349
350 /** \brief Configuration functionality on a port.
351 *
352 * \param port The port number.
353 * \param mask The mask.
354 * \param flags The configuration.
355 */
gpio_configure_group(uint32_t port,uint32_t mask,uint32_t flags)356 void gpio_configure_group(uint32_t port, uint32_t mask, uint32_t flags)
357 {
358 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
359
360 /* Both pull-up and pull-down set means buskeeper */
361 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
362 defined(AVR32_GPIO_212_H_INCLUDED)
363 if (flags & GPIO_PULL_DOWN) {
364 gpio_port->pders = mask;
365 } else {
366 gpio_port->pderc = mask;
367 }
368
369 #endif
370 if (flags & GPIO_PULL_UP) {
371 gpio_port->puers = mask;
372 } else {
373 gpio_port->puerc = mask;
374 }
375
376 /* Enable open-drain mode if requested */
377 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
378 defined(AVR32_GPIO_212_H_INCLUDED)
379 if (flags & GPIO_OPEN_DRAIN) {
380 gpio_port->odmers = mask;
381 } else {
382 gpio_port->odmerc = mask;
383 }
384
385 if (flags & GPIO_OPEN_DRAIN) {
386 gpio_port->pders = mask;
387 } else {
388 gpio_port->pderc = mask;
389 }
390
391 #endif
392
393 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
394 defined(AVR32_GPIO_212_H_INCLUDED)
395 /* Select drive strength */
396 if (flags & GPIO_DRIVE_LOW) {
397 gpio_port->odcr0s = mask;
398 } else {
399 gpio_port->odcr0c = mask;
400 }
401
402 if (flags & GPIO_DRIVE_HIGH) {
403 gpio_port->odcr1s = mask;
404 } else {
405 gpio_port->odcr1c = mask;
406 }
407
408 #endif
409
410 /* Select interrupt level for group */
411 if (flags & GPIO_INTERRUPT) {
412 if (flags & GPIO_BOTHEDGES) {
413 gpio_port->imr0c = mask;
414 gpio_port->imr1c = mask;
415 } else if (flags & GPIO_RISING) {
416 gpio_port->imr0s = mask;
417 gpio_port->imr1c = mask;
418 } else if (flags & GPIO_FALLING) {
419 gpio_port->imr0c = mask;
420 gpio_port->imr1s = mask;
421 }
422 }
423
424 /* Select direction and initial pin state */
425 if (flags & GPIO_DIR_OUTPUT) {
426 if (flags & GPIO_INIT_HIGH) {
427 gpio_port->ovrs = mask;
428 } else {
429 gpio_port->ovrc = mask;
430 }
431
432 gpio_port->oders = mask;
433 } else {
434 gpio_port->oderc = mask;
435 }
436
437 /* Enable GPIO */
438 gpio_port->gpers = mask;
439 }
440
441 /** \brief Returns the value of a pin.
442 *
443 * \param pin The pin number.
444 *
445 * \return The pin value.
446 */
gpio_get_pin_value(uint32_t pin)447 bool gpio_get_pin_value(uint32_t pin)
448 {
449 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
450
451 return (gpio_port->pvr >> (pin & 0x1F)) & 1;
452 }
453
454 /** \brief Returns the output value set for a GPIO pin.
455 *
456 * \param pin The pin number.
457 *
458 * \return The pin output value.
459 *
460 * \note This function must be used in conjunction with \ref gpio_set_gpio_pin,
461 * \ref gpio_clr_gpio_pin and \ref gpio_tgl_gpio_pin.
462 */
gpio_get_gpio_pin_output_value(uint32_t pin)463 bool gpio_get_gpio_pin_output_value(uint32_t pin)
464 {
465 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
466
467 return (gpio_port->ovr >> (pin & 0x1F)) & 1;
468 }
469
470 /** \brief Returns the output value set for a GPIO pin using open drain.
471 *
472 * \param pin The pin number.
473 *
474 * \return The pin output value.
475 *
476 * \note This function must be used in conjunction with
477 * \ref gpio_set_gpio_open_drain_pin, \ref gpio_clr_gpio_open_drain_pin
478 * and \ref gpio_tgl_gpio_open_drain_pin.
479 */
gpio_get_gpio_open_drain_pin_output_value(uint32_t pin)480 bool gpio_get_gpio_open_drain_pin_output_value(uint32_t pin)
481 {
482 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
483
484 return ((gpio_port->oder >> (pin & 0x1F)) & 1) ^ 1;
485 }
486
487 /** \brief Drives a GPIO pin to 1.
488 *
489 * \param pin The pin number.
490 */
gpio_set_gpio_pin(uint32_t pin)491 void gpio_set_gpio_pin(uint32_t pin)
492 {
493 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
494
495 /* Value to be driven on the I/O line: 1. */
496 gpio_port->ovrs = 1 << (pin & 0x1F);
497 /* The GPIO output driver is enabled for that pin. */
498 gpio_port->oders = 1 << (pin & 0x1F);
499 /* The GPIO module controls that pin. */
500 gpio_port->gpers = 1 << (pin & 0x1F);
501 }
502
503 /** \brief Drives a GPIO pin to 1.
504 *
505 * \param pin The pin number.
506 *
507 * \note The function \ref gpio_configure_pin must be called before.
508 */
gpio_set_pin_high(uint32_t pin)509 void gpio_set_pin_high(uint32_t pin)
510 {
511 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
512
513 /* Value to be driven on the I/O line: 1. */
514 gpio_port->ovrs = 1 << (pin & 0x1F);
515 }
516
517 /** \brief Drives a GPIO port to 1.
518 *
519 * \param port The port number.
520 * \param mask The mask.
521 */
gpio_set_group_high(uint32_t port,uint32_t mask)522 void gpio_set_group_high(uint32_t port, uint32_t mask)
523 {
524 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
525
526 /* Value to be driven on the I/O group: 1. */
527 gpio_port->ovrs = mask;
528 }
529
530 /** \brief Drives a GPIO pin to 0.
531 *
532 * \param pin The pin number.
533 *
534 * \note The function \ref gpio_configure_pin must be called before.
535 */
gpio_set_pin_low(uint32_t pin)536 void gpio_set_pin_low(uint32_t pin)
537 {
538 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
539
540 /* Value to be driven on the I/O line: 0. */
541 gpio_port->ovrc = 1 << (pin & 0x1F);
542 }
543
544 /** \brief Drives a GPIO pin to 0.
545 *
546 * \param pin The pin number.
547 */
gpio_clr_gpio_pin(uint32_t pin)548 void gpio_clr_gpio_pin(uint32_t pin)
549 {
550 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
551
552 /* Value to be driven on the I/O line: 0. */
553 gpio_port->ovrc = 1 << (pin & 0x1F);
554 /* The GPIO output driver is enabled for that pin. */
555 gpio_port->oders = 1 << (pin & 0x1F);
556 /* The GPIO module controls that pin. */
557 gpio_port->gpers = 1 << (pin & 0x1F);
558 }
559
560 /** \brief Drives a GPIO port to 0.
561 *
562 * \param port The port number.
563 * \param mask The mask.
564 */
gpio_set_group_low(uint32_t port,uint32_t mask)565 void gpio_set_group_low(uint32_t port, uint32_t mask)
566 {
567 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
568
569 /* Value to be driven on the I/O group: 0. */
570 gpio_port->ovrc = mask;
571 }
572
573 /** \brief Toggles a GPIO pin.
574 *
575 * \param pin The pin number.
576 */
gpio_tgl_gpio_pin(uint32_t pin)577 void gpio_tgl_gpio_pin(uint32_t pin)
578 {
579 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
580
581 /* Toggle the I/O line. */
582 gpio_port->ovrt = 1 << (pin & 0x1F);
583 /* The GPIO output driver is enabled for that pin. */
584 gpio_port->oders = 1 << (pin & 0x1F);
585 /* The GPIO module controls that pin. */
586 gpio_port->gpers = 1 << (pin & 0x1F);
587 }
588
589 /** \brief Toggles a GPIO pin.
590 *
591 * \param pin The pin number.
592 *
593 * \note The function \ref gpio_configure_pin must be called before.
594 */
gpio_toggle_pin(uint32_t pin)595 void gpio_toggle_pin(uint32_t pin)
596 {
597 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
598
599 /* Toggle the I/O line. */
600 gpio_port->ovrt = 1 << (pin & 0x1F);
601 }
602
603 /** \brief Toggles a GPIO group.
604 *
605 * \param port The port number.
606 * \param mask The mask.
607 */
gpio_toggle_group(uint32_t port,uint32_t mask)608 void gpio_toggle_group(uint32_t port, uint32_t mask)
609 {
610 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
611
612 /* Toggle the I/O port. */
613 gpio_port->ovrt = mask;
614 }
615
616 /** \brief Drives a GPIO pin to 1 using open drain.
617 *
618 * \param pin The pin number.
619 */
gpio_set_gpio_open_drain_pin(uint32_t pin)620 void gpio_set_gpio_open_drain_pin(uint32_t pin)
621 {
622 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
623
624 /* The GPIO output driver is disabled for that pin. */
625 gpio_port->oderc = 1 << (pin & 0x1F);
626 /* The GPIO module controls that pin. */
627 gpio_port->gpers = 1 << (pin & 0x1F);
628 }
629
630 /** \brief Drives a GPIO pin to 0 using open drain.
631 *
632 * \param pin The pin number.
633 */
gpio_clr_gpio_open_drain_pin(uint32_t pin)634 void gpio_clr_gpio_open_drain_pin(uint32_t pin)
635 {
636 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
637
638 /* Value to be driven on the I/O line: 0. */
639 gpio_port->ovrc = 1 << (pin & 0x1F);
640 /* The GPIO output driver is enabled for that pin. */
641 gpio_port->oders = 1 << (pin & 0x1F);
642 /* The GPIO module controls that pin. */
643 gpio_port->gpers = 1 << (pin & 0x1F);
644 }
645
646 /** \brief Toggles a GPIO pin using open drain.
647 *
648 * \param pin The pin number.
649 */
gpio_tgl_gpio_open_drain_pin(uint32_t pin)650 void gpio_tgl_gpio_open_drain_pin(uint32_t pin)
651 {
652 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
653
654 /* Value to be driven on the I/O line if the GPIO output driver is
655 * enabled: 0. */
656 gpio_port->ovrc = 1 << (pin & 0x1F);
657 /* The GPIO output driver is toggled for that pin. */
658 gpio_port->odert = 1 << (pin & 0x1F);
659 /* The GPIO module controls that pin. */
660 gpio_port->gpers = 1 << (pin & 0x1F);
661 }
662
663 /** \brief Enables the glitch filter of a pin.
664 *
665 * When the glitch filter is enabled, a glitch with duration of less than 1
666 * clock cycle is automatically rejected, while a pulse with duration of 2 clock
667 * cycles or more is accepted. For pulse durations between 1 clock cycle and 2
668 * clock cycles, the pulse may or may not be taken into account, depending on
669 * the precise timing of its occurrence. Thus for a pulse to be guaranteed
670 * visible it must exceed 2 clock cycles, whereas for a glitch to be reliably
671 * filtered out, its duration must not exceed 1 clock cycle. The filter
672 * introduces 2 clock cycles latency.
673 *
674 * \param pin The pin number.
675 */
gpio_enable_pin_glitch_filter(uint32_t pin)676 void gpio_enable_pin_glitch_filter(uint32_t pin)
677 {
678 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
679
680 gpio_port->gfers = 1 << (pin & 0x1F);
681 }
682
683 /** \brief Disables the glitch filter of a pin.
684 *
685 * \param pin The pin number.
686 */
gpio_disable_pin_glitch_filter(uint32_t pin)687 void gpio_disable_pin_glitch_filter(uint32_t pin)
688 {
689 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
690
691 gpio_port->gferc = 1 << (pin & 0x1F);
692 }
693
694 /** \brief Configure the edge detector of an input pin
695 *
696 * \param pin The pin number.
697 * \param mode The edge detection mode (\ref GPIO_PIN_CHANGE,
698 * \ref GPIO_RISING_EDGE or \ref GPIO_FALLING_EDGE).
699 *
700 * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
701 */
gpio_configure_edge_detector(uint32_t pin,uint32_t mode)702 static uint32_t gpio_configure_edge_detector(uint32_t pin, uint32_t mode)
703 {
704 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
705
706 /* Configure the edge detector. */
707 switch (mode) {
708 case GPIO_PIN_CHANGE:
709 gpio_port->imr0c = 1 << (pin & 0x1F);
710 gpio_port->imr1c = 1 << (pin & 0x1F);
711 break;
712
713 case GPIO_RISING_EDGE:
714 gpio_port->imr0s = 1 << (pin & 0x1F);
715 gpio_port->imr1c = 1 << (pin & 0x1F);
716 break;
717
718 case GPIO_FALLING_EDGE:
719 gpio_port->imr0c = 1 << (pin & 0x1F);
720 gpio_port->imr1s = 1 << (pin & 0x1F);
721 break;
722
723 default:
724 return GPIO_INVALID_ARGUMENT;
725 }
726
727 return GPIO_SUCCESS;
728 }
729
730 /** \brief Enables the interrupt of a pin with the specified settings.
731 *
732 * \param pin The pin number.
733 * \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or
734 * \ref GPIO_FALLING_EDGE).
735 *
736 * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
737 */
gpio_enable_pin_interrupt(uint32_t pin,uint32_t mode)738 uint32_t gpio_enable_pin_interrupt(uint32_t pin, uint32_t mode)
739 {
740 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
741
742 /* Enable the glitch filter. */
743 gpio_port->gfers = 1 << (pin & 0x1F);
744
745 /* Configure the edge detector. */
746 if (GPIO_INVALID_ARGUMENT == gpio_configure_edge_detector(pin, mode)) {
747 return(GPIO_INVALID_ARGUMENT);
748 }
749
750 /* Enable interrupt. */
751 gpio_port->iers = 1 << (pin & 0x1F);
752
753 return GPIO_SUCCESS;
754 }
755
756 /** \brief Disables the interrupt of a pin.
757 *
758 * \param pin The pin number.
759 */
gpio_disable_pin_interrupt(uint32_t pin)760 void gpio_disable_pin_interrupt(uint32_t pin)
761 {
762 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
763
764 gpio_port->ierc = 1 << (pin & 0x1F);
765 }
766
767 /** \brief Gets the interrupt flag of a pin.
768 *
769 * \param pin The pin number.
770 *
771 * \return The pin interrupt flag.
772 */
gpio_get_pin_interrupt_flag(uint32_t pin)773 bool gpio_get_pin_interrupt_flag(uint32_t pin)
774 {
775 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
776
777 return (gpio_port->ifr >> (pin & 0x1F)) & 1;
778 }
779
780 /** \brief Clears the interrupt flag of a pin.
781 *
782 * \param pin The pin number.
783 */
gpio_clear_pin_interrupt_flag(uint32_t pin)784 void gpio_clear_pin_interrupt_flag(uint32_t pin)
785 {
786 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
787
788 #if (AVR32_GPIO_H_VERSION == 211)
789 /* GPIO erratum - Writing a one to the GPIO.IFRC register */
790 /* to clear an interrupt will be ignored if interrupt is enabled for the */
791 /* corresponding port. */
792 /* Work around for the erratum - Disable the interrupt, clear it by
793 * writing */
794 /* a one to GPIO.IFRC, then enable the interrupt. */
795
796 /* Save interrupt enable register. */
797 uint32_t const gpio_ier = gpio_port->ier;
798
799 /* Disable interrupt. */
800 gpio_port->ierc = gpio_ier;
801
802 /* Clear pin interrupt. */
803 gpio_port->ifrc = 1 << (pin & 0x1F);
804
805 /* Restore interrupt enable register. */
806 gpio_port->ier = gpio_ier;
807 #else
808 gpio_port->ifrc = 1 << (pin & 0x1F);
809 #endif
810 }
811
812 #if UC3L
813
814 /** \brief Configure the peripheral event trigger mode of a pin
815 *
816 * \param pin The pin number.
817 * \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or
818 * \ref GPIO_FALLING_EDGE).
819 * \param use_igf use the Input Glitch Filter (true) or not (false).
820 *
821 * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
822 */
gpio_configure_pin_periph_event_mode(uint32_t pin,uint32_t mode,uint32_t use_igf)823 uint32_t gpio_configure_pin_periph_event_mode(uint32_t pin, uint32_t mode,
824 uint32_t use_igf)
825 {
826 volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
827
828 if (true == use_igf) {
829 /* Enable the glitch filter. */
830 gpio_port->gfers = 1 << (pin & 0x1F);
831 } else {
832 /* Disable the glitch filter. */
833 gpio_port->gferc = 1 << (pin & 0x1F);
834 }
835
836 /* Configure the edge detector. */
837 return gpio_configure_edge_detector(pin, mode);
838 }
839
840 #endif
841
842 /** @} */
843