xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_gpiote.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1*150812a8SEvalZero /*
2*150812a8SEvalZero  * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3*150812a8SEvalZero  * All rights reserved.
4*150812a8SEvalZero  *
5*150812a8SEvalZero  * Redistribution and use in source and binary forms, with or without
6*150812a8SEvalZero  * modification, are permitted provided that the following conditions are met:
7*150812a8SEvalZero  *
8*150812a8SEvalZero  * 1. Redistributions of source code must retain the above copyright notice, this
9*150812a8SEvalZero  *    list of conditions and the following disclaimer.
10*150812a8SEvalZero  *
11*150812a8SEvalZero  * 2. Redistributions in binary form must reproduce the above copyright
12*150812a8SEvalZero  *    notice, this list of conditions and the following disclaimer in the
13*150812a8SEvalZero  *    documentation and/or other materials provided with the distribution.
14*150812a8SEvalZero  *
15*150812a8SEvalZero  * 3. Neither the name of the copyright holder nor the names of its
16*150812a8SEvalZero  *    contributors may be used to endorse or promote products derived from this
17*150812a8SEvalZero  *    software without specific prior written permission.
18*150812a8SEvalZero  *
19*150812a8SEvalZero  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*150812a8SEvalZero  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*150812a8SEvalZero  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*150812a8SEvalZero  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*150812a8SEvalZero  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*150812a8SEvalZero  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*150812a8SEvalZero  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*150812a8SEvalZero  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*150812a8SEvalZero  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*150812a8SEvalZero  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*150812a8SEvalZero  * POSSIBILITY OF SUCH DAMAGE.
30*150812a8SEvalZero  */
31*150812a8SEvalZero #include <nrfx.h>
32*150812a8SEvalZero 
33*150812a8SEvalZero #if NRFX_CHECK(NRFX_GPIOTE_ENABLED)
34*150812a8SEvalZero 
35*150812a8SEvalZero #include <nrfx_gpiote.h>
36*150812a8SEvalZero #include "nrf_bitmask.h"
37*150812a8SEvalZero #include <string.h>
38*150812a8SEvalZero 
39*150812a8SEvalZero #define NRFX_LOG_MODULE GPIOTE
40*150812a8SEvalZero #include <nrfx_log.h>
41*150812a8SEvalZero 
42*150812a8SEvalZero 
43*150812a8SEvalZero #define FORBIDDEN_HANDLER_ADDRESS ((nrfx_gpiote_evt_handler_t)UINT32_MAX)
44*150812a8SEvalZero #define PIN_NOT_USED              (-1)
45*150812a8SEvalZero #define PIN_USED                  (-2)
46*150812a8SEvalZero #define NO_CHANNELS               (-1)
47*150812a8SEvalZero #define SENSE_FIELD_POS           (6)
48*150812a8SEvalZero #define SENSE_FIELD_MASK          (0xC0)
49*150812a8SEvalZero 
50*150812a8SEvalZero /* Check if every pin can be encoded on provided number of bits. */
51*150812a8SEvalZero NRFX_STATIC_ASSERT(NUMBER_OF_PINS <= (1 << SENSE_FIELD_POS));
52*150812a8SEvalZero 
53*150812a8SEvalZero /**
54*150812a8SEvalZero  * @brief Macro for converting task-event index to an address of an event register.
55*150812a8SEvalZero  *
56*150812a8SEvalZero  * Macro utilizes the fact that registers are grouped together in ascending order.
57*150812a8SEvalZero  */
58*150812a8SEvalZero #define TE_IDX_TO_EVENT_ADDR(idx)    (nrf_gpiote_events_t)((uint32_t)NRF_GPIOTE_EVENTS_IN_0 + \
59*150812a8SEvalZero                                                            (sizeof(uint32_t) * (idx)))
60*150812a8SEvalZero 
61*150812a8SEvalZero /**
62*150812a8SEvalZero  * @brief Macro for converting task-event index of OUT task to an address of a task register.
63*150812a8SEvalZero  *
64*150812a8SEvalZero  * Macro utilizes the fact that registers are grouped together in ascending order.
65*150812a8SEvalZero  */
66*150812a8SEvalZero #define TE_OUT_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_OUT_0 + \
67*150812a8SEvalZero                                                           (sizeof(uint32_t) * (idx)))
68*150812a8SEvalZero 
69*150812a8SEvalZero #if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
70*150812a8SEvalZero /**
71*150812a8SEvalZero  * @brief Macro for converting task-event index of SET task to an address of a task register.
72*150812a8SEvalZero  *
73*150812a8SEvalZero  * Macro utilizes the fact that registers are grouped together in ascending order.
74*150812a8SEvalZero  */
75*150812a8SEvalZero #define TE_SET_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_SET_0 + \
76*150812a8SEvalZero                                                           (sizeof(uint32_t) * (idx)))
77*150812a8SEvalZero 
78*150812a8SEvalZero #endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
79*150812a8SEvalZero 
80*150812a8SEvalZero #if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
81*150812a8SEvalZero /**
82*150812a8SEvalZero  * @brief Macro for converting task-event index of CLR task to an address of a task register.
83*150812a8SEvalZero  *
84*150812a8SEvalZero  * Macro utilizes the fact that registers are grouped together in ascending order.
85*150812a8SEvalZero  */
86*150812a8SEvalZero #define TE_CLR_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_CLR_0 + \
87*150812a8SEvalZero                                                           (sizeof(uint32_t) * (idx)))
88*150812a8SEvalZero 
89*150812a8SEvalZero #endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
90*150812a8SEvalZero 
91*150812a8SEvalZero /*lint -save -e571*/ /* Suppress "Warning 571: Suspicious cast" */
92*150812a8SEvalZero typedef struct
93*150812a8SEvalZero {
94*150812a8SEvalZero     nrfx_gpiote_evt_handler_t handlers[GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];
95*150812a8SEvalZero     int8_t                    pin_assignments[NUMBER_OF_PINS];
96*150812a8SEvalZero     int8_t                    port_handlers_pins[NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];
97*150812a8SEvalZero     uint8_t                   configured_pins[((NUMBER_OF_PINS)+7) / 8];
98*150812a8SEvalZero     nrfx_drv_state_t          state;
99*150812a8SEvalZero } gpiote_control_block_t;
100*150812a8SEvalZero 
101*150812a8SEvalZero static gpiote_control_block_t m_cb;
102*150812a8SEvalZero 
pin_in_use(uint32_t pin)103*150812a8SEvalZero __STATIC_INLINE bool pin_in_use(uint32_t pin)
104*150812a8SEvalZero {
105*150812a8SEvalZero     return (m_cb.pin_assignments[pin] != PIN_NOT_USED);
106*150812a8SEvalZero }
107*150812a8SEvalZero 
108*150812a8SEvalZero 
pin_in_use_as_non_task_out(uint32_t pin)109*150812a8SEvalZero __STATIC_INLINE bool pin_in_use_as_non_task_out(uint32_t pin)
110*150812a8SEvalZero {
111*150812a8SEvalZero     return (m_cb.pin_assignments[pin] == PIN_USED);
112*150812a8SEvalZero }
113*150812a8SEvalZero 
114*150812a8SEvalZero 
pin_in_use_by_te(uint32_t pin)115*150812a8SEvalZero __STATIC_INLINE bool pin_in_use_by_te(uint32_t pin)
116*150812a8SEvalZero {
117*150812a8SEvalZero     return (m_cb.pin_assignments[pin] >= 0 && m_cb.pin_assignments[pin] < GPIOTE_CH_NUM) ?
118*150812a8SEvalZero             true : false;
119*150812a8SEvalZero }
120*150812a8SEvalZero 
121*150812a8SEvalZero 
pin_in_use_by_port(uint32_t pin)122*150812a8SEvalZero __STATIC_INLINE bool pin_in_use_by_port(uint32_t pin)
123*150812a8SEvalZero {
124*150812a8SEvalZero     return (m_cb.pin_assignments[pin] >= GPIOTE_CH_NUM);
125*150812a8SEvalZero }
126*150812a8SEvalZero 
127*150812a8SEvalZero 
pin_in_use_by_gpiote(uint32_t pin)128*150812a8SEvalZero __STATIC_INLINE bool pin_in_use_by_gpiote(uint32_t pin)
129*150812a8SEvalZero {
130*150812a8SEvalZero     return (m_cb.pin_assignments[pin] >= 0);
131*150812a8SEvalZero }
132*150812a8SEvalZero 
133*150812a8SEvalZero 
pin_in_use_by_te_set(uint32_t pin,uint32_t channel_id,nrfx_gpiote_evt_handler_t handler,bool is_channel)134*150812a8SEvalZero __STATIC_INLINE void pin_in_use_by_te_set(uint32_t                  pin,
135*150812a8SEvalZero                                           uint32_t                  channel_id,
136*150812a8SEvalZero                                           nrfx_gpiote_evt_handler_t handler,
137*150812a8SEvalZero                                           bool                      is_channel)
138*150812a8SEvalZero {
139*150812a8SEvalZero     m_cb.pin_assignments[pin] = channel_id;
140*150812a8SEvalZero     m_cb.handlers[channel_id] = handler;
141*150812a8SEvalZero     if (!is_channel)
142*150812a8SEvalZero     {
143*150812a8SEvalZero         m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)pin;
144*150812a8SEvalZero     }
145*150812a8SEvalZero }
146*150812a8SEvalZero 
147*150812a8SEvalZero 
pin_in_use_set(uint32_t pin)148*150812a8SEvalZero __STATIC_INLINE void pin_in_use_set(uint32_t pin)
149*150812a8SEvalZero {
150*150812a8SEvalZero     m_cb.pin_assignments[pin] = PIN_USED;
151*150812a8SEvalZero }
152*150812a8SEvalZero 
153*150812a8SEvalZero 
pin_in_use_clear(uint32_t pin)154*150812a8SEvalZero __STATIC_INLINE void pin_in_use_clear(uint32_t pin)
155*150812a8SEvalZero {
156*150812a8SEvalZero     m_cb.pin_assignments[pin] = PIN_NOT_USED;
157*150812a8SEvalZero }
158*150812a8SEvalZero 
159*150812a8SEvalZero 
pin_configured_set(uint32_t pin)160*150812a8SEvalZero __STATIC_INLINE void pin_configured_set(uint32_t pin)
161*150812a8SEvalZero {
162*150812a8SEvalZero     nrf_bitmask_bit_set(pin, m_cb.configured_pins);
163*150812a8SEvalZero }
164*150812a8SEvalZero 
pin_configured_clear(uint32_t pin)165*150812a8SEvalZero __STATIC_INLINE void pin_configured_clear(uint32_t pin)
166*150812a8SEvalZero {
167*150812a8SEvalZero     nrf_bitmask_bit_clear(pin, m_cb.configured_pins);
168*150812a8SEvalZero }
169*150812a8SEvalZero 
pin_configured_check(uint32_t pin)170*150812a8SEvalZero __STATIC_INLINE bool pin_configured_check(uint32_t pin)
171*150812a8SEvalZero {
172*150812a8SEvalZero     return 0 != nrf_bitmask_bit_is_set(pin, m_cb.configured_pins);
173*150812a8SEvalZero }
174*150812a8SEvalZero 
channel_port_get(uint32_t pin)175*150812a8SEvalZero __STATIC_INLINE int8_t channel_port_get(uint32_t pin)
176*150812a8SEvalZero {
177*150812a8SEvalZero     return m_cb.pin_assignments[pin];
178*150812a8SEvalZero }
179*150812a8SEvalZero 
180*150812a8SEvalZero 
channel_handler_get(uint32_t channel)181*150812a8SEvalZero __STATIC_INLINE nrfx_gpiote_evt_handler_t channel_handler_get(uint32_t channel)
182*150812a8SEvalZero {
183*150812a8SEvalZero     return m_cb.handlers[channel];
184*150812a8SEvalZero }
185*150812a8SEvalZero 
186*150812a8SEvalZero 
channel_port_alloc(uint32_t pin,nrfx_gpiote_evt_handler_t handler,bool channel)187*150812a8SEvalZero static int8_t channel_port_alloc(uint32_t pin, nrfx_gpiote_evt_handler_t handler, bool channel)
188*150812a8SEvalZero {
189*150812a8SEvalZero     int8_t   channel_id = NO_CHANNELS;
190*150812a8SEvalZero     uint32_t i;
191*150812a8SEvalZero 
192*150812a8SEvalZero     uint32_t start_idx = channel ? 0 : GPIOTE_CH_NUM;
193*150812a8SEvalZero     uint32_t end_idx   =
194*150812a8SEvalZero         channel ? GPIOTE_CH_NUM : (GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS);
195*150812a8SEvalZero 
196*150812a8SEvalZero     // critical section
197*150812a8SEvalZero 
198*150812a8SEvalZero     for (i = start_idx; i < end_idx; i++)
199*150812a8SEvalZero     {
200*150812a8SEvalZero         if (m_cb.handlers[i] == FORBIDDEN_HANDLER_ADDRESS)
201*150812a8SEvalZero         {
202*150812a8SEvalZero             pin_in_use_by_te_set(pin, i, handler, channel);
203*150812a8SEvalZero             channel_id = i;
204*150812a8SEvalZero             break;
205*150812a8SEvalZero         }
206*150812a8SEvalZero     }
207*150812a8SEvalZero     // critical section
208*150812a8SEvalZero     return channel_id;
209*150812a8SEvalZero }
210*150812a8SEvalZero 
211*150812a8SEvalZero 
channel_free(uint8_t channel_id)212*150812a8SEvalZero static void channel_free(uint8_t channel_id)
213*150812a8SEvalZero {
214*150812a8SEvalZero     m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS;
215*150812a8SEvalZero     if (channel_id >= GPIOTE_CH_NUM)
216*150812a8SEvalZero     {
217*150812a8SEvalZero         m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)PIN_NOT_USED;
218*150812a8SEvalZero     }
219*150812a8SEvalZero }
220*150812a8SEvalZero 
221*150812a8SEvalZero 
nrfx_gpiote_init(void)222*150812a8SEvalZero nrfx_err_t nrfx_gpiote_init(void)
223*150812a8SEvalZero {
224*150812a8SEvalZero     nrfx_err_t err_code;
225*150812a8SEvalZero 
226*150812a8SEvalZero     if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
227*150812a8SEvalZero     {
228*150812a8SEvalZero         err_code = NRFX_ERROR_INVALID_STATE;
229*150812a8SEvalZero         NRFX_LOG_WARNING("Function: %s, error code: %s.",
230*150812a8SEvalZero                          __func__,
231*150812a8SEvalZero                          NRFX_LOG_ERROR_STRING_GET(err_code));
232*150812a8SEvalZero         return err_code;
233*150812a8SEvalZero     }
234*150812a8SEvalZero 
235*150812a8SEvalZero     uint8_t i;
236*150812a8SEvalZero 
237*150812a8SEvalZero     for (i = 0; i < NUMBER_OF_PINS; i++)
238*150812a8SEvalZero     {
239*150812a8SEvalZero         pin_in_use_clear(i);
240*150812a8SEvalZero     }
241*150812a8SEvalZero 
242*150812a8SEvalZero     for (i = 0; i < (GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++)
243*150812a8SEvalZero     {
244*150812a8SEvalZero         channel_free(i);
245*150812a8SEvalZero     }
246*150812a8SEvalZero 
247*150812a8SEvalZero     memset(m_cb.configured_pins, 0, sizeof(m_cb.configured_pins));
248*150812a8SEvalZero 
249*150812a8SEvalZero     NRFX_IRQ_PRIORITY_SET(GPIOTE_IRQn, NRFX_GPIOTE_CONFIG_IRQ_PRIORITY);
250*150812a8SEvalZero     NRFX_IRQ_ENABLE(GPIOTE_IRQn);
251*150812a8SEvalZero     nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
252*150812a8SEvalZero     nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk);
253*150812a8SEvalZero     m_cb.state = NRFX_DRV_STATE_INITIALIZED;
254*150812a8SEvalZero 
255*150812a8SEvalZero     err_code = NRFX_SUCCESS;
256*150812a8SEvalZero     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
257*150812a8SEvalZero     return err_code;
258*150812a8SEvalZero }
259*150812a8SEvalZero 
260*150812a8SEvalZero 
nrfx_gpiote_is_init(void)261*150812a8SEvalZero bool nrfx_gpiote_is_init(void)
262*150812a8SEvalZero {
263*150812a8SEvalZero     return (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED) ? true : false;
264*150812a8SEvalZero }
265*150812a8SEvalZero 
266*150812a8SEvalZero 
nrfx_gpiote_uninit(void)267*150812a8SEvalZero void nrfx_gpiote_uninit(void)
268*150812a8SEvalZero {
269*150812a8SEvalZero     NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
270*150812a8SEvalZero 
271*150812a8SEvalZero     uint32_t i;
272*150812a8SEvalZero 
273*150812a8SEvalZero     for (i = 0; i < NUMBER_OF_PINS; i++)
274*150812a8SEvalZero     {
275*150812a8SEvalZero         if (pin_in_use_as_non_task_out(i))
276*150812a8SEvalZero         {
277*150812a8SEvalZero             nrfx_gpiote_out_uninit(i);
278*150812a8SEvalZero         }
279*150812a8SEvalZero         else if ( pin_in_use_by_gpiote(i))
280*150812a8SEvalZero         {
281*150812a8SEvalZero             /* Disable gpiote_in is having the same effect on out pin as gpiote_out_uninit on
282*150812a8SEvalZero              * so it can be called on all pins used by GPIOTE.
283*150812a8SEvalZero              */
284*150812a8SEvalZero             nrfx_gpiote_in_uninit(i);
285*150812a8SEvalZero         }
286*150812a8SEvalZero     }
287*150812a8SEvalZero     m_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
288*150812a8SEvalZero     NRFX_LOG_INFO("Uninitialized.");
289*150812a8SEvalZero }
290*150812a8SEvalZero 
291*150812a8SEvalZero 
nrfx_gpiote_out_init(nrfx_gpiote_pin_t pin,nrfx_gpiote_out_config_t const * p_config)292*150812a8SEvalZero nrfx_err_t nrfx_gpiote_out_init(nrfx_gpiote_pin_t                pin,
293*150812a8SEvalZero                                 nrfx_gpiote_out_config_t const * p_config)
294*150812a8SEvalZero {
295*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
296*150812a8SEvalZero     NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
297*150812a8SEvalZero     NRFX_ASSERT(p_config);
298*150812a8SEvalZero 
299*150812a8SEvalZero     nrfx_err_t err_code = NRFX_SUCCESS;
300*150812a8SEvalZero 
301*150812a8SEvalZero     if (pin_in_use(pin))
302*150812a8SEvalZero     {
303*150812a8SEvalZero         err_code = NRFX_ERROR_INVALID_STATE;
304*150812a8SEvalZero     }
305*150812a8SEvalZero     else
306*150812a8SEvalZero     {
307*150812a8SEvalZero         if (p_config->task_pin)
308*150812a8SEvalZero         {
309*150812a8SEvalZero             int8_t channel = channel_port_alloc(pin, NULL, true);
310*150812a8SEvalZero 
311*150812a8SEvalZero             if (channel != NO_CHANNELS)
312*150812a8SEvalZero             {
313*150812a8SEvalZero                 nrf_gpiote_task_configure((uint32_t)channel,
314*150812a8SEvalZero                                           pin,
315*150812a8SEvalZero                                           p_config->action,
316*150812a8SEvalZero                                           p_config->init_state);
317*150812a8SEvalZero             }
318*150812a8SEvalZero             else
319*150812a8SEvalZero             {
320*150812a8SEvalZero                 err_code = NRFX_ERROR_NO_MEM;
321*150812a8SEvalZero             }
322*150812a8SEvalZero         }
323*150812a8SEvalZero         else
324*150812a8SEvalZero         {
325*150812a8SEvalZero             pin_in_use_set(pin);
326*150812a8SEvalZero         }
327*150812a8SEvalZero 
328*150812a8SEvalZero         if (err_code == NRFX_SUCCESS)
329*150812a8SEvalZero         {
330*150812a8SEvalZero             if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH)
331*150812a8SEvalZero             {
332*150812a8SEvalZero                 nrf_gpio_pin_set(pin);
333*150812a8SEvalZero             }
334*150812a8SEvalZero             else
335*150812a8SEvalZero             {
336*150812a8SEvalZero                 nrf_gpio_pin_clear(pin);
337*150812a8SEvalZero             }
338*150812a8SEvalZero 
339*150812a8SEvalZero             nrf_gpio_cfg_output(pin);
340*150812a8SEvalZero             pin_configured_set(pin);
341*150812a8SEvalZero         }
342*150812a8SEvalZero     }
343*150812a8SEvalZero 
344*150812a8SEvalZero     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
345*150812a8SEvalZero     return err_code;
346*150812a8SEvalZero }
347*150812a8SEvalZero 
348*150812a8SEvalZero 
nrfx_gpiote_out_uninit(nrfx_gpiote_pin_t pin)349*150812a8SEvalZero void nrfx_gpiote_out_uninit(nrfx_gpiote_pin_t pin)
350*150812a8SEvalZero {
351*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
352*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
353*150812a8SEvalZero 
354*150812a8SEvalZero     if (pin_in_use_by_te(pin))
355*150812a8SEvalZero     {
356*150812a8SEvalZero         channel_free((uint8_t)channel_port_get(pin));
357*150812a8SEvalZero         nrf_gpiote_te_default((uint32_t)channel_port_get(pin));
358*150812a8SEvalZero     }
359*150812a8SEvalZero     pin_in_use_clear(pin);
360*150812a8SEvalZero 
361*150812a8SEvalZero     if (pin_configured_check(pin))
362*150812a8SEvalZero     {
363*150812a8SEvalZero         nrf_gpio_cfg_default(pin);
364*150812a8SEvalZero         pin_configured_clear(pin);
365*150812a8SEvalZero     }
366*150812a8SEvalZero }
367*150812a8SEvalZero 
368*150812a8SEvalZero 
nrfx_gpiote_out_set(nrfx_gpiote_pin_t pin)369*150812a8SEvalZero void nrfx_gpiote_out_set(nrfx_gpiote_pin_t pin)
370*150812a8SEvalZero {
371*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
372*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
373*150812a8SEvalZero     NRFX_ASSERT(!pin_in_use_by_te(pin));
374*150812a8SEvalZero 
375*150812a8SEvalZero     nrf_gpio_pin_set(pin);
376*150812a8SEvalZero }
377*150812a8SEvalZero 
378*150812a8SEvalZero 
nrfx_gpiote_out_clear(nrfx_gpiote_pin_t pin)379*150812a8SEvalZero void nrfx_gpiote_out_clear(nrfx_gpiote_pin_t pin)
380*150812a8SEvalZero {
381*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
382*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
383*150812a8SEvalZero     NRFX_ASSERT(!pin_in_use_by_te(pin));
384*150812a8SEvalZero 
385*150812a8SEvalZero     nrf_gpio_pin_clear(pin);
386*150812a8SEvalZero }
387*150812a8SEvalZero 
388*150812a8SEvalZero 
nrfx_gpiote_out_toggle(nrfx_gpiote_pin_t pin)389*150812a8SEvalZero void nrfx_gpiote_out_toggle(nrfx_gpiote_pin_t pin)
390*150812a8SEvalZero {
391*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
392*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
393*150812a8SEvalZero     NRFX_ASSERT(!pin_in_use_by_te(pin));
394*150812a8SEvalZero 
395*150812a8SEvalZero     nrf_gpio_pin_toggle(pin);
396*150812a8SEvalZero }
397*150812a8SEvalZero 
398*150812a8SEvalZero 
nrfx_gpiote_out_task_enable(nrfx_gpiote_pin_t pin)399*150812a8SEvalZero void nrfx_gpiote_out_task_enable(nrfx_gpiote_pin_t pin)
400*150812a8SEvalZero {
401*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
402*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
403*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
404*150812a8SEvalZero 
405*150812a8SEvalZero     nrf_gpiote_task_enable((uint32_t)m_cb.pin_assignments[pin]);
406*150812a8SEvalZero }
407*150812a8SEvalZero 
408*150812a8SEvalZero 
nrfx_gpiote_out_task_disable(nrfx_gpiote_pin_t pin)409*150812a8SEvalZero void nrfx_gpiote_out_task_disable(nrfx_gpiote_pin_t pin)
410*150812a8SEvalZero {
411*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
412*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
413*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
414*150812a8SEvalZero 
415*150812a8SEvalZero     nrf_gpiote_task_disable((uint32_t)m_cb.pin_assignments[pin]);
416*150812a8SEvalZero }
417*150812a8SEvalZero 
418*150812a8SEvalZero 
nrfx_gpiote_out_task_addr_get(nrfx_gpiote_pin_t pin)419*150812a8SEvalZero uint32_t nrfx_gpiote_out_task_addr_get(nrfx_gpiote_pin_t pin)
420*150812a8SEvalZero {
421*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
422*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
423*150812a8SEvalZero 
424*150812a8SEvalZero     nrf_gpiote_tasks_t task = TE_OUT_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
425*150812a8SEvalZero     return nrf_gpiote_task_addr_get(task);
426*150812a8SEvalZero }
427*150812a8SEvalZero 
428*150812a8SEvalZero 
429*150812a8SEvalZero #if defined(GPIOTE_FEATURE_SET_PRESENT)
nrfx_gpiote_set_task_addr_get(nrfx_gpiote_pin_t pin)430*150812a8SEvalZero uint32_t nrfx_gpiote_set_task_addr_get(nrfx_gpiote_pin_t pin)
431*150812a8SEvalZero {
432*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
433*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
434*150812a8SEvalZero 
435*150812a8SEvalZero     nrf_gpiote_tasks_t task = TE_SET_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
436*150812a8SEvalZero     return nrf_gpiote_task_addr_get(task);
437*150812a8SEvalZero }
438*150812a8SEvalZero 
439*150812a8SEvalZero 
440*150812a8SEvalZero #endif // defined(GPIOTE_FEATURE_SET_PRESENT)
441*150812a8SEvalZero 
442*150812a8SEvalZero #if defined(GPIOTE_FEATURE_CLR_PRESENT)
nrfx_gpiote_clr_task_addr_get(nrfx_gpiote_pin_t pin)443*150812a8SEvalZero uint32_t nrfx_gpiote_clr_task_addr_get(nrfx_gpiote_pin_t pin)
444*150812a8SEvalZero {
445*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
446*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
447*150812a8SEvalZero 
448*150812a8SEvalZero     nrf_gpiote_tasks_t task = TE_CLR_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
449*150812a8SEvalZero     return nrf_gpiote_task_addr_get(task);
450*150812a8SEvalZero }
451*150812a8SEvalZero 
452*150812a8SEvalZero 
453*150812a8SEvalZero #endif // defined(GPIOTE_FEATURE_CLR_PRESENT)
454*150812a8SEvalZero 
nrfx_gpiote_out_task_force(nrfx_gpiote_pin_t pin,uint8_t state)455*150812a8SEvalZero void nrfx_gpiote_out_task_force(nrfx_gpiote_pin_t pin, uint8_t state)
456*150812a8SEvalZero {
457*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
458*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
459*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
460*150812a8SEvalZero 
461*150812a8SEvalZero     nrf_gpiote_outinit_t init_val =
462*150812a8SEvalZero         state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW;
463*150812a8SEvalZero     nrf_gpiote_task_force((uint32_t)m_cb.pin_assignments[pin], init_val);
464*150812a8SEvalZero }
465*150812a8SEvalZero 
466*150812a8SEvalZero 
nrfx_gpiote_out_task_trigger(nrfx_gpiote_pin_t pin)467*150812a8SEvalZero void nrfx_gpiote_out_task_trigger(nrfx_gpiote_pin_t pin)
468*150812a8SEvalZero {
469*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
470*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
471*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
472*150812a8SEvalZero 
473*150812a8SEvalZero     nrf_gpiote_tasks_t task = TE_OUT_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
474*150812a8SEvalZero     nrf_gpiote_task_set(task);
475*150812a8SEvalZero }
476*150812a8SEvalZero 
477*150812a8SEvalZero 
478*150812a8SEvalZero #if defined(GPIOTE_FEATURE_SET_PRESENT)
nrfx_gpiote_set_task_trigger(nrfx_gpiote_pin_t pin)479*150812a8SEvalZero void nrfx_gpiote_set_task_trigger(nrfx_gpiote_pin_t pin)
480*150812a8SEvalZero {
481*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
482*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
483*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
484*150812a8SEvalZero 
485*150812a8SEvalZero     nrf_gpiote_tasks_t task = TE_SET_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
486*150812a8SEvalZero     nrf_gpiote_task_set(task);
487*150812a8SEvalZero }
488*150812a8SEvalZero 
489*150812a8SEvalZero 
490*150812a8SEvalZero #endif // defined(GPIOTE_FEATURE_SET_PRESENT)
491*150812a8SEvalZero 
492*150812a8SEvalZero #if  defined(GPIOTE_FEATURE_CLR_PRESENT)
nrfx_gpiote_clr_task_trigger(nrfx_gpiote_pin_t pin)493*150812a8SEvalZero void nrfx_gpiote_clr_task_trigger(nrfx_gpiote_pin_t pin)
494*150812a8SEvalZero {
495*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
496*150812a8SEvalZero     NRFX_ASSERT(pin_in_use(pin));
497*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_te(pin));
498*150812a8SEvalZero 
499*150812a8SEvalZero     nrf_gpiote_tasks_t task = TE_CLR_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
500*150812a8SEvalZero     nrf_gpiote_task_set(task);
501*150812a8SEvalZero }
502*150812a8SEvalZero 
503*150812a8SEvalZero 
504*150812a8SEvalZero #endif // defined(GPIOTE_FEATURE_CLR_PRESENT)
505*150812a8SEvalZero 
nrfx_gpiote_in_init(nrfx_gpiote_pin_t pin,nrfx_gpiote_in_config_t const * p_config,nrfx_gpiote_evt_handler_t evt_handler)506*150812a8SEvalZero nrfx_err_t nrfx_gpiote_in_init(nrfx_gpiote_pin_t               pin,
507*150812a8SEvalZero                                nrfx_gpiote_in_config_t const * p_config,
508*150812a8SEvalZero                                nrfx_gpiote_evt_handler_t       evt_handler)
509*150812a8SEvalZero {
510*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
511*150812a8SEvalZero     nrfx_err_t err_code = NRFX_SUCCESS;
512*150812a8SEvalZero 
513*150812a8SEvalZero     /* Only one GPIOTE channel can be assigned to one physical pin. */
514*150812a8SEvalZero     if (pin_in_use_by_gpiote(pin))
515*150812a8SEvalZero     {
516*150812a8SEvalZero         err_code = NRFX_ERROR_INVALID_STATE;
517*150812a8SEvalZero     }
518*150812a8SEvalZero     else
519*150812a8SEvalZero     {
520*150812a8SEvalZero         int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy);
521*150812a8SEvalZero         if (channel != NO_CHANNELS)
522*150812a8SEvalZero         {
523*150812a8SEvalZero             if (!p_config->skip_gpio_setup)
524*150812a8SEvalZero             {
525*150812a8SEvalZero                 if (p_config->is_watcher)
526*150812a8SEvalZero                 {
527*150812a8SEvalZero                     nrf_gpio_cfg_watcher(pin);
528*150812a8SEvalZero                 }
529*150812a8SEvalZero                 else
530*150812a8SEvalZero                 {
531*150812a8SEvalZero                     nrf_gpio_cfg_input(pin, p_config->pull);
532*150812a8SEvalZero                 }
533*150812a8SEvalZero                 pin_configured_set(pin);
534*150812a8SEvalZero             }
535*150812a8SEvalZero 
536*150812a8SEvalZero             if (p_config->hi_accuracy)
537*150812a8SEvalZero             {
538*150812a8SEvalZero                 nrf_gpiote_event_configure((uint32_t)channel, pin, p_config->sense);
539*150812a8SEvalZero             }
540*150812a8SEvalZero             else
541*150812a8SEvalZero             {
542*150812a8SEvalZero                 m_cb.port_handlers_pins[channel -
543*150812a8SEvalZero                                         GPIOTE_CH_NUM] |= (p_config->sense) << SENSE_FIELD_POS;
544*150812a8SEvalZero             }
545*150812a8SEvalZero         }
546*150812a8SEvalZero         else
547*150812a8SEvalZero         {
548*150812a8SEvalZero             err_code = NRFX_ERROR_NO_MEM;
549*150812a8SEvalZero         }
550*150812a8SEvalZero     }
551*150812a8SEvalZero 
552*150812a8SEvalZero     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
553*150812a8SEvalZero     return err_code;
554*150812a8SEvalZero }
555*150812a8SEvalZero 
nrfx_gpiote_in_event_enable(nrfx_gpiote_pin_t pin,bool int_enable)556*150812a8SEvalZero void nrfx_gpiote_in_event_enable(nrfx_gpiote_pin_t pin, bool int_enable)
557*150812a8SEvalZero {
558*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
559*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_gpiote(pin));
560*150812a8SEvalZero     if (pin_in_use_by_port(pin))
561*150812a8SEvalZero     {
562*150812a8SEvalZero         uint8_t pin_and_sense = (uint8_t)
563*150812a8SEvalZero             m_cb.port_handlers_pins[channel_port_get(pin) - GPIOTE_CH_NUM];
564*150812a8SEvalZero         nrf_gpiote_polarity_t polarity =
565*150812a8SEvalZero             (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS);
566*150812a8SEvalZero         nrf_gpio_pin_sense_t sense;
567*150812a8SEvalZero         if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
568*150812a8SEvalZero         {
569*150812a8SEvalZero             /* read current pin state and set for next sense to oposit */
570*150812a8SEvalZero             sense = (nrf_gpio_pin_read(pin)) ?
571*150812a8SEvalZero                     NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
572*150812a8SEvalZero         }
573*150812a8SEvalZero         else
574*150812a8SEvalZero         {
575*150812a8SEvalZero             sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ?
576*150812a8SEvalZero                     NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW;
577*150812a8SEvalZero         }
578*150812a8SEvalZero         nrf_gpio_cfg_sense_set(pin, sense);
579*150812a8SEvalZero     }
580*150812a8SEvalZero     else if (pin_in_use_by_te(pin))
581*150812a8SEvalZero     {
582*150812a8SEvalZero         int32_t             channel = (int32_t)channel_port_get(pin);
583*150812a8SEvalZero         nrf_gpiote_events_t event   = TE_IDX_TO_EVENT_ADDR((uint32_t)channel);
584*150812a8SEvalZero 
585*150812a8SEvalZero         nrf_gpiote_event_enable((uint32_t)channel);
586*150812a8SEvalZero 
587*150812a8SEvalZero         nrf_gpiote_event_clear(event);
588*150812a8SEvalZero         if (int_enable)
589*150812a8SEvalZero         {
590*150812a8SEvalZero             nrfx_gpiote_evt_handler_t handler = channel_handler_get((uint32_t)channel_port_get(pin));
591*150812a8SEvalZero             // Enable the interrupt only if event handler was provided.
592*150812a8SEvalZero             if (handler)
593*150812a8SEvalZero             {
594*150812a8SEvalZero                 nrf_gpiote_int_enable(1 << channel);
595*150812a8SEvalZero             }
596*150812a8SEvalZero         }
597*150812a8SEvalZero     }
598*150812a8SEvalZero }
599*150812a8SEvalZero 
600*150812a8SEvalZero 
nrfx_gpiote_in_event_disable(nrfx_gpiote_pin_t pin)601*150812a8SEvalZero void nrfx_gpiote_in_event_disable(nrfx_gpiote_pin_t pin)
602*150812a8SEvalZero {
603*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
604*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_gpiote(pin));
605*150812a8SEvalZero     if (pin_in_use_by_port(pin))
606*150812a8SEvalZero     {
607*150812a8SEvalZero         nrf_gpio_cfg_sense_set(pin, NRF_GPIO_PIN_NOSENSE);
608*150812a8SEvalZero     }
609*150812a8SEvalZero     else if (pin_in_use_by_te(pin))
610*150812a8SEvalZero     {
611*150812a8SEvalZero         int32_t channel = (int32_t)channel_port_get(pin);
612*150812a8SEvalZero         nrf_gpiote_event_disable((uint32_t)channel);
613*150812a8SEvalZero         nrf_gpiote_int_disable(1 << channel);
614*150812a8SEvalZero     }
615*150812a8SEvalZero }
616*150812a8SEvalZero 
617*150812a8SEvalZero 
nrfx_gpiote_in_uninit(nrfx_gpiote_pin_t pin)618*150812a8SEvalZero void nrfx_gpiote_in_uninit(nrfx_gpiote_pin_t pin)
619*150812a8SEvalZero {
620*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
621*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_gpiote(pin));
622*150812a8SEvalZero     nrfx_gpiote_in_event_disable(pin);
623*150812a8SEvalZero     if (pin_in_use_by_te(pin))
624*150812a8SEvalZero     {
625*150812a8SEvalZero         nrf_gpiote_te_default((uint32_t)channel_port_get(pin));
626*150812a8SEvalZero     }
627*150812a8SEvalZero     if (pin_configured_check(pin))
628*150812a8SEvalZero     {
629*150812a8SEvalZero         nrf_gpio_cfg_default(pin);
630*150812a8SEvalZero         pin_configured_clear(pin);
631*150812a8SEvalZero     }
632*150812a8SEvalZero     channel_free((uint8_t)channel_port_get(pin));
633*150812a8SEvalZero     pin_in_use_clear(pin);
634*150812a8SEvalZero }
635*150812a8SEvalZero 
636*150812a8SEvalZero 
nrfx_gpiote_in_is_set(nrfx_gpiote_pin_t pin)637*150812a8SEvalZero bool nrfx_gpiote_in_is_set(nrfx_gpiote_pin_t pin)
638*150812a8SEvalZero {
639*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
640*150812a8SEvalZero     return nrf_gpio_pin_read(pin) ? true : false;
641*150812a8SEvalZero }
642*150812a8SEvalZero 
643*150812a8SEvalZero 
nrfx_gpiote_in_event_addr_get(nrfx_gpiote_pin_t pin)644*150812a8SEvalZero uint32_t nrfx_gpiote_in_event_addr_get(nrfx_gpiote_pin_t pin)
645*150812a8SEvalZero {
646*150812a8SEvalZero     NRFX_ASSERT(pin < NUMBER_OF_PINS);
647*150812a8SEvalZero     NRFX_ASSERT(pin_in_use_by_port(pin) || pin_in_use_by_te(pin));
648*150812a8SEvalZero 
649*150812a8SEvalZero     nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_PORT;
650*150812a8SEvalZero 
651*150812a8SEvalZero     if (pin_in_use_by_te(pin))
652*150812a8SEvalZero     {
653*150812a8SEvalZero         event = TE_IDX_TO_EVENT_ADDR((uint32_t)channel_port_get(pin));
654*150812a8SEvalZero     }
655*150812a8SEvalZero     return nrf_gpiote_event_addr_get(event);
656*150812a8SEvalZero }
657*150812a8SEvalZero 
658*150812a8SEvalZero 
nrfx_gpiote_irq_handler(void)659*150812a8SEvalZero void nrfx_gpiote_irq_handler(void)
660*150812a8SEvalZero {
661*150812a8SEvalZero     uint32_t status            = 0;
662*150812a8SEvalZero     uint32_t input[GPIO_COUNT] = {0};
663*150812a8SEvalZero 
664*150812a8SEvalZero     /* collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/
665*150812a8SEvalZero     uint32_t            i;
666*150812a8SEvalZero     nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_IN_0;
667*150812a8SEvalZero     uint32_t            mask  = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
668*150812a8SEvalZero 
669*150812a8SEvalZero     for (i = 0; i < GPIOTE_CH_NUM; i++)
670*150812a8SEvalZero     {
671*150812a8SEvalZero         if (nrf_gpiote_event_is_set(event) && nrf_gpiote_int_is_enabled(mask))
672*150812a8SEvalZero         {
673*150812a8SEvalZero             nrf_gpiote_event_clear(event);
674*150812a8SEvalZero             status |= mask;
675*150812a8SEvalZero         }
676*150812a8SEvalZero         mask <<= 1;
677*150812a8SEvalZero         /* Incrementing to next event, utilizing the fact that events are grouped together
678*150812a8SEvalZero          * in ascending order. */
679*150812a8SEvalZero         event = (nrf_gpiote_events_t)((uint32_t)event + sizeof(uint32_t));
680*150812a8SEvalZero     }
681*150812a8SEvalZero 
682*150812a8SEvalZero     /* collect PORT status event, if event is set read pins state. Processing is postponed to the
683*150812a8SEvalZero      * end of interrupt. */
684*150812a8SEvalZero     if (nrf_gpiote_event_is_set(NRF_GPIOTE_EVENTS_PORT))
685*150812a8SEvalZero     {
686*150812a8SEvalZero         nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
687*150812a8SEvalZero         status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK;
688*150812a8SEvalZero         nrf_gpio_ports_read(0, GPIO_COUNT, input);
689*150812a8SEvalZero     }
690*150812a8SEvalZero 
691*150812a8SEvalZero     /* Process pin events. */
692*150812a8SEvalZero     if (status & NRF_GPIOTE_INT_IN_MASK)
693*150812a8SEvalZero     {
694*150812a8SEvalZero         mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
695*150812a8SEvalZero 
696*150812a8SEvalZero         for (i = 0; i < GPIOTE_CH_NUM; i++)
697*150812a8SEvalZero         {
698*150812a8SEvalZero             if (mask & status)
699*150812a8SEvalZero             {
700*150812a8SEvalZero                 nrfx_gpiote_pin_t pin = nrf_gpiote_event_pin_get(i);
701*150812a8SEvalZero                 NRFX_LOG_DEBUG("Event in number: %d.", i);
702*150812a8SEvalZero                 nrf_gpiote_polarity_t        polarity = nrf_gpiote_event_polarity_get(i);
703*150812a8SEvalZero                 nrfx_gpiote_evt_handler_t handler  = channel_handler_get(i);
704*150812a8SEvalZero                 NRFX_LOG_DEBUG("Pin: %d, polarity: %d.", pin, polarity);
705*150812a8SEvalZero                 if (handler)
706*150812a8SEvalZero                 {
707*150812a8SEvalZero                     handler(pin, polarity);
708*150812a8SEvalZero                 }
709*150812a8SEvalZero             }
710*150812a8SEvalZero             mask <<= 1;
711*150812a8SEvalZero         }
712*150812a8SEvalZero     }
713*150812a8SEvalZero 
714*150812a8SEvalZero     if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK)
715*150812a8SEvalZero     {
716*150812a8SEvalZero         /* Process port event. */
717*150812a8SEvalZero         uint32_t port_idx;
718*150812a8SEvalZero         uint8_t  repeat                  = 0;
719*150812a8SEvalZero         uint32_t toggle_mask[GPIO_COUNT] = {0};
720*150812a8SEvalZero         uint32_t pins_to_check[GPIO_COUNT];
721*150812a8SEvalZero 
722*150812a8SEvalZero         // Faster way of doing memset because in interrupt context.
723*150812a8SEvalZero         for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
724*150812a8SEvalZero         {
725*150812a8SEvalZero             pins_to_check[port_idx] = 0xFFFFFFFF;
726*150812a8SEvalZero         }
727*150812a8SEvalZero 
728*150812a8SEvalZero         do
729*150812a8SEvalZero         {
730*150812a8SEvalZero             repeat = 0;
731*150812a8SEvalZero 
732*150812a8SEvalZero             for (i = 0; i < NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
733*150812a8SEvalZero             {
734*150812a8SEvalZero                 uint8_t           pin_and_sense = (uint8_t)m_cb.port_handlers_pins[i];
735*150812a8SEvalZero                 nrfx_gpiote_pin_t pin           = (pin_and_sense & ~SENSE_FIELD_MASK);
736*150812a8SEvalZero 
737*150812a8SEvalZero                 if ((m_cb.port_handlers_pins[i] != PIN_NOT_USED)
738*150812a8SEvalZero                     && nrf_bitmask_bit_is_set(pin, pins_to_check))
739*150812a8SEvalZero                 {
740*150812a8SEvalZero                     nrf_gpiote_polarity_t polarity =
741*150812a8SEvalZero                         (nrf_gpiote_polarity_t)((pin_and_sense &
742*150812a8SEvalZero                                                  SENSE_FIELD_MASK) >> SENSE_FIELD_POS);
743*150812a8SEvalZero                     nrfx_gpiote_evt_handler_t handler =
744*150812a8SEvalZero                         channel_handler_get((uint32_t)channel_port_get(pin));
745*150812a8SEvalZero                     if (handler || (polarity == NRF_GPIOTE_POLARITY_TOGGLE))
746*150812a8SEvalZero                     {
747*150812a8SEvalZero                         if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
748*150812a8SEvalZero                         {
749*150812a8SEvalZero                             nrf_bitmask_bit_set(pin, toggle_mask);
750*150812a8SEvalZero                         }
751*150812a8SEvalZero                         nrf_gpio_pin_sense_t sense     = nrf_gpio_pin_sense_get(pin);
752*150812a8SEvalZero                         uint32_t             pin_state = nrf_bitmask_bit_is_set(pin, input);
753*150812a8SEvalZero                         if ((pin_state && (sense == NRF_GPIO_PIN_SENSE_HIGH)) ||
754*150812a8SEvalZero                             (!pin_state && (sense == NRF_GPIO_PIN_SENSE_LOW))  )
755*150812a8SEvalZero                         {
756*150812a8SEvalZero                             NRFX_LOG_DEBUG("PORT event for pin: %d, polarity: %d.", pin, polarity);
757*150812a8SEvalZero                             if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
758*150812a8SEvalZero                             {
759*150812a8SEvalZero                                 nrf_gpio_pin_sense_t next_sense =
760*150812a8SEvalZero                                     (sense == NRF_GPIO_PIN_SENSE_HIGH) ?
761*150812a8SEvalZero                                     NRF_GPIO_PIN_SENSE_LOW :
762*150812a8SEvalZero                                     NRF_GPIO_PIN_SENSE_HIGH;
763*150812a8SEvalZero                                 nrf_gpio_cfg_sense_set(pin, next_sense);
764*150812a8SEvalZero                                 ++repeat;
765*150812a8SEvalZero 
766*150812a8SEvalZero                             }
767*150812a8SEvalZero                             if (handler)
768*150812a8SEvalZero                             {
769*150812a8SEvalZero                                 handler(pin, polarity);
770*150812a8SEvalZero                             }
771*150812a8SEvalZero                         }
772*150812a8SEvalZero                     }
773*150812a8SEvalZero                 }
774*150812a8SEvalZero             }
775*150812a8SEvalZero 
776*150812a8SEvalZero             if (repeat)
777*150812a8SEvalZero             {
778*150812a8SEvalZero                 // When one of the pins in low-accuracy and toggle mode becomes active,
779*150812a8SEvalZero                 // it's sense mode is inverted to clear the internal SENSE signal.
780*150812a8SEvalZero                 // State of any other enabled low-accuracy input in toggle mode must be checked
781*150812a8SEvalZero                 // explicitly, because it does not trigger the interrput when SENSE signal is active.
782*150812a8SEvalZero                 // For more information about SENSE functionality, refer to Product Specification.
783*150812a8SEvalZero 
784*150812a8SEvalZero                 uint32_t new_input[GPIO_COUNT];
785*150812a8SEvalZero                 bool     input_unchanged = true;
786*150812a8SEvalZero                 nrf_gpio_ports_read(0, GPIO_COUNT, new_input);
787*150812a8SEvalZero 
788*150812a8SEvalZero                 // Faster way of doing memcmp because in interrupt context.
789*150812a8SEvalZero                 for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
790*150812a8SEvalZero                 {
791*150812a8SEvalZero                     if (new_input[port_idx] != input[port_idx])
792*150812a8SEvalZero                     {
793*150812a8SEvalZero                         input_unchanged = false;
794*150812a8SEvalZero                         break;
795*150812a8SEvalZero                     }
796*150812a8SEvalZero                 }
797*150812a8SEvalZero 
798*150812a8SEvalZero                 if (input_unchanged)
799*150812a8SEvalZero                 {
800*150812a8SEvalZero                     // No change.
801*150812a8SEvalZero                     repeat = 0;
802*150812a8SEvalZero                 }
803*150812a8SEvalZero                 else
804*150812a8SEvalZero                 {
805*150812a8SEvalZero                     // Faster way of doing memcpy because in interrupt context.
806*150812a8SEvalZero                     for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
807*150812a8SEvalZero                     {
808*150812a8SEvalZero                         input[port_idx]         = new_input[port_idx];
809*150812a8SEvalZero                         pins_to_check[port_idx] = toggle_mask[port_idx];
810*150812a8SEvalZero                     }
811*150812a8SEvalZero                 }
812*150812a8SEvalZero             }
813*150812a8SEvalZero         }
814*150812a8SEvalZero         while (repeat);
815*150812a8SEvalZero     }
816*150812a8SEvalZero }
817*150812a8SEvalZero 
818*150812a8SEvalZero 
819*150812a8SEvalZero /*lint -restore*/
820*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_GPIOTE_ENABLED)
821