1*16749429SEvalZero /*
2*16749429SEvalZero * SPDX-License-Identifier: Apache-2.0
3*16749429SEvalZero *
4*16749429SEvalZero * Date Author Notes
5*16749429SEvalZero * 2018-03-13 ZeroFree first implementation
6*16749429SEvalZero */
7*16749429SEvalZero
8*16749429SEvalZero #include <rtthread.h>
9*16749429SEvalZero #include <rtdevice.h>
10*16749429SEvalZero #include <rthw.h>
11*16749429SEvalZero
12*16749429SEvalZero #include "drv_gpio.h"
13*16749429SEvalZero #include "nrf.h"
14*16749429SEvalZero
15*16749429SEvalZero #define MCU_GPIO_USE_PORT_EVENT 1
16*16749429SEvalZero
17*16749429SEvalZero #define NRF_GPIO_INDEX(pin) (pin)
18*16749429SEvalZero #define NRF_GPIO_PORT(pin) (NRF_P0)
19*16749429SEvalZero #define NRF_GPIO_MASK(pin) (1 << NRF_GPIO_INDEX(pin))
20*16749429SEvalZero #define NRF_GPIOTE_PIN_MASK GPIOTE_CONFIG_PSEL_Msk
21*16749429SEvalZero
22*16749429SEvalZero /* GPIO interrupts */
23*16749429SEvalZero #define NRF_GPIO_MAX_IRQ 8
24*16749429SEvalZero
25*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
26*16749429SEvalZero #define NRF_GPIO_SENSE_TRIG_NONE 0x00 /* just 0 */
27*16749429SEvalZero #define NRF_GPIO_SENSE_TRIG_BOTH 0x01 /* something else than both below */
28*16749429SEvalZero #define NRF_GPIO_SENSE_TRIG_HIGH 0x02 /* GPIO_PIN_CNF_SENSE_High */
29*16749429SEvalZero #define NRF_GPIO_SENSE_TRIG_LOW 0x03 /* GPIO_PIN_CNF_SENSE_Low */
30*16749429SEvalZero #endif
31*16749429SEvalZero
32*16749429SEvalZero /* Storage for GPIO callbacks */
33*16749429SEvalZero struct nrf_gpio_irq
34*16749429SEvalZero {
35*16749429SEvalZero void (*func)(void *args);
36*16749429SEvalZero void *args;
37*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
38*16749429SEvalZero rt_int16_t pin;
39*16749429SEvalZero uint8_t sense_trig;
40*16749429SEvalZero #endif
41*16749429SEvalZero };
42*16749429SEvalZero
43*16749429SEvalZero static struct nrf_gpio_irq nrf_gpio_irqs[NRF_GPIO_MAX_IRQ];
44*16749429SEvalZero
nrf_pin_mode(struct rt_device * device,rt_base_t pin,rt_base_t mode)45*16749429SEvalZero static void nrf_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
46*16749429SEvalZero {
47*16749429SEvalZero uint32_t conf;
48*16749429SEvalZero NRF_GPIO_Type *port;
49*16749429SEvalZero uint8_t dir = 0;
50*16749429SEvalZero int index = NRF_GPIO_INDEX(pin);
51*16749429SEvalZero
52*16749429SEvalZero switch (mode)
53*16749429SEvalZero {
54*16749429SEvalZero case PIN_MODE_OUTPUT:
55*16749429SEvalZero conf = GPIO_PIN_CNF_DIR_Output |
56*16749429SEvalZero (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
57*16749429SEvalZero dir = 1;
58*16749429SEvalZero break;
59*16749429SEvalZero case PIN_MODE_INPUT:
60*16749429SEvalZero conf = 0;
61*16749429SEvalZero break;
62*16749429SEvalZero case PIN_MODE_INPUT_PULLUP:
63*16749429SEvalZero conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos;
64*16749429SEvalZero break;
65*16749429SEvalZero case PIN_MODE_INPUT_PULLDOWN:
66*16749429SEvalZero conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos;
67*16749429SEvalZero break;
68*16749429SEvalZero default:
69*16749429SEvalZero conf = 0;
70*16749429SEvalZero break;
71*16749429SEvalZero }
72*16749429SEvalZero
73*16749429SEvalZero port = NRF_GPIO_PORT(pin);
74*16749429SEvalZero port->PIN_CNF[index] = conf;
75*16749429SEvalZero
76*16749429SEvalZero if (dir == 1)
77*16749429SEvalZero {
78*16749429SEvalZero /* output */
79*16749429SEvalZero port->DIRSET = NRF_GPIO_MASK(pin);
80*16749429SEvalZero port->OUTCLR = NRF_GPIO_MASK(pin);
81*16749429SEvalZero }
82*16749429SEvalZero else
83*16749429SEvalZero {
84*16749429SEvalZero /* input */
85*16749429SEvalZero port->DIRCLR = NRF_GPIO_MASK(pin);
86*16749429SEvalZero }
87*16749429SEvalZero }
88*16749429SEvalZero
nrf_pin_write(struct rt_device * device,rt_base_t pin,rt_base_t value)89*16749429SEvalZero static void nrf_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value)
90*16749429SEvalZero {
91*16749429SEvalZero NRF_GPIO_Type *port;
92*16749429SEvalZero
93*16749429SEvalZero port = NRF_GPIO_PORT(pin);
94*16749429SEvalZero if (value)
95*16749429SEvalZero {
96*16749429SEvalZero port->OUTSET = NRF_GPIO_MASK(pin);
97*16749429SEvalZero }
98*16749429SEvalZero else
99*16749429SEvalZero {
100*16749429SEvalZero port->OUTCLR = NRF_GPIO_MASK(pin);
101*16749429SEvalZero }
102*16749429SEvalZero }
103*16749429SEvalZero
nrf_pin_read(struct rt_device * device,rt_base_t pin)104*16749429SEvalZero static int nrf_pin_read(struct rt_device *device, rt_base_t pin)
105*16749429SEvalZero {
106*16749429SEvalZero NRF_GPIO_Type *port;
107*16749429SEvalZero port = NRF_GPIO_PORT(pin);
108*16749429SEvalZero
109*16749429SEvalZero return (port->DIR & NRF_GPIO_MASK(pin)) ?
110*16749429SEvalZero (port->OUT >> NRF_GPIO_INDEX(pin)) & 1UL :
111*16749429SEvalZero (port->IN >> NRF_GPIO_INDEX(pin)) & 1UL;
112*16749429SEvalZero }
113*16749429SEvalZero
114*16749429SEvalZero /*
115*16749429SEvalZero * GPIO irq handler
116*16749429SEvalZero *
117*16749429SEvalZero * Handles the gpio interrupt attached to a gpio pin.
118*16749429SEvalZero *
119*16749429SEvalZero * @param index
120*16749429SEvalZero */
nrf_gpio_irq_handler(void)121*16749429SEvalZero static void nrf_gpio_irq_handler(void)
122*16749429SEvalZero {
123*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
124*16749429SEvalZero NRF_GPIO_Type *gpio_port;
125*16749429SEvalZero int pin_index;
126*16749429SEvalZero int pin_state;
127*16749429SEvalZero uint8_t sense_trig;
128*16749429SEvalZero uint32_t gpio_state;
129*16749429SEvalZero #endif
130*16749429SEvalZero int i;
131*16749429SEvalZero
132*16749429SEvalZero rt_interrupt_enter();
133*16749429SEvalZero
134*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
135*16749429SEvalZero NRF_GPIOTE->EVENTS_PORT = 0;
136*16749429SEvalZero gpio_state = NRF_P0->IN;
137*16749429SEvalZero
138*16749429SEvalZero for (i = 0; i < NRF_GPIO_MAX_IRQ; i++)
139*16749429SEvalZero {
140*16749429SEvalZero if ((!nrf_gpio_irqs[i].func) ||
141*16749429SEvalZero (nrf_gpio_irqs[i].sense_trig == NRF_GPIO_SENSE_TRIG_NONE))
142*16749429SEvalZero {
143*16749429SEvalZero continue;
144*16749429SEvalZero }
145*16749429SEvalZero
146*16749429SEvalZero gpio_port = NRF_GPIO_PORT(nrf_gpio_irqs[i].pin);
147*16749429SEvalZero pin_index = NRF_GPIO_INDEX(nrf_gpio_irqs[i].pin);
148*16749429SEvalZero
149*16749429SEvalZero /* Store current SENSE setting */
150*16749429SEvalZero sense_trig = (gpio_port->PIN_CNF[pin_index] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos;
151*16749429SEvalZero
152*16749429SEvalZero if (!sense_trig)
153*16749429SEvalZero {
154*16749429SEvalZero continue;
155*16749429SEvalZero }
156*16749429SEvalZero
157*16749429SEvalZero /*
158*16749429SEvalZero * SENSE values are 0x02 for high and 0x03 for low, so bit #0 is the
159*16749429SEvalZero * opposite of state which triggers interrupt (thus its value should be
160*16749429SEvalZero * different than pin state).
161*16749429SEvalZero */
162*16749429SEvalZero pin_state = (gpio_state >> nrf_gpio_irqs[i].pin) & 0x01;
163*16749429SEvalZero if (pin_state == (sense_trig & 0x01))
164*16749429SEvalZero {
165*16749429SEvalZero continue;
166*16749429SEvalZero }
167*16749429SEvalZero
168*16749429SEvalZero /*
169*16749429SEvalZero * Toggle sense to clear interrupt or allow detection of opposite edge
170*16749429SEvalZero * when trigger on both edges is requested.
171*16749429SEvalZero */
172*16749429SEvalZero gpio_port->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk;
173*16749429SEvalZero if (sense_trig == NRF_GPIO_SENSE_TRIG_HIGH)
174*16749429SEvalZero {
175*16749429SEvalZero gpio_port->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;
176*16749429SEvalZero }
177*16749429SEvalZero else
178*16749429SEvalZero {
179*16749429SEvalZero gpio_port->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos;
180*16749429SEvalZero }
181*16749429SEvalZero
182*16749429SEvalZero /*
183*16749429SEvalZero * Call handler in case SENSE configuration matches requested one or
184*16749429SEvalZero * trigger on both edges is requested.
185*16749429SEvalZero */
186*16749429SEvalZero if ((nrf_gpio_irqs[i].sense_trig == NRF_GPIO_SENSE_TRIG_BOTH) ||
187*16749429SEvalZero (nrf_gpio_irqs[i].sense_trig == sense_trig))
188*16749429SEvalZero {
189*16749429SEvalZero nrf_gpio_irqs[i].func(nrf_gpio_irqs[i].args);
190*16749429SEvalZero }
191*16749429SEvalZero }
192*16749429SEvalZero #else
193*16749429SEvalZero for (i = 0; i < NRF_GPIO_MAX_IRQ; i++)
194*16749429SEvalZero {
195*16749429SEvalZero if (NRF_GPIOTE->EVENTS_IN[i] && (NRF_GPIOTE->INTENSET & (1 << i)))
196*16749429SEvalZero {
197*16749429SEvalZero NRF_GPIOTE->EVENTS_IN[i] = 0;
198*16749429SEvalZero if (nrf_gpio_irqs[i].func)
199*16749429SEvalZero {
200*16749429SEvalZero nrf_gpio_irqs[i].func(nrf_gpio_irqs[i].args);
201*16749429SEvalZero }
202*16749429SEvalZero }
203*16749429SEvalZero }
204*16749429SEvalZero #endif
205*16749429SEvalZero
206*16749429SEvalZero rt_interrupt_leave();
207*16749429SEvalZero }
208*16749429SEvalZero
GPIOTE_IRQHandler(void)209*16749429SEvalZero void GPIOTE_IRQHandler(void)
210*16749429SEvalZero {
211*16749429SEvalZero nrf_gpio_irq_handler();
212*16749429SEvalZero }
213*16749429SEvalZero
nrf_gpio_irq_setup(void)214*16749429SEvalZero static void nrf_gpio_irq_setup(void)
215*16749429SEvalZero {
216*16749429SEvalZero static uint8_t irq_setup = 0;
217*16749429SEvalZero
218*16749429SEvalZero if (!irq_setup)
219*16749429SEvalZero {
220*16749429SEvalZero NVIC_EnableIRQ(GPIOTE_IRQn);
221*16749429SEvalZero irq_setup = 1;
222*16749429SEvalZero
223*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
224*16749429SEvalZero NRF_GPIOTE->INTENCLR = GPIOTE_INTENCLR_PORT_Msk;
225*16749429SEvalZero NRF_GPIOTE->EVENTS_PORT = 0;
226*16749429SEvalZero #endif
227*16749429SEvalZero }
228*16749429SEvalZero }
229*16749429SEvalZero
230*16749429SEvalZero /*
231*16749429SEvalZero * Find out whether we have an GPIOTE pin event to use.
232*16749429SEvalZero */
hal_gpio_find_empty_slot(void)233*16749429SEvalZero static int hal_gpio_find_empty_slot(void)
234*16749429SEvalZero {
235*16749429SEvalZero int i;
236*16749429SEvalZero
237*16749429SEvalZero for (i = 0; i < NRF_GPIO_MAX_IRQ; i++)
238*16749429SEvalZero {
239*16749429SEvalZero if (nrf_gpio_irqs[i].func == NULL)
240*16749429SEvalZero {
241*16749429SEvalZero return i;
242*16749429SEvalZero }
243*16749429SEvalZero }
244*16749429SEvalZero return -1;
245*16749429SEvalZero }
246*16749429SEvalZero
247*16749429SEvalZero /*
248*16749429SEvalZero * Find the GPIOTE event which handles this pin.
249*16749429SEvalZero */
nrf_gpio_find_pin(int pin)250*16749429SEvalZero static int nrf_gpio_find_pin(int pin)
251*16749429SEvalZero {
252*16749429SEvalZero int i;
253*16749429SEvalZero
254*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
255*16749429SEvalZero for (i = 0; i < NRF_GPIO_MAX_IRQ; i++)
256*16749429SEvalZero {
257*16749429SEvalZero if (nrf_gpio_irqs[i].func && nrf_gpio_irqs[i].pin == pin)
258*16749429SEvalZero {
259*16749429SEvalZero return i;
260*16749429SEvalZero }
261*16749429SEvalZero }
262*16749429SEvalZero #else
263*16749429SEvalZero pin = pin << GPIOTE_CONFIG_PSEL_Pos;
264*16749429SEvalZero
265*16749429SEvalZero for (i = 0; i < NRF_GPIO_MAX_IRQ; i++)
266*16749429SEvalZero {
267*16749429SEvalZero if (nrf_gpio_irqs[i].func &&
268*16749429SEvalZero (NRF_GPIOTE->CONFIG[i] & NRF_GPIOTE_PIN_MASK) == pin)
269*16749429SEvalZero {
270*16749429SEvalZero return i;
271*16749429SEvalZero }
272*16749429SEvalZero }
273*16749429SEvalZero #endif
274*16749429SEvalZero
275*16749429SEvalZero return -1;
276*16749429SEvalZero }
277*16749429SEvalZero
nrf_pin_attach_irq(struct rt_device * device,rt_int32_t pin,rt_uint32_t mode,void (* hdr)(void * args),void * args)278*16749429SEvalZero static rt_err_t nrf_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
279*16749429SEvalZero rt_uint32_t mode, void (*hdr)(void *args), void *args)
280*16749429SEvalZero {
281*16749429SEvalZero uint32_t conf;
282*16749429SEvalZero int i;
283*16749429SEvalZero
284*16749429SEvalZero nrf_gpio_irq_setup();
285*16749429SEvalZero i = hal_gpio_find_empty_slot();
286*16749429SEvalZero if (i < 0)
287*16749429SEvalZero {
288*16749429SEvalZero return -RT_EFULL;
289*16749429SEvalZero }
290*16749429SEvalZero
291*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
292*16749429SEvalZero (void)conf;
293*16749429SEvalZero nrf_gpio_irqs[i].pin = pin;
294*16749429SEvalZero
295*16749429SEvalZero switch (mode)
296*16749429SEvalZero {
297*16749429SEvalZero case PIN_IRQ_MODE_RISING:
298*16749429SEvalZero nrf_gpio_irqs[i].sense_trig = NRF_GPIO_SENSE_TRIG_HIGH;
299*16749429SEvalZero break;
300*16749429SEvalZero case PIN_IRQ_MODE_FALLING:
301*16749429SEvalZero nrf_gpio_irqs[i].sense_trig = NRF_GPIO_SENSE_TRIG_LOW;
302*16749429SEvalZero break;
303*16749429SEvalZero case PIN_IRQ_MODE_RISING_FALLING:
304*16749429SEvalZero nrf_gpio_irqs[i].sense_trig = NRF_GPIO_SENSE_TRIG_BOTH;
305*16749429SEvalZero break;
306*16749429SEvalZero default:
307*16749429SEvalZero nrf_gpio_irqs[i].sense_trig = NRF_GPIO_SENSE_TRIG_NONE;
308*16749429SEvalZero return -1;
309*16749429SEvalZero }
310*16749429SEvalZero #else
311*16749429SEvalZero switch (mode)
312*16749429SEvalZero {
313*16749429SEvalZero case PIN_IRQ_MODE_RISING:
314*16749429SEvalZero conf = GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos;
315*16749429SEvalZero break;
316*16749429SEvalZero case PIN_IRQ_MODE_FALLING:
317*16749429SEvalZero conf = GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;
318*16749429SEvalZero break;
319*16749429SEvalZero case PIN_IRQ_MODE_RISING_FALLING:
320*16749429SEvalZero conf = GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos;
321*16749429SEvalZero break;
322*16749429SEvalZero default:
323*16749429SEvalZero return -RT_ERROR;
324*16749429SEvalZero }
325*16749429SEvalZero
326*16749429SEvalZero conf |= pin << GPIOTE_CONFIG_PSEL_Pos;
327*16749429SEvalZero conf |= GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos;
328*16749429SEvalZero NRF_GPIOTE->CONFIG[i] = conf;
329*16749429SEvalZero #endif
330*16749429SEvalZero
331*16749429SEvalZero nrf_gpio_irqs[i].func = hdr;
332*16749429SEvalZero nrf_gpio_irqs[i].args = args;
333*16749429SEvalZero
334*16749429SEvalZero return RT_EOK;
335*16749429SEvalZero }
336*16749429SEvalZero
nrf_pin_detach_irq(struct rt_device * device,rt_int32_t pin)337*16749429SEvalZero static rt_err_t nrf_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
338*16749429SEvalZero {
339*16749429SEvalZero rt_err_t ret = RT_EOK;
340*16749429SEvalZero
341*16749429SEvalZero int i;
342*16749429SEvalZero
343*16749429SEvalZero i = nrf_gpio_find_pin(pin);
344*16749429SEvalZero if (i < 0)
345*16749429SEvalZero {
346*16749429SEvalZero return -RT_ERROR;
347*16749429SEvalZero }
348*16749429SEvalZero /* disable pin irq */
349*16749429SEvalZero rt_pin_irq_enable(pin, 0);
350*16749429SEvalZero
351*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
352*16749429SEvalZero nrf_gpio_irqs[i].sense_trig = NRF_GPIO_SENSE_TRIG_NONE;
353*16749429SEvalZero #else
354*16749429SEvalZero NRF_GPIOTE->CONFIG[i] = 0;
355*16749429SEvalZero NRF_GPIOTE->EVENTS_IN[i] = 0;
356*16749429SEvalZero #endif
357*16749429SEvalZero
358*16749429SEvalZero nrf_gpio_irqs[i].args = NULL;
359*16749429SEvalZero nrf_gpio_irqs[i].func = NULL;
360*16749429SEvalZero
361*16749429SEvalZero return ret;
362*16749429SEvalZero }
363*16749429SEvalZero
nrf_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint32_t enabled)364*16749429SEvalZero static rt_err_t nrf_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
365*16749429SEvalZero {
366*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
367*16749429SEvalZero NRF_GPIO_Type *nrf_gpio;
368*16749429SEvalZero int pin_index, sense_enabled = 0;
369*16749429SEvalZero #endif
370*16749429SEvalZero int i;
371*16749429SEvalZero
372*16749429SEvalZero i = nrf_gpio_find_pin(pin);
373*16749429SEvalZero if (i < 0)
374*16749429SEvalZero {
375*16749429SEvalZero return -RT_ERROR;
376*16749429SEvalZero }
377*16749429SEvalZero
378*16749429SEvalZero #if MCU_GPIO_USE_PORT_EVENT
379*16749429SEvalZero nrf_gpio = NRF_GPIO_PORT(pin);
380*16749429SEvalZero pin_index = NRF_GPIO_INDEX(pin);
381*16749429SEvalZero nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk;
382*16749429SEvalZero
383*16749429SEvalZero if (enabled)
384*16749429SEvalZero {
385*16749429SEvalZero /*
386*16749429SEvalZero * Always set initial SENSE to opposite of current pin state to avoid
387*16749429SEvalZero * triggering immediately
388*16749429SEvalZero */
389*16749429SEvalZero if (nrf_gpio->IN & (1 << pin_index))
390*16749429SEvalZero {
391*16749429SEvalZero nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;
392*16749429SEvalZero }
393*16749429SEvalZero else
394*16749429SEvalZero {
395*16749429SEvalZero nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos;
396*16749429SEvalZero }
397*16749429SEvalZero
398*16749429SEvalZero NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
399*16749429SEvalZero }
400*16749429SEvalZero else
401*16749429SEvalZero {
402*16749429SEvalZero for (i = 0; i < NRF_GPIO_MAX_IRQ; i++)
403*16749429SEvalZero {
404*16749429SEvalZero if (nrf_gpio_irqs[i].sense_trig != NRF_GPIO_SENSE_TRIG_NONE)
405*16749429SEvalZero {
406*16749429SEvalZero sense_enabled = 1;
407*16749429SEvalZero break;
408*16749429SEvalZero }
409*16749429SEvalZero }
410*16749429SEvalZero if (!sense_enabled)
411*16749429SEvalZero {
412*16749429SEvalZero NRF_GPIOTE->INTENCLR = GPIOTE_INTENCLR_PORT_Msk;
413*16749429SEvalZero }
414*16749429SEvalZero }
415*16749429SEvalZero #else
416*16749429SEvalZero if (enabled)
417*16749429SEvalZero {
418*16749429SEvalZero NRF_GPIOTE->EVENTS_IN[i] = 0;
419*16749429SEvalZero NRF_GPIOTE->INTENSET = 1 << i;
420*16749429SEvalZero }
421*16749429SEvalZero else
422*16749429SEvalZero {
423*16749429SEvalZero NRF_GPIOTE->INTENCLR = 1 << i;
424*16749429SEvalZero }
425*16749429SEvalZero
426*16749429SEvalZero #endif
427*16749429SEvalZero
428*16749429SEvalZero return RT_EOK;
429*16749429SEvalZero }
430*16749429SEvalZero
431*16749429SEvalZero const static struct rt_pin_ops nrf_pin_ops =
432*16749429SEvalZero {
433*16749429SEvalZero nrf_pin_mode,
434*16749429SEvalZero nrf_pin_write,
435*16749429SEvalZero nrf_pin_read,
436*16749429SEvalZero
437*16749429SEvalZero nrf_pin_attach_irq,
438*16749429SEvalZero nrf_pin_detach_irq,
439*16749429SEvalZero nrf_pin_irq_enable
440*16749429SEvalZero };
441*16749429SEvalZero
rt_hw_pin_init(void)442*16749429SEvalZero int rt_hw_pin_init(void)
443*16749429SEvalZero {
444*16749429SEvalZero rt_err_t ret = RT_EOK;
445*16749429SEvalZero
446*16749429SEvalZero ret = rt_device_pin_register("pin", &nrf_pin_ops, RT_NULL);
447*16749429SEvalZero
448*16749429SEvalZero return ret;
449*16749429SEvalZero }
450*16749429SEvalZero
451*16749429SEvalZero INIT_BOARD_EXPORT(rt_hw_pin_init);
452