periph_cpu_common.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Freie Universität Berlin
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
21 #ifndef PERIPH_CPU_COMMON_H
22 #define PERIPH_CPU_COMMON_H
23 
24 #include "cpu.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
33 #define CPUID_LEN (16U)
34 
39 #define PERIPH_SPI_NEEDS_INIT_CS
40 #define PERIPH_SPI_NEEDS_TRANSFER_BYTE
41 #define PERIPH_SPI_NEEDS_TRANSFER_REG
42 #define PERIPH_SPI_NEEDS_TRANSFER_REGS
43 
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
53 
59 #define HAVE_GPIO_T
60 typedef uint32_t gpio_t;
66 #define GPIO_UNDEF (0xffffffff)
67 
72 #ifdef CPU_FAM_SAML11
73 #define GPIO_PIN(x, y) (((gpio_t)(&PORT_SEC->Group[x])) | y)
74 #else
75 #define GPIO_PIN(x, y) (((gpio_t)(&PORT->Group[x])) | y)
76 #endif
77 
81 enum {
82  PA = 0,
83  PB = 1,
84  PC = 2,
85  PD = 3,
86 };
87 
96 #define GPIO_MODE(pr, ie, pe) (pr | (ie << 1) | (pe << 2))
97 
102 #ifdef CPU_SAML1X
103 #define PM_NUM_MODES (2)
104 #else
105 #define PM_NUM_MODES (3)
106 #endif
107 
109 #ifndef DOXYGEN
110 
113 #define HAVE_GPIO_MODE_T
114 typedef enum {
115  GPIO_IN = GPIO_MODE(0, 1, 0),
116  GPIO_IN_PD = GPIO_MODE(0, 1, 1),
117  GPIO_IN_PU = GPIO_MODE(1, 1, 1),
118  GPIO_OUT = GPIO_MODE(0, 0, 0),
119  GPIO_OD = 0xfe,
120  GPIO_OD_PU = 0xff
121 } gpio_mode_t;
122 
127 #define HAVE_GPIO_FLANK_T
128 typedef enum {
129  GPIO_FALLING = 2,
130  GPIO_RISING = 1,
131  GPIO_BOTH = 3
132 } gpio_flank_t;
134 #endif /* ndef DOXYGEN */
135 
139 #ifndef SAM_MUX_T
140 typedef enum {
141  GPIO_MUX_A = 0x0,
142  GPIO_MUX_B = 0x1,
143  GPIO_MUX_C = 0x2,
144  GPIO_MUX_D = 0x3,
145  GPIO_MUX_E = 0x4,
146  GPIO_MUX_F = 0x5,
147  GPIO_MUX_G = 0x6,
148  GPIO_MUX_H = 0x7,
149 } gpio_mux_t;
150 #endif
151 
155 typedef enum {
160 } uart_rxpad_t;
161 
165 typedef enum {
170 } uart_txpad_t;
171 
175 typedef enum {
179 } uart_flag_t;
180 
181 #ifndef DOXYGEN
182 
189 #define HAVE_UART_DATA_BITS_T
190 typedef enum {
191  UART_DATA_BITS_5 = 0x5,
192  UART_DATA_BITS_6 = 0x6,
193  UART_DATA_BITS_7 = 0x7,
194  UART_DATA_BITS_8 = 0x0,
197 #endif /* ndef DOXYGEN */
198 
199 
203 #ifndef SAM0_UART_TXBUF_SIZE
204 #define SAM0_UART_TXBUF_SIZE (64)
205 #endif
206 
210 typedef struct {
211  SercomUsart *dev;
212  gpio_t rx_pin;
213  gpio_t tx_pin;
214 #ifdef MODULE_SAM0_PERIPH_UART_HW_FC
215  gpio_t rts_pin;
216  gpio_t cts_pin;
217 #endif
222  uint32_t gclk_src;
223 } uart_conf_t;
224 
228 typedef enum {
233 } spi_misopad_t;
234 
238 typedef enum {
243 } spi_mosipad_t;
244 
245 #ifndef DOXYGEN
246 
250 #define HAVE_SPI_MODE_T
251 typedef enum {
252  SPI_MODE_0 = 0x0,
253  SPI_MODE_1 = 0x1,
254  SPI_MODE_2 = 0x2,
255  SPI_MODE_3 = 0x3
256 } spi_mode_t;
263 #define HAVE_SPI_CLK_T
264 typedef enum {
265  SPI_CLK_100KHZ = 100000U,
266  SPI_CLK_400KHZ = 400000U,
267  SPI_CLK_1MHZ = 1000000U,
268  SPI_CLK_5MHZ = 5000000U,
269  SPI_CLK_10MHZ = 10000000U
270 } spi_clk_t;
272 #endif /* ndef DOXYGEN */
273 
277 typedef struct {
278  SercomSpi *dev;
279  gpio_t miso_pin;
280  gpio_t mosi_pin;
281  gpio_t clk_pin;
287 } spi_conf_t;
293 typedef enum {
296 } i2c_flag_t;
297 
298 #ifndef DOXYGEN
299 
303 #define HAVE_I2C_SPEED_T
304 typedef enum {
305  I2C_SPEED_LOW = 10000U,
306  I2C_SPEED_NORMAL = 100000U,
307  I2C_SPEED_FAST = 400000U,
308  I2C_SPEED_FAST_PLUS = 1000000U,
309  I2C_SPEED_HIGH = 3400000U,
310 } i2c_speed_t;
312 #endif /* ndef DOXYGEN */
313 
317 typedef struct {
318  SercomI2cm *dev;
319  i2c_speed_t speed;
320  gpio_t scl_pin;
321  gpio_t sda_pin;
323  uint8_t gclk_src;
324  uint8_t flags;
325 } i2c_conf_t;
326 
330 typedef struct {
331  Tc *dev;
333 #ifdef MCLK
334  volatile uint32_t *mclk;
335  uint32_t mclk_mask;
336  uint16_t gclk_id;
337 #else
338  uint32_t pm_mask;
339  uint16_t gclk_ctrl;
340 #endif
341  uint16_t gclk_src;
342  uint16_t prescaler;
343  uint16_t flags;
344 } tc32_conf_t;
345 
352 void gpio_init_mux(gpio_t pin, gpio_mux_t mux);
353 
361 static inline uint8_t sercom_id(const void *sercom)
362 {
363 #ifdef SERCOM0
364  if (sercom == SERCOM0) {
365  return 0;
366  }
367 #endif
368 #ifdef SERCOM1
369  if (sercom == SERCOM1) {
370  return 1;
371  }
372 #endif
373 #ifdef SERCOM2
374  if (sercom == SERCOM2) {
375  return 2;
376  }
377 #endif
378 #ifdef SERCOM3
379  if (sercom == SERCOM3) {
380  return 3;
381  }
382 #endif
383 #ifdef SERCOM4
384  if (sercom == SERCOM4) {
385  return 4;
386  }
387 #endif
388 #ifdef SERCOM5
389  if (sercom == SERCOM5) {
390  return 5;
391  }
392 #endif
393 #ifdef SERCOM6
394  if (sercom == SERCOM6) {
395  return 6;
396  }
397 #endif
398 #ifdef SERCOM7
399  if (sercom == SERCOM7) {
400  return 7;
401  }
402 #endif
403 
404  /* should not be reached, so fail with assert */
405  assert(false);
406 
407  return SERCOM_INST_NUM;
408 }
409 
415 static inline void sercom_clk_en(void *sercom)
416 {
417  const uint8_t id = sercom_id(sercom);
418 #if defined(CPU_FAM_SAMD21)
419  PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << id);
420 #elif defined (CPU_FAM_SAMD5X)
421  if (id < 2) {
422  MCLK->APBAMASK.reg |= (1 << (id + 12));
423  } else if (id < 4) {
424  MCLK->APBBMASK.reg |= (1 << (id + 7));
425  } else {
426  MCLK->APBDMASK.reg |= (1 << (id - 4));
427  }
428 #else
429  if (id < 5) {
430  MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << id);
431  }
432 #if defined(CPU_FAM_SAML21)
433  else {
434  MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
435  }
436 #endif /* CPU_FAM_SAML21 */
437 #endif
438 }
439 
445 static inline void sercom_clk_dis(void *sercom)
446 {
447  const uint8_t id = sercom_id(sercom);
448 #if defined(CPU_FAM_SAMD21)
449  PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << id);
450 #elif defined (CPU_FAM_SAMD5X)
451  if (id < 2) {
452  MCLK->APBAMASK.reg &= ~(1 << (id + 12));
453  } else if (id < 4) {
454  MCLK->APBBMASK.reg &= ~(1 << (id + 7));
455  } else {
456  MCLK->APBDMASK.reg &= ~(1 << (id - 4));
457  }
458 #else
459  if (id < 5) {
460  MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << id);
461  }
462 #if defined (CPU_FAM_SAML21)
463  else {
464  MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
465  }
466 #endif /* CPU_FAM_SAML21 */
467 #endif
468 }
469 
470 #ifdef CPU_FAM_SAMD5X
471 static inline uint8_t _sercom_gclk_id_core(uint8_t sercom_id) {
472  if (sercom_id < 2)
473  return sercom_id + 7;
474  if (sercom_id < 4)
475  return sercom_id + 21;
476  else
477  return sercom_id + 30;
478 }
479 #endif
480 
487 static inline void sercom_set_gen(void *sercom, uint32_t gclk)
488 {
489  const uint8_t id = sercom_id(sercom);
490 #if defined(CPU_FAM_SAMD21)
491  GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | gclk |
492  (SERCOM0_GCLK_ID_CORE + id));
493  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
494 #elif defined(CPU_FAM_SAMD5X)
495  GCLK->PCHCTRL[_sercom_gclk_id_core(id)].reg = (GCLK_PCHCTRL_CHEN | gclk);
496 #else
497  if (id < 5) {
498  GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + id].reg = (GCLK_PCHCTRL_CHEN | gclk);
499  }
500 #if defined(CPU_FAM_SAML21)
501  else {
502  GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = (GCLK_PCHCTRL_CHEN | gclk);
503  }
504 #endif /* CPU_FAM_SAML21 */
505 #endif
506 }
507 
511 static inline bool cpu_woke_from_backup(void)
512 {
513 #ifdef RSTC_RCAUSE_BACKUP
514  return RSTC->RCAUSE.bit.BACKUP;
515 #else
516  return false;
517 #endif
518 }
519 
523 typedef struct {
524  gpio_t pin;
525  uint32_t muxpos;
527 
531 #if defined(USB_INST_NUM) || defined(DOXYGEN)
532 typedef struct {
533  gpio_t dm;
534  gpio_t dp;
536  UsbDevice *device;
538 #endif /* USB_INST_NUM */
539 
544 /* Limits are in clock cycles according to data sheet.
545  As the WDT is clocked by a 1024 Hz clock, 1 cycle ≈ 1 ms */
546 #define NWDT_TIME_LOWER_LIMIT (8U)
547 #define NWDT_TIME_UPPER_LIMIT (16384U)
548 
554 #define WDT_HAS_STOP (1)
555 
558 #define WDT_HAS_INIT (1)
559 
560 #ifdef __cplusplus
561 }
562 #endif
563 
564 #endif /* PERIPH_CPU_COMMON_H */
565 
select peripheral function D
fast mode: ~400 kbit/s
Definition: i2c.h:184
CPOL=0, CPHA=1.
Definition: spi.h:159
configure as output in push-pull mode
Definition: gpio.h:117
uart_data_bits_t
Definition of possible data bits lengths in a UART frame.
Definition: uart.h:141
high speed mode: ~3400 kbit/s
Definition: i2c.h:186
I2C configuration options.
Definition: periph_cpu.h:128
Tc * dev
pointer to the used Timer device
use pad 0 for MISO line
emit interrupt on rising flank
Definition: gpio.h:131
port A
uart_flag_t
Available SERCOM UART flag selections.
uint32_t gclk_src
GCLK source which supplys SERCOM.
select peripheral function E
gpio_mux_t clk_mux
alternate function for CLK pin (mux)
i2c_flag_t
Available SERCOM I2C flag selections.
select peripheral function B
No flags set.
select pad 3
spi_misopad_t
Available values for SERCOM SPI MISO pad selection.
SercomSpi * dev
pointer to the used SPI device
run SERCOM in standby mode
enum IRQn IRQn_Type
Interrupt Number Definition.
uart_txpad_t
Available values for SERCOM UART TX pad selection.
CPOL=0, CPHA=0.
Definition: spi.h:158
select pad 1
select pad 0
select peripheral function F
i2c_speed_t
Default mapping of I2C bus speed values.
Definition: i2c.h:181
drive the SPI bus with 100KHz
Definition: spi.h:174
uint16_t flags
flags for CTRA, e.g.
port D
spi_mosipad_t mosi_pad
pad to use for MOSI and CLK line
drive the SPI bus with 400KHz
Definition: spi.h:175
gpio_t dm
D- line gpio.
No flags set.
ADC Channel Configuration.
use pad 0 for MISO line
SercomUsart * dev
pointer to the used UART device
emit interrupt on both flanks
Definition: gpio.h:132
select peripheral function H
5 data bits
Definition: uart.h:142
uart_txpad_t tx_pad
pad selection for TX line
select peripheral function C
gpio_flank_t
Definition of possible active flanks for external interrupt mode.
Definition: gpio.h:129
spi_mode_t
Available SPI modes, defining the configuration of clock polarity and clock phase.
Definition: spi.h:157
gpio_mux_t mosi_mux
alternate function for MOSI pin (mux)
select pad 2
uint32_t muxpos
ADC channel pin multiplexer value.
spi_misopad_t miso_pad
pad to use for MISO line
select peripheral function G
select peripheral function A
select pad 2
USB peripheral parameters.
static uint8_t sercom_id(const void *sercom)
Return the numeric id of a SERCOM device derived from its address.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:104
uint32_t pm_mask
PM_APBCMASK bits to enable Timer.
7 data bits
Definition: uart.h:144
spi_clk_t
Available SPI clock speeds.
Definition: spi.h:173
CPOL=1, CPHA=1.
Definition: spi.h:161
uart_rxpad_t
Available values for SERCOM UART RX pad selection.
gpio_mux_t miso_mux
alternate function for MISO pin (mux)
unsigned int gpio_t
GPIO type identifier.
Definition: gpio.h:86
IRQn_Type irq
IRQ# of Timer Interrupt.
uint16_t gclk_ctrl
GCLK_CLKCTRL_ID for the Timer.
gpio_mux_t
Available MUX values for configuring a pin&#39;s alternate function.
gpio_t clk_pin
used CLK pin
drive the SPI bus with 5MHz
Definition: spi.h:177
static void sercom_set_gen(void *sercom, uint32_t gclk)
Configure generator clock for given SERCOM device.
static void sercom_clk_en(void *sercom)
Enable peripheral clock for given SERCOM device.
uart_rxpad_t rx_pad
pad selection for RX line
SercomI2cm * dev
pointer to the used I2C device
drive the SPI bus with 10MHz
Definition: spi.h:178
port B
emit interrupt on falling flank
Definition: gpio.h:130
run SERCOM in standby mode
gpio_t pin
ADC channel pin.
drive the SPI bus with 1MHz
Definition: spi.h:176
8 data bits
Definition: uart.h:145
void gpio_init_mux(gpio_t pin, gpio_mux_t mux)
Set up alternate function (PMUX setting) for a PORT pin.
6 data bits
Definition: uart.h:143
configure as input with pull-up resistor
Definition: gpio.h:116
use pad 0 for RX line
use pad 0 for MISO line
use pad 3 for MOSI, pad 1 for SCK
use pad 0 for MOSI, pad 3 for SCK
uint8_t flags
allow SERCOM to run in standby mode
static bool cpu_woke_from_backup(void)
Returns true if the CPU woke deep sleep (backup/standby)
UART device configuration.
Definition: periph_cpu.h:166
gpio_mode_t
Available pin modes.
Definition: gpio.h:113
configure as input without pull resistor
Definition: gpio.h:114
gpio_mux_t mux
alternate function (mux)
spi_mosipad_t
Available values for SERCOM SPI MOSI and SCK pad selection.
use pad 2 for MOSI, pad 3 for SCK
uint16_t gclk_src
GCLK source which supplys Timer.
low speed mode: ~10 kbit/s
Definition: i2c.h:182
configure as output in open-drain mode without pull resistor
Definition: gpio.h:118
CPOL=1, CPHA=0.
Definition: spi.h:160
uart_flag_t flags
set optional SERCOM flags
SPI configuration structure type.
Definition: periph_cpu.h:271
gpio_mux_t mux
alternative function for pins
port C
TX is pad 0, on top RTS on pad 2 and CTS on pad 3.
normal mode: ~100 kbit/s
Definition: i2c.h:183
use pad 0 for MOSI, pad 1 for SCK
configure as input with pull-down resistor
Definition: gpio.h:115
configure as output in open-drain mode with pull resistor enabled
Definition: gpio.h:120
use pad 0 for MISO line
uint16_t prescaler
prescaler used by the Timer
#define GPIO_MODE(pr, ie, pe)
Generate GPIO mode bitfields.
UsbDevice * device
ptr to the device registers
gpio_mux_t d_mux
alternate function (mux) for data pins
gpio_t dp
D+ line gpio.
static void sercom_clk_dis(void *sercom)
Disable peripheral clock for given SERCOM device.
uint8_t gclk_src
GCLK source which supplys SERCOM.
wake from sleep on receive
Timer device configuration.
fast plus mode: ~1000 kbit/s
Definition: i2c.h:185