1 /***************************************************************************//**
2  * @file
3  * @brief General Purpose IO (GPIO) peripheral API
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 
31 #ifndef EM_GPIO_H
32 #define EM_GPIO_H
33 
34 #include "em_device.h"
35 #if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
36 
37 #include <stdbool.h>
38 #include "sl_assert.h"
39 #include "em_bus.h"
40 #include "sl_enum.h"
41 #include "sl_common.h"
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /*******************************************************************************
48  *******************************   DEFINES   ***********************************
49  ******************************************************************************/
50 
51 #if defined(_SILICON_LABS_32B_SERIES_0) \
52   && defined(_EFM32_TINY_FAMILY) || defined(_EFM32_ZERO_FAMILY)
53 
54 #define _GPIO_PORT_A_PIN_COUNT 14
55 #define _GPIO_PORT_B_PIN_COUNT 10
56 #define _GPIO_PORT_C_PIN_COUNT 16
57 #define _GPIO_PORT_D_PIN_COUNT 9
58 #define _GPIO_PORT_E_PIN_COUNT 12
59 #define _GPIO_PORT_F_PIN_COUNT 6
60 #define _GPIO_PORT_G_PIN_COUNT 0
61 #define _GPIO_PORT_H_PIN_COUNT 0
62 #define _GPIO_PORT_I_PIN_COUNT 0
63 #define _GPIO_PORT_J_PIN_COUNT 0
64 #define _GPIO_PORT_K_PIN_COUNT 0
65 
66 #define _GPIO_PORT_A_PIN_MASK 0xF77FUL
67 #define _GPIO_PORT_B_PIN_MASK 0x79F8UL
68 #define _GPIO_PORT_C_PIN_MASK 0xFFFFUL
69 #define _GPIO_PORT_D_PIN_MASK 0x01FFUL
70 #define _GPIO_PORT_E_PIN_MASK 0xFFF0UL
71 #define _GPIO_PORT_F_PIN_MASK 0x003FUL
72 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
73 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
74 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
75 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
76 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
77 
78 #elif defined(_EFM32_HAPPY_FAMILY)
79 
80 #define _GPIO_PORT_A_PIN_COUNT 6
81 #define _GPIO_PORT_B_PIN_COUNT 5
82 #define _GPIO_PORT_C_PIN_COUNT 12
83 #define _GPIO_PORT_D_PIN_COUNT 4
84 #define _GPIO_PORT_E_PIN_COUNT 4
85 #define _GPIO_PORT_F_PIN_COUNT 6
86 #define _GPIO_PORT_G_PIN_COUNT 0
87 #define _GPIO_PORT_H_PIN_COUNT 0
88 #define _GPIO_PORT_I_PIN_COUNT 0
89 #define _GPIO_PORT_J_PIN_COUNT 0
90 #define _GPIO_PORT_K_PIN_COUNT 0
91 
92 #define _GPIO_PORT_A_PIN_MASK 0x0707UL
93 #define _GPIO_PORT_B_PIN_MASK 0x6980UL
94 #define _GPIO_PORT_C_PIN_MASK 0xEF1FUL
95 #define _GPIO_PORT_D_PIN_MASK 0x00F0UL
96 #define _GPIO_PORT_E_PIN_MASK 0x3C00UL
97 #define _GPIO_PORT_F_PIN_MASK 0x003FUL
98 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
99 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
100 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
101 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
102 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
103 
104 #elif defined(_SILICON_LABS_32B_SERIES_0) \
105   && (defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY))
106 
107 #define _GPIO_PORT_A_PIN_COUNT 16
108 #define _GPIO_PORT_B_PIN_COUNT 16
109 #define _GPIO_PORT_C_PIN_COUNT 16
110 #define _GPIO_PORT_D_PIN_COUNT 16
111 #define _GPIO_PORT_E_PIN_COUNT 16
112 #define _GPIO_PORT_F_PIN_COUNT 13
113 #define _GPIO_PORT_G_PIN_COUNT 0
114 #define _GPIO_PORT_H_PIN_COUNT 0
115 #define _GPIO_PORT_I_PIN_COUNT 0
116 #define _GPIO_PORT_J_PIN_COUNT 0
117 #define _GPIO_PORT_K_PIN_COUNT 0
118 
119 #define _GPIO_PORT_A_PIN_MASK 0xFFFFUL
120 #define _GPIO_PORT_B_PIN_MASK 0xFFFFUL
121 #define _GPIO_PORT_C_PIN_MASK 0xFFFFUL
122 #define _GPIO_PORT_D_PIN_MASK 0xFFFFUL
123 #define _GPIO_PORT_E_PIN_MASK 0xFFFFUL
124 #define _GPIO_PORT_F_PIN_MASK 0x1FFFUL
125 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
126 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
127 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
128 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
129 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
130 
131 #elif defined(_EFM32_GECKO_FAMILY)
132 
133 #define _GPIO_PORT_A_PIN_COUNT 16
134 #define _GPIO_PORT_B_PIN_COUNT 16
135 #define _GPIO_PORT_C_PIN_COUNT 16
136 #define _GPIO_PORT_D_PIN_COUNT 16
137 #define _GPIO_PORT_E_PIN_COUNT 16
138 #define _GPIO_PORT_F_PIN_COUNT 10
139 #define _GPIO_PORT_G_PIN_COUNT 0
140 #define _GPIO_PORT_H_PIN_COUNT 0
141 #define _GPIO_PORT_I_PIN_COUNT 0
142 #define _GPIO_PORT_J_PIN_COUNT 0
143 #define _GPIO_PORT_K_PIN_COUNT 0
144 
145 #define _GPIO_PORT_A_PIN_MASK 0xFFFFUL
146 #define _GPIO_PORT_B_PIN_MASK 0xFFFFUL
147 #define _GPIO_PORT_C_PIN_MASK 0xFFFFUL
148 #define _GPIO_PORT_D_PIN_MASK 0xFFFFUL
149 #define _GPIO_PORT_E_PIN_MASK 0xFFFFUL
150 #define _GPIO_PORT_F_PIN_MASK 0x03FFUL
151 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
152 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
153 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
154 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
155 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
156 
157 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) && defined(_EFR_DEVICE)
158 
159 #define _GPIO_PORT_A_PIN_COUNT 6
160 #define _GPIO_PORT_B_PIN_COUNT 5
161 #define _GPIO_PORT_C_PIN_COUNT 6
162 #define _GPIO_PORT_D_PIN_COUNT 7
163 #define _GPIO_PORT_E_PIN_COUNT 0
164 #define _GPIO_PORT_F_PIN_COUNT 8
165 #define _GPIO_PORT_G_PIN_COUNT 0
166 #define _GPIO_PORT_H_PIN_COUNT 0
167 #define _GPIO_PORT_I_PIN_COUNT 0
168 #define _GPIO_PORT_J_PIN_COUNT 0
169 #define _GPIO_PORT_K_PIN_COUNT 0
170 
171 #define _GPIO_PORT_A_PIN_MASK 0x003FUL
172 #define _GPIO_PORT_B_PIN_MASK 0xF800UL
173 #define _GPIO_PORT_C_PIN_MASK 0x0FC0UL
174 #define _GPIO_PORT_D_PIN_MASK 0xFE00UL
175 #define _GPIO_PORT_E_PIN_MASK 0x0000UL
176 #define _GPIO_PORT_F_PIN_MASK 0x00FFUL
177 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
178 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
179 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
180 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
181 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
182 
183 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) && defined(_EFM_DEVICE)
184 
185 #define _GPIO_PORT_A_PIN_COUNT 6
186 #define _GPIO_PORT_B_PIN_COUNT 5
187 #define _GPIO_PORT_C_PIN_COUNT 6
188 #define _GPIO_PORT_D_PIN_COUNT 7
189 #define _GPIO_PORT_E_PIN_COUNT 0
190 #define _GPIO_PORT_F_PIN_COUNT 8
191 #define _GPIO_PORT_G_PIN_COUNT 0
192 #define _GPIO_PORT_H_PIN_COUNT 0
193 #define _GPIO_PORT_I_PIN_COUNT 0
194 #define _GPIO_PORT_J_PIN_COUNT 0
195 #define _GPIO_PORT_K_PIN_COUNT 0
196 
197 #define _GPIO_PORT_A_PIN_MASK 0x003FUL
198 #define _GPIO_PORT_B_PIN_MASK 0xF800UL
199 #define _GPIO_PORT_C_PIN_MASK 0x0FC0UL
200 #define _GPIO_PORT_D_PIN_MASK 0xFE00UL
201 #define _GPIO_PORT_E_PIN_MASK 0x0000UL
202 #define _GPIO_PORT_F_PIN_MASK 0x00FFUL
203 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
204 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
205 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
206 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
207 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
208 
209 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84)
210 
211 #define _GPIO_PORT_A_PIN_COUNT 10
212 #define _GPIO_PORT_B_PIN_COUNT 10
213 #define _GPIO_PORT_C_PIN_COUNT 12
214 #define _GPIO_PORT_D_PIN_COUNT 8
215 #define _GPIO_PORT_E_PIN_COUNT 0
216 #define _GPIO_PORT_F_PIN_COUNT 16
217 #define _GPIO_PORT_G_PIN_COUNT 0
218 #define _GPIO_PORT_H_PIN_COUNT 0
219 #define _GPIO_PORT_I_PIN_COUNT 4
220 #define _GPIO_PORT_J_PIN_COUNT 2
221 #define _GPIO_PORT_K_PIN_COUNT 3
222 
223 #define _GPIO_PORT_A_PIN_MASK 0x03FFUL
224 #define _GPIO_PORT_B_PIN_MASK 0xFFC0UL
225 #define _GPIO_PORT_C_PIN_MASK 0x0FFFUL
226 #define _GPIO_PORT_D_PIN_MASK 0xFF00UL
227 #define _GPIO_PORT_E_PIN_MASK 0x0000UL
228 #define _GPIO_PORT_F_PIN_MASK 0xFFFFUL
229 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
230 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
231 #define _GPIO_PORT_I_PIN_MASK 0x000FUL
232 #define _GPIO_PORT_J_PIN_MASK 0xC000UL
233 #define _GPIO_PORT_K_PIN_MASK 0x0007UL
234 
235 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
236 
237 #define _GPIO_PORT_A_PIN_COUNT 6
238 #define _GPIO_PORT_B_PIN_COUNT 5
239 #define _GPIO_PORT_C_PIN_COUNT 6
240 #define _GPIO_PORT_D_PIN_COUNT 7
241 #define _GPIO_PORT_E_PIN_COUNT 0
242 #define _GPIO_PORT_F_PIN_COUNT 8
243 #define _GPIO_PORT_G_PIN_COUNT 0
244 #define _GPIO_PORT_H_PIN_COUNT 0
245 #define _GPIO_PORT_I_PIN_COUNT 0
246 #define _GPIO_PORT_J_PIN_COUNT 0
247 #define _GPIO_PORT_K_PIN_COUNT 0
248 
249 #define _GPIO_PORT_A_PIN_MASK 0x003FUL
250 #define _GPIO_PORT_B_PIN_MASK 0xF800UL
251 #define _GPIO_PORT_C_PIN_MASK 0x0FC0UL
252 #define _GPIO_PORT_D_PIN_MASK 0xFE00UL
253 #define _GPIO_PORT_E_PIN_MASK 0x0000UL
254 #define _GPIO_PORT_F_PIN_MASK 0x00FFUL
255 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
256 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
257 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
258 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
259 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
260 
261 #elif defined (_SILICON_LABS_GECKO_INTERNAL_SDID_106)
262 #define _GPIO_PORT_A_PIN_COUNT 16
263 #define _GPIO_PORT_B_PIN_COUNT 16
264 #define _GPIO_PORT_C_PIN_COUNT 16
265 #define _GPIO_PORT_D_PIN_COUNT 16
266 #define _GPIO_PORT_E_PIN_COUNT 16
267 #define _GPIO_PORT_F_PIN_COUNT 15
268 #define _GPIO_PORT_G_PIN_COUNT 0
269 #define _GPIO_PORT_H_PIN_COUNT 0
270 #define _GPIO_PORT_I_PIN_COUNT 0
271 #define _GPIO_PORT_J_PIN_COUNT 0
272 #define _GPIO_PORT_K_PIN_COUNT 0
273 
274 #define _GPIO_PORT_A_PIN_MASK 0xFFFFUL
275 #define _GPIO_PORT_B_PIN_MASK 0xFFFFUL
276 #define _GPIO_PORT_C_PIN_MASK 0xFFFFUL
277 #define _GPIO_PORT_D_PIN_MASK 0xFFFFUL
278 #define _GPIO_PORT_E_PIN_MASK 0xFFFFUL
279 #define _GPIO_PORT_F_PIN_MASK 0x7FFFUL
280 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
281 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
282 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
283 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
284 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
285 
286 #elif defined(_SILICON_LABS_32B_SERIES_1) && defined(_EFM32_GIANT_FAMILY)
287 
288 #define _GPIO_PORT_A_PIN_COUNT 16
289 #define _GPIO_PORT_B_PIN_COUNT 16
290 #define _GPIO_PORT_C_PIN_COUNT 16
291 #define _GPIO_PORT_D_PIN_COUNT 16
292 #define _GPIO_PORT_E_PIN_COUNT 16
293 #define _GPIO_PORT_F_PIN_COUNT 16
294 #define _GPIO_PORT_G_PIN_COUNT 16
295 #define _GPIO_PORT_H_PIN_COUNT 16
296 #define _GPIO_PORT_I_PIN_COUNT 16
297 #define _GPIO_PORT_J_PIN_COUNT  0
298 #define _GPIO_PORT_K_PIN_COUNT  0
299 
300 #define _GPIO_PORT_A_PIN_MASK 0xFFFFUL
301 #define _GPIO_PORT_B_PIN_MASK 0xFFFFUL
302 #define _GPIO_PORT_C_PIN_MASK 0xFFFFUL
303 #define _GPIO_PORT_D_PIN_MASK 0xFFFFUL
304 #define _GPIO_PORT_E_PIN_MASK 0xFFFFUL
305 #define _GPIO_PORT_F_PIN_MASK 0xFFFFUL
306 #define _GPIO_PORT_G_PIN_MASK 0xFFFFUL
307 #define _GPIO_PORT_H_PIN_MASK 0xFFFFUL
308 #define _GPIO_PORT_I_PIN_MASK 0xFFFFUL
309 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
310 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
311 
312 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95)
313 
314 #define _GPIO_PORT_A_PIN_COUNT 6
315 #define _GPIO_PORT_B_PIN_COUNT 5
316 #define _GPIO_PORT_C_PIN_COUNT 6
317 #define _GPIO_PORT_D_PIN_COUNT 7
318 #define _GPIO_PORT_E_PIN_COUNT 0
319 #define _GPIO_PORT_F_PIN_COUNT 8
320 #define _GPIO_PORT_G_PIN_COUNT 0
321 #define _GPIO_PORT_H_PIN_COUNT 0
322 #define _GPIO_PORT_I_PIN_COUNT 0
323 #define _GPIO_PORT_J_PIN_COUNT 0
324 #define _GPIO_PORT_K_PIN_COUNT 0
325 
326 #define _GPIO_PORT_A_PIN_MASK 0x003FUL
327 #define _GPIO_PORT_B_PIN_MASK 0xF800UL
328 #define _GPIO_PORT_C_PIN_MASK 0x0FC0UL
329 #define _GPIO_PORT_D_PIN_MASK 0xFE00UL
330 #define _GPIO_PORT_E_PIN_MASK 0x0000UL
331 #define _GPIO_PORT_F_PIN_MASK 0x00FFUL
332 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
333 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
334 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
335 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
336 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
337 
338 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_103)
339 
340 #define _GPIO_PORT_A_PIN_COUNT 14
341 #define _GPIO_PORT_B_PIN_COUNT 10
342 #define _GPIO_PORT_C_PIN_COUNT 16
343 #define _GPIO_PORT_D_PIN_COUNT 9
344 #define _GPIO_PORT_E_PIN_COUNT 12
345 #define _GPIO_PORT_F_PIN_COUNT 6
346 #define _GPIO_PORT_G_PIN_COUNT 0
347 #define _GPIO_PORT_H_PIN_COUNT 0
348 #define _GPIO_PORT_I_PIN_COUNT 0
349 #define _GPIO_PORT_J_PIN_COUNT 0
350 #define _GPIO_PORT_K_PIN_COUNT 0
351 
352 #define _GPIO_PORT_A_PIN_MASK 0xF77FUL
353 #define _GPIO_PORT_B_PIN_MASK 0x79F8UL
354 #define _GPIO_PORT_C_PIN_MASK 0xFFFFUL
355 #define _GPIO_PORT_D_PIN_MASK 0x01FFUL
356 #define _GPIO_PORT_E_PIN_MASK 0xFFF0UL
357 #define _GPIO_PORT_F_PIN_MASK 0x003FUL
358 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
359 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
360 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
361 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
362 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
363 
364 #elif defined (_SILICON_LABS_32B_SERIES_2)
365 
366 #define _GPIO_PORT_A_PIN_COUNT GPIO_PA_COUNT
367 #define _GPIO_PORT_B_PIN_COUNT GPIO_PB_COUNT
368 #define _GPIO_PORT_C_PIN_COUNT GPIO_PC_COUNT
369 #define _GPIO_PORT_D_PIN_COUNT GPIO_PD_COUNT
370 #define _GPIO_PORT_E_PIN_COUNT 0
371 #define _GPIO_PORT_F_PIN_COUNT 0
372 #define _GPIO_PORT_G_PIN_COUNT 0
373 #define _GPIO_PORT_H_PIN_COUNT 0
374 #define _GPIO_PORT_I_PIN_COUNT 0
375 #define _GPIO_PORT_J_PIN_COUNT 0
376 #define _GPIO_PORT_K_PIN_COUNT 0
377 
378 #define _GPIO_PORT_A_PIN_MASK (GPIO_PA_MASK)
379 #define _GPIO_PORT_B_PIN_MASK (GPIO_PB_MASK)
380 #define _GPIO_PORT_C_PIN_MASK (GPIO_PC_MASK)
381 #define _GPIO_PORT_D_PIN_MASK (GPIO_PD_MASK)
382 #define _GPIO_PORT_E_PIN_MASK 0x0000UL
383 #define _GPIO_PORT_F_PIN_MASK 0x0000UL
384 #define _GPIO_PORT_G_PIN_MASK 0x0000UL
385 #define _GPIO_PORT_H_PIN_MASK 0x0000UL
386 #define _GPIO_PORT_I_PIN_MASK 0x0000UL
387 #define _GPIO_PORT_J_PIN_MASK 0x0000UL
388 #define _GPIO_PORT_K_PIN_MASK 0x0000UL
389 
390 #else
391 #warning "Port and pin masks are not defined for this family."
392 #endif
393 
394 #define _GPIO_PORT_SIZE(port) (             \
395     (port) == 0  ? _GPIO_PORT_A_PIN_COUNT   \
396     : (port) == 1  ? _GPIO_PORT_B_PIN_COUNT \
397     : (port) == 2  ? _GPIO_PORT_C_PIN_COUNT \
398     : (port) == 3  ? _GPIO_PORT_D_PIN_COUNT \
399     : (port) == 4  ? _GPIO_PORT_E_PIN_COUNT \
400     : (port) == 5  ? _GPIO_PORT_F_PIN_COUNT \
401     : (port) == 6  ? _GPIO_PORT_G_PIN_COUNT \
402     : (port) == 7  ? _GPIO_PORT_H_PIN_COUNT \
403     : (port) == 8  ? _GPIO_PORT_I_PIN_COUNT \
404     : (port) == 9  ? _GPIO_PORT_J_PIN_COUNT \
405     : (port) == 10 ? _GPIO_PORT_K_PIN_COUNT \
406     : 0)
407 
408 #define _GPIO_PORT_MASK(port) (                 \
409     ((int)port) == 0  ? _GPIO_PORT_A_PIN_MASK   \
410     : ((int)port) == 1  ? _GPIO_PORT_B_PIN_MASK \
411     : ((int)port) == 2  ? _GPIO_PORT_C_PIN_MASK \
412     : ((int)port) == 3  ? _GPIO_PORT_D_PIN_MASK \
413     : ((int)port) == 4  ? _GPIO_PORT_E_PIN_MASK \
414     : ((int)port) == 5  ? _GPIO_PORT_F_PIN_MASK \
415     : ((int)port) == 6  ? _GPIO_PORT_G_PIN_MASK \
416     : ((int)port) == 7  ? _GPIO_PORT_H_PIN_MASK \
417     : ((int)port) == 8  ? _GPIO_PORT_I_PIN_MASK \
418     : ((int)port) == 9  ? _GPIO_PORT_J_PIN_MASK \
419     : ((int)port) == 10 ? _GPIO_PORT_K_PIN_MASK \
420     : 0UL)
421 
422 /** Validation of port and pin. */
423 #define GPIO_PORT_VALID(port)          (_GPIO_PORT_MASK(port) != 0x0UL)
424 #define GPIO_PORT_PIN_VALID(port, pin) ((((_GPIO_PORT_MASK(port)) >> (pin)) & 0x1UL) == 0x1UL)
425 
426 #if defined(_GPIO_EXTIPINSELL_MASK)
427 /** Validation of interrupt number and pin. */
428 #define GPIO_INTNO_PIN_VALID(intNo, pin)           \
429   (((intNo) & ~_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK) \
430    == ((pin) & ~_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK))
431 #endif
432 
433 /** Highest GPIO pin number. */
434 #define GPIO_PIN_MAX  15
435 
436 /** Highest GPIO port number. */
437 #if (_GPIO_PORT_K_PIN_COUNT > 0)
438 #define GPIO_PORT_MAX  10
439 #elif (_GPIO_PORT_J_PIN_COUNT > 0)
440 #define GPIO_PORT_MAX  9
441 #elif (_GPIO_PORT_I_PIN_COUNT > 0)
442 #define GPIO_PORT_MAX  8
443 #elif (_GPIO_PORT_H_PIN_COUNT > 0)
444 #define GPIO_PORT_MAX  7
445 #elif (_GPIO_PORT_G_PIN_COUNT > 0)
446 #define GPIO_PORT_MAX  6
447 #elif (_GPIO_PORT_F_PIN_COUNT > 0)
448 #define GPIO_PORT_MAX  5
449 #elif (_GPIO_PORT_E_PIN_COUNT > 0)
450 #define GPIO_PORT_MAX  4
451 #elif (_GPIO_PORT_D_PIN_COUNT > 0)
452 #define GPIO_PORT_MAX  3
453 #else
454 #error "Max GPIO port number is undefined for this part."
455 #endif
456 
457 /** Highest EXT GPIO interrupt number. */
458 #define GPIO_EXTINTNO_MAX   15
459 
460 /***************************************************************************//**
461  * @addtogroup gpio
462  * @{
463  ******************************************************************************/
464 
465 /*******************************************************************************
466  ********************************   ENUMS   ************************************
467  ******************************************************************************/
468 
469 /** GPIO ports IDs. */
SL_ENUM(GPIO_Port_TypeDef)470 SL_ENUM(GPIO_Port_TypeDef) {
471 #if (_GPIO_PORT_A_PIN_COUNT > 0)
472   /** Port A. */
473   gpioPortA = 0,
474 #endif
475 #if (_GPIO_PORT_B_PIN_COUNT > 0)
476   /** Port B. */
477   gpioPortB = 1,
478 #endif
479 #if (_GPIO_PORT_C_PIN_COUNT > 0)
480   /** Port C. */
481   gpioPortC = 2,
482 #endif
483 #if (_GPIO_PORT_D_PIN_COUNT > 0)
484   /** Port D. */
485   gpioPortD = 3,
486 #endif
487 #if (_GPIO_PORT_E_PIN_COUNT > 0)
488   /** Port E. */
489   gpioPortE = 4,
490 #endif
491 #if (_GPIO_PORT_F_PIN_COUNT > 0)
492   /** Port F. */
493   gpioPortF = 5,
494 #endif
495 #if (_GPIO_PORT_G_PIN_COUNT > 0)
496   /** Port G. */
497   gpioPortG = 6,
498 #endif
499 #if (_GPIO_PORT_H_PIN_COUNT > 0)
500   /** Port H. */
501   gpioPortH = 7,
502 #endif
503 #if (_GPIO_PORT_I_PIN_COUNT > 0)
504   /** Port I. */
505   gpioPortI = 8,
506 #endif
507 #if (_GPIO_PORT_J_PIN_COUNT > 0)
508   /** Port J. */
509   gpioPortJ = 9,
510 #endif
511 #if (_GPIO_PORT_K_PIN_COUNT > 0)
512   /** Port K. */
513   gpioPortK = 10,
514 #endif
515 };
516 
517 #if defined(_GPIO_P_CTRL_DRIVEMODE_MASK)
518 /** GPIO drive mode. */
SL_ENUM_GENERIC(GPIO_DriveMode_TypeDef,uint32_t)519 SL_ENUM_GENERIC(GPIO_DriveMode_TypeDef, uint32_t) {
520   /** Default 6mA. */
521   gpioDriveModeStandard = GPIO_P_CTRL_DRIVEMODE_STANDARD,
522   /** 0.5 mA. */
523   gpioDriveModeLowest   = GPIO_P_CTRL_DRIVEMODE_LOWEST,
524   /** 20 mA. */
525   gpioDriveModeHigh     = GPIO_P_CTRL_DRIVEMODE_HIGH,
526   /** 2 mA. */
527   gpioDriveModeLow      = GPIO_P_CTRL_DRIVEMODE_LOW
528 };
529 #endif
530 
531 #if defined(_GPIO_P_CTRL_DRIVESTRENGTH_MASK) && defined(_GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)
532 /** GPIO drive strength. */
SL_ENUM_GENERIC(GPIO_DriveStrength_TypeDef,uint32_t)533 SL_ENUM_GENERIC(GPIO_DriveStrength_TypeDef, uint32_t) {
534   /** GPIO weak 1mA and alternate function weak 1mA. */
535   gpioDriveStrengthWeakAlternateWeak     = GPIO_P_CTRL_DRIVESTRENGTH_WEAK | GPIO_P_CTRL_DRIVESTRENGTHALT_WEAK,
536 
537   /** GPIO weak 1mA and alternate function strong 10mA. */
538   gpioDriveStrengthWeakAlternateStrong   = GPIO_P_CTRL_DRIVESTRENGTH_WEAK | GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG,
539 
540   /** GPIO strong 10mA and alternate function weak 1mA. */
541   gpioDriveStrengthStrongAlternateWeak   = GPIO_P_CTRL_DRIVESTRENGTH_STRONG | GPIO_P_CTRL_DRIVESTRENGTHALT_WEAK,
542 
543   /** GPIO strong 10mA and alternate function strong 10mA. */
544   gpioDriveStrengthStrongAlternateStrong = GPIO_P_CTRL_DRIVESTRENGTH_STRONG | GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG,
545 };
546 
547 /* Deprecated enums. */
548 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
549 #define gpioDriveStrengthStrong   gpioDriveStrengthStrongAlternateStrong
550 #define gpioDriveStrengthWeak     gpioDriveStrengthWeakAlternateWeak
551 /** @endcond */
552 #endif
553 
554 /** Pin mode. For more details on each mode, refer to the
555  * reference manual. */
SL_ENUM_GENERIC(GPIO_Mode_TypeDef,uint32_t)556 SL_ENUM_GENERIC(GPIO_Mode_TypeDef, uint32_t) {
557   /** Input disabled. Pull-up if DOUT is set. */
558   gpioModeDisabled                  = _GPIO_P_MODEL_MODE0_DISABLED,
559   /** Input enabled. Filter if DOUT is set. */
560   gpioModeInput                     = _GPIO_P_MODEL_MODE0_INPUT,
561   /** Input enabled. DOUT determines pull direction. */
562   gpioModeInputPull                 = _GPIO_P_MODEL_MODE0_INPUTPULL,
563   /** Input enabled with filter. DOUT determines pull direction. */
564   gpioModeInputPullFilter           = _GPIO_P_MODEL_MODE0_INPUTPULLFILTER,
565   /** Push-pull output. */
566   gpioModePushPull                  = _GPIO_P_MODEL_MODE0_PUSHPULL,
567 #if defined(_GPIO_P_MODEL_MODE0_PUSHPULLDRIVE)
568   /** Push-pull output with drive-strength set by DRIVEMODE. */
569   gpioModePushPullDrive             = _GPIO_P_MODEL_MODE0_PUSHPULLDRIVE,
570 #endif
571 #if defined(_GPIO_P_MODEL_MODE0_PUSHPULLALT)
572   /** Push-pull using alternate control. */
573   gpioModePushPullAlternate       = _GPIO_P_MODEL_MODE0_PUSHPULLALT,
574 #endif
575   /** Wired-or output. */
576   gpioModeWiredOr                       = _GPIO_P_MODEL_MODE0_WIREDOR,
577   /** Wired-or output with pull-down. */
578   gpioModeWiredOrPullDown               = _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN,
579   /** Open-drain output. */
580   gpioModeWiredAnd                      = _GPIO_P_MODEL_MODE0_WIREDAND,
581   /** Open-drain output with filter. */
582   gpioModeWiredAndFilter                = _GPIO_P_MODEL_MODE0_WIREDANDFILTER,
583   /** Open-drain output with pull-up. */
584   gpioModeWiredAndPullUp                = _GPIO_P_MODEL_MODE0_WIREDANDPULLUP,
585   /** Open-drain output with filter and pull-up. */
586   gpioModeWiredAndPullUpFilter          = _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER,
587 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDDRIVE)
588   /** Open-drain output with drive-strength set by DRIVEMODE. */
589   gpioModeWiredAndDrive                 = _GPIO_P_MODEL_MODE0_WIREDANDDRIVE,
590   /** Open-drain output with filter and drive-strength set by DRIVEMODE. */
591   gpioModeWiredAndDriveFilter           = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER,
592   /** Open-drain output with pull-up and drive-strength set by DRIVEMODE. */
593   gpioModeWiredAndDrivePullUp           = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP,
594   /** Open-drain output with filter, pull-up and drive-strength set by DRIVEMODE. */
595   gpioModeWiredAndDrivePullUpFilter     = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER
596 #endif
597 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALT)
598   /** Open-drain output using alternate control. */
599   gpioModeWiredAndAlternate             = _GPIO_P_MODEL_MODE0_WIREDANDALT,
600   /** Open-drain output using alternate control with filter. */
601   gpioModeWiredAndAlternateFilter       = _GPIO_P_MODEL_MODE0_WIREDANDALTFILTER,
602   /** Open-drain output using alternate control with pull-up. */
603   gpioModeWiredAndAlternatePullUp       = _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP,
604   /** Open-drain output using alternate control with filter and pull-up. */
605   gpioModeWiredAndAlternatePullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER,
606 #endif
607 };
608 
609 /*******************************************************************************
610  *****************************   PROTOTYPES   **********************************
611  ******************************************************************************/
612 
613 void GPIO_DbgLocationSet(unsigned int location);
614 
615 /***************************************************************************//**
616  * @brief
617  *   Enable/disable serial wire clock pin.
618  *
619  * @note
620  *   Disabling SWDClk will disable the debug interface, which may result in
621  *   a lockout if done early in startup (before debugger is able to halt core).
622  *
623  * @param[in] enable
624  *   @li false - disable serial wire clock.
625  *   @li true - enable serial wire clock (default after reset).
626  ******************************************************************************/
GPIO_DbgSWDClkEnable(bool enable)627 __STATIC_INLINE void GPIO_DbgSWDClkEnable(bool enable)
628 {
629   unsigned int bit = enable ? 0x1UL : 0x0UL;
630 
631 #if defined(_GPIO_ROUTE_SWCLKPEN_MASK)
632   BUS_RegBitWrite(&(GPIO->ROUTE), _GPIO_ROUTE_SWCLKPEN_SHIFT, bit);
633 #elif defined(_GPIO_ROUTEPEN_SWCLKTCKPEN_MASK)
634   BUS_RegBitWrite(&(GPIO->ROUTEPEN), _GPIO_ROUTEPEN_SWCLKTCKPEN_SHIFT, bit);
635 #elif defined(_GPIO_DBGROUTEPEN_SWCLKTCKPEN_MASK)
636   BUS_RegBitWrite(&(GPIO->DBGROUTEPEN), _GPIO_DBGROUTEPEN_SWCLKTCKPEN_SHIFT, bit);
637 #else
638 #warning "ROUTE enable for SWCLK pin is not defined."
639 #endif
640 }
641 
642 /***************************************************************************//**
643  * @brief
644  *   Enable/disable serial wire data I/O pin.
645  *
646  * @note
647  *   Disabling SWDClk will disable the debug interface, which may result in
648  *   a lockout if done early in startup (before debugger is able to halt core).
649  *
650  * @param[in] enable
651  *   @li false - disable serial wire data pin.
652  *   @li true - enable serial wire data pin (default after reset).
653  ******************************************************************************/
GPIO_DbgSWDIOEnable(bool enable)654 __STATIC_INLINE void GPIO_DbgSWDIOEnable(bool enable)
655 {
656   unsigned int bit = enable ? 0x1UL : 0x0UL;
657 
658 #if defined(_GPIO_ROUTE_SWDIOPEN_MASK)
659   BUS_RegBitWrite(&(GPIO->ROUTE), _GPIO_ROUTE_SWDIOPEN_SHIFT, bit);
660 #elif defined(_GPIO_ROUTEPEN_SWDIOTMSPEN_MASK)
661   BUS_RegBitWrite(&(GPIO->ROUTEPEN), _GPIO_ROUTEPEN_SWDIOTMSPEN_SHIFT, bit);
662 #elif defined(_GPIO_DBGROUTEPEN_SWDIOTMSPEN_MASK)
663   BUS_RegBitWrite(&(GPIO->DBGROUTEPEN), _GPIO_DBGROUTEPEN_SWDIOTMSPEN_SHIFT, bit);
664 #else
665 #warning "ROUTE enable for SWDIO pin is not defined."
666 #endif
667 }
668 
669 #if defined(_GPIO_ROUTE_SWOPEN_MASK) || defined(_GPIO_ROUTEPEN_SWVPEN_MASK) \
670   || defined(_GPIO_TRACEROUTEPEN_SWVPEN_MASK)
671 /***************************************************************************//**
672  * @brief
673  *   Enable/Disable serial wire output pin.
674  *
675  * @note
676  *   Enabling this pin is not sufficient to fully enable serial wire output,
677  *   which is also dependent on issues outside the GPIO module. Refer to
678  *   DBG_SWOEnable().
679  *
680  * @warning
681  *   If debug port is locked, SWO pin is not disabled automatically. To avoid
682  *   information leakage through SWO, disable SWO pin after locking debug port.
683  *
684  * @param[in] enable
685  *   @li false - disable serial wire viewer pin (default after reset).
686  *   @li true - enable serial wire viewer pin.
687  ******************************************************************************/
GPIO_DbgSWOEnable(bool enable)688 __STATIC_INLINE void GPIO_DbgSWOEnable(bool enable)
689 {
690   unsigned int bit = enable ? 0x1UL : 0x0UL;
691 
692 #if defined(_GPIO_ROUTE_SWOPEN_MASK)
693   BUS_RegBitWrite(&(GPIO->ROUTE), _GPIO_ROUTE_SWOPEN_SHIFT, bit);
694 #elif defined(_GPIO_ROUTEPEN_SWVPEN_MASK)
695   BUS_RegBitWrite(&(GPIO->ROUTEPEN), _GPIO_ROUTEPEN_SWVPEN_SHIFT, bit);
696 #elif defined(_GPIO_TRACEROUTEPEN_SWVPEN_MASK)
697   BUS_RegBitWrite(&(GPIO->TRACEROUTEPEN), _GPIO_TRACEROUTEPEN_SWVPEN_SHIFT, bit);
698 #else
699 #warning "ROUTE enable for SWO/SWV pin is not defined."
700 #endif
701 }
702 #endif
703 
704 #if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)
705 void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode);
706 #endif
707 
708 #if defined(_GPIO_P_CTRL_DRIVESTRENGTH_MASK)
709 void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port, GPIO_DriveStrength_TypeDef strength);
710 #endif
711 
712 # if defined(_GPIO_EM4WUEN_MASK)
713 /**************************************************************************//**
714  * @brief
715  *   Disable GPIO pin wake-up from EM4.
716  *
717  * @param[in] pinmask
718  *   Bit mask containing the bitwise logic OR of which GPIO pin(s) to disable.
719  *   Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
720  *****************************************************************************/
GPIO_EM4DisablePinWakeup(uint32_t pinmask)721 __STATIC_INLINE void GPIO_EM4DisablePinWakeup(uint32_t pinmask)
722 {
723   EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0UL);
724 
725   GPIO->EM4WUEN &= ~pinmask;
726 }
727 #endif
728 
729 # if defined(_GPIO_EM4WUEN_MASK)
730 void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask);
731 #endif
732 
733 #if defined(_GPIO_EM4WUCAUSE_MASK) || defined(_GPIO_IF_EM4WU_MASK)
734 /**************************************************************************//**
735  * @brief
736  *   Check which GPIO pin(s) that caused a wake-up from EM4.
737  *
738  * @return
739  *   Bit mask containing the bitwise logic OR of which GPIO pin(s) caused the
740  *   wake-up. Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
741  *****************************************************************************/
GPIO_EM4GetPinWakeupCause(void)742 __STATIC_INLINE uint32_t GPIO_EM4GetPinWakeupCause(void)
743 {
744 #if defined(_GPIO_EM4WUCAUSE_MASK)
745   return GPIO->EM4WUCAUSE & _GPIO_EM4WUCAUSE_MASK;
746 #else
747   return GPIO->IF & _GPIO_IF_EM4WU_MASK;
748 #endif
749 }
750 #endif
751 
752 #if defined(GPIO_CTRL_EM4RET) || defined(_EMU_EM4CTRL_EM4IORETMODE_MASK)
753 /**************************************************************************//**
754  * @brief
755  *   Enable GPIO pin retention of output enable, output value, pull enable, and
756  *   pull direction in EM4.
757  *
758  * @note
759  *   On series 0 devices EM4 gpio retention can either be turned on or off. On
760  *   series 1 devices there are three EM4 GPIO retention modes available. These
761  *   modes are "Disabled", "EM4EXIT" and "SWUNLATCH". Use the EMU_EM4Init()
762  *   to configure the GPIO retention mode on a series 1 device.
763  *
764  *   The behavior of this function depends on the configured GPIO retention mode.
765  *   If the GPIO retention mode is configured to be "SWUNLATCH" then this
766  *   function will not change anything. If the retention mode is anything else
767  *   then this function will set the GPIO retention mode to "EM4EXIT" when the
768  *   enable argument is true, and "Disabled" when false.
769  *
770  * @param[in] enable
771  *   @li true - enable EM4 pin retention.
772  *   @li false - disable EM4 pin retention.
773  *****************************************************************************/
GPIO_EM4SetPinRetention(bool enable)774 __STATIC_INLINE void GPIO_EM4SetPinRetention(bool enable)
775 {
776 #if defined(GPIO_CTRL_EM4RET)
777   BUS_RegBitWrite(&GPIO->CTRL, _GPIO_CTRL_EM4RET_SHIFT, enable);
778 #else
779 
780   // Leave configuration alone when software unlatch is used.
781   uint32_t mode = EMU->EM4CTRL & _EMU_EM4CTRL_EM4IORETMODE_MASK;
782   if (mode == EMU_EM4CTRL_EM4IORETMODE_SWUNLATCH) {
783     return;
784   }
785 
786   if (enable) {
787     EMU->EM4CTRL = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4IORETMODE_MASK)
788                    | EMU_EM4CTRL_EM4IORETMODE_EM4EXIT;
789   } else {
790     EMU->EM4CTRL = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4IORETMODE_MASK)
791                    | EMU_EM4CTRL_EM4IORETMODE_DISABLE;
792   }
793 #endif
794 }
795 #endif
796 
797 void GPIO_ExtIntConfig(GPIO_Port_TypeDef port,
798                        unsigned int pin,
799                        unsigned int intNo,
800                        bool risingEdge,
801                        bool fallingEdge,
802                        bool enable);
803 
804 #if _SILICON_LABS_32B_SERIES > 0
805 void GPIO_EM4WUExtIntConfig(GPIO_Port_TypeDef port,
806                             unsigned int pin,
807                             uint32_t intNo,
808                             bool polarity,
809                             bool enable);
810 #endif
811 /***************************************************************************//**
812  * @brief
813  *   Enable/disable input sensing.
814  *
815  * @details
816  *   Disabling input sensing if not used, can save some energy consumption.
817  *
818  * @param[in] val
819  *   Bitwise logic OR of one or more of:
820  *   @li GPIO_INSENSE_INT - interrupt input sensing.
821  *   @li GPIO_INSENSE_PRS - peripheral reflex system input sensing.
822  *
823  * @param[in] mask
824  *   Mask containing bitwise logic OR of bits similar as for @p val used to
825  *   indicate which input sense options to disable/enable.
826  ******************************************************************************/
GPIO_InputSenseSet(uint32_t val,uint32_t mask)827 __STATIC_INLINE void GPIO_InputSenseSet(uint32_t val, uint32_t mask)
828 {
829 #if defined(_GPIO_INSENSE_MASK)
830   BUS_RegMaskedWrite(&(GPIO->INSENSE), mask, val);
831 #else
832   (void) val;
833   (void) mask;
834 #endif
835 }
836 
837 /***************************************************************************//**
838  * @brief
839  *   Clear one or more pending GPIO interrupts.
840  *
841  * @param[in] flags
842  *   Bitwise logic OR of GPIO interrupt sources to clear.
843  ******************************************************************************/
GPIO_IntClear(uint32_t flags)844 __STATIC_INLINE void GPIO_IntClear(uint32_t flags)
845 {
846 #if defined(GPIO_HAS_SET_CLEAR)
847   GPIO->IF_CLR = flags;
848 #else
849   GPIO->IFC = flags;
850 #endif
851 }
852 
853 /***************************************************************************//**
854  * @brief
855  *   Disable one or more GPIO interrupts.
856  *
857  * @param[in] flags
858  *   GPIO interrupt sources to disable.
859  ******************************************************************************/
GPIO_IntDisable(uint32_t flags)860 __STATIC_INLINE void GPIO_IntDisable(uint32_t flags)
861 {
862   BUS_RegMaskedClear(&(GPIO->IEN), flags);
863 }
864 
865 /***************************************************************************//**
866  * @brief
867  *   Enable one or more GPIO interrupts.
868  *
869  * @note
870  *   Depending on the use, a pending interrupt may already be set prior to
871  *   enabling the interrupt. To ignore a pending interrupt, consider using
872  *   GPIO_IntClear() prior to enabling the interrupt.
873  *
874  * @param[in] flags
875  *   GPIO interrupt sources to enable.
876  ******************************************************************************/
GPIO_IntEnable(uint32_t flags)877 __STATIC_INLINE void GPIO_IntEnable(uint32_t flags)
878 {
879   BUS_RegMaskedSet(&(GPIO->IEN), flags);
880 }
881 
882 /***************************************************************************//**
883  * @brief
884  *   Get enabled GPIO interrupts.
885  *
886  * @return
887  *   Enabled GPIO interrupt sources.
888  *
889  ******************************************************************************/
GPIO_EnabledIntGet(void)890 __STATIC_INLINE uint32_t GPIO_EnabledIntGet(void)
891 {
892   return GPIO->IEN;
893 }
894 
895 /***************************************************************************//**
896  * @brief
897  *   Get pending GPIO interrupts.
898  *
899  * @return
900  *   GPIO interrupt sources pending.
901  ******************************************************************************/
GPIO_IntGet(void)902 __STATIC_INLINE uint32_t GPIO_IntGet(void)
903 {
904   return GPIO->IF;
905 }
906 
907 /***************************************************************************//**
908  * @brief
909  *   Get enabled and pending GPIO interrupt flags.
910  *   Useful for handling more interrupt sources in the same interrupt handler.
911  *
912  * @note
913  *   Interrupt flags are not cleared by the use of this function.
914  *
915  * @return
916  *   Pending and enabled GPIO interrupt sources.
917  *   The return value is the bitwise AND combination of
918  *   - the OR combination of enabled interrupt sources in GPIO_IEN register
919  *     and
920  *   - the OR combination of valid interrupt flags in GPIO_IF register.
921  ******************************************************************************/
GPIO_IntGetEnabled(void)922 __STATIC_INLINE uint32_t GPIO_IntGetEnabled(void)
923 {
924   uint32_t tmp;
925 
926   /* Store GPIO->IEN in temporary variable in order to define explicit order
927    * of volatile accesses. */
928   tmp = GPIO->IEN;
929 
930   /* Bitwise AND of pending and enabled interrupts */
931   return GPIO->IF & tmp;
932 }
933 
934 /**************************************************************************//**
935  * @brief
936  *   Set one or more pending GPIO interrupts from SW.
937  *
938  * @param[in] flags
939  *   GPIO interrupt sources to set to pending.
940  *****************************************************************************/
GPIO_IntSet(uint32_t flags)941 __STATIC_INLINE void GPIO_IntSet(uint32_t flags)
942 {
943 #if defined (GPIO_HAS_SET_CLEAR)
944   GPIO->IF_SET = flags;
945 #else
946   GPIO->IFS = flags;
947 #endif
948 }
949 
950 /***************************************************************************//**
951  * @brief
952  *   Lock the GPIO configuration.
953  ******************************************************************************/
GPIO_Lock(void)954 __STATIC_INLINE void GPIO_Lock(void)
955 {
956   GPIO->LOCK = ~GPIO_LOCK_LOCKKEY_UNLOCK;
957 }
958 
959 /***************************************************************************//**
960  * @brief
961  *   Read the pad value for a single pin in a GPIO port.
962  *
963  * @param[in] port
964  *   The GPIO port to access.
965  *
966  * @param[in] pin
967  *   The pin number to read.
968  *
969  * @return
970  *   The pin value, 0 or 1.
971  ******************************************************************************/
GPIO_PinInGet(GPIO_Port_TypeDef port,unsigned int pin)972 __STATIC_INLINE unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port,
973                                            unsigned int pin)
974 {
975   EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
976   return BUS_RegBitRead(&GPIO->P[port].DIN, pin);
977 }
978 
979 #if defined (_GPIO_P_PINLOCKN_MASK)
980 /***************************************************************************//**
981  * @brief
982  *   Lock all GPIO configuration settings for a given pin.
983  *   The lock can only be cleared by a chip reset.
984  *
985  * @param[in] port
986  *   The GPIO port to access.
987  *
988  * @param[in] pin
989  *   The pin number to lock.
990  ******************************************************************************/
GPIO_PinLock(GPIO_Port_TypeDef port,unsigned int pin)991 __STATIC_INLINE void GPIO_PinLock(GPIO_Port_TypeDef port, unsigned int pin)
992 {
993   BUS_RegBitWrite(&GPIO->P[port].PINLOCKN, pin, 0);
994 }
995 #endif
996 
997 GPIO_Mode_TypeDef GPIO_PinModeGet(GPIO_Port_TypeDef port,
998                                   unsigned int pin);
999 
1000 void GPIO_PinModeSet(GPIO_Port_TypeDef port,
1001                      unsigned int pin,
1002                      GPIO_Mode_TypeDef mode,
1003                      unsigned int out);
1004 
1005 /***************************************************************************//**
1006  * @brief
1007  *   Set a single pin in GPIO data out port register to 0.
1008  *
1009  * @note
1010  *   To ensure that the setting takes effect on the output pad, the pin must
1011  *   be configured properly. If not, it will take effect whenever the
1012  *   pin has been properly configured.
1013  *
1014  * @param[in] port
1015  *   The GPIO port to access.
1016  *
1017  * @param[in] pin
1018  *   The pin to set.
1019  ******************************************************************************/
GPIO_PinOutClear(GPIO_Port_TypeDef port,unsigned int pin)1020 __STATIC_INLINE void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin)
1021 {
1022   EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
1023 #if defined(_GPIO_P_DOUTCLR_MASK)
1024   GPIO->P[port].DOUTCLR = 1UL << pin;
1025 #elif defined(GPIO_HAS_SET_CLEAR)
1026   GPIO->P_CLR[port].DOUT = 1UL << pin;
1027 #else
1028   BUS_RegMaskedClear(&GPIO->P[port].DOUT, 1UL << pin);
1029 #endif
1030 }
1031 
1032 /***************************************************************************//**
1033  * @brief
1034  *   Get current setting for a pin in a GPIO port data out register.
1035  *
1036  * @param[in] port
1037  *   The GPIO port to access.
1038  *
1039  * @param[in] pin
1040  *   The pin to get setting for.
1041  *
1042  * @return
1043  *   The DOUT setting for the requested pin, 0 or 1.
1044  ******************************************************************************/
GPIO_PinOutGet(GPIO_Port_TypeDef port,unsigned int pin)1045 __STATIC_INLINE unsigned int GPIO_PinOutGet(GPIO_Port_TypeDef port,
1046                                             unsigned int pin)
1047 {
1048   EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
1049   return BUS_RegBitRead(&GPIO->P[port].DOUT, pin);
1050 }
1051 
1052 /***************************************************************************//**
1053  * @brief
1054  *   Set a single pin in GPIO data out register to 1.
1055  *
1056  * @note
1057  *   To ensure that the setting takes effect on the output pad, the pin must
1058  *   be configured properly. If not, it will take effect whenever the
1059  *   pin has been properly configured.
1060  *
1061  * @param[in] port
1062  *   The GPIO port to access.
1063  *
1064  * @param[in] pin
1065  *   The pin to set.
1066  ******************************************************************************/
GPIO_PinOutSet(GPIO_Port_TypeDef port,unsigned int pin)1067 __STATIC_INLINE void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin)
1068 {
1069   EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
1070 #if defined(_GPIO_P_DOUTSET_MASK)
1071   GPIO->P[port].DOUTSET = 1UL << pin;
1072 #elif defined(GPIO_HAS_SET_CLEAR)
1073   GPIO->P_SET[port].DOUT = 1UL << pin;
1074 #else
1075   BUS_RegMaskedSet(&GPIO->P[port].DOUT, 1UL << pin);
1076 #endif
1077 }
1078 
1079 /***************************************************************************//**
1080  * @brief
1081  *   Toggle a single pin in GPIO port data out register.
1082  *
1083  * @note
1084  *   To ensure that the setting takes effect on the output pad, the pin must
1085  *   be configured properly. If not, it will take effect whenever the
1086  *   pin has been properly configured.
1087  *
1088  * @param[in] port
1089  *   The GPIO port to access.
1090  *
1091  * @param[in] pin
1092  *   The pin to toggle.
1093  ******************************************************************************/
GPIO_PinOutToggle(GPIO_Port_TypeDef port,unsigned int pin)1094 __STATIC_INLINE void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin)
1095 {
1096   EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
1097 
1098 #if defined (_GPIO_P_DOUTTGL_MASK)
1099   GPIO->P[port].DOUTTGL = 1UL << pin;
1100 #elif defined(GPIO_HAS_SET_CLEAR)
1101   GPIO->P_TGL[port].DOUT = 1UL << pin;
1102 #else
1103   GPIO->P[port].DOUT ^= 1UL << pin;
1104 #endif
1105 }
1106 
1107 /***************************************************************************//**
1108  * @brief
1109  *   Read the pad values for GPIO port.
1110  *
1111  * @param[in] port
1112  *   The GPIO port to access.
1113  *
1114  * @return
1115  *   The pad values for the GPIO port.
1116  ******************************************************************************/
GPIO_PortInGet(GPIO_Port_TypeDef port)1117 __STATIC_INLINE uint32_t GPIO_PortInGet(GPIO_Port_TypeDef port)
1118 {
1119   EFM_ASSERT(GPIO_PORT_VALID(port));
1120 
1121   return GPIO->P[port].DIN;
1122 }
1123 
1124 /***************************************************************************//**
1125  * @brief
1126  *   Set bits in DOUT register for a port to 0.
1127  *
1128  * @note
1129  *   To ensure that the setting takes effect on the output pad, the pin must
1130  *   be configured properly. If not, it will take effect whenever the
1131  *   pin has been properly configured.
1132  *
1133  * @param[in] port
1134  *   The GPIO port to access.
1135  *
1136  * @param[in] pins
1137  *   Bit mask for bits to clear in DOUT register.
1138  ******************************************************************************/
GPIO_PortOutClear(GPIO_Port_TypeDef port,uint32_t pins)1139 __STATIC_INLINE void GPIO_PortOutClear(GPIO_Port_TypeDef port, uint32_t pins)
1140 {
1141   EFM_ASSERT(GPIO_PORT_VALID(port));
1142 #if defined(_GPIO_P_DOUTCLR_MASK)
1143   GPIO->P[port].DOUTCLR = pins;
1144 #elif defined(GPIO_HAS_SET_CLEAR)
1145   GPIO->P_CLR[port].DOUT = pins;
1146 #else
1147   BUS_RegMaskedClear(&GPIO->P[port].DOUT, pins);
1148 #endif
1149 }
1150 
1151 /***************************************************************************//**
1152  * @brief
1153  *   Get the current setting for a GPIO port data out register.
1154  *
1155  * @param[in] port
1156  *   The GPIO port to access.
1157  *
1158  * @return
1159  *   The data out setting for the requested port.
1160  ******************************************************************************/
GPIO_PortOutGet(GPIO_Port_TypeDef port)1161 __STATIC_INLINE uint32_t GPIO_PortOutGet(GPIO_Port_TypeDef port)
1162 {
1163   EFM_ASSERT(GPIO_PORT_VALID(port));
1164 
1165   return GPIO->P[port].DOUT;
1166 }
1167 
1168 /***************************************************************************//**
1169  * @brief
1170  *   Set bits GPIO data out register to 1.
1171  *
1172  * @note
1173  *   To ensure that the setting takes effect on the respective output pads, the
1174  *   pins must be configured properly. If not, it will take effect
1175  *   whenever the pin has been properly configured.
1176  *
1177  * @param[in] port
1178  *   The GPIO port to access.
1179  *
1180  * @param[in] pins
1181  *   Bit mask for bits to set to 1 in DOUT register.
1182  ******************************************************************************/
GPIO_PortOutSet(GPIO_Port_TypeDef port,uint32_t pins)1183 __STATIC_INLINE void GPIO_PortOutSet(GPIO_Port_TypeDef port, uint32_t pins)
1184 {
1185   EFM_ASSERT(GPIO_PORT_VALID(port));
1186 #if defined(_GPIO_P_DOUTSET_MASK)
1187   GPIO->P[port].DOUTSET = pins;
1188 #elif defined(GPIO_HAS_SET_CLEAR)
1189   GPIO->P_SET[port].DOUT = pins;
1190 #else
1191   BUS_RegMaskedSet(&GPIO->P[port].DOUT, pins);
1192 #endif
1193 }
1194 
1195 /***************************************************************************//**
1196  * @brief
1197  *   Set GPIO port data out register.
1198  *
1199  * @note
1200  *   To ensure that the setting takes effect on the respective output pads, the
1201  *   pins must be configured properly. If not, it will take effect
1202  *   whenever the pin has been properly configured.
1203  *
1204  * @param[in] port
1205  *   The GPIO port to access.
1206  *
1207  * @param[in] val
1208  *   Value to write to port data out register.
1209  *
1210  * @param[in] mask
1211  *   Mask indicating which bits to modify.
1212  ******************************************************************************/
GPIO_PortOutSetVal(GPIO_Port_TypeDef port,uint32_t val,uint32_t mask)1213 __STATIC_INLINE void GPIO_PortOutSetVal(GPIO_Port_TypeDef port,
1214                                         uint32_t val,
1215                                         uint32_t mask)
1216 {
1217   EFM_ASSERT(GPIO_PORT_VALID(port));
1218 
1219   GPIO->P[port].DOUT = (GPIO->P[port].DOUT & ~mask) | (val & mask);
1220 }
1221 
1222 /***************************************************************************//**
1223  * @brief
1224  *   Toggle pins in GPIO port data out register.
1225  *
1226  * @note
1227  *   To ensure that the setting takes effect on the output pad, the pin must
1228  *   be configured properly. If not, it will take effect whenever the
1229  *   pin has been properly configured.
1230  *
1231  * @param[in] port
1232  *   The GPIO port to access.
1233  *
1234  * @param[in] pins
1235  *   Bit mask with pins to toggle.
1236  ******************************************************************************/
GPIO_PortOutToggle(GPIO_Port_TypeDef port,uint32_t pins)1237 __STATIC_INLINE void GPIO_PortOutToggle(GPIO_Port_TypeDef port, uint32_t pins)
1238 {
1239   EFM_ASSERT(GPIO_PORT_VALID(port));
1240 #if defined (GPIO_HAS_SET_CLEAR)
1241   GPIO->P_TGL[port].DOUT = pins;
1242 #else
1243   GPIO->P[port].DOUTTGL = pins;
1244 #endif
1245 }
1246 
1247 #if defined(_GPIO_P_CTRL_SLEWRATE_MASK)
1248 /***************************************************************************//**
1249  * @brief
1250  *   Set slewrate for pins on a GPIO port.
1251  *
1252  * @param[in] port
1253  *   The GPIO port to configure.
1254  *
1255  * @param[in] slewrate
1256  *   The slewrate to configure for pins on this GPIO port.
1257  *
1258  * @param[in] slewrateAlt
1259  *   The slewrate to configure for pins using alternate modes on this GPIO port.
1260  ******************************************************************************/
GPIO_SlewrateSet(GPIO_Port_TypeDef port,uint32_t slewrate,uint32_t slewrateAlt)1261 __STATIC_INLINE void GPIO_SlewrateSet(GPIO_Port_TypeDef port,
1262                                       uint32_t slewrate,
1263                                       uint32_t slewrateAlt)
1264 {
1265   EFM_ASSERT(GPIO_PORT_VALID(port));
1266   EFM_ASSERT(slewrate <= (_GPIO_P_CTRL_SLEWRATE_MASK
1267                           >> _GPIO_P_CTRL_SLEWRATE_SHIFT));
1268   EFM_ASSERT(slewrateAlt <= (_GPIO_P_CTRL_SLEWRATEALT_MASK
1269                              >> _GPIO_P_CTRL_SLEWRATEALT_SHIFT));
1270 
1271   GPIO->P[port].CTRL = (GPIO->P[port].CTRL
1272                         & ~(_GPIO_P_CTRL_SLEWRATE_MASK
1273                             | _GPIO_P_CTRL_SLEWRATEALT_MASK))
1274                        | (slewrate << _GPIO_P_CTRL_SLEWRATE_SHIFT)
1275                        | (slewrateAlt << _GPIO_P_CTRL_SLEWRATEALT_SHIFT);
1276 }
1277 #endif
1278 
1279 /***************************************************************************//**
1280  * @brief
1281  *   Unlock the GPIO configuration.
1282  ******************************************************************************/
GPIO_Unlock(void)1283 __STATIC_INLINE void GPIO_Unlock(void)
1284 {
1285   GPIO->LOCK = GPIO_LOCK_LOCKKEY_UNLOCK;
1286 }
1287 
1288 /*******************************************************************************
1289  ***********************   DEPRECATED PROTOTYPES   *****************************
1290  ***********************     (will be removed)     *****************************
1291  ******************************************************************************/
1292 
1293 /***************************************************************************//**
1294  * @brief
1295  *   Configure GPIO interrupt.
1296  *
1297  * @details
1298  *   If reconfiguring a GPIO interrupt that is already enabled, it is generally
1299  *   recommended to disable it first, see @ref GPIO_IntDisable().
1300  *
1301  *   The actual GPIO interrupt handler must be in place before enabling the
1302  *   interrupt.
1303  *
1304  *   Notice that any pending interrupt for the selected pin is cleared by this
1305  *   function.
1306  *
1307  * @deprecated
1308  *   Deprecated function. New code should use @ref GPIO_ExtIntConfig().
1309  *
1310  * @note
1311  *   A certain pin number can only be associated with one port; i.e., if GPIO
1312  *   interrupt 1 is assigned to port A/pin 1, then it is not possible to use
1313  *   pin 1 from any other ports for interrupts. Refer to the reference
1314  *   manual. On devices which implement GPIO_EXTIPINSEL registers a more
1315  *   flexible approach is possible, refer to @ref GPIO_ExtIntConfig().
1316  *
1317  * @param[in] port
1318  *   The port to associate with @p pin.
1319  *
1320  * @param[in] pin
1321  *   The pin number on the port ( == GPIO EXTI interrupt number).
1322  *
1323  * @param[in] risingEdge
1324  *   Set to true if interrupts will be enabled on rising edge, otherwise false.
1325  *
1326  * @param[in] fallingEdge
1327  *   Set to true if interrupts will be enabled on falling edge, otherwise false.
1328  *
1329  * @param[in] enable
1330  *   Set to true if interrupt will be enabled after configuration completed,
1331  *   false to leave disabled. See @ref GPIO_IntDisable() and @ref GPIO_IntEnable().
1332  ******************************************************************************/
GPIO_IntConfig(GPIO_Port_TypeDef port,unsigned int pin,bool risingEdge,bool fallingEdge,bool enable)1333 __STATIC_INLINE SL_DEPRECATED_API_SDK_4_1 void GPIO_IntConfig(GPIO_Port_TypeDef port,
1334                                                               unsigned int pin,
1335                                                               bool risingEdge,
1336                                                               bool fallingEdge,
1337                                                               bool enable)
1338 {
1339   GPIO_ExtIntConfig(port, pin, pin, risingEdge, fallingEdge, enable);
1340 }
1341 
1342 /** @} (end addtogroup gpio) */
1343 
1344 #ifdef __cplusplus
1345 }
1346 #endif
1347 
1348 #endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */
1349 #endif /* EM_GPIO_H */
1350