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