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