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 
20 #ifndef PERIPH_CPU_COMMON_H
21 #define PERIPH_CPU_COMMON_H
22 
23 #include "cpu.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
32 #define CPUID_LEN (16U)
33 
38 #define PERIPH_SPI_NEEDS_INIT_CS
39 #define PERIPH_SPI_NEEDS_TRANSFER_BYTE
40 #define PERIPH_SPI_NEEDS_TRANSFER_REG
41 #define PERIPH_SPI_NEEDS_TRANSFER_REGS
42 
48 #define HAVE_GPIO_T
49 typedef uint32_t gpio_t;
55 #define GPIO_UNDEF (0xffffffff)
56 
61 #define GPIO_PIN(x, y) (((gpio_t)(&PORT->Group[x])) | y)
62 
66 enum {
67  PA = 0,
68  PB = 1,
69  PC = 2,
70 };
71 
80 #define GPIO_MODE(pr, ie, pe) (pr | (ie << 1) | (pe << 2))
81 
86 #define PM_NUM_MODES (3)
87 
89 #ifndef DOXYGEN
90 
93 #define HAVE_GPIO_MODE_T
94 typedef enum {
95  GPIO_IN = GPIO_MODE(0, 1, 0),
96  GPIO_IN_PD = GPIO_MODE(0, 1, 1),
97  GPIO_IN_PU = GPIO_MODE(1, 1, 1),
98  GPIO_OUT = GPIO_MODE(0, 0, 0),
99  GPIO_OD = 0xfe,
100  GPIO_OD_PU = 0xff
101 } gpio_mode_t;
102 
107 #define HAVE_GPIO_FLANK_T
108 typedef enum {
109  GPIO_FALLING = 2,
110  GPIO_RISING = 1,
111  GPIO_BOTH = 3
112 } gpio_flank_t;
114 #endif /* ndef DOXYGEN */
115 
119 typedef enum {
120  GPIO_MUX_A = 0x0,
121  GPIO_MUX_B = 0x1,
122  GPIO_MUX_C = 0x2,
123  GPIO_MUX_D = 0x3,
124  GPIO_MUX_E = 0x4,
125  GPIO_MUX_F = 0x5,
126  GPIO_MUX_G = 0x6,
127  GPIO_MUX_H = 0x7,
128 } gpio_mux_t;
129 
133 typedef enum {
138 } uart_rxpad_t;
139 
143 typedef enum {
148 } uart_txpad_t;
149 
153 typedef enum {
157 } uart_flag_t;
158 
162 typedef struct {
163  SercomUsart *dev;
164  gpio_t rx_pin;
165  gpio_t tx_pin;
170  uint32_t gclk_src;
171 } uart_conf_t;
172 
176 typedef enum {
181 } spi_misopad_t;
182 
186 typedef enum {
191 } spi_mosipad_t;
192 
197 #define HAVE_SPI_MODE_T
198 typedef enum {
199  SPI_MODE_0 = 0x0,
200  SPI_MODE_1 = 0x1,
201  SPI_MODE_2 = 0x2,
202  SPI_MODE_3 = 0x3
203 } spi_mode_t;
210 #define HAVE_SPI_CLK_T
211 typedef enum {
212  SPI_CLK_100KHZ = 100000U,
213  SPI_CLK_400KHZ = 400000U,
214  SPI_CLK_1MHZ = 1000000U,
215  SPI_CLK_5MHZ = 5000000U,
216  SPI_CLK_10MHZ = 10000000U
217 } spi_clk_t;
223 typedef struct {
224  SercomSpi *dev;
225  gpio_t miso_pin;
226  gpio_t mosi_pin;
227  gpio_t clk_pin;
233 } spi_conf_t;
234 
241 void gpio_init_mux(gpio_t pin, gpio_mux_t mux);
242 
250 static inline int sercom_id(void *sercom)
251 {
252 #if defined(CPU_FAM_SAMD21)
253  return ((((uint32_t)sercom) >> 10) & 0x7) - 2;
254 #elif defined(CPU_FAM_SAML21)
255  return ((((uint32_t)sercom) >> 10) & 0x7);
256 #endif
257 }
258 
264 static inline void sercom_clk_en(void *sercom)
265 {
266 #if defined(CPU_FAM_SAMD21)
267  PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << sercom_id(sercom));
268 #elif defined(CPU_FAM_SAML21)
269  if (sercom_id(sercom) < 5) {
270  MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << sercom_id(sercom));
271  } else {
272  MCLK->APBDMASK.reg |= (MCLK_APBDMASK_SERCOM5);
273  }
274 #endif
275 }
276 
282 static inline void sercom_clk_dis(void *sercom)
283 {
284 #if defined(CPU_FAM_SAMD21)
285  PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << sercom_id(sercom));
286 #elif defined(CPU_FAM_SAML21)
287  if (sercom_id(sercom) < 5) {
288  MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom_id(sercom));
289  } else {
290  MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_SERCOM5);
291  }
292 #endif
293 }
294 
301 static inline void sercom_set_gen(void *sercom, uint32_t gclk)
302 {
303 #if defined(CPU_FAM_SAMD21)
304  GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | gclk |
305  (SERCOM0_GCLK_ID_CORE + sercom_id(sercom)));
306  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
307 #elif defined(CPU_FAM_SAML21)
308  GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + sercom_id(sercom)].reg =
309  (GCLK_PCHCTRL_CHEN | gclk);
310 #endif
311 }
312 
316 typedef struct {
317  gpio_t pin;
318  uint32_t muxpos;
320 
321 
322 #ifdef __cplusplus
323 }
324 #endif
325 
326 #endif /* PERIPH_CPU_COMMON_H */
327 
select peripheral function D
static int sercom_id(void *sercom)
Return the numeric id of a SERCOM device derived from its address.
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)
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
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
UART device configuration.
input, no pull
spi_mosipad_t
Available values for SERCOM SPI MOSI and SCK pad selection.
use pad 2 for MOSI, pad 3 for SCK
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.