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 
202 typedef struct {
203  SercomUsart *dev;
204  gpio_t rx_pin;
205  gpio_t tx_pin;
210  uint32_t gclk_src;
211 } uart_conf_t;
212 
216 typedef enum {
221 } spi_misopad_t;
222 
226 typedef enum {
231 } spi_mosipad_t;
232 
233 #ifndef DOXYGEN
234 
238 #define HAVE_SPI_MODE_T
239 typedef enum {
240  SPI_MODE_0 = 0x0,
241  SPI_MODE_1 = 0x1,
242  SPI_MODE_2 = 0x2,
243  SPI_MODE_3 = 0x3
244 } spi_mode_t;
251 #define HAVE_SPI_CLK_T
252 typedef enum {
253  SPI_CLK_100KHZ = 100000U,
254  SPI_CLK_400KHZ = 400000U,
255  SPI_CLK_1MHZ = 1000000U,
256  SPI_CLK_5MHZ = 5000000U,
257  SPI_CLK_10MHZ = 10000000U
258 } spi_clk_t;
260 #endif /* ndef DOXYGEN */
261 
265 typedef struct {
266  SercomSpi *dev;
267  gpio_t miso_pin;
268  gpio_t mosi_pin;
269  gpio_t clk_pin;
275 } spi_conf_t;
281 typedef enum {
284 } i2c_flag_t;
285 
286 #ifndef DOXYGEN
287 
291 #define HAVE_I2C_SPEED_T
292 typedef enum {
293  I2C_SPEED_LOW = 10000U,
294  I2C_SPEED_NORMAL = 100000U,
295  I2C_SPEED_FAST = 400000U,
296  I2C_SPEED_FAST_PLUS = 1000000U,
297  I2C_SPEED_HIGH = 3400000U,
298 } i2c_speed_t;
300 #endif /* ndef DOXYGEN */
301 
305 typedef struct {
306  SercomI2cm *dev;
307  i2c_speed_t speed;
308  gpio_t scl_pin;
309  gpio_t sda_pin;
311  uint8_t gclk_src;
312  uint8_t flags;
313 } i2c_conf_t;
314 
318 typedef struct {
319  Tc *dev;
321 #ifdef MCLK
322  volatile uint32_t *mclk;
323  uint32_t mclk_mask;
324  uint16_t gclk_id;
325 #else
326  uint32_t pm_mask;
327  uint16_t gclk_ctrl;
328 #endif
329  uint16_t gclk_src;
330  uint16_t prescaler;
331  uint16_t flags;
332 } tc32_conf_t;
333 
340 void gpio_init_mux(gpio_t pin, gpio_mux_t mux);
341 
349 static inline uint8_t sercom_id(const void *sercom)
350 {
351 #ifdef SERCOM0
352  if (sercom == SERCOM0) {
353  return 0;
354  }
355 #endif
356 #ifdef SERCOM1
357  if (sercom == SERCOM1) {
358  return 1;
359  }
360 #endif
361 #ifdef SERCOM2
362  if (sercom == SERCOM2) {
363  return 2;
364  }
365 #endif
366 #ifdef SERCOM3
367  if (sercom == SERCOM3) {
368  return 3;
369  }
370 #endif
371 #ifdef SERCOM4
372  if (sercom == SERCOM4) {
373  return 4;
374  }
375 #endif
376 #ifdef SERCOM5
377  if (sercom == SERCOM5) {
378  return 5;
379  }
380 #endif
381 #ifdef SERCOM6
382  if (sercom == SERCOM6) {
383  return 6;
384  }
385 #endif
386 #ifdef SERCOM7
387  if (sercom == SERCOM7) {
388  return 7;
389  }
390 #endif
391 
392  /* should not be reached, so fail with assert */
393  assert(false);
394 
395  return SERCOM_INST_NUM;
396 }
397 
403 static inline void sercom_clk_en(void *sercom)
404 {
405  const uint8_t id = sercom_id(sercom);
406 #if defined(CPU_FAM_SAMD21)
407  PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << id);
408 #elif defined (CPU_FAM_SAMD5X)
409  if (id < 2) {
410  MCLK->APBAMASK.reg |= (1 << (id + 12));
411  } else if (id < 4) {
412  MCLK->APBBMASK.reg |= (1 << (id + 7));
413  } else {
414  MCLK->APBDMASK.reg |= (1 << (id - 4));
415  }
416 #else
417  if (id < 5) {
418  MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << id);
419  }
420 #if defined(CPU_FAM_SAML21)
421  else {
422  MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
423  }
424 #endif /* CPU_FAM_SAML21 */
425 #endif
426 }
427 
433 static inline void sercom_clk_dis(void *sercom)
434 {
435  const uint8_t id = sercom_id(sercom);
436 #if defined(CPU_FAM_SAMD21)
437  PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << id);
438 #elif defined (CPU_FAM_SAMD5X)
439  if (id < 2) {
440  MCLK->APBAMASK.reg &= ~(1 << (id + 12));
441  } else if (id < 4) {
442  MCLK->APBBMASK.reg &= ~(1 << (id + 7));
443  } else {
444  MCLK->APBDMASK.reg &= ~(1 << (id - 4));
445  }
446 #else
447  if (id < 5) {
448  MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << id);
449  }
450 #if defined (CPU_FAM_SAML21)
451  else {
452  MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
453  }
454 #endif /* CPU_FAM_SAML21 */
455 #endif
456 }
457 
458 #ifdef CPU_FAM_SAMD5X
459 static inline uint8_t _sercom_gclk_id_core(uint8_t sercom_id) {
460  if (sercom_id < 2)
461  return sercom_id + 7;
462  if (sercom_id < 4)
463  return sercom_id + 21;
464  else
465  return sercom_id + 30;
466 }
467 #endif
468 
475 static inline void sercom_set_gen(void *sercom, uint32_t gclk)
476 {
477  const uint8_t id = sercom_id(sercom);
478 #if defined(CPU_FAM_SAMD21)
479  GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | gclk |
480  (SERCOM0_GCLK_ID_CORE + id));
481  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
482 #elif defined(CPU_FAM_SAMD5X)
483  GCLK->PCHCTRL[_sercom_gclk_id_core(id)].reg = (GCLK_PCHCTRL_CHEN | gclk);
484 #else
485  if (id < 5) {
486  GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + id].reg = (GCLK_PCHCTRL_CHEN | gclk);
487  }
488 #if defined(CPU_FAM_SAML21)
489  else {
490  GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = (GCLK_PCHCTRL_CHEN | gclk);
491  }
492 #endif /* CPU_FAM_SAML21 */
493 #endif
494 }
495 
499 static inline bool cpu_woke_from_backup(void)
500 {
501 #ifdef RSTC_RCAUSE_BACKUP
502  return RSTC->RCAUSE.bit.BACKUP;
503 #else
504  return false;
505 #endif
506 }
507 
511 typedef struct {
512  gpio_t pin;
513  uint32_t muxpos;
515 
519 #if defined(USB_INST_NUM) || defined(DOXYGEN)
520 typedef struct {
521  gpio_t dm;
522  gpio_t dp;
524  UsbDevice *device;
526 #endif /* USB_INST_NUM */
527 
532 /* Limits are in clock cycles according to data sheet.
533  As the WDT is clocked by a 1024 Hz clock, 1 cycle ≈ 1 ms */
534 #define NWDT_TIME_LOWER_LIMIT (8U)
535 #define NWDT_TIME_UPPER_LIMIT (16384U)
536 
542 #define WDT_HAS_STOP (1)
543 
546 #define WDT_HAS_INIT (1)
547 
548 #ifdef __cplusplus
549 }
550 #endif
551 
552 #endif /* PERIPH_CPU_COMMON_H */
553 
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
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)
spi_clk_t
SPI clock speed values.
Definition: periph_cpu.h:83
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