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