4 * \brief Parallel Input/Output (PIO) Controller driver for SAM.
\r
6 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
\r
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions are met:
\r
15 * 1. Redistributions of source code must retain the above copyright notice,
\r
16 * this list of conditions and the following disclaimer.
\r
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
19 * this list of conditions and the following disclaimer in the documentation
\r
20 * and/or other materials provided with the distribution.
\r
22 * 3. The name of Atmel may not be used to endorse or promote products derived
\r
23 * from this software without specific prior written permission.
\r
25 * 4. This software may only be redistributed and used in connection with an
\r
26 * Atmel microcontroller product.
\r
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
\r
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
\r
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
\r
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
\r
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
38 * POSSIBILITY OF SUCH DAMAGE.
\r
44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
\r
49 #ifndef PIO_WPMR_WPKEY_PASSWD
\r
50 # define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494Fu)
\r
54 * \defgroup sam_drivers_pio_group Peripheral Parallel Input/Output (PIO) Controller
\r
58 * The Parallel Input/Output Controller (PIO) manages up to 32 fully
\r
59 * programmable input/output lines. Each I/O line may be dedicated as a
\r
60 * general-purpose I/O or be assigned to a function of an embedded peripheral.
\r
61 * This assures effective optimization of the pins of a product.
\r
66 #ifndef FREQ_SLOW_CLOCK_EXT
\r
67 /* External slow clock frequency (hz) */
\r
68 #define FREQ_SLOW_CLOCK_EXT 32768
\r
72 * \brief Configure PIO internal pull-up.
\r
74 * \param p_pio Pointer to a PIO instance.
\r
75 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
76 * \param ul_pull_up_enable Indicates if the pin(s) internal pull-up shall be
\r
79 void pio_pull_up(Pio *p_pio, const uint32_t ul_mask,
\r
80 const uint32_t ul_pull_up_enable)
\r
82 /* Enable the pull-up(s) if necessary */
\r
83 if (ul_pull_up_enable) {
\r
84 p_pio->PIO_PUER = ul_mask;
\r
86 p_pio->PIO_PUDR = ul_mask;
\r
91 * \brief Configure Glitch or Debouncing filter for the specified input(s).
\r
93 * \param p_pio Pointer to a PIO instance.
\r
94 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
95 * \param ul_cut_off Cuts off frequency for debouncing filter.
\r
97 void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask,
\r
98 const uint32_t ul_cut_off)
\r
100 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
101 /* Set Debouncing, 0 bit field no effect */
\r
102 p_pio->PIO_IFSCER = ul_mask;
\r
103 #elif (SAM3XA || SAM3U)
\r
104 /* Set Debouncing, 0 bit field no effect */
\r
105 p_pio->PIO_DIFSR = ul_mask;
\r
107 #error "Unsupported device"
\r
111 * The debouncing filter can filter a pulse of less than 1/2 Period of a
\r
112 * programmable Divided Slow Clock:
\r
113 * Tdiv_slclk = ((DIV+1)*2).Tslow_clock
\r
115 p_pio->PIO_SCDR = PIO_SCDR_DIV((FREQ_SLOW_CLOCK_EXT /
\r
116 (2 * (ul_cut_off))) - 1);
\r
120 * \brief Set a high output level on all the PIOs defined in ul_mask.
\r
121 * This has no immediate effects on PIOs that are not output, but the PIO
\r
122 * controller will save the value if they are changed to outputs.
\r
124 * \param p_pio Pointer to a PIO instance.
\r
125 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
127 void pio_set(Pio *p_pio, const uint32_t ul_mask)
\r
129 p_pio->PIO_SODR = ul_mask;
\r
133 * \brief Set a low output level on all the PIOs defined in ul_mask.
\r
134 * This has no immediate effects on PIOs that are not output, but the PIO
\r
135 * controller will save the value if they are changed to outputs.
\r
137 * \param p_pio Pointer to a PIO instance.
\r
138 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
140 void pio_clear(Pio *p_pio, const uint32_t ul_mask)
\r
142 p_pio->PIO_CODR = ul_mask;
\r
146 * \brief Return 1 if one or more PIOs of the given Pin instance currently have
\r
147 * a high level; otherwise returns 0. This method returns the actual value that
\r
148 * is being read on the pin. To return the supposed output value of a pin, use
\r
149 * pio_get_output_data_status() instead.
\r
151 * \param p_pio Pointer to a PIO instance.
\r
152 * \param ul_type PIO type.
\r
153 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
155 * \retval 1 at least one PIO currently has a high level.
\r
156 * \retval 0 all PIOs have a low level.
\r
158 uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type,
\r
159 const uint32_t ul_mask)
\r
163 if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) {
\r
164 ul_reg = p_pio->PIO_ODSR;
\r
166 ul_reg = p_pio->PIO_PDSR;
\r
169 if ((ul_reg & ul_mask) == 0) {
\r
177 * \brief Configure IO of a PIO controller as being controlled by a specific
\r
180 * \param p_pio Pointer to a PIO instance.
\r
181 * \param ul_type PIO type.
\r
182 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
184 void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type,
\r
185 const uint32_t ul_mask)
\r
189 /* Disable interrupts on the pin(s) */
\r
190 p_pio->PIO_IDR = ul_mask;
\r
192 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
195 ul_sr = p_pio->PIO_ABCDSR[0];
\r
196 p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);
\r
198 ul_sr = p_pio->PIO_ABCDSR[1];
\r
199 p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);
\r
202 ul_sr = p_pio->PIO_ABCDSR[0];
\r
203 p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);
\r
205 ul_sr = p_pio->PIO_ABCDSR[1];
\r
206 p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);
\r
210 ul_sr = p_pio->PIO_ABCDSR[0];
\r
211 p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);
\r
213 ul_sr = p_pio->PIO_ABCDSR[1];
\r
214 p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);
\r
217 ul_sr = p_pio->PIO_ABCDSR[0];
\r
218 p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);
\r
220 ul_sr = p_pio->PIO_ABCDSR[1];
\r
221 p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);
\r
224 /* Other types are invalid in this function */
\r
228 case PIO_NOT_A_PIN:
\r
231 #elif (SAM3XA|| SAM3U)
\r
234 ul_sr = p_pio->PIO_ABSR;
\r
235 p_pio->PIO_ABSR &= (~ul_mask & ul_sr);
\r
239 ul_sr = p_pio->PIO_ABSR;
\r
240 p_pio->PIO_ABSR = (ul_mask | ul_sr);
\r
243 // other types are invalid in this function
\r
247 case PIO_NOT_A_PIN:
\r
251 #error "Unsupported device"
\r
254 /* Remove the pins from under the control of PIO */
\r
255 p_pio->PIO_PDR = ul_mask;
\r
259 * \brief Configure one or more pin(s) or a PIO controller as inputs.
\r
260 * Optionally, the corresponding internal pull-up(s) and glitch filter(s) can
\r
263 * \param p_pio Pointer to a PIO instance.
\r
264 * \param ul_mask Bitmask indicating which pin(s) to configure as input(s).
\r
265 * \param ul_attribute PIO attribute(s).
\r
267 void pio_set_input(Pio *p_pio, const uint32_t ul_mask,
\r
268 const uint32_t ul_attribute)
\r
270 pio_disable_interrupt(p_pio, ul_mask);
\r
271 pio_pull_up(p_pio, ul_mask, ul_attribute & PIO_PULLUP);
\r
273 /* Enable Input Filter if necessary */
\r
274 if (ul_attribute & (PIO_DEGLITCH | PIO_DEBOUNCE)) {
\r
275 p_pio->PIO_IFER = ul_mask;
\r
277 p_pio->PIO_IFDR = ul_mask;
\r
280 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
281 /* Enable de-glitch or de-bounce if necessary */
\r
282 if (ul_attribute & PIO_DEGLITCH) {
\r
283 p_pio->PIO_IFSCDR = ul_mask;
\r
285 if (ul_attribute & PIO_DEBOUNCE) {
\r
286 p_pio->PIO_IFSCER = ul_mask;
\r
289 #elif (SAM3XA|| SAM3U)
\r
290 /* Enable de-glitch or de-bounce if necessary */
\r
291 if (ul_attribute & PIO_DEGLITCH) {
\r
292 p_pio->PIO_SCIFSR = ul_mask;
\r
294 if (ul_attribute & PIO_DEBOUNCE) {
\r
295 p_pio->PIO_DIFSR = ul_mask;
\r
299 #error "Unsupported device"
\r
302 /* Configure pin as input */
\r
303 p_pio->PIO_ODR = ul_mask;
\r
304 p_pio->PIO_PER = ul_mask;
\r
308 * \brief Configure one or more pin(s) of a PIO controller as outputs, with
\r
309 * the given default value. Optionally, the multi-drive feature can be enabled
\r
312 * \param p_pio Pointer to a PIO instance.
\r
313 * \param ul_mask Bitmask indicating which pin(s) to configure.
\r
314 * \param ul_default_level Default level on the pin(s).
\r
315 * \param ul_multidrive_enable Indicates if the pin(s) shall be configured as
\r
317 * \param ul_pull_up_enable Indicates if the pin shall have its pull-up
\r
320 void pio_set_output(Pio *p_pio, const uint32_t ul_mask,
\r
321 const uint32_t ul_default_level,
\r
322 const uint32_t ul_multidrive_enable,
\r
323 const uint32_t ul_pull_up_enable)
\r
325 pio_disable_interrupt(p_pio, ul_mask);
\r
326 pio_pull_up(p_pio, ul_mask, ul_pull_up_enable);
\r
328 /* Enable multi-drive if necessary */
\r
329 if (ul_multidrive_enable) {
\r
330 p_pio->PIO_MDER = ul_mask;
\r
332 p_pio->PIO_MDDR = ul_mask;
\r
335 /* Set default value */
\r
336 if (ul_default_level) {
\r
337 p_pio->PIO_SODR = ul_mask;
\r
339 p_pio->PIO_CODR = ul_mask;
\r
342 /* Configure pin(s) as output(s) */
\r
343 p_pio->PIO_OER = ul_mask;
\r
344 p_pio->PIO_PER = ul_mask;
\r
348 * \brief Perform complete pin(s) configuration; general attributes and PIO init
\r
351 * \param p_pio Pointer to a PIO instance.
\r
352 * \param ul_type PIO type.
\r
353 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
354 * \param ul_attribute Pins attributes.
\r
356 * \return Whether the pin(s) have been configured properly.
\r
358 uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type,
\r
359 const uint32_t ul_mask, const uint32_t ul_attribute)
\r
361 /* Configure pins */
\r
365 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
369 pio_set_peripheral(p_pio, ul_type, ul_mask);
\r
370 pio_pull_up(p_pio, ul_mask, (ul_attribute & PIO_PULLUP));
\r
374 pio_set_input(p_pio, ul_mask, ul_attribute);
\r
379 pio_set_output(p_pio, ul_mask, (ul_type == PIO_OUTPUT_1),
\r
380 (ul_attribute & PIO_OPENDRAIN) ? 1 : 0,
\r
381 (ul_attribute & PIO_PULLUP) ? 1 : 0);
\r
392 * \brief Return 1 if one or more PIOs of the given Pin are configured to
\r
393 * output a high level (even if they are not output).
\r
394 * To get the actual value of the pin, use PIO_Get() instead.
\r
396 * \param p_pio Pointer to a PIO instance.
\r
397 * \param ul_mask Bitmask of one or more pin(s).
\r
399 * \retval 1 At least one PIO is configured to output a high level.
\r
400 * \retval 0 All PIOs are configured to output a low level.
\r
402 uint32_t pio_get_output_data_status(const Pio *p_pio,
\r
403 const uint32_t ul_mask)
\r
405 if ((p_pio->PIO_ODSR & ul_mask) == 0) {
\r
413 * \brief Configure PIO pin multi-driver.
\r
415 * \param p_pio Pointer to a PIO instance.
\r
416 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
417 * \param ul_multi_driver_enable Indicates if the pin(s) multi-driver shall be
\r
420 void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask,
\r
421 const uint32_t ul_multi_driver_enable)
\r
423 /* Enable the multi-driver if necessary */
\r
424 if (ul_multi_driver_enable) {
\r
425 p_pio->PIO_MDER = ul_mask;
\r
427 p_pio->PIO_MDDR = ul_mask;
\r
432 * \brief Get multi-driver status.
\r
434 * \param p_pio Pointer to a PIO instance.
\r
436 * \return The multi-driver mask value.
\r
438 uint32_t pio_get_multi_driver_status(const Pio *p_pio)
\r
440 return p_pio->PIO_MDSR;
\r
444 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
446 * \brief Configure PIO pin internal pull-down.
\r
448 * \param p_pio Pointer to a PIO instance.
\r
449 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
450 * \param ul_pull_down_enable Indicates if the pin(s) internal pull-down shall
\r
453 void pio_pull_down(Pio *p_pio, const uint32_t ul_mask,
\r
454 const uint32_t ul_pull_down_enable)
\r
456 /* Enable the pull-down if necessary */
\r
457 if (ul_pull_down_enable) {
\r
458 p_pio->PIO_PPDER = ul_mask;
\r
460 p_pio->PIO_PPDDR = ul_mask;
\r
466 * \brief Enable PIO output write for synchronous data output.
\r
468 * \param p_pio Pointer to a PIO instance.
\r
469 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
471 void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask)
\r
473 p_pio->PIO_OWER = ul_mask;
\r
477 * \brief Disable PIO output write.
\r
479 * \param p_pio Pointer to a PIO instance.
\r
480 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
482 void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask)
\r
484 p_pio->PIO_OWDR = ul_mask;
\r
488 * \brief Read PIO output write status.
\r
490 * \param p_pio Pointer to a PIO instance.
\r
492 * \return The output write mask value.
\r
494 uint32_t pio_get_output_write_status(const Pio *p_pio)
\r
496 return p_pio->PIO_OWSR;
\r
500 * \brief Synchronously write on output pins.
\r
501 * \note Only bits unmasked by PIO_OWSR (Output Write Status Register) are
\r
504 * \param p_pio Pointer to a PIO instance.
\r
505 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
507 void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask)
\r
509 p_pio->PIO_ODSR = ul_mask;
\r
512 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
514 * \brief Configure PIO pin schmitt trigger. By default the Schmitt trigger is
\r
516 * Disabling the Schmitt Trigger is requested when using the QTouch Library.
\r
518 * \param p_pio Pointer to a PIO instance.
\r
519 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
521 void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask)
\r
523 p_pio->PIO_SCHMITT = ul_mask;
\r
527 * \brief Get PIO pin schmitt trigger status.
\r
529 * \param p_pio Pointer to a PIO instance.
\r
531 * \return The schmitt trigger mask value.
\r
533 uint32_t pio_get_schmitt_trigger(const Pio *p_pio)
\r
535 return p_pio->PIO_SCHMITT;
\r
540 * \brief Configure the given interrupt source.
\r
541 * Interrupt can be configured to trigger on rising edge, falling edge,
\r
542 * high level, low level or simply on level change.
\r
544 * \param p_pio Pointer to a PIO instance.
\r
545 * \param ul_mask Interrupt source bit map.
\r
546 * \param ul_attr Interrupt source attributes.
\r
548 void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask,
\r
549 const uint32_t ul_attr)
\r
551 /* Configure additional interrupt mode registers. */
\r
552 if (ul_attr & PIO_IT_AIME) {
\r
553 /* Enable additional interrupt mode. */
\r
554 p_pio->PIO_AIMER = ul_mask;
\r
556 /* If bit field of the selected pin is 1, set as
\r
557 Rising Edge/High level detection event. */
\r
558 if (ul_attr & PIO_IT_RE_OR_HL) {
\r
559 /* Rising Edge or High Level */
\r
560 p_pio->PIO_REHLSR = ul_mask;
\r
562 /* Falling Edge or Low Level */
\r
563 p_pio->PIO_FELLSR = ul_mask;
\r
566 /* If bit field of the selected pin is 1, set as
\r
567 edge detection source. */
\r
568 if (ul_attr & PIO_IT_EDGE) {
\r
570 p_pio->PIO_ESR = ul_mask;
\r
573 p_pio->PIO_LSR = ul_mask;
\r
576 /* Disable additional interrupt mode. */
\r
577 p_pio->PIO_AIMDR = ul_mask;
\r
582 * \brief Enable the given interrupt source.
\r
583 * The PIO must be configured as an NVIC interrupt source as well.
\r
584 * The status register of the corresponding PIO controller is cleared
\r
585 * prior to enabling the interrupt.
\r
587 * \param p_pio Pointer to a PIO instance.
\r
588 * \param ul_mask Interrupt sources bit map.
\r
590 void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
\r
593 p_pio->PIO_IER = ul_mask;
\r
597 * \brief Disable a given interrupt source, with no added side effects.
\r
599 * \param p_pio Pointer to a PIO instance.
\r
600 * \param ul_mask Interrupt sources bit map.
\r
602 void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
\r
604 p_pio->PIO_IDR = ul_mask;
\r
608 * \brief Read PIO interrupt status.
\r
610 * \param p_pio Pointer to a PIO instance.
\r
612 * \return The interrupt status mask value.
\r
614 uint32_t pio_get_interrupt_status(const Pio *p_pio)
\r
616 return p_pio->PIO_ISR;
\r
620 * \brief Read PIO interrupt mask.
\r
622 * \param p_pio Pointer to a PIO instance.
\r
624 * \return The interrupt mask value.
\r
626 uint32_t pio_get_interrupt_mask(const Pio *p_pio)
\r
628 return p_pio->PIO_IMR;
\r
632 * \brief Set additional interrupt mode.
\r
634 * \param p_pio Pointer to a PIO instance.
\r
635 * \param ul_mask Interrupt sources bit map.
\r
636 * \param ul_attribute Pin(s) attributes.
\r
638 void pio_set_additional_interrupt_mode(Pio *p_pio,
\r
639 const uint32_t ul_mask, const uint32_t ul_attribute)
\r
641 /* Enables additional interrupt mode if needed */
\r
642 if (ul_attribute & PIO_IT_AIME) {
\r
643 /* Enables additional interrupt mode */
\r
644 p_pio->PIO_AIMER = ul_mask;
\r
646 /* Configures the Polarity of the event detection */
\r
647 /* (Rising/Falling Edge or High/Low Level) */
\r
648 if (ul_attribute & PIO_IT_RE_OR_HL) {
\r
649 /* Rising Edge or High Level */
\r
650 p_pio->PIO_REHLSR = ul_mask;
\r
652 /* Falling Edge or Low Level */
\r
653 p_pio->PIO_FELLSR = ul_mask;
\r
656 /* Configures the type of event detection (Edge or Level) */
\r
657 if (ul_attribute & PIO_IT_EDGE) {
\r
659 p_pio->PIO_ESR = ul_mask;
\r
662 p_pio->PIO_LSR = ul_mask;
\r
665 /* Disable additional interrupt mode */
\r
666 p_pio->PIO_AIMDR = ul_mask;
\r
670 #ifndef PIO_WPMR_WPKEY_PASSWD
\r
671 #define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494FU)
\r
675 * \brief Enable or disable write protect of PIO registers.
\r
677 * \param p_pio Pointer to a PIO instance.
\r
678 * \param ul_enable 1 to enable, 0 to disable.
\r
680 void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable)
\r
682 p_pio->PIO_WPMR = PIO_WPMR_WPKEY_PASSWD | (ul_enable & PIO_WPMR_WPEN);
\r
686 * \brief Read write protect status.
\r
688 * \param p_pio Pointer to a PIO instance.
\r
690 * \return Return write protect status.
\r
692 uint32_t pio_get_writeprotect_status(const Pio *p_pio)
\r
694 return p_pio->PIO_WPSR;
\r
698 * \brief Return the value of a pin.
\r
700 * \param ul_pin The pin number.
\r
702 * \return The pin value.
\r
704 * \note If pin is output: a pull-up or pull-down could hide the actual value.
\r
705 * The function \ref pio_get can be called to get the actual pin output
\r
707 * \note If pin is input: PIOx must be clocked to sample the signal.
\r
710 uint32_t pio_get_pin_value(uint32_t ul_pin)
\r
712 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
714 return (p_pio->PIO_PDSR >> (ul_pin & 0x1F)) & 1;
\r
718 * \brief Drive a GPIO pin to 1.
\r
720 * \param ul_pin The pin index.
\r
722 * \note The function \ref pio_configure_pin must be called beforehand.
\r
724 void pio_set_pin_high(uint32_t ul_pin)
\r
726 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
728 /* Value to be driven on the I/O line: 1. */
\r
729 p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
\r
733 * \brief Drive a GPIO pin to 0.
\r
735 * \param ul_pin The pin index.
\r
737 * \note The function \ref pio_configure_pin must be called before.
\r
739 void pio_set_pin_low(uint32_t ul_pin)
\r
741 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
743 /* Value to be driven on the I/O line: 0. */
\r
744 p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);
\r
748 * \brief Toggle a GPIO pin.
\r
750 * \param ul_pin The pin index.
\r
752 * \note The function \ref pio_configure_pin must be called before.
\r
754 void pio_toggle_pin(uint32_t ul_pin)
\r
756 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
758 if (p_pio->PIO_ODSR & (1 << (ul_pin & 0x1F))) {
\r
759 /* Value to be driven on the I/O line: 0. */
\r
760 p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);
\r
762 /* Value to be driven on the I/O line: 1. */
\r
763 p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
\r
768 * \brief Perform complete pin(s) configuration; general attributes and PIO init
\r
771 * \param ul_pin Bitmask of one or more pin(s) to configure.
\r
772 * \param ul_flags Pins attributes.
\r
774 * \return Whether the pin(s) have been configured properly.
\r
776 uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags)
\r
778 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
780 /* Configure pins */
\r
781 switch (ul_flags & PIO_TYPE_Msk) {
\r
782 case PIO_TYPE_PIO_PERIPH_A:
\r
783 pio_set_peripheral(p_pio, PIO_PERIPH_A, (1 << (ul_pin & 0x1F)));
\r
784 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
\r
785 (ul_flags & PIO_PULLUP));
\r
787 case PIO_TYPE_PIO_PERIPH_B:
\r
788 pio_set_peripheral(p_pio, PIO_PERIPH_B, (1 << (ul_pin & 0x1F)));
\r
789 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
\r
790 (ul_flags & PIO_PULLUP));
\r
792 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
793 case PIO_TYPE_PIO_PERIPH_C:
\r
794 pio_set_peripheral(p_pio, PIO_PERIPH_C, (1 << (ul_pin & 0x1F)));
\r
795 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
\r
796 (ul_flags & PIO_PULLUP));
\r
798 case PIO_TYPE_PIO_PERIPH_D:
\r
799 pio_set_peripheral(p_pio, PIO_PERIPH_D, (1 << (ul_pin & 0x1F)));
\r
800 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
\r
801 (ul_flags & PIO_PULLUP));
\r
805 case PIO_TYPE_PIO_INPUT:
\r
806 pio_set_input(p_pio, (1 << (ul_pin & 0x1F)), ul_flags);
\r
809 case PIO_TYPE_PIO_OUTPUT_0:
\r
810 case PIO_TYPE_PIO_OUTPUT_1:
\r
811 pio_set_output(p_pio, (1 << (ul_pin & 0x1F)),
\r
812 ((ul_flags & PIO_TYPE_PIO_OUTPUT_1)
\r
813 == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0,
\r
814 (ul_flags & PIO_OPENDRAIN) ? 1 : 0,
\r
815 (ul_flags & PIO_PULLUP) ? 1 : 0);
\r
826 * \brief Drive a GPIO port to 1.
\r
828 * \param p_pio Base address of the PIO port.
\r
829 * \param ul_mask Bitmask of one or more pin(s) to toggle.
\r
831 void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask)
\r
833 /* Value to be driven on the I/O line: 1. */
\r
834 p_pio->PIO_SODR = ul_mask;
\r
838 * \brief Drive a GPIO port to 0.
\r
840 * \param p_pio Base address of the PIO port.
\r
841 * \param ul_mask Bitmask of one or more pin(s) to toggle.
\r
843 void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask)
\r
845 /* Value to be driven on the I/O line: 0. */
\r
846 p_pio->PIO_CODR = ul_mask;
\r
850 * \brief Toggle a GPIO group.
\r
852 * \param p_pio Pointer to a PIO instance.
\r
853 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
855 void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask)
\r
857 if (p_pio->PIO_ODSR & ul_mask) {
\r
858 /* Value to be driven on the I/O line: 0. */
\r
859 p_pio->PIO_CODR = ul_mask;
\r
861 /* Value to be driven on the I/O line: 1. */
\r
862 p_pio->PIO_SODR = ul_mask;
\r
867 * \brief Perform complete pin(s) configuration; general attributes and PIO init
\r
870 * \param p_pio Pointer to a PIO instance.
\r
871 * \param ul_mask Bitmask of one or more pin(s) to configure.
\r
872 * \param ul_flags Pin(s) attributes.
\r
874 * \return Whether the pin(s) have been configured properly.
\r
876 uint32_t pio_configure_pin_group(Pio *p_pio,
\r
877 uint32_t ul_mask, const uint32_t ul_flags)
\r
879 /* Configure pins */
\r
880 switch (ul_flags & PIO_TYPE_Msk) {
\r
881 case PIO_TYPE_PIO_PERIPH_A:
\r
882 pio_set_peripheral(p_pio, PIO_PERIPH_A, ul_mask);
\r
883 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
\r
885 case PIO_TYPE_PIO_PERIPH_B:
\r
886 pio_set_peripheral(p_pio, PIO_PERIPH_B, ul_mask);
\r
887 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
\r
889 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
890 case PIO_TYPE_PIO_PERIPH_C:
\r
891 pio_set_peripheral(p_pio, PIO_PERIPH_C, ul_mask);
\r
892 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
\r
894 case PIO_TYPE_PIO_PERIPH_D:
\r
895 pio_set_peripheral(p_pio, PIO_PERIPH_D, ul_mask);
\r
896 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
\r
900 case PIO_TYPE_PIO_INPUT:
\r
901 pio_set_input(p_pio, ul_mask, ul_flags);
\r
904 case PIO_TYPE_PIO_OUTPUT_0:
\r
905 case PIO_TYPE_PIO_OUTPUT_1:
\r
906 pio_set_output(p_pio, ul_mask,
\r
907 ((ul_flags & PIO_TYPE_PIO_OUTPUT_1)
\r
908 == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0,
\r
909 (ul_flags & PIO_OPENDRAIN) ? 1 : 0,
\r
910 (ul_flags & PIO_PULLUP) ? 1 : 0);
\r
921 * \brief Enable interrupt for a GPIO pin.
\r
923 * \param ul_pin The pin index.
\r
925 * \note The function \ref gpio_configure_pin must be called before.
\r
927 void pio_enable_pin_interrupt(uint32_t ul_pin)
\r
929 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
931 p_pio->PIO_IER = 1 << (ul_pin & 0x1F);
\r
936 * \brief Disable interrupt for a GPIO pin.
\r
938 * \param ul_pin The pin index.
\r
940 * \note The function \ref gpio_configure_pin must be called before.
\r
942 void pio_disable_pin_interrupt(uint32_t ul_pin)
\r
944 Pio *p_pio = pio_get_pin_group(ul_pin);
\r
946 p_pio->PIO_IDR = 1 << (ul_pin & 0x1F);
\r
951 * \brief Return GPIO port for a GPIO pin.
\r
953 * \param ul_pin The pin index.
\r
955 * \return Pointer to \ref Pio struct for GPIO port.
\r
957 Pio *pio_get_pin_group(uint32_t ul_pin)
\r
961 #if (SAM4C || SAM4CP)
\r
963 if (ul_pin > PIO_PC9_IDX) {
\r
965 } else if (ul_pin > PIO_PB31_IDX) {
\r
967 if (ul_pin > PIO_PB31_IDX) {
\r
971 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
\r
974 if (ul_pin > PIO_PB21_IDX) {
\r
977 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
\r
980 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
\r
986 * \brief Return GPIO port peripheral ID for a GPIO pin.
\r
988 * \param ul_pin The pin index.
\r
990 * \return GPIO port peripheral ID.
\r
992 uint32_t pio_get_pin_group_id(uint32_t ul_pin)
\r
996 #if (SAM4C || SAM4CP)
\r
998 if (ul_pin > PIO_PC9_IDX) {
\r
1000 } else if (ul_pin > PIO_PB31_IDX) {
\r
1002 if (ul_pin > PIO_PB31_IDX) {
\r
1006 ul_id = ID_PIOA + (ul_pin >> 5);
\r
1009 if (ul_pin > PIO_PB21_IDX) {
\r
1012 ul_id = ID_PIOA + (ul_pin >> 5);
\r
1014 #elif (SAMV70 || SAMV71 || SAME70 || SAMS70)
\r
1015 if (ul_pin > PIO_PC31_IDX) {
\r
1016 if(ul_pin > PIO_PD31_IDX){
\r
1022 ul_id = ID_PIOA + (ul_pin >> 5);
\r
1025 ul_id = ID_PIOA + (ul_pin >> 5);
\r
1032 * \brief Return GPIO port pin mask for a GPIO pin.
\r
1034 * \param ul_pin The pin index.
\r
1036 * \return GPIO port pin mask.
\r
1038 uint32_t pio_get_pin_group_mask(uint32_t ul_pin)
\r
1040 uint32_t ul_mask = 1 << (ul_pin & 0x1F);
\r
1044 #if (SAM3S || SAM4S || SAM4E || SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
1045 /* Capture mode enable flag */
\r
1046 uint32_t pio_capture_enable_flag;
\r
1049 * \brief Configure PIO capture mode.
\r
1050 * \note PIO capture mode will be disabled automatically.
\r
1052 * \param p_pio Pointer to a PIO instance.
\r
1053 * \param ul_mode Bitmask of one or more modes.
\r
1055 void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode)
\r
1057 ul_mode &= (~PIO_PCMR_PCEN); /* Disable PIO capture mode */
\r
1058 p_pio->PIO_PCMR = ul_mode;
\r
1062 * \brief Enable PIO capture mode.
\r
1064 * \param p_pio Pointer to a PIO instance.
\r
1066 void pio_capture_enable(Pio *p_pio)
\r
1068 p_pio->PIO_PCMR |= PIO_PCMR_PCEN;
\r
1069 pio_capture_enable_flag = true;
\r
1073 * \brief Disable PIO capture mode.
\r
1075 * \param p_pio Pointer to a PIO instance.
\r
1077 void pio_capture_disable(Pio *p_pio)
\r
1079 p_pio->PIO_PCMR &= (~PIO_PCMR_PCEN);
\r
1080 pio_capture_enable_flag = false;
\r
1084 * \brief Read from Capture Reception Holding Register.
\r
1085 * \note Data presence should be tested before any read attempt.
\r
1087 * \param p_pio Pointer to a PIO instance.
\r
1088 * \param pul_data Pointer to store the data.
\r
1090 * \retval 0 Success.
\r
1091 * \retval 1 I/O Failure, Capture data is not ready.
\r
1093 uint32_t pio_capture_read(const Pio *p_pio, uint32_t *pul_data)
\r
1095 /* Check if the data is ready */
\r
1096 if ((p_pio->PIO_PCISR & PIO_PCISR_DRDY) == 0) {
\r
1101 *pul_data = p_pio->PIO_PCRHR;
\r
1106 * \brief Enable the given interrupt source of PIO capture. The status
\r
1107 * register of the corresponding PIO capture controller is cleared prior
\r
1108 * to enabling the interrupt.
\r
1110 * \param p_pio Pointer to a PIO instance.
\r
1111 * \param ul_mask Interrupt sources bit map.
\r
1113 void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
\r
1116 p_pio->PIO_PCIER = ul_mask;
\r
1120 * \brief Disable a given interrupt source of PIO capture.
\r
1122 * \param p_pio Pointer to a PIO instance.
\r
1123 * \param ul_mask Interrupt sources bit map.
\r
1125 void pio_capture_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
\r
1127 p_pio->PIO_PCIDR = ul_mask;
\r
1131 * \brief Read PIO interrupt status of PIO capture.
\r
1133 * \param p_pio Pointer to a PIO instance.
\r
1135 * \return The interrupt status mask value.
\r
1137 uint32_t pio_capture_get_interrupt_status(const Pio *p_pio)
\r
1139 return p_pio->PIO_PCISR;
\r
1143 * \brief Read PIO interrupt mask of PIO capture.
\r
1145 * \param p_pio Pointer to a PIO instance.
\r
1147 * \return The interrupt mask value.
\r
1149 uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio)
\r
1151 return p_pio->PIO_PCIMR;
\r
1153 #if !(SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
1155 * \brief Get PDC registers base address.
\r
1157 * \param p_pio Pointer to an PIO peripheral.
\r
1159 * \return PIOA PDC register base address.
\r
1161 Pdc *pio_capture_get_pdc_base(const Pio *p_pio)
\r
1163 UNUSED(p_pio); /* Stop warning */
\r
1169 #if (SAM4C || SAM4CP || SAM4CM || SAMG55)
\r
1171 * \brief Set PIO IO drive.
\r
1173 * \param p_pio Pointer to an PIO peripheral.
\r
1174 * \param ul_line Line index (0..31).
\r
1175 * \param mode IO drive mode.
\r
1177 void pio_set_io_drive(Pio *p_pio, uint32_t ul_line,
\r
1178 enum pio_io_drive_mode mode)
\r
1180 p_pio->PIO_DRIVER &= ~(1 << ul_line);
\r
1181 p_pio->PIO_DRIVER |= mode << ul_line;
\r
1185 #if (SAMV71 || SAMV70 || SAME70 || SAMS70)
\r
1187 * \brief Enable PIO keypad controller.
\r
1189 * \param p_pio Pointer to a PIO instance.
\r
1191 void pio_keypad_enable(Pio *p_pio)
\r
1193 p_pio->PIO_KER |= PIO_KER_KCE;
\r
1197 * \brief Disable PIO keypad controller.
\r
1199 * \param p_pio Pointer to a PIO instance.
\r
1201 void pio_keypad_disable(Pio *p_pio)
\r
1203 p_pio->PIO_KER &= (~PIO_KER_KCE);
\r
1207 * \brief Set PIO keypad controller row number.
\r
1209 * \param p_pio Pointer to a PIO instance.
\r
1210 * \param num Number of row of the keypad matrix.
\r
1212 void pio_keypad_set_row_num(Pio *p_pio, uint8_t num)
\r
1214 p_pio->PIO_KRCR &= (~PIO_KRCR_NBR_Msk);
\r
1215 p_pio->PIO_KRCR |= PIO_KRCR_NBR(num);
\r
1219 * \brief Get PIO keypad controller row number.
\r
1221 * \param p_pio Pointer to a PIO instance.
\r
1223 * \return Number of row of the keypad matrix.
\r
1225 uint8_t pio_keypad_get_row_num(const Pio *p_pio)
\r
1227 return ((p_pio->PIO_KRCR & PIO_KRCR_NBR_Msk) >> PIO_KRCR_NBR_Pos);
\r
1231 * \brief Set PIO keypad controller column number.
\r
1233 * \param p_pio Pointer to a PIO instance.
\r
1234 * \param num Number of column of the keypad matrix.
\r
1236 void pio_keypad_set_column_num(Pio *p_pio, uint8_t num)
\r
1238 p_pio->PIO_KRCR &= (~PIO_KRCR_NBC_Msk);
\r
1239 p_pio->PIO_KRCR |= PIO_KRCR_NBC(num);
\r
1243 * \brief Get PIO keypad controller column number.
\r
1245 * \param p_pio Pointer to a PIO instance.
\r
1247 * \return Number of column of the keypad matrix.
\r
1249 uint8_t pio_keypad_get_column_num(const Pio *p_pio)
\r
1251 return ((p_pio->PIO_KRCR & PIO_KRCR_NBC_Msk) >> PIO_KRCR_NBC_Pos);
\r
1255 * \brief Set PIO keypad matrix debouncing value.
\r
1257 * \param p_pio Pointer to a PIO instance.
\r
1258 * \param num Number of debouncing value.
\r
1260 void pio_keypad_set_debouncing_value(Pio *p_pio, uint16_t value)
\r
1262 p_pio->PIO_KDR = PIO_KDR_DBC(value);
\r
1266 * \brief Get PIO keypad matrix debouncing value.
\r
1268 * \param p_pio Pointer to a PIO instance.
\r
1270 * \return The keypad debouncing value.
\r
1272 uint16_t pio_keypad_get_debouncing_value(const Pio *p_pio)
\r
1274 return ((p_pio->PIO_KDR & PIO_KDR_DBC_Msk) >> PIO_KDR_DBC_Pos);
\r
1278 * \brief Enable the interrupt source of PIO keypad.
\r
1280 * \param p_pio Pointer to a PIO instance.
\r
1281 * \param ul_mask Interrupt sources bit map.
\r
1283 void pio_keypad_enable_interrupt(Pio *p_pio, uint32_t ul_mask)
\r
1285 p_pio->PIO_KIER = ul_mask;
\r
1289 * \brief Disable the interrupt source of PIO keypad.
\r
1291 * \param p_pio Pointer to a PIO instance.
\r
1292 * \param ul_mask Interrupt sources bit map.
\r
1294 void pio_keypad_disable_interrupt(Pio *p_pio, uint32_t ul_mask)
\r
1296 p_pio->PIO_KIDR = ul_mask;
\r
1300 * \brief Get interrupt mask of PIO keypad.
\r
1302 * \param p_pio Pointer to a PIO instance.
\r
1304 * \return The interrupt mask value.
\r
1306 uint32_t pio_keypad_get_interrupt_mask(const Pio *p_pio)
\r
1308 return p_pio->PIO_KIMR;
\r
1312 * \brief Get key press status of PIO keypad.
\r
1314 * \param p_pio Pointer to a PIO instance.
\r
1316 * \return The status of key press.
\r
1317 * 0: No key press has been detected.
\r
1318 * 1: At least one key press has been detected.
\r
1320 uint32_t pio_keypad_get_press_status(const Pio *p_pio)
\r
1322 if (p_pio->PIO_KSR & PIO_KSR_KPR) {
\r
1330 * \brief Get key release status of PIO keypad.
\r
1332 * \param p_pio Pointer to a PIO instance.
\r
1334 * \return The status of key release.
\r
1335 * 0 No key release has been detected.
\r
1336 * 1 At least one key release has been detected.
\r
1338 uint32_t pio_keypad_get_release_status(const Pio *p_pio)
\r
1340 if (p_pio->PIO_KSR & PIO_KSR_KRL) {
\r
1348 * \brief Get simultaneous key press number of PIO keypad.
\r
1350 * \param p_pio Pointer to a PIO instance.
\r
1352 * \return The number of simultaneous key press.
\r
1354 uint8_t pio_keypad_get_simult_press_num(const Pio *p_pio)
\r
1356 return ((p_pio->PIO_KSR & PIO_KSR_NBKPR_Msk) >> PIO_KSR_NBKPR_Pos);
\r
1360 * \brief Get simultaneous key release number of PIO keypad.
\r
1362 * \param p_pio Pointer to a PIO instance.
\r
1364 * \return The number of simultaneous key release.
\r
1366 uint8_t pio_keypad_get_simult_release_num(const Pio *p_pio)
\r
1368 return ((p_pio->PIO_KSR & PIO_KSR_NBKRL_Msk) >> PIO_KSR_NBKRL_Pos);
\r
1372 * \brief Get detected key press row index of PIO keypad.
\r
1374 * \param p_pio Pointer to a PIO instance.
\r
1375 * \param queue The queue of key press row
\r
1377 * \return The index of detected key press row.
\r
1379 uint8_t pio_keypad_get_press_row_index(const Pio *p_pio, uint8_t queue)
\r
1383 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0ROW_Msk) >> PIO_KKPR_KEY0ROW_Pos);
\r
1385 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1ROW_Msk) >> PIO_KKPR_KEY1ROW_Pos);
\r
1387 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2ROW_Msk) >> PIO_KKPR_KEY2ROW_Pos);
\r
1389 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3ROW_Msk) >> PIO_KKPR_KEY3ROW_Pos);
\r
1396 * \brief Get detected key press column index of PIO keypad.
\r
1398 * \param p_pio Pointer to a PIO instance.
\r
1399 * \param queue The queue of key press column
\r
1401 * \return The index of detected key press column.
\r
1403 uint8_t pio_keypad_get_press_column_index(const Pio *p_pio, uint8_t queue)
\r
1407 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0COL_Msk) >> PIO_KKPR_KEY0COL_Pos);
\r
1409 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1COL_Msk) >> PIO_KKPR_KEY1COL_Pos);
\r
1411 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2COL_Msk) >> PIO_KKPR_KEY2COL_Pos);
\r
1413 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3COL_Msk) >> PIO_KKPR_KEY3COL_Pos);
\r
1420 * \brief Get detected key release row index of PIO keypad.
\r
1422 * \param p_pio Pointer to a PIO instance.
\r
1423 * \param queue The queue of key release row
\r
1425 * \return The index of detected key release row.
\r
1427 uint8_t pio_keypad_get_release_row_index(const Pio *p_pio, uint8_t queue)
\r
1431 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0ROW_Msk) >> PIO_KKRR_KEY0ROW_Pos);
\r
1433 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1ROW_Msk) >> PIO_KKRR_KEY1ROW_Pos);
\r
1435 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2ROW_Msk) >> PIO_KKRR_KEY2ROW_Pos);
\r
1437 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3ROW_Msk) >> PIO_KKRR_KEY3ROW_Pos);
\r
1444 * \brief Get detected key release column index of PIO keypad.
\r
1446 * \param p_pio Pointer to a PIO instance.
\r
1447 * \param queue The queue of key release column
\r
1449 * \return The index of detected key release column.
\r
1451 uint8_t pio_keypad_get_release_column_index(const Pio *p_pio, uint8_t queue)
\r
1455 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0COL_Msk) >> PIO_KKRR_KEY0COL_Pos);
\r
1457 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1COL_Msk) >> PIO_KKRR_KEY1COL_Pos);
\r
1459 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2COL_Msk) >> PIO_KKRR_KEY2COL_Pos);
\r
1461 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3COL_Msk) >> PIO_KKRR_KEY3COL_Pos);
\r