-
Notifications
You must be signed in to change notification settings - Fork 2k
/
periph_cpu.h
369 lines (332 loc) · 9.9 KB
/
periph_cpu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*
* Copyright (C) 2015-2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_efm32
* @{
*
* @file
* @brief CPU specific definitions for internal peripheral handling
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Bas Stottelaar <basstottelaar@gmail.com>
*/
#ifndef PERIPH_CPU_H
#define PERIPH_CPU_H
#include "mutex.h"
#include "cpu_conf.h"
#include "em_adc.h"
#include "em_cmu.h"
#include "em_device.h"
#include "em_gpio.h"
#include "em_usart.h"
#ifdef _SILICON_LABS_32B_SERIES_0
#include "em_dac.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable support for Low-power peripherals (if supported by CPU).
* @{
*/
#ifndef LOW_POWER_ENABLED
#define LOW_POWER_ENABLED (1)
#endif
/** @} */
/**
* @brief Internal macro for combining ADC resolution (x) with number of
* shifts (y).
*/
#define ADC_MODE(x, y) ((y << 4) | x)
/**
* @brief Internal define to note that resolution is not supported.
*/
#define ADC_MODE_UNDEF (0xff)
#ifndef DOXYGEN
/**
* @brief Possible ADC resolution settings
* @{
*/
#define HAVE_ADC_RES_T
typedef enum {
ADC_RES_6BIT = ADC_MODE(adcRes6Bit, 0), /**< ADC resolution: 6 bit */
ADC_RES_8BIT = ADC_MODE(adcRes8Bit, 0), /**< ADC resolution: 8 bit */
ADC_RES_10BIT = ADC_MODE(adcRes12Bit, 2), /**< ADC resolution: 10 bit (shifted from 12 bit) */
ADC_RES_12BIT = ADC_MODE(adcRes12Bit, 0), /**< ADC resolution: 12 bit */
ADC_RES_14BIT = ADC_MODE_UNDEF, /**< ADC resolution: 14 bit (unsupported) */
ADC_RES_16BIT = ADC_MODE_UNDEF, /**< ADC resolution: 16 bit (unsupported) */
} adc_res_t;
/** @} */
#endif /* ndef DOXYGEN */
/**
* @brief ADC device configuration
*/
typedef struct {
ADC_TypeDef *dev; /**< ADC device used */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
} adc_conf_t;
/**
* @brief ADC channel configuration
*/
typedef struct {
uint8_t dev; /**< device index */
#ifdef _SILICON_LABS_32B_SERIES_0
ADC_SingleInput_TypeDef input; /**< input channel */
#else
ADC_PosSel_TypeDef input; /**< input channel */
#endif
ADC_Ref_TypeDef reference; /**< channel voltage reference */
ADC_AcqTime_TypeDef acq_time; /**< channel acquisition time */
} adc_chan_conf_t;
/**
* @brief Length of CPU ID in octets.
*/
#define CPUID_LEN (8U)
#if defined(DAC_COUNT) && DAC_COUNT > 0
/**
* @brief DAC device configuration
*/
typedef struct {
DAC_TypeDef *dev; /**< DAC device used */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
} dac_conf_t;
/**
* @brief DAC channel configuration
*/
typedef struct {
uint8_t dev; /**< device index */
uint8_t index; /**< channel index */
DAC_Ref_TypeDef ref; /**< channel voltage reference */
} dac_chan_conf_t;
#endif
/**
* @brief Define a custom type for GPIO pins.
* @{
*/
#define HAVE_GPIO_T
typedef uint32_t gpio_t;
/** @} */
/**
* @brief Definition of a fitting UNDEF value.
*/
#define GPIO_UNDEF (0xffffffff)
/**
* @brief Mandatory function for defining a GPIO pins.
*/
#define GPIO_PIN(x, y) ((gpio_t) ((x << 4) | y))
/**
* @brief Internal macro for combining pin mode (x) and pull-up/down (y).
*/
#define GPIO_MODE(x, y) ((x << 1) | y)
/**
* @brief Available ports on the EFM32.
*/
enum {
#if (_GPIO_PORT_A_PIN_COUNT > 0)
PA = gpioPortA, /**< port A */
#endif
#if (_GPIO_PORT_B_PIN_COUNT > 0)
PB = gpioPortB, /**< port B */
#endif
#if (_GPIO_PORT_C_PIN_COUNT > 0)
PC = gpioPortC, /**< port C */
#endif
#if (_GPIO_PORT_D_PIN_COUNT > 0)
PD = gpioPortD, /**< port D */
#endif
#if (_GPIO_PORT_E_PIN_COUNT > 0)
PE = gpioPortE, /**< port E */
#endif
#if (_GPIO_PORT_F_PIN_COUNT > 0)
PF = gpioPortF, /**< port F */
#endif
#if (_GPIO_PORT_G_PIN_COUNT > 0)
PG = gpioPortG, /**< port G */
#endif
#if (_GPIO_PORT_H_PIN_COUNT > 0)
PH = gpioPortH, /**< port H */
#endif
#if (_GPIO_PORT_I_PIN_COUNT > 0)
PI = gpioPortI, /**< port I */
#endif
#if (_GPIO_PORT_J_PIN_COUNT > 0)
PJ = gpioPortJ, /**< port J */
#endif
#if (_GPIO_PORT_K_PIN_COUNT > 0)
PK = gpioPortK /**< port K */
#endif
};
#ifndef DOXYGEN
/**
* @brief Override direction values.
* @{
*/
#define HAVE_GPIO_MODE_T
typedef enum {
GPIO_IN = GPIO_MODE(gpioModeInput, 0), /**< pin as input */
GPIO_IN_PD = GPIO_MODE(gpioModeInputPull, 0), /**< pin as input with pull-down */
GPIO_IN_PU = GPIO_MODE(gpioModeInputPull, 1), /**< pin as input with pull-up */
GPIO_OUT = GPIO_MODE(gpioModePushPull, 0), /**< pin as output */
GPIO_OD = GPIO_MODE(gpioModeWiredAnd, 1), /**< pin as open-drain */
GPIO_OD_PU = GPIO_MODE(gpioModeWiredAndPullUp, 1), /**< pin as open-drain with pull-up */
} gpio_mode_t;
/** @} */
/**
* @brief Override active flank configuration values.
* @{
*/
#define HAVE_GPIO_FLANK_T
typedef enum {
GPIO_FALLING = 2, /**< emit interrupt on falling flank */
GPIO_RISING = 1, /**< emit interrupt on rising flank */
GPIO_BOTH = 3 /**< emit interrupt on both flanks */
} gpio_flank_t;
/** @} */
#endif /* ndef DOXYGEN */
/**
* @brief Override hardware crypto supported methods.
* @{
*/
#define HAVE_HWCRYPTO_AES128
#ifdef AES_CTRL_AES256
#define HAVE_HWCRYPTO_AES256
#endif
#ifdef _SILICON_LABS_32B_SERIES_1
#define HAVE_HWCRYPTO_SHA1
#define HAVE_HWCRYPTO_SHA256
#endif
/** @} */
#ifndef DOXYGEN
/**
* @brief Override I2C speed values.
* @{
*/
#define HAVE_I2C_SPEED_T
typedef enum {
I2C_SPEED_LOW = 10000, /**< low speed mode: ~10kbit/s */
I2C_SPEED_NORMAL = 100000, /**< normal mode: ~100kbit/s */
I2C_SPEED_FAST = 400000, /**< fast mode: ~400kbit/sj */
I2C_SPEED_FAST_PLUS = 1000000, /**< fast plus mode: ~1Mbit/s */
I2C_SPEED_HIGH = 3400000, /**< high speed mode: ~3.4Mbit/s */
} i2c_speed_t;
/** @} */
#endif /* ndef DOXYGEN */
/**
* @brief I2C device configuration.
*/
typedef struct {
I2C_TypeDef *dev; /**< USART device used */
gpio_t sda_pin; /**< pin used for SDA */
gpio_t scl_pin; /**< pin used for SCL */
uint32_t loc; /**< location of I2C pins */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
IRQn_Type irq; /**< the devices base IRQ channel */
} i2c_conf_t;
/**
* @brief PWM channel configuration.
*/
typedef struct {
uint8_t index; /**< TIMER channel to use */
gpio_t pin; /**< pin used for pwm */
uint32_t loc; /**< location of the pin */
} pwm_chan_conf_t;
/**
* @brief PWM device configuration.
*/
typedef struct {
TIMER_TypeDef *dev; /**< TIMER device used */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
IRQn_Type irq; /**< the devices base IRQ channel */
uint8_t channels; /**< the number of available channels */
const pwm_chan_conf_t* channel; /**< pointer to first channel config */
} pwm_conf_t;
#ifndef DOXYGEN
/**
* @brief Override SPI clocks.
* @{
*/
#define HAVE_SPI_MODE_T
typedef enum {
SPI_MODE_0 = usartClockMode0,
SPI_MODE_1 = usartClockMode1,
SPI_MODE_2 = usartClockMode2,
SPI_MODE_3 = usartClockMode3
} spi_mode_t;
/** @} */
/**
* @brief Define a set of pre-defined SPI clock speeds.
* @{
*/
#define HAVE_SPI_CLK_T
typedef enum {
SPI_CLK_100KHZ = 100000, /**< drive the SPI bus with 100KHz */
SPI_CLK_400KHZ = 400000, /**< drive the SPI bus with 400KHz */
SPI_CLK_1MHZ = 1000000, /**< drive the SPI bus with 1MHz */
SPI_CLK_5MHZ = 5000000, /**< drive the SPI bus with 5MHz */
SPI_CLK_10MHZ = 10000000 /**< drive the SPI bus with 10MHz */
} spi_clk_t;
/** @} */
#endif /* ndef DOXYGEN */
/**
* @brief SPI device configuration.
*/
typedef struct {
USART_TypeDef *dev; /**< USART device used */
gpio_t mosi_pin; /**< pin used for MOSI */
gpio_t miso_pin; /**< pin used for MISO */
gpio_t clk_pin; /**< pin used for CLK */
uint32_t loc; /**< location of USART pins */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
IRQn_Type irq; /**< the devices base IRQ channel */
} spi_dev_t;
/**
* @brief Declare needed generic SPI functions.
* @{
*/
#define PERIPH_SPI_NEEDS_INIT_CS
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE
#define PERIPH_SPI_NEEDS_TRANSFER_REG
#define PERIPH_SPI_NEEDS_TRANSFER_REGS
/** @} */
/**
* @brief Define timer configuration values
*
* @note The two timers must be adjacent to each other (e.g. TIMER0 and
* TIMER1, or TIMER2 and TIMER3, etc.).
* @{
*/
typedef struct {
TIMER_TypeDef *dev; /**< Timer device used */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
} timer_dev_t;
typedef struct {
timer_dev_t prescaler; /**< the lower numbered neighboring timer */
timer_dev_t timer; /**< the higher numbered timer */
IRQn_Type irq; /**< number of the higher timer IRQ channel */
} timer_conf_t;
/** @} */
/**
* @brief UART device configuration.
*/
typedef struct {
void *dev; /**< UART, USART or LEUART device used */
gpio_t rx_pin; /**< pin used for RX */
gpio_t tx_pin; /**< pin used for TX */
uint32_t loc; /**< location of USART pins */
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
IRQn_Type irq; /**< the devices base IRQ channel */
} uart_conf_t;
/**
* @brief Number of usable power modes.
*/
#define PM_NUM_MODES (3U)
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_CPU_H */
/** @} */