sam0_common/include/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 #define GPIO_PIN(x, y) (((gpio_t)(&PORT->Group[x])) | y)
73 
77 enum {
78  PA = 0,
79  PB = 1,
80  PC = 2,
81 };
82 
91 #define GPIO_MODE(pr, ie, pe) (pr | (ie << 1) | (pe << 2))
92 
97 #define PM_NUM_MODES (3)
98 
100 #ifndef DOXYGEN
101 
104 #define HAVE_GPIO_MODE_T
105 typedef enum {
106  GPIO_IN = GPIO_MODE(0, 1, 0),
107  GPIO_IN_PD = GPIO_MODE(0, 1, 1),
108  GPIO_IN_PU = GPIO_MODE(1, 1, 1),
109  GPIO_OUT = GPIO_MODE(0, 0, 0),
110  GPIO_OD = 0xfe,
111  GPIO_OD_PU = 0xff
112 } gpio_mode_t;
113 
118 #define HAVE_GPIO_FLANK_T
119 typedef enum {
120  GPIO_FALLING = 2,
121  GPIO_RISING = 1,
122  GPIO_BOTH = 3
123 } gpio_flank_t;
125 #endif /* ndef DOXYGEN */
126 
130 typedef enum {
131  GPIO_MUX_A = 0x0,
132  GPIO_MUX_B = 0x1,
133  GPIO_MUX_C = 0x2,
134  GPIO_MUX_D = 0x3,
135  GPIO_MUX_E = 0x4,
136  GPIO_MUX_F = 0x5,
137  GPIO_MUX_G = 0x6,
138  GPIO_MUX_H = 0x7,
139 } gpio_mux_t;
140 
144 typedef enum {
149 } uart_rxpad_t;
150 
154 typedef enum {
159 } uart_txpad_t;
160 
164 typedef enum {
168 } uart_flag_t;
169 
173 typedef struct {
174  SercomUsart *dev;
175  gpio_t rx_pin;
176  gpio_t tx_pin;
181  uint32_t gclk_src;
182 } uart_conf_t;
183 
187 typedef enum {
192 } spi_misopad_t;
193 
197 typedef enum {
202 } spi_mosipad_t;
203 
208 #define HAVE_SPI_MODE_T
209 typedef enum {
210  SPI_MODE_0 = 0x0,
211  SPI_MODE_1 = 0x1,
212  SPI_MODE_2 = 0x2,
213  SPI_MODE_3 = 0x3
214 } spi_mode_t;
221 #define HAVE_SPI_CLK_T
222 typedef enum {
223  SPI_CLK_100KHZ = 100000U,
224  SPI_CLK_400KHZ = 400000U,
225  SPI_CLK_1MHZ = 1000000U,
226  SPI_CLK_5MHZ = 5000000U,
227  SPI_CLK_10MHZ = 10000000U
228 } spi_clk_t;
234 typedef struct {
235  SercomSpi *dev;
236  gpio_t miso_pin;
237  gpio_t mosi_pin;
238  gpio_t clk_pin;
244 } spi_conf_t;
250 typedef enum {
253 } i2c_flag_t;
254 
259 #define HAVE_I2C_SPEED_T
260 typedef enum {
261  I2C_SPEED_LOW = 10000U,
262  I2C_SPEED_NORMAL = 100000U,
263  I2C_SPEED_FAST = 400000U,
264  I2C_SPEED_FAST_PLUS = 1000000U,
265  I2C_SPEED_HIGH = 3400000U,
266 } i2c_speed_t;
272 typedef struct {
273  SercomI2cm *dev;
274  i2c_speed_t speed;
275  gpio_t scl_pin;
276  gpio_t sda_pin;
278  uint8_t gclk_src;
279  uint8_t flags;
280 } i2c_conf_t;
281 
288 void gpio_init_mux(gpio_t pin, gpio_mux_t mux);
289 
297 static inline int sercom_id(void *sercom)
298 {
299 #if defined(CPU_FAM_SAMD21)
300  return ((((uint32_t)sercom) >> 10) & 0x7) - 2;
301 #elif defined(CPU_FAM_SAML21) || defined(CPU_FAM_SAMR30)
302  /* Left side handles SERCOM0-4 while right side handles unaligned address of SERCOM5 */
303  return ((((uint32_t)sercom) >> 10) & 0x7) + ((((uint32_t)sercom) >> 22) & 0x04);
304 #endif
305 }
306 
312 static inline void sercom_clk_en(void *sercom)
313 {
314 #if defined(CPU_FAM_SAMD21)
315  PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << sercom_id(sercom));
316 #elif defined(CPU_FAM_SAML21) || defined(CPU_FAM_SAMR30)
317  if (sercom_id(sercom) < 5) {
318  MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << sercom_id(sercom));
319  } else {
320  MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
321  }
322 #endif
323 }
324 
330 static inline void sercom_clk_dis(void *sercom)
331 {
332 #if defined(CPU_FAM_SAMD21)
333  PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << sercom_id(sercom));
334 #elif defined(CPU_FAM_SAML21) || defined(CPU_FAM_SAMR30)
335  if (sercom_id(sercom) < 5) {
336  MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom_id(sercom));
337  } else {
338  MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
339  }
340 #endif
341 }
342 
349 static inline void sercom_set_gen(void *sercom, uint32_t gclk)
350 {
351 #if defined(CPU_FAM_SAMD21)
352  GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | gclk |
353  (SERCOM0_GCLK_ID_CORE + sercom_id(sercom)));
354  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
355 #elif defined(CPU_FAM_SAML21) || defined(CPU_FAM_SAMR30)
356  if (sercom_id(sercom) < 5) {
357  GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + sercom_id(sercom)].reg =
358  (GCLK_PCHCTRL_CHEN | gclk);
359  } else {
360  GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg =
361  (GCLK_PCHCTRL_CHEN | gclk);
362  }
363 #endif
364 }
365 
369 typedef struct {
370  gpio_t pin;
371  uint32_t muxpos;
373 
374 
375 #ifdef __cplusplus
376 }
377 #endif
378 
379 #endif /* PERIPH_CPU_COMMON_H */
380 
select peripheral function D
high speed mode: ~3.4Mbit/s
static int sercom_id(void *sercom)
Return the numeric id of a SERCOM device derived from its address.
I2C configuration options.
emit interrupt on rising flank
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
spi_misopad_t
Available values for SERCOM SPI MISO pad selection.
SercomSpi * dev
pointer to the used SPI device
uart_txpad_t
Available values for SERCOM UART TX pad selection.
select peripheral function F
drive the SPI bus with 100KHz
spi_mosipad_t mosi_pad
pad to use for MOSI and CLK line
drive the SPI bus with 400KHz
ADC Channel Configuration.
SercomUsart * dev
pointer to the used UART device
emit interrupt on both flanks
select peripheral function H
uart_txpad_t tx_pad
pad selection for TX line
select peripheral function C
gpio_mux_t mosi_mux
alternate function for MOSI pin (mux)
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
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:69
gpio_mux_t
Available MUX values for configuring a pin&#39;s alternate function.
drive the SPI bus with 5MHz
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
emit interrupt on falling flank
drive the SPI bus with 1MHz
void gpio_init_mux(gpio_t pin, gpio_mux_t mux)
Set up alternate function (PMUX setting) for a PORT pin.
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
UART device configuration.
input, no pull
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
low speed mode: ~10kbit/s
not supported
uart_flag_t flags
set optional SERCOM flags
SPI module configuration options.
gpio_mux_t mux
alternative function for pins
TX is pad 0, on top RTS on pad 2 and CTS on pad 3.
use pad 0 for MOSI, pad 1 for SCK
input, pull-down
#define GPIO_MODE(pr, ie, pe)
Generate GPIO mode bitfields.
static void sercom_clk_dis(void *sercom)
Disable peripheral clock for given SERCOM device.
uint8_t gclk_src
GCLK source which supplys SERCOM.