5 #define TWR_GPIO_CHANNEL_COUNT 23
7 #define TWR_GPIO_PORT_P0 GPIOA
8 #define TWR_GPIO_PORT_P1 GPIOA
9 #define TWR_GPIO_PORT_P2 GPIOA
10 #define TWR_GPIO_PORT_P3 GPIOA
11 #define TWR_GPIO_PORT_P4 GPIOA
12 #define TWR_GPIO_PORT_P5 GPIOA
13 #define TWR_GPIO_PORT_P6 GPIOB
14 #define TWR_GPIO_PORT_P7 GPIOA
15 #define TWR_GPIO_PORT_P8 GPIOB
16 #define TWR_GPIO_PORT_P9 GPIOB
17 #define TWR_GPIO_PORT_P10 GPIOA
18 #define TWR_GPIO_PORT_P11 GPIOA
19 #define TWR_GPIO_PORT_P12 GPIOB
20 #define TWR_GPIO_PORT_P13 GPIOB
21 #define TWR_GPIO_PORT_P14 GPIOB
22 #define TWR_GPIO_PORT_P15 GPIOB
23 #define TWR_GPIO_PORT_P16 GPIOB
24 #define TWR_GPIO_PORT_P17 GPIOB
25 #define TWR_GPIO_PORT_LED GPIOH
26 #define TWR_GPIO_PORT_BUTTON GPIOA
27 #define TWR_GPIO_PORT_INT GPIOC
28 #define TWR_GPIO_PORT_SCL0 GPIOB
29 #define TWR_GPIO_PORT_SDA0 GPIOB
31 #define TWR_GPIO_POS_P0 0
32 #define TWR_GPIO_POS_P1 1
33 #define TWR_GPIO_POS_P2 2
34 #define TWR_GPIO_POS_P3 3
35 #define TWR_GPIO_POS_P4 4
36 #define TWR_GPIO_POS_P5 5
37 #define TWR_GPIO_POS_P6 1
38 #define TWR_GPIO_POS_P7 6
39 #define TWR_GPIO_POS_P8 0
40 #define TWR_GPIO_POS_P9 2
41 #define TWR_GPIO_POS_P10 10
42 #define TWR_GPIO_POS_P11 9
43 #define TWR_GPIO_POS_P12 14
44 #define TWR_GPIO_POS_P13 15
45 #define TWR_GPIO_POS_P14 13
46 #define TWR_GPIO_POS_P15 12
47 #define TWR_GPIO_POS_P16 8
48 #define TWR_GPIO_POS_P17 9
49 #define TWR_GPIO_POS_LED 1
50 #define TWR_GPIO_POS_BUTTON 8
51 #define TWR_GPIO_POS_INT 13
52 #define TWR_GPIO_POS_SCL0 10
53 #define TWR_GPIO_POS_SDA0 11
55 #define _TWR_GPIO_MODE_MASK 0xf
56 #define _TWR_GPIO_MODE_AF_POS 4
57 #define _twr_gpio_64_bit_pos(__CHANNEL__) (_twr_gpio_32_bit_pos[(__CHANNEL__)] << 1)
59 GPIO_TypeDef *
const twr_gpio_port[TWR_GPIO_CHANNEL_COUNT] =
86 static const uint8_t _twr_gpio_iopenr_mask[TWR_GPIO_CHANNEL_COUNT] =
113 static const uint16_t _twr_gpio_16_bit_pos[TWR_GPIO_CHANNEL_COUNT] =
140 static const uint16_t _twr_gpio_32_bit_pos[TWR_GPIO_CHANNEL_COUNT] =
152 2 * TWR_GPIO_POS_P10,
153 2 * TWR_GPIO_POS_P11,
154 2 * TWR_GPIO_POS_P12,
155 2 * TWR_GPIO_POS_P13,
156 2 * TWR_GPIO_POS_P14,
157 2 * TWR_GPIO_POS_P15,
158 2 * TWR_GPIO_POS_P16,
159 2 * TWR_GPIO_POS_P17,
160 2 * TWR_GPIO_POS_LED,
161 2 * TWR_GPIO_POS_BUTTON,
162 2 * TWR_GPIO_POS_INT,
163 2 * TWR_GPIO_POS_SCL0,
164 2 * TWR_GPIO_POS_SDA0
167 const uint16_t twr_gpio_16_bit_mask[TWR_GPIO_CHANNEL_COUNT] =
169 1 << TWR_GPIO_POS_P0,
170 1 << TWR_GPIO_POS_P1,
171 1 << TWR_GPIO_POS_P2,
172 1 << TWR_GPIO_POS_P3,
173 1 << TWR_GPIO_POS_P4,
174 1 << TWR_GPIO_POS_P5,
175 1 << TWR_GPIO_POS_P6,
176 1 << TWR_GPIO_POS_P7,
177 1 << TWR_GPIO_POS_P8,
178 1 << TWR_GPIO_POS_P9,
179 1 << TWR_GPIO_POS_P10,
180 1 << TWR_GPIO_POS_P11,
181 1 << TWR_GPIO_POS_P12,
182 1 << TWR_GPIO_POS_P13,
183 1 << TWR_GPIO_POS_P14,
184 1 << TWR_GPIO_POS_P15,
185 1 << TWR_GPIO_POS_P16,
186 1 << TWR_GPIO_POS_P17,
187 1 << TWR_GPIO_POS_LED,
188 1 << TWR_GPIO_POS_BUTTON,
189 1 << TWR_GPIO_POS_INT,
190 1 << TWR_GPIO_POS_SCL0,
191 1 << TWR_GPIO_POS_SDA0
194 static const uint32_t _twr_gpio_32_bit_mask[4][TWR_GPIO_CHANNEL_COUNT] =
222 1UL << (2 * TWR_GPIO_POS_P0),
223 1UL << (2 * TWR_GPIO_POS_P1),
224 1UL << (2 * TWR_GPIO_POS_P2),
225 1UL << (2 * TWR_GPIO_POS_P3),
226 1UL << (2 * TWR_GPIO_POS_P4),
227 1UL << (2 * TWR_GPIO_POS_P5),
228 1UL << (2 * TWR_GPIO_POS_P6),
229 1UL << (2 * TWR_GPIO_POS_P7),
230 1UL << (2 * TWR_GPIO_POS_P8),
231 1UL << (2 * TWR_GPIO_POS_P9),
232 1UL << (2 * TWR_GPIO_POS_P10),
233 1UL << (2 * TWR_GPIO_POS_P11),
234 1UL << (2 * TWR_GPIO_POS_P12),
235 1UL << (2 * TWR_GPIO_POS_P13),
236 1UL << (2 * TWR_GPIO_POS_P14),
237 1UL << (2 * TWR_GPIO_POS_P15),
238 1UL << (2 * TWR_GPIO_POS_P16),
239 1UL << (2 * TWR_GPIO_POS_P17),
240 1UL << (2 * TWR_GPIO_POS_LED),
241 1UL << (2 * TWR_GPIO_POS_BUTTON),
242 1UL << (2 * TWR_GPIO_POS_INT),
243 1UL << (2 * TWR_GPIO_POS_SCL0),
244 1UL << (2 * TWR_GPIO_POS_SDA0)
247 2UL << (2 * TWR_GPIO_POS_P0),
248 2UL << (2 * TWR_GPIO_POS_P1),
249 2UL << (2 * TWR_GPIO_POS_P2),
250 2UL << (2 * TWR_GPIO_POS_P3),
251 2UL << (2 * TWR_GPIO_POS_P4),
252 2UL << (2 * TWR_GPIO_POS_P5),
253 2UL << (2 * TWR_GPIO_POS_P6),
254 2UL << (2 * TWR_GPIO_POS_P7),
255 2UL << (2 * TWR_GPIO_POS_P8),
256 2UL << (2 * TWR_GPIO_POS_P9),
257 2UL << (2 * TWR_GPIO_POS_P10),
258 2UL << (2 * TWR_GPIO_POS_P11),
259 2UL << (2 * TWR_GPIO_POS_P12),
260 2UL << (2 * TWR_GPIO_POS_P13),
261 2UL << (2 * TWR_GPIO_POS_P14),
262 2UL << (2 * TWR_GPIO_POS_P15),
263 2UL << (2 * TWR_GPIO_POS_P16),
264 2UL << (2 * TWR_GPIO_POS_P17),
265 2UL << (2 * TWR_GPIO_POS_LED),
266 2UL << (2 * TWR_GPIO_POS_BUTTON),
267 2UL << (2 * TWR_GPIO_POS_INT),
268 2UL << (2 * TWR_GPIO_POS_SCL0),
269 2UL << (2 * TWR_GPIO_POS_SDA0)
272 3UL << (2 * TWR_GPIO_POS_P0),
273 3UL << (2 * TWR_GPIO_POS_P1),
274 3UL << (2 * TWR_GPIO_POS_P2),
275 3UL << (2 * TWR_GPIO_POS_P3),
276 3UL << (2 * TWR_GPIO_POS_P4),
277 3UL << (2 * TWR_GPIO_POS_P5),
278 3UL << (2 * TWR_GPIO_POS_P6),
279 3UL << (2 * TWR_GPIO_POS_P7),
280 3UL << (2 * TWR_GPIO_POS_P8),
281 3UL << (2 * TWR_GPIO_POS_P9),
282 3UL << (2 * TWR_GPIO_POS_P10),
283 3UL << (2 * TWR_GPIO_POS_P11),
284 3UL << (2 * TWR_GPIO_POS_P12),
285 3UL << (2 * TWR_GPIO_POS_P13),
286 3UL << (2 * TWR_GPIO_POS_P14),
287 3UL << (2 * TWR_GPIO_POS_P15),
288 3UL << (2 * TWR_GPIO_POS_P16),
289 3UL << (2 * TWR_GPIO_POS_P17),
290 3UL << (2 * TWR_GPIO_POS_LED),
291 3UL << (2 * TWR_GPIO_POS_BUTTON),
292 3UL << (2 * TWR_GPIO_POS_INT),
293 3UL << (2 * TWR_GPIO_POS_SCL0),
294 3UL << (2 * TWR_GPIO_POS_SDA0)
298 const uint32_t twr_gpio_32_bit_upper_mask[TWR_GPIO_CHANNEL_COUNT] =
300 (1UL << 16) << TWR_GPIO_POS_P0,
301 (1UL << 16) << TWR_GPIO_POS_P1,
302 (1UL << 16) << TWR_GPIO_POS_P2,
303 (1UL << 16) << TWR_GPIO_POS_P3,
304 (1UL << 16) << TWR_GPIO_POS_P4,
305 (1UL << 16) << TWR_GPIO_POS_P5,
306 (1UL << 16) << TWR_GPIO_POS_P6,
307 (1UL << 16) << TWR_GPIO_POS_P7,
308 (1UL << 16) << TWR_GPIO_POS_P8,
309 (1UL << 16) << TWR_GPIO_POS_P9,
310 (1UL << 16) << TWR_GPIO_POS_P10,
311 (1UL << 16) << TWR_GPIO_POS_P11,
312 (1UL << 16) << TWR_GPIO_POS_P12,
313 (1UL << 16) << TWR_GPIO_POS_P13,
314 (1UL << 16) << TWR_GPIO_POS_P14,
315 (1UL << 16) << TWR_GPIO_POS_P15,
316 (1UL << 16) << TWR_GPIO_POS_P16,
317 (1UL << 16) << TWR_GPIO_POS_P17,
318 (1UL << 16) << TWR_GPIO_POS_LED,
319 (1UL << 16) << TWR_GPIO_POS_BUTTON,
320 (1UL << 16) << TWR_GPIO_POS_INT,
321 (1UL << 16) << TWR_GPIO_POS_SCL0,
322 (1UL << 16) << TWR_GPIO_POS_SDA0
331 RCC->IOPENR |= _twr_gpio_iopenr_mask[channel];
346 uint32_t pupdr = twr_gpio_port[channel]->PUPDR;
349 pupdr &= ~_twr_gpio_32_bit_mask[3][channel];
352 pupdr |= _twr_gpio_32_bit_mask[pull][channel];
355 twr_gpio_port[channel]->PUPDR = pupdr;
364 return (
twr_gpio_pull_t) ((twr_gpio_port[channel]->PUPDR >> _twr_gpio_32_bit_pos[channel]) & 3);
373 uint32_t otyper = twr_gpio_port[channel]->OTYPER;
376 uint32_t moder = twr_gpio_port[channel]->MODER;
382 otyper |= twr_gpio_16_bit_mask[channel];
390 otyper &= ~twr_gpio_16_bit_mask[channel];
397 if(_twr_gpio_16_bit_pos[channel] >= 8)
399 twr_gpio_port[channel]->AFR[1] &= ~(0x0f << (_twr_gpio_64_bit_pos(channel) - 32));
400 twr_gpio_port[channel]->AFR[1] |= ((uint8_t)mode >> _TWR_GPIO_MODE_AF_POS) << (_twr_gpio_64_bit_pos(channel) - 32);
404 twr_gpio_port[channel]->AFR[0] &= ~(0x0f << _twr_gpio_64_bit_pos(channel));
405 twr_gpio_port[channel]->AFR[0] |= ((uint8_t)mode >> _TWR_GPIO_MODE_AF_POS) << _twr_gpio_64_bit_pos(channel);
409 mode &= _TWR_GPIO_MODE_MASK;
413 moder &= ~_twr_gpio_32_bit_mask[3][channel];
416 moder |= _twr_gpio_32_bit_mask[mode][channel];
419 twr_gpio_port[channel]->OTYPER = otyper;
422 twr_gpio_port[channel]->MODER = moder;
437 if (((twr_gpio_port[channel]->OTYPER >> _twr_gpio_16_bit_pos[channel]) & 1) != 0)
448 if(_twr_gpio_16_bit_pos[channel] >= 8)
450 mode = (twr_gpio_port[channel]->AFR[1] >> (_twr_gpio_64_bit_pos(channel) - 32)) & 0x0f;
454 mode = (twr_gpio_port[channel]->AFR[0] >> _twr_gpio_64_bit_pos(channel)) & 0x0f;
468 return (twr_gpio_port[channel]->IDR & twr_gpio_16_bit_mask[channel]) != 0 ? 1 : 0;
474 twr_gpio_port[channel]->BSRR = state ? twr_gpio_16_bit_mask[channel] : twr_gpio_32_bit_upper_mask[channel];
480 return (twr_gpio_port[channel]->ODR & twr_gpio_16_bit_mask[channel]) != 0 ? 1 : 0;
489 twr_gpio_port[channel]->ODR ^= twr_gpio_16_bit_mask[channel];
twr_gpio_pull_t twr_gpio_get_pull(twr_gpio_channel_t channel)
Get pull-up/pull-down configuration for GPIO channel.
void twr_gpio_set_output(twr_gpio_channel_t channel, int state)
Set output state for GPIO channel.
void twr_gpio_set_pull(twr_gpio_channel_t channel, twr_gpio_pull_t pull)
Set pull-up/pull-down configuration for GPIO channel.
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
twr_gpio_mode_t
GPIO mode of operation.
twr_gpio_channel_t
GPIO channels.
void twr_gpio_toggle_output(twr_gpio_channel_t channel)
Toggle output state for GPIO channel.
int twr_gpio_get_output(twr_gpio_channel_t channel)
Get output state for GPIO channel.
twr_gpio_mode_t twr_gpio_get_mode(twr_gpio_channel_t channel)
Get mode of operation for GPIO channel.
twr_gpio_pull_t
GPIO pull-up/pull-down setting.
int twr_gpio_get_input(twr_gpio_channel_t channel)
Get input state for GPIO channel.
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
@ TWR_GPIO_MODE_OUTPUT
GPIO channel operates as output.
@ TWR_GPIO_MODE_ALTERNATE
GPIO channel operates in alternate mode.
@ TWR_GPIO_MODE_OUTPUT_OD
GPIO channel operates as open-drain output.
void twr_irq_disable(void)
Disable interrupt requests globally (call can be nested)
void twr_irq_enable(void)
Enable interrupt requests globally (call can be nested)