1 /***************************************************************************//**
2 * @file
3 * @brief General Purpose IO (GPIO) driver 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 #ifndef SL_GPIO_H
32 #define SL_GPIO_H
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 #include <stdbool.h>
39 #include "sl_status.h"
40 #include "sl_device_gpio.h"
41
42 #ifndef EM_GPIO_H
43 #define gpioPortA 0
44 #define gpioPortB 1
45 #define gpioPortC 2
46 #define gpioPortD 3
47 #define gpioPortE 4
48 #define gpioPortF 5
49 #define gpioPortG 6
50 #define gpioPortH 7
51 #define gpioPortI 8
52 #define gpioPortJ 9
53 #define gpioPortK 10
54 #endif
55
56 /* *INDENT-OFF* */
57 // *****************************************************************************
58 /// @addtogroup gpio GPIO - General Purpose Input Output
59 /// @brief General Purpose Input Output driver
60 ///
61 /// @li @ref gpio_intro
62 ///
63 ///@n @section gpio_intro Introduction
64 /// This module contains functions to control the GPIO peripheral of Silicon Labs 32-bit MCUs and SoCs.
65 /// The GPIO driver is used for external and EM4 interrupt configuration, port and pin configuration.
66 /// as well as manages the interrupt handler.
67 ///
68 /// @{
69 // *****************************************************************************
70 /* *INDENT-ON* */
71
72 /*******************************************************************************
73 ******************************** ENUMS ************************************
74 ******************************************************************************/
75
76 /// GPIO Pin directions.
SL_ENUM(sl_gpio_pin_direction_t)77 SL_ENUM(sl_gpio_pin_direction_t) {
78 /// Input direction.
79 SL_GPIO_PIN_DIRECTION_IN = 0,
80 /// Output direction.
81 SL_GPIO_PIN_DIRECTION_OUT
82 };
83
84 /*******************************************************************************
85 ******************************* STRUCTS ***********************************
86 ******************************************************************************/
87
88 /***************************************************************************//**
89 * @brief
90 * Structure for GPIO port and pin configuration.
91 ******************************************************************************/
92 typedef struct {
93 sl_gpio_mode_t mode;
94 sl_gpio_pin_direction_t direction;
95 } sl_gpio_pin_config_t;
96
97 /*******************************************************************************
98 ******************************* TYPEDEFS **********************************
99 ******************************************************************************/
100
101 /***************************************************************************//**
102 * GPIO interrupt callback function pointer.
103 *
104 * @param int_no The pin interrupt number to which the callback function is invoked for.
105 * @param context Pointer to callback context.
106 ******************************************************************************/
107 typedef void (*sl_gpio_irq_callback_t)(uint8_t int_no, void *context);
108
109 /*******************************************************************************
110 ***************************** PROTOTYPES **********************************
111 ******************************************************************************/
112
113 /***************************************************************************//**
114 * Initialization of GPIO driver module.
115 *
116 * @return SL_STATUS_OK if initialization is successful.
117 ******************************************************************************/
118 sl_status_t sl_gpio_init(void);
119
120 /***************************************************************************//**
121 * Sets the pin direction of GPIO pin.
122 *
123 * @param[in] gpio Pointer to GPIO structure with port and pin
124 * @param[in] pin_dir Pin direction of GPIO pin.
125 *
126 * @return SL_STATUS_OK if there's no error.
127 * SL_STATUS_INVALID_PARAMATER if any of the port, pin, direction parameters are invalid.
128 * SL_STATUS_INVALID_STATE if GPIO configuration is in lock state.
129 ******************************************************************************/
130 sl_status_t sl_gpio_set_pin_direction(const sl_gpio_t *gpio,
131 sl_gpio_pin_direction_t pin_dir);
132
133 /***************************************************************************//**
134 * Set the pin mode and set/clear the pin for GPIO pin.
135 *
136 * @param[in] gpio Pointer to GPIO structure with port and pin
137 * @param[in] mode The desired pin mode.
138 * @param[in] output_value Value to set/clear for pin output on the port.
139 * Determines the pull-up/pull-down direction of the pin for
140 * some input mode configurations.
141 *
142 * @return SL_STATUS_OK if there's no error.
143 * SL_STATUS_INVALID_PARAMETER if any of the port, pin, mode parameters are invalid.
144 * SL_STATUS_INVALID_STATE if GPIO configuration is in locked state.
145 ******************************************************************************/
146 sl_status_t sl_gpio_set_pin_mode(const sl_gpio_t *gpio,
147 sl_gpio_mode_t mode,
148 bool output_value);
149
150 /***************************************************************************//**
151 * Gets the current configuration selected pin on selected port.
152 *
153 * @param[in] gpio Pointer to GPIO structure with port and pin
154 * @param[out] pin_config Pointer to pin configuration such as mode and direction.
155 * Pointer acts as an output and returns the configuration of
156 * selected pin on selected port.
157 *
158 * @return SL_STATUS_OK if there's no error.
159 * SL_STATUS_INVALID_PARAMETER if any of the port, pin parameters are invalid.
160 * SL_STATUS_NULL_POINTER if pin_config is passed as null.
161 ******************************************************************************/
162 sl_status_t sl_gpio_get_pin_config(const sl_gpio_t *gpio,
163 sl_gpio_pin_config_t *pin_config);
164
165 /***************************************************************************//**
166 * Sets the selected pin of the selected port.
167 *
168 * @param[in] gpio Pointer to GPIO structure with port and pin
169 *
170 * @return SL_STATUS_OK if there's no error.
171 * SL_STATUS_INVALID_PARAMATER if any of the port, pin parameters are invalid.
172 ******************************************************************************/
173 sl_status_t sl_gpio_set_pin(const sl_gpio_t *gpio);
174
175 /***************************************************************************//**
176 * Clears the selected pin of the selected port.
177 *
178 * @param[in] gpio Pointer to GPIO structure with port and pin
179 *
180 * @return SL_STATUS_OK if there's no error.
181 * SL_STATUS_INVALID_PARAMATER if any of the port, pin parameters are invalid.
182 ******************************************************************************/
183 sl_status_t sl_gpio_clear_pin(const sl_gpio_t *gpio);
184
185 /***************************************************************************//**
186 * Toggles the state of selected pin on selected port.
187 *
188 * @param[in] gpio Pointer to GPIO structure with port and pin
189 *
190 * @return SL_STATUS_OK if there's no error.
191 * SL_STATUS_INVALID_PARAMATER if any of the port, pin parameters are invalid.
192 ******************************************************************************/
193 sl_status_t sl_gpio_toggle_pin(const sl_gpio_t *gpio);
194
195 /***************************************************************************//**
196 * Gets the output state of selected pin on selected port.
197 *
198 * @param[in] gpio Pointer to GPIO structure with port and pin
199 * @param[out] pin_value Pointer to return output state of selected pin on selected port
200 * when configured to output mode.
201 *
202 * @return SL_STATUS_OK if there's no error.
203 * SL_STATUS_INVALID_PARAMATER if any of the port, pin parameters are invalid.
204 * SL_STATUS_NULL_POINTER if pin_value passed as null.
205 ******************************************************************************/
206 sl_status_t sl_gpio_get_pin_output(const sl_gpio_t *gpio,
207 bool *pin_value);
208
209 /***************************************************************************//**
210 * Gets the input state of selected pin on selected port.
211 *
212 * @param[in] gpio Pointer to GPIO structure with port and pin
213 * @param[out] pin_value Pointer to return input state of selected pin on selected port
214 * when configured to input mode.
215 *
216 * @return SL_STATUS_OK if there's no error.
217 * SL_STATUS_INVALID_PARAMATER if any of the port, pin parameters are invalid.
218 * SL_STATUS_NULL_POINTER if pin_value passed as null.
219 ******************************************************************************/
220 sl_status_t sl_gpio_get_pin_input(const sl_gpio_t *gpio,
221 bool *pin_value);
222
223 /***************************************************************************//**
224 * Sets the selected pin(s) of selected port.
225 *
226 * @param[in] port The GPIO port to access.
227 * @param[in] pins Bit mask for pins to set.
228 *
229 * @return SL_STATUS_OK if there's no error.
230 * SL_STATUS_INVALID_PARAMETER if port is invalid.
231 ******************************************************************************/
232 sl_status_t sl_gpio_set_port(sl_gpio_port_t port,
233 uint32_t pins);
234
235 /***************************************************************************//**
236 * Clears the selected pin(s) of selected port.
237 *
238 * @param[in] port The GPIO Port to access.
239 * @param[in] pins Bit mask for bits to clear.
240 *
241 * @return SL_STATUS_OK if there's no error.
242 * SL_STATUS_INVALID_PARAMETER if port is invalid.
243 ******************************************************************************/
244 sl_status_t sl_gpio_clear_port(sl_gpio_port_t port,
245 uint32_t pins);
246
247 /***************************************************************************//**
248 * Gets the output state of pins of selected port.
249 *
250 * @param[in] gpio The GPIO Port to access.
251 * @param[out] port_value Pointer to return output state of pins on selected port.
252 *
253 * @return SL_STATUS_OK if there's no error.
254 * SL_STATUS_INVALID_PARAMETER if port is invalid.
255 * SL_STATUS_NULL_POINTER if port_value passed as null.
256 ******************************************************************************/
257 sl_status_t sl_gpio_get_port_output(sl_gpio_port_t port,
258 uint32_t *port_value);
259
260 /***************************************************************************//**
261 * Gets the input state of pins of selected port.
262 *
263 * @param[in] gpio The GPIO Port to access.
264 * @param[out] port_value Pointer to return output state of pins on selected port.
265 *
266 * @return SL_STATUS_OK if there's no error.
267 * SL_STATUS_INVALID_PARAMETER if port is invalid.
268 * SL_STATUS_NULL_POINTER if port_value passed as null.
269 ******************************************************************************/
270 sl_status_t sl_gpio_get_port_input(sl_gpio_port_t port,
271 uint32_t *port_value);
272
273 /***************************************************************************//**
274 * Configures the GPIO pin interrupt.
275 *
276 * @details By default, this function can be used to register a callback which shall be called upon
277 * interrupt generated for a given pin interrupt number and enables interrupt.
278 * This function configures and enables the external interrupt and performs
279 * callback registration.
280 * It is recommended to use sl_gpio_deconfigure_external_interrupt()
281 * to disable the interrupt and unregister the callback.
282 * see @ref sl_gpio_deconfigure_external_interrupt for more information.
283 * If a valid interrupt number is provided, operation will proceed accordingly.
284 * Otherwise, a valid interrupt number will be generated based on provided port and
285 * pin and used for subsequent operations.
286 *
287 * @note If the user has a valid interrupt number to provide as input, it can be used.
288 * If the user does not have an interrupt number, they can pass -1 (SL_GPIO_INTERRUPT_UNAVAILABLE)
289 * as value to variable int_no.
290 * The int_no parameter serves even as an output, a pointer to convey the interrupt number
291 * for cases where user lacks an interrupt number.
292 * @note the pin number can be selected freely within a group.
293 * Interrupt numbers are divided into 4 groups (int_no / 4) and valid pin
294 * number within the interrupt groups are:
295 * 0: pins 0-3 (interrupt number 0-3)
296 * 1: pins 4-7 (interrupt number 4-7)
297 * 2: pins 8-11 (interrupt number 8-11)
298 * 3: pins 12-15 (interrupt number 12-15)
299 *
300 * @param[in] gpio Pointer to GPIO structure with port and pin
301 * @param[in/out] int_no Pointer to interrupt number to trigger.
302 * Pointer that serves as both an input and an output to return int_no
303 * when the user lacks an int_no.
304 * @param[in] flags Interrupt flags for interrupt configuration.
305 * Determines the interrupt to get trigger based on rising/falling edge.
306 * @param[in] gpio_callback A pointer to gpio callback function.
307 * @param[in] context A pointer to the callback context.
308 *
309 * @return SL_STATUS_OK if there's no error.
310 * SL_STATUS_INVALID_PARAMETER if any of the port, pin, flag parameters are invalid.
311 * SL_STATUS_NULL_POINTER if the int_no is passed as NULL.
312 * SL_STATUS_NOT_FOUND if there's no available interrupt number.
313 ******************************************************************************/
314 sl_status_t sl_gpio_configure_external_interrupt(const sl_gpio_t *gpio,
315 int32_t *int_no,
316 sl_gpio_interrupt_flag_t flags,
317 sl_gpio_irq_callback_t gpio_callback,
318 void *context);
319
320 /***************************************************************************//**
321 * Deconfigures the GPIO external pin interrupt.
322 *
323 * @details This function can be used to deconfigure the external GPIO interrupt.
324 * This function performs callback unregistration, clears and disables the
325 * given interrupt.
326 *
327 * @note the pin number can be selected freely within a group.
328 * Interrupt numbers are divided into 4 groups (int_no / 4) and valid pin
329 * number within the interrupt groups are:
330 * 0: pins 0-3 (interrupt number 0-3)
331 * 1: pins 4-7 (interrupt number 4-7)
332 * 2: pins 8-11 (interrupt number 8-11)
333 * 3: pins 12-15 (interrupt number 12-15)
334 *
335 * @param[in] int_no Interrupt number to unregister and disable.
336 *
337 * @return SL_STATUS_OK if there's no error.
338 * SL_STATUS_INVALID_PARAMETER if int_no is invalid.
339 ******************************************************************************/
340 sl_status_t sl_gpio_deconfigure_external_interrupt(int32_t int_no);
341
342 /***************************************************************************//**
343 * Enables one or more GPIO Interrupts.
344 *
345 * @param[in] int_mask Mask for GPIO Interrupt sources to enable.
346 *
347 * @return SL_STATUS_OK if there's no error.
348 ******************************************************************************/
349 sl_status_t sl_gpio_enable_interrupts(uint32_t int_mask);
350
351 /***************************************************************************//**
352 * Disables one or more GPIO Interrupts.
353 *
354 * @param[in] int_mask Mask for GPIO Interrupt sources to disable.
355 *
356 * @return SL_STATUS_OK if there's no error.
357 ******************************************************************************/
358 sl_status_t sl_gpio_disable_interrupts(uint32_t int_mask);
359
360 /***************************************************************************//**
361 * Configuration EM4WU pins as external level-sensitive interrupts.
362 *
363 * @details By default, this function performs callback registration, enables GPIO pin wake-up from EM4,
364 * sets the wake-up polarity, enables GPIO pin retention and enables the EM4 wake-up interrupt.
365 * It is recommended to use sl_gpio_deconfigure_wakeup_em4_interrupt()
366 * to unregister the callback and disable the em4 interrupt as well as GPIO pin wake-up from EM4.
367 * It is recommended to use sl_gpio_set_pin_em4_retention() to enable/disable the GPIO pin retention.
368 * see @ref sl_gpio_deconfigure_wakeup_em4_interrupt() and @ref sl_gpio_set_pin_em4_retention().
369 * If a valid EM4 wake-up interrupt number is provided, operation will proceed accordingly.
370 * Otherwise, a valid EM4 interrupt number will be generated based on provided EM4 configured
371 * port and pin and used for subsequent operations.
372 *
373 * @note If the user has a valid em4 interrupt number to provide as input, it can be used.
374 * If the user does not have an interrupt number, they can pass -1 (SL_GPIO_INTERRUPT_UNAVAILABLE)
375 * as value to variable em4_int_no.
376 * The em4_int_no parameter serves even as an output, a pointer to convey the em4 interrupt number
377 * for cases where user lacks an em4 interrupt number.
378 * @note There are specific ports and pins mapped to an existent EM4WU interrupt
379 * Each EM4WU signal is connected to a fixed pin and port.
380 * Based on chip, EM4 wake up interrupts configured port and pin might vary.
381 *
382 * @param[in] gpio Pointer to GPIO structure with port and pin
383 * @param[in/out] em4_int_no Pointer to interrupt number to trigger.
384 * Pointer that serves as both an input and an output to return em4_int_no
385 * when the user lacks an em4_int_no.
386 * @param[in] polarity Determines the wakeup polarity.
387 * true = Active high level-sensitive interrupt.
388 * false = Active low level-sensitive interrupt.
389 * @param[in] gpio_callback A pointer to callback.
390 * @param[in] context A pointer to callback context.
391 *
392 * @return SL_STATUS_OK if there's no error.
393 * SL_STATUS_INVALID_PARAMETER if any of the port, pin parameters are invalid.
394 * SL_STATUS_NULL_POINTER if the int_no is passed as NULL.
395 * SL_STATUS_NOT_FOUND if there's no available interrupt number.
396 ******************************************************************************/
397 sl_status_t sl_gpio_configure_wakeup_em4_interrupt(const sl_gpio_t *gpio,
398 int32_t *em4_int_no,
399 bool polarity,
400 sl_gpio_irq_callback_t gpio_callback,
401 void *context);
402
403 /***************************************************************************//**
404 * Utilize this function to deconfigure the EM4 GPIO pin interrupt.
405 * It serves to unregister a callback, disable/clear interrupt and clear em4 wakeup source.
406 *
407 * @details This function performs callback unregistration, clears and disables given em4
408 * interrupt and disables GPIO pin wake-up from EM4.
409 *
410 * @param[in] em4_int_no EM4 wakeup interrupt number.
411 *
412 * @return SL_STATUS_OK if there's no error.
413 * SL_STATUS_INVALID_PARAMETER if em4_int_no is invalid.
414 ******************************************************************************/
415 sl_status_t sl_gpio_deconfigure_wakeup_em4_interrupt(int32_t em4_int_no);
416
417 /***************************************************************************//**
418 * Enable EM4 GPIO pin Wake-up bit.
419 * Sets the wakeup and polarity of the EM4 wakeup.
420 *
421 * @param[in] em4_int_mask Mask for setting desired EM4 wake up interrupt to enable.
422 * Mask contains the bitwise logic OR of which EM4 wake up interrupt to
423 * enable.
424 * @param[in] em4_polarity_mask Mask for setting the wake up polarity for the EM4 wake up interrupt.
425 * Mask contains the bitwise logic OR of EM4 wake-up interrupt polarity.
426 *
427 * @return SL_STATUS_OK if there's no error.
428 ******************************************************************************/
429 sl_status_t sl_gpio_enable_pin_em4_wakeup(uint32_t em4_int_mask,
430 uint32_t em4_polarity_mask);
431
432 /***************************************************************************//**
433 * Disabled the GPIO wake up from EM4.
434 *
435 * @param[in] pinmask Mask for clearing desired EM4 wake up interrupt to disable.
436 * Mask contains the bitwise logic OR of which EM4 wake up interrupt to
437 * disable.
438 *
439 * @return SL_STATUS_OK if there's no error.
440 ******************************************************************************/
441 sl_status_t sl_gpio_disable_pin_em4_wakeup(uint32_t em4_int_mask);
442
443 /***************************************************************************//**
444 * Enable/Disable GPIO pin retention of output enable, output value, pull enable, and pull direction in EM4.
445 *
446 * @param[in] enable true - enables EM4 pin retention.
447 * false - disables EM4 pin retention.
448 *
449 * @return SL_STATUS_OK if there's no error.
450 ******************************************************************************/
451 sl_status_t sl_gpio_set_pin_em4_retention(bool enable);
452
453 /***************************************************************************//**
454 * Sets slewrate for selected port.
455 *
456 * @param[in] port The GPIO port to configure.
457 * @param[in] slewrate The slewrate to configure the GPIO port.
458 *
459 * @return SL_STATUS_OK if there's no error.
460 * SL_STATUS_INVALID_PARAMETER if port is invalid.
461 ******************************************************************************/
462 sl_status_t sl_gpio_set_slew_rate(sl_gpio_port_t port,
463 uint8_t slewrate);
464
465 /***************************************************************************//**
466 * Gets slewrate for selected port.
467 *
468 * @param[in] port The GPIO port to get slewrate.
469 * @param[out] slewrate Pointer to store the slewrate of selected port.
470 *
471 * @return SL_STATUS_OK if there's no error.
472 * SL_STATUS_INVALID_PARAMETER if port is invalid.
473 * SL_STATUS_NULL_POINTER if slewrate is passed as null.
474 ******************************************************************************/
475 sl_status_t sl_gpio_get_slew_rate(sl_gpio_port_t port,
476 uint8_t *slewrate);
477
478 /***************************************************************************//**
479 * Locks the GPIO Configuration.
480 *
481 * @note This API locks the functionalities such as sl_gpio_set_pin_mode(),
482 * sl_gpio_configure_external_interrupt() and sl_gpio_configure_wakeup_em4_interrupt().
483 * After locking the GPIO configuration, use sl_gpio_unlock API to unlock
484 * the GPIO configuration to use mentioned functionalities.
485 *
486 * @return SL_STATUS_OK if there's no error.
487 ******************************************************************************/
488 sl_status_t sl_gpio_lock(void);
489
490 /***************************************************************************//**
491 * Unlocks the GPIO Configuration.
492 *
493 * @note After locking the GPIO configuration it is recommended to unlock the GPIO configuration
494 * using sl_gpio_unlock(). You can determine if the GPIO configuration is locked or unlocked
495 * by using the sl_gpio_is_locked() function.
496 * Before using certain functions like sl_gpio_set_pin_mode(),
497 * sl_gpio_configure_external_interrupt(), and sl_gpio_configure_wakeup_em4_interrupt(),
498 * it's important to check if the GPIO configuration lock is unlocked.
499 *
500 * @return SL_STATUS_OK if there's no error.
501 ******************************************************************************/
502 sl_status_t sl_gpio_unlock(void);
503
504 /***************************************************************************//**
505 * Gets current GPIO Lock status.
506 *
507 * @note This function helps check the current status of GPIO configuration.
508 *
509 * @param[out] state Pointer to current state of GPIO configuration (lock/unlock).
510 *
511 * @return SL_STATUS_OK if there's no error.
512 * SL_STATUS_NULL_POINTER if state is passed as null.
513 ******************************************************************************/
514 sl_status_t sl_gpio_is_locked(bool *state);
515
516 /** @} (end addtogroup gpio driver) */
517 #ifdef __cplusplus
518 }
519 #endif
520
521 #endif /* SL_GPIO_H */
522