1 /***************************************************************************//**
2 * @file
3 * @brief General Purpose IO (GPIO) peripheral API.
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2024 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 #include "sl_hal_gpio.h"
32 #if defined(GPIO_PRESENT)
33 #include "sl_hal_bus.h"
34
35 /*******************************************************************************
36 ************************** GLOBAL FUNCTIONS *******************************
37 ******************************************************************************/
38 extern __INLINE void sl_hal_gpio_lock(void);
39 extern __INLINE void sl_hal_gpio_unlock(void);
40 extern __INLINE uint32_t sl_hal_gpio_get_lock_status(void);
41 extern __INLINE void sl_hal_gpio_set_pin(const sl_gpio_t *gpio);
42 extern __INLINE void sl_hal_gpio_set_port(sl_gpio_port_t port,
43 uint32_t pins);
44 extern __INLINE void sl_hal_gpio_set_port_value(sl_gpio_port_t port,
45 uint32_t val,
46 uint32_t mask);
47 extern __INLINE void sl_hal_gpio_set_slew_rate(sl_gpio_port_t port,
48 uint8_t slewrate);
49 extern __INLINE void sl_hal_gpio_set_slew_rate_alternate(sl_gpio_port_t port,
50 uint8_t slewrate_alt);
51 extern __INLINE uint8_t sl_hal_gpio_get_slew_rate(sl_gpio_port_t port);
52 extern __INLINE uint8_t sl_hal_gpio_get_slew_rate_alternate(sl_gpio_port_t port);
53 extern __INLINE void sl_hal_gpio_clear_pin(const sl_gpio_t *gpio);
54 extern __INLINE void sl_hal_gpio_clear_port(sl_gpio_port_t port,
55 uint32_t pins);
56 extern __INLINE bool sl_hal_gpio_get_pin_input(const sl_gpio_t *gpio);
57 extern __INLINE bool sl_hal_gpio_get_pin_output(const sl_gpio_t *gpio);
58 extern __INLINE uint32_t sl_hal_gpio_get_port_input(sl_gpio_port_t port);
59 extern __INLINE uint32_t sl_hal_gpio_get_port_output(sl_gpio_port_t port);
60 extern __INLINE void sl_hal_gpio_toggle_pin(const sl_gpio_t *gpio);
61 extern __INLINE void sl_hal_gpio_toggle_port(sl_gpio_port_t port,
62 uint32_t pins);
63 extern __INLINE void sl_hal_gpio_enable_interrupts(uint32_t flags);
64 extern __INLINE void sl_hal_gpio_disable_interrupts(uint32_t flags);
65 extern __INLINE void sl_hal_gpio_clear_interrupts(uint32_t flags);
66 extern __INLINE void sl_hal_gpio_set_interrupts(uint32_t flags);
67 extern __INLINE uint32_t sl_hal_gpio_get_pending_interrupts(void);
68 extern __INLINE uint32_t sl_hal_gpio_get_enabled_interrupts(void);
69 extern __INLINE uint32_t sl_hal_gpio_get_enabled_pending_interrupts(void);
70 extern __INLINE int32_t sl_hal_gpio_get_external_interrupt_number(uint8_t pin,
71 uint32_t enabled_interrupts_mask);
72 extern __INLINE int32_t sl_hal_gpio_get_em4_interrupt_number(const sl_gpio_t *gpio);
73 extern __INLINE void sl_hal_gpio_set_pin_em4_retention(bool enable);
74 extern __INLINE void sl_hal_gpio_disable_pin_em4_wakeup (uint32_t pinmask);
75 extern __INLINE uint32_t sl_hal_gpio_get_pin_em4_wakeup_cause(void);
76 extern __INLINE void sl_hal_gpio_enable_debug_swo(bool enable);
77 extern __INLINE void sl_hal_gpio_enable_debug_swd_clk(bool enable);
78 extern __INLINE void sl_hal_gpio_enable_debug_swd_io(bool enable);
79
80 /***************************************************************************//**
81 * Sets the mode for GPIO pin.
82 ******************************************************************************/
sl_hal_gpio_set_pin_mode(const sl_gpio_t * gpio,sl_gpio_mode_t mode,bool output_value)83 void sl_hal_gpio_set_pin_mode(const sl_gpio_t *gpio,
84 sl_gpio_mode_t mode,
85 bool output_value)
86 {
87 sl_gpio_mode_t gpio_mode = SL_GPIO_MODE_DISABLED;
88
89 EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
90 EFM_ASSERT(sl_hal_gpio_get_lock_status() == 0);
91
92 switch (mode) {
93 #if defined(_GPIO_P_MODEL_MODE0_DISABLED)
94 case SL_GPIO_MODE_DISABLED:
95 gpio_mode = _GPIO_P_MODEL_MODE0_DISABLED;
96 break;
97 #endif
98 #if defined(_GPIO_P_MODEL_MODE0_INPUT)
99 case SL_GPIO_MODE_INPUT:
100 gpio_mode = _GPIO_P_MODEL_MODE0_INPUT;
101 break;
102 #endif
103 #if defined(_GPIO_P_MODEL_MODE0_INPUTPULL)
104 case SL_GPIO_MODE_INPUT_PULL:
105 gpio_mode = _GPIO_P_MODEL_MODE0_INPUTPULL;
106 break;
107 #endif
108 #if defined(_GPIO_P_MODEL_MODE0_INPUTPULLFILTER)
109 case SL_GPIO_MODE_INPUT_PULL_FILTER:
110 gpio_mode = _GPIO_P_MODEL_MODE0_INPUTPULLFILTER;
111 break;
112 #endif
113 #if defined(_GPIO_P_MODEL_MODE0_PUSHPULL)
114 case SL_GPIO_MODE_PUSH_PULL:
115 gpio_mode = _GPIO_P_MODEL_MODE0_PUSHPULL;
116 break;
117 #endif
118 #if defined(_GPIO_P_MODEL_MODE0_PUSHPULLALT)
119 case SL_GPIO_MODE_PUSH_PULL_ALTERNATE:
120 gpio_mode = _GPIO_P_MODEL_MODE0_PUSHPULLALT;
121 break;
122 #endif
123 #if defined(_GPIO_P_MODEL_MODE0_WIREDOR)
124 case SL_GPIO_MODE_WIRED_OR:
125 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDOR;
126 break;
127 #endif
128 #if defined(_GPIO_P_MODEL_MODE0_WIREDORPULLDOWN)
129 case SL_GPIO_MODE_WIRED_OR_PULL_DOWN:
130 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN;
131 break;
132 #endif
133 #if defined(_GPIO_P_MODEL_MODE0_WIREDAND)
134 case SL_GPIO_MODE_WIRED_AND:
135 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDAND;
136 break;
137 #endif
138 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDFILTER)
139 case SL_GPIO_MODE_WIRED_AND_FILTER:
140 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDFILTER;
141 break;
142 #endif
143 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUP)
144 case SL_GPIO_MODE_WIRED_AND_PULLUP:
145 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDPULLUP;
146 break;
147 #endif
148 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER)
149 case SL_GPIO_MODE_WIRED_AND_PULLUP_FILTER:
150 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER;
151 break;
152 #endif
153 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALT)
154 case SL_GPIO_MODE_WIRED_AND_ALTERNATE:
155 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALT;
156 break;
157 #endif
158 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTFILTER)
159 case SL_GPIO_MODE_WIRED_AND_ALTERNATE_FILTER:
160 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALTFILTER;
161 break;
162 #endif
163 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP)
164 case SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP:
165 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP;
166 break;
167 #endif
168 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER)
169 case SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP_FILTER:
170 gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER;
171 break;
172 #endif
173 default:
174 EFM_ASSERT(false);
175 break;
176 }
177
178 EFM_ASSERT(SL_HAL_GPIO_MODE_IS_VALID(gpio_mode));
179
180 // If disabling a pin, do not modify DOUT to reduce the chance of
181 // a glitch/spike (may not be sufficient precaution in all use cases).
182 // As mode settings are dependent on DOUT values, setting output value
183 // prior to mode. @ref enum - sl_gpio_mode_t
184 if (mode != SL_GPIO_MODE_DISABLED) {
185 if (output_value) {
186 sl_hal_gpio_set_pin(gpio);
187 } else {
188 sl_hal_gpio_clear_pin(gpio);
189 }
190 }
191
192 // There are two registers controlling the pins for each port.
193 // The MODEL register controls pins 0-7 and MODEH controls pins 8-15.
194 if (gpio->pin < 8) {
195 sl_hal_bus_reg_write_mask(&(GPIO->P[gpio->port].MODEL), 0xFu << (gpio->pin * 4), gpio_mode << (gpio->pin * 4));
196 } else {
197 sl_hal_bus_reg_write_mask(&(GPIO->P[gpio->port].MODEH), 0xFu << ((gpio->pin - 8) * 4), gpio_mode << ((gpio->pin - 8) * 4));
198 }
199
200 // SL_GPIO_MODE_DISABLED based on DOUT Value (low/high) act as two different configurations.
201 // By setting mode to disabled first and then modifying the DOUT value, so that
202 // previous mode configuration on given pin not effected.
203 if (mode == SL_GPIO_MODE_DISABLED) {
204 if (output_value) {
205 sl_hal_gpio_set_pin(gpio);
206 } else {
207 sl_hal_gpio_clear_pin(gpio);
208 }
209 }
210 }
211
212 /***************************************************************************//**
213 * Get the mode for a GPIO pin.
214 ******************************************************************************/
sl_hal_gpio_get_pin_mode(const sl_gpio_t * gpio)215 sl_gpio_mode_t sl_hal_gpio_get_pin_mode(const sl_gpio_t *gpio)
216 {
217 sl_gpio_mode_t mode = SL_GPIO_MODE_DISABLED;
218 EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
219
220 // Determine the current mode of the GPIO pin based on the pin number.
221 if (gpio->pin < 8) {
222 mode = (sl_gpio_mode_t) ((GPIO->P[gpio->port].MODEL >> (gpio->pin * 4)) & 0xF);
223 } else {
224 mode = (sl_gpio_mode_t) ((GPIO->P[gpio->port].MODEH >> ((gpio->pin - 8) * 4)) & 0xF);
225 }
226
227 // Map the hardware-specific mode to the corresponding sl_gpio_mode_t value
228 switch (mode) {
229 #if defined(_GPIO_P_MODEL_MODE0_DISABLED)
230 case _GPIO_P_MODEL_MODE0_DISABLED:
231 return SL_GPIO_MODE_DISABLED;
232 #endif
233 #if defined(_GPIO_P_MODEL_MODE0_INPUT)
234 case _GPIO_P_MODEL_MODE0_INPUT:
235 return SL_GPIO_MODE_INPUT;
236 #endif
237 #if defined(_GPIO_P_MODEL_MODE0_INPUTPULL)
238 case _GPIO_P_MODEL_MODE0_INPUTPULL:
239 return SL_GPIO_MODE_INPUT_PULL;
240 #endif
241 #if defined(_GPIO_P_MODEL_MODE0_INPUTPULLFILTER)
242 case _GPIO_P_MODEL_MODE0_INPUTPULLFILTER:
243 return SL_GPIO_MODE_INPUT_PULL_FILTER;
244 #endif
245 #if defined(_GPIO_P_MODEL_MODE0_PUSHPULL)
246 case _GPIO_P_MODEL_MODE0_PUSHPULL:
247 return SL_GPIO_MODE_PUSH_PULL;
248 #endif
249 #if defined(_GPIO_P_MODEL_MODE0_PUSHPULLALT)
250 case _GPIO_P_MODEL_MODE0_PUSHPULLALT:
251 return SL_GPIO_MODE_PUSH_PULL_ALTERNATE;
252 #endif
253 #if defined(_GPIO_P_MODEL_MODE0_WIREDOR)
254 case _GPIO_P_MODEL_MODE0_WIREDOR:
255 return SL_GPIO_MODE_WIRED_OR;
256 #endif
257 #if defined(_GPIO_P_MODEL_MODE0_WIREDORPULLDOWN)
258 case _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN:
259 return SL_GPIO_MODE_WIRED_OR_PULL_DOWN;
260 #endif
261 #if defined(_GPIO_P_MODEL_MODE0_WIREDAND)
262 case _GPIO_P_MODEL_MODE0_WIREDAND:
263 return SL_GPIO_MODE_WIRED_AND;
264 #endif
265 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDFILTER)
266 case _GPIO_P_MODEL_MODE0_WIREDANDFILTER:
267 return SL_GPIO_MODE_WIRED_AND_FILTER;
268 #endif
269 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUP)
270 case _GPIO_P_MODEL_MODE0_WIREDANDPULLUP:
271 return SL_GPIO_MODE_WIRED_AND_PULLUP;
272 #endif
273 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER)
274 case _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER:
275 return SL_GPIO_MODE_WIRED_AND_PULLUP_FILTER;
276 #endif
277 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALT)
278 case _GPIO_P_MODEL_MODE0_WIREDANDALT:
279 return SL_GPIO_MODE_WIRED_AND_ALTERNATE;
280 #endif
281 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTFILTER)
282 case _GPIO_P_MODEL_MODE0_WIREDANDALTFILTER:
283 return SL_GPIO_MODE_WIRED_AND_ALTERNATE_FILTER;
284 #endif
285 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP)
286 case _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP:
287 return SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP;
288 #endif
289 #if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER)
290 case _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER:
291 return SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP_FILTER;
292 #endif
293 default:
294 EFM_ASSERT(false);
295 return mode; // returning the default state
296 }
297 }
298
299 /***************************************************************************//**
300 * Configure the GPIO pin interrupt.
301 ******************************************************************************/
sl_hal_gpio_configure_external_interrupt(const sl_gpio_t * gpio,int32_t int_no,sl_gpio_interrupt_flag_t flags)302 int32_t sl_hal_gpio_configure_external_interrupt(const sl_gpio_t *gpio,
303 int32_t int_no,
304 sl_gpio_interrupt_flag_t flags)
305 {
306 EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
307 EFM_ASSERT(SL_GPIO_FLAG_IS_VALID(flags));
308 EFM_ASSERT(sl_hal_gpio_get_lock_status() == 0);
309
310 if (int_no != SL_GPIO_INTERRUPT_UNAVAILABLE && int_no >= 0) {
311 #if defined(_GPIO_EXTIPINSELL_MASK)
312 EFM_ASSERT(SL_HAL_GPIO_INTNO_PIN_VALID(int_no, gpio->pin));
313 #endif
314 }
315
316 #if !defined(_GPIO_EXTIPINSELL_MASK)
317 int_no = gpio->pin;
318 #endif
319
320 if (int_no == SL_GPIO_INTERRUPT_UNAVAILABLE) {
321 uint32_t interrupts_enabled = sl_hal_gpio_get_enabled_interrupts();
322 int_no = sl_hal_gpio_get_external_interrupt_number(gpio->pin, interrupts_enabled);
323 }
324
325 if (int_no != SL_GPIO_INTERRUPT_UNAVAILABLE && int_no >= 0) {
326 if (int_no < 8) {
327 // The EXTIPSELL register controls pins 0-7 of the interrupt configuration.
328 #if defined(_GPIO_EXTIPSELL_EXTIPSEL0_MASK)
329 sl_hal_bus_reg_write_mask(&GPIO->EXTIPSELL,
330 _GPIO_EXTIPSELL_EXTIPSEL0_MASK
331 << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * int_no),
332 (uint32_t)gpio->port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * int_no));
333 #endif
334 // The EXTIPINSELL register controls interrupt 0-7 of the interrupt/pin number mapping.
335 #if defined(_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
336 sl_hal_bus_reg_write_mask(&GPIO->EXTIPINSELL,
337 _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
338 << (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * int_no),
339 ((gpio->pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
340 << (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * int_no));
341 #endif
342 } else {
343 // EXTIPSELH controls pins 8-15 of the interrupt configuration.
344 #if defined(_GPIO_EXTIPSELH_EXTIPSEL0_MASK)
345 uint32_t tmp = int_no - 8;
346 sl_hal_bus_reg_write_mask(&GPIO->EXTIPSELH,
347 _GPIO_EXTIPSELH_EXTIPSEL0_MASK
348 << (_GPIO_EXTIPSELH_EXTIPSEL1_SHIFT * tmp),
349 (uint32_t)gpio->port << (_GPIO_EXTIPSELH_EXTIPSEL1_SHIFT * tmp));
350 #endif
351 // EXTIPINSELH controls interrupt 8-15 of the interrupt/pin number mapping.
352 #if defined(_GPIO_EXTIPINSELH_EXTIPINSEL0_MASK)
353 sl_hal_bus_reg_write_mask(&GPIO->EXTIPINSELH,
354 _GPIO_EXTIPINSELH_EXTIPINSEL0_MASK
355 << (_GPIO_EXTIPINSELH_EXTIPINSEL1_SHIFT * tmp),
356 ((gpio->pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL0_MASK)
357 << (_GPIO_EXTIPSELH_EXTIPSEL1_SHIFT * tmp));
358 #endif
359 }
360
361 // Enable/disable rising edge interrupt.
362 (((flags & SL_GPIO_INTERRUPT_RISING_EDGE) == SL_GPIO_INTERRUPT_RISING_EDGE)
363 || ((flags & SL_GPIO_INTERRUPT_RISING_FALLING_EDGE) == SL_GPIO_INTERRUPT_RISING_FALLING_EDGE)) \
364 ? sl_hal_bus_reg_write_bit(&(GPIO->EXTIRISE), int_no, true) \
365 : sl_hal_bus_reg_write_bit(&(GPIO->EXTIRISE), int_no, false);
366
367 // Enable/disable falling edge interrupt.
368 (((flags & SL_GPIO_INTERRUPT_FALLING_EDGE) == SL_GPIO_INTERRUPT_FALLING_EDGE)
369 || (flags & SL_GPIO_INTERRUPT_RISING_FALLING_EDGE) == SL_GPIO_INTERRUPT_RISING_FALLING_EDGE) \
370 ? sl_hal_bus_reg_write_bit(&(GPIO->EXTIFALL), int_no, true) \
371 : sl_hal_bus_reg_write_bit(&(GPIO->EXTIFALL), int_no, false);
372
373 // Clear any pending interrupt.
374 sl_hal_gpio_clear_interrupts(1 << int_no);
375 }
376
377 return int_no;
378 }
379
380 /**************************************************************************//**
381 * Enable GPIO pin wake-up from EM4. When the function exits,
382 * EM4 mode can be safely entered.
383 *****************************************************************************/
sl_hal_gpio_enable_pin_em4_wakeup(uint32_t pinmask,uint32_t polaritymask)384 void sl_hal_gpio_enable_pin_em4_wakeup(uint32_t pinmask,
385 uint32_t polaritymask)
386 {
387 EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
388 EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
389
390 GPIO->EM4WUPOL &= ~pinmask; // Set the wakeup polarity.
391 GPIO->EM4WUPOL |= pinmask & polaritymask;
392 GPIO->EM4WUEN |= pinmask; // Enable wakeup.
393
394 sl_hal_gpio_set_pin_em4_retention(true); // Enable the pin retention.
395 sl_hal_gpio_clear_interrupts(pinmask); // clear any pending interrupt.
396 }
397
398 /***************************************************************************//**
399 * Configure EM4WU pins as external level-sensitive interrupts.
400 ******************************************************************************/
sl_hal_gpio_configure_wakeup_em4_external_interrupt(const sl_gpio_t * gpio,int32_t int_no,bool polarity)401 int32_t sl_hal_gpio_configure_wakeup_em4_external_interrupt(const sl_gpio_t *gpio,
402 int32_t int_no,
403 bool polarity)
404 {
405 EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
406 EFM_ASSERT(sl_hal_gpio_get_lock_status() == 0);
407
408 int32_t em4_int_no = sl_hal_gpio_get_em4_interrupt_number(gpio);
409
410 if (int_no == SL_GPIO_INTERRUPT_UNAVAILABLE) {
411 int_no = em4_int_no;
412 }
413
414 if (em4_int_no == SL_GPIO_INTERRUPT_UNAVAILABLE || int_no != em4_int_no) {
415 return SL_GPIO_INTERRUPT_UNAVAILABLE;
416 }
417
418 if (int_no != SL_GPIO_INTERRUPT_UNAVAILABLE) {
419 // GPIO pin mode set.
420 sl_hal_gpio_set_pin_mode(gpio, SL_GPIO_MODE_INPUT_PULL_FILTER, (unsigned int)!polarity);
421
422 // Enable EM4WU function and set polarity.
423 uint32_t polarityMask = (uint32_t)polarity << (int_no + _GPIO_EM4WUEN_EM4WUEN_SHIFT);
424 uint32_t pinmask = 1UL << (int_no + _GPIO_EM4WUEN_EM4WUEN_SHIFT);
425
426 sl_hal_gpio_enable_pin_em4_wakeup(pinmask, polarityMask);
427 }
428
429 return int_no;
430 }
431
432 #endif /* defined(GPIO_PRESENT)*/
433