xref: /btstack/port/samv71-xplained-atwilc3000/ASF/sam/drivers/pio/pio.c (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald  * \file
3*1b2596b5SMatthias Ringwald  *
4*1b2596b5SMatthias Ringwald  * \brief Parallel Input/Output (PIO) Controller driver for SAM.
5*1b2596b5SMatthias Ringwald  *
6*1b2596b5SMatthias Ringwald  * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
7*1b2596b5SMatthias Ringwald  *
8*1b2596b5SMatthias Ringwald  * \asf_license_start
9*1b2596b5SMatthias Ringwald  *
10*1b2596b5SMatthias Ringwald  * \page License
11*1b2596b5SMatthias Ringwald  *
12*1b2596b5SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
13*1b2596b5SMatthias Ringwald  * modification, are permitted provided that the following conditions are met:
14*1b2596b5SMatthias Ringwald  *
15*1b2596b5SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright notice,
16*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer.
17*1b2596b5SMatthias Ringwald  *
18*1b2596b5SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright notice,
19*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer in the documentation
20*1b2596b5SMatthias Ringwald  *    and/or other materials provided with the distribution.
21*1b2596b5SMatthias Ringwald  *
22*1b2596b5SMatthias Ringwald  * 3. The name of Atmel may not be used to endorse or promote products derived
23*1b2596b5SMatthias Ringwald  *    from this software without specific prior written permission.
24*1b2596b5SMatthias Ringwald  *
25*1b2596b5SMatthias Ringwald  * 4. This software may only be redistributed and used in connection with an
26*1b2596b5SMatthias Ringwald  *    Atmel microcontroller product.
27*1b2596b5SMatthias Ringwald  *
28*1b2596b5SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29*1b2596b5SMatthias Ringwald  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30*1b2596b5SMatthias Ringwald  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31*1b2596b5SMatthias Ringwald  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32*1b2596b5SMatthias Ringwald  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33*1b2596b5SMatthias Ringwald  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34*1b2596b5SMatthias Ringwald  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35*1b2596b5SMatthias Ringwald  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36*1b2596b5SMatthias Ringwald  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37*1b2596b5SMatthias Ringwald  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*1b2596b5SMatthias Ringwald  * POSSIBILITY OF SUCH DAMAGE.
39*1b2596b5SMatthias Ringwald  *
40*1b2596b5SMatthias Ringwald  * \asf_license_stop
41*1b2596b5SMatthias Ringwald  *
42*1b2596b5SMatthias Ringwald  */
43*1b2596b5SMatthias Ringwald /*
44*1b2596b5SMatthias Ringwald  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45*1b2596b5SMatthias Ringwald  */
46*1b2596b5SMatthias Ringwald 
47*1b2596b5SMatthias Ringwald #include "pio.h"
48*1b2596b5SMatthias Ringwald 
49*1b2596b5SMatthias Ringwald #ifndef PIO_WPMR_WPKEY_PASSWD
50*1b2596b5SMatthias Ringwald #  define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494Fu)
51*1b2596b5SMatthias Ringwald #endif
52*1b2596b5SMatthias Ringwald 
53*1b2596b5SMatthias Ringwald /**
54*1b2596b5SMatthias Ringwald  * \defgroup sam_drivers_pio_group Peripheral Parallel Input/Output (PIO) Controller
55*1b2596b5SMatthias Ringwald  *
56*1b2596b5SMatthias Ringwald  * \par Purpose
57*1b2596b5SMatthias Ringwald  *
58*1b2596b5SMatthias Ringwald  * The Parallel Input/Output Controller (PIO) manages up to 32 fully
59*1b2596b5SMatthias Ringwald  * programmable input/output lines. Each I/O line may be dedicated as a
60*1b2596b5SMatthias Ringwald  * general-purpose I/O or be assigned to a function of an embedded peripheral.
61*1b2596b5SMatthias Ringwald  * This assures effective optimization of the pins of a product.
62*1b2596b5SMatthias Ringwald  *
63*1b2596b5SMatthias Ringwald  * @{
64*1b2596b5SMatthias Ringwald  */
65*1b2596b5SMatthias Ringwald 
66*1b2596b5SMatthias Ringwald #ifndef FREQ_SLOW_CLOCK_EXT
67*1b2596b5SMatthias Ringwald /* External slow clock frequency (hz) */
68*1b2596b5SMatthias Ringwald #define FREQ_SLOW_CLOCK_EXT 32768
69*1b2596b5SMatthias Ringwald #endif
70*1b2596b5SMatthias Ringwald 
71*1b2596b5SMatthias Ringwald /**
72*1b2596b5SMatthias Ringwald  * \brief Configure PIO internal pull-up.
73*1b2596b5SMatthias Ringwald  *
74*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
75*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
76*1b2596b5SMatthias Ringwald  * \param ul_pull_up_enable Indicates if the pin(s) internal pull-up shall be
77*1b2596b5SMatthias Ringwald  * configured.
78*1b2596b5SMatthias Ringwald  */
pio_pull_up(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_pull_up_enable)79*1b2596b5SMatthias Ringwald void pio_pull_up(Pio *p_pio, const uint32_t ul_mask,
80*1b2596b5SMatthias Ringwald 		const uint32_t ul_pull_up_enable)
81*1b2596b5SMatthias Ringwald {
82*1b2596b5SMatthias Ringwald 	/* Enable the pull-up(s) if necessary */
83*1b2596b5SMatthias Ringwald 	if (ul_pull_up_enable) {
84*1b2596b5SMatthias Ringwald 		p_pio->PIO_PUER = ul_mask;
85*1b2596b5SMatthias Ringwald 	} else {
86*1b2596b5SMatthias Ringwald 		p_pio->PIO_PUDR = ul_mask;
87*1b2596b5SMatthias Ringwald 	}
88*1b2596b5SMatthias Ringwald }
89*1b2596b5SMatthias Ringwald 
90*1b2596b5SMatthias Ringwald /**
91*1b2596b5SMatthias Ringwald  * \brief Configure Glitch or Debouncing filter for the specified input(s).
92*1b2596b5SMatthias Ringwald  *
93*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
94*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
95*1b2596b5SMatthias Ringwald  * \param ul_cut_off Cuts off frequency for debouncing filter.
96*1b2596b5SMatthias Ringwald  */
pio_set_debounce_filter(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_cut_off)97*1b2596b5SMatthias Ringwald void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask,
98*1b2596b5SMatthias Ringwald 		const uint32_t ul_cut_off)
99*1b2596b5SMatthias Ringwald {
100*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
101*1b2596b5SMatthias Ringwald 	/* Set Debouncing, 0 bit field no effect */
102*1b2596b5SMatthias Ringwald 	p_pio->PIO_IFSCER = ul_mask;
103*1b2596b5SMatthias Ringwald #elif (SAM3XA || SAM3U)
104*1b2596b5SMatthias Ringwald 	/* Set Debouncing, 0 bit field no effect */
105*1b2596b5SMatthias Ringwald 	p_pio->PIO_DIFSR = ul_mask;
106*1b2596b5SMatthias Ringwald #else
107*1b2596b5SMatthias Ringwald #error "Unsupported device"
108*1b2596b5SMatthias Ringwald #endif
109*1b2596b5SMatthias Ringwald 
110*1b2596b5SMatthias Ringwald 	/*
111*1b2596b5SMatthias Ringwald 	 * The debouncing filter can filter a pulse of less than 1/2 Period of a
112*1b2596b5SMatthias Ringwald 	 * programmable Divided Slow Clock:
113*1b2596b5SMatthias Ringwald 	 * Tdiv_slclk = ((DIV+1)*2).Tslow_clock
114*1b2596b5SMatthias Ringwald 	 */
115*1b2596b5SMatthias Ringwald 	p_pio->PIO_SCDR = PIO_SCDR_DIV((FREQ_SLOW_CLOCK_EXT /
116*1b2596b5SMatthias Ringwald 			(2 * (ul_cut_off))) - 1);
117*1b2596b5SMatthias Ringwald }
118*1b2596b5SMatthias Ringwald 
119*1b2596b5SMatthias Ringwald /**
120*1b2596b5SMatthias Ringwald  * \brief Set a high output level on all the PIOs defined in ul_mask.
121*1b2596b5SMatthias Ringwald  * This has no immediate effects on PIOs that are not output, but the PIO
122*1b2596b5SMatthias Ringwald  * controller will save the value if they are changed to outputs.
123*1b2596b5SMatthias Ringwald  *
124*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
125*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
126*1b2596b5SMatthias Ringwald  */
pio_set(Pio * p_pio,const uint32_t ul_mask)127*1b2596b5SMatthias Ringwald void pio_set(Pio *p_pio, const uint32_t ul_mask)
128*1b2596b5SMatthias Ringwald {
129*1b2596b5SMatthias Ringwald 	p_pio->PIO_SODR = ul_mask;
130*1b2596b5SMatthias Ringwald }
131*1b2596b5SMatthias Ringwald 
132*1b2596b5SMatthias Ringwald /**
133*1b2596b5SMatthias Ringwald  * \brief Set a low output level on all the PIOs defined in ul_mask.
134*1b2596b5SMatthias Ringwald  * This has no immediate effects on PIOs that are not output, but the PIO
135*1b2596b5SMatthias Ringwald  * controller will save the value if they are changed to outputs.
136*1b2596b5SMatthias Ringwald  *
137*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
138*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
139*1b2596b5SMatthias Ringwald  */
pio_clear(Pio * p_pio,const uint32_t ul_mask)140*1b2596b5SMatthias Ringwald void pio_clear(Pio *p_pio, const uint32_t ul_mask)
141*1b2596b5SMatthias Ringwald {
142*1b2596b5SMatthias Ringwald 	p_pio->PIO_CODR = ul_mask;
143*1b2596b5SMatthias Ringwald }
144*1b2596b5SMatthias Ringwald 
145*1b2596b5SMatthias Ringwald /**
146*1b2596b5SMatthias Ringwald  * \brief Return 1 if one or more PIOs of the given Pin instance currently have
147*1b2596b5SMatthias Ringwald  * a high level; otherwise returns 0. This method returns the actual value that
148*1b2596b5SMatthias Ringwald  * is being read on the pin. To return the supposed output value of a pin, use
149*1b2596b5SMatthias Ringwald  * pio_get_output_data_status() instead.
150*1b2596b5SMatthias Ringwald  *
151*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
152*1b2596b5SMatthias Ringwald  * \param ul_type PIO type.
153*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
154*1b2596b5SMatthias Ringwald  *
155*1b2596b5SMatthias Ringwald  * \retval 1 at least one PIO currently has a high level.
156*1b2596b5SMatthias Ringwald  * \retval 0 all PIOs have a low level.
157*1b2596b5SMatthias Ringwald  */
pio_get(Pio * p_pio,const pio_type_t ul_type,const uint32_t ul_mask)158*1b2596b5SMatthias Ringwald uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type,
159*1b2596b5SMatthias Ringwald 		const uint32_t ul_mask)
160*1b2596b5SMatthias Ringwald {
161*1b2596b5SMatthias Ringwald 	uint32_t ul_reg;
162*1b2596b5SMatthias Ringwald 
163*1b2596b5SMatthias Ringwald 	if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) {
164*1b2596b5SMatthias Ringwald 		ul_reg = p_pio->PIO_ODSR;
165*1b2596b5SMatthias Ringwald 	} else {
166*1b2596b5SMatthias Ringwald 		ul_reg = p_pio->PIO_PDSR;
167*1b2596b5SMatthias Ringwald 	}
168*1b2596b5SMatthias Ringwald 
169*1b2596b5SMatthias Ringwald 	if ((ul_reg & ul_mask) == 0) {
170*1b2596b5SMatthias Ringwald 		return 0;
171*1b2596b5SMatthias Ringwald 	} else {
172*1b2596b5SMatthias Ringwald 		return 1;
173*1b2596b5SMatthias Ringwald 	}
174*1b2596b5SMatthias Ringwald }
175*1b2596b5SMatthias Ringwald 
176*1b2596b5SMatthias Ringwald /**
177*1b2596b5SMatthias Ringwald  * \brief Configure IO of a PIO controller as being controlled by a specific
178*1b2596b5SMatthias Ringwald  * peripheral.
179*1b2596b5SMatthias Ringwald  *
180*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
181*1b2596b5SMatthias Ringwald  * \param ul_type PIO type.
182*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
183*1b2596b5SMatthias Ringwald  */
pio_set_peripheral(Pio * p_pio,const pio_type_t ul_type,const uint32_t ul_mask)184*1b2596b5SMatthias Ringwald void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type,
185*1b2596b5SMatthias Ringwald 		const uint32_t ul_mask)
186*1b2596b5SMatthias Ringwald {
187*1b2596b5SMatthias Ringwald 	uint32_t ul_sr;
188*1b2596b5SMatthias Ringwald 
189*1b2596b5SMatthias Ringwald 	/* Disable interrupts on the pin(s) */
190*1b2596b5SMatthias Ringwald 	p_pio->PIO_IDR = ul_mask;
191*1b2596b5SMatthias Ringwald 
192*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
193*1b2596b5SMatthias Ringwald 	switch (ul_type) {
194*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_A:
195*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[0];
196*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);
197*1b2596b5SMatthias Ringwald 
198*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[1];
199*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);
200*1b2596b5SMatthias Ringwald 		break;
201*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_B:
202*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[0];
203*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);
204*1b2596b5SMatthias Ringwald 
205*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[1];
206*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);
207*1b2596b5SMatthias Ringwald 		break;
208*1b2596b5SMatthias Ringwald #if (!SAMG)
209*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_C:
210*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[0];
211*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);
212*1b2596b5SMatthias Ringwald 
213*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[1];
214*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);
215*1b2596b5SMatthias Ringwald 		break;
216*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_D:
217*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[0];
218*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);
219*1b2596b5SMatthias Ringwald 
220*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABCDSR[1];
221*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);
222*1b2596b5SMatthias Ringwald 		break;
223*1b2596b5SMatthias Ringwald #endif
224*1b2596b5SMatthias Ringwald 		/* Other types are invalid in this function */
225*1b2596b5SMatthias Ringwald 	case PIO_INPUT:
226*1b2596b5SMatthias Ringwald 	case PIO_OUTPUT_0:
227*1b2596b5SMatthias Ringwald 	case PIO_OUTPUT_1:
228*1b2596b5SMatthias Ringwald 	case PIO_NOT_A_PIN:
229*1b2596b5SMatthias Ringwald 		return;
230*1b2596b5SMatthias Ringwald 	}
231*1b2596b5SMatthias Ringwald #elif (SAM3XA|| SAM3U)
232*1b2596b5SMatthias Ringwald 	switch (ul_type) {
233*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_A:
234*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABSR;
235*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABSR &= (~ul_mask & ul_sr);
236*1b2596b5SMatthias Ringwald 		break;
237*1b2596b5SMatthias Ringwald 
238*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_B:
239*1b2596b5SMatthias Ringwald 		ul_sr = p_pio->PIO_ABSR;
240*1b2596b5SMatthias Ringwald 		p_pio->PIO_ABSR = (ul_mask | ul_sr);
241*1b2596b5SMatthias Ringwald 		break;
242*1b2596b5SMatthias Ringwald 
243*1b2596b5SMatthias Ringwald 		// other types are invalid in this function
244*1b2596b5SMatthias Ringwald 	case PIO_INPUT:
245*1b2596b5SMatthias Ringwald 	case PIO_OUTPUT_0:
246*1b2596b5SMatthias Ringwald 	case PIO_OUTPUT_1:
247*1b2596b5SMatthias Ringwald 	case PIO_NOT_A_PIN:
248*1b2596b5SMatthias Ringwald 		return;
249*1b2596b5SMatthias Ringwald 	}
250*1b2596b5SMatthias Ringwald #else
251*1b2596b5SMatthias Ringwald #error "Unsupported device"
252*1b2596b5SMatthias Ringwald #endif
253*1b2596b5SMatthias Ringwald 
254*1b2596b5SMatthias Ringwald 	/* Remove the pins from under the control of PIO */
255*1b2596b5SMatthias Ringwald 	p_pio->PIO_PDR = ul_mask;
256*1b2596b5SMatthias Ringwald }
257*1b2596b5SMatthias Ringwald 
258*1b2596b5SMatthias Ringwald /**
259*1b2596b5SMatthias Ringwald  * \brief Configure one or more pin(s) or a PIO controller as inputs.
260*1b2596b5SMatthias Ringwald  * Optionally, the corresponding internal pull-up(s) and glitch filter(s) can
261*1b2596b5SMatthias Ringwald  * be enabled.
262*1b2596b5SMatthias Ringwald  *
263*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
264*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask indicating which pin(s) to configure as input(s).
265*1b2596b5SMatthias Ringwald  * \param ul_attribute PIO attribute(s).
266*1b2596b5SMatthias Ringwald  */
pio_set_input(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_attribute)267*1b2596b5SMatthias Ringwald void pio_set_input(Pio *p_pio, const uint32_t ul_mask,
268*1b2596b5SMatthias Ringwald 		const uint32_t ul_attribute)
269*1b2596b5SMatthias Ringwald {
270*1b2596b5SMatthias Ringwald 	pio_disable_interrupt(p_pio, ul_mask);
271*1b2596b5SMatthias Ringwald 	pio_pull_up(p_pio, ul_mask, ul_attribute & PIO_PULLUP);
272*1b2596b5SMatthias Ringwald 
273*1b2596b5SMatthias Ringwald 	/* Enable Input Filter if necessary */
274*1b2596b5SMatthias Ringwald 	if (ul_attribute & (PIO_DEGLITCH | PIO_DEBOUNCE)) {
275*1b2596b5SMatthias Ringwald 		p_pio->PIO_IFER = ul_mask;
276*1b2596b5SMatthias Ringwald 	} else {
277*1b2596b5SMatthias Ringwald 		p_pio->PIO_IFDR = ul_mask;
278*1b2596b5SMatthias Ringwald 	}
279*1b2596b5SMatthias Ringwald 
280*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
281*1b2596b5SMatthias Ringwald 	/* Enable de-glitch or de-bounce if necessary */
282*1b2596b5SMatthias Ringwald 	if (ul_attribute & PIO_DEGLITCH) {
283*1b2596b5SMatthias Ringwald 		p_pio->PIO_IFSCDR = ul_mask;
284*1b2596b5SMatthias Ringwald 	} else {
285*1b2596b5SMatthias Ringwald 		if (ul_attribute & PIO_DEBOUNCE) {
286*1b2596b5SMatthias Ringwald 			p_pio->PIO_IFSCER = ul_mask;
287*1b2596b5SMatthias Ringwald 		}
288*1b2596b5SMatthias Ringwald 	}
289*1b2596b5SMatthias Ringwald #elif (SAM3XA|| SAM3U)
290*1b2596b5SMatthias Ringwald 	/* Enable de-glitch or de-bounce if necessary */
291*1b2596b5SMatthias Ringwald 	if (ul_attribute & PIO_DEGLITCH) {
292*1b2596b5SMatthias Ringwald 		p_pio->PIO_SCIFSR = ul_mask;
293*1b2596b5SMatthias Ringwald 	} else {
294*1b2596b5SMatthias Ringwald 		if (ul_attribute & PIO_DEBOUNCE) {
295*1b2596b5SMatthias Ringwald 			p_pio->PIO_DIFSR = ul_mask;
296*1b2596b5SMatthias Ringwald 		}
297*1b2596b5SMatthias Ringwald 	}
298*1b2596b5SMatthias Ringwald #else
299*1b2596b5SMatthias Ringwald #error "Unsupported device"
300*1b2596b5SMatthias Ringwald #endif
301*1b2596b5SMatthias Ringwald 
302*1b2596b5SMatthias Ringwald 	/* Configure pin as input */
303*1b2596b5SMatthias Ringwald 	p_pio->PIO_ODR = ul_mask;
304*1b2596b5SMatthias Ringwald 	p_pio->PIO_PER = ul_mask;
305*1b2596b5SMatthias Ringwald }
306*1b2596b5SMatthias Ringwald 
307*1b2596b5SMatthias Ringwald /**
308*1b2596b5SMatthias Ringwald  * \brief Configure one or more pin(s) of a PIO controller as outputs, with
309*1b2596b5SMatthias Ringwald  * the given default value. Optionally, the multi-drive feature can be enabled
310*1b2596b5SMatthias Ringwald  * on the pin(s).
311*1b2596b5SMatthias Ringwald  *
312*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
313*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask indicating which pin(s) to configure.
314*1b2596b5SMatthias Ringwald  * \param ul_default_level Default level on the pin(s).
315*1b2596b5SMatthias Ringwald  * \param ul_multidrive_enable Indicates if the pin(s) shall be configured as
316*1b2596b5SMatthias Ringwald  * open-drain.
317*1b2596b5SMatthias Ringwald  * \param ul_pull_up_enable Indicates if the pin shall have its pull-up
318*1b2596b5SMatthias Ringwald  * activated.
319*1b2596b5SMatthias Ringwald  */
pio_set_output(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_default_level,const uint32_t ul_multidrive_enable,const uint32_t ul_pull_up_enable)320*1b2596b5SMatthias Ringwald void pio_set_output(Pio *p_pio, const uint32_t ul_mask,
321*1b2596b5SMatthias Ringwald 		const uint32_t ul_default_level,
322*1b2596b5SMatthias Ringwald 		const uint32_t ul_multidrive_enable,
323*1b2596b5SMatthias Ringwald 		const uint32_t ul_pull_up_enable)
324*1b2596b5SMatthias Ringwald {
325*1b2596b5SMatthias Ringwald 	pio_disable_interrupt(p_pio, ul_mask);
326*1b2596b5SMatthias Ringwald 	pio_pull_up(p_pio, ul_mask, ul_pull_up_enable);
327*1b2596b5SMatthias Ringwald 
328*1b2596b5SMatthias Ringwald 	/* Enable multi-drive if necessary */
329*1b2596b5SMatthias Ringwald 	if (ul_multidrive_enable) {
330*1b2596b5SMatthias Ringwald 		p_pio->PIO_MDER = ul_mask;
331*1b2596b5SMatthias Ringwald 	} else {
332*1b2596b5SMatthias Ringwald 		p_pio->PIO_MDDR = ul_mask;
333*1b2596b5SMatthias Ringwald 	}
334*1b2596b5SMatthias Ringwald 
335*1b2596b5SMatthias Ringwald 	/* Set default value */
336*1b2596b5SMatthias Ringwald 	if (ul_default_level) {
337*1b2596b5SMatthias Ringwald 		p_pio->PIO_SODR = ul_mask;
338*1b2596b5SMatthias Ringwald 	} else {
339*1b2596b5SMatthias Ringwald 		p_pio->PIO_CODR = ul_mask;
340*1b2596b5SMatthias Ringwald 	}
341*1b2596b5SMatthias Ringwald 
342*1b2596b5SMatthias Ringwald 	/* Configure pin(s) as output(s) */
343*1b2596b5SMatthias Ringwald 	p_pio->PIO_OER = ul_mask;
344*1b2596b5SMatthias Ringwald 	p_pio->PIO_PER = ul_mask;
345*1b2596b5SMatthias Ringwald }
346*1b2596b5SMatthias Ringwald 
347*1b2596b5SMatthias Ringwald /**
348*1b2596b5SMatthias Ringwald  * \brief Perform complete pin(s) configuration; general attributes and PIO init
349*1b2596b5SMatthias Ringwald  * if necessary.
350*1b2596b5SMatthias Ringwald  *
351*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
352*1b2596b5SMatthias Ringwald  * \param ul_type PIO type.
353*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
354*1b2596b5SMatthias Ringwald  * \param ul_attribute Pins attributes.
355*1b2596b5SMatthias Ringwald  *
356*1b2596b5SMatthias Ringwald  * \return Whether the pin(s) have been configured properly.
357*1b2596b5SMatthias Ringwald  */
pio_configure(Pio * p_pio,const pio_type_t ul_type,const uint32_t ul_mask,const uint32_t ul_attribute)358*1b2596b5SMatthias Ringwald uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type,
359*1b2596b5SMatthias Ringwald 		const uint32_t ul_mask, const uint32_t ul_attribute)
360*1b2596b5SMatthias Ringwald {
361*1b2596b5SMatthias Ringwald 	/* Configure pins */
362*1b2596b5SMatthias Ringwald 	switch (ul_type) {
363*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_A:
364*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_B:
365*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
366*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_C:
367*1b2596b5SMatthias Ringwald 	case PIO_PERIPH_D:
368*1b2596b5SMatthias Ringwald #endif
369*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, ul_type, ul_mask);
370*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, ul_mask, (ul_attribute & PIO_PULLUP));
371*1b2596b5SMatthias Ringwald 		break;
372*1b2596b5SMatthias Ringwald 
373*1b2596b5SMatthias Ringwald 	case PIO_INPUT:
374*1b2596b5SMatthias Ringwald 		pio_set_input(p_pio, ul_mask, ul_attribute);
375*1b2596b5SMatthias Ringwald 		break;
376*1b2596b5SMatthias Ringwald 
377*1b2596b5SMatthias Ringwald 	case PIO_OUTPUT_0:
378*1b2596b5SMatthias Ringwald 	case PIO_OUTPUT_1:
379*1b2596b5SMatthias Ringwald 		pio_set_output(p_pio, ul_mask, (ul_type == PIO_OUTPUT_1),
380*1b2596b5SMatthias Ringwald 				(ul_attribute & PIO_OPENDRAIN) ? 1 : 0,
381*1b2596b5SMatthias Ringwald 				(ul_attribute & PIO_PULLUP) ? 1 : 0);
382*1b2596b5SMatthias Ringwald 		break;
383*1b2596b5SMatthias Ringwald 
384*1b2596b5SMatthias Ringwald 	default:
385*1b2596b5SMatthias Ringwald 		return 0;
386*1b2596b5SMatthias Ringwald 	}
387*1b2596b5SMatthias Ringwald 
388*1b2596b5SMatthias Ringwald 	return 1;
389*1b2596b5SMatthias Ringwald }
390*1b2596b5SMatthias Ringwald 
391*1b2596b5SMatthias Ringwald /**
392*1b2596b5SMatthias Ringwald  * \brief Return 1 if one or more PIOs of the given Pin are configured to
393*1b2596b5SMatthias Ringwald  * output a high level (even if they are not output).
394*1b2596b5SMatthias Ringwald  * To get the actual value of the pin, use PIO_Get() instead.
395*1b2596b5SMatthias Ringwald  *
396*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
397*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s).
398*1b2596b5SMatthias Ringwald  *
399*1b2596b5SMatthias Ringwald  * \retval 1 At least one PIO is configured to output a high level.
400*1b2596b5SMatthias Ringwald  * \retval 0 All PIOs are configured to output a low level.
401*1b2596b5SMatthias Ringwald  */
pio_get_output_data_status(const Pio * p_pio,const uint32_t ul_mask)402*1b2596b5SMatthias Ringwald uint32_t pio_get_output_data_status(const Pio *p_pio,
403*1b2596b5SMatthias Ringwald 		const uint32_t ul_mask)
404*1b2596b5SMatthias Ringwald {
405*1b2596b5SMatthias Ringwald 	if ((p_pio->PIO_ODSR & ul_mask) == 0) {
406*1b2596b5SMatthias Ringwald 		return 0;
407*1b2596b5SMatthias Ringwald 	} else {
408*1b2596b5SMatthias Ringwald 		return 1;
409*1b2596b5SMatthias Ringwald 	}
410*1b2596b5SMatthias Ringwald }
411*1b2596b5SMatthias Ringwald 
412*1b2596b5SMatthias Ringwald /**
413*1b2596b5SMatthias Ringwald  * \brief Configure PIO pin multi-driver.
414*1b2596b5SMatthias Ringwald  *
415*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
416*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
417*1b2596b5SMatthias Ringwald  * \param ul_multi_driver_enable Indicates if the pin(s) multi-driver shall be
418*1b2596b5SMatthias Ringwald  * configured.
419*1b2596b5SMatthias Ringwald  */
pio_set_multi_driver(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_multi_driver_enable)420*1b2596b5SMatthias Ringwald void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask,
421*1b2596b5SMatthias Ringwald 		const uint32_t ul_multi_driver_enable)
422*1b2596b5SMatthias Ringwald {
423*1b2596b5SMatthias Ringwald 	/* Enable the multi-driver if necessary */
424*1b2596b5SMatthias Ringwald 	if (ul_multi_driver_enable) {
425*1b2596b5SMatthias Ringwald 		p_pio->PIO_MDER = ul_mask;
426*1b2596b5SMatthias Ringwald 	} else {
427*1b2596b5SMatthias Ringwald 		p_pio->PIO_MDDR = ul_mask;
428*1b2596b5SMatthias Ringwald 	}
429*1b2596b5SMatthias Ringwald }
430*1b2596b5SMatthias Ringwald 
431*1b2596b5SMatthias Ringwald /**
432*1b2596b5SMatthias Ringwald  * \brief Get multi-driver status.
433*1b2596b5SMatthias Ringwald  *
434*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
435*1b2596b5SMatthias Ringwald  *
436*1b2596b5SMatthias Ringwald  * \return The multi-driver mask value.
437*1b2596b5SMatthias Ringwald  */
pio_get_multi_driver_status(const Pio * p_pio)438*1b2596b5SMatthias Ringwald uint32_t pio_get_multi_driver_status(const Pio *p_pio)
439*1b2596b5SMatthias Ringwald {
440*1b2596b5SMatthias Ringwald 	return p_pio->PIO_MDSR;
441*1b2596b5SMatthias Ringwald }
442*1b2596b5SMatthias Ringwald 
443*1b2596b5SMatthias Ringwald 
444*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
445*1b2596b5SMatthias Ringwald /**
446*1b2596b5SMatthias Ringwald  * \brief Configure PIO pin internal pull-down.
447*1b2596b5SMatthias Ringwald  *
448*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
449*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
450*1b2596b5SMatthias Ringwald  * \param ul_pull_down_enable Indicates if the pin(s) internal pull-down shall
451*1b2596b5SMatthias Ringwald  * be configured.
452*1b2596b5SMatthias Ringwald  */
pio_pull_down(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_pull_down_enable)453*1b2596b5SMatthias Ringwald void pio_pull_down(Pio *p_pio, const uint32_t ul_mask,
454*1b2596b5SMatthias Ringwald 		const uint32_t ul_pull_down_enable)
455*1b2596b5SMatthias Ringwald {
456*1b2596b5SMatthias Ringwald 	/* Enable the pull-down if necessary */
457*1b2596b5SMatthias Ringwald 	if (ul_pull_down_enable) {
458*1b2596b5SMatthias Ringwald 		p_pio->PIO_PPDER = ul_mask;
459*1b2596b5SMatthias Ringwald 	} else {
460*1b2596b5SMatthias Ringwald 		p_pio->PIO_PPDDR = ul_mask;
461*1b2596b5SMatthias Ringwald 	}
462*1b2596b5SMatthias Ringwald }
463*1b2596b5SMatthias Ringwald #endif
464*1b2596b5SMatthias Ringwald 
465*1b2596b5SMatthias Ringwald /**
466*1b2596b5SMatthias Ringwald  * \brief Enable PIO output write for synchronous data output.
467*1b2596b5SMatthias Ringwald  *
468*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
469*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
470*1b2596b5SMatthias Ringwald  */
pio_enable_output_write(Pio * p_pio,const uint32_t ul_mask)471*1b2596b5SMatthias Ringwald void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask)
472*1b2596b5SMatthias Ringwald {
473*1b2596b5SMatthias Ringwald 	p_pio->PIO_OWER = ul_mask;
474*1b2596b5SMatthias Ringwald }
475*1b2596b5SMatthias Ringwald 
476*1b2596b5SMatthias Ringwald /**
477*1b2596b5SMatthias Ringwald  * \brief Disable PIO output write.
478*1b2596b5SMatthias Ringwald  *
479*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
480*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
481*1b2596b5SMatthias Ringwald  */
pio_disable_output_write(Pio * p_pio,const uint32_t ul_mask)482*1b2596b5SMatthias Ringwald void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask)
483*1b2596b5SMatthias Ringwald {
484*1b2596b5SMatthias Ringwald 	p_pio->PIO_OWDR = ul_mask;
485*1b2596b5SMatthias Ringwald }
486*1b2596b5SMatthias Ringwald 
487*1b2596b5SMatthias Ringwald /**
488*1b2596b5SMatthias Ringwald  * \brief Read PIO output write status.
489*1b2596b5SMatthias Ringwald  *
490*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
491*1b2596b5SMatthias Ringwald  *
492*1b2596b5SMatthias Ringwald  * \return The output write mask value.
493*1b2596b5SMatthias Ringwald  */
pio_get_output_write_status(const Pio * p_pio)494*1b2596b5SMatthias Ringwald uint32_t pio_get_output_write_status(const Pio *p_pio)
495*1b2596b5SMatthias Ringwald {
496*1b2596b5SMatthias Ringwald 	return p_pio->PIO_OWSR;
497*1b2596b5SMatthias Ringwald }
498*1b2596b5SMatthias Ringwald 
499*1b2596b5SMatthias Ringwald /**
500*1b2596b5SMatthias Ringwald  * \brief Synchronously write on output pins.
501*1b2596b5SMatthias Ringwald  * \note Only bits unmasked by PIO_OWSR (Output Write Status Register) are
502*1b2596b5SMatthias Ringwald  * written.
503*1b2596b5SMatthias Ringwald  *
504*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
505*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
506*1b2596b5SMatthias Ringwald  */
pio_sync_output_write(Pio * p_pio,const uint32_t ul_mask)507*1b2596b5SMatthias Ringwald void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask)
508*1b2596b5SMatthias Ringwald {
509*1b2596b5SMatthias Ringwald 	p_pio->PIO_ODSR = ul_mask;
510*1b2596b5SMatthias Ringwald }
511*1b2596b5SMatthias Ringwald 
512*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
513*1b2596b5SMatthias Ringwald /**
514*1b2596b5SMatthias Ringwald  * \brief Configure PIO pin schmitt trigger. By default the Schmitt trigger is
515*1b2596b5SMatthias Ringwald  * active.
516*1b2596b5SMatthias Ringwald  * Disabling the Schmitt Trigger is requested when using the QTouch Library.
517*1b2596b5SMatthias Ringwald  *
518*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
519*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
520*1b2596b5SMatthias Ringwald  */
pio_set_schmitt_trigger(Pio * p_pio,const uint32_t ul_mask)521*1b2596b5SMatthias Ringwald void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask)
522*1b2596b5SMatthias Ringwald {
523*1b2596b5SMatthias Ringwald 	p_pio->PIO_SCHMITT = ul_mask;
524*1b2596b5SMatthias Ringwald }
525*1b2596b5SMatthias Ringwald 
526*1b2596b5SMatthias Ringwald /**
527*1b2596b5SMatthias Ringwald  * \brief Get PIO pin schmitt trigger status.
528*1b2596b5SMatthias Ringwald  *
529*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
530*1b2596b5SMatthias Ringwald  *
531*1b2596b5SMatthias Ringwald  * \return The schmitt trigger mask value.
532*1b2596b5SMatthias Ringwald  */
pio_get_schmitt_trigger(const Pio * p_pio)533*1b2596b5SMatthias Ringwald uint32_t pio_get_schmitt_trigger(const Pio *p_pio)
534*1b2596b5SMatthias Ringwald {
535*1b2596b5SMatthias Ringwald 	return p_pio->PIO_SCHMITT;
536*1b2596b5SMatthias Ringwald }
537*1b2596b5SMatthias Ringwald #endif
538*1b2596b5SMatthias Ringwald 
539*1b2596b5SMatthias Ringwald /**
540*1b2596b5SMatthias Ringwald  * \brief Configure the given interrupt source.
541*1b2596b5SMatthias Ringwald  * Interrupt can be configured to trigger on rising edge, falling edge,
542*1b2596b5SMatthias Ringwald  * high level, low level or simply on level change.
543*1b2596b5SMatthias Ringwald  *
544*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
545*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt source bit map.
546*1b2596b5SMatthias Ringwald  * \param ul_attr Interrupt source attributes.
547*1b2596b5SMatthias Ringwald  */
pio_configure_interrupt(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_attr)548*1b2596b5SMatthias Ringwald void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask,
549*1b2596b5SMatthias Ringwald 		const uint32_t ul_attr)
550*1b2596b5SMatthias Ringwald {
551*1b2596b5SMatthias Ringwald 	/* Configure additional interrupt mode registers. */
552*1b2596b5SMatthias Ringwald 	if (ul_attr & PIO_IT_AIME) {
553*1b2596b5SMatthias Ringwald 		/* Enable additional interrupt mode. */
554*1b2596b5SMatthias Ringwald 		p_pio->PIO_AIMER = ul_mask;
555*1b2596b5SMatthias Ringwald 
556*1b2596b5SMatthias Ringwald 		/* If bit field of the selected pin is 1, set as
557*1b2596b5SMatthias Ringwald 		   Rising Edge/High level detection event. */
558*1b2596b5SMatthias Ringwald 		if (ul_attr & PIO_IT_RE_OR_HL) {
559*1b2596b5SMatthias Ringwald 			/* Rising Edge or High Level */
560*1b2596b5SMatthias Ringwald 			p_pio->PIO_REHLSR = ul_mask;
561*1b2596b5SMatthias Ringwald 		} else {
562*1b2596b5SMatthias Ringwald 			/* Falling Edge or Low Level */
563*1b2596b5SMatthias Ringwald 			p_pio->PIO_FELLSR = ul_mask;
564*1b2596b5SMatthias Ringwald 		}
565*1b2596b5SMatthias Ringwald 
566*1b2596b5SMatthias Ringwald 		/* If bit field of the selected pin is 1, set as
567*1b2596b5SMatthias Ringwald 		   edge detection source. */
568*1b2596b5SMatthias Ringwald 		if (ul_attr & PIO_IT_EDGE) {
569*1b2596b5SMatthias Ringwald 			/* Edge select */
570*1b2596b5SMatthias Ringwald 			p_pio->PIO_ESR = ul_mask;
571*1b2596b5SMatthias Ringwald 		} else {
572*1b2596b5SMatthias Ringwald 			/* Level select */
573*1b2596b5SMatthias Ringwald 			p_pio->PIO_LSR = ul_mask;
574*1b2596b5SMatthias Ringwald 		}
575*1b2596b5SMatthias Ringwald 	} else {
576*1b2596b5SMatthias Ringwald 		/* Disable additional interrupt mode. */
577*1b2596b5SMatthias Ringwald 		p_pio->PIO_AIMDR = ul_mask;
578*1b2596b5SMatthias Ringwald 	}
579*1b2596b5SMatthias Ringwald }
580*1b2596b5SMatthias Ringwald 
581*1b2596b5SMatthias Ringwald /**
582*1b2596b5SMatthias Ringwald  * \brief Enable the given interrupt source.
583*1b2596b5SMatthias Ringwald  * The PIO must be configured as an NVIC interrupt source as well.
584*1b2596b5SMatthias Ringwald  * The status register of the corresponding PIO controller is cleared
585*1b2596b5SMatthias Ringwald  * prior to enabling the interrupt.
586*1b2596b5SMatthias Ringwald  *
587*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
588*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
589*1b2596b5SMatthias Ringwald  */
pio_enable_interrupt(Pio * p_pio,const uint32_t ul_mask)590*1b2596b5SMatthias Ringwald void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
591*1b2596b5SMatthias Ringwald {
592*1b2596b5SMatthias Ringwald 	p_pio->PIO_ISR;
593*1b2596b5SMatthias Ringwald 	p_pio->PIO_IER = ul_mask;
594*1b2596b5SMatthias Ringwald }
595*1b2596b5SMatthias Ringwald 
596*1b2596b5SMatthias Ringwald /**
597*1b2596b5SMatthias Ringwald  * \brief Disable a given interrupt source, with no added side effects.
598*1b2596b5SMatthias Ringwald  *
599*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
600*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
601*1b2596b5SMatthias Ringwald  */
pio_disable_interrupt(Pio * p_pio,const uint32_t ul_mask)602*1b2596b5SMatthias Ringwald void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
603*1b2596b5SMatthias Ringwald {
604*1b2596b5SMatthias Ringwald 	p_pio->PIO_IDR = ul_mask;
605*1b2596b5SMatthias Ringwald }
606*1b2596b5SMatthias Ringwald 
607*1b2596b5SMatthias Ringwald /**
608*1b2596b5SMatthias Ringwald  * \brief Read PIO interrupt status.
609*1b2596b5SMatthias Ringwald  *
610*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
611*1b2596b5SMatthias Ringwald  *
612*1b2596b5SMatthias Ringwald  * \return The interrupt status mask value.
613*1b2596b5SMatthias Ringwald  */
pio_get_interrupt_status(const Pio * p_pio)614*1b2596b5SMatthias Ringwald uint32_t pio_get_interrupt_status(const Pio *p_pio)
615*1b2596b5SMatthias Ringwald {
616*1b2596b5SMatthias Ringwald 	return p_pio->PIO_ISR;
617*1b2596b5SMatthias Ringwald }
618*1b2596b5SMatthias Ringwald 
619*1b2596b5SMatthias Ringwald /**
620*1b2596b5SMatthias Ringwald  * \brief Read PIO interrupt mask.
621*1b2596b5SMatthias Ringwald  *
622*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
623*1b2596b5SMatthias Ringwald  *
624*1b2596b5SMatthias Ringwald  * \return The interrupt mask value.
625*1b2596b5SMatthias Ringwald  */
pio_get_interrupt_mask(const Pio * p_pio)626*1b2596b5SMatthias Ringwald uint32_t pio_get_interrupt_mask(const Pio *p_pio)
627*1b2596b5SMatthias Ringwald {
628*1b2596b5SMatthias Ringwald 	return p_pio->PIO_IMR;
629*1b2596b5SMatthias Ringwald }
630*1b2596b5SMatthias Ringwald 
631*1b2596b5SMatthias Ringwald /**
632*1b2596b5SMatthias Ringwald  * \brief Set additional interrupt mode.
633*1b2596b5SMatthias Ringwald  *
634*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
635*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
636*1b2596b5SMatthias Ringwald  * \param ul_attribute Pin(s) attributes.
637*1b2596b5SMatthias Ringwald  */
pio_set_additional_interrupt_mode(Pio * p_pio,const uint32_t ul_mask,const uint32_t ul_attribute)638*1b2596b5SMatthias Ringwald void pio_set_additional_interrupt_mode(Pio *p_pio,
639*1b2596b5SMatthias Ringwald 		const uint32_t ul_mask, const uint32_t ul_attribute)
640*1b2596b5SMatthias Ringwald {
641*1b2596b5SMatthias Ringwald 	/* Enables additional interrupt mode if needed */
642*1b2596b5SMatthias Ringwald 	if (ul_attribute & PIO_IT_AIME) {
643*1b2596b5SMatthias Ringwald 		/* Enables additional interrupt mode */
644*1b2596b5SMatthias Ringwald 		p_pio->PIO_AIMER = ul_mask;
645*1b2596b5SMatthias Ringwald 
646*1b2596b5SMatthias Ringwald 		/* Configures the Polarity of the event detection */
647*1b2596b5SMatthias Ringwald 		/* (Rising/Falling Edge or High/Low Level) */
648*1b2596b5SMatthias Ringwald 		if (ul_attribute & PIO_IT_RE_OR_HL) {
649*1b2596b5SMatthias Ringwald 			/* Rising Edge or High Level */
650*1b2596b5SMatthias Ringwald 			p_pio->PIO_REHLSR = ul_mask;
651*1b2596b5SMatthias Ringwald 		} else {
652*1b2596b5SMatthias Ringwald 			/* Falling Edge or Low Level */
653*1b2596b5SMatthias Ringwald 			p_pio->PIO_FELLSR = ul_mask;
654*1b2596b5SMatthias Ringwald 		}
655*1b2596b5SMatthias Ringwald 
656*1b2596b5SMatthias Ringwald 		/* Configures the type of event detection (Edge or Level) */
657*1b2596b5SMatthias Ringwald 		if (ul_attribute & PIO_IT_EDGE) {
658*1b2596b5SMatthias Ringwald 			/* Edge select */
659*1b2596b5SMatthias Ringwald 			p_pio->PIO_ESR = ul_mask;
660*1b2596b5SMatthias Ringwald 		} else {
661*1b2596b5SMatthias Ringwald 			/* Level select */
662*1b2596b5SMatthias Ringwald 			p_pio->PIO_LSR = ul_mask;
663*1b2596b5SMatthias Ringwald 		}
664*1b2596b5SMatthias Ringwald 	} else {
665*1b2596b5SMatthias Ringwald 		/* Disable additional interrupt mode */
666*1b2596b5SMatthias Ringwald 		p_pio->PIO_AIMDR = ul_mask;
667*1b2596b5SMatthias Ringwald 	}
668*1b2596b5SMatthias Ringwald }
669*1b2596b5SMatthias Ringwald 
670*1b2596b5SMatthias Ringwald #ifndef PIO_WPMR_WPKEY_PASSWD
671*1b2596b5SMatthias Ringwald #define PIO_WPMR_WPKEY_PASSWD    PIO_WPMR_WPKEY(0x50494FU)
672*1b2596b5SMatthias Ringwald #endif
673*1b2596b5SMatthias Ringwald 
674*1b2596b5SMatthias Ringwald /**
675*1b2596b5SMatthias Ringwald  * \brief Enable or disable write protect of PIO registers.
676*1b2596b5SMatthias Ringwald  *
677*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
678*1b2596b5SMatthias Ringwald  * \param ul_enable 1 to enable, 0 to disable.
679*1b2596b5SMatthias Ringwald  */
pio_set_writeprotect(Pio * p_pio,const uint32_t ul_enable)680*1b2596b5SMatthias Ringwald void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable)
681*1b2596b5SMatthias Ringwald {
682*1b2596b5SMatthias Ringwald 	p_pio->PIO_WPMR = PIO_WPMR_WPKEY_PASSWD | (ul_enable & PIO_WPMR_WPEN);
683*1b2596b5SMatthias Ringwald }
684*1b2596b5SMatthias Ringwald 
685*1b2596b5SMatthias Ringwald /**
686*1b2596b5SMatthias Ringwald  * \brief Read write protect status.
687*1b2596b5SMatthias Ringwald  *
688*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
689*1b2596b5SMatthias Ringwald  *
690*1b2596b5SMatthias Ringwald  * \return Return write protect status.
691*1b2596b5SMatthias Ringwald  */
pio_get_writeprotect_status(const Pio * p_pio)692*1b2596b5SMatthias Ringwald uint32_t pio_get_writeprotect_status(const Pio *p_pio)
693*1b2596b5SMatthias Ringwald {
694*1b2596b5SMatthias Ringwald 	return p_pio->PIO_WPSR;
695*1b2596b5SMatthias Ringwald }
696*1b2596b5SMatthias Ringwald 
697*1b2596b5SMatthias Ringwald /**
698*1b2596b5SMatthias Ringwald  * \brief Return the value of a pin.
699*1b2596b5SMatthias Ringwald  *
700*1b2596b5SMatthias Ringwald  * \param ul_pin The pin number.
701*1b2596b5SMatthias Ringwald  *
702*1b2596b5SMatthias Ringwald  * \return The pin value.
703*1b2596b5SMatthias Ringwald  *
704*1b2596b5SMatthias Ringwald  * \note If pin is output: a pull-up or pull-down could hide the actual value.
705*1b2596b5SMatthias Ringwald  *       The function \ref pio_get can be called to get the actual pin output
706*1b2596b5SMatthias Ringwald  *       level.
707*1b2596b5SMatthias Ringwald  * \note If pin is input: PIOx must be clocked to sample the signal.
708*1b2596b5SMatthias Ringwald  *       See PMC driver.
709*1b2596b5SMatthias Ringwald  */
pio_get_pin_value(uint32_t ul_pin)710*1b2596b5SMatthias Ringwald uint32_t pio_get_pin_value(uint32_t ul_pin)
711*1b2596b5SMatthias Ringwald {
712*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
713*1b2596b5SMatthias Ringwald 
714*1b2596b5SMatthias Ringwald 	return (p_pio->PIO_PDSR >> (ul_pin & 0x1F)) & 1;
715*1b2596b5SMatthias Ringwald }
716*1b2596b5SMatthias Ringwald 
717*1b2596b5SMatthias Ringwald /**
718*1b2596b5SMatthias Ringwald  * \brief Drive a GPIO pin to 1.
719*1b2596b5SMatthias Ringwald  *
720*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
721*1b2596b5SMatthias Ringwald  *
722*1b2596b5SMatthias Ringwald  * \note The function \ref pio_configure_pin must be called beforehand.
723*1b2596b5SMatthias Ringwald  */
pio_set_pin_high(uint32_t ul_pin)724*1b2596b5SMatthias Ringwald void pio_set_pin_high(uint32_t ul_pin)
725*1b2596b5SMatthias Ringwald {
726*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
727*1b2596b5SMatthias Ringwald 
728*1b2596b5SMatthias Ringwald 	/* Value to be driven on the I/O line: 1. */
729*1b2596b5SMatthias Ringwald 	p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
730*1b2596b5SMatthias Ringwald }
731*1b2596b5SMatthias Ringwald 
732*1b2596b5SMatthias Ringwald /**
733*1b2596b5SMatthias Ringwald  * \brief Drive a GPIO pin to 0.
734*1b2596b5SMatthias Ringwald  *
735*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
736*1b2596b5SMatthias Ringwald  *
737*1b2596b5SMatthias Ringwald  * \note The function \ref pio_configure_pin must be called before.
738*1b2596b5SMatthias Ringwald  */
pio_set_pin_low(uint32_t ul_pin)739*1b2596b5SMatthias Ringwald void pio_set_pin_low(uint32_t ul_pin)
740*1b2596b5SMatthias Ringwald {
741*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
742*1b2596b5SMatthias Ringwald 
743*1b2596b5SMatthias Ringwald 	/* Value to be driven on the I/O line: 0. */
744*1b2596b5SMatthias Ringwald 	p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);
745*1b2596b5SMatthias Ringwald }
746*1b2596b5SMatthias Ringwald 
747*1b2596b5SMatthias Ringwald /**
748*1b2596b5SMatthias Ringwald  * \brief Toggle a GPIO pin.
749*1b2596b5SMatthias Ringwald  *
750*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
751*1b2596b5SMatthias Ringwald  *
752*1b2596b5SMatthias Ringwald  * \note The function \ref pio_configure_pin must be called before.
753*1b2596b5SMatthias Ringwald  */
pio_toggle_pin(uint32_t ul_pin)754*1b2596b5SMatthias Ringwald void pio_toggle_pin(uint32_t ul_pin)
755*1b2596b5SMatthias Ringwald {
756*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
757*1b2596b5SMatthias Ringwald 
758*1b2596b5SMatthias Ringwald 	if (p_pio->PIO_ODSR & (1 << (ul_pin & 0x1F))) {
759*1b2596b5SMatthias Ringwald 		/* Value to be driven on the I/O line: 0. */
760*1b2596b5SMatthias Ringwald 		p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);
761*1b2596b5SMatthias Ringwald 	} else {
762*1b2596b5SMatthias Ringwald 		/* Value to be driven on the I/O line: 1. */
763*1b2596b5SMatthias Ringwald 		p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
764*1b2596b5SMatthias Ringwald 	}
765*1b2596b5SMatthias Ringwald }
766*1b2596b5SMatthias Ringwald 
767*1b2596b5SMatthias Ringwald /**
768*1b2596b5SMatthias Ringwald  * \brief Perform complete pin(s) configuration; general attributes and PIO init
769*1b2596b5SMatthias Ringwald  * if necessary.
770*1b2596b5SMatthias Ringwald  *
771*1b2596b5SMatthias Ringwald  * \param ul_pin Bitmask of one or more pin(s) to configure.
772*1b2596b5SMatthias Ringwald  * \param ul_flags Pins attributes.
773*1b2596b5SMatthias Ringwald  *
774*1b2596b5SMatthias Ringwald  * \return Whether the pin(s) have been configured properly.
775*1b2596b5SMatthias Ringwald  */
pio_configure_pin(uint32_t ul_pin,const uint32_t ul_flags)776*1b2596b5SMatthias Ringwald uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags)
777*1b2596b5SMatthias Ringwald {
778*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
779*1b2596b5SMatthias Ringwald 
780*1b2596b5SMatthias Ringwald 	/* Configure pins */
781*1b2596b5SMatthias Ringwald 	switch (ul_flags & PIO_TYPE_Msk) {
782*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_A:
783*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_A, (1 << (ul_pin & 0x1F)));
784*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
785*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_PULLUP));
786*1b2596b5SMatthias Ringwald 		break;
787*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_B:
788*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_B, (1 << (ul_pin & 0x1F)));
789*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
790*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_PULLUP));
791*1b2596b5SMatthias Ringwald 		break;
792*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
793*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_C:
794*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_C, (1 << (ul_pin & 0x1F)));
795*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
796*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_PULLUP));
797*1b2596b5SMatthias Ringwald 		break;
798*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_D:
799*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_D, (1 << (ul_pin & 0x1F)));
800*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
801*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_PULLUP));
802*1b2596b5SMatthias Ringwald 		break;
803*1b2596b5SMatthias Ringwald #endif
804*1b2596b5SMatthias Ringwald 
805*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_INPUT:
806*1b2596b5SMatthias Ringwald 		pio_set_input(p_pio, (1 << (ul_pin & 0x1F)), ul_flags);
807*1b2596b5SMatthias Ringwald 		break;
808*1b2596b5SMatthias Ringwald 
809*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_OUTPUT_0:
810*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_OUTPUT_1:
811*1b2596b5SMatthias Ringwald 		pio_set_output(p_pio, (1 << (ul_pin & 0x1F)),
812*1b2596b5SMatthias Ringwald 				((ul_flags & PIO_TYPE_PIO_OUTPUT_1)
813*1b2596b5SMatthias Ringwald 				== PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0,
814*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_OPENDRAIN) ? 1 : 0,
815*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_PULLUP) ? 1 : 0);
816*1b2596b5SMatthias Ringwald 		break;
817*1b2596b5SMatthias Ringwald 
818*1b2596b5SMatthias Ringwald 	default:
819*1b2596b5SMatthias Ringwald 		return 0;
820*1b2596b5SMatthias Ringwald 	}
821*1b2596b5SMatthias Ringwald 
822*1b2596b5SMatthias Ringwald 	return 1;
823*1b2596b5SMatthias Ringwald }
824*1b2596b5SMatthias Ringwald 
825*1b2596b5SMatthias Ringwald /**
826*1b2596b5SMatthias Ringwald  * \brief Drive a GPIO port to 1.
827*1b2596b5SMatthias Ringwald  *
828*1b2596b5SMatthias Ringwald  * \param p_pio Base address of the PIO port.
829*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to toggle.
830*1b2596b5SMatthias Ringwald  */
pio_set_pin_group_high(Pio * p_pio,uint32_t ul_mask)831*1b2596b5SMatthias Ringwald void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask)
832*1b2596b5SMatthias Ringwald {
833*1b2596b5SMatthias Ringwald 	/* Value to be driven on the I/O line: 1. */
834*1b2596b5SMatthias Ringwald 	p_pio->PIO_SODR = ul_mask;
835*1b2596b5SMatthias Ringwald }
836*1b2596b5SMatthias Ringwald 
837*1b2596b5SMatthias Ringwald /**
838*1b2596b5SMatthias Ringwald  * \brief Drive a GPIO port to 0.
839*1b2596b5SMatthias Ringwald  *
840*1b2596b5SMatthias Ringwald  * \param p_pio Base address of the PIO port.
841*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to toggle.
842*1b2596b5SMatthias Ringwald  */
pio_set_pin_group_low(Pio * p_pio,uint32_t ul_mask)843*1b2596b5SMatthias Ringwald void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask)
844*1b2596b5SMatthias Ringwald {
845*1b2596b5SMatthias Ringwald 	/* Value to be driven on the I/O line: 0. */
846*1b2596b5SMatthias Ringwald 	p_pio->PIO_CODR = ul_mask;
847*1b2596b5SMatthias Ringwald }
848*1b2596b5SMatthias Ringwald 
849*1b2596b5SMatthias Ringwald /**
850*1b2596b5SMatthias Ringwald  * \brief Toggle a GPIO group.
851*1b2596b5SMatthias Ringwald  *
852*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
853*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
854*1b2596b5SMatthias Ringwald  */
pio_toggle_pin_group(Pio * p_pio,uint32_t ul_mask)855*1b2596b5SMatthias Ringwald void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask)
856*1b2596b5SMatthias Ringwald {
857*1b2596b5SMatthias Ringwald 	if (p_pio->PIO_ODSR & ul_mask) {
858*1b2596b5SMatthias Ringwald 		/* Value to be driven on the I/O line: 0. */
859*1b2596b5SMatthias Ringwald 		p_pio->PIO_CODR = ul_mask;
860*1b2596b5SMatthias Ringwald 	} else {
861*1b2596b5SMatthias Ringwald 		/* Value to be driven on the I/O line: 1. */
862*1b2596b5SMatthias Ringwald 		p_pio->PIO_SODR = ul_mask;
863*1b2596b5SMatthias Ringwald 	}
864*1b2596b5SMatthias Ringwald }
865*1b2596b5SMatthias Ringwald 
866*1b2596b5SMatthias Ringwald /**
867*1b2596b5SMatthias Ringwald  * \brief Perform complete pin(s) configuration; general attributes and PIO init
868*1b2596b5SMatthias Ringwald  * if necessary.
869*1b2596b5SMatthias Ringwald  *
870*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
871*1b2596b5SMatthias Ringwald  * \param ul_mask Bitmask of one or more pin(s) to configure.
872*1b2596b5SMatthias Ringwald  * \param ul_flags Pin(s) attributes.
873*1b2596b5SMatthias Ringwald  *
874*1b2596b5SMatthias Ringwald  * \return Whether the pin(s) have been configured properly.
875*1b2596b5SMatthias Ringwald  */
pio_configure_pin_group(Pio * p_pio,uint32_t ul_mask,const uint32_t ul_flags)876*1b2596b5SMatthias Ringwald uint32_t pio_configure_pin_group(Pio *p_pio,
877*1b2596b5SMatthias Ringwald 		uint32_t ul_mask, const uint32_t ul_flags)
878*1b2596b5SMatthias Ringwald {
879*1b2596b5SMatthias Ringwald 	/* Configure pins */
880*1b2596b5SMatthias Ringwald 	switch (ul_flags & PIO_TYPE_Msk) {
881*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_A:
882*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_A, ul_mask);
883*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
884*1b2596b5SMatthias Ringwald 		break;
885*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_B:
886*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_B, ul_mask);
887*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
888*1b2596b5SMatthias Ringwald 		break;
889*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
890*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_C:
891*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_C, ul_mask);
892*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
893*1b2596b5SMatthias Ringwald 		break;
894*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_PERIPH_D:
895*1b2596b5SMatthias Ringwald 		pio_set_peripheral(p_pio, PIO_PERIPH_D, ul_mask);
896*1b2596b5SMatthias Ringwald 		pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
897*1b2596b5SMatthias Ringwald 		break;
898*1b2596b5SMatthias Ringwald #endif
899*1b2596b5SMatthias Ringwald 
900*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_INPUT:
901*1b2596b5SMatthias Ringwald 		pio_set_input(p_pio, ul_mask, ul_flags);
902*1b2596b5SMatthias Ringwald 		break;
903*1b2596b5SMatthias Ringwald 
904*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_OUTPUT_0:
905*1b2596b5SMatthias Ringwald 	case PIO_TYPE_PIO_OUTPUT_1:
906*1b2596b5SMatthias Ringwald 		pio_set_output(p_pio, ul_mask,
907*1b2596b5SMatthias Ringwald 				((ul_flags & PIO_TYPE_PIO_OUTPUT_1)
908*1b2596b5SMatthias Ringwald 				== PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0,
909*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_OPENDRAIN) ? 1 : 0,
910*1b2596b5SMatthias Ringwald 				(ul_flags & PIO_PULLUP) ? 1 : 0);
911*1b2596b5SMatthias Ringwald 		break;
912*1b2596b5SMatthias Ringwald 
913*1b2596b5SMatthias Ringwald 	default:
914*1b2596b5SMatthias Ringwald 		return 0;
915*1b2596b5SMatthias Ringwald 	}
916*1b2596b5SMatthias Ringwald 
917*1b2596b5SMatthias Ringwald 	return 1;
918*1b2596b5SMatthias Ringwald }
919*1b2596b5SMatthias Ringwald 
920*1b2596b5SMatthias Ringwald /**
921*1b2596b5SMatthias Ringwald  * \brief Enable interrupt for a GPIO pin.
922*1b2596b5SMatthias Ringwald  *
923*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
924*1b2596b5SMatthias Ringwald  *
925*1b2596b5SMatthias Ringwald  * \note The function \ref gpio_configure_pin must be called before.
926*1b2596b5SMatthias Ringwald  */
pio_enable_pin_interrupt(uint32_t ul_pin)927*1b2596b5SMatthias Ringwald void pio_enable_pin_interrupt(uint32_t ul_pin)
928*1b2596b5SMatthias Ringwald {
929*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
930*1b2596b5SMatthias Ringwald 
931*1b2596b5SMatthias Ringwald 	p_pio->PIO_IER = 1 << (ul_pin & 0x1F);
932*1b2596b5SMatthias Ringwald }
933*1b2596b5SMatthias Ringwald 
934*1b2596b5SMatthias Ringwald 
935*1b2596b5SMatthias Ringwald /**
936*1b2596b5SMatthias Ringwald  * \brief Disable interrupt for a GPIO pin.
937*1b2596b5SMatthias Ringwald  *
938*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
939*1b2596b5SMatthias Ringwald  *
940*1b2596b5SMatthias Ringwald  * \note The function \ref gpio_configure_pin must be called before.
941*1b2596b5SMatthias Ringwald  */
pio_disable_pin_interrupt(uint32_t ul_pin)942*1b2596b5SMatthias Ringwald void pio_disable_pin_interrupt(uint32_t ul_pin)
943*1b2596b5SMatthias Ringwald {
944*1b2596b5SMatthias Ringwald 	Pio *p_pio = pio_get_pin_group(ul_pin);
945*1b2596b5SMatthias Ringwald 
946*1b2596b5SMatthias Ringwald 	p_pio->PIO_IDR = 1 << (ul_pin & 0x1F);
947*1b2596b5SMatthias Ringwald }
948*1b2596b5SMatthias Ringwald 
949*1b2596b5SMatthias Ringwald 
950*1b2596b5SMatthias Ringwald /**
951*1b2596b5SMatthias Ringwald  * \brief Return GPIO port for a GPIO pin.
952*1b2596b5SMatthias Ringwald  *
953*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
954*1b2596b5SMatthias Ringwald  *
955*1b2596b5SMatthias Ringwald  * \return Pointer to \ref Pio struct for GPIO port.
956*1b2596b5SMatthias Ringwald  */
pio_get_pin_group(uint32_t ul_pin)957*1b2596b5SMatthias Ringwald Pio *pio_get_pin_group(uint32_t ul_pin)
958*1b2596b5SMatthias Ringwald {
959*1b2596b5SMatthias Ringwald 	Pio *p_pio;
960*1b2596b5SMatthias Ringwald 
961*1b2596b5SMatthias Ringwald #if (SAM4C || SAM4CP)
962*1b2596b5SMatthias Ringwald #  ifdef ID_PIOD
963*1b2596b5SMatthias Ringwald 	if (ul_pin > PIO_PC9_IDX) {
964*1b2596b5SMatthias Ringwald 		p_pio = PIOD;
965*1b2596b5SMatthias Ringwald 	} else if (ul_pin > PIO_PB31_IDX) {
966*1b2596b5SMatthias Ringwald #  else
967*1b2596b5SMatthias Ringwald 	if  (ul_pin > PIO_PB31_IDX) {
968*1b2596b5SMatthias Ringwald #  endif
969*1b2596b5SMatthias Ringwald 		p_pio = PIOC;
970*1b2596b5SMatthias Ringwald 	} else {
971*1b2596b5SMatthias Ringwald 		p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
972*1b2596b5SMatthias Ringwald 	}
973*1b2596b5SMatthias Ringwald #elif (SAM4CM)
974*1b2596b5SMatthias Ringwald 	if (ul_pin > PIO_PB21_IDX) {
975*1b2596b5SMatthias Ringwald 		p_pio = PIOC;
976*1b2596b5SMatthias Ringwald 	} else {
977*1b2596b5SMatthias Ringwald 		p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
978*1b2596b5SMatthias Ringwald 	}
979*1b2596b5SMatthias Ringwald #else
980*1b2596b5SMatthias Ringwald 	p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
981*1b2596b5SMatthias Ringwald #endif
982*1b2596b5SMatthias Ringwald 	return p_pio;
983*1b2596b5SMatthias Ringwald }
984*1b2596b5SMatthias Ringwald 
985*1b2596b5SMatthias Ringwald /**
986*1b2596b5SMatthias Ringwald  * \brief Return GPIO port peripheral ID for a GPIO pin.
987*1b2596b5SMatthias Ringwald  *
988*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
989*1b2596b5SMatthias Ringwald  *
990*1b2596b5SMatthias Ringwald  * \return GPIO port peripheral ID.
991*1b2596b5SMatthias Ringwald  */
992*1b2596b5SMatthias Ringwald uint32_t pio_get_pin_group_id(uint32_t ul_pin)
993*1b2596b5SMatthias Ringwald {
994*1b2596b5SMatthias Ringwald 	uint32_t ul_id;
995*1b2596b5SMatthias Ringwald 
996*1b2596b5SMatthias Ringwald #if (SAM4C || SAM4CP)
997*1b2596b5SMatthias Ringwald #  ifdef ID_PIOD
998*1b2596b5SMatthias Ringwald 	if (ul_pin > PIO_PC9_IDX) {
999*1b2596b5SMatthias Ringwald 		ul_id = ID_PIOD;
1000*1b2596b5SMatthias Ringwald 	} else if (ul_pin > PIO_PB31_IDX) {
1001*1b2596b5SMatthias Ringwald #  else
1002*1b2596b5SMatthias Ringwald 	if (ul_pin > PIO_PB31_IDX) {
1003*1b2596b5SMatthias Ringwald #  endif
1004*1b2596b5SMatthias Ringwald 		ul_id = ID_PIOC;
1005*1b2596b5SMatthias Ringwald 	} else {
1006*1b2596b5SMatthias Ringwald 		ul_id = ID_PIOA + (ul_pin >> 5);
1007*1b2596b5SMatthias Ringwald 	}
1008*1b2596b5SMatthias Ringwald #elif (SAM4CM)
1009*1b2596b5SMatthias Ringwald 	if (ul_pin > PIO_PB21_IDX) {
1010*1b2596b5SMatthias Ringwald 		ul_id = ID_PIOC;
1011*1b2596b5SMatthias Ringwald 	} else {
1012*1b2596b5SMatthias Ringwald 		ul_id = ID_PIOA + (ul_pin >> 5);
1013*1b2596b5SMatthias Ringwald 	}
1014*1b2596b5SMatthias Ringwald #else
1015*1b2596b5SMatthias Ringwald 	ul_id = ID_PIOA + (ul_pin >> 5);
1016*1b2596b5SMatthias Ringwald #endif
1017*1b2596b5SMatthias Ringwald 	return ul_id;
1018*1b2596b5SMatthias Ringwald }
1019*1b2596b5SMatthias Ringwald 
1020*1b2596b5SMatthias Ringwald 
1021*1b2596b5SMatthias Ringwald /**
1022*1b2596b5SMatthias Ringwald  * \brief Return GPIO port pin mask for a GPIO pin.
1023*1b2596b5SMatthias Ringwald  *
1024*1b2596b5SMatthias Ringwald  * \param ul_pin The pin index.
1025*1b2596b5SMatthias Ringwald  *
1026*1b2596b5SMatthias Ringwald  * \return GPIO port pin mask.
1027*1b2596b5SMatthias Ringwald  */
1028*1b2596b5SMatthias Ringwald uint32_t pio_get_pin_group_mask(uint32_t ul_pin)
1029*1b2596b5SMatthias Ringwald {
1030*1b2596b5SMatthias Ringwald 	uint32_t ul_mask = 1 << (ul_pin & 0x1F);
1031*1b2596b5SMatthias Ringwald 	return ul_mask;
1032*1b2596b5SMatthias Ringwald }
1033*1b2596b5SMatthias Ringwald 
1034*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM4E || SAMV71 || SAMV70 || SAME70 || SAMS70)
1035*1b2596b5SMatthias Ringwald /* Capture mode enable flag */
1036*1b2596b5SMatthias Ringwald uint32_t pio_capture_enable_flag;
1037*1b2596b5SMatthias Ringwald 
1038*1b2596b5SMatthias Ringwald /**
1039*1b2596b5SMatthias Ringwald  * \brief Configure PIO capture mode.
1040*1b2596b5SMatthias Ringwald  * \note PIO capture mode will be disabled automatically.
1041*1b2596b5SMatthias Ringwald  *
1042*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1043*1b2596b5SMatthias Ringwald  * \param ul_mode Bitmask of one or more modes.
1044*1b2596b5SMatthias Ringwald  */
1045*1b2596b5SMatthias Ringwald void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode)
1046*1b2596b5SMatthias Ringwald {
1047*1b2596b5SMatthias Ringwald 	ul_mode &= (~PIO_PCMR_PCEN); /* Disable PIO capture mode */
1048*1b2596b5SMatthias Ringwald 	p_pio->PIO_PCMR = ul_mode;
1049*1b2596b5SMatthias Ringwald }
1050*1b2596b5SMatthias Ringwald 
1051*1b2596b5SMatthias Ringwald /**
1052*1b2596b5SMatthias Ringwald  * \brief Enable PIO capture mode.
1053*1b2596b5SMatthias Ringwald  *
1054*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1055*1b2596b5SMatthias Ringwald  */
1056*1b2596b5SMatthias Ringwald void pio_capture_enable(Pio *p_pio)
1057*1b2596b5SMatthias Ringwald {
1058*1b2596b5SMatthias Ringwald 	p_pio->PIO_PCMR |= PIO_PCMR_PCEN;
1059*1b2596b5SMatthias Ringwald 	pio_capture_enable_flag = true;
1060*1b2596b5SMatthias Ringwald }
1061*1b2596b5SMatthias Ringwald 
1062*1b2596b5SMatthias Ringwald /**
1063*1b2596b5SMatthias Ringwald  * \brief Disable PIO capture mode.
1064*1b2596b5SMatthias Ringwald  *
1065*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1066*1b2596b5SMatthias Ringwald  */
1067*1b2596b5SMatthias Ringwald void pio_capture_disable(Pio *p_pio)
1068*1b2596b5SMatthias Ringwald {
1069*1b2596b5SMatthias Ringwald 	p_pio->PIO_PCMR &= (~PIO_PCMR_PCEN);
1070*1b2596b5SMatthias Ringwald 	pio_capture_enable_flag = false;
1071*1b2596b5SMatthias Ringwald }
1072*1b2596b5SMatthias Ringwald 
1073*1b2596b5SMatthias Ringwald /**
1074*1b2596b5SMatthias Ringwald  * \brief Read from Capture Reception Holding Register.
1075*1b2596b5SMatthias Ringwald  * \note Data presence should be tested before any read attempt.
1076*1b2596b5SMatthias Ringwald  *
1077*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1078*1b2596b5SMatthias Ringwald  * \param pul_data Pointer to store the data.
1079*1b2596b5SMatthias Ringwald  *
1080*1b2596b5SMatthias Ringwald  * \retval 0 Success.
1081*1b2596b5SMatthias Ringwald  * \retval 1 I/O Failure, Capture data is not ready.
1082*1b2596b5SMatthias Ringwald  */
1083*1b2596b5SMatthias Ringwald uint32_t pio_capture_read(const Pio *p_pio, uint32_t *pul_data)
1084*1b2596b5SMatthias Ringwald {
1085*1b2596b5SMatthias Ringwald 	/* Check if the data is ready */
1086*1b2596b5SMatthias Ringwald 	if ((p_pio->PIO_PCISR & PIO_PCISR_DRDY) == 0) {
1087*1b2596b5SMatthias Ringwald 		return 1;
1088*1b2596b5SMatthias Ringwald 	}
1089*1b2596b5SMatthias Ringwald 
1090*1b2596b5SMatthias Ringwald 	/* Read data */
1091*1b2596b5SMatthias Ringwald 	*pul_data = p_pio->PIO_PCRHR;
1092*1b2596b5SMatthias Ringwald 	return 0;
1093*1b2596b5SMatthias Ringwald }
1094*1b2596b5SMatthias Ringwald 
1095*1b2596b5SMatthias Ringwald /**
1096*1b2596b5SMatthias Ringwald  * \brief Enable the given interrupt source of PIO capture. The status
1097*1b2596b5SMatthias Ringwald  * register of the corresponding PIO capture controller is cleared prior
1098*1b2596b5SMatthias Ringwald  * to enabling the interrupt.
1099*1b2596b5SMatthias Ringwald  *
1100*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1101*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
1102*1b2596b5SMatthias Ringwald  */
1103*1b2596b5SMatthias Ringwald void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
1104*1b2596b5SMatthias Ringwald {
1105*1b2596b5SMatthias Ringwald 	p_pio->PIO_PCISR;
1106*1b2596b5SMatthias Ringwald 	p_pio->PIO_PCIER = ul_mask;
1107*1b2596b5SMatthias Ringwald }
1108*1b2596b5SMatthias Ringwald 
1109*1b2596b5SMatthias Ringwald /**
1110*1b2596b5SMatthias Ringwald  * \brief Disable a given interrupt source of PIO capture.
1111*1b2596b5SMatthias Ringwald  *
1112*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1113*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
1114*1b2596b5SMatthias Ringwald  */
1115*1b2596b5SMatthias Ringwald void pio_capture_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
1116*1b2596b5SMatthias Ringwald {
1117*1b2596b5SMatthias Ringwald 	p_pio->PIO_PCIDR = ul_mask;
1118*1b2596b5SMatthias Ringwald }
1119*1b2596b5SMatthias Ringwald 
1120*1b2596b5SMatthias Ringwald /**
1121*1b2596b5SMatthias Ringwald  * \brief Read PIO interrupt status of PIO capture.
1122*1b2596b5SMatthias Ringwald  *
1123*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1124*1b2596b5SMatthias Ringwald  *
1125*1b2596b5SMatthias Ringwald  * \return The interrupt status mask value.
1126*1b2596b5SMatthias Ringwald  */
1127*1b2596b5SMatthias Ringwald uint32_t pio_capture_get_interrupt_status(const Pio *p_pio)
1128*1b2596b5SMatthias Ringwald {
1129*1b2596b5SMatthias Ringwald 	return p_pio->PIO_PCISR;
1130*1b2596b5SMatthias Ringwald }
1131*1b2596b5SMatthias Ringwald 
1132*1b2596b5SMatthias Ringwald /**
1133*1b2596b5SMatthias Ringwald  * \brief Read PIO interrupt mask of PIO capture.
1134*1b2596b5SMatthias Ringwald  *
1135*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1136*1b2596b5SMatthias Ringwald  *
1137*1b2596b5SMatthias Ringwald  * \return The interrupt mask value.
1138*1b2596b5SMatthias Ringwald  */
1139*1b2596b5SMatthias Ringwald uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio)
1140*1b2596b5SMatthias Ringwald {
1141*1b2596b5SMatthias Ringwald 	return p_pio->PIO_PCIMR;
1142*1b2596b5SMatthias Ringwald }
1143*1b2596b5SMatthias Ringwald #if !(SAMV71 || SAMV70 || SAME70 || SAMS70)
1144*1b2596b5SMatthias Ringwald /**
1145*1b2596b5SMatthias Ringwald  * \brief Get PDC registers base address.
1146*1b2596b5SMatthias Ringwald  *
1147*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to an PIO peripheral.
1148*1b2596b5SMatthias Ringwald  *
1149*1b2596b5SMatthias Ringwald  * \return PIOA PDC register base address.
1150*1b2596b5SMatthias Ringwald  */
1151*1b2596b5SMatthias Ringwald Pdc *pio_capture_get_pdc_base(const Pio *p_pio)
1152*1b2596b5SMatthias Ringwald {
1153*1b2596b5SMatthias Ringwald 	UNUSED(p_pio); /* Stop warning */
1154*1b2596b5SMatthias Ringwald 	return PDC_PIOA;
1155*1b2596b5SMatthias Ringwald }
1156*1b2596b5SMatthias Ringwald #endif
1157*1b2596b5SMatthias Ringwald #endif
1158*1b2596b5SMatthias Ringwald 
1159*1b2596b5SMatthias Ringwald #if (SAM4C || SAM4CP || SAM4CM || SAMG55)
1160*1b2596b5SMatthias Ringwald /**
1161*1b2596b5SMatthias Ringwald  * \brief Set PIO IO drive.
1162*1b2596b5SMatthias Ringwald  *
1163*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to an PIO peripheral.
1164*1b2596b5SMatthias Ringwald  * \param ul_line Line index (0..31).
1165*1b2596b5SMatthias Ringwald  * \param mode IO drive mode.
1166*1b2596b5SMatthias Ringwald  */
1167*1b2596b5SMatthias Ringwald void pio_set_io_drive(Pio *p_pio, uint32_t ul_line,
1168*1b2596b5SMatthias Ringwald 		enum pio_io_drive_mode mode)
1169*1b2596b5SMatthias Ringwald {
1170*1b2596b5SMatthias Ringwald 	p_pio->PIO_DRIVER &= ~(1 << ul_line);
1171*1b2596b5SMatthias Ringwald 	p_pio->PIO_DRIVER |= mode << ul_line;
1172*1b2596b5SMatthias Ringwald }
1173*1b2596b5SMatthias Ringwald #endif
1174*1b2596b5SMatthias Ringwald 
1175*1b2596b5SMatthias Ringwald #if (SAMV71 || SAMV70 || SAME70 || SAMS70)
1176*1b2596b5SMatthias Ringwald /**
1177*1b2596b5SMatthias Ringwald  * \brief Enable PIO keypad controller.
1178*1b2596b5SMatthias Ringwald  *
1179*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1180*1b2596b5SMatthias Ringwald  */
1181*1b2596b5SMatthias Ringwald void pio_keypad_enable(Pio *p_pio)
1182*1b2596b5SMatthias Ringwald {
1183*1b2596b5SMatthias Ringwald 	p_pio->PIO_KER |= PIO_KER_KCE;
1184*1b2596b5SMatthias Ringwald }
1185*1b2596b5SMatthias Ringwald 
1186*1b2596b5SMatthias Ringwald /**
1187*1b2596b5SMatthias Ringwald  * \brief Disable PIO keypad controller.
1188*1b2596b5SMatthias Ringwald  *
1189*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1190*1b2596b5SMatthias Ringwald  */
1191*1b2596b5SMatthias Ringwald void pio_keypad_disable(Pio *p_pio)
1192*1b2596b5SMatthias Ringwald {
1193*1b2596b5SMatthias Ringwald 	p_pio->PIO_KER &= (~PIO_KER_KCE);
1194*1b2596b5SMatthias Ringwald }
1195*1b2596b5SMatthias Ringwald 
1196*1b2596b5SMatthias Ringwald /**
1197*1b2596b5SMatthias Ringwald  * \brief Set PIO keypad controller row number.
1198*1b2596b5SMatthias Ringwald  *
1199*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1200*1b2596b5SMatthias Ringwald  * \param num   Number of row of the keypad matrix.
1201*1b2596b5SMatthias Ringwald  */
1202*1b2596b5SMatthias Ringwald void pio_keypad_set_row_num(Pio *p_pio, uint8_t num)
1203*1b2596b5SMatthias Ringwald {
1204*1b2596b5SMatthias Ringwald 	p_pio->PIO_KRCR &= (~PIO_KRCR_NBR_Msk);
1205*1b2596b5SMatthias Ringwald 	p_pio->PIO_KRCR |= PIO_KRCR_NBR(num);
1206*1b2596b5SMatthias Ringwald }
1207*1b2596b5SMatthias Ringwald 
1208*1b2596b5SMatthias Ringwald /**
1209*1b2596b5SMatthias Ringwald  * \brief Get PIO keypad controller row number.
1210*1b2596b5SMatthias Ringwald  *
1211*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1212*1b2596b5SMatthias Ringwald  *
1213*1b2596b5SMatthias Ringwald  * \return Number of row of the keypad matrix.
1214*1b2596b5SMatthias Ringwald  */
1215*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_row_num(const Pio *p_pio)
1216*1b2596b5SMatthias Ringwald {
1217*1b2596b5SMatthias Ringwald 	return ((p_pio->PIO_KRCR & PIO_KRCR_NBR_Msk) >> PIO_KRCR_NBR_Pos);
1218*1b2596b5SMatthias Ringwald }
1219*1b2596b5SMatthias Ringwald 
1220*1b2596b5SMatthias Ringwald /**
1221*1b2596b5SMatthias Ringwald  * \brief Set PIO keypad controller column number.
1222*1b2596b5SMatthias Ringwald  *
1223*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1224*1b2596b5SMatthias Ringwald  * \param num   Number of column of the keypad matrix.
1225*1b2596b5SMatthias Ringwald  */
1226*1b2596b5SMatthias Ringwald void pio_keypad_set_column_num(Pio *p_pio, uint8_t num)
1227*1b2596b5SMatthias Ringwald {
1228*1b2596b5SMatthias Ringwald 	p_pio->PIO_KRCR &= (~PIO_KRCR_NBC_Msk);
1229*1b2596b5SMatthias Ringwald 	p_pio->PIO_KRCR |= PIO_KRCR_NBC(num);
1230*1b2596b5SMatthias Ringwald }
1231*1b2596b5SMatthias Ringwald 
1232*1b2596b5SMatthias Ringwald /**
1233*1b2596b5SMatthias Ringwald  * \brief Get PIO keypad controller column number.
1234*1b2596b5SMatthias Ringwald  *
1235*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1236*1b2596b5SMatthias Ringwald  *
1237*1b2596b5SMatthias Ringwald  * \return Number of column of the keypad matrix.
1238*1b2596b5SMatthias Ringwald  */
1239*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_column_num(const Pio *p_pio)
1240*1b2596b5SMatthias Ringwald {
1241*1b2596b5SMatthias Ringwald 	return ((p_pio->PIO_KRCR & PIO_KRCR_NBC_Msk) >> PIO_KRCR_NBC_Pos);
1242*1b2596b5SMatthias Ringwald }
1243*1b2596b5SMatthias Ringwald 
1244*1b2596b5SMatthias Ringwald /**
1245*1b2596b5SMatthias Ringwald  * \brief Set PIO keypad matrix debouncing value.
1246*1b2596b5SMatthias Ringwald  *
1247*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1248*1b2596b5SMatthias Ringwald  * \param num   Number of debouncing value.
1249*1b2596b5SMatthias Ringwald  */
1250*1b2596b5SMatthias Ringwald void pio_keypad_set_debouncing_value(Pio *p_pio, uint16_t value)
1251*1b2596b5SMatthias Ringwald {
1252*1b2596b5SMatthias Ringwald 	p_pio->PIO_KDR = PIO_KDR_DBC(value);
1253*1b2596b5SMatthias Ringwald }
1254*1b2596b5SMatthias Ringwald 
1255*1b2596b5SMatthias Ringwald /**
1256*1b2596b5SMatthias Ringwald  * \brief Get PIO keypad matrix debouncing value.
1257*1b2596b5SMatthias Ringwald  *
1258*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1259*1b2596b5SMatthias Ringwald  *
1260*1b2596b5SMatthias Ringwald  * \return The keypad debouncing value.
1261*1b2596b5SMatthias Ringwald  */
1262*1b2596b5SMatthias Ringwald uint16_t pio_keypad_get_debouncing_value(const Pio *p_pio)
1263*1b2596b5SMatthias Ringwald {
1264*1b2596b5SMatthias Ringwald 	return ((p_pio->PIO_KDR & PIO_KDR_DBC_Msk) >> PIO_KDR_DBC_Pos);
1265*1b2596b5SMatthias Ringwald }
1266*1b2596b5SMatthias Ringwald 
1267*1b2596b5SMatthias Ringwald /**
1268*1b2596b5SMatthias Ringwald  * \brief Enable the interrupt source of PIO keypad.
1269*1b2596b5SMatthias Ringwald  *
1270*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1271*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
1272*1b2596b5SMatthias Ringwald  */
1273*1b2596b5SMatthias Ringwald void pio_keypad_enable_interrupt(Pio *p_pio, uint32_t ul_mask)
1274*1b2596b5SMatthias Ringwald {
1275*1b2596b5SMatthias Ringwald 	p_pio->PIO_KIER = ul_mask;
1276*1b2596b5SMatthias Ringwald }
1277*1b2596b5SMatthias Ringwald 
1278*1b2596b5SMatthias Ringwald /**
1279*1b2596b5SMatthias Ringwald  * \brief Disable the interrupt source of PIO keypad.
1280*1b2596b5SMatthias Ringwald  *
1281*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1282*1b2596b5SMatthias Ringwald  * \param ul_mask Interrupt sources bit map.
1283*1b2596b5SMatthias Ringwald  */
1284*1b2596b5SMatthias Ringwald void pio_keypad_disable_interrupt(Pio *p_pio, uint32_t ul_mask)
1285*1b2596b5SMatthias Ringwald {
1286*1b2596b5SMatthias Ringwald 	p_pio->PIO_KIDR = ul_mask;
1287*1b2596b5SMatthias Ringwald }
1288*1b2596b5SMatthias Ringwald 
1289*1b2596b5SMatthias Ringwald /**
1290*1b2596b5SMatthias Ringwald  * \brief Get interrupt mask of PIO keypad.
1291*1b2596b5SMatthias Ringwald  *
1292*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1293*1b2596b5SMatthias Ringwald  *
1294*1b2596b5SMatthias Ringwald  * \return The interrupt mask value.
1295*1b2596b5SMatthias Ringwald  */
1296*1b2596b5SMatthias Ringwald uint32_t pio_keypad_get_interrupt_mask(const Pio *p_pio)
1297*1b2596b5SMatthias Ringwald {
1298*1b2596b5SMatthias Ringwald 	return p_pio->PIO_KIMR;
1299*1b2596b5SMatthias Ringwald }
1300*1b2596b5SMatthias Ringwald 
1301*1b2596b5SMatthias Ringwald /**
1302*1b2596b5SMatthias Ringwald  * \brief Get key press status of PIO keypad.
1303*1b2596b5SMatthias Ringwald  *
1304*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1305*1b2596b5SMatthias Ringwald  *
1306*1b2596b5SMatthias Ringwald  * \return The status of key press.
1307*1b2596b5SMatthias Ringwald  * 0: No key press has been detected.
1308*1b2596b5SMatthias Ringwald  * 1: At least one key press has been detected.
1309*1b2596b5SMatthias Ringwald  */
1310*1b2596b5SMatthias Ringwald uint32_t pio_keypad_get_press_status(const Pio *p_pio)
1311*1b2596b5SMatthias Ringwald {
1312*1b2596b5SMatthias Ringwald 	if (p_pio->PIO_KSR & PIO_KSR_KPR) {
1313*1b2596b5SMatthias Ringwald 		return 1;
1314*1b2596b5SMatthias Ringwald 	} else {
1315*1b2596b5SMatthias Ringwald 		return 0;
1316*1b2596b5SMatthias Ringwald 	}
1317*1b2596b5SMatthias Ringwald }
1318*1b2596b5SMatthias Ringwald 
1319*1b2596b5SMatthias Ringwald /**
1320*1b2596b5SMatthias Ringwald  * \brief Get key release status of PIO keypad.
1321*1b2596b5SMatthias Ringwald  *
1322*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1323*1b2596b5SMatthias Ringwald  *
1324*1b2596b5SMatthias Ringwald  * \return The status of key release.
1325*1b2596b5SMatthias Ringwald  * 0 No key release has been detected.
1326*1b2596b5SMatthias Ringwald  * 1 At least one key release has been detected.
1327*1b2596b5SMatthias Ringwald  */
1328*1b2596b5SMatthias Ringwald uint32_t pio_keypad_get_release_status(const Pio *p_pio)
1329*1b2596b5SMatthias Ringwald {
1330*1b2596b5SMatthias Ringwald 	if (p_pio->PIO_KSR & PIO_KSR_KRL) {
1331*1b2596b5SMatthias Ringwald 		return 1;
1332*1b2596b5SMatthias Ringwald 	} else {
1333*1b2596b5SMatthias Ringwald 		return 0;
1334*1b2596b5SMatthias Ringwald 	}
1335*1b2596b5SMatthias Ringwald }
1336*1b2596b5SMatthias Ringwald 
1337*1b2596b5SMatthias Ringwald /**
1338*1b2596b5SMatthias Ringwald  * \brief Get simultaneous key press number of PIO keypad.
1339*1b2596b5SMatthias Ringwald  *
1340*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1341*1b2596b5SMatthias Ringwald  *
1342*1b2596b5SMatthias Ringwald  * \return The number of simultaneous key press.
1343*1b2596b5SMatthias Ringwald  */
1344*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_simult_press_num(const Pio *p_pio)
1345*1b2596b5SMatthias Ringwald {
1346*1b2596b5SMatthias Ringwald 	return ((p_pio->PIO_KSR & PIO_KSR_NBKPR_Msk) >> PIO_KSR_NBKPR_Pos);
1347*1b2596b5SMatthias Ringwald }
1348*1b2596b5SMatthias Ringwald 
1349*1b2596b5SMatthias Ringwald /**
1350*1b2596b5SMatthias Ringwald  * \brief Get simultaneous key release number of PIO keypad.
1351*1b2596b5SMatthias Ringwald  *
1352*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1353*1b2596b5SMatthias Ringwald  *
1354*1b2596b5SMatthias Ringwald  * \return The number of simultaneous key release.
1355*1b2596b5SMatthias Ringwald  */
1356*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_simult_release_num(const Pio *p_pio)
1357*1b2596b5SMatthias Ringwald {
1358*1b2596b5SMatthias Ringwald 	return ((p_pio->PIO_KSR & PIO_KSR_NBKRL_Msk) >> PIO_KSR_NBKRL_Pos);
1359*1b2596b5SMatthias Ringwald }
1360*1b2596b5SMatthias Ringwald 
1361*1b2596b5SMatthias Ringwald /**
1362*1b2596b5SMatthias Ringwald  * \brief Get detected key press row index of PIO keypad.
1363*1b2596b5SMatthias Ringwald  *
1364*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1365*1b2596b5SMatthias Ringwald  * \param queue The queue of key press row
1366*1b2596b5SMatthias Ringwald  *
1367*1b2596b5SMatthias Ringwald  * \return The index of detected key press row.
1368*1b2596b5SMatthias Ringwald  */
1369*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_press_row_index(const Pio *p_pio, uint8_t queue)
1370*1b2596b5SMatthias Ringwald {
1371*1b2596b5SMatthias Ringwald 	switch (queue) {
1372*1b2596b5SMatthias Ringwald 	case 0:
1373*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0ROW_Msk) >> PIO_KKPR_KEY0ROW_Pos);
1374*1b2596b5SMatthias Ringwald 	case 1:
1375*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1ROW_Msk) >> PIO_KKPR_KEY1ROW_Pos);
1376*1b2596b5SMatthias Ringwald 	case 2:
1377*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2ROW_Msk) >> PIO_KKPR_KEY2ROW_Pos);
1378*1b2596b5SMatthias Ringwald 	case 3:
1379*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3ROW_Msk) >> PIO_KKPR_KEY3ROW_Pos);
1380*1b2596b5SMatthias Ringwald 	default:
1381*1b2596b5SMatthias Ringwald 		return 0;
1382*1b2596b5SMatthias Ringwald 	}
1383*1b2596b5SMatthias Ringwald }
1384*1b2596b5SMatthias Ringwald 
1385*1b2596b5SMatthias Ringwald /**
1386*1b2596b5SMatthias Ringwald  * \brief Get detected key press column index of PIO keypad.
1387*1b2596b5SMatthias Ringwald  *
1388*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1389*1b2596b5SMatthias Ringwald  * \param queue The queue of key press column
1390*1b2596b5SMatthias Ringwald  *
1391*1b2596b5SMatthias Ringwald  * \return The index of detected key press column.
1392*1b2596b5SMatthias Ringwald  */
1393*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_press_column_index(const Pio *p_pio, uint8_t queue)
1394*1b2596b5SMatthias Ringwald {
1395*1b2596b5SMatthias Ringwald 	switch (queue) {
1396*1b2596b5SMatthias Ringwald 	case 0:
1397*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0COL_Msk) >> PIO_KKPR_KEY0COL_Pos);
1398*1b2596b5SMatthias Ringwald 	case 1:
1399*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1COL_Msk) >> PIO_KKPR_KEY1COL_Pos);
1400*1b2596b5SMatthias Ringwald 	case 2:
1401*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2COL_Msk) >> PIO_KKPR_KEY2COL_Pos);
1402*1b2596b5SMatthias Ringwald 	case 3:
1403*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3COL_Msk) >> PIO_KKPR_KEY3COL_Pos);
1404*1b2596b5SMatthias Ringwald 	default:
1405*1b2596b5SMatthias Ringwald 		return 0;
1406*1b2596b5SMatthias Ringwald 	}
1407*1b2596b5SMatthias Ringwald }
1408*1b2596b5SMatthias Ringwald 
1409*1b2596b5SMatthias Ringwald /**
1410*1b2596b5SMatthias Ringwald  * \brief Get detected key release row index of PIO keypad.
1411*1b2596b5SMatthias Ringwald  *
1412*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1413*1b2596b5SMatthias Ringwald  * \param queue The queue of key release row
1414*1b2596b5SMatthias Ringwald  *
1415*1b2596b5SMatthias Ringwald  * \return The index of detected key release row.
1416*1b2596b5SMatthias Ringwald  */
1417*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_release_row_index(const Pio *p_pio, uint8_t queue)
1418*1b2596b5SMatthias Ringwald {
1419*1b2596b5SMatthias Ringwald 	switch (queue) {
1420*1b2596b5SMatthias Ringwald 	case 0:
1421*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0ROW_Msk) >> PIO_KKRR_KEY0ROW_Pos);
1422*1b2596b5SMatthias Ringwald 	case 1:
1423*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1ROW_Msk) >> PIO_KKRR_KEY1ROW_Pos);
1424*1b2596b5SMatthias Ringwald 	case 2:
1425*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2ROW_Msk) >> PIO_KKRR_KEY2ROW_Pos);
1426*1b2596b5SMatthias Ringwald 	case 3:
1427*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3ROW_Msk) >> PIO_KKRR_KEY3ROW_Pos);
1428*1b2596b5SMatthias Ringwald 	default:
1429*1b2596b5SMatthias Ringwald 		return 0;
1430*1b2596b5SMatthias Ringwald 	}
1431*1b2596b5SMatthias Ringwald }
1432*1b2596b5SMatthias Ringwald 
1433*1b2596b5SMatthias Ringwald /**
1434*1b2596b5SMatthias Ringwald  * \brief Get detected key release column index of PIO keypad.
1435*1b2596b5SMatthias Ringwald  *
1436*1b2596b5SMatthias Ringwald  * \param p_pio Pointer to a PIO instance.
1437*1b2596b5SMatthias Ringwald  * \param queue The queue of key release column
1438*1b2596b5SMatthias Ringwald  *
1439*1b2596b5SMatthias Ringwald  * \return The index of detected key release column.
1440*1b2596b5SMatthias Ringwald  */
1441*1b2596b5SMatthias Ringwald uint8_t pio_keypad_get_release_column_index(const Pio *p_pio, uint8_t queue)
1442*1b2596b5SMatthias Ringwald {
1443*1b2596b5SMatthias Ringwald 	switch (queue) {
1444*1b2596b5SMatthias Ringwald 	case 0:
1445*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0COL_Msk) >> PIO_KKRR_KEY0COL_Pos);
1446*1b2596b5SMatthias Ringwald 	case 1:
1447*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1COL_Msk) >> PIO_KKRR_KEY1COL_Pos);
1448*1b2596b5SMatthias Ringwald 	case 2:
1449*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2COL_Msk) >> PIO_KKRR_KEY2COL_Pos);
1450*1b2596b5SMatthias Ringwald 	case 3:
1451*1b2596b5SMatthias Ringwald 		return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3COL_Msk) >> PIO_KKRR_KEY3COL_Pos);
1452*1b2596b5SMatthias Ringwald 	default:
1453*1b2596b5SMatthias Ringwald 		return 0;
1454*1b2596b5SMatthias Ringwald 	}
1455*1b2596b5SMatthias Ringwald }
1456*1b2596b5SMatthias Ringwald 
1457*1b2596b5SMatthias Ringwald #endif
1458*1b2596b5SMatthias Ringwald 
1459*1b2596b5SMatthias Ringwald //@}
1460*1b2596b5SMatthias Ringwald 
1461