Loading...
Searching...
No Matches
gpio_ll_arch.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Freie Universität Berlin
3 * 2017 OTA keys S.A.
4 *
5 * This file is subject to the terms and conditions of the GNU Lesser
6 * General Public License v2.1. See the file LICENSE in the top level
7 * directory for more details.
8 */
9
10#pragma once
11
23
24#include "architecture.h"
25#include "periph_cpu.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#ifndef DOXYGEN /* hide implementation specific details from Doxygen */
32
33#define GPIO_PORT_NUMBERING_ALPHABETIC 1
34
35#ifdef GPIOA_BASE
36# define GPIO_PORT_0 GPIOA_BASE
37#endif
38
39#ifdef GPIOB_BASE
40# define GPIO_PORT_1 GPIOB_BASE
41#endif
42
43#ifdef GPIOC_BASE
44# define GPIO_PORT_2 GPIOC_BASE
45#endif
46
47#ifdef GPIOD_BASE
48# define GPIO_PORT_3 GPIOD_BASE
49#endif
50
51#ifdef GPIOE_BASE
52# define GPIO_PORT_4 GPIOE_BASE
53#endif
54
55#ifdef GPIOF_BASE
56# define GPIO_PORT_5 GPIOF_BASE
57#endif
58
59#ifdef GPIOG_BASE
60# define GPIO_PORT_6 GPIOG_BASE
61#endif
62
63#ifdef GPIOH_BASE
64# define GPIO_PORT_7 GPIOH_BASE
65#endif
66
67#ifdef GPIOI_BASE
68# define GPIO_PORT_8 GPIOI_BASE
69#endif
70
71#ifdef GPIOJ_BASE
72# define GPIO_PORT_9 GPIOJ_BASE
73#endif
74
75#ifdef GPIOK_BASE
76# define GPIO_PORT_10 GPIOK_BASE
77#endif
78
79static inline gpio_port_t gpio_port(uword_t num)
80{
81#if defined(CPU_FAM_STM32MP1)
82 return GPIOA_BASE + (num << 12);
83#else
84 return GPIOA_BASE + (num << 10);
85#endif
86}
87
88static inline uword_t gpio_port_num(gpio_port_t port)
89{
90#if defined(CPU_FAM_STM32MP1)
91 return (port - GPIOA_BASE) >> 12;
92#else
93 return (port - GPIOA_BASE) >> 10;
94#endif
95}
96
97static inline uword_t gpio_ll_read(gpio_port_t port)
98{
99 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
100 return p->IDR;
101}
102
103static inline uword_t gpio_ll_read_output(gpio_port_t port)
104{
105 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
106 return p->ODR;
107}
108
109static inline void gpio_ll_set(gpio_port_t port, uword_t mask)
110{
111 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
112 p->BSRR = mask;
113}
114
115static inline void gpio_ll_clear(gpio_port_t port, uword_t mask)
116{
117 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
118 /* The STM32F4 vendor header files do include defines for accessing the
119 * BRR register, but do not have a BRR register.
120 * See https://github.com/STMicroelectronics/cmsis_device_f4/pull/7 */
121#if defined(GPIO_BRR_BR0) && !defined(CPU_FAM_STM32F4)
122 p->BRR = mask;
123#else
124 /* The first half-word sets GPIOs, the second half-world clears GPIOs */
125 volatile uint16_t *brr = (volatile uint16_t *)&(p->BSRR);
126 brr[1] = (uint16_t)mask;
127#endif
128}
129
130static inline void gpio_ll_toggle(gpio_port_t port, uword_t mask)
131{
132 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
133 unsigned irq_state = irq_disable();
134 p->ODR ^= mask;
135 irq_restore(irq_state);
136}
137
138static inline void gpio_ll_write(gpio_port_t port, uword_t value)
139{
140 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
141 p->ODR = value;
142}
143
144#ifdef MODULE_PERIPH_GPIO_LL_SWITCH_DIR
146{
147 /* implementation too large to always inline */
148 extern uword_t gpio_ll_prepare_switch_dir_impl(uword_t mask);
149 return gpio_ll_prepare_switch_dir_impl(mask);
150}
151
152static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t pins)
153{
154 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
155 unsigned irq_state = irq_disable();
156 p->MODER |= pins;
157 irq_restore(irq_state);
158}
159
160static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t pins)
161{
162 GPIO_TypeDef *p = (GPIO_TypeDef *)port;
163 unsigned irq_state = irq_disable();
164 p->MODER &= ~pins;
165 irq_restore(irq_state);
166}
167#endif
168
169static inline gpio_port_t gpio_get_port(gpio_t pin)
170{
171 return pin & 0xfffffff0LU;
172}
173
174static inline uint8_t gpio_get_pin_num(gpio_t pin)
175{
176 return pin & 0xfLU;
177}
178
179static inline gpio_port_t gpio_port_pack_addr(void *addr)
180{
181 return (gpio_port_t)addr;
182}
183
184static inline void * gpio_port_unpack_addr(gpio_port_t port)
185{
186 if (port < GPIOA_BASE) {
187 return (void *)port;
188 }
189
190 return NULL;
191}
192
193static inline bool is_gpio_port_num_valid(uint_fast8_t num)
194{
195 switch (num) {
196 default:
197 return false;
198#ifdef GPIOA_BASE
199 case 0:
200#endif
201#ifdef GPIOB_BASE
202 case 1:
203#endif
204#ifdef GPIOC_BASE
205 case 2:
206#endif
207#ifdef GPIOD_BASE
208 case 3:
209#endif
210#ifdef GPIOE_BASE
211 case 4:
212#endif
213#ifdef GPIOF_BASE
214 case 5:
215#endif
216#ifdef GPIOG_BASE
217 case 6:
218#endif
219#ifdef GPIOH_BASE
220 case 7:
221#endif
222#ifdef GPIOI_BASE
223 case 8:
224#endif
225#ifdef GPIOJ_BASE
226 case 9:
227#endif
228#ifdef GPIOK_BASE
229 case 10:
230#endif
231#ifdef GPIOL_BASE
232 case 11:
233#endif
234#ifdef GPIOM_BASE
235 case 12:
236#endif
237#ifdef GPION_BASE
238 case 13:
239#endif
240#ifdef GPIOO_BASE
241 case 14:
242#endif
243#ifdef GPIOP_BASE
244 case 15:
245#endif
246#ifdef GPIOQ_BASE
247 case 16:
248#endif
249#ifdef GPIOR_BASE
250 case 17:
251#endif
252#ifdef GPIOS_BASE
253 case 18:
254#endif
255#ifdef GPIOT_BASE
256 case 19:
257#endif
258#ifdef GPIOU_BASE
259 case 20:
260#endif
261#ifdef GPIOV_BASE
262 case 21:
263#endif
264#ifdef GPIOW_BASE
265 case 22:
266#endif
267#ifdef GPIOX_BASE
268 case 23:
269#endif
270#ifdef GPIOY_BASE
271 case 24:
272#endif
273#ifdef GPIOZ_BASE
274 case 25:
275#endif
276 return true;
277 }
278}
279
280#endif /* DOXYGEN */
281#ifdef __cplusplus
282}
283#endif
284
Platform-independent access to architecture details.
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
static uint8_t gpio_get_pin_num(gpio_t pin)
Extract the pin number from a gpio_t
static void gpio_ll_set(gpio_port_t port, uword_t mask)
Perform an reg |= mask operation on the I/O register of the port.
gpio_port_t gpio_port(uword_t num)
Get the gpio_port_t value of the port number num.
static gpio_port_t gpio_port_pack_addr(void *addr)
Pack a pointer into a gpio_port_t.
static void gpio_ll_switch_dir_output(gpio_port_t port, uword_t pins)
Turn GPIO pins specified by pins (obtained from gpio_ll_prepare_switch_dir) to outputs.
static void gpio_ll_switch_dir_input(gpio_port_t port, uword_t pins)
Turn GPIO pins specified by pins (obtained from gpio_ll_prepare_switch_dir) to inputs.
static uword_t gpio_ll_read(gpio_port_t port)
Get the current input value of all GPIO pins of the given port as bitmask.
static gpio_port_t gpio_get_port(gpio_t pin)
Extract the gpio_port_t from a gpio_t
uword_t gpio_port_num(gpio_port_t port)
Get the number of the GPIO port port refers to.
static uword_t gpio_ll_prepare_switch_dir(uword_t mask)
Prepare bitmask for use with gpio_ll_switch_dir_output and gpio_ll_switch_dir_input.
Definition gpio_ll.h:750
static void * gpio_port_unpack_addr(gpio_port_t port)
Extract a data pointer that was packed by gpio_port_pack_addr.
static bool is_gpio_port_num_valid(uint_fast8_t num)
Check if the given number is a valid argument for gpio_port.
static uword_t gpio_ll_read_output(gpio_port_t port)
Get the current output value of all GPIO pins of the given port as bitmask.
static void gpio_ll_clear(gpio_port_t port, uword_t mask)
Perform an reg &= ~mask operation on the I/O register of the port.
static void gpio_ll_toggle(gpio_port_t port, uword_t mask)
Perform an reg ^= mask operation on the I/O register of the port.
static void gpio_ll_write(gpio_port_t port, uword_t state)
Perform a masked write operation on the I/O register of the port.
uintptr_t gpio_port_t
GPIO port type.
Definition gpio_ll.h:95
uint< NUM > _t uword_t
Word sized unsigned integer.
Shared CPU specific definitions for the STM32 family.