Skip to content

Commit 02ac2b7

Browse files
authored
Merge pull request #3706 from guohp1128/guohp
提交nrf5x的gpio驱动
2 parents 87999c4 + 9f2c1ce commit 02ac2b7

File tree

6 files changed

+444
-12
lines changed

6 files changed

+444
-12
lines changed
+375
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
/*
2+
* Copyright (c) 2006-2018, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-06-16 guohp1128 first version
9+
*/
10+
11+
#include "drv_gpio.h"
12+
13+
#ifdef RT_USING_PIN
14+
15+
static const struct pin_index pins[] =
16+
{
17+
__NRF5X_PIN(0 , 0, 0 ),
18+
__NRF5X_PIN(1 , 0, 1 ),
19+
__NRF5X_PIN(2 , 0, 2 ),
20+
__NRF5X_PIN(3 , 0, 3 ),
21+
__NRF5X_PIN(4 , 0, 4 ),
22+
__NRF5X_PIN(5 , 0, 5 ),
23+
__NRF5X_PIN(6 , 0, 6 ),
24+
__NRF5X_PIN(7 , 0, 7 ),
25+
__NRF5X_PIN(8 , 0, 8 ),
26+
__NRF5X_PIN(9 , 0, 9 ),
27+
__NRF5X_PIN(10, 0, 10),
28+
__NRF5X_PIN(11, 0, 11),
29+
__NRF5X_PIN(12, 0, 12),
30+
__NRF5X_PIN(13, 0, 13),
31+
__NRF5X_PIN(14, 0, 14),
32+
__NRF5X_PIN(15, 0, 15),
33+
__NRF5X_PIN(16, 0, 16),
34+
__NRF5X_PIN(17, 0, 17),
35+
__NRF5X_PIN(18, 0, 18),
36+
__NRF5X_PIN(19, 0, 19),
37+
__NRF5X_PIN(20, 0, 20),
38+
__NRF5X_PIN(21, 0, 21),
39+
__NRF5X_PIN(22, 0, 22),
40+
__NRF5X_PIN(23, 0, 23),
41+
__NRF5X_PIN(24, 0, 24),
42+
__NRF5X_PIN(25, 0, 25),
43+
__NRF5X_PIN(26, 0, 26),
44+
__NRF5X_PIN(27, 0, 27),
45+
__NRF5X_PIN(28, 0, 28),
46+
__NRF5X_PIN(29, 0, 29),
47+
__NRF5X_PIN(30, 0, 30),
48+
__NRF5X_PIN(31, 0, 31),
49+
__NRF5X_PIN(32, 1, 0 ),
50+
__NRF5X_PIN(33, 1, 1 ),
51+
__NRF5X_PIN(34, 1, 2 ),
52+
__NRF5X_PIN(35, 1, 3 ),
53+
__NRF5X_PIN(36, 1, 4 ),
54+
__NRF5X_PIN(37, 1, 5 ),
55+
__NRF5X_PIN(38, 1, 6 ),
56+
__NRF5X_PIN(39, 1, 7 ),
57+
__NRF5X_PIN(40, 1, 8 ),
58+
__NRF5X_PIN(41, 1, 9 ),
59+
__NRF5X_PIN(42, 1, 10),
60+
__NRF5X_PIN(43, 1, 11),
61+
__NRF5X_PIN(44, 1, 12),
62+
__NRF5X_PIN(45, 1, 13),
63+
__NRF5X_PIN(46, 1, 14),
64+
__NRF5X_PIN(47, 1, 15),
65+
};
66+
67+
/* EVENTS_IN[n](n=0..7) and EVENTS_PORT */
68+
static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
69+
{
70+
{-1, 0, RT_NULL, RT_NULL},
71+
{-1, 0, RT_NULL, RT_NULL},
72+
{-1, 0, RT_NULL, RT_NULL},
73+
{-1, 0, RT_NULL, RT_NULL},
74+
{-1, 0, RT_NULL, RT_NULL},
75+
{-1, 0, RT_NULL, RT_NULL},
76+
{-1, 0, RT_NULL, RT_NULL},
77+
{-1, 0, RT_NULL, RT_NULL},
78+
{-1, 0, RT_NULL, RT_NULL},
79+
};
80+
81+
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
82+
83+
/* pin: the number of pins */
84+
static const struct pin_index *get_pin(uint8_t pin)
85+
{
86+
const struct pin_index *index;
87+
88+
if (pin < ITEM_NUM(pins))
89+
{
90+
index = &pins[pin];
91+
if (index->index == -1)
92+
index = RT_NULL;
93+
}
94+
else
95+
{
96+
index = RT_NULL;
97+
}
98+
99+
return index;
100+
};
101+
102+
static void nrf5x_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
103+
{
104+
const struct pin_index *index;
105+
106+
index = get_pin(pin);
107+
if (index == RT_NULL)
108+
{
109+
return;
110+
}
111+
112+
nrf_gpio_pin_write(pin, value);
113+
}
114+
115+
static int nrf5x_pin_read(rt_device_t dev, rt_base_t pin)
116+
{
117+
int value;
118+
const struct pin_index *index;
119+
120+
value = PIN_LOW;
121+
122+
index = get_pin(pin);
123+
if (index == RT_NULL)
124+
{
125+
return value;
126+
}
127+
128+
value = nrf_gpio_pin_read(pin);
129+
130+
return value;
131+
}
132+
133+
static void nrf5x_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
134+
{
135+
const struct pin_index *index;
136+
137+
index = get_pin(pin);
138+
if (index == RT_NULL)
139+
{
140+
return;
141+
}
142+
143+
if (mode == PIN_MODE_OUTPUT)
144+
{
145+
/* output setting */
146+
nrf_gpio_cfg_output(pin);
147+
}
148+
else if (mode == PIN_MODE_INPUT)
149+
{
150+
/* input setting: not pull. */
151+
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);
152+
}
153+
else if (mode == PIN_MODE_INPUT_PULLUP)
154+
{
155+
/* input setting: pull up. */
156+
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLUP);
157+
}
158+
else if (mode == PIN_MODE_INPUT_PULLDOWN)
159+
{
160+
/* input setting: pull down. */
161+
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLDOWN);
162+
}
163+
else if (mode == PIN_MODE_OUTPUT_OD)
164+
{
165+
/* output setting: od. */
166+
nrf_gpio_cfg(
167+
pin,
168+
NRF_GPIO_PIN_DIR_OUTPUT,
169+
NRF_GPIO_PIN_INPUT_DISCONNECT,
170+
NRF_GPIO_PIN_NOPULL,
171+
NRF_GPIO_PIN_S0D1,
172+
NRF_GPIO_PIN_NOSENSE);
173+
}
174+
}
175+
176+
static void pin_irq_hdr(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
177+
{
178+
int i;
179+
int irq_quantity;
180+
181+
irq_quantity = ITEM_NUM(pin_irq_hdr_tab);
182+
for(i = 0; i < irq_quantity; i++)
183+
{
184+
if(pin_irq_hdr_tab[i].pin == pin)
185+
{
186+
pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
187+
}
188+
}
189+
}
190+
191+
/* args = true : hi_accuracy(IN_EVENT)
192+
* args = false: lo_accuracy(PORT_EVENT)
193+
*/
194+
static rt_err_t nrf5x_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
195+
rt_uint32_t mode, void (*hdr)(void *args), void *args)
196+
{
197+
const struct pin_index *index;
198+
rt_int32_t irqindex = -1;
199+
rt_base_t level;
200+
nrfx_err_t err_code;
201+
int i;
202+
int irq_quantity;
203+
204+
index = get_pin(pin);
205+
if (index == RT_NULL)
206+
{
207+
return RT_ENOSYS;
208+
}
209+
210+
irq_quantity = ITEM_NUM(pin_irq_hdr_tab);
211+
for(i = 0; i < irq_quantity; i++)
212+
{
213+
if(pin_irq_hdr_tab[i].pin != -1)
214+
{
215+
irqindex = -1;
216+
continue;
217+
}
218+
else
219+
{
220+
irqindex = i;
221+
break;
222+
}
223+
}
224+
if(irqindex == -1)
225+
{
226+
return RT_ENOMEM;
227+
}
228+
229+
level = rt_hw_interrupt_disable();
230+
pin_irq_hdr_tab[irqindex].pin = pin;
231+
pin_irq_hdr_tab[irqindex].hdr = hdr;
232+
pin_irq_hdr_tab[irqindex].mode = mode;
233+
pin_irq_hdr_tab[irqindex].args = args;
234+
235+
if(mode == PIN_IRQ_MODE_RISING)
236+
{
237+
nrfx_gpiote_in_config_t inConfig = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(args);
238+
inConfig.pull = NRF_GPIO_PIN_PULLDOWN;
239+
err_code = nrfx_gpiote_in_init(pin, &inConfig, pin_irq_hdr);
240+
}
241+
242+
else if(mode == PIN_IRQ_MODE_FALLING)
243+
{
244+
nrfx_gpiote_in_config_t inConfig = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(args);
245+
inConfig.pull = NRF_GPIO_PIN_PULLUP;
246+
err_code = nrfx_gpiote_in_init(pin, &inConfig, pin_irq_hdr);
247+
}
248+
249+
else if(mode == PIN_IRQ_MODE_RISING_FALLING)
250+
{
251+
nrfx_gpiote_in_config_t inConfig = NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(args);
252+
inConfig.pull = NRF_GPIO_PIN_PULLUP;
253+
err_code = nrfx_gpiote_in_init(pin, &inConfig, pin_irq_hdr);
254+
}
255+
256+
rt_hw_interrupt_enable(level);
257+
258+
switch(err_code)
259+
{
260+
case NRFX_ERROR_BUSY:
261+
return RT_EBUSY;
262+
case NRFX_SUCCESS:
263+
return RT_EOK;
264+
case NRFX_ERROR_NO_MEM:
265+
return RT_ENOMEM;
266+
default:
267+
return RT_ERROR;
268+
}
269+
}
270+
271+
static rt_err_t nrf5x_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
272+
{
273+
const struct pin_index *index;
274+
rt_base_t level;
275+
int i;
276+
int irq_quantity;
277+
278+
index = get_pin(pin);
279+
if (index == RT_NULL)
280+
{
281+
return RT_ENOSYS;
282+
}
283+
284+
irq_quantity = ITEM_NUM(pin_irq_hdr_tab);
285+
for(i = 0; i < irq_quantity; i++)
286+
{
287+
if(pin_irq_hdr_tab[i].pin == pin)
288+
{
289+
level = rt_hw_interrupt_disable();
290+
pin_irq_hdr_tab[i].pin = -1;
291+
pin_irq_hdr_tab[i].hdr = RT_NULL;
292+
pin_irq_hdr_tab[i].mode = 0;
293+
pin_irq_hdr_tab[i].args = RT_NULL;
294+
nrfx_gpiote_in_uninit(pin);
295+
rt_hw_interrupt_enable(level);
296+
break;
297+
}
298+
}
299+
if(i >= irq_quantity)
300+
{
301+
return RT_ENOSYS;
302+
}
303+
return RT_EOK;
304+
}
305+
306+
static rt_err_t nrf5x_pin_irq_enable(struct rt_device *device, rt_base_t pin,
307+
rt_uint32_t enabled)
308+
{
309+
const struct pin_index *index;
310+
rt_base_t level;
311+
int i;
312+
int irq_quantity;
313+
314+
index = get_pin(pin);
315+
if (index == RT_NULL)
316+
{
317+
return RT_ENOSYS;
318+
}
319+
320+
irq_quantity = ITEM_NUM(pin_irq_hdr_tab);
321+
for(i = 0; i < irq_quantity; i++)
322+
{
323+
if(pin_irq_hdr_tab[i].pin == pin)
324+
{
325+
level = rt_hw_interrupt_disable();
326+
if(enabled == PIN_IRQ_ENABLE)
327+
{
328+
nrfx_gpiote_in_event_enable(pin,enabled);
329+
}
330+
else if(enabled == PIN_IRQ_DISABLE)
331+
{
332+
nrfx_gpiote_in_event_disable(pin);
333+
}
334+
rt_hw_interrupt_enable(level);
335+
break;
336+
}
337+
}
338+
339+
if(i >= irq_quantity)
340+
{
341+
return RT_ENOSYS;
342+
}
343+
return RT_EOK;
344+
}
345+
346+
const static struct rt_pin_ops _nrf5x_pin_ops =
347+
{
348+
nrf5x_pin_mode,
349+
nrf5x_pin_write,
350+
nrf5x_pin_read,
351+
nrf5x_pin_attach_irq,
352+
nrf5x_pin_dettach_irq,
353+
nrf5x_pin_irq_enable,
354+
};
355+
356+
int rt_hw_pin_init(void)
357+
{
358+
nrfx_err_t err_code;
359+
360+
err_code = (nrfx_err_t)rt_device_pin_register("pin", &_nrf5x_pin_ops, RT_NULL);
361+
err_code = nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY);
362+
363+
switch(err_code)
364+
{
365+
case NRFX_ERROR_INVALID_STATE:
366+
return RT_EINVAL;
367+
case NRFX_SUCCESS:
368+
return RT_EOK;
369+
default:
370+
return RT_ERROR;;
371+
}
372+
373+
}
374+
375+
#endif /* RT_USING_PIN */

0 commit comments

Comments
 (0)