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