1 /******************************************************************************
2 * @file sl_si91x_peripheral_gpio.c
3 *******************************************************************************
4 * # License
5 * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6 *******************************************************************************
7 *
8 * SPDX-License-Identifier: Zlib
9 *
10 * The licensor of this software is Silicon Laboratories Inc.
11 *
12 * This software is provided 'as-is', without any express or implied
13 * warranty. In no event will the authors be held liable for any damages
14 * arising from the use of this software.
15 *
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, subject to the following restrictions:
19 *
20 * 1. The origin of this software must not be misrepresented; you must not
21 * claim that you wrote the original software. If you use this software
22 * in a product, an acknowledgment in the product documentation would be
23 * appreciated but is not required.
24 * 2. Altered source versions must be plainly marked as such, and must not be
25 * misrepresented as being the original software.
26 * 3. This notice may not be removed or altered from any source distribution.
27 *
28 ******************************************************************************/
29 #include "sl_si91x_peripheral_gpio.h"
30 #ifdef DEBUG_UART
31 #include "rsi_debug.h"
32 #endif
33
34 /*******************************************************************************
35 *************************** DEFINES / MACROS ********************************
36 ******************************************************************************/
37 #define GPIO_RELEASE_VERSION 0 // gpio Release version
38 #define GPIO_MAJOR_VERSION 0 // gpio SQA version
39 #define GPIO_MINOR_VERSION 2 // gpio Developer version
40
41 /*******************************************************************************
42 ************************ GLOBAL FUNCTIONS **************************
43 ******************************************************************************/
44 extern __INLINE void sl_gpio_set_pin_output(sl_gpio_port_t port, uint8_t pin);
45 extern __INLINE void sl_gpio_clear_pin_output(sl_gpio_port_t port, uint8_t pin);
46 /*******************************************************************************
47 * This API is used to configure the pin interrupt in GPIO HP instance.
48 * There are total 8 pin interrupts in this instance.
49 * To configure the interrupt, first GPIO initialization must be done.
50 * The actions to be performed in GPIO initialization are:
51 * - Enable the M4 clock of GPIO HP instance.
52 * - Select PAD selection of the GPIO HP instance.
53 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
54 * output/input.
55 * - Set pin mode and direction of the GPIO pin.
56 * Configuring the pin interrupt requires port number, pin number, interrupt number,
57 * and interrupt flag to be generated.
58 * Enable the IRQ handler.
59 ******************************************************************************/
sl_gpio_configure_interrupt(sl_gpio_port_t port,uint8_t pin,uint32_t int_no,sl_gpio_interrupt_flag_t flags)60 void sl_gpio_configure_interrupt(sl_gpio_port_t port, uint8_t pin, uint32_t int_no, sl_gpio_interrupt_flag_t flags)
61 {
62 // Pin interrupt configuration in HP GPIO instance
63 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
64 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_FLAG(flags));
65 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_INTR(int_no));
66 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.PORT_NUMBER = port;
67 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.PIN_NUMBER = (sl_si91x_gpio_pin_t)pin;
68 // Enable or disable GPIO interrupt falling edge in GPIO HP instance
69 if ((flags & SL_GPIO_INTERRUPT_FALLING_EDGE) == SL_GPIO_INTERRUPT_FALLING_EDGE) {
70 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.FALL_EDGE_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
71 } else {
72 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.FALL_EDGE_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
73 }
74 // Enable or disable GPIO interrupt rising edge in GPIO HP instance
75 if ((flags & SL_GPIO_INTERRUPT_RISING_EDGE) == SL_GPIO_INTERRUPT_RISING_EDGE) {
76 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.RISE_EDGE_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
77 } else {
78 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.RISE_EDGE_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
79 }
80 // Enable GPIO interrupt level high
81 if ((flags & SL_GPIO_INTERRUPT_HIGH) == SL_GPIO_INTERRUPT_HIGH) {
82 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_HIGH_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
83 }
84 // Disable GPIO interrupt level high
85 else {
86 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_HIGH_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
87 }
88 // Enable GPIO interrupt level low
89 if ((flags & SL_GPIO_INTERRUPT_LOW) == SL_GPIO_INTERRUPT_LOW) {
90 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_LOW_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
91 }
92 // Disable GPIO interrupt level low
93 else {
94 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_LOW_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
95 }
96 // Un-mask the interrupt
97 GPIO->INTR[int_no].GPIO_INTR_CTRL_b.MASK = CLR;
98 }
99
100 /*******************************************************************************
101 * This API is used for GPIO HP, ULP instances to set pin mode.
102 * - If GPIO HP instance is considered, the following actions are performed:
103 * - To set the pin mode in GPIO HP instance, GPIO initialization needs to be done first.
104 * - The actions to be performed in GPIO initialization are:
105 * - Enable the M4 clock of GPIO HP instance.
106 * - Select PAD selection of the GPIO HP instance.
107 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
108 * output/input.
109 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
110 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
111 * - If GPIO ULP instance is considered, the following actions are performed:
112 * - To set the pin mode in GPIO ULP instance, GPIO initialization needs to be done first.
113 * - The actions to be performed in GPIO initialization are:
114 * - Enable the ULP clock of GPIO ULP instance.
115 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
116 * output/input.
117 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
118 ******************************************************************************/
sl_gpio_set_pin_mode(sl_gpio_port_t port,uint8_t pin,sl_gpio_mode_t mode,uint32_t output_value)119 void sl_gpio_set_pin_mode(sl_gpio_port_t port, uint8_t pin, sl_gpio_mode_t mode, uint32_t output_value)
120 {
121 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(output_value));
122 /* If disabling a pin, do not modify register to reduce the chance of */
123 /* a glitch/spike(may not be sufficient precaution in all use cases). */
124 if (mode != SL_GPIO_MODE_DISABLED) {
125 if (output_value) {
126 sl_gpio_set_pin_output(port, pin); // Set the GPIO pin
127 } else {
128 sl_gpio_clear_pin_output(port, pin); // Clear the GPIO pin
129 }
130 }
131 // if condition is satisfied when ULP GPIO instance occurs
132 if (port == SL_GPIO_ULP_PORT) {
133 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_MODE_PARAMETER(mode));
134 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.MODE = mode; // Set mode in ULP GPIO instance
135 }
136 // else condition is satisfied when HP GPIO instance occurs
137 else {
138 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_MODE(mode));
139 // Set mode in HP GPIO instance
140 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.MODE = mode;
141 }
142 if (mode == SL_GPIO_MODE_DISABLED) {
143 if (output_value) {
144 sl_gpio_set_pin_output(port, pin); // Set the GPIO pin
145 } else {
146 sl_gpio_clear_pin_output(port, pin); // Clear the GPIO pin
147 }
148 }
149 }
150
151 /*******************************************************************************
152 * This API is used for GPIO HP, ULP instances to get pin mode.
153 * - If GPIO HP instance is considered, the following actions are performed:
154 * - To get the pin status in GPIO HP instance, GPIO initialization needs to be done first.
155 * - The actions to be performed in GPIO initialization are:
156 * - Enable the M4 clock of GPIO HP instance.
157 * - Select PAD selection of the GPIO HP instance.
158 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
159 * output/input.
160 * - Set pin mode and direction of the GPIO pin.
161 * - Get the pin mode of GPIO pin.
162 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
163 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
164 * - If GPIO ULP instance is considered, the following actions are performed:
165 * - To get the pin mode in GPIO ULP instance, GPIO initialization needs to be done first.
166 * - The actions to be performed in GPIO initialization are:
167 * - Enable the ULP clock of GPIO ULP instance.
168 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
169 * output/input.
170 * - Set pin mode and direction of the GPIO pin.
171 * - Get the pin mode of GPIO pin.
172 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
173 ******************************************************************************/
sl_gpio_get_pin_mode(sl_gpio_port_t port,uint8_t pin)174 sl_gpio_mode_t sl_gpio_get_pin_mode(sl_gpio_port_t port, uint8_t pin)
175 {
176 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
177 if (port == SL_GPIO_ULP_PORT) {
178 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
179 // Read status of the pin in ULP GPIO instance
180 return (sl_gpio_mode_t)(ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.MODE);
181 } else {
182 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
183 // Read status of the pin in HP GPIO instance
184 return (sl_gpio_mode_t)(GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.MODE);
185 }
186 }
187
188 /*******************************************************************************
189 * This API is used for GPIO HP, ULP instances to set pin direction.
190 * - If GPIO HP instance is considered, the following actions are performed:
191 * - To set the pin direction in GPIO HP instance, GPIO initialization needs to be done first.
192 * - The actions to be performed in GPIO initialization are:
193 * - Enable the M4 clock of GPIO HP instance.
194 * - Select PAD selection of the GPIO HP instance.
195 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
196 * output/input.
197 * - Set pin mode and direction of the GPIO pin.
198 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
199 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
200 * - If GPIO ULP instance is considered, the following actions are performed:
201 * - To set the pin direction in GPIO ULP instance, GPIO initialization needs to be done first.
202 * - The actions to be performed in GPIO initialization are:
203 * - Enable the ULP clock of GPIO ULP instance.
204 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
205 * output/input.
206 * - Set pin mode and direction of the GPIO pin.
207 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
208 *******************************************************************************/
sl_si91x_gpio_set_pin_direction(uint8_t port,uint8_t pin,sl_si91x_gpio_direction_t direction)209 void sl_si91x_gpio_set_pin_direction(uint8_t port, uint8_t pin, sl_si91x_gpio_direction_t direction)
210 {
211 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
212 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(direction));
213 if ((port == SL_GPIO_PORT_A) || (port == SL_GPIO_PORT_B) || (port == SL_GPIO_PORT_C) || (port == SL_GPIO_PORT_D)) {
214 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
215 // Set the pin direction in HP GPIO instance
216 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.DIRECTION = direction;
217 } else if (port == SL_GPIO_ULP_PORT) {
218 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
219 // Set the pin direction in ULP GPIO instance
220 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.DIRECTION = direction;
221 } else {
222 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
223 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(direction));
224 // Set direction(input/output) in UULP GPIO instance
225 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_OEN = direction;
226 }
227 }
228
229 /*******************************************************************************
230 * This API is used for GPIO HP, ULP instances to get pin direction.
231 * - If GPIO HP instance is considered, the following actions are performed:
232 * - To get the pin direction in GPIO HP instance, GPIO initialization needs to be done first.
233 * - The actions to be performed in GPIO initialization are:
234 * - Enable the M4 clock of GPIO HP instance.
235 * - Select PAD selection of the GPIO HP instance.
236 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
237 * output/input.
238 * - Set pin mode and direction of the GPIO pin.
239 * - Get the pin direction of the GPIO pin.
240 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
241 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
242 * - If GPIO ULP instance is considered, the following actions are performed:
243 * - To get the pin direction in GPIO ULP instance, GPIO initialization needs to be done first.
244 * - The actions to be performed in GPIO initialization are:
245 * - Enable the ULP clock of GPIO ULP instance.
246 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
247 * output/input.
248 * - Set pin mode and direction of the GPIO pin.
249 * - Get the pin direction of the GPIO pin.
250 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
251 ******************************************************************************/
sl_si91x_gpio_get_pin_direction(uint8_t port,uint8_t pin)252 uint8_t sl_si91x_gpio_get_pin_direction(uint8_t port, uint8_t pin)
253 {
254 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
255 if (port == SL_GPIO_ULP_PORT) {
256 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
257 // Get the pin direction in ULP GPIO instance
258 return ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.DIRECTION;
259 } else {
260 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
261 // Get the pin direction in HP GPIO instance
262 return GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.DIRECTION;
263 }
264 }
265
266 /*******************************************************************************
267 * This API is used to enable PAD receiver in GPIO HP instance.
268 * The actions to be performed for enabling PAD are:
269 * - Enable the M4 clock of GPIO HP instance.
270 * - Select PAD selection of the GPIO HP instance.
271 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
272 * output/input.
273 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
274 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
275 *******************************************************************************/
sl_si91x_gpio_enable_pad_receiver(uint8_t gpio_num)276 void sl_si91x_gpio_enable_pad_receiver(uint8_t gpio_num)
277 {
278 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PIN(gpio_num));
279 // Set the REN(receiver bit) in PAD configuration register
280 PAD_REG(gpio_num)->GPIO_PAD_CONFIG_REG_b.PADCONFIG_REN = SET;
281 }
282
283 /*******************************************************************************
284 * This API is used to disable PAD receiver in GPIO HP instance.
285 * The actions to be performed for disabling PAD are:
286 * - Enable the M4 clock of GPIO HP instance.
287 * - Select PAD selection of the GPIO HP instance.
288 * - Disable PAD receiver for GPIO pin number, whether GPIO pin is selected as
289 * output/input.
290 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
291 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
292 *******************************************************************************/
sl_si91x_gpio_disable_pad_receiver(uint8_t gpio_num)293 void sl_si91x_gpio_disable_pad_receiver(uint8_t gpio_num)
294 {
295 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PIN(gpio_num));
296 // Clear the REN(receiver bit) in PAD configuration register
297 PAD_REG(gpio_num)->GPIO_PAD_CONFIG_REG_b.PADCONFIG_REN = CLR;
298 }
299
300 /*******************************************************************************
301 * This API is used to enable PAD selection in GPIO HP instance.
302 * The actions to be performed for enable PAD selection are:
303 * - Enable the M4 clock of GPIO HP instance.
304 * - Select PAD selection of the GPIO HP instance.
305 * @note: PAD number(25 to 30) are used for HOST PAD selection.
306 * Do not use PAD number-9 as it is used for other functionality.
307 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
308 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
309 *******************************************************************************/
sl_si91x_gpio_enable_pad_selection(uint8_t gpio_padnum)310 void sl_si91x_gpio_enable_pad_selection(uint8_t gpio_padnum)
311 {
312 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PAD(gpio_padnum));
313 if (gpio_padnum < PAD_SELECT) {
314 /*(tass_m4ss_gpio_sel)PAD selection (0 to 21)
315 A value of 1 on this gives control to M4SS(by default it is 0 means control) */
316 PADSELECTION |= BIT(gpio_padnum);
317 }
318 if (gpio_padnum >= PAD_SELECT) {
319 /*(tass_m4ss_gpio_sel)PAD selection (22 to 33)
320 A value of 1 on this gives control to M4SS(by default it is 0 means NWP control) */
321 PADSELECTION_1 |= BIT(gpio_padnum - PAD_SELECT);
322 }
323 }
324
325 /*******************************************************************************
326 * This API is used to enable PAD selection in GPIO HP instance.
327 * @note: GPIO pin number(25 to 30) are used for HOST PAD selection.
328 *******************************************************************************/
sl_si91x_gpio_enable_host_pad_selection(uint8_t gpio_num)329 void sl_si91x_gpio_enable_host_pad_selection(uint8_t gpio_num)
330 {
331 if (gpio_num >= HOST_PAD_MIN && gpio_num <= HOST_PAD_MAX) {
332 // (tass_m4ss_gpio_sel)PAD selection (25 to 30)
333 // A value of 1 on this gives control to M4SS(by default it is 0)
334 HOST_PADS_GPIO_MODE |= BIT(gpio_num - HOST_PAD_SELECT);
335 }
336 }
337
338 /*******************************************************************************
339 * To select the PAD driver strength in GPIO HP instance, GPIO initialization
340 * needs to be done first.
341 * - The actions to be performed in GPIO initialization are:
342 * - Enable the M4 clock of GPIO HP instance.
343 * - Select PAD selection of the GPIO HP instance.
344 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
345 * output/input.
346 * - Set pin mode and direction of the GPIO pin.
347 * - Select the PAD driver strength of type @ref sl_si91x_gpio_driver_strength_select_t.
348 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
349 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
350 ******************************************************************************/
sl_si91x_gpio_select_pad_driver_strength(uint8_t gpio_num,sl_si91x_gpio_driver_strength_select_t strength)351 void sl_si91x_gpio_select_pad_driver_strength(uint8_t gpio_num, sl_si91x_gpio_driver_strength_select_t strength)
352 {
353 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PIN(gpio_num));
354 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_STRENGTH(strength));
355 // Select the required drive strength in HP GPIO instance
356 PAD_REG(gpio_num)->GPIO_PAD_CONFIG_REG_b.PADCONFIG_E1_E2 = strength;
357 }
358
359 /*******************************************************************************
360 * To select the PAD driver disable state in GPIO HP instance, GPIO initialization
361 * needs to be done first.
362 * - The actions to be performed in GPIO initialization are:
363 * - Enable the M4 clock of GPIO HP instance.
364 * - Select PAD selection of the GPIO HP instance.
365 * - Enable PAD receiver for GPIO pin number, whether GPIO pin is selected as
366 * output/input.
367 * - Set pin mode and direction of the GPIO pin.
368 * - Select the PAD driver disable state of type @ref sl_si91x_gpio_driver_disable_state_t.
369 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
370 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
371 ******************************************************************************/
sl_si91x_gpio_select_pad_driver_disable_state(uint8_t gpio_num,sl_si91x_gpio_driver_disable_state_t disable_state)372 void sl_si91x_gpio_select_pad_driver_disable_state(uint8_t gpio_num, sl_si91x_gpio_driver_disable_state_t disable_state)
373 {
374 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PIN(gpio_num));
375 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_DISABLE_STATE(disable_state));
376 // Select the required driver disable state in HP GPIO instance
377 PAD_REG(gpio_num)->GPIO_PAD_CONFIG_REG_b.PADCONFIG_P1_P2 = disable_state;
378 }
379
380 /*******************************************************************************
381 * The GPIO pins to work in different instances, requires this clock.
382 * For GPIO HP instance, enable M4 clock of type @ref sl_si91x_gpio_select_clock_t.
383 * For GPIO ULP/UULP instances, enable ULP clock of type
384 * @ref sl_si91x_gpio_select_clock_t
385 ******************************************************************************/
sl_si91x_gpio_enable_clock(sl_si91x_gpio_select_clock_t clock)386 void sl_si91x_gpio_enable_clock(sl_si91x_gpio_select_clock_t clock)
387 {
388 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(clock));
389 // Set M4 clock
390 if (clock == M4CLK_GPIO) {
391 SL_PERIPHERAL_CLK->CLK_ENABLE_SET_REG3_b.EGPIO_CLK_ENABLE_b = SET;
392 SL_PERIPHERAL_CLK->CLK_ENABLE_SET_REG2_b.EGPIO_PCLK_ENABLE_b = SET;
393 }
394 // Set ULP clock
395 else {
396 ULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_CLK_EN_b = SET;
397 ULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_PCLK_ENABLE_b = SET;
398 }
399 }
400
401 /*******************************************************************************
402 * This API disables the M4/ ULP clock of GPIO instances.
403 * For GPIO HP instance, disable M4 clock of type @ref sl_si91x_gpio_select_clock_t.
404 * For GPIO ULP/UULP instances, disable ULP clock of type
405 * @ref sl_si91x_gpio_select_clock_t
406 ******************************************************************************/
sl_si91x_gpio_disable_clock(sl_si91x_gpio_select_clock_t clock)407 void sl_si91x_gpio_disable_clock(sl_si91x_gpio_select_clock_t clock)
408 {
409 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(clock));
410 // Clear M4 clock
411 if (clock == M4CLK_GPIO) {
412 SL_PERIPHERAL_CLK->CLK_ENABLE_SET_REG3_b.EGPIO_CLK_ENABLE_b = CLR;
413 SL_PERIPHERAL_CLK->CLK_ENABLE_SET_REG2_b.EGPIO_PCLK_ENABLE_b = CLR;
414 }
415 // Clear ULP clock
416 else {
417 ULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_CLK_EN_b = CLR;
418 ULPCLK->ULP_MISC_SOFT_SET_REG_b.EGPIO_PCLK_ENABLE_b = CLR;
419 }
420 }
421
422 /*******************************************************************************
423 * This API is used for GPIO HP, ULP instances.
424 * It is used to enable the group interrupts.
425 * @note: We are calling this API, inside the group interrupt configuration API's
426 * @ref sl_si91x_gpio_configure_group_interrupt(), used for HP instance,
427 * @ref sl_si91x_gpio_configure_ulp_group_interrupt(), used for ULP instance.
428 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
429 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
430 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
431 *******************************************************************************/
sl_si91x_gpio_enable_group_interrupt(sl_si91x_group_interrupt_t group_interrupt,uint8_t port,uint8_t pin)432 void sl_si91x_gpio_enable_group_interrupt(sl_si91x_group_interrupt_t group_interrupt, uint8_t port, uint8_t pin)
433 {
434 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
435 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
436 // Enable group interrupt in ULP GPIO instance
437 if (port == SL_GPIO_ULP_PORT) {
438 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
439 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_INTERRUPT = ENABLE;
440 // Enable group interrupt 1 in ULP GPIO instance
441 if (group_interrupt == GROUP_INT_1) {
442 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_ENABLE = ENABLE;
443 } else {
444 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT2_ENABLE = ENABLE;
445 }
446 }
447 // Enable group interrupt in HP GPIO instance
448 else {
449 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
450 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_INTERRUPT = ENABLE;
451 if (group_interrupt == GROUP_INT_1) {
452 // Enable group interrupt 1 in HP GPIO instance
453 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_ENABLE = ENABLE;
454 } else {
455 // Enable group interrupt 2 in HP GPIO instance
456 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT2_ENABLE = ENABLE;
457 }
458 }
459 }
460
461 /*******************************************************************************
462 * This API is used for GPIO HP, ULP instances.
463 * It is used to disable the group interrupts.
464 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
465 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
466 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
467 *******************************************************************************/
sl_si91x_gpio_disable_group_interrupt(sl_si91x_group_interrupt_t group_interrupt,uint8_t port,uint8_t pin)468 void sl_si91x_gpio_disable_group_interrupt(sl_si91x_group_interrupt_t group_interrupt, uint8_t port, uint8_t pin)
469 {
470 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
471 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
472 // Disable group interrupt in ULP GPIO instance
473 if (port == SL_GPIO_ULP_PORT) {
474 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
475 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_INTERRUPT = DISABLE;
476 // Disable group interrupt 1 in ULP GPIO instance
477 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_ENABLE = DISABLE;
478 } else {
479 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
480 // Disable group interrupt in HP GPIO instance
481 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_INTERRUPT = DISABLE;
482 if (group_interrupt == GROUP_INT_1) {
483 // Disable group interrupt 1 in HP GPIO instance
484 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_ENABLE = DISABLE;
485 } else {
486 // Disable group interrupt 2 in HP GPIO instance
487 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT2_ENABLE = DISABLE;
488 }
489 }
490 }
491
492 /*******************************************************************************
493 * This API is used for GPIO HP, ULP instances.
494 * It is used to mask the group interrupts.
495 *******************************************************************************/
sl_si91x_gpio_mask_group_interrupt(uint8_t port,sl_si91x_group_interrupt_t group_interrupt)496 void sl_si91x_gpio_mask_group_interrupt(uint8_t port, sl_si91x_group_interrupt_t group_interrupt)
497 {
498 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
499 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
500 if (port == SL_GPIO_ULP_PORT) {
501 // Enable group interrupt mask in ULP GPIO instance
502 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.MASK = ENABLE;
503 } else {
504 // Enable group interrupt mask in HP GPIO instance
505 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.MASK = ENABLE;
506 }
507 }
508
509 /*******************************************************************************
510 * This API is used for GPIO HP, ULP instances.
511 * It is used to unmask the group interrupts.
512 * @note: We are calling this API, inside the group interrupt configuration API's
513 * @ref sl_si91x_gpio_configure_group_interrupt(), used for HP instance,
514 * @ref sl_si91x_gpio_configure_ulp_group_interrupt(), used for ULP instance.
515 *******************************************************************************/
sl_si91x_gpio_unmask_group_interrupt(uint8_t port,sl_si91x_group_interrupt_t group_interrupt)516 void sl_si91x_gpio_unmask_group_interrupt(uint8_t port, sl_si91x_group_interrupt_t group_interrupt)
517 {
518 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
519 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
520 if (port == SL_GPIO_ULP_PORT) {
521 // Disable group interrupt mask in ULP GPIO instance
522 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.MASK = DISABLE;
523 } else {
524 // Disable group interrupt mask in HP GPIO instance
525 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.MASK = DISABLE;
526 }
527 }
528
529 /*******************************************************************************
530 * This API is used for GPIO HP, ULP instances.
531 * It is used to set level/edge event of group interrupt.
532 * @note: We are calling this API, inside the group interrupt configuration API's
533 * @ref sl_si91x_gpio_configure_group_interrupt(), used for HP instance,
534 * @ref sl_si91x_gpio_configure_ulp_group_interrupt(), used for ULP instance.
535 ******************************************************************************/
sl_si91x_gpio_set_group_interrupt_level_edge(uint8_t port,sl_si91x_group_interrupt_t group_interrupt,sl_si91x_gpio_level_edge_t level_edge)536 void sl_si91x_gpio_set_group_interrupt_level_edge(uint8_t port,
537 sl_si91x_group_interrupt_t group_interrupt,
538 sl_si91x_gpio_level_edge_t level_edge)
539 {
540 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
541 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
542 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(level_edge));
543 if (port == SL_GPIO_ULP_PORT) {
544 // Enable group level edge interrupt in ULP GPIO instance
545 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.LEVEL_EDGE = level_edge;
546 } else {
547 // Enable group level edge interrupt in HP GPIO instance
548 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.LEVEL_EDGE = level_edge;
549 }
550 }
551
552 /*******************************************************************************
553 * This API is used for GPIO HP, ULP instances.
554 * It is used to get level/edge event of group interrupt.
555 ******************************************************************************/
sl_si91x_gpio_get_group_interrupt_level_edge(uint8_t port,sl_si91x_group_interrupt_t group_interrupt)556 uint8_t sl_si91x_gpio_get_group_interrupt_level_edge(uint8_t port, sl_si91x_group_interrupt_t group_interrupt)
557 {
558 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
559 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
560 if (port == SL_GPIO_ULP_PORT) {
561 // Get group level edge interrupt in ULP GPIO instance
562 return ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.LEVEL_EDGE;
563 } else {
564 // Get group level edge interrupt in HP GPIO instance
565 return GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.LEVEL_EDGE;
566 }
567 }
568
569 /*******************************************************************************
570 * This API is used for GPIO HP, ULP instances.
571 * It is used to set polarity of group interrupt.
572 * @note: We are calling this API, inside the group interrupt configuration API's
573 * @ref sl_si91x_gpio_configure_group_interrupt(), used for HP instance,
574 * @ref sl_si91x_gpio_configure_ulp_group_interrupt(), used for ULP instance.
575 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
576 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
577 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
578 ******************************************************************************/
sl_si91x_gpio_set_group_interrupt_polarity(sl_si91x_group_interrupt_t group_interrupt,uint8_t port,uint8_t pin,sl_si91x_gpio_polarity_t polarity)579 void sl_si91x_gpio_set_group_interrupt_polarity(sl_si91x_group_interrupt_t group_interrupt,
580 uint8_t port,
581 uint8_t pin,
582 sl_si91x_gpio_polarity_t polarity)
583 {
584 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
585 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
586 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(polarity));
587 if (port == SL_GPIO_ULP_PORT) {
588 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
589 // Set group interrupt polarity in ULP GPIO instance
590 if (group_interrupt == GROUP_INT_1) {
591 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_POLARITY = polarity;
592 } else {
593 ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT2_POLARITY = polarity;
594 }
595 } else {
596 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
597 // Set group interrupt polarity in HP GPIO instance
598 if (group_interrupt == GROUP_INT_1) {
599 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_POLARITY = polarity;
600 } else {
601 GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT2_POLARITY = polarity;
602 }
603 }
604 }
605
606 /*******************************************************************************
607 * This API is used for GPIO HP, ULP instances.
608 * It is used to get polarity of group interrupt .
609 * @note: Select HP GPIO pins for HP instances(GPIO_6 to GPIO_57). Do not use
610 * GPIO pin number(0 to 5) in HP instance as these are used for other functionality.
611 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
612 ******************************************************************************/
sl_si91x_gpio_get_group_interrupt_polarity(sl_si91x_group_interrupt_t group_interrupt,uint8_t port,uint8_t pin)613 uint8_t sl_si91x_gpio_get_group_interrupt_polarity(sl_si91x_group_interrupt_t group_interrupt,
614 uint8_t port,
615 uint8_t pin)
616 {
617 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
618 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
619 if (port == SL_GPIO_ULP_PORT) {
620 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PORT_PIN(port, pin));
621 // Get group interrupt polarity in ULP GPIO instance
622 return ULP_GPIO->PIN_CONFIG[pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_POLARITY;
623 } else {
624 SL_GPIO_ASSERT(SL_GPIO_NDEBUG_PORT_PIN(port, pin));
625 // Get group interrupt polarity in HP GPIO instance
626 if (group_interrupt == GROUP_INT_1) {
627 return GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT1_POLARITY;
628 } else {
629 return GPIO->PIN_CONFIG[(port * MAX_GPIO_PORT_PIN) + pin].GPIO_CONFIG_REG_b.GROUP_INTERRUPT2_POLARITY;
630 }
631 }
632 }
633
634 /*******************************************************************************
635 * This API is used for GPIO HP, ULP instances.
636 * It is used to select and/or event of group interrupt.
637 * @example: Consider two GPIO pins for group interrupts.
638 * - If AND event is selected then both GPIO pins, interrupt should be
639 * generated to do specific task.
640 * - If OR event is selected then any one GPIO pin, interrupt generation
641 * should be enough to do specific task.
642 * @note: We are calling this API, inside the group interrupt configuration API's
643 * @ref sl_si91x_gpio_configure_group_interrupt(), used for HP instance,
644 * @ref sl_si91x_gpio_configure_ulp_group_interrupt(), used for ULP instance.
645 *******************************************************************************/
sl_si91x_gpio_select_group_interrupt_and_or(uint8_t port,sl_si91x_group_interrupt_t group_interrupt,sl_si91x_gpio_and_or_t and_or)646 void sl_si91x_gpio_select_group_interrupt_and_or(uint8_t port,
647 sl_si91x_group_interrupt_t group_interrupt,
648 sl_si91x_gpio_and_or_t and_or)
649 {
650 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
651 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
652 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(and_or));
653 if (port == SL_GPIO_ULP_PORT) {
654 // Set group interrupt OR in ULP GPIO instance
655 if ((and_or & SL_GPIO_GROUP_INTERRUPT_OR) == (SL_GPIO_GROUP_INTERRUPT_OR)) {
656 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.AND_OR = SET;
657 }
658 // Set group interrupt AND in ULP GPIO instance
659 else {
660 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.AND_OR = CLR;
661 }
662 } else {
663 // Set group interrupt OR in HP GPIO instance
664 if ((and_or & SL_GPIO_GROUP_INTERRUPT_OR) == (SL_GPIO_GROUP_INTERRUPT_OR)) {
665 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.AND_OR = SET;
666 }
667 // Set group interrupt AND in HP GPIO instance
668 else {
669 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.AND_OR = CLR;
670 }
671 }
672 }
673
674 /*******************************************************************************
675 * This API is used in GPIO HP instance to configure group interrupts.
676 * It has configuration pointer of type @ref sl_si91x_gpio_group_interrupt_config_t
677 * structure.
678 * GPIO HP instance has total 4 ports. Port-0, 1, 2 has 16 pins each. Port-3 has 9 pins.
679 * While configuring group interrupts, one can select random ports and pins for
680 * group interrupt.
681 * @example 1:
682 * - If port 1 is selected, any group of pins(0 to 16) can be selected for group interrupt.
683 * - Same applied for other ports also.
684 * @example 2:
685 * - Once can select port 1, pin 7 and port 2, pin 3 as a group for interrupt generation.
686 * - One should assign group count of how many pins are passed.
687 * For more clarification look into group interrupt configuration structure
688 * @ref sl_si91x_gpio_group_interrupt_config_t.
689 * @note: Do not use Port 0, GPIO pin number(0 to 5) in HP instance
690 * as these are used for other functionality.
691 *******************************************************************************/
sl_si91x_gpio_configure_group_interrupt(sl_si91x_gpio_group_interrupt_config_t * configuration)692 void sl_si91x_gpio_configure_group_interrupt(sl_si91x_gpio_group_interrupt_config_t *configuration)
693 {
694 uint8_t int_pin_count;
695 // Group interrupt pin configuration in HP GPIO instance
696 for (int_pin_count = 0; int_pin_count < configuration->grp_interrupt_cnt; int_pin_count++) {
697 sl_gpio_set_pin_mode(configuration->grp_interrupt_port[int_pin_count],
698 configuration->grp_interrupt_pin[int_pin_count],
699 SL_GPIO_MODE_0,
700 SET);
701 sl_si91x_gpio_set_pin_direction(configuration->grp_interrupt_port[int_pin_count],
702 configuration->grp_interrupt_pin[int_pin_count],
703 GPIO_INPUT);
704 sl_si91x_gpio_enable_pad_receiver(configuration->grp_interrupt_pin[int_pin_count]);
705 sl_si91x_gpio_set_group_interrupt_polarity(configuration->grp_interrupt,
706 configuration->grp_interrupt_port[int_pin_count],
707 configuration->grp_interrupt_pin[int_pin_count],
708 configuration->grp_interrupt_pol[int_pin_count]);
709 sl_si91x_gpio_set_group_interrupt_level_edge(configuration->grp_interrupt_port[int_pin_count],
710 configuration->grp_interrupt,
711 configuration->level_edge);
712 sl_si91x_gpio_select_group_interrupt_and_or(configuration->grp_interrupt_port[int_pin_count],
713 configuration->grp_interrupt,
714 configuration->and_or);
715 sl_si91x_gpio_enable_group_interrupt(configuration->grp_interrupt,
716 configuration->grp_interrupt_port[int_pin_count],
717 configuration->grp_interrupt_pin[int_pin_count]);
718 sl_si91x_gpio_unmask_group_interrupt(configuration->grp_interrupt_port[int_pin_count],
719 configuration->grp_interrupt);
720 }
721 // NVIC enable for group interrupt 1
722 if (configuration->grp_interrupt == GROUP_INT_1) {
723 NVIC_EnableIRQ(GROUP_0_INTERRUPT_NAME);
724 NVIC_SetPriority(GROUP_0_INTERRUPT_NAME, PRIORITY_50);
725 }
726 // NVIC enable for group interrupt 2
727 else if (configuration->grp_interrupt == GROUP_INT_2) {
728 NVIC_EnableIRQ(GROUP_1_INTERRUPT_NAME);
729 NVIC_SetPriority(GROUP_1_INTERRUPT_NAME, PRIORITY_51);
730 }
731 }
732
733 /*******************************************************************************
734 * This API is used to configure the pin interrupt in GPIO ULP instance.
735 * There are total 12 pin interrupts in this instance.
736 * To configure the interrupt, first ULP GPIO initialization must be done.
737 * The actions to be performed in ULP GPIO initialization are:
738 * - Enable the ULP clock of GPIO ULP instance.
739 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
740 * output/input.
741 * - Set pin mode and direction of the GPIO pin.
742 * Configuring the pin interrupt requires pin number, interrupt number,
743 * and interrupt flag to be generated.
744 * Enable the IRQ handler.
745 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
746 *******************************************************************************/
sl_si91x_gpio_configure_ulp_pin_interrupt(uint8_t int_no,sl_si91x_gpio_interrupt_config_flag_t flags,sl_si91x_gpio_pin_ulp_t pin)747 void sl_si91x_gpio_configure_ulp_pin_interrupt(uint8_t int_no,
748 sl_si91x_gpio_interrupt_config_flag_t flags,
749 sl_si91x_gpio_pin_ulp_t pin)
750 {
751 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PIN(pin));
752 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_FLAG(flags));
753 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_INTR(int_no));
754 // Pin interrupt configuration in ULP GPIO instance
755 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.PORT_NUMBER = ULP_PORT_NUM;
756 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.PIN_NUMBER = pin;
757 // Enable or disable GPIO interrupt falling edge in GPIO ULP instance
758 if ((flags & SL_GPIO_INTERRUPT_FALLING_EDGE) == SL_GPIO_INTERRUPT_FALLING_EDGE) {
759 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.FALL_EDGE_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
760 } else {
761 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.FALL_EDGE_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
762 }
763 // Enable or disable GPIO interrupt rising edge in GPIO ULP instance
764 if ((flags & SL_GPIO_INTERRUPT_RISING_EDGE) == SL_GPIO_INTERRUPT_RISING_EDGE) {
765 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.RISE_EDGE_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
766 } else {
767 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.RISE_EDGE_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
768 }
769 // Enable or disable GPIO interrupt level high
770 if ((flags & SL_GPIO_INTERRUPT_HIGH) == SL_GPIO_INTERRUPT_HIGH) {
771 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_HIGH_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
772 } else {
773 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_HIGH_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
774 }
775 // Enable or disable GPIO interrupt level low
776 if ((flags & SL_GPIO_INTERRUPT_LOW) == SL_GPIO_INTERRUPT_LOW) {
777 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_LOW_ENABLE = SL_GPIO_INTERRUPT_ENABLE;
778 } else {
779 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.LEVEL_LOW_ENABLE = SL_GPIO_INTERRUPT_DISABLE;
780 }
781 // Un-mask the interrupt
782 ULP_GPIO->INTR[int_no].GPIO_INTR_CTRL_b.MASK = CLR;
783 }
784
785 /*******************************************************************************
786 * This API is used in GPIO ULP instance to configure group interrupts.
787 * It has configuration pointer of type @ref sl_si91x_gpio_group_interrupt_config_t
788 * structure.
789 * ULP GPIO domain has only one port and calling as Port 4 in program which has maximum of 12 pins.
790 * While configuring group interrupts, one can select random pins which are allocated for
791 * ULP port.
792 * - One should assign group count of how many pins are passed.
793 * For more clarification look into group interrupt configuration structure
794 * @ref sl_si91x_gpio_group_interrupt_config_t.
795 *******************************************************************************/
sl_si91x_gpio_configure_ulp_group_interrupt(sl_si91x_gpio_group_interrupt_config_t * configuration)796 void sl_si91x_gpio_configure_ulp_group_interrupt(sl_si91x_gpio_group_interrupt_config_t *configuration)
797 {
798 uint8_t int_pin_count;
799 // Group interrupt pin configuration in ULP GPIO instance
800 for (int_pin_count = 0; int_pin_count < configuration->grp_interrupt_cnt; int_pin_count++) {
801 sl_gpio_set_pin_mode(SL_GPIO_ULP_PORT, configuration->grp_interrupt_pin[int_pin_count], SL_GPIO_MODE_0, SET);
802 sl_si91x_gpio_set_pin_direction(SL_GPIO_ULP_PORT, configuration->grp_interrupt_pin[int_pin_count], GPIO_INPUT);
803 sl_si91x_gpio_enable_ulp_pad_receiver(configuration->grp_interrupt_pin[int_pin_count]);
804 sl_si91x_gpio_set_group_interrupt_polarity(configuration->grp_interrupt,
805 SL_GPIO_ULP_PORT,
806 configuration->grp_interrupt_pin[int_pin_count],
807 configuration->grp_interrupt_pol[int_pin_count]);
808 sl_si91x_gpio_set_group_interrupt_level_edge(SL_GPIO_ULP_PORT,
809 configuration->grp_interrupt,
810 configuration->level_edge);
811 sl_si91x_gpio_select_group_interrupt_and_or(SL_GPIO_ULP_PORT, configuration->grp_interrupt, configuration->and_or);
812 sl_si91x_gpio_enable_group_interrupt(configuration->grp_interrupt,
813 SL_GPIO_ULP_PORT,
814 configuration->grp_interrupt_pin[int_pin_count]);
815 sl_si91x_gpio_unmask_group_interrupt(SL_GPIO_ULP_PORT, configuration->grp_interrupt);
816 }
817 // NVIC enable for ULP group interrupt
818 NVIC_EnableIRQ(ULP_GROUP_INTERRUPT_NAME);
819 NVIC_SetPriority(ULP_GROUP_INTERRUPT_NAME, PRIORITY_19);
820 }
821
822 /*******************************************************************************
823 * This API is used for GPIO HP instance.
824 * It is used to clear group interrupt.
825 *******************************************************************************/
sl_si91x_gpio_clear_group_interrupt(sl_si91x_group_interrupt_t group_interrupt)826 void sl_si91x_gpio_clear_group_interrupt(sl_si91x_group_interrupt_t group_interrupt)
827 {
828 // Clear group interrupt in HP GPIO instance
829 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_STS_b.INTERRUPT_STATUS = SET;
830 }
831
832 /*******************************************************************************
833 * This API is used for GPIO HP, ULP instance.
834 * It is used to get status of group interrupt generated.
835 ******************************************************************************/
sl_si91x_gpio_get_group_interrupt_status(uint8_t port,sl_si91x_group_interrupt_t group_interrupt)836 uint32_t sl_si91x_gpio_get_group_interrupt_status(uint8_t port, sl_si91x_group_interrupt_t group_interrupt)
837 {
838 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
839 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
840 if (port == SL_GPIO_ULP_PORT) {
841 // Get group interrupt status in ULP GPIO instance
842 return ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_STS;
843 } else {
844 // Get group interrupt status in HP GPIO instance
845 return GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_STS;
846 }
847 }
848
849 /*******************************************************************************
850 * This API is used for GPIO HP, ULP instance.
851 * It is used to select group interrupt wakeup.
852 ******************************************************************************/
sl_si91x_gpio_select_group_interrupt_wakeup(uint8_t port,sl_si91x_group_interrupt_t group_interrupt,uint8_t flags)853 void sl_si91x_gpio_select_group_interrupt_wakeup(uint8_t port,
854 sl_si91x_group_interrupt_t group_interrupt,
855 uint8_t flags)
856 {
857 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PORT(port));
858 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(group_interrupt));
859 // Enables or Disables wakeup group interrupt in ULP GPIO instance
860 if (port == SL_GPIO_ULP_PORT) {
861 if ((flags & SL_GPIO_GROUP_INTERRUPT_WAKEUP) == (SL_GPIO_GROUP_INTERRUPT_WAKEUP)) {
862 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_WAKEUP = SET;
863 } else {
864 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_WAKEUP = CLR;
865 }
866 } else {
867 // Enables or Disables wakeup group interrupt in HP GPIO instance
868 if ((flags & SL_GPIO_GROUP_INTERRUPT_WAKEUP) == (SL_GPIO_GROUP_INTERRUPT_WAKEUP)) {
869 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_WAKEUP = SET;
870 } else {
871 GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_CTRL_REG_b.ENABLE_WAKEUP = CLR;
872 }
873 }
874 }
875
876 /*******************************************************************************
877 * To enable ULP PAD receiver in GPIO ULP instance, ULP GPIO initialization needs to be done first.
878 * - The actions to be performed in ULP GPIO initialization are:
879 * - Enable the ULP clock of GPIO ULP instance.
880 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
881 * output/input.
882 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
883 *******************************************************************************/
sl_si91x_gpio_enable_ulp_pad_receiver(uint8_t gpio_num)884 void sl_si91x_gpio_enable_ulp_pad_receiver(uint8_t gpio_num)
885 {
886 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PIN(gpio_num));
887 // Enable receiver bit in PAD configuration register in ULP instance
888 ULP_PAD_CONFIG_REG |= BIT(gpio_num);
889 }
890
891 /*******************************************************************************
892 * This API is used to disable the ULP PAD receiver.
893 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
894 *******************************************************************************/
sl_si91x_gpio_disable_ulp_pad_receiver(uint32_t gpio_num)895 void sl_si91x_gpio_disable_ulp_pad_receiver(uint32_t gpio_num)
896 {
897 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PIN(gpio_num));
898 // Disable receiver bit in PAD configuration register in ULP instance
899 ULP_PAD_CONFIG_REG &= ~BIT(gpio_num);
900 }
901
902 /*******************************************************************************
903 * To select the ULP PAD driver disable state in GPIO ULP instance, ULP GPIO initialization
904 * needs to be done first.
905 * - The actions to be performed in ULP GPIO initialization are:
906 * - Enable the ULP clock of GPIO ULP instance.
907 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
908 * output/input.
909 * - Set pin mode and direction of the GPIO pin.
910 * - Select the PAD driver disable state of type @ref sl_si91x_gpio_driver_disable_state_t.
911 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
912 ******************************************************************************/
sl_si91x_gpio_select_ulp_pad_driver_disable_state(uint8_t gpio_num,sl_si91x_gpio_driver_disable_state_t disable_state)913 void sl_si91x_gpio_select_ulp_pad_driver_disable_state(uint8_t gpio_num,
914 sl_si91x_gpio_driver_disable_state_t disable_state)
915 {
916 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PIN(gpio_num));
917 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_DISABLE_STATE(disable_state));
918 // Select driver disable state in ULP PAD configuration registers
919 if (gpio_num <= GPIO_PAD_3) {
920 ULP_PAD_CONFIG0_REG->ULP_GPIO_PAD_CONFIG_REG_0.PADCONFIG_P1_P2_1 = disable_state;
921 } else if ((gpio_num >= GPIO_PAD_4) && (gpio_num <= GPIO_PAD_7)) {
922 ULP_PAD_CONFIG0_REG->ULP_GPIO_PAD_CONFIG_REG_0.PADCONFIG_P1_P2_2 = disable_state;
923 } else {
924 ULP_PAD_CONFIG1_REG->ULP_GPIO_PAD_CONFIG_REG_1.PADCONFIG_P1_P2_1 = disable_state;
925 }
926 }
927
928 /*******************************************************************************
929 * To select the ULP PAD driver strength in GPIO ULP instance, ULP GPIO initialization
930 * needs to be done first.
931 * - The actions to be performed in ULP GPIO initialization are:
932 * - Enable the ULP clock of GPIO ULP instance.
933 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
934 * output/input.
935 * - Set pin mode and direction of the GPIO pin.
936 * - Select the PAD driver strength of type @ref sl_si91x_gpio_driver_strength_select_t.
937 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
938 ******************************************************************************/
sl_si91x_gpio_select_ulp_pad_driver_strength(uint8_t gpio_num,sl_si91x_gpio_driver_strength_select_t strength)939 void sl_si91x_gpio_select_ulp_pad_driver_strength(uint8_t gpio_num, sl_si91x_gpio_driver_strength_select_t strength)
940 {
941 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PIN(gpio_num));
942 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_STRENGTH(strength));
943 // Select drive strength in ULP PAD configuration registers
944 if (gpio_num <= GPIO_PAD_3) {
945 ULP_PAD_CONFIG0_REG->ULP_GPIO_PAD_CONFIG_REG_0.PADCONFIG_E1_E2_1 = strength;
946 } else if ((gpio_num >= GPIO_PAD_4) && (gpio_num <= GPIO_PAD_7)) {
947 ULP_PAD_CONFIG0_REG->ULP_GPIO_PAD_CONFIG_REG_0.PADCONFIG_E1_E2_2 = strength;
948 } else {
949 ULP_PAD_CONFIG1_REG->ULP_GPIO_PAD_CONFIG_REG_1.PADCONFIG_E1_E2_1 = strength;
950 }
951 }
952
953 /*******************************************************************************
954 * To select the ULP PAD slew rate in GPIO ULP instance, ULP GPIO initialization
955 * needs to be done first.
956 * - The actions to be performed in ULP GPIO initialization are:
957 * - Enable the ULP clock of GPIO ULP instance.
958 * - Enable ULP PAD receiver for GPIO pin number, whether GPIO pin is selected as
959 * output/input.
960 * - Set pin mode and direction of the GPIO pin.
961 * - Select the PAD slew rate of type @ref sl_si91x_gpio_slew_rate_t.
962 * @note: Select ULP GPIO pins for ULP instances(ULP_GPIO_0 to ULP_GPIO_11).
963 ******************************************************************************/
sl_si91x_gpio_select_ulp_pad_slew_rate(uint8_t gpio_num,sl_si91x_gpio_slew_rate_t slew_rate)964 void sl_si91x_gpio_select_ulp_pad_slew_rate(uint8_t gpio_num, sl_si91x_gpio_slew_rate_t slew_rate)
965 {
966 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_ULP_PIN(gpio_num));
967 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(slew_rate));
968 // Select slew rate in ULP PAD configuration registers
969 if (gpio_num <= GPIO_PAD_3) {
970 ULP_PAD_CONFIG0_REG->ULP_GPIO_PAD_CONFIG_REG_0.PADCONFIG_SR_1 = slew_rate;
971 } else if ((gpio_num >= GPIO_PAD_4) && (gpio_num <= GPIO_PAD_7)) {
972 ULP_PAD_CONFIG0_REG->ULP_GPIO_PAD_CONFIG_REG_0.PADCONFIG_SR_2 = slew_rate;
973 } else {
974 ULP_PAD_CONFIG1_REG->ULP_GPIO_PAD_CONFIG_REG_1.PADCONFIG_SR_1 = slew_rate;
975 }
976 }
977
978 /*******************************************************************************
979 * This API is used to select the UULP mode in NPSS GPIO control register.
980 * Few actions are required to be performed before setting the mode,
981 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
982 * - Select UULP NPSS receiver for UULP GPIO pin.
983 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
984 ******************************************************************************/
sl_si91x_gpio_set_uulp_npss_pin_mux(uint8_t pin,sl_si91x_uulp_npss_mode_t mode)985 void sl_si91x_gpio_set_uulp_npss_pin_mux(uint8_t pin, sl_si91x_uulp_npss_mode_t mode)
986 {
987 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
988 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_MODE_PARAMETER(mode));
989 // Select pin mode in UULP GPIO instance
990 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_MODE = mode;
991 }
992
993 /*******************************************************************************
994 * This API is used to enable receiver bit in NPSS GPIO control register.
995 * Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API, before
996 * using this API.
997 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
998 ******************************************************************************/
sl_si91x_gpio_select_uulp_npss_receiver(uint8_t pin,sl_si91x_gpio_receiver_t receiver)999 void sl_si91x_gpio_select_uulp_npss_receiver(uint8_t pin, sl_si91x_gpio_receiver_t receiver)
1000 {
1001 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1002 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(receiver));
1003 // Select input buffer in UULP GPIO instance
1004 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_REN = receiver;
1005 }
1006
1007 /*******************************************************************************
1008 * This API is used to select the UULP direction in NPSS GPIO control register.
1009 * Few actions are required to be performed before setting the direction,
1010 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1011 * - Select UULP NPSS receiver for UULP GPIO pin.
1012 * - Select UULP NPSS direction for UULP GPIO pin.
1013 * - Set the mode of the GPIO pin.
1014 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
1015 ******************************************************************************/
sl_si91x_gpio_set_uulp_npss_direction(uint8_t pin,sl_si91x_gpio_direction_t direction)1016 void sl_si91x_gpio_set_uulp_npss_direction(uint8_t pin, sl_si91x_gpio_direction_t direction)
1017 {
1018 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1019 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(direction));
1020 // Set direction(input/output) in UULP GPIO instance
1021 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_OEN = direction;
1022 }
1023
1024 /*******************************************************************************
1025 * This API is used to get the UULP direction in NPSS GPIO control register.
1026 * Few actions are required to be performed before setting the direction,
1027 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1028 * - Select UULP NPSS receiver for UULP GPIO pin.
1029 * - Set the mode of the GPIO pin.
1030 * - Set the direction of the GPIO pin.
1031 * - Get the direction of the GPIO pin.
1032 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
1033 *******************************************************************************/
sl_si91x_gpio_get_uulp_npss_direction(uint8_t pin)1034 uint8_t sl_si91x_gpio_get_uulp_npss_direction(uint8_t pin)
1035 {
1036 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1037 // Get direction(input/output) in UULP GPIO instance
1038 return UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_OEN;
1039 }
1040
1041 /*******************************************************************************
1042 * This API is used to select the UULP pin value in NPSS GPIO control register.
1043 * Few actions are required to be performed before setting the direction,
1044 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1045 * - Select UULP NPSS receiver for UULP GPIO pin.
1046 * - Set the mode of the GPIO pin.
1047 * - Set the direction of the GPIO pin.
1048 * - Select the GPIO pin value.
1049 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
1050 ******************************************************************************/
sl_si91x_gpio_set_uulp_npss_pin_value(uint8_t pin,sl_si91x_gpio_pin_value_t pin_value)1051 void sl_si91x_gpio_set_uulp_npss_pin_value(uint8_t pin, sl_si91x_gpio_pin_value_t pin_value)
1052 {
1053 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1054 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(pin_value));
1055 // Set or Clear pin in UULP GPIO instance by controlling pin value
1056 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_OUT = pin_value;
1057 }
1058
1059 /*******************************************************************************
1060 * This API is used to toggle the UULP pin.
1061 * Few actions are required to be performed before setting the direction,
1062 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1063 * - Select UULP NPSS receiver for UULP GPIO pin.
1064 * - Set the mode of the GPIO pin.
1065 * - Set the direction of the GPIO pin.
1066 * - Toggle the UULP GPIO pin.
1067 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
1068 ******************************************************************************/
sl_si91x_gpio_toggle_uulp_npss_pin(uint8_t pin)1069 void sl_si91x_gpio_toggle_uulp_npss_pin(uint8_t pin)
1070 {
1071 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1072 // Set or Clear pin in UULP GPIO instance by controlling pin value
1073 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_OUT ^= SET;
1074 }
1075
1076 /*******************************************************************************
1077 * This API is used to get the UULP pin value in NPSS GPIO control register.
1078 * Few actions are required to be performed before setting the direction,
1079 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1080 * - Select UULP NPSS receiver for UULP GPIO pin.
1081 * - Set the mode of the GPIO pin.
1082 * - Set the direction of the GPIO pin.
1083 * - Select the GPIO pin value.
1084 * - Get the GPIO pin value.
1085 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
1086 ******************************************************************************/
sl_si91x_gpio_get_uulp_npss_pin(uint8_t pin)1087 uint8_t sl_si91x_gpio_get_uulp_npss_pin(uint8_t pin)
1088 {
1089 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1090 // Read pin status in UULP GPIO instance
1091 return (UULP_GPIO_STATUS >> pin) & MASK_INTR;
1092 }
1093
1094 /*******************************************************************************
1095 * This API is used to select polarity of the UULP GPIO to be considered
1096 when used as a wakeup source from any of the Sleep States.
1097 ******************************************************************************/
sl_si91x_gpio_select_uulp_npss_polarity(uint8_t pin,sl_si91x_gpio_polarity_t polarity)1098 void sl_si91x_gpio_select_uulp_npss_polarity(uint8_t pin, sl_si91x_gpio_polarity_t polarity)
1099 {
1100 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_PIN(pin));
1101 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_PARAMETER(polarity));
1102 UULP_GPIO->NPSS_GPIO_CNTRL[pin].NPSS_GPIO_CTRLS_b.NPSS_GPIO_POLARITY = polarity;
1103 }
1104
1105 /*******************************************************************************
1106 * This API is used to set the UULP NPSS GPIO to wakeup interrupt
1107 *******************************************************************************/
sl_si91x_gpio_set_uulp_npss_wakeup_interrupt(uint8_t npssgpio_interrupt)1108 void sl_si91x_gpio_set_uulp_npss_wakeup_interrupt(uint8_t npssgpio_interrupt)
1109 {
1110 UULP_GPIO_FSM->GPIO_WAKEUP_REGISTER |= (BIT(npssgpio_interrupt));
1111 }
1112
1113 /*******************************************************************************
1114 * This API is used to clear the UULP NPSS GPIO to wakeup interrupt
1115 *******************************************************************************/
sl_si91x_gpio_clear_uulp_npss_wakeup_interrupt(uint8_t npssgpio_interrupt)1116 void sl_si91x_gpio_clear_uulp_npss_wakeup_interrupt(uint8_t npssgpio_interrupt)
1117 {
1118 UULP_GPIO_FSM->GPIO_WAKEUP_REGISTER &= ~(BIT(npssgpio_interrupt));
1119 }
1120
1121 /*******************************************************************************
1122 * This API is used to mask the UULP NPSS GPIO interrupt.
1123 * Few actions are required to be performed before interrupt mask is performed,
1124 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1125 * - Select the .
1126 * @note: All the UULP interrupts are masked by default.
1127 *******************************************************************************/
sl_si91x_gpio_mask_uulp_npss_interrupt(uint8_t npssgpio_interrupt)1128 void sl_si91x_gpio_mask_uulp_npss_interrupt(uint8_t npssgpio_interrupt)
1129 {
1130 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_INTR(npssgpio_interrupt));
1131 GPIO_NPSS_INTERRUPT_MASK_SET_REG = (npssgpio_interrupt << 1);
1132 }
1133
1134 /*******************************************************************************
1135 * This API is used to un-mask the UULP NPSS GPIO interrupt.
1136 * Few actions are required to be performed before interrupt un-mask is performed,
1137 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1138 * - Set UULP PAD configuration register.
1139 * - Select UULP NPSS receiver for UULP GPIO pin.
1140 * - Set the mode of the GPIO pin.
1141 * - Set the direction of the GPIO pin.
1142 * - Un-mask interrupt by setting corresponding bit in register.
1143 * @note: All the UULP interrupts are masked by default.
1144 *******************************************************************************/
sl_si91x_gpio_unmask_uulp_npss_interrupt(uint8_t npssgpio_interrupt)1145 void sl_si91x_gpio_unmask_uulp_npss_interrupt(uint8_t npssgpio_interrupt)
1146 {
1147 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_UULP_INTR(npssgpio_interrupt));
1148 GPIO_NPSS_INTERRUPT_MASK_CLR_REG = (npssgpio_interrupt << 1);
1149 }
1150
1151 /*******************************************************************************
1152 * This API is used to clear the UULP interrupt.
1153 *******************************************************************************/
sl_si91x_gpio_clear_uulp_interrupt(uint8_t npssgpio_interrupt)1154 void sl_si91x_gpio_clear_uulp_interrupt(uint8_t npssgpio_interrupt)
1155 {
1156 GPIO_NPSS_INTERRUPT_CLEAR_REG = (npssgpio_interrupt << 1);
1157 }
1158
1159 /*******************************************************************************
1160 * This API is used to get the UULP interrupt status.
1161 ******************************************************************************/
sl_si91x_gpio_get_uulp_interrupt_status(void)1162 uint8_t sl_si91x_gpio_get_uulp_interrupt_status(void)
1163 {
1164 return (GPIO_NPSS_INTERRUPT_STATUS_REG >> 1) & UULP_PIN_MASK;
1165 }
1166
1167 /*******************************************************************************
1168 * This API is used to get the ULP interrupt status.
1169 ******************************************************************************/
sl_si91x_gpio_get_ulp_interrupt_status(uint32_t flags)1170 uint32_t sl_si91x_gpio_get_ulp_interrupt_status(uint32_t flags)
1171 {
1172 return ULP_GPIO->INTR[flags].GPIO_INTR_STATUS_b.INTERRUPT_STATUS;
1173 }
1174
1175 /*******************************************************************************
1176 * This API is used to configure the pin interrupt in GPIO UULP instance.
1177 * There are total 5 pin interrupts in this instance.
1178 * To configure the interrupt, first UULP GPIO initialization must be done.
1179 * The actions to be performed in UULP GPIO initialization are:
1180 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1181 * - Set UULP PAD configuration register.
1182 * - Select UULP NPSS receiver for UULP GPIO pin.
1183 * - Set the mode of the GPIO pin.
1184 * - Set the direction of the GPIO pin.
1185 * - Configure the UULP pin interrupt.
1186 * Enable the IRQ handler.
1187 * @note: The NPSS GPIO interrupt pin number is transformed into a bit mask by
1188 * shifting a single bit to the left by the specified pin number.
1189 *******************************************************************************/
sl_si91x_gpio_configure_uulp_interrupt(sl_si91x_gpio_interrupt_config_flag_t flags,uint8_t npssgpio_interrupt)1190 void sl_si91x_gpio_configure_uulp_interrupt(sl_si91x_gpio_interrupt_config_flag_t flags, uint8_t npssgpio_interrupt)
1191 {
1192 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_FLAG(flags));
1193 SL_GPIO_ASSERT(SL_GPIO_VALIDATE_INTR(npssgpio_interrupt));
1194 npssgpio_interrupt = BIT(npssgpio_interrupt);
1195 // Unmask NPSS interrupt
1196 sl_si91x_gpio_unmask_uulp_npss_interrupt(npssgpio_interrupt);
1197 // Enable or disable interrupt rising edge in GPIO UULP instance
1198 if ((flags & SL_GPIO_INTERRUPT_RISING_EDGE) == SL_GPIO_INTERRUPT_RISING_EDGE) {
1199 GPIO_NPSS_GPIO_CONFIG_REG |= (npssgpio_interrupt << BIT_0);
1200 } else {
1201 GPIO_NPSS_GPIO_CONFIG_REG &= ~((uint32_t)npssgpio_interrupt << BIT_0);
1202 }
1203 // Enable or disable GPIO interrupt falling edge in GPIO UULP instance
1204 if ((flags & SL_GPIO_INTERRUPT_FALLING_EDGE) == SL_GPIO_INTERRUPT_FALLING_EDGE) {
1205 GPIO_NPSS_GPIO_CONFIG_REG |= (npssgpio_interrupt << BIT_8);
1206 } else {
1207 GPIO_NPSS_GPIO_CONFIG_REG &= ~((uint32_t)npssgpio_interrupt << BIT_8);
1208 }
1209 // Enable or disable interrupt level low in UULP GPIO instance
1210 if ((flags & SL_GPIO_INTERRUPT_LOW) == SL_GPIO_INTERRUPT_LOW) {
1211 GPIO_NPSS_GPIO_CONFIG_REG |= (npssgpio_interrupt << BIT_16);
1212 } else {
1213 GPIO_NPSS_GPIO_CONFIG_REG &= ~((uint32_t)npssgpio_interrupt << BIT_16);
1214 }
1215 // Enable or disable interrupt level high in UULP GPIO instance
1216 if ((flags & SL_GPIO_INTERRUPT_HIGH) == SL_GPIO_INTERRUPT_HIGH) {
1217 GPIO_NPSS_GPIO_CONFIG_REG |= (npssgpio_interrupt << BIT_24);
1218 } else {
1219 GPIO_NPSS_GPIO_CONFIG_REG &= ~((uint32_t)npssgpio_interrupt << BIT_24);
1220 }
1221 NVIC_EnableIRQ(UULP_PININT_NVIC_NAME);
1222 }
1223
1224 /*******************************************************************************
1225 * This API is used to clear one (or) more pending ULP GPIO interrupts.
1226 *******************************************************************************/
sl_si91x_gpio_clear_ulp_interrupt(uint32_t flags)1227 void sl_si91x_gpio_clear_ulp_interrupt(uint32_t flags)
1228 {
1229 ULP_GPIO->INTR[flags].GPIO_INTR_STATUS_b.INTERRUPT_STATUS = SET;
1230 }
1231
1232 /*******************************************************************************
1233 * This API is used to clear the ULP group interrupts.
1234 *******************************************************************************/
sl_si91x_gpio_clear_ulp_group_interrupt(sl_si91x_group_interrupt_t group_interrupt)1235 void sl_si91x_gpio_clear_ulp_group_interrupt(sl_si91x_group_interrupt_t group_interrupt)
1236 {
1237 ULP_GPIO->GPIO_GRP_INTR[group_interrupt].GPIO_GRP_INTR_STS_b.INTERRUPT_STATUS = SET;
1238 }
1239
1240 /*******************************************************************************
1241 * This API is used to verify assumptions and print message if the assumption is false.
1242 ******************************************************************************/
sl_assert_failed(uint8_t * file,uint32_t line)1243 void sl_assert_failed(uint8_t *file, uint32_t line)
1244 {
1245 #ifdef DEBUG_UART
1246 DEBUGOUT("Assert failed: file %s on line %lu \r\n", file, line);
1247 #else
1248 (void)file;
1249 (void)line;
1250 #endif
1251 }
1252
1253 /*******************************************************************************
1254 * This API is used to select the UULP PAD configuration register.
1255 * It has pad_config pointer of type @ref uulp_pad_config_t.
1256 * It selects the mode, direction, polarity, enables receiver etc in the register.
1257 * To set the UULP PAD configuration,
1258 * - Enable the ULP clock using @ref sl_si91x_gpio_enable_clock() API.
1259 * - Select UULP NPSS input buffer for UULP GPIO pin.
1260 * @note: Select UULP GPIO pins for UULP instances(UULP_GPIO_0 to UULP_GPIO_4).
1261 *******************************************************************************/
sl_si91x_gpio_set_uulp_pad_configuration(uulp_pad_config_t * pad_config)1262 void sl_si91x_gpio_set_uulp_pad_configuration(uulp_pad_config_t *pad_config)
1263 {
1264 UULP_PAD_CONFIG_REG(pad_config->gpio_padnum)->UULP_GPIO_PAD_CONFIG_REG_b.GPIO_MODE =
1265 (sl_si91x_uulp_npss_mode_t)pad_config->mode;
1266 UULP_PAD_CONFIG_REG(pad_config->gpio_padnum)->UULP_GPIO_PAD_CONFIG_REG_b.GPIO_REN =
1267 (sl_si91x_gpio_receiver_t)pad_config->receiver;
1268 UULP_PAD_CONFIG_REG(pad_config->gpio_padnum)->UULP_GPIO_PAD_CONFIG_REG_b.GPIO_OEN =
1269 (sl_si91x_gpio_direction_t)pad_config->direction;
1270 UULP_PAD_CONFIG_REG(pad_config->gpio_padnum)->UULP_GPIO_PAD_CONFIG_REG_b.GPIO_OUTPUT =
1271 (sl_si91x_gpio_pin_value_t)pad_config->output;
1272 UULP_PAD_CONFIG_REG(pad_config->gpio_padnum)->UULP_GPIO_PAD_CONFIG_REG_b.GPIO_PAD_SELECT =
1273 (sl_si91x_gpio_uulp_pad_t)pad_config->pad_select;
1274 UULP_PAD_CONFIG_REG(pad_config->gpio_padnum)->UULP_GPIO_PAD_CONFIG_REG_b.GPIO_POLARITY =
1275 (sl_si91x_gpio_polarity_t)pad_config->polarity;
1276 }
1277
1278 /*******************************************************************************
1279 * To get the release, sqa and dev version of gpio peripheral
1280 * It returns the structure for gpio version.
1281 * Structure includes three members:
1282 * - Release version
1283 * - Major version (SQA version)
1284 * - Minor version (Dev version)
1285 ******************************************************************************/
sl_si91x_gpio_get_version(void)1286 sl_si91x_gpio_version_t sl_si91x_gpio_get_version(void)
1287 {
1288 sl_si91x_gpio_version_t version;
1289 version.release = GPIO_RELEASE_VERSION;
1290 version.major = GPIO_MAJOR_VERSION;
1291 version.minor = GPIO_MINOR_VERSION;
1292 return version;
1293 }
1294