Skip to content

Commit f177f11

Browse files
authored
Merge pull request RT-Thread#3835 from guohp1128/master
add nrf5x adc driver
2 parents 8f0be7c + 614f0a7 commit f177f11

File tree

5 files changed

+438
-1
lines changed

5 files changed

+438
-1
lines changed

Diff for: bsp/nrf5x/libraries/drivers/SConscript

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ if GetDepend(['BSP_USING_SPI']):
2222

2323
if GetDepend(['BSP_USING_GPIO']):
2424
src += ['drv_gpio.c']
25+
26+
if GetDepend(['BSP_USING_SAADC']):
27+
src += ['drv_adc.c']
2528

2629
if GetDepend(['BSP_USING_PWM']):
2730
src += ['drv_pwm.c']

Diff for: bsp/nrf5x/libraries/drivers/drv_adc.c

+261
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
/*
2+
* Copyright (c) 2006-2020, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-08-18 guohp1128 the first version
9+
*/
10+
11+
#include "drv_adc.h"
12+
13+
#ifdef RT_USING_ADC
14+
15+
struct rt_adc_device nrf5x_adc_device;
16+
17+
drv_nrfx_saadc_result_t results;
18+
nrf_saadc_value_t result_buff_cache[8];
19+
20+
static void nrf5x_saadc_event_hdr(nrfx_saadc_evt_t const * p_event)
21+
{
22+
uint8_t i,j;
23+
if(p_event->type == NRFX_SAADC_EVT_DONE)
24+
{
25+
j = 0;
26+
for(i = 0; i < 8; i++)
27+
{
28+
if(results.channels[i].channel_index == i)
29+
{
30+
results.result_buffer[i] = result_buff_cache[j];
31+
j ++;
32+
}
33+
}
34+
results.done = 1;
35+
}
36+
}
37+
38+
static uint32_t get_channels_mask(void)
39+
{
40+
uint8_t i;
41+
uint32_t mask = 0;
42+
for(i = 0; i < 8; i++)
43+
{
44+
if(results.channels[i].channel_index != 0xff)
45+
{
46+
mask |= (1 << results.channels[i].channel_index);
47+
}
48+
}
49+
return mask;
50+
}
51+
52+
static void set_channels(drv_nrfx_saadc_channel_t * channel)
53+
{
54+
uint8_t i;
55+
if(channel -> mode == NRF_SAADC_MODE_SINGLE_ENDED)
56+
{
57+
results.channels[channel->channel_num] = (nrfx_saadc_channel_t)NRFX_SAADC_DEFAULT_CHANNEL_SE(channel -> pin_p + 1, channel -> channel_num);
58+
}
59+
else if(channel -> mode == NRF_SAADC_MODE_DIFFERENTIAL)
60+
{
61+
results.channels[channel->channel_num] = (nrfx_saadc_channel_t)NRFX_SAADC_DEFAULT_CHANNEL_DIFFERENTIAL(channel -> pin_p + 1, channel -> pin_n + 1, channel -> channel_num);
62+
}
63+
results.channel_count = 0;
64+
for(i = 0; i < 8; i++)
65+
{
66+
if(results.channels[i].channel_index != 0xff)
67+
{
68+
results.channel_count ++;
69+
}
70+
}
71+
}
72+
73+
/* channel: 0-7 */
74+
static rt_err_t nrf5x_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
75+
{
76+
nrfx_err_t err_code = NRFX_SUCCESS;
77+
uint8_t i,j;
78+
79+
if (enabled)
80+
{
81+
RT_ASSERT(device != RT_NULL);
82+
RT_ASSERT(device->parent.user_data != RT_NULL);
83+
84+
drv_nrfx_saadc_channel_t * drv_channel_config = NULL;
85+
drv_channel_config = (drv_nrfx_saadc_channel_t *)device->parent.user_data;
86+
87+
set_channels(drv_channel_config);
88+
89+
nrfx_saadc_channel_t channels_cache[results.channel_count];
90+
91+
j = 0;
92+
for(i = 0; i < 8; i++)
93+
{
94+
if(results.channels[i].channel_index != 0xff)
95+
{
96+
channels_cache[j] = results.channels[i];
97+
j ++;
98+
}
99+
}
100+
101+
err_code = nrfx_saadc_channels_config(channels_cache,results.channel_count);
102+
103+
err_code = nrfx_saadc_simple_mode_set(get_channels_mask(),
104+
NRF_SAADC_RESOLUTION_12BIT,
105+
NRF_SAADC_OVERSAMPLE_DISABLED,
106+
nrf5x_saadc_event_hdr);
107+
108+
err_code = nrfx_saadc_buffer_set(result_buff_cache, results.channel_count);
109+
}
110+
else
111+
{
112+
results.channels[channel].channel_index = 0xff;
113+
114+
results.channel_count = 0;
115+
for(i = 0; i < 8; i++)
116+
{
117+
if(results.channels[i].channel_index != 0xff)
118+
{
119+
results.channel_count ++;
120+
}
121+
}
122+
123+
if(results.channel_count == 0)
124+
{
125+
nrfx_saadc_channel_t channels_cache[1];
126+
err_code = nrfx_saadc_channels_config(channels_cache, 0);
127+
return err_code;
128+
}
129+
else
130+
{
131+
nrfx_saadc_channel_t channels_cache[results.channel_count];
132+
133+
j = 0;
134+
for(i = 0; i < 8; i++)
135+
{
136+
if(results.channels[i].channel_index != 0xff)
137+
{
138+
channels_cache[j] = results.channels[i];
139+
j ++;
140+
}
141+
}
142+
143+
err_code = nrfx_saadc_channels_config(channels_cache,results.channel_count);
144+
145+
err_code = nrfx_saadc_simple_mode_set(get_channels_mask(),
146+
NRF_SAADC_RESOLUTION_12BIT,
147+
NRF_SAADC_OVERSAMPLE_DISABLED,
148+
nrf5x_saadc_event_hdr);
149+
150+
err_code = nrfx_saadc_buffer_set(result_buff_cache, results.channel_count);
151+
}
152+
}
153+
154+
return err_code;
155+
}
156+
157+
static rt_err_t nrf5x_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
158+
{
159+
nrfx_err_t err_code = NRFX_SUCCESS;
160+
161+
if (results.channels[channel].channel_index != 0xff)
162+
{
163+
results.done = 0;
164+
err_code = nrfx_saadc_mode_trigger();
165+
while(results.done == 0)
166+
{
167+
;
168+
}
169+
* value = results.result_buffer[channel];
170+
results.done = 0;
171+
}
172+
173+
return err_code;
174+
}
175+
176+
static const struct rt_adc_ops nrf5x_adc_ops =
177+
{
178+
.enabled = nrf5x_adc_enabled,
179+
.convert = nrf5x_get_adc_value,
180+
};
181+
182+
int rt_hw_adc_init(void)
183+
{
184+
int result = RT_EOK;
185+
uint8_t i;
186+
char name_buf[6] = {'S', 'A', 'A', 'D', 'C', 0};
187+
188+
for(i = 0; i < 8; i++)
189+
{
190+
results.channels[i].channel_index = 0xff;
191+
results.result_buffer[i] = 0;
192+
results.channel_count = 0;
193+
results.done = 0;
194+
}
195+
196+
/* initializing SAADC interrupt priority */
197+
if (nrfx_saadc_init(NRFX_SAADC_CONFIG_IRQ_PRIORITY) != NRFX_SUCCESS)
198+
{
199+
rt_kprintf("%s init failed", name_buf);
200+
rt_kprintf("The driver is already initialized.");
201+
result = -RT_ERROR;
202+
}
203+
else
204+
{
205+
/* register ADC device */
206+
if (rt_hw_adc_register(&nrf5x_adc_device, name_buf, &nrf5x_adc_ops, nrf5x_adc_device.parent.user_data) == RT_EOK)
207+
{
208+
rt_kprintf("%s init success", name_buf);
209+
}
210+
else
211+
{
212+
rt_kprintf("%s register failed", name_buf);
213+
result = -RT_ERROR;
214+
}
215+
}
216+
return result;
217+
}
218+
INIT_BOARD_EXPORT(rt_hw_adc_init);
219+
220+
221+
/*test saadc*/
222+
#include <drv_adc.h>
223+
224+
void saadc_sample(void)
225+
{
226+
drv_nrfx_saadc_channel_t channel_config;
227+
rt_uint32_t result;
228+
229+
rt_adc_device_t adc_dev;
230+
adc_dev = (rt_adc_device_t)rt_device_find("SAADC");
231+
adc_dev->parent.user_data = &channel_config;
232+
233+
channel_config = (drv_nrfx_saadc_channel_t){.mode = 0, .pin_p = 1, .pin_n = 1, .channel_num = 0};
234+
rt_adc_enable(adc_dev, channel_config.channel_num);
235+
236+
channel_config = (drv_nrfx_saadc_channel_t){.mode = 0, .pin_p = 2, .pin_n = 1, .channel_num = 1};
237+
rt_adc_enable(adc_dev, channel_config.channel_num);
238+
239+
channel_config = (drv_nrfx_saadc_channel_t){.mode = 0, .pin_p = 7, .pin_n = 1, .channel_num = 5};
240+
rt_adc_enable(adc_dev, channel_config.channel_num);
241+
242+
int count = 1;
243+
while(count++)
244+
{
245+
result = rt_adc_read(adc_dev, 0);
246+
rt_kprintf("saadc channel 0 value = %d, ",result);
247+
248+
result = rt_adc_read(adc_dev, 1);
249+
rt_kprintf("saadc channel 1 value = %d, ",result);
250+
251+
result = rt_adc_read(adc_dev, 5);
252+
rt_kprintf("saadc channel 5 value = %d",result);
253+
254+
rt_kprintf("\r\n");
255+
rt_thread_mdelay(1000);
256+
}
257+
}
258+
MSH_CMD_EXPORT(saadc_sample, saadc sample);
259+
260+
#endif /* RT_USING_ADC */
261+

Diff for: bsp/nrf5x/libraries/drivers/drv_adc.h

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2006-2020, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-08-18 guohp1128 the first version
9+
*/
10+
11+
#ifndef __DRV_ADC_H__
12+
#define __DRV_ADC_H__
13+
14+
#include <board.h>
15+
#include "rtdevice.h"
16+
#include <hal/nrf_saadc.h>
17+
#include <drivers/include/nrfx_saadc.h>
18+
19+
/*
20+
previous definition in application
21+
22+
set single-ended mode or differential mode.
23+
selection ADC input pin, and config the number of Channel.
24+
25+
mode: 0 single-ended mode,1 differential mode
26+
pin_p: 0-7
27+
pin_n: 0-7,if single-ended mode, pin_n invalid
28+
channel_num: 0-7
29+
*/
30+
typedef struct
31+
{
32+
nrf_saadc_mode_t mode; ///< SAADC mode. Single-ended or differential.
33+
uint8_t pin_p; ///< Input positive pin selection.
34+
uint8_t pin_n; ///< Input negative pin selection.
35+
uint8_t channel_num; ///< Channel number.
36+
} drv_nrfx_saadc_channel_t;
37+
38+
typedef struct
39+
{
40+
nrfx_saadc_channel_t channels[8];
41+
uint8_t channel_count;
42+
nrf_saadc_value_t result_buffer[8];
43+
uint8_t done;
44+
} drv_nrfx_saadc_result_t;
45+
46+
#endif /* __DRV_ADC_H__ */

0 commit comments

Comments
 (0)