1 /**
2  * \file
3  *
4  * \brief SAM GPIO Port Driver
5  *
6  * Copyright (C) 2012-2016 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
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  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #ifndef PORT_H_INCLUDED
47 #define PORT_H_INCLUDED
48 
49 /**
50  * \defgroup asfdoc_sam0_port_group SAM Port (PORT) Driver
51  *
52  * This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers provides
53  * an interface for the configuration and management of the device's General
54  * Purpose Input/Output (GPIO) pin functionality, for manual pin state reading
55  * and writing.
56  *
57  * The following peripheral is used by this module:
58  *  - PORT (GPIO Management)
59  *
60  * The following devices can use this module:
61  *  - Atmel | SMART SAM D20/D21
62  *  - Atmel | SMART SAM R21
63  *  - Atmel | SMART SAM D09/D10/D11
64  *  - Atmel | SMART SAM L21/L22
65  *  - Atmel | SMART SAM DA1
66  *  - Atmel | SMART SAM C20/C21
67  *  - Atmel | SMART SAM HA1
68  *  - Atmel | SMART SAM R30
69  *
70  * The outline of this documentation is as follows:
71  *  - \ref asfdoc_sam0_port_prerequisites
72  *  - \ref asfdoc_sam0_port_module_overview
73  *  - \ref asfdoc_sam0_port_special_considerations
74  *  - \ref asfdoc_sam0_port_extra_info
75  *  - \ref asfdoc_sam0_port_examples
76  *  - \ref asfdoc_sam0_port_api_overview
77  *
78  *
79  * \section asfdoc_sam0_port_prerequisites Prerequisites
80  *
81  * There are no prerequisites for this module.
82  *
83  *
84  * \section asfdoc_sam0_port_module_overview Module Overview
85  *
86  * The device GPIO (PORT) module provides an interface between the user
87  * application logic and external hardware peripherals, when general pin state
88  * manipulation is required. This driver provides an easy-to-use interface to
89  * the physical pin input samplers and output drivers, so that pins can be read
90  * from or written to for general purpose external hardware control.
91  *
92  * \subsection asfdoc_sam0_port_features Driver Feature Macro Definition
93  * <table>
94  *  <tr>
95  *    <th>Driver Feature Macro</th>
96  *    <th>Supported devices</th>
97  *  </tr>
98  *  <tr>
99  *    <td>FEATURE_PORT_INPUT_EVENT</td>
100  *    <td>SAM L21/L22/C20/C21/R30</td>
101  *  </tr>
102  * </table>
103  * \note The specific features are only available in the driver when the
104  * selected device supports those features.
105  *
106  * \subsection asfdoc_sam0_port_module_overview_pin_numbering Physical and Logical GPIO Pins
107  * SAM devices use two naming conventions for the I/O pins in the device; one
108  * physical and one logical. Each physical pin on a device package is assigned
109  * both a physical port and pin identifier (e.g. "PORTA.0") as well as a
110  * monotonically incrementing logical GPIO number (e.g. "GPIO0"). While the
111  * former is used to map physical pins to their physical internal device module
112  * counterparts, for simplicity the design of this driver uses the logical GPIO
113  * numbers instead.
114  *
115  * \subsection asfdoc_sam0_port_module_overview_physical Physical Connection
116  *
117  * \ref asfdoc_sam0_port_module_int_connections "The diagram below" shows how
118  * this module is interconnected within the device.
119  *
120  * \anchor asfdoc_sam0_port_module_int_connections
121  * \dot
122  * digraph overview {
123  *   node [label="Port Pad" shape=square] pad;
124  *
125  *   subgraph driver {
126  *     node [label="Peripheral MUX" shape=trapezium] pinmux;
127  *     node [label="GPIO Module" shape=ellipse] gpio;
128  *     node [label="Other Peripheral Modules" shape=ellipse style=filled fillcolor=lightgray] peripherals;
129  *   }
130  *
131  *   pinmux -> gpio;
132  *   pad    -> pinmux;
133  *   pinmux -> peripherals;
134  * }
135  * \enddot
136  *
137  *
138  * \section asfdoc_sam0_port_special_considerations Special Considerations
139  *
140  * The SAM port pin input sampler can be disabled when the pin is configured
141  * in pure output mode to save power; reading the pin state of a pin configured
142  * in output-only mode will read the logical output state that was last set.
143  *
144  * \section asfdoc_sam0_port_extra_info Extra Information
145  *
146  * For extra information, see \ref asfdoc_sam0_port_extra. This includes:
147  *  - \ref asfdoc_sam0_port_extra_acronyms
148  *  - \ref asfdoc_sam0_port_extra_dependencies
149  *  - \ref asfdoc_sam0_port_extra_errata
150  *  - \ref asfdoc_sam0_port_extra_history
151  *
152  *
153  * \section asfdoc_sam0_port_examples Examples
154  *
155  * For a list of examples related to this driver, see
156  * \ref asfdoc_sam0_port_exqsg.
157  *
158  *
159  * \section asfdoc_sam0_port_api_overview API Overview
160  * @{
161  */
162 
163 #include <compiler.h>
164 #include <pinmux.h>
165 
166 #ifdef __cplusplus
167 extern "C" {
168 #endif
169 
170 /**
171  * \name Driver Feature Definition
172  * Define port features set according to different device family.
173  * @{
174 */
175 #if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30) || defined(__DOXYGEN__)
176 /** Event input control feature support for PORT group. */
177 #  define FEATURE_PORT_INPUT_EVENT
178 #endif
179 /*@}*/
180 
181 /** \name PORT Alias Macros
182  * @{
183  */
184 
185 /** Convenience definition for GPIO module group A on the device (if
186  *  available). */
187 #if (PORT_GROUPS > 0) || defined(__DOXYGEN__)
188 #  define PORTA             PORT->Group[0]
189 #endif
190 
191 #if (PORT_GROUPS > 1) || defined(__DOXYGEN__)
192 /** Convenience definition for GPIO module group B on the device (if
193  *  available). */
194 #  define PORTB             PORT->Group[1]
195 #endif
196 
197 #if (PORT_GROUPS > 2) || defined(__DOXYGEN__)
198 /** Convenience definition for GPIO module group C on the device (if
199  *  available). */
200 #  define PORTC             PORT->Group[2]
201 #endif
202 
203 #if (PORT_GROUPS > 3) || defined(__DOXYGEN__)
204 /** Convenience definition for GPIO module group D on the device (if
205  *  available). */
206 #  define PORTD             PORT->Group[3]
207 #endif
208 
209 /** @} */
210 
211 /**
212  *  \brief Port pin direction configuration enum.
213  *
214  *  Enum for the possible pin direction settings of the port pin configuration
215  *  structure, to indicate the direction the pin should use.
216  */
217 enum port_pin_dir {
218 	/** The pin's input buffer should be enabled, so that the pin state can
219 	 *  be read */
220 	PORT_PIN_DIR_INPUT               = SYSTEM_PINMUX_PIN_DIR_INPUT,
221 	/** The pin's output buffer should be enabled, so that the pin state can
222 	 *  be set */
223 	PORT_PIN_DIR_OUTPUT              = SYSTEM_PINMUX_PIN_DIR_OUTPUT,
224 	/** The pin's output and input buffers should be enabled, so that the pin
225 	 *  state can be set and read back */
226 	PORT_PIN_DIR_OUTPUT_WTH_READBACK = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK,
227 };
228 
229 /**
230  *  \brief Port pin input pull configuration enum.
231  *
232  *  Enum for the possible pin pull settings of the port pin configuration
233  *  structure, to indicate the type of logic level pull the pin should use.
234  */
235 enum port_pin_pull {
236 	/** No logical pull should be applied to the pin */
237 	PORT_PIN_PULL_NONE = SYSTEM_PINMUX_PIN_PULL_NONE,
238 	/** Pin should be pulled up when idle */
239 	PORT_PIN_PULL_UP   = SYSTEM_PINMUX_PIN_PULL_UP,
240 	/** Pin should be pulled down when idle */
241 	PORT_PIN_PULL_DOWN = SYSTEM_PINMUX_PIN_PULL_DOWN,
242 };
243 
244 #ifdef FEATURE_PORT_INPUT_EVENT
245 /**
246  *  \brief Port input event action.
247  *
248  *  List of port input events action on pin.
249  */
250 enum port_input_event_action {
251 	/** Event out to pin */
252 	PORT_INPUT_EVENT_ACTION_OUT = 0,
253 	/** Set output register of pin on event */
254 	PORT_INPUT_EVENT_ACTION_SET,
255 	/** Clear output register pin on event */
256 	PORT_INPUT_EVENT_ACTION_CLR,
257 	/** Toggle output register pin on event */
258 	PORT_INPUT_EVENT_ACTION_TGL,
259 };
260 
261 /**
262  *  \brief Port input event.
263  *
264  *  List of port input events.
265  */
266 enum port_input_event{
267 	/** Port input event 0 */
268 	PORT_INPUT_EVENT_0 = 0,
269 	/** Port input event 1 */
270 	PORT_INPUT_EVENT_1 = 1,
271 	/** Port input event 2 */
272 	PORT_INPUT_EVENT_2 = 2,
273 	/** Port input event 3 */
274 	PORT_INPUT_EVENT_3 = 3,
275 };
276 
277 /**
278  *  \brief Port input event configuration structure.
279  *
280  *  Configuration structure for a port input event.
281  */
282 struct port_input_event_config{
283 	/** Port input event action */
284 	enum port_input_event_action  action;
285 	/** GPIO pin */
286 	uint8_t gpio_pin;
287 };
288 #endif
289 
290 /**
291  *  \brief Port pin configuration structure.
292  *
293  *  Configuration structure for a port pin instance. This structure should be
294  *  initialized by the \ref port_get_config_defaults() function before being
295  *  modified by the user application.
296  */
297 struct port_config {
298 	/** Port buffer input/output direction */
299 	enum port_pin_dir  direction;
300 
301 	/** Port pull-up/pull-down for input pins */
302 	enum port_pin_pull input_pull;
303 
304 	/** Enable lowest possible powerstate on the pin
305 	 *
306 	 *  \note All other configurations will be ignored, the pin will be disabled.
307 	 */
308 	bool powersave;
309 };
310 
311 /** \name State Reading/Writing (Physical Group Orientated)
312  * @{
313  */
314 
315 /**
316  *  \brief Retrieves the PORT module group instance from a given GPIO pin number.
317  *
318  *  Retrieves the PORT module group instance associated with a given logical
319  *  GPIO pin number.
320  *
321  *  \param[in] gpio_pin  Index of the GPIO pin to convert
322  *
323  *  \return Base address of the associated PORT module.
324  */
port_get_group_from_gpio_pin(const uint8_t gpio_pin)325 static inline PortGroup* port_get_group_from_gpio_pin(
326 		const uint8_t gpio_pin)
327 {
328 	return system_pinmux_get_group_from_gpio_pin(gpio_pin);
329 }
330 
331 /**
332  *  \brief Retrieves the state of a group of port pins that are configured as inputs.
333  *
334  *  Reads the current logic level of a port module's pins and returns the
335  *  current levels as a bitmask.
336  *
337  *  \param[in] port  Base of the PORT module to read from
338  *  \param[in] mask  Mask of the port pin(s) to read
339  *
340  *  \return Status of the port pin(s) input buffers.
341  */
port_group_get_input_level(const PortGroup * const port,const uint32_t mask)342 static inline uint32_t port_group_get_input_level(
343 		const PortGroup *const port,
344 		const uint32_t mask)
345 {
346 	/* Sanity check arguments */
347 	Assert(port);
348 
349 	return (port->IN.reg & mask);
350 }
351 
352 /**
353  *  \brief Retrieves the state of a group of port pins that are configured as outputs.
354  *
355  *  Reads the current logical output level of a port module's pins and returns
356  *  the current levels as a bitmask.
357  *
358  *  \param[in] port  Base of the PORT module to read from
359  *  \param[in] mask  Mask of the port pin(s) to read
360  *
361  *  \return Status of the port pin(s) output buffers.
362  */
port_group_get_output_level(const PortGroup * const port,const uint32_t mask)363 static inline uint32_t port_group_get_output_level(
364 		const PortGroup *const port,
365 		const uint32_t mask)
366 {
367 	/* Sanity check arguments */
368 	Assert(port);
369 
370 	return (port->OUT.reg & mask);
371 }
372 
373 /**
374  *  \brief Sets the state of a group of port pins that are configured as outputs.
375  *
376  *  Sets the current output level of a port module's pins to a given logic
377  *  level.
378  *
379  *  \param[out] port        Base of the PORT module to write to
380  *  \param[in]  mask        Mask of the port pin(s) to change
381  *  \param[in]  level_mask  Mask of the port level(s) to set
382  */
port_group_set_output_level(PortGroup * const port,const uint32_t mask,const uint32_t level_mask)383 static inline void port_group_set_output_level(
384 		PortGroup *const port,
385 		const uint32_t mask,
386 		const uint32_t level_mask)
387 {
388 	/* Sanity check arguments */
389 	Assert(port);
390 
391 	port->OUTSET.reg = (mask &  level_mask);
392 	port->OUTCLR.reg = (mask & ~level_mask);
393 }
394 
395 /**
396  *  \brief Toggles the state of a group of port pins that are configured as an outputs.
397  *
398  *  Toggles the current output levels of a port module's pins.
399  *
400  *  \param[out] port  Base of the PORT module to write to
401  *  \param[in]  mask  Mask of the port pin(s) to toggle
402  */
port_group_toggle_output_level(PortGroup * const port,const uint32_t mask)403 static inline void port_group_toggle_output_level(
404 		PortGroup *const port,
405 		const uint32_t mask)
406 {
407 	/* Sanity check arguments */
408 	Assert(port);
409 
410 	port->OUTTGL.reg = mask;
411 }
412 
413 /** @} */
414 
415 /** \name Configuration and Initialization
416  * @{
417  */
418 
419 /**
420  *  \brief Initializes a Port pin/group configuration structure to defaults.
421  *
422  *  Initializes a given Port pin/group configuration structure to a set of
423  *  known default values. This function should be called on all new
424  *  instances of these configuration structures before being modified by the
425  *  user application.
426  *
427  *  The default configuration is as follows:
428  *   \li Input mode with internal pull-up enabled
429  *
430  *  \param[out] config  Configuration structure to initialize to default values
431  */
port_get_config_defaults(struct port_config * const config)432 static inline void port_get_config_defaults(
433 		struct port_config *const config)
434 {
435 	/* Sanity check arguments */
436 	Assert(config);
437 
438 	/* Default configuration values */
439 	config->direction  = PORT_PIN_DIR_INPUT;
440 	config->input_pull = PORT_PIN_PULL_UP;
441 	config->powersave  = false;
442 }
443 
444 void port_pin_set_config(
445 		const uint8_t gpio_pin,
446 		const struct port_config *const config);
447 
448 void port_group_set_config(
449 		PortGroup *const port,
450 		const uint32_t mask,
451 		const struct port_config *const config);
452 
453 /** @} */
454 
455 /** \name State Reading/Writing (Logical Pin Orientated)
456  * @{
457  */
458 
459 /**
460  *  \brief Retrieves the state of a port pin that is configured as an input.
461  *
462  *  Reads the current logic level of a port pin and returns the current
463  *  level as a Boolean value.
464  *
465  *  \param[in] gpio_pin  Index of the GPIO pin to read
466  *
467  *  \return Status of the port pin's input buffer.
468  */
port_pin_get_input_level(const uint8_t gpio_pin)469 static inline bool port_pin_get_input_level(
470 		const uint8_t gpio_pin)
471 {
472 	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
473 	uint32_t pin_mask  = (1UL << (gpio_pin % 32));
474 
475 	return (port_base->IN.reg & pin_mask);
476 }
477 
478 /**
479  *  \brief Retrieves the state of a port pin that is configured as an output.
480  *
481  *  Reads the current logical output level of a port pin and returns the current
482  *  level as a Boolean value.
483  *
484  *  \param[in] gpio_pin  Index of the GPIO pin to read
485  *
486  *  \return Status of the port pin's output buffer.
487  */
port_pin_get_output_level(const uint8_t gpio_pin)488 static inline bool port_pin_get_output_level(
489 		const uint8_t gpio_pin)
490 {
491 	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
492 	uint32_t pin_mask  = (1UL << (gpio_pin % 32));
493 
494 	return (port_base->OUT.reg & pin_mask);
495 }
496 
497 /**
498  *  \brief Sets the state of a port pin that is configured as an output.
499  *
500  *  Sets the current output level of a port pin to a given logic level.
501  *
502  *  \param[in] gpio_pin  Index of the GPIO pin to write to
503  *  \param[in] level     Logical level to set the given pin to
504  */
port_pin_set_output_level(const uint8_t gpio_pin,const bool level)505 static inline void port_pin_set_output_level(
506 		const uint8_t gpio_pin,
507 		const bool level)
508 {
509 	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
510 	uint32_t pin_mask  = (1UL << (gpio_pin % 32));
511 
512 	/* Set the pin to high or low atomically based on the requested level */
513 	if (level) {
514 		port_base->OUTSET.reg = pin_mask;
515 	} else {
516 		port_base->OUTCLR.reg = pin_mask;
517 	}
518 }
519 
520 /**
521  *  \brief Toggles the state of a port pin that is configured as an output.
522  *
523  *  Toggles the current output level of a port pin.
524  *
525  *  \param[in] gpio_pin  Index of the GPIO pin to toggle
526  */
port_pin_toggle_output_level(const uint8_t gpio_pin)527 static inline void port_pin_toggle_output_level(
528 		const uint8_t gpio_pin)
529 {
530 	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
531 	uint32_t pin_mask  = (1UL << (gpio_pin % 32));
532 
533 	/* Toggle pin output level */
534 	port_base->OUTTGL.reg = pin_mask;
535 }
536 
537 /** @} */
538 
539 #ifdef FEATURE_PORT_INPUT_EVENT
540 
541 /** \name Port Input Event
542  * @{
543  */
544 
545 /**
546  *  \brief Enable the port event input.
547  *
548  *  Enable the port event input with the given pin and event.
549  *
550  *  \param[in] gpio_pin  Index of the GPIO pin
551  *  \param[in] n  Port input event
552  *
553  * \retval STATUS_ERR_INVALID_ARG  Invalid parameter
554  * \retval STATUS_OK               Successfully
555  */
port_enable_input_event(const uint8_t gpio_pin,const enum port_input_event n)556 static inline enum status_code port_enable_input_event(
557 		const uint8_t gpio_pin,
558 		const enum port_input_event n)
559 {
560 	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
561 	switch (n) {
562 		case PORT_INPUT_EVENT_0:
563 			port_base->EVCTRL.reg |= PORT_EVCTRL_PORTEI0;
564 			break;
565 		case PORT_INPUT_EVENT_1:
566 			port_base->EVCTRL.reg |= PORT_EVCTRL_PORTEI1;
567 			break;
568 		case PORT_INPUT_EVENT_2:
569 			port_base->EVCTRL.reg |= PORT_EVCTRL_PORTEI2;
570 			break;
571 		case PORT_INPUT_EVENT_3:
572 			port_base->EVCTRL.reg |= PORT_EVCTRL_PORTEI3;
573 			break;
574 		default:
575 			Assert(false);
576 			return STATUS_ERR_INVALID_ARG;
577 	}
578 	return STATUS_OK;
579 }
580 
581 /**
582  *  \brief Disable the port event input.
583  *
584  *  Disable the port event input with the given pin and event.
585  *
586  *  \param[in] gpio_pin  Index of the GPIO pin
587  *  \param[in] gpio_pin  Port input event
588  *
589  * \retval STATUS_ERR_INVALID_ARG  Invalid parameter
590  * \retval STATUS_OK               Successfully
591  */
port_disable_input_event(const uint8_t gpio_pin,const enum port_input_event n)592 static inline enum status_code port_disable_input_event(
593 		const uint8_t gpio_pin,
594 		const enum port_input_event n)
595 {
596 	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
597 	switch (n) {
598 		case PORT_INPUT_EVENT_0:
599 			port_base->EVCTRL.reg &= ~PORT_EVCTRL_PORTEI0;
600 			break;
601 		case PORT_INPUT_EVENT_1:
602 			port_base->EVCTRL.reg &= ~PORT_EVCTRL_PORTEI1;
603 			break;
604 		case PORT_INPUT_EVENT_2:
605 			port_base->EVCTRL.reg &= ~PORT_EVCTRL_PORTEI2;
606 			break;
607 		case PORT_INPUT_EVENT_3:
608 			port_base->EVCTRL.reg &= ~PORT_EVCTRL_PORTEI3;
609 			break;
610 		default:
611 			Assert(false);
612 			return STATUS_ERR_INVALID_ARG;
613 	}
614 	return STATUS_OK;
615 }
616 
617 /**
618  * \brief Retrieve the default configuration for port input event.
619  *
620  * Fills a configuration structure with the default configuration for port input event:
621  *   - Event output to pin
622  *   - Event action to be executed on PIN 0
623  *
624  * \param[out] config  Configuration structure to fill with default values
625  */
port_input_event_get_config_defaults(struct port_input_event_config * const config)626 static inline void port_input_event_get_config_defaults(
627 		struct port_input_event_config *const config)
628 {
629 	Assert(config);
630 	config->action   = PORT_INPUT_EVENT_ACTION_OUT;
631 	config->gpio_pin = 0;
632 }
633 
634 /**
635  * \brief Configure port input event.
636  *
637  * Configures port input event with the given configuration settings.
638  *
639  * \param[in] config  Port input even configuration structure containing the new config
640  *
641  * \retval STATUS_ERR_INVALID_ARG  Invalid parameter
642  * \retval STATUS_OK               Successfully
643  */
644 
port_input_event_set_config(const enum port_input_event n,struct port_input_event_config * const config)645 static inline enum status_code port_input_event_set_config(
646 		const enum port_input_event n,
647 		struct port_input_event_config *const config)
648 {
649 	Assert(config);
650 	PortGroup *const port_base = port_get_group_from_gpio_pin(config->gpio_pin);
651 	uint8_t pin_index = config->gpio_pin % 32;
652 	struct port_config pin_conf;
653 
654 	port_get_config_defaults(&pin_conf);
655 	/* Configure the GPIO pin as outputs*/
656 	pin_conf.direction  = PORT_PIN_DIR_OUTPUT;
657 	port_pin_set_config(config->gpio_pin, &pin_conf);
658 
659 	switch (n) {
660 		case PORT_INPUT_EVENT_0:
661 			port_base->EVCTRL.reg |= PORT_EVCTRL_EVACT0(config->action)
662 									| PORT_EVCTRL_PID0(pin_index);
663 			break;
664 		case PORT_INPUT_EVENT_1:
665 			port_base->EVCTRL.reg |= PORT_EVCTRL_EVACT1(config->action)
666 						   		   | PORT_EVCTRL_PID1(pin_index);
667 			break;
668 		case PORT_INPUT_EVENT_2:
669 			port_base->EVCTRL.reg |= PORT_EVCTRL_EVACT2(config->action)
670 						   		   | PORT_EVCTRL_PID2(pin_index);
671 			break;
672 		case PORT_INPUT_EVENT_3:
673 			port_base->EVCTRL.reg |= PORT_EVCTRL_EVACT3(config->action)
674 						   		   | PORT_EVCTRL_PID3(pin_index);
675 			break;
676 		default:
677 			Assert(false);
678 			return STATUS_ERR_INVALID_ARG;
679 	}
680 	return STATUS_OK;
681 }
682 
683 /** @} */
684 
685 #endif
686 
687 #ifdef __cplusplus
688 }
689 #endif
690 
691 /** @} */
692 
693 /**
694  * \page asfdoc_sam0_port_extra Extra Information for PORT Driver
695  *
696  * \section asfdoc_sam0_port_extra_acronyms Acronyms
697  * Below is a table listing the acronyms used in this module, along with their
698  * intended meanings.
699  *
700  * <table>
701  *	<tr>
702  *		<th>Acronym</th>
703  *		<th>Description</th>
704  *	</tr>
705  *	<tr>
706  *		<td>GPIO</td>
707  *		<td>General Purpose Input/Output</td>
708  *	</tr>
709  *	<tr>
710  *		<td>MUX</td>
711  *		<td>Multiplexer</td>
712  *	</tr>
713  * </table>
714  *
715  *
716  * \section asfdoc_sam0_port_extra_dependencies Dependencies
717  * This driver has the following dependencies:
718  *
719  *  - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver"
720  *
721  *
722  * \section asfdoc_sam0_port_extra_errata Errata
723  * There are no errata related to this driver.
724  *
725  *
726  * \section asfdoc_sam0_port_extra_history Module History
727  * An overview of the module history is presented in the table below, with
728  * details on the enhancements and fixes made to the module since its first
729  * release. The current version of this corresponds to the newest version in
730  * the table.
731  *
732  * <table>
733  *	<tr>
734  *		<th>Changelog</th>
735  *	</tr>
736  *	<tr>
737  *		<td>Added input event feature</td>
738  *	</tr>
739  *	<tr>
740  *		<td>Initial release</td>
741  *	</tr>
742  * </table>
743  */
744 
745 /**
746  * \page asfdoc_sam0_port_exqsg Examples for PORT Driver
747  *
748  * This is a list of the available Quick Start guides (QSGs) and example
749  * applications for \ref asfdoc_sam0_port_group. QSGs are simple examples with
750  * step-by-step instructions to configure and use this driver in a selection of
751  * use cases. Note that a QSG can be compiled as a standalone application or be
752  * added to the user application.
753  *
754  *  - \subpage asfdoc_sam0_port_basic_use_case
755  *
756  * \page asfdoc_sam0_port_document_revision_history Document Revision History
757  *
758  * <table>
759  *	<tr>
760  *		<th>Doc. Rev.</td>
761  *		<th>Date</td>
762  *		<th>Comments</td>
763  *	</tr>
764  *	<tr>
765  *		<td>42113E</td>
766  *		<td>12/2015</td>
767  *		<td>Added input event feature.
768  *			Added support for SAM L21/L22, SAM C21, SAM D09, SAMR30 and SAM DA1.</td>
769  *	</tr>
770  *	<tr>
771  *		<td>42113D</td>
772  *		<td>12/2014</td>
773  *		<td>Added support for SAM R21 and SAM D10/D11</td>
774  *	</tr>
775  *	<tr>
776  *		<td>42113C</td>
777  *		<td>01/2014</td>
778  *		<td>Added support for SAM D21</td>
779  *	</tr>
780  *	<tr>
781  *		<td>42113B</td>
782  *		<td>06/2013</td>
783  *		<td>Corrected documentation typos</td>
784  *	</tr>
785  *	<tr>
786  *		<td>42113A</td>
787  *		<td>06/2013</td>
788  *		<td>Initial document release</td>
789  *	</tr>
790  * </table>
791  */
792 
793 #endif
794