pio.c
Go to the documentation of this file.
1 
33 /*
34  * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
35  */
36 
37 #include "pio.h"
38 
39 #ifndef PIO_WPMR_WPKEY_PASSWD
40 # define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494Fu)
41 #endif
42 
56 #ifndef FREQ_SLOW_CLOCK_EXT
57 /* External slow clock frequency (hz) */
58 #define FREQ_SLOW_CLOCK_EXT 32768
59 #endif
60 
69 void pio_pull_up(Pio *p_pio, const uint32_t ul_mask,
70  const uint32_t ul_pull_up_enable)
71 {
72  /* Enable the pull-up(s) if necessary */
73  if (ul_pull_up_enable) {
74  p_pio->PIO_PUER = ul_mask;
75  } else {
76  p_pio->PIO_PUDR = ul_mask;
77  }
78 }
79 
87 void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask,
88  const uint32_t ul_cut_off)
89 {
90 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
91  /* Set Debouncing, 0 bit field no effect */
92  p_pio->PIO_IFSCER = ul_mask;
93 #elif (SAM3XA || SAM3U)
94  /* Set Debouncing, 0 bit field no effect */
95  p_pio->PIO_DIFSR = ul_mask;
96 #else
97 #error "Unsupported device"
98 #endif
99 
100  /*
101  * The debouncing filter can filter a pulse of less than 1/2 Period of a
102  * programmable Divided Slow Clock:
103  * Tdiv_slclk = ((DIV+1)*2).Tslow_clock
104  */
106  (2 * (ul_cut_off))) - 1);
107 }
108 
117 void pio_set(Pio *p_pio, const uint32_t ul_mask)
118 {
119  p_pio->PIO_SODR = ul_mask;
120 }
121 
130 void pio_clear(Pio *p_pio, const uint32_t ul_mask)
131 {
132  p_pio->PIO_CODR = ul_mask;
133 }
134 
148 uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type,
149  const uint32_t ul_mask)
150 {
151  uint32_t ul_reg;
152 
153  if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) {
154  ul_reg = p_pio->PIO_ODSR;
155  } else {
156  ul_reg = p_pio->PIO_PDSR;
157  }
158 
159  if ((ul_reg & ul_mask) == 0) {
160  return 0;
161  } else {
162  return 1;
163  }
164 }
165 
174 void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type,
175  const uint32_t ul_mask)
176 {
177  uint32_t ul_sr;
178 
179  /* Disable interrupts on the pin(s) */
180  p_pio->PIO_IDR = ul_mask;
181 
182 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
183  switch (ul_type) {
184  case PIO_PERIPH_A:
185  ul_sr = p_pio->PIO_ABCDSR[0];
186  p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);
187 
188  ul_sr = p_pio->PIO_ABCDSR[1];
189  p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);
190  break;
191  case PIO_PERIPH_B:
192  ul_sr = p_pio->PIO_ABCDSR[0];
193  p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);
194 
195  ul_sr = p_pio->PIO_ABCDSR[1];
196  p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr);
197  break;
198 #if (!SAMG)
199  case PIO_PERIPH_C:
200  ul_sr = p_pio->PIO_ABCDSR[0];
201  p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr);
202 
203  ul_sr = p_pio->PIO_ABCDSR[1];
204  p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);
205  break;
206  case PIO_PERIPH_D:
207  ul_sr = p_pio->PIO_ABCDSR[0];
208  p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr);
209 
210  ul_sr = p_pio->PIO_ABCDSR[1];
211  p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr);
212  break;
213 #endif
214  /* Other types are invalid in this function */
215  case PIO_INPUT:
216  case PIO_OUTPUT_0:
217  case PIO_OUTPUT_1:
218  case PIO_NOT_A_PIN:
219  return;
220  }
221 #elif (SAM3XA|| SAM3U)
222  switch (ul_type) {
223  case PIO_PERIPH_A:
224  ul_sr = p_pio->PIO_ABSR;
225  p_pio->PIO_ABSR &= (~ul_mask & ul_sr);
226  break;
227 
228  case PIO_PERIPH_B:
229  ul_sr = p_pio->PIO_ABSR;
230  p_pio->PIO_ABSR = (ul_mask | ul_sr);
231  break;
232 
233  // other types are invalid in this function
234  case PIO_INPUT:
235  case PIO_OUTPUT_0:
236  case PIO_OUTPUT_1:
237  case PIO_NOT_A_PIN:
238  return;
239  }
240 #else
241 #error "Unsupported device"
242 #endif
243 
244  /* Remove the pins from under the control of PIO */
245  p_pio->PIO_PDR = ul_mask;
246 }
247 
257 void pio_set_input(Pio *p_pio, const uint32_t ul_mask,
258  const uint32_t ul_attribute)
259 {
260  pio_disable_interrupt(p_pio, ul_mask);
261  pio_pull_up(p_pio, ul_mask, ul_attribute & PIO_PULLUP);
262 
263  /* Enable Input Filter if necessary */
264  if (ul_attribute & (PIO_DEGLITCH | PIO_DEBOUNCE)) {
265  p_pio->PIO_IFER = ul_mask;
266  } else {
267  p_pio->PIO_IFDR = ul_mask;
268  }
269 
270 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
271  /* Enable de-glitch or de-bounce if necessary */
272  if (ul_attribute & PIO_DEGLITCH) {
273  p_pio->PIO_IFSCDR = ul_mask;
274  } else {
275  if (ul_attribute & PIO_DEBOUNCE) {
276  p_pio->PIO_IFSCER = ul_mask;
277  }
278  }
279 #elif (SAM3XA|| SAM3U)
280  /* Enable de-glitch or de-bounce if necessary */
281  if (ul_attribute & PIO_DEGLITCH) {
282  p_pio->PIO_SCIFSR = ul_mask;
283  } else {
284  if (ul_attribute & PIO_DEBOUNCE) {
285  p_pio->PIO_DIFSR = ul_mask;
286  }
287  }
288 #else
289 #error "Unsupported device"
290 #endif
291 
292  /* Configure pin as input */
293  p_pio->PIO_ODR = ul_mask;
294  p_pio->PIO_PER = ul_mask;
295 }
296 
310 void pio_set_output(Pio *p_pio, const uint32_t ul_mask,
311  const uint32_t ul_default_level,
312  const uint32_t ul_multidrive_enable,
313  const uint32_t ul_pull_up_enable)
314 {
315  pio_disable_interrupt(p_pio, ul_mask);
316  pio_pull_up(p_pio, ul_mask, ul_pull_up_enable);
317 
318  /* Enable multi-drive if necessary */
319  if (ul_multidrive_enable) {
320  p_pio->PIO_MDER = ul_mask;
321  } else {
322  p_pio->PIO_MDDR = ul_mask;
323  }
324 
325  /* Set default value */
326  if (ul_default_level) {
327  p_pio->PIO_SODR = ul_mask;
328  } else {
329  p_pio->PIO_CODR = ul_mask;
330  }
331 
332  /* Configure pin(s) as output(s) */
333  p_pio->PIO_OER = ul_mask;
334  p_pio->PIO_PER = ul_mask;
335 }
336 
348 uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type,
349  const uint32_t ul_mask, const uint32_t ul_attribute)
350 {
351  /* Configure pins */
352  switch (ul_type) {
353  case PIO_PERIPH_A:
354  case PIO_PERIPH_B:
355 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
356  case PIO_PERIPH_C:
357  case PIO_PERIPH_D:
358 #endif
359  pio_set_peripheral(p_pio, ul_type, ul_mask);
360  pio_pull_up(p_pio, ul_mask, (ul_attribute & PIO_PULLUP));
361  break;
362 
363  case PIO_INPUT:
364  pio_set_input(p_pio, ul_mask, ul_attribute);
365  break;
366 
367  case PIO_OUTPUT_0:
368  case PIO_OUTPUT_1:
369  pio_set_output(p_pio, ul_mask, (ul_type == PIO_OUTPUT_1),
370  (ul_attribute & PIO_OPENDRAIN) ? 1 : 0,
371  (ul_attribute & PIO_PULLUP) ? 1 : 0);
372  break;
373 
374  default:
375  return 0;
376  }
377 
378  return 1;
379 }
380 
392 uint32_t pio_get_output_data_status(const Pio *p_pio,
393  const uint32_t ul_mask)
394 {
395  if ((p_pio->PIO_ODSR & ul_mask) == 0) {
396  return 0;
397  } else {
398  return 1;
399  }
400 }
401 
410 void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask,
411  const uint32_t ul_multi_driver_enable)
412 {
413  /* Enable the multi-driver if necessary */
414  if (ul_multi_driver_enable) {
415  p_pio->PIO_MDER = ul_mask;
416  } else {
417  p_pio->PIO_MDDR = ul_mask;
418  }
419 }
420 
428 uint32_t pio_get_multi_driver_status(const Pio *p_pio)
429 {
430  return p_pio->PIO_MDSR;
431 }
432 
433 
434 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
435 
443 void pio_pull_down(Pio *p_pio, const uint32_t ul_mask,
444  const uint32_t ul_pull_down_enable)
445 {
446  /* Enable the pull-down if necessary */
447  if (ul_pull_down_enable) {
448  p_pio->PIO_PPDER = ul_mask;
449  } else {
450  p_pio->PIO_PPDDR = ul_mask;
451  }
452 }
453 #endif
454 
461 void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask)
462 {
463  p_pio->PIO_OWER = ul_mask;
464 }
465 
472 void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask)
473 {
474  p_pio->PIO_OWDR = ul_mask;
475 }
476 
484 uint32_t pio_get_output_write_status(const Pio *p_pio)
485 {
486  return p_pio->PIO_OWSR;
487 }
488 
497 void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask)
498 {
499  p_pio->PIO_ODSR = ul_mask;
500 }
501 
502 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
503 
511 void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask)
512 {
513  p_pio->PIO_SCHMITT = ul_mask;
514 }
515 
523 uint32_t pio_get_schmitt_trigger(const Pio *p_pio)
524 {
525  return p_pio->PIO_SCHMITT;
526 }
527 #endif
528 
538 void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask,
539  const uint32_t ul_attr)
540 {
541  /* Configure additional interrupt mode registers. */
542  if (ul_attr & PIO_IT_AIME) {
543  /* Enable additional interrupt mode. */
544  p_pio->PIO_AIMER = ul_mask;
545 
546  /* If bit field of the selected pin is 1, set as
547  Rising Edge/High level detection event. */
548  if (ul_attr & PIO_IT_RE_OR_HL) {
549  /* Rising Edge or High Level */
550  p_pio->PIO_REHLSR = ul_mask;
551  } else {
552  /* Falling Edge or Low Level */
553  p_pio->PIO_FELLSR = ul_mask;
554  }
555 
556  /* If bit field of the selected pin is 1, set as
557  edge detection source. */
558  if (ul_attr & PIO_IT_EDGE) {
559  /* Edge select */
560  p_pio->PIO_ESR = ul_mask;
561  } else {
562  /* Level select */
563  p_pio->PIO_LSR = ul_mask;
564  }
565  } else {
566  /* Disable additional interrupt mode. */
567  p_pio->PIO_AIMDR = ul_mask;
568  }
569 }
570 
578 void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
579 {
580  p_pio->PIO_IER = ul_mask;
581 }
582 
589 void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
590 {
591  p_pio->PIO_IDR = ul_mask;
592 }
593 
601 uint32_t pio_get_interrupt_status(const Pio *p_pio)
602 {
603  return p_pio->PIO_ISR;
604 }
605 
613 uint32_t pio_get_interrupt_mask(const Pio *p_pio)
614 {
615  return p_pio->PIO_IMR;
616 }
617 
626  const uint32_t ul_mask, const uint32_t ul_attribute)
627 {
628  /* Enables additional interrupt mode if needed */
629  if (ul_attribute & PIO_IT_AIME) {
630  /* Enables additional interrupt mode */
631  p_pio->PIO_AIMER = ul_mask;
632 
633  /* Configures the Polarity of the event detection */
634  /* (Rising/Falling Edge or High/Low Level) */
635  if (ul_attribute & PIO_IT_RE_OR_HL) {
636  /* Rising Edge or High Level */
637  p_pio->PIO_REHLSR = ul_mask;
638  } else {
639  /* Falling Edge or Low Level */
640  p_pio->PIO_FELLSR = ul_mask;
641  }
642 
643  /* Configures the type of event detection (Edge or Level) */
644  if (ul_attribute & PIO_IT_EDGE) {
645  /* Edge select */
646  p_pio->PIO_ESR = ul_mask;
647  } else {
648  /* Level select */
649  p_pio->PIO_LSR = ul_mask;
650  }
651  } else {
652  /* Disable additional interrupt mode */
653  p_pio->PIO_AIMDR = ul_mask;
654  }
655 }
656 
657 #ifndef PIO_WPMR_WPKEY_PASSWD
658 #define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494FU)
659 #endif
660 
667 void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable)
668 {
669  p_pio->PIO_WPMR = PIO_WPMR_WPKEY_PASSWD | (ul_enable & PIO_WPMR_WPEN);
670 }
671 
679 uint32_t pio_get_writeprotect_status(const Pio *p_pio)
680 {
681  return p_pio->PIO_WPSR;
682 }
683 
697 uint32_t pio_get_pin_value(uint32_t ul_pin)
698 {
699  Pio *p_pio = pio_get_pin_group(ul_pin);
700 
701  return (p_pio->PIO_PDSR >> (ul_pin & 0x1F)) & 1;
702 }
703 
711 void pio_set_pin_high(uint32_t ul_pin)
712 {
713  Pio *p_pio = pio_get_pin_group(ul_pin);
714 
715  /* Value to be driven on the I/O line: 1. */
716  p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
717 }
718 
726 void pio_set_pin_low(uint32_t ul_pin)
727 {
728  Pio *p_pio = pio_get_pin_group(ul_pin);
729 
730  /* Value to be driven on the I/O line: 0. */
731  p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);
732 }
733 
741 void pio_toggle_pin(uint32_t ul_pin)
742 {
743  Pio *p_pio = pio_get_pin_group(ul_pin);
744 
745  if (p_pio->PIO_ODSR & (1 << (ul_pin & 0x1F))) {
746  /* Value to be driven on the I/O line: 0. */
747  p_pio->PIO_CODR = 1 << (ul_pin & 0x1F);
748  } else {
749  /* Value to be driven on the I/O line: 1. */
750  p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
751  }
752 }
753 
763 uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags)
764 {
765  Pio *p_pio = pio_get_pin_group(ul_pin);
766 
767  /* Configure pins */
768  switch (ul_flags & PIO_TYPE_Msk) {
770  pio_set_peripheral(p_pio, PIO_PERIPH_A, (1 << (ul_pin & 0x1F)));
771  pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
772  (ul_flags & PIO_PULLUP));
773  break;
775  pio_set_peripheral(p_pio, PIO_PERIPH_B, (1 << (ul_pin & 0x1F)));
776  pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
777  (ul_flags & PIO_PULLUP));
778  break;
779 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
781  pio_set_peripheral(p_pio, PIO_PERIPH_C, (1 << (ul_pin & 0x1F)));
782  pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
783  (ul_flags & PIO_PULLUP));
784  break;
786  pio_set_peripheral(p_pio, PIO_PERIPH_D, (1 << (ul_pin & 0x1F)));
787  pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)),
788  (ul_flags & PIO_PULLUP));
789  break;
790 #endif
791 
792  case PIO_TYPE_PIO_INPUT:
793  pio_set_input(p_pio, (1 << (ul_pin & 0x1F)), ul_flags);
794  break;
795 
798  pio_set_output(p_pio, (1 << (ul_pin & 0x1F)),
799  ((ul_flags & PIO_TYPE_PIO_OUTPUT_1)
800  == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0,
801  (ul_flags & PIO_OPENDRAIN) ? 1 : 0,
802  (ul_flags & PIO_PULLUP) ? 1 : 0);
803  break;
804 
805  default:
806  return 0;
807  }
808 
809  return 1;
810 }
811 
818 void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask)
819 {
820  /* Value to be driven on the I/O line: 1. */
821  p_pio->PIO_SODR = ul_mask;
822 }
823 
830 void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask)
831 {
832  /* Value to be driven on the I/O line: 0. */
833  p_pio->PIO_CODR = ul_mask;
834 }
835 
842 void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask)
843 {
844  if (p_pio->PIO_ODSR & ul_mask) {
845  /* Value to be driven on the I/O line: 0. */
846  p_pio->PIO_CODR = ul_mask;
847  } else {
848  /* Value to be driven on the I/O line: 1. */
849  p_pio->PIO_SODR = ul_mask;
850  }
851 }
852 
863 uint32_t pio_configure_pin_group(Pio *p_pio,
864  uint32_t ul_mask, const uint32_t ul_flags)
865 {
866  /* Configure pins */
867  switch (ul_flags & PIO_TYPE_Msk) {
869  pio_set_peripheral(p_pio, PIO_PERIPH_A, ul_mask);
870  pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
871  break;
873  pio_set_peripheral(p_pio, PIO_PERIPH_B, ul_mask);
874  pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
875  break;
876 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
878  pio_set_peripheral(p_pio, PIO_PERIPH_C, ul_mask);
879  pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
880  break;
882  pio_set_peripheral(p_pio, PIO_PERIPH_D, ul_mask);
883  pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP));
884  break;
885 #endif
886 
887  case PIO_TYPE_PIO_INPUT:
888  pio_set_input(p_pio, ul_mask, ul_flags);
889  break;
890 
893  pio_set_output(p_pio, ul_mask,
894  ((ul_flags & PIO_TYPE_PIO_OUTPUT_1)
895  == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0,
896  (ul_flags & PIO_OPENDRAIN) ? 1 : 0,
897  (ul_flags & PIO_PULLUP) ? 1 : 0);
898  break;
899 
900  default:
901  return 0;
902  }
903 
904  return 1;
905 }
906 
914 void pio_enable_pin_interrupt(uint32_t ul_pin)
915 {
916  Pio *p_pio = pio_get_pin_group(ul_pin);
917 
918  p_pio->PIO_IER = 1 << (ul_pin & 0x1F);
919 }
920 
921 
929 void pio_disable_pin_interrupt(uint32_t ul_pin)
930 {
931  Pio *p_pio = pio_get_pin_group(ul_pin);
932 
933  p_pio->PIO_IDR = 1 << (ul_pin & 0x1F);
934 }
935 
936 
944 Pio *pio_get_pin_group(uint32_t ul_pin)
945 {
946  Pio *p_pio;
947 
948 #if (SAM4C || SAM4CP)
949 # ifdef ID_PIOD
950  if (ul_pin > PIO_PC9_IDX) {
951  p_pio = PIOD;
952  } else if (ul_pin > PIO_PB31_IDX) {
953 # else
954  if (ul_pin > PIO_PB31_IDX) {
955 # endif
956  p_pio = PIOC;
957  } else {
958  p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
959  }
960 #elif (SAM4CM)
961  if (ul_pin > PIO_PB21_IDX) {
962  p_pio = PIOC;
963  } else {
964  p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
965  }
966 #else
967  p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
968 #endif
969  return p_pio;
970 }
971 
979 uint32_t pio_get_pin_group_id(uint32_t ul_pin)
980 {
981  uint32_t ul_id;
982 
983 #if (SAM4C || SAM4CP)
984 # ifdef ID_PIOD
985  if (ul_pin > PIO_PC9_IDX) {
986  ul_id = ID_PIOD;
987  } else if (ul_pin > PIO_PB31_IDX) {
988 # else
989  if (ul_pin > PIO_PB31_IDX) {
990 # endif
991  ul_id = ID_PIOC;
992  } else {
993  ul_id = ID_PIOA + (ul_pin >> 5);
994  }
995 #elif (SAM4CM)
996  if (ul_pin > PIO_PB21_IDX) {
997  ul_id = ID_PIOC;
998  } else {
999  ul_id = ID_PIOA + (ul_pin >> 5);
1000  }
1001 #elif (SAMV70 || SAMV71 || SAME70 || SAMS70)
1002  ul_id = ID_PIOA + (ul_pin >> 5);
1003 
1004  #ifdef ID_PIOD
1005  if (ul_pin >= PIO_PD0_IDX) ul_id = ID_PIOD;
1006  #endif
1007 
1008  #ifdef ID_PIOE
1009  if (ul_pin >= PIO_PE0_IDX) ul_id = ID_PIOE;
1010  #endif
1011 #else
1012  ul_id = ID_PIOA + (ul_pin >> 5);
1013 #endif
1014  return ul_id;
1015 }
1016 
1017 
1025 uint32_t pio_get_pin_group_mask(uint32_t ul_pin)
1026 {
1027  uint32_t ul_mask = 1 << (ul_pin & 0x1F);
1028  return ul_mask;
1029 }
1030 
1031 #if (SAM3S || SAM4S || SAM4E || SAMV71 || SAMV70 || SAME70 || SAMS70)
1032 /* Capture mode enable flag */
1033 uint32_t pio_capture_enable_flag;
1034 
1042 void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode)
1043 {
1044  ul_mode &= (~PIO_PCMR_PCEN); /* Disable PIO capture mode */
1045  p_pio->PIO_PCMR = ul_mode;
1046 }
1047 
1053 void pio_capture_enable(Pio *p_pio)
1054 {
1055  p_pio->PIO_PCMR |= PIO_PCMR_PCEN;
1056  pio_capture_enable_flag = true;
1057 }
1058 
1064 void pio_capture_disable(Pio *p_pio)
1065 {
1066  p_pio->PIO_PCMR &= (~PIO_PCMR_PCEN);
1067  pio_capture_enable_flag = false;
1068 }
1069 
1080 uint32_t pio_capture_read(const Pio *p_pio, uint32_t *pul_data)
1081 {
1082  /* Check if the data is ready */
1083  if ((p_pio->PIO_PCISR & PIO_PCISR_DRDY) == 0) {
1084  return 1;
1085  }
1086 
1087  /* Read data */
1088  *pul_data = p_pio->PIO_PCRHR;
1089  return 0;
1090 }
1091 
1100 void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
1101 {
1102  p_pio->PIO_PCISR;
1103  p_pio->PIO_PCIER = ul_mask;
1104 }
1105 
1112 void pio_capture_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
1113 {
1114  p_pio->PIO_PCIDR = ul_mask;
1115 }
1116 
1124 uint32_t pio_capture_get_interrupt_status(const Pio *p_pio)
1125 {
1126  return p_pio->PIO_PCISR;
1127 }
1128 
1136 uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio)
1137 {
1138  return p_pio->PIO_PCIMR;
1139 }
1140 #if !(SAMV71 || SAMV70 || SAME70 || SAMS70)
1141 
1148 Pdc *pio_capture_get_pdc_base(const Pio *p_pio)
1149 {
1150  UNUSED(p_pio); /* Stop warning */
1151  return PDC_PIOA;
1152 }
1153 #endif
1154 #endif
1155 
1156 #if (SAM4C || SAM4CP || SAM4CM || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)
1157 
1164 void pio_set_io_drive(Pio *p_pio, uint32_t ul_line,
1165  enum pio_io_drive_mode mode)
1166 {
1167  p_pio->PIO_DRIVER &= ~(1 << ul_line);
1168  p_pio->PIO_DRIVER |= mode << ul_line;
1169 }
1170 #endif
1171 
1173 
void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_attr)
Configure the given interrupt source. Interrupt can be configured to trigger on rising edge...
Definition: pio.c:538
#define PIO_PE0_IDX
#define PIO_PD0_IDX
__O uint32_t PIO_IER
(Pio Offset: 0x0040) Interrupt Enable Register
#define PIO_TYPE_PIO_OUTPUT_0
#define PIOA
(PIOA ) Base Address
Definition: same70j19.h:529
#define UNUSED(v)
Marking v as a unused parameter or value.
Definition: compiler.h:86
__O uint32_t PIO_PER
(Pio Offset: 0x0000) PIO Enable Register
void pio_set_pin_high(uint32_t ul_pin)
Drive a GPIO pin to 1.
Definition: pio.c:711
void pio_set_input(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_attribute)
Configure one or more pin(s) or a PIO controller as inputs. Optionally, the corresponding internal pu...
Definition: pio.c:257
#define PIO_TYPE_Msk
#define PIO_TYPE_PIO_PERIPH_D
void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_cut_off)
Configure Glitch or Debouncing filter for the specified input(s).
Definition: pio.c:87
__O uint32_t PIO_MDER
(Pio Offset: 0x0050) Multi-driver Enable Register
__O uint32_t PIO_IFDR
(Pio Offset: 0x0024) Glitch Input Filter Disable Register
void pio_enable_pin_interrupt(uint32_t ul_pin)
Enable interrupt for a GPIO pin.
Definition: pio.c:914
#define PIO_TYPE_PIO_PERIPH_C
uint32_t pio_get_pin_value(uint32_t ul_pin)
Return the value of a pin.
Definition: pio.c:697
void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_multi_driver_enable)
Configure PIO pin multi-driver.
Definition: pio.c:410
void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable)
Enable or disable write protect of PIO registers.
Definition: pio.c:667
void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask)
Drive a GPIO port to 0.
Definition: pio.c:830
__I uint32_t PIO_PCISR
(Pio Offset: 0x0160) Parallel Capture Interrupt Status Register
__O uint32_t PIO_PUER
(Pio Offset: 0x0064) Pull-up Enable Register
__I uint32_t PIO_IMR
(Pio Offset: 0x0048) Interrupt Mask Register
#define PIO_TYPE_PIO_PERIPH_B
void pio_set(Pio *p_pio, const uint32_t ul_mask)
Set a high output level on all the PIOs defined in ul_mask. This has no immediate effects on PIOs tha...
Definition: pio.c:117
uint32_t pio_get_output_write_status(const Pio *p_pio)
Read PIO output write status.
Definition: pio.c:484
#define PIO_IT_RE_OR_HL
void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask)
Disable PIO output write.
Definition: pio.c:472
__O uint32_t PIO_IDR
(Pio Offset: 0x0044) Interrupt Disable Register
__O uint32_t PIO_PDR
(Pio Offset: 0x0004) PIO Disable Register
__IO uint32_t PIO_DRIVER
(Pio Offset: 0x0118) I/O Drive Register
__IO uint32_t PIO_SCDR
(Pio Offset: 0x008C) Slow Clock Divider Debouncing Register
__O uint32_t PIO_REHLSR
(Pio Offset: 0x00D4) Rising Edge/High-Level Select Register
void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask)
Drive a GPIO port to 1.
Definition: pio.c:818
__O uint32_t PIO_PPDDR
(Pio Offset: 0x0090) Pad Pull-down Disable Register
__O uint32_t PIO_AIMER
(Pio Offset: 0x00B0) Additional Interrupt Modes Enable Register
#define FREQ_SLOW_CLOCK_EXT
Definition: pio.c:58
__O uint32_t PIO_AIMDR
(Pio Offset: 0x00B4) Additional Interrupt Modes Disable Register
__O uint32_t PIO_PCIER
(Pio Offset: 0x0154) Parallel Capture Interrupt Enable Register
__I uint32_t PIO_PCRHR
(Pio Offset: 0x0164) Parallel Capture Reception Holding Register
void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask)
Enable PIO output write for synchronous data output.
Definition: pio.c:461
enum _pio_type pio_type_t
Parallel Input/Output (PIO) Controller driver for SAM.
uint32_t pio_get_pin_group_id(uint32_t ul_pin)
Return GPIO port peripheral ID for a GPIO pin.
Definition: pio.c:979
#define PIO_DELTA
__O uint32_t PIO_MDDR
(Pio Offset: 0x0054) Multi-driver Disable Register
uint32_t pio_configure_pin_group(Pio *p_pio, uint32_t ul_mask, const uint32_t ul_flags)
Perform complete pin(s) configuration; general attributes and PIO init if necessary.
Definition: pio.c:863
__O uint32_t PIO_CODR
(Pio Offset: 0x0034) Clear Output Data Register
uint32_t pio_get_output_data_status(const Pio *p_pio, const uint32_t ul_mask)
Return 1 if one or more PIOs of the given Pin are configured to output a high level (even if they are...
Definition: pio.c:392
#define PIO_WPMR_WPKEY_PASSWD
Definition: pio.c:40
void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask)
Synchronously write on output pins.
Definition: pio.c:497
void 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)
Configure one or more pin(s) of a PIO controller as outputs, with the given default value...
Definition: pio.c:310
void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
Enable the given interrupt source. The PIO must be configured as an NVIC interrupt source as well...
Definition: pio.c:578
__I uint32_t PIO_PCIMR
(Pio Offset: 0x015C) Parallel Capture Interrupt Mask Register
#define PIO_TYPE_PIO_PERIPH_A
__O uint32_t PIO_PCIDR
(Pio Offset: 0x0158) Parallel Capture Interrupt Disable Register
void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
Disable a given interrupt source, with no added side effects.
Definition: pio.c:589
__IO uint32_t PIO_SCHMITT
(Pio Offset: 0x0100) Schmitt Trigger Register
__O uint32_t PIO_ESR
(Pio Offset: 0x00C0) Edge Select Register
#define PIO_DEGLITCH
#define PIO_IT_EDGE
__O uint32_t PIO_PPDER
(Pio Offset: 0x0094) Pad Pull-down Enable Register
__I uint32_t PIO_WPSR
(Pio Offset: 0x00E8) Write Protection Status Register
__O uint32_t PIO_OER
(Pio Offset: 0x0010) Output Enable Register
__I uint32_t PIO_OWSR
(Pio Offset: 0x00A8) Output Write Status Register
#define PIO_PCMR_PCEN
(PIO_PCMR) Parallel Capture Mode Enable
#define ID_PIOA
Parallel I/O Controller A (PIOA)
Definition: same70j19.h:416
void pio_toggle_pin(uint32_t ul_pin)
Toggle a GPIO pin.
Definition: pio.c:741
Pio hardware registers.
__O uint32_t PIO_ODR
(Pio Offset: 0x0014) Output Disable Register
void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask)
Toggle a GPIO group.
Definition: pio.c:842
__O uint32_t PIO_SODR
(Pio Offset: 0x0030) Set Output Data Register
__IO uint32_t PIO_PCMR
(Pio Offset: 0x0150) Parallel Capture Mode Register
__I uint32_t PIO_PDSR
(Pio Offset: 0x003C) Pin Data Status Register
#define PIOD
(PIOD ) Base Address
Definition: same70j19.h:531
__IO uint32_t PIO_ABCDSR[2]
(Pio Offset: 0x0070) Peripheral Select Register
void pio_pull_up(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_pull_up_enable)
Configure PIO internal pull-up.
Definition: pio.c:69
Pio * pio_get_pin_group(uint32_t ul_pin)
Return GPIO port for a GPIO pin.
Definition: pio.c:944
__O uint32_t PIO_IFSCDR
(Pio Offset: 0x0080) Input Filter Slow Clock Disable Register
uint32_t pio_get_interrupt_status(const Pio *p_pio)
Read and clear PIO interrupt status.
Definition: pio.c:601
void pio_set_pin_low(uint32_t ul_pin)
Drive a GPIO pin to 0.
Definition: pio.c:726
#define PIO_WPMR_WPEN
(PIO_WPMR) Write Protection Enable
#define ID_PIOD
Parallel I/O Controller D (PIOD)
Definition: same70j19.h:420
__O uint32_t PIO_OWDR
(Pio Offset: 0x00A4) Output Write Disable
#define ID_PIOE
Parallel I/O Controller E (PIOE)
Definition: same70q19.h:477
__O uint32_t PIO_OWER
(Pio Offset: 0x00A0) Output Write Enable
__O uint32_t PIO_IFSCER
(Pio Offset: 0x0084) Input Filter Slow Clock Enable Register
#define PIO_PULLUP
__IO uint32_t PIO_ODSR
(Pio Offset: 0x0038) Output Data Status Register
__O uint32_t PIO_IFER
(Pio Offset: 0x0020) Glitch Input Filter Enable Register
uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask)
Return 1 if one or more PIOs of the given Pin instance currently have a high level; otherwise returns...
Definition: pio.c:148
__IO uint32_t PIO_WPMR
(Pio Offset: 0x00E4) Write Protection Mode Register
uint32_t pio_get_multi_driver_status(const Pio *p_pio)
Get multi-driver status.
Definition: pio.c:428
#define PIO_TYPE_PIO_INPUT
uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute)
Perform complete pin(s) configuration; general attributes and PIO init if necessary.
Definition: pio.c:348
#define PIO_PC9_IDX
__O uint32_t PIO_FELLSR
(Pio Offset: 0x00D0) Falling Edge/Low-Level Select Register
#define PIO_DEBOUNCE
__O uint32_t PIO_LSR
(Pio Offset: 0x00C4) Level Select Register
uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags)
Perform complete pin(s) configuration; general attributes and PIO init if necessary.
Definition: pio.c:763
void pio_disable_pin_interrupt(uint32_t ul_pin)
Disable interrupt for a GPIO pin.
Definition: pio.c:929
#define PIO_IT_AIME
void pio_clear(Pio *p_pio, const uint32_t ul_mask)
Set a low output level on all the PIOs defined in ul_mask. This has no immediate effects on PIOs that...
Definition: pio.c:130
#define PIO_OPENDRAIN
__O uint32_t PIO_PUDR
(Pio Offset: 0x0060) Pull-up Disable Register
__I uint32_t PIO_ISR
(Pio Offset: 0x004C) Interrupt Status Register
uint32_t pio_get_writeprotect_status(const Pio *p_pio)
Read write protect status.
Definition: pio.c:679
#define ID_PIOC
Parallel I/O Controller C (PIOC)
Definition: same70q19.h:472
#define PIOC
(PIOC ) Base Address
Definition: same70q19.h:626
uint32_t pio_get_interrupt_mask(const Pio *p_pio)
Read PIO interrupt mask.
Definition: pio.c:613
void pio_set_additional_interrupt_mode(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_attribute)
Set additional interrupt mode.
Definition: pio.c:625
#define PIO_PCISR_DRDY
(PIO_PCISR) Parallel Capture Mode Data Ready
uint32_t pio_get_pin_group_mask(uint32_t ul_pin)
Return GPIO port pin mask for a GPIO pin.
Definition: pio.c:1025
#define PIO_TYPE_PIO_OUTPUT_1
void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask)
Configure IO of a PIO controller as being controlled by a specific peripheral.
Definition: pio.c:174
__I uint32_t PIO_MDSR
(Pio Offset: 0x0058) Multi-driver Status Register


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04