Skip to content

Commit 1d96089

Browse files
committed
提交nrf5x的gpio驱动
1 parent 6bcf52b commit 1d96089

File tree

6 files changed

+453
-17
lines changed

6 files changed

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

0 commit comments

Comments
 (0)