periph_cpu_common.h
9.81 KB
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
/*
* Copyright (C) 2016 Freie Universität Berlin
* 2017 OTA keys S.A.
*
* 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_stm32_common
* @{
*
* @file
* @brief Shared CPU specific definitions for the STM32 family
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Vincent Dupont <vincent@otakeys.com>
*/
#ifndef PERIPH_CPU_COMMON_H
#define PERIPH_CPU_COMMON_H
#include "cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief CPU specific LSI clock speed
*/
#if defined(CPU_FAM_STM32F0) || defined (CPU_FAM_STM32F1) || \
defined(CPU_FAM_STM32F3)
#define CLOCK_LSI (40000U)
#elif defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L0) || \
defined(CPU_FAM_STM32L1)
#define CLOCK_LSI (37000U)
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \
defined(CPU_FAM_STM32L4)
#define CLOCK_LSI (32000U)
#else
#error "error: LSI clock speed not defined for your target CPU"
#endif
/**
* @brief Length of the CPU_ID in octets
*
* This is the same for all members of the stm32 family
*/
#define CPUID_LEN (12U)
/**
* @brief We provide our own pm_off() function for all STM32-based CPUs
*/
#define PROVIDES_PM_LAYERED_OFF
/**
* @brief All STM timers have 4 capture-compare channels
*/
#define TIMER_CHAN (4U)
/**
* @brief Use the shared SPI functions
* @{
*/
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE
#define PERIPH_SPI_NEEDS_TRANSFER_REG
#define PERIPH_SPI_NEEDS_TRANSFER_REGS
/** @} */
/**
* @brief Number of usable low power modes
*/
#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) \
|| defined(CPU_FAM_STM32F4) || defined(DOXYGEN)
#define PM_NUM_MODES (2U)
#endif
/**
* @brief Available peripheral buses
*/
typedef enum {
APB1, /**< APB1 bus */
APB2, /**< APB2 bus */
#if defined(CPU_FAM_STM32L0)
AHB, /**< AHB bus */
IOP, /**< IOP bus */
#elif defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1) \
|| defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
AHB, /**< AHB bus */
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) \
|| defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32F7)
AHB1, /**< AHB1 bus */
AHB2, /**< AHB2 bus */
AHB3 /**< AHB3 bus */
#else
#warning "unsupported stm32XX family"
#endif
} bus_t;
#ifndef DOXYGEN
/**
* @brief Overwrite the default gpio_t type definition
* @{
*/
#define HAVE_GPIO_T
typedef uint32_t gpio_t;
/** @} */
#endif
/**
* @brief Definition of a fitting UNDEF value
*/
#define GPIO_UNDEF (0xffffffff)
/**
* @brief Define a CPU specific GPIO pin generator macro
*/
#define GPIO_PIN(x, y) ((GPIOA_BASE + (x << 10)) | y)
/**
* @brief Define a magic number that tells us to use hardware chip select
*
* We use a random value here, that does clearly differentiate from any possible
* GPIO_PIN(x) value.
*/
#define SPI_HWCS_MASK (0xffffff00)
/**
* @brief Override the default SPI hardware chip select access macro
*
* Since the CPU does only support one single hardware chip select line, we can
* detect the usage of non-valid lines by comparing to SPI_HWCS_VALID.
*/
#define SPI_HWCS(x) (SPI_HWCS_MASK | x)
/**
* @brief Available MUX values for configuring a pin's alternate function
*/
typedef enum {
#ifdef CPU_FAM_STM32F1
GPIO_AF_OUT_PP = 0xb, /**< alternate function output - push-pull */
GPIO_AF_OUT_OD = 0xf, /**< alternate function output - open-drain */
#else
GPIO_AF0 = 0, /**< use alternate function 0 */
GPIO_AF1, /**< use alternate function 1 */
GPIO_AF2, /**< use alternate function 2 */
GPIO_AF3, /**< use alternate function 3 */
GPIO_AF4, /**< use alternate function 4 */
GPIO_AF5, /**< use alternate function 5 */
GPIO_AF6, /**< use alternate function 6 */
GPIO_AF7, /**< use alternate function 7 */
#ifndef CPU_FAM_STM32F0
GPIO_AF8, /**< use alternate function 8 */
GPIO_AF9, /**< use alternate function 9 */
GPIO_AF10, /**< use alternate function 10 */
GPIO_AF11, /**< use alternate function 11 */
GPIO_AF12, /**< use alternate function 12 */
GPIO_AF13, /**< use alternate function 13 */
GPIO_AF14, /**< use alternate function 14 */
GPIO_AF15 /**< use alternate function 15 */
#endif
#endif
} gpio_af_t;
#ifndef CPU_FAM_STM32F1
/**
* @brief Generate GPIO mode bitfields
*
* We use 5 bit to encode the mode:
* - bit 0+1: pin mode (input / output)
* - bit 2+3: pull resistor configuration
* - bit 4: output type (0: push-pull, 1: open-drain)
*/
#define GPIO_MODE(io, pr, ot) ((io << 0) | (pr << 2) | (ot << 4))
#ifndef DOXYGEN
/**
* @brief Override GPIO mode options
* @{
*/
#define HAVE_GPIO_MODE_T
typedef enum {
GPIO_IN = GPIO_MODE(0, 0, 0), /**< input w/o pull R */
GPIO_IN_PD = GPIO_MODE(0, 2, 0), /**< input with pull-down */
GPIO_IN_PU = GPIO_MODE(0, 1, 0), /**< input with pull-up */
GPIO_OUT = GPIO_MODE(1, 0, 0), /**< push-pull output */
GPIO_OD = GPIO_MODE(1, 0, 1), /**< open-drain w/o pull R */
GPIO_OD_PU = GPIO_MODE(1, 1, 1) /**< open-drain with pull-up */
} gpio_mode_t;
/** @} */
/**
* @brief Override flank configuration values
* @{
*/
#define HAVE_GPIO_FLANK_T
typedef enum {
GPIO_RISING = 1, /**< emit interrupt on rising flank */
GPIO_FALLING = 2, /**< emit interrupt on falling flank */
GPIO_BOTH = 3 /**< emit interrupt on both flanks */
} gpio_flank_t;
/** @} */
#endif /* ndef DOXYGEN */
#endif /* ndef CPU_FAM_STM32F1 */
/**
* @brief DAC line configuration data
*/
typedef struct {
gpio_t pin; /**< pin connected to the line */
uint8_t chan; /**< DAC device used for this line */
} dac_conf_t;
/**
* @brief Timer configuration
*/
typedef struct {
TIM_TypeDef *dev; /**< timer device */
uint32_t max; /**< maximum value to count to (16/32 bit) */
uint32_t rcc_mask; /**< corresponding bit in the RCC register */
uint8_t bus; /**< APBx bus the timer is clock from */
uint8_t irqn; /**< global IRQ channel */
} timer_conf_t;
/**
* @brief PWM channel
*/
typedef struct {
gpio_t pin; /**< GPIO pin mapped to this channel */
uint8_t cc_chan; /**< capture compare channel used */
} pwm_chan_t;
/**
* @brief PWM configuration
*/
typedef struct {
TIM_TypeDef *dev; /**< Timer used */
uint32_t rcc_mask; /**< bit in clock enable register */
pwm_chan_t chan[TIMER_CHAN]; /**< channel mapping, set to {GPIO_UNDEF, 0}
* if not used */
gpio_af_t af; /**< alternate function used */
uint8_t bus; /**< APB bus */
} pwm_conf_t;
/**
* @brief Structure for UART configuration data
*/
typedef struct {
USART_TypeDef *dev; /**< UART device base register address */
uint32_t rcc_mask; /**< bit in clock enable register */
gpio_t rx_pin; /**< RX pin */
gpio_t tx_pin; /**< TX pin */
#ifndef CPU_FAM_STM32F1
gpio_af_t rx_af; /**< alternate function for RX pin */
gpio_af_t tx_af; /**< alternate function for TX pin */
#endif
uint8_t bus; /**< APB bus */
uint8_t irqn; /**< IRQ channel */
#if 0 /* TODO */
uint8_t dma_stream; /**< DMA stream used for TX */
uint8_t dma_chan; /**< DMA channel used for TX */
#endif
#ifdef MODULE_STM32_PERIPH_UART_HW_FC
gpio_t cts_pin; /**< CTS pin - set to GPIO_UNDEF when not using HW flow control */
gpio_t rts_pin; /**< RTS pin */
#ifndef CPU_FAM_STM32F1
gpio_af_t cts_af; /**< alternate function for CTS pin */
gpio_af_t rts_af; /**< alternate function for RTS pin */
#endif
#endif
} uart_conf_t;
/**
* @brief Structure for SPI configuration data
*/
typedef struct {
SPI_TypeDef *dev; /**< SPI device base register address */
gpio_t mosi_pin; /**< MOSI pin */
gpio_t miso_pin; /**< MISO pin */
gpio_t sclk_pin; /**< SCLK pin */
gpio_t cs_pin; /**< HWCS pin, set to GPIO_UNDEF if not mapped */
#ifndef CPU_FAM_STM32F1
gpio_af_t af; /**< pin alternate function */
#endif
uint32_t rccmask; /**< bit in the RCC peripheral enable register */
uint8_t apbbus; /**< APBx bus the device is connected to */
} spi_conf_t;
/**
* @brief Get the actual bus clock frequency for the APB buses
*
* @param[in] bus target APBx bus
*
* @return bus clock frequency in Hz
*/
uint32_t periph_apb_clk(uint8_t bus);
/**
* @brief Enable the given peripheral clock
*
* @param[in] bus bus the peripheral is connected to
* @param[in] mask bit in the RCC enable register
*/
void periph_clk_en(bus_t bus, uint32_t mask);
/**
* @brief Disable the given peripheral clock
*
* @param[in] bus bus the peripheral is connected to
* @param[in] mask bit in the RCC enable register
*/
void periph_clk_dis(bus_t bus, uint32_t mask);
/**
* @brief Configure the alternate function for the given pin
*
* @param[in] pin pin to configure
* @param[in] af alternate function to use
*/
void gpio_init_af(gpio_t pin, gpio_af_t af);
/**
* @brief Configure the given pin to be used as ADC input
*
* @param[in] pin pin to configure
*/
void gpio_init_analog(gpio_t pin);
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_CPU_COMMON_H */
/** @} */