Skip to content

Commit 5c1396c

Browse files
Thinh Le Congduynguyenxa
authored andcommitted
drivers: adc: Adding ADC 16-bit driver support for board EK-RA2A1
Adding ADC 16-bit driver support for board EK-RA2A1 Signed-off-by: Thinh Le Cong <[email protected]>
1 parent 4eb457c commit 5c1396c

File tree

2 files changed

+213
-33
lines changed

2 files changed

+213
-33
lines changed

drivers/adc/adc_renesas_ra.c

Lines changed: 183 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,36 @@
1414
#include <zephyr/sys/util_internal.h>
1515
#include <instances/r_adc.h>
1616

17+
#include "rp_adc.h"
18+
1719
#include <zephyr/irq.h>
1820

1921
LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL);
2022

2123
#define ADC_CONTEXT_USES_KERNEL_TIMER
2224
#include "adc_context.h"
2325

24-
#define ADC_RA_MAX_RESOLUTION 12
25-
#define ADC_AVERAGE_1 ADC_ADD_OFF
26-
#define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO
27-
#define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR
28-
#define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT
29-
#define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN
26+
#define ADC_AVERAGE_1 ADC_ADD_OFF
27+
#define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO
28+
#define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR
29+
#define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT
30+
#define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN
31+
32+
#define ADC_RES_12 ADC_RESOLUTION_12_BIT
33+
#define ADC_RES_16 ADC_RESOLUTION_16_BIT
3034

31-
void adc_scan_end_isr(void);
35+
#define ADC_VARIANT_ADC12 12
36+
#define ADC_VARIANT_ADC16 16
37+
38+
#define ADC_CHANNEL_BIT_MASK (0x01U)
39+
40+
enum ra_adc_reference {
41+
RA_ADC_REF_VDD,
42+
RA_ADC_REF_INTERNAL,
43+
RA_ADC_REF_EXTERNAL,
44+
};
45+
46+
extern void adc_scan_end_isr(void);
3247

3348
/**
3449
* @brief RA ADC config
@@ -40,6 +55,14 @@ struct adc_ra_config {
4055
uint32_t channel_available_mask;
4156
/** pinctrl configs */
4257
const struct pinctrl_dev_config *pcfg;
58+
/** Variant support ADC16 or ADC12 */
59+
uint8_t variant;
60+
/** Mapping reference voltage */
61+
uint32_t reference;
62+
/** Resolution support */
63+
uint8_t resolution;
64+
/** Sampling time in nanoseconds */
65+
uint32_t sampling_time_ns;
4366
/** function pointer to irq setup */
4467
void (*irq_configure)(void);
4568
};
@@ -66,8 +89,20 @@ struct adc_ra_data {
6689
uint32_t channels;
6790
/** Buffer id */
6891
uint16_t buf_id;
92+
/** Calibration process semaphore */
93+
struct k_sem calibrate_sem;
6994
};
7095

96+
static adc_sample_state_reg_t map_channel_to_sample_state_reg(uint8_t channel_id)
97+
{
98+
if (channel_id <= 15) {
99+
return (adc_sample_state_reg_t)channel_id;
100+
}
101+
102+
/* Channel IDs 16–31 share the same sample state register */
103+
return ADC_SAMPLE_STATE_CHANNEL_16_TO_31;
104+
}
105+
71106
/**
72107
* @brief Setup channels before starting to scan ADC
73108
*
@@ -83,6 +118,8 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
83118
fsp_err_t fsp_err = FSP_SUCCESS;
84119
struct adc_ra_data *data = dev->data;
85120
const struct adc_ra_config *config = dev->config;
121+
adc_sample_state_t sample_state;
122+
uint32_t sample_states = 0;
86123

87124
if (!((config->channel_available_mask & (1 << channel_cfg->channel_id)) != 0)) {
88125
LOG_ERR("unsupported channel id '%d'", channel_cfg->channel_id);
@@ -104,6 +141,18 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
104141
return -EINVAL;
105142
}
106143

144+
fsp_err = RP_ADC_SampleStateCalculation(config->sampling_time_ns, &sample_states);
145+
if (FSP_SUCCESS != fsp_err) {
146+
return -ENOTSUP;
147+
}
148+
149+
sample_state.reg_id = map_channel_to_sample_state_reg(channel_cfg->channel_id);
150+
sample_state.num_states = sample_states;
151+
fsp_err = R_ADC_SampleStateCountSet(&data->adc, &sample_state);
152+
if (FSP_SUCCESS != fsp_err) {
153+
return -ENOTSUP;
154+
}
155+
107156
data->f_channel_cfg.scan_mask |= (1U << channel_cfg->channel_id);
108157
/* Configure ADC channel specific settings */
109158
fsp_err = R_ADC_ScanCfg(&data->adc, &data->f_channel_cfg);
@@ -114,32 +163,86 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
114163
return 0;
115164
}
116165

117-
/**
118-
* Interrupt handler
119-
*/
120-
static void adc_ra_isr(const struct device *dev)
166+
static void renesas_ra_adc_callback(adc_callback_args_t *p_args)
121167
{
168+
const struct device *dev = p_args->p_context;
122169
struct adc_ra_data *data = dev->data;
123170
fsp_err_t fsp_err = FSP_SUCCESS;
124171
adc_channel_t channel_id = 0;
125172
uint32_t channels = 0;
126173
int16_t *sample_buffer = (int16_t *)data->buf;
127174

128-
channels = data->channels;
129-
for (channel_id = 0; channels > 0; channel_id++) {
130-
/* Check if it is right channel id */
131-
if ((channels & 0x01) != 0) {
132-
fsp_err = R_ADC_Read(&data->adc, channel_id, &sample_buffer[data->buf_id]);
133-
if (FSP_SUCCESS != fsp_err) {
134-
break;
175+
if (p_args->event == ADC_EVENT_SCAN_COMPLETE) {
176+
channels = data->channels;
177+
for (channel_id = 0; channels > 0; channel_id++) {
178+
/* Check if it is right channel id */
179+
if ((channels & ADC_CHANNEL_BIT_MASK) != 0) {
180+
fsp_err = R_ADC_Read(&data->adc, channel_id,
181+
&sample_buffer[data->buf_id]);
182+
if (FSP_SUCCESS != fsp_err) {
183+
break;
184+
}
185+
/* Do not return negative value for single-ended configuration */
186+
if (sample_buffer[data->buf_id] < 0) {
187+
sample_buffer[data->buf_id] = 0;
188+
}
189+
data->buf_id = data->buf_id + 1;
190+
191+
fsp_err = R_ADC_ScanStop(&data->adc);
192+
if (FSP_SUCCESS != fsp_err) {
193+
break;
194+
}
135195
}
136-
data->buf_id = data->buf_id + 1;
196+
197+
channels = channels >> 1;
137198
}
199+
adc_context_on_sampling_done(&data->ctx, dev);
200+
}
138201

139-
channels = channels >> 1;
202+
else if (p_args->event == ADC_EVENT_CALIBRATION_COMPLETE) {
203+
k_sem_give(&data->calibrate_sem);
204+
}
205+
}
206+
207+
/**
208+
* Voltage reference covert handler
209+
*/
210+
static int adc_map_vref(const struct adc_ra_config *cfg, adc_extended_cfg_t *extend)
211+
{
212+
switch (cfg->variant) {
213+
case ADC_VARIANT_ADC16:
214+
switch (cfg->reference) {
215+
case RA_ADC_REF_INTERNAL:
216+
extend->adc_vref_control = ADC_VREF_CONTROL_2_5V_OUTPUT;
217+
return 0;
218+
case RA_ADC_REF_EXTERNAL:
219+
extend->adc_vref_control = ADC_VREF_CONTROL_VREFH;
220+
return 0;
221+
default:
222+
LOG_ERR("Reference %d not supported", cfg->reference);
223+
return -ENOTSUP;
224+
}
225+
226+
case ADC_VARIANT_ADC12:
227+
switch (cfg->reference) {
228+
case RA_ADC_REF_VDD:
229+
extend->adc_vref_control = ADC_VREF_CONTROL_AVCC0_AVSS0;
230+
return 0;
231+
case RA_ADC_REF_EXTERNAL:
232+
extend->adc_vref_control = ADC_VREF_CONTROL_VREFH0_VREFL0;
233+
return 0;
234+
case RA_ADC_REF_INTERNAL:
235+
extend->adc_vref_control = ADC_VREF_CONTROL_IVREF_AVSS0;
236+
return 0;
237+
default:
238+
LOG_ERR("Reference %d not supported", cfg->reference);
239+
return -ENOTSUP;
240+
}
241+
242+
default:
243+
LOG_ERR("Variant %d not supported", cfg->variant);
244+
return -ENOTSUP;
140245
}
141-
adc_scan_end_isr();
142-
adc_context_on_sampling_done(&data->ctx, dev);
143246
}
144247

145248
/**
@@ -187,9 +290,18 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
187290
{
188291
const struct adc_ra_config *config = dev->config;
189292
struct adc_ra_data *data = dev->data;
293+
fsp_err_t fsp_err = FSP_SUCCESS;
190294
int err;
191295

192-
if (sequence->resolution > ADC_RA_MAX_RESOLUTION || sequence->resolution == 0) {
296+
if (config->variant == ADC_VARIANT_ADC16) {
297+
uint8_t expected = config->resolution - 1;
298+
299+
if (sequence->resolution != expected) {
300+
LOG_ERR("unsupported resolution %d for single-ended mode, must be %d",
301+
sequence->resolution, expected);
302+
return -ENOTSUP;
303+
}
304+
} else if (sequence->resolution != config->resolution) {
193305
LOG_ERR("unsupported resolution %d", sequence->resolution);
194306
return -ENOTSUP;
195307
}
@@ -207,6 +319,21 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
207319

208320
data->buf_id = 0;
209321
data->buf = sequence->buffer;
322+
323+
if (config->variant == ADC_VARIANT_ADC16) {
324+
if (!sequence->calibrate) {
325+
return -ENOTSUP;
326+
}
327+
328+
/* Start calibration process */
329+
k_sem_reset(&data->calibrate_sem);
330+
fsp_err = R_ADC_Calibrate(&data->adc, NULL);
331+
if (FSP_SUCCESS != fsp_err) {
332+
return -EIO;
333+
}
334+
k_sem_take(&data->calibrate_sem, K_FOREVER);
335+
}
336+
210337
adc_context_start_read(&data->ctx, sequence);
211338

212339
adc_context_wait_for_completion(&data->ctx);
@@ -293,12 +420,21 @@ static int adc_ra_init(const struct device *dev)
293420
struct adc_ra_data *data = dev->data;
294421
int ret;
295422
fsp_err_t fsp_err = FSP_SUCCESS;
423+
adc_extended_cfg_t *extend = (adc_extended_cfg_t *)data->f_config.p_extend;
424+
425+
/* Override reference voltage */
426+
ret = adc_map_vref(config, extend);
427+
if (ret < 0) {
428+
return ret;
429+
}
296430

297431
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
298432
if (ret < 0) {
299433
return ret;
300434
}
301435

436+
k_sem_init(&data->calibrate_sem, 0, 1);
437+
302438
/* Open ADC module */
303439
fsp_err = R_ADC_Open(&data->adc, &data->f_config);
304440
if (FSP_SUCCESS != fsp_err) {
@@ -307,19 +443,29 @@ static int adc_ra_init(const struct device *dev)
307443

308444
config->irq_configure();
309445

446+
if (config->variant == ADC_VARIANT_ADC16) {
447+
/* Start calibration process */
448+
fsp_err = R_ADC_Calibrate(&data->adc, NULL);
449+
if (FSP_SUCCESS != fsp_err) {
450+
return -EIO;
451+
}
452+
k_sem_take(&data->calibrate_sem, K_FOREVER);
453+
}
454+
310455
adc_context_unlock_unconditionally(&data->ctx);
311456
return 0;
312457
}
313458

314-
#define EVENT_ADC_SCAN_END(idx) BSP_PRV_IELS_ENUM(CONCAT(EVENT_ADC, idx, _SCAN_END))
459+
#define EVENT_ADC_SCAN_END(unit) BSP_PRV_IELS_ENUM(CONCAT(EVENT_ADC, unit, _SCAN_END))
315460

316461
#define IRQ_CONFIGURE_FUNC(idx) \
317462
static void adc_ra_configure_func_##idx(void) \
318463
{ \
319-
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = EVENT_ADC_SCAN_END(idx); \
464+
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = \
465+
EVENT_ADC_SCAN_END(DT_PROP(DT_DRV_INST(idx), unit)); \
320466
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
321-
DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_ra_isr, \
322-
DEVICE_DT_INST_GET(idx), 0); \
467+
DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_scan_end_isr, NULL, \
468+
0); \
323469
irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \
324470
}
325471

@@ -328,7 +474,7 @@ static int adc_ra_init(const struct device *dev)
328474
#define ADC_RA_INIT(idx) \
329475
IRQ_CONFIGURE_FUNC(idx) \
330476
PINCTRL_DT_INST_DEFINE(idx); \
331-
static const adc_extended_cfg_t g_adc_cfg_extend_##idx = { \
477+
static adc_extended_cfg_t g_adc_cfg_extend_##idx = { \
332478
.add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \
333479
.clearing = ADC_CLEAR_AFTER_READ_ON, \
334480
.trigger_group_b = ADC_START_SOURCE_DISABLED, \
@@ -345,9 +491,13 @@ static int adc_ra_init(const struct device *dev)
345491
.channel_setup = adc_ra_channel_setup, \
346492
.read = adc_ra_read, \
347493
.ref_internal = DT_INST_PROP(idx, vref_mv), \
348-
IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
494+
IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
349495
static const struct adc_ra_config adc_ra_config_##idx = { \
350496
.channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \
497+
.variant = DT_INST_PROP(idx, variant), \
498+
.reference = DT_INST_ENUM_IDX(idx, reference), \
499+
.resolution = DT_INST_PROP(idx, variant), \
500+
.sampling_time_ns = DT_INST_PROP_OR(idx, sampling_time_ns, UNSPECIFIED), \
351501
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
352502
IRQ_CONFIGURE_DEFINE(idx), \
353503
}; \
@@ -358,13 +508,13 @@ static int adc_ra_init(const struct device *dev)
358508
.dev = DEVICE_DT_INST_GET(idx), \
359509
.f_config = \
360510
{ \
361-
.unit = idx, \
511+
.unit = DT_INST_PROP(idx, unit), \
362512
.mode = ADC_MODE_SINGLE_SCAN, \
363-
.resolution = ADC_RESOLUTION_12_BIT, \
513+
.resolution = UTIL_CAT(ADC_RES_, DT_INST_PROP(idx, variant)), \
364514
.alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \
365515
.trigger = 0, \
366-
.p_callback = NULL, \
367-
.p_context = NULL, \
516+
.p_callback = renesas_ra_adc_callback, \
517+
.p_context = (void *)DEVICE_DT_GET(DT_DRV_INST(idx)), \
368518
.p_extend = &g_adc_cfg_extend_##idx, \
369519
.scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
370520
.scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \

dts/bindings/adc/renesas,ra-adc.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,35 @@ properties:
3232
The ADC module will take multiple samples of an analog signal
3333
and averages them to reduce noise and enhance accuracy
3434

35+
reference:
36+
type: string
37+
enum:
38+
- vdd
39+
- internal
40+
- external
41+
default: vdd
42+
description: |
43+
ADC reference voltage source:
44+
- vdd: use VDD as reference
45+
- internal: use internal reference
46+
- external: use external reference
47+
48+
variant:
49+
type: int
50+
enum: [12, 16]
51+
default: 12
52+
description: Select ADC variant for RA SoC
53+
54+
sampling-time-ns:
55+
type: int
56+
description: |
57+
Sampling time in nanoseconds, i.e. the duration the ADC input
58+
signal is sampled before conversion starts.
59+
60+
unit:
61+
type: int
62+
required: true
63+
description: Indicates the unit number of the ADC device.
64+
3565
io-channel-cells:
3666
- input

0 commit comments

Comments
 (0)