periph_cpu_common.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016 Freie Universität Berlin
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
20 #include "cpu.h"
21 #include "exti_config.h"
22 #include "timer_config.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
31 #define CPUID_LEN (16U)
32 
37 #define PERIPH_SPI_NEEDS_INIT_CS
38 #define PERIPH_SPI_NEEDS_TRANSFER_BYTE
39 #ifndef MODULE_PERIPH_DMA
40 # define PERIPH_SPI_NEEDS_TRANSFER_REG
41 # define PERIPH_SPI_NEEDS_TRANSFER_REGS
42 #endif
49 #define PERIPH_I2C_NEED_READ_REG
50 #define PERIPH_I2C_NEED_READ_REGS
51 #define PERIPH_I2C_NEED_WRITE_REG
52 #define PERIPH_I2C_NEED_WRITE_REGS
58 #define PERIPH_I2C_MAX_BYTES_PER_FRAME 256
59 
64 #define HAVE_GPIO_T
65 typedef uint32_t gpio_t;
71 #define GPIO_UNDEF (0xffffffff)
72 
77 #ifdef MODULE_PERIPH_GPIO_FAST_READ
78 # ifdef PORT_IOBUS_SEC
79 # define GPIO_PIN(x, y) (((gpio_t)(&PORT_IOBUS_SEC->Group[x])) | y)
80 # else /* Use IOBUS access when available */
81 # define GPIO_PIN(x, y) (((gpio_t)(&PORT_IOBUS->Group[x])) | y)
82 # endif /* PORT_IOBUS_SEC */
83 #else
84 # ifdef PORT_SEC
85 # define GPIO_PIN(x, y) (((gpio_t)(&PORT_SEC->Group[x])) | y)
86 # else
87 # define GPIO_PIN(x, y) (((gpio_t)(&PORT->Group[x])) | y)
88 # endif /* PORT_IOBUS_SEC */
89 #endif
90 
94 enum {
95  PA = 0,
96  PB = 1,
97  PC = 2,
98  PD = 3,
99 };
100 
109 #define GPIO_MODE(pr, ie, pe) (pr | (ie << 1) | (pe << 2))
110 
111 #ifndef DOXYGEN
115 # define HAVE_GPIO_MODE_T
116 typedef enum {
117  GPIO_IN = GPIO_MODE(0, 1, 0),
118  GPIO_IN_PD = GPIO_MODE(0, 1, 1),
119  GPIO_IN_PU = GPIO_MODE(1, 1, 1),
120  GPIO_OUT = GPIO_MODE(0, 0, 0),
121  GPIO_OD = 0xfe,
122  GPIO_OD_PU = 0xff
123 } gpio_mode_t;
124 
125 # define HAVE_GPIO_SLEW_T
126 typedef enum {
127  GPIO_SLEW_SLOWEST = 0,
128  GPIO_SLEW_SLOW = 0,
129  GPIO_SLEW_FAST = 0,
130  GPIO_SLEW_FASTEST = 0,
131 } gpio_slew_t;
132 
133 # define HAVE_GPIO_PULL_STRENGTH_T
134 typedef enum {
135  GPIO_PULL_WEAKEST = 0,
136  GPIO_PULL_WEAK = 0,
137  GPIO_PULL_STRONG = 0,
140 
141 # define HAVE_GPIO_DRIVE_STRENGTH_T
142 typedef enum {
143  GPIO_DRIVE_WEAKEST = 0,
144  GPIO_DRIVE_WEAK = 0,
145  GPIO_DRIVE_STRONG = 1,
148 
149 # define HAVE_GPIO_PULL_T
150 typedef enum {
152  GPIO_PULL_UP,
155 } gpio_pull_t;
156 
157 # define HAVE_GPIO_STATE_T
158 typedef enum {
162  GPIO_INPUT,
165 } gpio_state_t;
166 
167 # define HAVE_GPIO_IRQ_TRIG_T
168 typedef enum {
169  GPIO_TRIGGER_EDGE_RISING = EIC_CONFIG_SENSE0_RISE_Val,
170  GPIO_TRIGGER_EDGE_FALLING = EIC_CONFIG_SENSE0_FALL_Val,
171  GPIO_TRIGGER_EDGE_BOTH = EIC_CONFIG_SENSE0_BOTH_Val,
172  GPIO_TRIGGER_LEVEL_HIGH = EIC_CONFIG_SENSE0_HIGH_Val,
173  GPIO_TRIGGER_LEVEL_LOW = EIC_CONFIG_SENSE0_LOW_Val,
175 
176 # define HAVE_GPIO_CONF_T
177 typedef union gpio_conf_sam0 gpio_conf_t;
178 
183 # define HAVE_GPIO_FLANK_T
184 typedef enum {
185  GPIO_FALLING = 2,
186  GPIO_RISING = 1,
187  GPIO_BOTH = 3
188 } gpio_flank_t;
190 #endif /* ndef DOXYGEN */
191 
197  uint8_t bits;
198  struct {
230  bool initial_value : 1;
231  uint8_t : 1;
232  };
233 };
234 
238 #ifndef SAM_MUX_T
239 typedef enum {
240  GPIO_MUX_A = 0x0,
241  GPIO_MUX_B = 0x1,
242  GPIO_MUX_C = 0x2,
243  GPIO_MUX_D = 0x3,
244  GPIO_MUX_E = 0x4,
245  GPIO_MUX_F = 0x5,
246  GPIO_MUX_G = 0x6,
247  GPIO_MUX_H = 0x7,
248  GPIO_MUX_I = 0x8,
249  GPIO_MUX_J = 0x9,
250  GPIO_MUX_K = 0xa,
251  GPIO_MUX_L = 0xb,
252  GPIO_MUX_M = 0xc,
253  GPIO_MUX_N = 0xd,
255 } gpio_mux_t;
256 #endif
257 
261 typedef enum {
266 } uart_rxpad_t;
267 
271 typedef enum {
276 } uart_txpad_t;
277 
281 typedef enum {
286 } uart_flag_t;
287 
288 #ifndef DOXYGEN
296 # define HAVE_UART_DATA_BITS_T
297 typedef enum {
298  UART_DATA_BITS_5 = 0x5,
299  UART_DATA_BITS_6 = 0x6,
300  UART_DATA_BITS_7 = 0x7,
301  UART_DATA_BITS_8 = 0x0,
309 # define uart_pin_rx(dev) uart_config[dev].rx_pin
310 # define uart_pin_tx(dev) uart_config[dev].tx_pin
313 #endif /* ndef DOXYGEN */
314 
318 #ifndef UART_TXBUF_SIZE
319 # define UART_TXBUF_SIZE (64)
320 #endif
321 
335 typedef struct {
336  SercomUsart *dev;
337  gpio_t rx_pin;
338  gpio_t tx_pin;
339 #ifdef MODULE_PERIPH_UART_HW_FC
340  gpio_t rts_pin;
341  gpio_t cts_pin;
342 #endif
347  uint8_t gclk_src;
348 } uart_conf_t;
349 
350 enum {
353 };
354 
358 typedef struct {
359  union {
360 #ifdef REV_TC
361  Tc *tc;
362 #endif
363 #ifdef REV_TCC
364  Tcc *tcc;
365 #endif
366  } dev;
367 #ifdef MCLK
368  volatile uint32_t *mclk;
369  uint32_t mclk_mask;
370 #else
371  uint32_t pm_mask;
372 #endif
373  uint16_t gclk_id;
374  uint8_t type;
375 } tc_tcc_cfg_t;
376 
380 #ifdef MCLK
381 # define TC_CONFIG(tim) { \
382  .dev = {.tc = tim}, \
383  .mclk = MCLK_ ## tim, \
384  .mclk_mask = MCLK_ ## tim ## _MASK, \
385  .gclk_id = tim ## _GCLK_ID, \
386  .type = TIMER_TYPE_TC, }
387 #else
388 # define TC_CONFIG(tim) { \
389  .dev = {.tc = tim}, \
390  .pm_mask = PM_APBCMASK_ ## tim, \
391  .gclk_id = tim ## _GCLK_ID, \
392  .type = TIMER_TYPE_TC, }
393 #endif
394 
398 #ifdef MCLK
399 # define TCC_CONFIG(tim) { \
400  .dev = {.tcc = tim}, \
401  .mclk = MCLK_ ## tim, \
402  .mclk_mask = MCLK_ ## tim ## _MASK, \
403  .gclk_id = tim ## _GCLK_ID, \
404  .type = TIMER_TYPE_TCC, }
405 #else
406 # define TCC_CONFIG(tim) { \
407  .dev = {.tcc = tim}, \
408  .pm_mask = PM_APBCMASK_ ## tim, \
409  .gclk_id = tim ## _GCLK_ID, \
410  .type = TIMER_TYPE_TCC, }
411 #endif
412 
416 typedef struct {
417  gpio_t pin;
419  uint8_t chan;
421 
425 typedef struct {
428  uint8_t chan_numof;
429  uint8_t gclk_src;
430 } pwm_conf_t;
431 
435 typedef enum {
440 } spi_misopad_t;
441 
445 typedef enum {
450 } spi_mosipad_t;
451 
452 #ifndef DOXYGEN
457 # define HAVE_SPI_MODE_T
458 typedef enum {
459  SPI_MODE_0 = 0x0,
460  SPI_MODE_1 = 0x1,
461  SPI_MODE_2 = 0x2,
462  SPI_MODE_3 = 0x3
463 } spi_mode_t;
470 # define HAVE_SPI_CLK_T
471 typedef enum {
472  SPI_CLK_100KHZ = 100000U,
473  SPI_CLK_400KHZ = 400000U,
474  SPI_CLK_1MHZ = 1000000U,
475  SPI_CLK_5MHZ = 5000000U,
476  SPI_CLK_10MHZ = 10000000U
477 } spi_clk_t;
484 # define spi_pin_mosi(dev) spi_config[dev].mosi_pin
485 # define spi_pin_miso(dev) spi_config[dev].miso_pin
486 # define spi_pin_clk(dev) spi_config[dev].clk_pin
489 #endif /* ndef DOXYGEN */
490 
494 typedef struct {
495  void *dev;
496  gpio_t miso_pin;
497  gpio_t mosi_pin;
498  gpio_t clk_pin;
504  uint8_t gclk_src;
505 #ifdef MODULE_PERIPH_DMA
506  uint8_t tx_trigger;
507  uint8_t rx_trigger;
508 #endif
509 } spi_conf_t;
515 typedef enum {
518 } i2c_flag_t;
519 
520 #ifndef DOXYGEN
525 # define HAVE_I2C_SPEED_T
526 typedef enum {
527  I2C_SPEED_LOW = 10000U,
528  I2C_SPEED_NORMAL = 100000U,
529  I2C_SPEED_FAST = 400000U,
530  I2C_SPEED_FAST_PLUS = 1000000U,
531  I2C_SPEED_HIGH = 3400000U,
532 } i2c_speed_t;
539 # define i2c_pin_sda(dev) i2c_config[dev].sda_pin
540 # define i2c_pin_scl(dev) i2c_config[dev].scl_pin
543 #endif /* ndef DOXYGEN */
544 
557 typedef struct {
558  SercomI2cm *dev;
559  i2c_speed_t speed;
560  gpio_t scl_pin;
561  gpio_t sda_pin;
563  uint8_t gclk_src;
564  uint8_t flags;
565 } i2c_conf_t;
566 
570 typedef struct {
571  Tc *dev;
573 #ifdef MCLK
574  volatile uint32_t *mclk;
575  uint32_t mclk_mask;
576  uint16_t gclk_id;
577 #else
578  uint32_t pm_mask;
579  uint16_t gclk_ctrl;
580 #endif
581  uint8_t gclk_src;
582  uint16_t flags;
583 } tc32_conf_t;
584 
588 #define TIMER_CHANNEL_NUMOF (2)
589 
596 void gpio_init_mux(gpio_t pin, gpio_mux_t mux);
597 
598 #ifdef PM_SLEEPCFG_SLEEPMODE_OFF
599 
603 # define PROVIDES_PM_OFF
604 
608 # define PROVIDES_PM_LAYERED_OFF
609 
610 #endif /* PM_SLEEPCFG_SLEEPMODE_OFF */
611 
617 void gpio_pm_cb_enter(int deep);
618 
624 void gpio_pm_cb_leave(int deep);
625 
631 void cpu_pm_cb_enter(int deep);
632 
638 void cpu_pm_cb_leave(int deep);
639 
645 static inline void sam0_cortexm_sleep(int deep)
646 {
647 #ifdef MODULE_PERIPH_GPIO
648  gpio_pm_cb_enter(deep);
649 #endif
650 
651  cpu_pm_cb_enter(deep);
652 
653  cortexm_sleep(deep);
654 
655  cpu_pm_cb_leave(deep);
656 
657 #ifdef MODULE_PERIPH_GPIO
658  gpio_pm_cb_leave(deep);
659 #endif
660 }
661 
667 void gpio_disable_mux(gpio_t pin);
668 
672 typedef enum {
677 
693 {
694 #ifdef REG_SUPC_VREG
695  if (src == SAM0_VREG_BUCK) {
696  SUPC->VREG.reg |= (1 << SUPC_VREG_SEL_Pos);
697  }
698  else {
699  SUPC->VREG.reg &= ~(1 << SUPC_VREG_SEL_Pos);
700  }
701  while (!(SUPC->STATUS.reg & SUPC_STATUS_VREGRDY)) {}
702 #else
703  (void) src;
704  assert(0);
705 #endif
706 }
707 
715 uint32_t sam0_gclk_freq(uint8_t id);
716 
722 void sam0_gclk_enable(uint8_t id);
723 
731 static inline uint8_t sercom_id(const void *sercom)
732 {
733 #ifdef SERCOM0
734  if (sercom == SERCOM0) {
735  return 0;
736  }
737 #endif
738 #ifdef SERCOM1
739  if (sercom == SERCOM1) {
740  return 1;
741  }
742 #endif
743 #ifdef SERCOM2
744  if (sercom == SERCOM2) {
745  return 2;
746  }
747 #endif
748 #ifdef SERCOM3
749  if (sercom == SERCOM3) {
750  return 3;
751  }
752 #endif
753 #ifdef SERCOM4
754  if (sercom == SERCOM4) {
755  return 4;
756  }
757 #endif
758 #ifdef SERCOM5
759  if (sercom == SERCOM5) {
760  return 5;
761  }
762 #endif
763 #ifdef SERCOM6
764  if (sercom == SERCOM6) {
765  return 6;
766  }
767 #endif
768 #ifdef SERCOM7
769  if (sercom == SERCOM7) {
770  return 7;
771  }
772 #endif
773 
774  /* should not be reached, so fail with assert */
775  assert(false);
776 
777  return SERCOM_INST_NUM;
778 }
779 
785 static inline void sercom_clk_en(void *sercom)
786 {
787  const uint8_t id = sercom_id(sercom);
788 #if defined(CPU_COMMON_SAMD21)
789  PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << id);
790 #elif defined (CPU_COMMON_SAMD5X)
791  if (id < 2) {
792  MCLK->APBAMASK.reg |= (1 << (id + 12));
793  } else if (id < 4) {
794  MCLK->APBBMASK.reg |= (1 << (id + 7));
795  } else {
796  MCLK->APBDMASK.reg |= (1 << (id - 4));
797  }
798 #else
799  if (id < 5) {
800  MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << id);
801  }
802 # if defined(CPU_COMMON_SAML21)
803  else {
804  MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
805  }
806 # endif /* CPU_COMMON_SAML21 */
807 #endif
808 }
809 
815 static inline void sercom_clk_dis(void *sercom)
816 {
817  const uint8_t id = sercom_id(sercom);
818 #if defined(CPU_COMMON_SAMD21)
819  PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << id);
820 #elif defined (CPU_COMMON_SAMD5X)
821  if (id < 2) {
822  MCLK->APBAMASK.reg &= ~(1 << (id + 12));
823  } else if (id < 4) {
824  MCLK->APBBMASK.reg &= ~(1 << (id + 7));
825  } else {
826  MCLK->APBDMASK.reg &= ~(1 << (id - 4));
827  }
828 #else
829  if (id < 5) {
830  MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << id);
831  }
832 # if defined (CPU_COMMON_SAML21)
833  else {
834  MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
835  }
836 # endif /* CPU_COMMON_SAML21 */
837 #endif
838 }
839 
840 #ifdef CPU_COMMON_SAMD5X
841 static inline uint8_t _sercom_gclk_id_core(uint8_t sercom_id) {
842  if (sercom_id < 2) {
843  return sercom_id + 7;
844  }
845  else if (sercom_id < 4) {
846  return sercom_id + 21;
847  }
848  else {
849  return sercom_id + 30;
850  }
851 }
852 #endif
853 
860 static inline void sercom_set_gen(void *sercom, uint8_t gclk)
861 {
862  const uint8_t id = sercom_id(sercom);
863  sam0_gclk_enable(gclk);
864 #if defined(CPU_COMMON_SAMD21)
865  GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(gclk) |
866  (SERCOM0_GCLK_ID_CORE + id));
867  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
868 #elif defined(CPU_COMMON_SAMD5X)
869  GCLK->PCHCTRL[_sercom_gclk_id_core(id)].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
870 #else
871  if (id < 5) {
872  GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + id].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
873  }
874 # if defined(CPU_COMMON_SAML21)
875  else {
876  GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk));
877  }
878 # endif /* CPU_COMMON_SAML21 */
879 #endif
880 }
881 
885 static inline bool cpu_woke_from_backup(void)
886 {
887 #ifdef RSTC_RCAUSE_BACKUP
888  return RSTC->RCAUSE.reg & RSTC_RCAUSE_BACKUP;
889 #else
890  return false;
891 #endif
892 }
893 
897 typedef struct {
898  uint32_t inputctrl;
899 #ifdef ADC0
900  Adc *dev;
901 #endif
903 
908 #ifndef ADC_INPUTCTRL_DIFFMODE
909 # define ADC_INPUTCTRL_DIFFMODE (1 << 7)
910 #endif
911 
915 #define ADC_REFSEL_AREFA_PIN GPIO_PIN(PA, 3)
916 
920 #define ADC_REFSEL_AREFB_PIN GPIO_PIN(PA, 4)
921 
922 #if defined(ADC_REFCTRL_REFSEL_AREFC) || DOXYGEN
926 # define ADC_REFSEL_AREFC_PIN GPIO_PIN(PA, 6)
927 #endif
928 
929 #ifndef DOXYGEN
930 # define HAVE_ADC_RES_T
931 typedef enum {
932  ADC_RES_6BIT = 0xff,
933 # if defined(ADC_CTRLB_RESSEL)
934  ADC_RES_8BIT = ADC_CTRLB_RESSEL_8BIT_Val,
935  ADC_RES_10BIT = ADC_CTRLB_RESSEL_10BIT_Val,
936  ADC_RES_12BIT = ADC_CTRLB_RESSEL_12BIT_Val,
937 # elif defined(ADC_CTRLC_RESSEL)
938  ADC_RES_8BIT = ADC_CTRLC_RESSEL_8BIT_Val,
939  ADC_RES_10BIT = ADC_CTRLC_RESSEL_10BIT_Val,
940  ADC_RES_12BIT = ADC_CTRLC_RESSEL_12BIT_Val,
941 # endif
942  ADC_RES_16BIT_2SAMPL = ( 0x1 << 2) | 0x1,
943  ADC_RES_16BIT_4SAMPL = ( 0x2 << 2) | 0x1,
944  ADC_RES_16BIT_8SAMPL = ( 0x3 << 2) | 0x1,
945  ADC_RES_16BIT_16SAMPL = ( 0x4 << 2) | 0x1,
946  ADC_RES_16BIT_32SAMPL = ( 0x5 << 2) | 0x1,
947  ADC_RES_16BIT_64SAMPL = ( 0x6 << 2) | 0x1,
948  ADC_RES_16BIT_128SAMPL = ( 0x7 << 2) | 0x1,
949  ADC_RES_16BIT_256SAMPL = ( 0x8 << 2) | 0x1,
950  ADC_RES_16BIT_512SAMPL = ( 0x9 << 2) | 0x1,
951  ADC_RES_16BIT_1024SAMPL = ( 0xA << 2) | 0x1,
952  ADC_RES_14BIT = 0xfe,
953 } adc_res_t;
954 
955 # define ADC_RES_16BIT ADC_RES_16BIT_16SAMPL
956 #endif /* DOXYGEN */
957 
962 #ifndef ETH_RX_BUFFER_COUNT
963 # define ETH_RX_BUFFER_COUNT (4)
964 #endif
965 
966 #ifndef ETH_TX_BUFFER_COUNT
967 # define ETH_TX_BUFFER_COUNT (2)
968 #endif
969 
970 #ifndef ETH_RX_BUFFER_SIZE
971 # define ETH_RX_BUFFER_SIZE (1536)
972 #endif
973 
974 #ifndef ETH_TX_BUFFER_SIZE
975 # define ETH_TX_BUFFER_SIZE (1536)
976 #endif
982 #if defined(GMAC_INST_NUM) || defined(DOXYGEN)
983 typedef struct {
984  Gmac *dev;
985  gpio_t refclk;
986  gpio_t txen;
987  gpio_t txd0;
988  gpio_t txd1;
989  gpio_t crsdv;
990  gpio_t rxd0;
991  gpio_t rxd1;
992  gpio_t rxer;
993  gpio_t mdc;
994  gpio_t mdio;
995  gpio_t rst_pin;
996  gpio_t int_pin;
998 #endif
999 
1003 #define USBDEV_CPU_DMA_ALIGNMENT (4)
1004 
1008 #define USBDEV_CPU_DMA_REQUIREMENTS __attribute__((aligned(USBDEV_CPU_DMA_ALIGNMENT)))
1009 
1013 #if defined(USB_INST_NUM) || defined(DOXYGEN)
1014 typedef struct {
1015  gpio_t dm;
1016  gpio_t dp;
1018  UsbDevice *device;
1019  uint8_t gclk_src;
1021 #endif /* USB_INST_NUM */
1022 
1026 #define SDMMC_CPU_DMA_ALIGNMENT 4
1027 
1031 #define SDMMC_CPU_DMA_REQUIREMENTS __attribute__((aligned(SDMMC_CPU_DMA_ALIGNMENT)))
1032 
1036 typedef struct {
1037  void *sdhc;
1038  gpio_t cd;
1039  gpio_t wp;
1040 } sdhc_conf_t;
1041 
1046 /* Limits are in clock cycles according to data sheet.
1047  As the WDT is clocked by a 1024 Hz clock, 1 cycle ≈ 1 ms */
1048 #define NWDT_TIME_LOWER_LIMIT (8U)
1049 #define NWDT_TIME_UPPER_LIMIT (16384U)
1055 #define WDT_HAS_STOP (1)
1059 #define WDT_HAS_INIT (1)
1060 
1064 typedef struct {
1065  gpio_t pin;
1066  uint8_t gclk_src;
1067 } freqm_config_t;
1068 
1069 #if defined(REV_DMAC) || DOXYGEN
1119 # define DMA_TRIGGER_DISABLED 0
1120 
1124 # if defined(CPU_COMMON_SAML21) || defined(DOXYGEN)
1125 # define DMA_DESCRIPTOR_IN_LPSRAM
1126 # endif
1127 
1131 # ifdef DMA_DESCRIPTOR_IN_LPSRAM
1132 # define DMA_DESCRIPTOR_ATTRS __attribute__((section(".backup.bss")))
1133 # else
1134 # define DMA_DESCRIPTOR_ATTRS
1135 # endif
1136 
1140 typedef unsigned dma_t;
1141 
1145 typedef enum {
1150 } dma_incr_t;
1151 
1155 void dma_init(void);
1156 
1168 
1175 
1184 void dma_setup(dma_t dma, unsigned trigger, uint8_t prio, bool irq);
1185 
1199 void dma_prepare(dma_t dma, uint8_t width, const void *src, void *dst,
1200  size_t num, dma_incr_t incr);
1201 
1222 void dma_prepare_src(dma_t dma, const void *src, size_t num, bool incr);
1223 
1244 void dma_prepare_dst(dma_t dma, void *dst, size_t num, bool incr);
1245 
1265 void dma_append(dma_t dma, DmacDescriptor *descriptor, uint8_t width,
1266  const void *src, void *dst, size_t num, dma_incr_t incr);
1267 
1286 void dma_append_src(dma_t dma, DmacDescriptor *next, const void *src,
1287  size_t num, bool incr);
1288 
1307 void dma_append_dst(dma_t dma, DmacDescriptor *next, void *dst, size_t num,
1308  bool incr);
1309 
1315 void dma_start(dma_t dma);
1316 
1326 void dma_wait(dma_t dma);
1327 
1336 void dma_cancel(dma_t dma);
1338 #endif /* REV_DMAC || DOXYGEN */
1339 
1348 void rtc_tamper_init(void);
1349 
1358 int rtc_tamper_register(gpio_t pin, gpio_flank_t flank);
1359 
1364 
1372 uint8_t rtc_get_tamper_event(void);
1373 
1384 uint8_t rtc_tamper_pin_mask(gpio_t pin);
1401 typedef struct sam0_aux_cfg_mapping nvm_user_page_t;
1402 
1406 #ifdef FLASH_USER_PAGE_SIZE
1407 # define FLASH_USER_PAGE_AUX_SIZE (FLASH_USER_PAGE_SIZE - sizeof(nvm_user_page_t))
1408 #else
1409 # define FLASH_USER_PAGE_AUX_SIZE (AUX_PAGE_SIZE * AUX_NB_OF_PAGES - sizeof(nvm_user_page_t))
1410 #endif
1411 
1421 
1437 void sam0_flashpage_aux_write(uint32_t offset, const void *data, size_t len);
1438 
1446 #define sam0_flashpage_aux_get(offset) \
1447  (const void*)((uint8_t*)NVMCTRL_USER + sizeof(nvm_user_page_t) + (offset))
1448 
1454 #define sam0_flashpage_aux_cfg() \
1455  ((const nvm_user_page_t*)NVMCTRL_USER)
1456 
1459 #ifdef __cplusplus
1460 }
1461 #endif
1462 
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:146
gpio_flank_t
Definition: periph_cpu.h:176
@ GPIO_OUT
select GPIO MASK as output
Definition: periph_cpu.h:161
@ GPIO_IN
select GPIO MASK as input
Definition: periph_cpu.h:160
i2c_speed_t
Definition: periph_cpu.h:272
spi_clk_t
Definition: periph_cpu.h:348
enum IRQn IRQn_Type
Interrupt Number Definition.
static void cortexm_sleep(int deep)
Put the CPU into (deep) sleep mode, using the WFI instruction.
Definition: cpu.h:151
gpio_mode_t
Available pin modes.
Definition: periph_cpu.h:88
adc_res_t
Possible ADC resolution settings.
Definition: adc.h:92
@ ADC_RES_8BIT
ADC resolution: 8 bit.
Definition: adc.h:94
@ ADC_RES_14BIT
ADC resolution: 14 bit.
Definition: adc.h:97
@ ADC_RES_6BIT
ADC resolution: 6 bit.
Definition: adc.h:93
@ ADC_RES_10BIT
ADC resolution: 10 bit.
Definition: adc.h:95
@ ADC_RES_12BIT
ADC resolution: 12 bit.
Definition: adc.h:96
gpio_irq_trig_t
Definition of possible IRQ triggers.
Definition: gpio_ll_irq.h:71
@ GPIO_TRIGGER_EDGE_FALLING
edge triggered IRQ on falling flanks only
Definition: gpio_ll_irq.h:72
@ GPIO_TRIGGER_LEVEL_HIGH
level triggered IRQ on high input
Definition: gpio_ll_irq.h:77
@ GPIO_TRIGGER_EDGE_RISING
edge triggered IRQ on rising flanks only
Definition: gpio_ll_irq.h:74
@ GPIO_TRIGGER_EDGE_BOTH
edge triggered IRQ on falling AND rising flanks
Definition: gpio_ll_irq.h:75
@ GPIO_TRIGGER_LEVEL_LOW
level triggered IRQ on low input
Definition: gpio_ll_irq.h:78
gpio_pull_t
Enumeration of pull resistor configurations.
Definition: gpio_ll.h:257
gpio_pull_strength_t
Enumeration of pull resistor values.
Definition: gpio_ll.h:275
gpio_state_t
Enumeration of GPIO states (direction)
Definition: gpio_ll.h:165
gpio_slew_t
Enumeration of slew rate settings.
Definition: gpio_ll.h:339
gpio_drive_strength_t
Enumeration of drive strength options.
Definition: gpio_ll.h:306
typedef gpio_conf_t
GPIO pin configuration.
Definition: gpio_ll.h:423
@ GPIO_FLOATING
No pull ups nor pull downs enabled.
Definition: gpio_ll.h:258
@ GPIO_PULL_KEEP
Keep the signal at current logic level with pull up/down resistors.
Definition: gpio_ll.h:261
@ GPIO_PULL_DOWN
Pull down resistor enabled.
Definition: gpio_ll.h:260
@ GPIO_PULL_UP
Pull up resistor enabled.
Definition: gpio_ll.h:259
@ GPIO_PULL_WEAKEST
Use the weakest (highest Ohm value) resistor.
Definition: gpio_ll.h:276
@ GPIO_PULL_WEAK
Use a weak pull resistor.
Definition: gpio_ll.h:277
@ GPIO_PULL_STRONG
Use a strong pull resistor.
Definition: gpio_ll.h:278
@ GPIO_PULL_STRONGEST
Use the strongest pull resistor.
Definition: gpio_ll.h:279
@ GPIO_OUTPUT_OPEN_SOURCE
Use pin as output in open emitter configuration.
Definition: gpio_ll.h:202
@ GPIO_USED_BY_PERIPHERAL
The GPIO pin is used by a peripheral.
Definition: gpio_ll.h:221
@ GPIO_OUTPUT_OPEN_DRAIN
Use pin as output in open collector configuration.
Definition: gpio_ll.h:189
@ GPIO_OUTPUT_PUSH_PULL
Use pin as output in push-pull configuration.
Definition: gpio_ll.h:176
@ GPIO_DISCONNECT
Disconnect pin from all peripherals.
Definition: gpio_ll.h:249
@ GPIO_INPUT
Use pin as input.
Definition: gpio_ll.h:208
@ GPIO_SLEW_SLOWEST
let the output voltage level rise/fall as slow as possible
Definition: gpio_ll.h:340
@ GPIO_SLEW_FAST
let the output voltage level rise/fall fast
Definition: gpio_ll.h:343
@ GPIO_SLEW_SLOW
let the output voltage level rise/fall slowly
Definition: gpio_ll.h:342
@ GPIO_SLEW_FASTEST
let the output voltage level rise/fall as fast as possible
Definition: gpio_ll.h:344
@ GPIO_DRIVE_STRONG
Use a strong drive strength.
Definition: gpio_ll.h:309
@ GPIO_DRIVE_WEAK
Use a weak drive strength.
Definition: gpio_ll.h:308
@ GPIO_DRIVE_STRONGEST
Use the strongest drive strength.
Definition: gpio_ll.h:310
@ GPIO_DRIVE_WEAKEST
Use the weakest drive strength.
Definition: gpio_ll.h:307
unsigned int gpio_t
GPIO type identifier.
Definition: gpio.h:91
@ GPIO_FALLING
emit interrupt on falling flank
@ GPIO_RISING
emit interrupt on rising flank
@ GPIO_BOTH
not supported -> random value
@ GPIO_OD
configure as output in open-drain mode without pull resistor
Definition: gpio.h:123
@ GPIO_IN_PU
configure as input with pull-up resistor
Definition: gpio.h:121
@ GPIO_OD_PU
configure as output in open-drain mode with pull resistor enabled
Definition: gpio.h:125
@ GPIO_IN_PD
configure as input with pull-down resistor
Definition: gpio.h:120
@ I2C_SPEED_NORMAL
normal mode: ~100 kbit/s
Definition: periph_cpu.h:274
@ I2C_SPEED_FAST_PLUS
fast plus mode: ~1000 kbit/s
Definition: periph_cpu.h:276
@ I2C_SPEED_LOW
low speed mode: ~10 kbit/s
Definition: periph_cpu.h:273
@ I2C_SPEED_HIGH
high speed mode: ~3400 kbit/s
Definition: periph_cpu.h:278
@ I2C_SPEED_FAST
fast mode: ~400 kbit/s
Definition: periph_cpu.h:275
@ SPI_MODE_0
CPOL=0, CPHA=0.
Definition: periph_cpu.h:40
@ SPI_MODE_2
CPOL=1, CPHA=0.
Definition: periph_cpu.h:42
@ SPI_MODE_1
CPOL=0, CPHA=1.
Definition: periph_cpu.h:41
@ SPI_MODE_3
CPOL=1, CPHA=1.
Definition: periph_cpu.h:43
@ SPI_CLK_10MHZ
drive the SPI bus with 10MHz
Definition: periph_cpu.h:353
@ SPI_CLK_5MHZ
drive the SPI bus with 5MHz
Definition: periph_cpu.h:352
@ SPI_CLK_400KHZ
drive the SPI bus with 400KHz
Definition: periph_cpu.h:350
@ SPI_CLK_1MHZ
drive the SPI bus with 1MHz
Definition: periph_cpu.h:351
@ SPI_CLK_100KHZ
drive the SPI bus with 100KHz
Definition: periph_cpu.h:349
@ UART_DATA_BITS_6
6 data bits
Definition: periph_cpu.h:516
@ UART_DATA_BITS_5
5 data bits
Definition: periph_cpu.h:515
@ UART_DATA_BITS_7
7 data bits
Definition: periph_cpu.h:517
@ UART_DATA_BITS_8
8 data bits
Definition: periph_cpu.h:518
spi_mode_t
Support SPI modes.
Definition: periph_cpu.h:39
gpio_flank_t
Enumeration of supported GPIO flanks.
uart_data_bits_t
Definition of possible data bits lengths in a UART frame.
Definition: periph_cpu.h:514
uint8_t rtc_get_tamper_event(void)
Get and clear the RTC tamper event that has woken the CPU from Deep Sleep.
uart_rxpad_t
Available values for SERCOM UART RX pad selection.
@ UART_PAD_RX_1
select pad 1
@ UART_PAD_RX_0
use pad 0 for RX line
@ UART_PAD_RX_3
select pad 3
@ UART_PAD_RX_2
select pad 2
void gpio_disable_mux(gpio_t pin)
Disable alternate function (PMUX setting) for a PORT pin.
@ PB
port B
@ PC
port C
@ PA
port A
@ PD
port D
void dma_prepare(dma_t dma, uint8_t width, const void *src, void *dst, size_t num, dma_incr_t incr)
Prepare the DMA channel for an individual transfer.
void dma_init(void)
Initialize DMA.
@ TIMER_TYPE_TC
Timer is a TC timer
@ TIMER_TYPE_TCC
Timer is a TCC timer.
int rtc_tamper_register(gpio_t pin, gpio_flank_t flank)
Enable Tamper Detection IRQs.
#define GPIO_MODE(pr, ie, pe)
Generate GPIO mode bitfields.
static uint8_t sercom_id(const void *sercom)
Return the numeric id of a SERCOM device derived from its address.
void dma_wait(dma_t dma)
Wait for a DMA channel to finish the transfer.
void dma_cancel(dma_t dma)
Cancel an active DMA transfer.
i2c_flag_t
Available SERCOM I2C flag selections.
@ I2C_FLAG_NONE
No flags set.
@ I2C_FLAG_RUN_STANDBY
run SERCOM in standby mode
void dma_prepare_dst(dma_t dma, void *dst, size_t num, bool incr)
Prepare a transfer without modifying the source address settings.
void cpu_pm_cb_leave(int deep)
Called after the power management left a power mode.
void gpio_init_mux(gpio_t pin, gpio_mux_t mux)
Set up alternate function (PMUX setting) for a PORT pin.
void dma_setup(dma_t dma, unsigned trigger, uint8_t prio, bool irq)
Initialize a previously allocated DMA channel with one-time settings.
uint32_t sam0_gclk_freq(uint8_t id)
Returns the frequency of a GCLK provider.
dma_t dma_acquire_channel(void)
Acquire a DMA channel.
spi_misopad_t
Available values for SERCOM SPI MISO pad selection.
@ SPI_PAD_MISO_1
use pad 1 for MISO line
@ SPI_PAD_MISO_2
use pad 2 for MISO line
@ SPI_PAD_MISO_0
use pad 0 for MISO line
@ SPI_PAD_MISO_3
use pad 3 for MISO line
void dma_release_channel(dma_t dma)
Release a previously acquired DMA channel.
void gpio_pm_cb_leave(int deep)
Called after the power management left a power mode.
static void sercom_set_gen(void *sercom, uint8_t gclk)
Configure generator clock for given SERCOM device.
uint8_t rtc_tamper_pin_mask(gpio_t pin)
Get the tamper event mask for a certain pin.
uart_flag_t
Available SERCOM UART flag selections.
@ UART_FLAG_TX_ONDEMAND
Only enable TX pin on demand.
@ UART_FLAG_NONE
No flags set.
@ UART_FLAG_RUN_STANDBY
run SERCOM in standby mode
@ UART_FLAG_WAKEUP
wake from sleep on receive
void sam0_flashpage_aux_reset(const nvm_user_page_t *cfg)
Reset the configuration area, apply a new configuration.
static void sam0_cortexm_sleep(int deep)
Wrapper for cortexm_sleep calling power management callbacks.
static void sercom_clk_dis(void *sercom)
Disable peripheral clock for given SERCOM device.
static bool cpu_woke_from_backup(void)
Returns true if the CPU woke deep sleep (backup/standby)
void cpu_pm_cb_enter(int deep)
Called before the power management enters a power mode.
void dma_append_dst(dma_t dma, DmacDescriptor *next, void *dst, size_t num, bool incr)
Append a second transfer descriptor after the default channel descriptor, copying source and block si...
void sam0_flashpage_aux_write(uint32_t offset, const void *data, size_t len)
Write data to the user configuration area.
uart_txpad_t
Available values for SERCOM UART TX pad selection.
@ UART_PAD_TX_0_RTS_2_CTS_3
TX is pad 0, on top RTS on pad 2 and CTS on pad 3.
@ UART_PAD_TX_0
select pad 0
@ UART_PAD_TX_2
select pad 2
dma_incr_t
Available DMA address increment modes.
@ DMA_INCR_NONE
Don't increment any addresses after a beat.
@ DMA_INCR_DEST
Increment destination address after a beat.
@ DMA_INCR_BOTH
Increment both addresses after a beat.
@ DMA_INCR_SRC
Increment the source address after a beat.
void dma_append(dma_t dma, DmacDescriptor *descriptor, uint8_t width, const void *src, void *dst, size_t num, dma_incr_t incr)
Append a second transfer descriptor after the default channel descriptor.
void rtc_tamper_enable(void)
Enable Tamper Detection IRQs.
void rtc_tamper_init(void)
Power on the RTC (if the RTC/RTT is not otherwise used)
unsigned dma_t
DMA channel type.
void sam0_gclk_enable(uint8_t id)
Enables an on-demand GCLK that has been configured in cpu.c.
void dma_append_src(dma_t dma, DmacDescriptor *next, const void *src, size_t num, bool incr)
Append a second transfer descriptor after the default channel descriptor, copying destination and blo...
gpio_mux_t
Available MUX values for configuring a pin's alternate function.
@ GPIO_MUX_E
select peripheral function E
@ GPIO_MUX_J
select peripheral function J
@ GPIO_MUX_K
select peripheral function K
@ GPIO_MUX_M
select peripheral function M
@ GPIO_MUX_H
select peripheral function H
@ GPIO_MUX_I
select peripheral function I
@ GPIO_MUX_D
select peripheral function D
@ GPIO_MUX_G
select peripheral function G
@ GPIO_MUX_C
select peripheral function C
@ GPIO_MUX_N
select peripheral function N
@ GPIO_MUX_A
select peripheral function A
@ GPIO_MUX_L
select peripheral function L
@ GPIO_MUX_B
select peripheral function B
@ GPIO_MUX_DISABLED
Disable
@ GPIO_MUX_F
select peripheral function F
static void sam0_set_voltage_regulator(sam0_supc_t src)
Switch the internal voltage regulator used for generating the internal MCU voltages.
spi_mosipad_t
Available values for SERCOM SPI MOSI and SCK pad selection.
@ SPI_PAD_MOSI_2_SCK_3
use pad 2 for MOSI, pad 3 for SCK
@ SPI_PAD_MOSI_0_SCK_3
use pad 0 for MOSI, pad 3 for SCK
@ SPI_PAD_MOSI_3_SCK_1
use pad 3 for MOSI, pad 1 for SCK
@ SPI_PAD_MOSI_0_SCK_1
use pad 0 for MOSI, pad 1 for SCK
static void sercom_clk_en(void *sercom)
Enable peripheral clock for given SERCOM device.
sam0_supc_t
Available voltage regulators on the supply controller.
@ SAM0_VREG_BUCK
Buck converter, efficient but may clash with internal fast clock generators (see errata sheets)
@ SAM0_VREG_LDO
LDO, always available but not very power efficient.
void dma_prepare_src(dma_t dma, const void *src, size_t num, bool incr)
Prepare a transfer without modifying the destination address settings.
void dma_start(dma_t dma)
Start a DMA transfer.
void gpio_pm_cb_enter(int deep)
Called before the power management enters a power mode.
ADC Channel Configuration.
uint32_t inputctrl
ADC channel pin multiplexer value
Frequency meter configuration.
uint8_t gclk_src
GCLK source select for reference.
gpio_t pin
GPIO at which the frequency is to be measured.
I2C configuration structure.
Definition: periph_cpu.h:295
uint8_t gclk_src
GCLK source which supplys SERCOM.
gpio_mux_t mux
alternate function (mux)
uint8_t flags
allow SERCOM to run in standby mode
SercomI2cm * dev
pointer to the used I2C device
PWM channel configuration data structure.
gpio_t pin
GPIO pin.
uint8_t chan
TCC channel to use.
gpio_mux_t mux
pin function multiplex value
PWM device configuration.
tc_tcc_cfg_t tim
timer configuration
uint8_t chan_numof
number of channels
const pwm_conf_chan_t * chan
channel configuration
uint8_t gclk_src
GCLK source which clocks TIMER.
NVM User Row Mapping - Dedicated Entries Config values will be applied at power-on.
Definition: periph_cpu.h:176
Ethernet parameters struct.
Gmac * dev
ptr to the device registers
gpio_t mdc
MII interface, clock gpio.
gpio_t mdio
MII interface, data gpio.
gpio_t rst_pin
PHY reset gpio.
gpio_t int_pin
PHY interrupt gpio.
USB peripheral parameters.
gpio_mux_t d_mux
alternate function (mux) for data pins
uint8_t gclk_src
GCLK source which supplys 48 MHz
UsbDevice * device
ptr to the device registers
SDHC peripheral configuration.
gpio_t wp
Write Protect pin (must be GPIO_UNDEF if not connected)
void * sdhc
SDHC peripheral.
gpio_t cd
Card Detect pin (must be GPIO_UNDEF if not connected)
SPI device configuration.
Definition: periph_cpu.h:333
gpio_mux_t miso_mux
alternate function for MISO pin (mux)
spi_misopad_t miso_pad
pad to use for MISO line
gpio_mux_t clk_mux
alternate function for CLK pin (mux)
spi_mosipad_t mosi_pad
pad to use for MOSI and CLK line
gpio_mux_t mosi_mux
alternate function for MOSI pin (mux)
uint8_t gclk_src
GCLK source which supplys SERCOM.
void * dev
pointer to the used SPI device
Timer device configuration.
uint16_t flags
flags for CTRA, e.g.
uint32_t pm_mask
PM_APBCMASK bits to enable Timer.
uint8_t gclk_src
GCLK source which supplys Timer.
IRQn_Type irq
IRQ# of Timer Interrupt.
uint16_t gclk_ctrl
GCLK_CLKCTRL_ID for the Timer.
Tc * dev
pointer to the used Timer device
Common configuration for timer devices.
uint16_t gclk_id
TCn_GCLK_ID.
uint8_t type
Timer type (TC/TCC)
uint32_t pm_mask
PM_APBCMASK bits to enable Timer.
UART device configuration.
Definition: periph_cpu.h:214
gpio_mux_t mux
alternative function for pins
uint8_t gclk_src
GCLK source which supplys SERCOM.
uart_txpad_t tx_pad
pad selection for TX line
SercomUsart * dev
pointer to the used UART device
uart_rxpad_t rx_pad
pad selection for RX line
uart_flag_t flags
set optional SERCOM flags
GPIO pin configuration for SAM0 MCUs.
bool initial_value
Initial value of the output.
uint8_t bits
the raw bits
gpio_pull_t pull
Pull resistor configuration.
gpio_state_t state
State of the pin.
gpio_drive_strength_t drive_strength
Drive strength of the GPIO.