]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAME70_Xplained_AtmelStudio/src/ASF/sam/drivers/pio/pio.c
Rename DummyTCB_t to StaticTCB_t.
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAME70_Xplained_AtmelStudio / src / ASF / sam / drivers / pio / pio.c
1 /**\r
2  * \file\r
3  *\r
4  * \brief Parallel Input/Output (PIO) Controller driver for SAM.\r
5  *\r
6  * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.\r
7  *\r
8  * \asf_license_start\r
9  *\r
10  * \page License\r
11  *\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
14  *\r
15  * 1. Redistributions of source code must retain the above copyright notice,\r
16  *    this list of conditions and the following disclaimer.\r
17  *\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
21  *\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
24  *\r
25  * 4. This software may only be redistributed and used in connection with an\r
26  *    Atmel microcontroller product.\r
27  *\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
39  *\r
40  * \asf_license_stop\r
41  *\r
42  */\r
43 /*\r
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>\r
45  */\r
46 \r
47 #include "pio.h"\r
48 \r
49 #ifndef PIO_WPMR_WPKEY_PASSWD\r
50 #  define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494Fu)\r
51 #endif\r
52 \r
53 /**\r
54  * \defgroup sam_drivers_pio_group Peripheral Parallel Input/Output (PIO) Controller\r
55  *\r
56  * \par Purpose\r
57  *\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
62  *\r
63  * @{\r
64  */\r
65 \r
66 #ifndef FREQ_SLOW_CLOCK_EXT\r
67 /* External slow clock frequency (hz) */\r
68 #define FREQ_SLOW_CLOCK_EXT 32768\r
69 #endif\r
70 \r
71 /**\r
72  * \brief Configure PIO internal pull-up.\r
73  *\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
77  * configured.\r
78  */\r
79 void pio_pull_up(Pio *p_pio, const uint32_t ul_mask,\r
80                 const uint32_t ul_pull_up_enable)\r
81 {\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
85         } else {\r
86                 p_pio->PIO_PUDR = ul_mask;\r
87         }\r
88 }\r
89 \r
90 /**\r
91  * \brief Configure Glitch or Debouncing filter for the specified input(s).\r
92  *\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
96  */\r
97 void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask,\r
98                 const uint32_t ul_cut_off)\r
99 {\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
106 #else\r
107 #error "Unsupported device"\r
108 #endif\r
109 \r
110         /*\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
114          */\r
115         p_pio->PIO_SCDR = PIO_SCDR_DIV((FREQ_SLOW_CLOCK_EXT /\r
116                         (2 * (ul_cut_off))) - 1);\r
117 }\r
118 \r
119 /**\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
123  *\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
126  */\r
127 void pio_set(Pio *p_pio, const uint32_t ul_mask)\r
128 {\r
129         p_pio->PIO_SODR = ul_mask;\r
130 }\r
131 \r
132 /**\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
136  *\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
139  */\r
140 void pio_clear(Pio *p_pio, const uint32_t ul_mask)\r
141 {\r
142         p_pio->PIO_CODR = ul_mask;\r
143 }\r
144 \r
145 /**\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
150  *\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
154  *\r
155  * \retval 1 at least one PIO currently has a high level.\r
156  * \retval 0 all PIOs have a low level.\r
157  */\r
158 uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type,\r
159                 const uint32_t ul_mask)\r
160 {\r
161         uint32_t ul_reg;\r
162 \r
163         if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) {\r
164                 ul_reg = p_pio->PIO_ODSR;\r
165         } else {\r
166                 ul_reg = p_pio->PIO_PDSR;\r
167         }\r
168 \r
169         if ((ul_reg & ul_mask) == 0) {\r
170                 return 0;\r
171         } else {\r
172                 return 1;\r
173         }\r
174 }\r
175 \r
176 /**\r
177  * \brief Configure IO of a PIO controller as being controlled by a specific\r
178  * peripheral.\r
179  *\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
183  */\r
184 void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type,\r
185                 const uint32_t ul_mask)\r
186 {\r
187         uint32_t ul_sr;\r
188 \r
189         /* Disable interrupts on the pin(s) */\r
190         p_pio->PIO_IDR = ul_mask;\r
191 \r
192 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
193         switch (ul_type) {\r
194         case PIO_PERIPH_A:\r
195                 ul_sr = p_pio->PIO_ABCDSR[0];\r
196                 p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);\r
197 \r
198                 ul_sr = p_pio->PIO_ABCDSR[1];\r
199                 p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);\r
200                 break;\r
201         case PIO_PERIPH_B:\r
202                 ul_sr = p_pio->PIO_ABCDSR[0];\r
203                 p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);\r
204 \r
205                 ul_sr = p_pio->PIO_ABCDSR[1];\r
206                 p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);\r
207                 break;\r
208 #if (!SAMG)\r
209         case PIO_PERIPH_C:\r
210                 ul_sr = p_pio->PIO_ABCDSR[0];\r
211                 p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);\r
212 \r
213                 ul_sr = p_pio->PIO_ABCDSR[1];\r
214                 p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);\r
215                 break;\r
216         case PIO_PERIPH_D:\r
217                 ul_sr = p_pio->PIO_ABCDSR[0];\r
218                 p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);\r
219 \r
220                 ul_sr = p_pio->PIO_ABCDSR[1];\r
221                 p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);\r
222                 break;\r
223 #endif\r
224                 /* Other types are invalid in this function */\r
225         case PIO_INPUT:\r
226         case PIO_OUTPUT_0:\r
227         case PIO_OUTPUT_1:\r
228         case PIO_NOT_A_PIN:\r
229                 return;\r
230         }\r
231 #elif (SAM3XA|| SAM3U)\r
232         switch (ul_type) {\r
233         case PIO_PERIPH_A:\r
234                 ul_sr = p_pio->PIO_ABSR;\r
235                 p_pio->PIO_ABSR &= (~ul_mask & ul_sr);\r
236                 break;\r
237 \r
238         case PIO_PERIPH_B:\r
239                 ul_sr = p_pio->PIO_ABSR;\r
240                 p_pio->PIO_ABSR = (ul_mask | ul_sr);\r
241                 break;\r
242 \r
243                 // other types are invalid in this function\r
244         case PIO_INPUT:\r
245         case PIO_OUTPUT_0:\r
246         case PIO_OUTPUT_1:\r
247         case PIO_NOT_A_PIN:\r
248                 return;\r
249         }\r
250 #else\r
251 #error "Unsupported device"\r
252 #endif\r
253 \r
254         /* Remove the pins from under the control of PIO */\r
255         p_pio->PIO_PDR = ul_mask;\r
256 }\r
257 \r
258 /**\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
261  * be enabled.\r
262  *\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
266  */\r
267 void pio_set_input(Pio *p_pio, const uint32_t ul_mask,\r
268                 const uint32_t ul_attribute)\r
269 {\r
270         pio_disable_interrupt(p_pio, ul_mask);\r
271         pio_pull_up(p_pio, ul_mask, ul_attribute & PIO_PULLUP);\r
272 \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
276         } else {\r
277                 p_pio->PIO_IFDR = ul_mask;\r
278         }\r
279 \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
284         } else {\r
285                 if (ul_attribute & PIO_DEBOUNCE) {\r
286                         p_pio->PIO_IFSCER = ul_mask;\r
287                 }\r
288         }\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
293         } else {\r
294                 if (ul_attribute & PIO_DEBOUNCE) {\r
295                         p_pio->PIO_DIFSR = ul_mask;\r
296                 }\r
297         }\r
298 #else\r
299 #error "Unsupported device"\r
300 #endif\r
301 \r
302         /* Configure pin as input */\r
303         p_pio->PIO_ODR = ul_mask;\r
304         p_pio->PIO_PER = ul_mask;\r
305 }\r
306 \r
307 /**\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
310  * on the pin(s).\r
311  *\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
316  * open-drain.\r
317  * \param ul_pull_up_enable Indicates if the pin shall have its pull-up\r
318  * activated.\r
319  */\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
324 {\r
325         pio_disable_interrupt(p_pio, ul_mask);\r
326         pio_pull_up(p_pio, ul_mask, ul_pull_up_enable);\r
327 \r
328         /* Enable multi-drive if necessary */\r
329         if (ul_multidrive_enable) {\r
330                 p_pio->PIO_MDER = ul_mask;\r
331         } else {\r
332                 p_pio->PIO_MDDR = ul_mask;\r
333         }\r
334 \r
335         /* Set default value */\r
336         if (ul_default_level) {\r
337                 p_pio->PIO_SODR = ul_mask;\r
338         } else {\r
339                 p_pio->PIO_CODR = ul_mask;\r
340         }\r
341 \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
345 }\r
346 \r
347 /**\r
348  * \brief Perform complete pin(s) configuration; general attributes and PIO init\r
349  * if necessary.\r
350  *\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
355  *\r
356  * \return Whether the pin(s) have been configured properly.\r
357  */\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
360 {\r
361         /* Configure pins */\r
362         switch (ul_type) {\r
363         case PIO_PERIPH_A:\r
364         case PIO_PERIPH_B:\r
365 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
366         case PIO_PERIPH_C:\r
367         case PIO_PERIPH_D:\r
368 #endif\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
371                 break;\r
372 \r
373         case PIO_INPUT:\r
374                 pio_set_input(p_pio, ul_mask, ul_attribute);\r
375                 break;\r
376 \r
377         case PIO_OUTPUT_0:\r
378         case PIO_OUTPUT_1:\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
382                 break;\r
383 \r
384         default:\r
385                 return 0;\r
386         }\r
387 \r
388         return 1;\r
389 }\r
390 \r
391 /**\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
395  *\r
396  * \param p_pio Pointer to a PIO instance.\r
397  * \param ul_mask Bitmask of one or more pin(s).\r
398  *\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
401  */\r
402 uint32_t pio_get_output_data_status(const Pio *p_pio,\r
403                 const uint32_t ul_mask)\r
404 {\r
405         if ((p_pio->PIO_ODSR & ul_mask) == 0) {\r
406                 return 0;\r
407         } else {\r
408                 return 1;\r
409         }\r
410 }\r
411 \r
412 /**\r
413  * \brief Configure PIO pin multi-driver.\r
414  *\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
418  * configured.\r
419  */\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
422 {\r
423         /* Enable the multi-driver if necessary */\r
424         if (ul_multi_driver_enable) {\r
425                 p_pio->PIO_MDER = ul_mask;\r
426         } else {\r
427                 p_pio->PIO_MDDR = ul_mask;\r
428         }\r
429 }\r
430 \r
431 /**\r
432  * \brief Get multi-driver status.\r
433  *\r
434  * \param p_pio Pointer to a PIO instance.\r
435  *\r
436  * \return The multi-driver mask value.\r
437  */\r
438 uint32_t pio_get_multi_driver_status(const Pio *p_pio)\r
439 {\r
440         return p_pio->PIO_MDSR;\r
441 }\r
442 \r
443 \r
444 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
445 /**\r
446  * \brief Configure PIO pin internal pull-down.\r
447  *\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
451  * be configured.\r
452  */\r
453 void pio_pull_down(Pio *p_pio, const uint32_t ul_mask,\r
454                 const uint32_t ul_pull_down_enable)\r
455 {\r
456         /* Enable the pull-down if necessary */\r
457         if (ul_pull_down_enable) {\r
458                 p_pio->PIO_PPDER = ul_mask;\r
459         } else {\r
460                 p_pio->PIO_PPDDR = ul_mask;\r
461         }\r
462 }\r
463 #endif\r
464 \r
465 /**\r
466  * \brief Enable PIO output write for synchronous data output.\r
467  *\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
470  */\r
471 void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask)\r
472 {\r
473         p_pio->PIO_OWER = ul_mask;\r
474 }\r
475 \r
476 /**\r
477  * \brief Disable PIO output write.\r
478  *\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
481  */\r
482 void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask)\r
483 {\r
484         p_pio->PIO_OWDR = ul_mask;\r
485 }\r
486 \r
487 /**\r
488  * \brief Read PIO output write status.\r
489  *\r
490  * \param p_pio Pointer to a PIO instance.\r
491  *\r
492  * \return The output write mask value.\r
493  */\r
494 uint32_t pio_get_output_write_status(const Pio *p_pio)\r
495 {\r
496         return p_pio->PIO_OWSR;\r
497 }\r
498 \r
499 /**\r
500  * \brief Synchronously write on output pins.\r
501  * \note Only bits unmasked by PIO_OWSR (Output Write Status Register) are\r
502  * written.\r
503  *\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
506  */\r
507 void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask)\r
508 {\r
509         p_pio->PIO_ODSR = ul_mask;\r
510 }\r
511 \r
512 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
513 /**\r
514  * \brief Configure PIO pin schmitt trigger. By default the Schmitt trigger is\r
515  * active.\r
516  * Disabling the Schmitt Trigger is requested when using the QTouch Library.\r
517  *\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
520  */\r
521 void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask)\r
522 {\r
523         p_pio->PIO_SCHMITT = ul_mask;\r
524 }\r
525 \r
526 /**\r
527  * \brief Get PIO pin schmitt trigger status.\r
528  *\r
529  * \param p_pio Pointer to a PIO instance.\r
530  *\r
531  * \return The schmitt trigger mask value.\r
532  */\r
533 uint32_t pio_get_schmitt_trigger(const Pio *p_pio)\r
534 {\r
535         return p_pio->PIO_SCHMITT;\r
536 }\r
537 #endif\r
538 \r
539 /**\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
543  *\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
547  */\r
548 void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask,\r
549                 const uint32_t ul_attr)\r
550 {\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
555 \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
561                 } else {\r
562                         /* Falling Edge or Low Level */\r
563                         p_pio->PIO_FELLSR = ul_mask;\r
564                 }\r
565 \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
569                         /* Edge select */\r
570                         p_pio->PIO_ESR = ul_mask;\r
571                 } else {\r
572                         /* Level select */\r
573                         p_pio->PIO_LSR = ul_mask;\r
574                 }\r
575         } else {\r
576                 /* Disable additional interrupt mode. */\r
577                 p_pio->PIO_AIMDR = ul_mask;\r
578         }\r
579 }\r
580 \r
581 /**\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
586  *\r
587  * \param p_pio Pointer to a PIO instance.\r
588  * \param ul_mask Interrupt sources bit map.\r
589  */\r
590 void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)\r
591 {\r
592         p_pio->PIO_ISR;\r
593         p_pio->PIO_IER = ul_mask;\r
594 }\r
595 \r
596 /**\r
597  * \brief Disable a given interrupt source, with no added side effects.\r
598  *\r
599  * \param p_pio Pointer to a PIO instance.\r
600  * \param ul_mask Interrupt sources bit map.\r
601  */\r
602 void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)\r
603 {\r
604         p_pio->PIO_IDR = ul_mask;\r
605 }\r
606 \r
607 /**\r
608  * \brief Read PIO interrupt status.\r
609  *\r
610  * \param p_pio Pointer to a PIO instance.\r
611  *\r
612  * \return The interrupt status mask value.\r
613  */\r
614 uint32_t pio_get_interrupt_status(const Pio *p_pio)\r
615 {\r
616         return p_pio->PIO_ISR;\r
617 }\r
618 \r
619 /**\r
620  * \brief Read PIO interrupt mask.\r
621  *\r
622  * \param p_pio Pointer to a PIO instance.\r
623  *\r
624  * \return The interrupt mask value.\r
625  */\r
626 uint32_t pio_get_interrupt_mask(const Pio *p_pio)\r
627 {\r
628         return p_pio->PIO_IMR;\r
629 }\r
630 \r
631 /**\r
632  * \brief Set additional interrupt mode.\r
633  *\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
637  */\r
638 void pio_set_additional_interrupt_mode(Pio *p_pio,\r
639                 const uint32_t ul_mask, const uint32_t ul_attribute)\r
640 {\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
645 \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
651                 } else {\r
652                         /* Falling Edge or Low Level */\r
653                         p_pio->PIO_FELLSR = ul_mask;\r
654                 }\r
655 \r
656                 /* Configures the type of event detection (Edge or Level) */\r
657                 if (ul_attribute & PIO_IT_EDGE) {\r
658                         /* Edge select */\r
659                         p_pio->PIO_ESR = ul_mask;\r
660                 } else {\r
661                         /* Level select */\r
662                         p_pio->PIO_LSR = ul_mask;\r
663                 }\r
664         } else {\r
665                 /* Disable additional interrupt mode */\r
666                 p_pio->PIO_AIMDR = ul_mask;\r
667         }\r
668 }\r
669 \r
670 #ifndef PIO_WPMR_WPKEY_PASSWD\r
671 #define PIO_WPMR_WPKEY_PASSWD    PIO_WPMR_WPKEY(0x50494FU)\r
672 #endif\r
673 \r
674 /**\r
675  * \brief Enable or disable write protect of PIO registers.\r
676  *\r
677  * \param p_pio Pointer to a PIO instance.\r
678  * \param ul_enable 1 to enable, 0 to disable.\r
679  */\r
680 void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable)\r
681 {\r
682         p_pio->PIO_WPMR = PIO_WPMR_WPKEY_PASSWD | (ul_enable & PIO_WPMR_WPEN);\r
683 }\r
684 \r
685 /**\r
686  * \brief Read write protect status.\r
687  *\r
688  * \param p_pio Pointer to a PIO instance.\r
689  *\r
690  * \return Return write protect status.\r
691  */\r
692 uint32_t pio_get_writeprotect_status(const Pio *p_pio)\r
693 {\r
694         return p_pio->PIO_WPSR;\r
695 }\r
696 \r
697 /**\r
698  * \brief Return the value of a pin.\r
699  *\r
700  * \param ul_pin The pin number.\r
701  *\r
702  * \return The pin value.\r
703  *\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
706  *       level.\r
707  * \note If pin is input: PIOx must be clocked to sample the signal.\r
708  *       See PMC driver.\r
709  */\r
710 uint32_t pio_get_pin_value(uint32_t ul_pin)\r
711 {\r
712         Pio *p_pio = pio_get_pin_group(ul_pin);\r
713 \r
714         return (p_pio->PIO_PDSR >> (ul_pin & 0x1F)) & 1;\r
715 }\r
716 \r
717 /**\r
718  * \brief Drive a GPIO pin to 1.\r
719  *\r
720  * \param ul_pin The pin index.\r
721  *\r
722  * \note The function \ref pio_configure_pin must be called beforehand.\r
723  */\r
724 void pio_set_pin_high(uint32_t ul_pin)\r
725 {\r
726         Pio *p_pio = pio_get_pin_group(ul_pin);\r
727 \r
728         /* Value to be driven on the I/O line: 1. */\r
729         p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);\r
730 }\r
731 \r
732 /**\r
733  * \brief Drive a GPIO pin to 0.\r
734  *\r
735  * \param ul_pin The pin index.\r
736  *\r
737  * \note The function \ref pio_configure_pin must be called before.\r
738  */\r
739 void pio_set_pin_low(uint32_t ul_pin)\r
740 {\r
741         Pio *p_pio = pio_get_pin_group(ul_pin);\r
742 \r
743         /* Value to be driven on the I/O line: 0. */\r
744         p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);\r
745 }\r
746 \r
747 /**\r
748  * \brief Toggle a GPIO pin.\r
749  *\r
750  * \param ul_pin The pin index.\r
751  *\r
752  * \note The function \ref pio_configure_pin must be called before.\r
753  */\r
754 void pio_toggle_pin(uint32_t ul_pin)\r
755 {\r
756         Pio *p_pio = pio_get_pin_group(ul_pin);\r
757 \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
761         } else {\r
762                 /* Value to be driven on the I/O line: 1. */\r
763                 p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);\r
764         }\r
765 }\r
766 \r
767 /**\r
768  * \brief Perform complete pin(s) configuration; general attributes and PIO init\r
769  * if necessary.\r
770  *\r
771  * \param ul_pin Bitmask of one or more pin(s) to configure.\r
772  * \param ul_flags Pins attributes.\r
773  *\r
774  * \return Whether the pin(s) have been configured properly.\r
775  */\r
776 uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags)\r
777 {\r
778         Pio *p_pio = pio_get_pin_group(ul_pin);\r
779 \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
786                 break;\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
791                 break;\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
797                 break;\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
802                 break;\r
803 #endif\r
804 \r
805         case PIO_TYPE_PIO_INPUT:\r
806                 pio_set_input(p_pio, (1 << (ul_pin & 0x1F)), ul_flags);\r
807                 break;\r
808 \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
816                 break;\r
817 \r
818         default:\r
819                 return 0;\r
820         }\r
821 \r
822         return 1;\r
823 }\r
824 \r
825 /**\r
826  * \brief Drive a GPIO port to 1.\r
827  *\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
830  */\r
831 void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask)\r
832 {\r
833         /* Value to be driven on the I/O line: 1. */\r
834         p_pio->PIO_SODR = ul_mask;\r
835 }\r
836 \r
837 /**\r
838  * \brief Drive a GPIO port to 0.\r
839  *\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
842  */\r
843 void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask)\r
844 {\r
845         /* Value to be driven on the I/O line: 0. */\r
846         p_pio->PIO_CODR = ul_mask;\r
847 }\r
848 \r
849 /**\r
850  * \brief Toggle a GPIO group.\r
851  *\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
854  */\r
855 void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask)\r
856 {\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
860         } else {\r
861                 /* Value to be driven on the I/O line: 1. */\r
862                 p_pio->PIO_SODR = ul_mask;\r
863         }\r
864 }\r
865 \r
866 /**\r
867  * \brief Perform complete pin(s) configuration; general attributes and PIO init\r
868  * if necessary.\r
869  *\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
873  *\r
874  * \return Whether the pin(s) have been configured properly.\r
875  */\r
876 uint32_t pio_configure_pin_group(Pio *p_pio,\r
877                 uint32_t ul_mask, const uint32_t ul_flags)\r
878 {\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
884                 break;\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
888                 break;\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
893                 break;\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
897                 break;\r
898 #endif\r
899 \r
900         case PIO_TYPE_PIO_INPUT:\r
901                 pio_set_input(p_pio, ul_mask, ul_flags);\r
902                 break;\r
903 \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
911                 break;\r
912 \r
913         default:\r
914                 return 0;\r
915         }\r
916 \r
917         return 1;\r
918 }\r
919 \r
920 /**\r
921  * \brief Enable interrupt for a GPIO pin.\r
922  *\r
923  * \param ul_pin The pin index.\r
924  *\r
925  * \note The function \ref gpio_configure_pin must be called before.\r
926  */\r
927 void pio_enable_pin_interrupt(uint32_t ul_pin)\r
928 {\r
929         Pio *p_pio = pio_get_pin_group(ul_pin);\r
930 \r
931         p_pio->PIO_IER = 1 << (ul_pin & 0x1F);\r
932 }\r
933 \r
934 \r
935 /**\r
936  * \brief Disable interrupt for a GPIO pin.\r
937  *\r
938  * \param ul_pin The pin index.\r
939  *\r
940  * \note The function \ref gpio_configure_pin must be called before.\r
941  */\r
942 void pio_disable_pin_interrupt(uint32_t ul_pin)\r
943 {\r
944         Pio *p_pio = pio_get_pin_group(ul_pin);\r
945 \r
946         p_pio->PIO_IDR = 1 << (ul_pin & 0x1F);\r
947 }\r
948 \r
949 \r
950 /**\r
951  * \brief Return GPIO port for a GPIO pin.\r
952  *\r
953  * \param ul_pin The pin index.\r
954  *\r
955  * \return Pointer to \ref Pio struct for GPIO port.\r
956  */\r
957 Pio *pio_get_pin_group(uint32_t ul_pin)\r
958 {\r
959         Pio *p_pio;\r
960 \r
961 #if (SAM4C || SAM4CP)\r
962 #  ifdef ID_PIOD\r
963         if (ul_pin > PIO_PC9_IDX) {\r
964                 p_pio = PIOD;\r
965         } else if (ul_pin > PIO_PB31_IDX) {\r
966 #  else\r
967         if  (ul_pin > PIO_PB31_IDX) {\r
968 #  endif\r
969                 p_pio = PIOC;\r
970         } else {\r
971                 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));\r
972         }\r
973 #elif (SAM4CM)\r
974         if (ul_pin > PIO_PB21_IDX) {\r
975                 p_pio = PIOC;\r
976         } else {\r
977                 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));\r
978         }\r
979 #else\r
980         p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));\r
981 #endif\r
982         return p_pio;\r
983 }\r
984 \r
985 /**\r
986  * \brief Return GPIO port peripheral ID for a GPIO pin.\r
987  *\r
988  * \param ul_pin The pin index.\r
989  *\r
990  * \return GPIO port peripheral ID.\r
991  */\r
992 uint32_t pio_get_pin_group_id(uint32_t ul_pin)\r
993 {\r
994         uint32_t ul_id;\r
995 \r
996 #if (SAM4C || SAM4CP)\r
997 #  ifdef ID_PIOD\r
998         if (ul_pin > PIO_PC9_IDX) {\r
999                 ul_id = ID_PIOD;\r
1000         } else if (ul_pin > PIO_PB31_IDX) {\r
1001 #  else\r
1002         if (ul_pin > PIO_PB31_IDX) {\r
1003 #  endif\r
1004                 ul_id = ID_PIOC;\r
1005         } else {\r
1006                 ul_id = ID_PIOA + (ul_pin >> 5);\r
1007         }\r
1008 #elif (SAM4CM)\r
1009         if (ul_pin > PIO_PB21_IDX) {\r
1010                 ul_id = ID_PIOC;\r
1011         } else {\r
1012                 ul_id = ID_PIOA + (ul_pin >> 5);\r
1013         }\r
1014 #elif (SAMV70 || SAMV71 || SAME70 || SAMS70)\r
1015         if (ul_pin > PIO_PC31_IDX) {\r
1016                 if(ul_pin > PIO_PD31_IDX){\r
1017                         ul_id = ID_PIOE;\r
1018                         } else {\r
1019                         ul_id = ID_PIOD;\r
1020                 }\r
1021         } else {\r
1022                 ul_id = ID_PIOA + (ul_pin >> 5);\r
1023         }\r
1024 #else\r
1025         ul_id = ID_PIOA + (ul_pin >> 5);\r
1026 #endif\r
1027         return ul_id;\r
1028 }\r
1029 \r
1030 \r
1031 /**\r
1032  * \brief Return GPIO port pin mask for a GPIO pin.\r
1033  *\r
1034  * \param ul_pin The pin index.\r
1035  *\r
1036  * \return GPIO port pin mask.\r
1037  */\r
1038 uint32_t pio_get_pin_group_mask(uint32_t ul_pin)\r
1039 {\r
1040         uint32_t ul_mask = 1 << (ul_pin & 0x1F);\r
1041         return ul_mask;\r
1042 }\r
1043 \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
1047 \r
1048 /**\r
1049  * \brief Configure PIO capture mode.\r
1050  * \note PIO capture mode will be disabled automatically.\r
1051  *\r
1052  * \param p_pio Pointer to a PIO instance.\r
1053  * \param ul_mode Bitmask of one or more modes.\r
1054  */\r
1055 void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode)\r
1056 {\r
1057         ul_mode &= (~PIO_PCMR_PCEN); /* Disable PIO capture mode */\r
1058         p_pio->PIO_PCMR = ul_mode;\r
1059 }\r
1060 \r
1061 /**\r
1062  * \brief Enable PIO capture mode.\r
1063  *\r
1064  * \param p_pio Pointer to a PIO instance.\r
1065  */\r
1066 void pio_capture_enable(Pio *p_pio)\r
1067 {\r
1068         p_pio->PIO_PCMR |= PIO_PCMR_PCEN;\r
1069         pio_capture_enable_flag = true;\r
1070 }\r
1071 \r
1072 /**\r
1073  * \brief Disable PIO capture mode.\r
1074  *\r
1075  * \param p_pio Pointer to a PIO instance.\r
1076  */\r
1077 void pio_capture_disable(Pio *p_pio)\r
1078 {\r
1079         p_pio->PIO_PCMR &= (~PIO_PCMR_PCEN);\r
1080         pio_capture_enable_flag = false;\r
1081 }\r
1082 \r
1083 /**\r
1084  * \brief Read from Capture Reception Holding Register.\r
1085  * \note Data presence should be tested before any read attempt.\r
1086  *\r
1087  * \param p_pio Pointer to a PIO instance.\r
1088  * \param pul_data Pointer to store the data.\r
1089  *\r
1090  * \retval 0 Success.\r
1091  * \retval 1 I/O Failure, Capture data is not ready.\r
1092  */\r
1093 uint32_t pio_capture_read(const Pio *p_pio, uint32_t *pul_data)\r
1094 {\r
1095         /* Check if the data is ready */\r
1096         if ((p_pio->PIO_PCISR & PIO_PCISR_DRDY) == 0) {\r
1097                 return 1;\r
1098         }\r
1099 \r
1100         /* Read data */\r
1101         *pul_data = p_pio->PIO_PCRHR;\r
1102         return 0;\r
1103 }\r
1104 \r
1105 /**\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
1109  *\r
1110  * \param p_pio Pointer to a PIO instance.\r
1111  * \param ul_mask Interrupt sources bit map.\r
1112  */\r
1113 void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)\r
1114 {\r
1115         p_pio->PIO_PCISR;\r
1116         p_pio->PIO_PCIER = ul_mask;\r
1117 }\r
1118 \r
1119 /**\r
1120  * \brief Disable a given interrupt source of PIO capture.\r
1121  *\r
1122  * \param p_pio Pointer to a PIO instance.\r
1123  * \param ul_mask Interrupt sources bit map.\r
1124  */\r
1125 void pio_capture_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)\r
1126 {\r
1127         p_pio->PIO_PCIDR = ul_mask;\r
1128 }\r
1129 \r
1130 /**\r
1131  * \brief Read PIO interrupt status of PIO capture.\r
1132  *\r
1133  * \param p_pio Pointer to a PIO instance.\r
1134  *\r
1135  * \return The interrupt status mask value.\r
1136  */\r
1137 uint32_t pio_capture_get_interrupt_status(const Pio *p_pio)\r
1138 {\r
1139         return p_pio->PIO_PCISR;\r
1140 }\r
1141 \r
1142 /**\r
1143  * \brief Read PIO interrupt mask of PIO capture.\r
1144  *\r
1145  * \param p_pio Pointer to a PIO instance.\r
1146  *\r
1147  * \return The interrupt mask value.\r
1148  */\r
1149 uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio)\r
1150 {\r
1151         return p_pio->PIO_PCIMR;\r
1152 }\r
1153 #if !(SAMV71 || SAMV70 || SAME70 || SAMS70)\r
1154 /**\r
1155  * \brief Get PDC registers base address.\r
1156  *\r
1157  * \param p_pio Pointer to an PIO peripheral.\r
1158  *\r
1159  * \return PIOA PDC register base address.\r
1160  */\r
1161 Pdc *pio_capture_get_pdc_base(const Pio *p_pio)\r
1162 {\r
1163         UNUSED(p_pio); /* Stop warning */\r
1164         return PDC_PIOA;\r
1165 }\r
1166 #endif\r
1167 #endif\r
1168 \r
1169 #if (SAM4C || SAM4CP || SAM4CM || SAMG55)\r
1170 /**\r
1171  * \brief Set PIO IO drive.\r
1172  *\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
1176  */\r
1177 void pio_set_io_drive(Pio *p_pio, uint32_t ul_line,\r
1178                 enum pio_io_drive_mode mode)\r
1179 {\r
1180         p_pio->PIO_DRIVER &= ~(1 << ul_line);\r
1181         p_pio->PIO_DRIVER |= mode << ul_line;\r
1182 }\r
1183 #endif\r
1184 \r
1185 #if (SAMV71 || SAMV70 || SAME70 || SAMS70)\r
1186 /**\r
1187  * \brief Enable PIO keypad controller.\r
1188  *\r
1189  * \param p_pio Pointer to a PIO instance.\r
1190  */\r
1191 void pio_keypad_enable(Pio *p_pio)\r
1192 {\r
1193         p_pio->PIO_KER |= PIO_KER_KCE;\r
1194 }\r
1195 \r
1196 /**\r
1197  * \brief Disable PIO keypad controller.\r
1198  *\r
1199  * \param p_pio Pointer to a PIO instance.\r
1200  */\r
1201 void pio_keypad_disable(Pio *p_pio)\r
1202 {\r
1203         p_pio->PIO_KER &= (~PIO_KER_KCE);\r
1204 }\r
1205 \r
1206 /**\r
1207  * \brief Set PIO keypad controller row number.\r
1208  *\r
1209  * \param p_pio Pointer to a PIO instance.\r
1210  * \param num   Number of row of the keypad matrix.\r
1211  */\r
1212 void pio_keypad_set_row_num(Pio *p_pio, uint8_t num)\r
1213 {\r
1214         p_pio->PIO_KRCR &= (~PIO_KRCR_NBR_Msk);\r
1215         p_pio->PIO_KRCR |= PIO_KRCR_NBR(num);\r
1216 }\r
1217 \r
1218 /**\r
1219  * \brief Get PIO keypad controller row number.\r
1220  *\r
1221  * \param p_pio Pointer to a PIO instance.\r
1222  * \r
1223  * \return Number of row of the keypad matrix.\r
1224  */\r
1225 uint8_t pio_keypad_get_row_num(const Pio *p_pio)\r
1226 {\r
1227         return ((p_pio->PIO_KRCR & PIO_KRCR_NBR_Msk) >> PIO_KRCR_NBR_Pos);\r
1228 }\r
1229 \r
1230 /**\r
1231  * \brief Set PIO keypad controller column number.\r
1232  *\r
1233  * \param p_pio Pointer to a PIO instance.\r
1234  * \param num   Number of column of the keypad matrix.\r
1235  */\r
1236 void pio_keypad_set_column_num(Pio *p_pio, uint8_t num)\r
1237 {\r
1238         p_pio->PIO_KRCR &= (~PIO_KRCR_NBC_Msk);\r
1239         p_pio->PIO_KRCR |= PIO_KRCR_NBC(num);\r
1240 }\r
1241 \r
1242 /**\r
1243  * \brief Get PIO keypad controller column number.\r
1244  *\r
1245  * \param p_pio Pointer to a PIO instance.\r
1246  * \r
1247  * \return Number of column of the keypad matrix.\r
1248  */\r
1249 uint8_t pio_keypad_get_column_num(const Pio *p_pio)\r
1250 {\r
1251         return ((p_pio->PIO_KRCR & PIO_KRCR_NBC_Msk) >> PIO_KRCR_NBC_Pos);\r
1252 }\r
1253 \r
1254 /**\r
1255  * \brief Set PIO keypad matrix debouncing value.\r
1256  *\r
1257  * \param p_pio Pointer to a PIO instance.\r
1258  * \param num   Number of debouncing value.\r
1259  */\r
1260 void pio_keypad_set_debouncing_value(Pio *p_pio, uint16_t value)\r
1261 {\r
1262         p_pio->PIO_KDR = PIO_KDR_DBC(value);\r
1263 }\r
1264 \r
1265 /**\r
1266  * \brief Get PIO keypad matrix debouncing value.\r
1267  *\r
1268  * \param p_pio Pointer to a PIO instance.\r
1269  *\r
1270  * \return The keypad debouncing value.\r
1271  */\r
1272 uint16_t pio_keypad_get_debouncing_value(const Pio *p_pio)\r
1273 {\r
1274         return ((p_pio->PIO_KDR & PIO_KDR_DBC_Msk) >> PIO_KDR_DBC_Pos);\r
1275 }\r
1276 \r
1277 /**\r
1278  * \brief Enable the interrupt source of PIO keypad.\r
1279  *\r
1280  * \param p_pio Pointer to a PIO instance.\r
1281  * \param ul_mask Interrupt sources bit map.\r
1282  */\r
1283 void pio_keypad_enable_interrupt(Pio *p_pio, uint32_t ul_mask)\r
1284 {\r
1285         p_pio->PIO_KIER = ul_mask;\r
1286 }\r
1287 \r
1288 /**\r
1289  * \brief Disable the interrupt source of PIO keypad.\r
1290  *\r
1291  * \param p_pio Pointer to a PIO instance.\r
1292  * \param ul_mask Interrupt sources bit map.\r
1293  */\r
1294 void pio_keypad_disable_interrupt(Pio *p_pio, uint32_t ul_mask)\r
1295 {\r
1296         p_pio->PIO_KIDR = ul_mask;\r
1297 }\r
1298 \r
1299 /**\r
1300  * \brief Get interrupt mask of PIO keypad.\r
1301  *\r
1302  * \param p_pio Pointer to a PIO instance.\r
1303  *\r
1304  * \return The interrupt mask value.\r
1305  */\r
1306 uint32_t pio_keypad_get_interrupt_mask(const Pio *p_pio)\r
1307 {\r
1308         return p_pio->PIO_KIMR;\r
1309 }\r
1310 \r
1311 /**\r
1312  * \brief Get key press status of PIO keypad.\r
1313  *\r
1314  * \param p_pio Pointer to a PIO instance.\r
1315  *\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
1319  */\r
1320 uint32_t pio_keypad_get_press_status(const Pio *p_pio)\r
1321 {\r
1322         if (p_pio->PIO_KSR & PIO_KSR_KPR) {\r
1323                 return 1;\r
1324         } else {\r
1325                 return 0;\r
1326         }\r
1327 }\r
1328 \r
1329 /**\r
1330  * \brief Get key release status of PIO keypad.\r
1331  *\r
1332  * \param p_pio Pointer to a PIO instance.\r
1333  *\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
1337  */\r
1338 uint32_t pio_keypad_get_release_status(const Pio *p_pio)\r
1339 {\r
1340         if (p_pio->PIO_KSR & PIO_KSR_KRL) {\r
1341                 return 1;\r
1342         } else {\r
1343                 return 0;\r
1344         }\r
1345 }\r
1346 \r
1347 /**\r
1348  * \brief Get simultaneous key press number of PIO keypad.\r
1349  *\r
1350  * \param p_pio Pointer to a PIO instance.\r
1351  *\r
1352  * \return The number of simultaneous key press.\r
1353  */\r
1354 uint8_t pio_keypad_get_simult_press_num(const Pio *p_pio)\r
1355 {\r
1356         return ((p_pio->PIO_KSR & PIO_KSR_NBKPR_Msk) >> PIO_KSR_NBKPR_Pos);\r
1357 }\r
1358 \r
1359 /**\r
1360  * \brief Get simultaneous key release number of PIO keypad.\r
1361  *\r
1362  * \param p_pio Pointer to a PIO instance.\r
1363  *\r
1364  * \return The number of simultaneous key release.\r
1365  */\r
1366 uint8_t pio_keypad_get_simult_release_num(const Pio *p_pio)\r
1367 {\r
1368         return ((p_pio->PIO_KSR & PIO_KSR_NBKRL_Msk) >> PIO_KSR_NBKRL_Pos);\r
1369 }\r
1370 \r
1371 /**\r
1372  * \brief Get detected key press row index of PIO keypad.\r
1373  *\r
1374  * \param p_pio Pointer to a PIO instance.\r
1375  * \param queue The queue of key press row\r
1376  *\r
1377  * \return The index of detected key press row.\r
1378  */\r
1379 uint8_t pio_keypad_get_press_row_index(const Pio *p_pio, uint8_t queue)\r
1380 {\r
1381         switch (queue) {\r
1382         case 0:\r
1383                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0ROW_Msk) >> PIO_KKPR_KEY0ROW_Pos);\r
1384         case 1:\r
1385                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1ROW_Msk) >> PIO_KKPR_KEY1ROW_Pos);\r
1386         case 2:\r
1387                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2ROW_Msk) >> PIO_KKPR_KEY2ROW_Pos);\r
1388         case 3:\r
1389                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3ROW_Msk) >> PIO_KKPR_KEY3ROW_Pos);\r
1390         default:\r
1391                 return 0;\r
1392         }\r
1393 }\r
1394 \r
1395 /**\r
1396  * \brief Get detected key press column index of PIO keypad.\r
1397  *\r
1398  * \param p_pio Pointer to a PIO instance.\r
1399  * \param queue The queue of key press column\r
1400  *\r
1401  * \return The index of detected key press column.\r
1402  */\r
1403 uint8_t pio_keypad_get_press_column_index(const Pio *p_pio, uint8_t queue)\r
1404 {\r
1405         switch (queue) {\r
1406         case 0:\r
1407                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0COL_Msk) >> PIO_KKPR_KEY0COL_Pos);\r
1408         case 1:\r
1409                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1COL_Msk) >> PIO_KKPR_KEY1COL_Pos);\r
1410         case 2:\r
1411                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2COL_Msk) >> PIO_KKPR_KEY2COL_Pos);\r
1412         case 3:\r
1413                 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3COL_Msk) >> PIO_KKPR_KEY3COL_Pos);\r
1414         default:\r
1415                 return 0;\r
1416         }\r
1417 }\r
1418 \r
1419 /**\r
1420  * \brief Get detected key release row index of PIO keypad.\r
1421  *\r
1422  * \param p_pio Pointer to a PIO instance.\r
1423  * \param queue The queue of key release row\r
1424  *\r
1425  * \return The index of detected key release row.\r
1426  */\r
1427 uint8_t pio_keypad_get_release_row_index(const Pio *p_pio, uint8_t queue)\r
1428 {\r
1429         switch (queue) {\r
1430         case 0:\r
1431                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0ROW_Msk) >> PIO_KKRR_KEY0ROW_Pos);\r
1432         case 1:\r
1433                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1ROW_Msk) >> PIO_KKRR_KEY1ROW_Pos);\r
1434         case 2:\r
1435                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2ROW_Msk) >> PIO_KKRR_KEY2ROW_Pos);\r
1436         case 3:\r
1437                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3ROW_Msk) >> PIO_KKRR_KEY3ROW_Pos);\r
1438         default:\r
1439                 return 0;\r
1440         }\r
1441 }\r
1442 \r
1443 /**\r
1444  * \brief Get detected key release column index of PIO keypad.\r
1445  *\r
1446  * \param p_pio Pointer to a PIO instance.\r
1447  * \param queue The queue of key release column\r
1448  *\r
1449  * \return The index of detected key release column.\r
1450  */\r
1451 uint8_t pio_keypad_get_release_column_index(const Pio *p_pio, uint8_t queue)\r
1452 {\r
1453         switch (queue) {\r
1454         case 0:\r
1455                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0COL_Msk) >> PIO_KKRR_KEY0COL_Pos);\r
1456         case 1:\r
1457                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1COL_Msk) >> PIO_KKRR_KEY1COL_Pos);\r
1458         case 2:\r
1459                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2COL_Msk) >> PIO_KKRR_KEY2COL_Pos);\r
1460         case 3:\r
1461                 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3COL_Msk) >> PIO_KKRR_KEY3COL_Pos);\r
1462         default:\r
1463                 return 0;\r
1464         }\r
1465 }\r
1466 \r
1467 #endif\r
1468 \r
1469 //@}\r
1470 \r