Skip to content

Commit e80e9f4

Browse files
Thinh Le Congduynguyenxa
authored andcommitted
drivers: adc: Adding ADC 16-bit driver support for board EK-RA2A1
Adding ADC 16-bit driver compatible to support ADC16 on RA2A1 Signed-off-by: Thinh Le Cong <[email protected]>
1 parent 95e7652 commit e80e9f4

File tree

5 files changed

+230
-43
lines changed

5 files changed

+230
-43
lines changed

drivers/adc/Kconfig.renesas_ra

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
config ADC_RENESAS_RA
77
bool "Renesas RA ADC"
88
default y
9-
depends on DT_HAS_RENESAS_RA_ADC_ENABLED
9+
depends on DT_HAS_RENESAS_RA_ADC12_ENABLED || DT_HAS_RENESAS_RA_ADC16_ENABLED
1010
select USE_RA_FSP_ADC
1111
select PINCTRL
1212
help

drivers/adc/adc_renesas_ra.c

Lines changed: 188 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#define DT_DRV_COMPAT renesas_ra_adc
8-
97
#include <zephyr/drivers/adc.h>
108
#include <zephyr/drivers/clock_control.h>
119
#include <zephyr/drivers/pinctrl.h>
@@ -14,21 +12,33 @@
1412
#include <zephyr/sys/util_internal.h>
1513
#include <instances/r_adc.h>
1614

15+
#include "rp_adc.h"
16+
1717
#include <zephyr/irq.h>
1818

1919
LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL);
2020

2121
#define ADC_CONTEXT_USES_KERNEL_TIMER
2222
#include "adc_context.h"
2323

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
24+
#define ADC_AVERAGE_1 ADC_ADD_OFF
25+
#define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO
26+
#define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR
27+
#define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT
28+
#define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN
3029

31-
void adc_scan_end_isr(void);
30+
#define ADC_VARIANT_ADC12 12
31+
#define ADC_VARIANT_ADC16 16
32+
33+
#define ADC_CHANNEL_BIT_MASK (0x01U)
34+
35+
enum ra_adc_reference {
36+
RA_ADC_REF_VDD,
37+
RA_ADC_REF_INTERNAL,
38+
RA_ADC_REF_EXTERNAL,
39+
};
40+
41+
extern void adc_scan_end_isr(void);
3242

3343
/**
3444
* @brief RA ADC config
@@ -40,6 +50,14 @@ struct adc_ra_config {
4050
uint32_t channel_available_mask;
4151
/** pinctrl configs */
4252
const struct pinctrl_dev_config *pcfg;
53+
/** Variant support ADC16 or ADC12 */
54+
uint8_t variant;
55+
/** Mapping reference voltage */
56+
uint32_t reference;
57+
/** Resolution support */
58+
uint8_t resolution;
59+
/** Sampling time in nanoseconds */
60+
uint32_t sampling_time_ns;
4361
/** function pointer to irq setup */
4462
void (*irq_configure)(void);
4563
};
@@ -66,8 +84,20 @@ struct adc_ra_data {
6684
uint32_t channels;
6785
/** Buffer id */
6886
uint16_t buf_id;
87+
/** Calibration process semaphore */
88+
struct k_sem calibrate_sem;
6989
};
7090

91+
static adc_sample_state_reg_t map_channel_to_sample_state_reg(uint8_t channel_id)
92+
{
93+
if (channel_id <= 15) {
94+
return (adc_sample_state_reg_t)channel_id;
95+
}
96+
97+
/* Channel IDs 16–31 share the same sample state register */
98+
return ADC_SAMPLE_STATE_CHANNEL_16_TO_31;
99+
}
100+
71101
/**
72102
* @brief Setup channels before starting to scan ADC
73103
*
@@ -83,6 +113,8 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
83113
fsp_err_t fsp_err = FSP_SUCCESS;
84114
struct adc_ra_data *data = dev->data;
85115
const struct adc_ra_config *config = dev->config;
116+
adc_sample_state_t sample_state;
117+
uint32_t sample_states = 0;
86118

87119
if (!((config->channel_available_mask & (1 << channel_cfg->channel_id)) != 0)) {
88120
LOG_ERR("unsupported channel id '%d'", channel_cfg->channel_id);
@@ -104,6 +136,18 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
104136
return -EINVAL;
105137
}
106138

139+
fsp_err = RP_ADC_SampleStateCalculation(config->sampling_time_ns, &sample_states);
140+
if (FSP_SUCCESS != fsp_err) {
141+
return -ENOTSUP;
142+
}
143+
144+
sample_state.reg_id = map_channel_to_sample_state_reg(channel_cfg->channel_id);
145+
sample_state.num_states = sample_states;
146+
fsp_err = R_ADC_SampleStateCountSet(&data->adc, &sample_state);
147+
if (FSP_SUCCESS != fsp_err) {
148+
return -ENOTSUP;
149+
}
150+
107151
data->f_channel_cfg.scan_mask |= (1U << channel_cfg->channel_id);
108152
/* Configure ADC channel specific settings */
109153
fsp_err = R_ADC_ScanCfg(&data->adc, &data->f_channel_cfg);
@@ -114,32 +158,86 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
114158
return 0;
115159
}
116160

117-
/**
118-
* Interrupt handler
119-
*/
120-
static void adc_ra_isr(const struct device *dev)
161+
static void renesas_ra_adc_callback(adc_callback_args_t *p_args)
121162
{
163+
const struct device *dev = p_args->p_context;
122164
struct adc_ra_data *data = dev->data;
123165
fsp_err_t fsp_err = FSP_SUCCESS;
124166
adc_channel_t channel_id = 0;
125167
uint32_t channels = 0;
126168
int16_t *sample_buffer = (int16_t *)data->buf;
127169

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;
170+
if (p_args->event == ADC_EVENT_SCAN_COMPLETE) {
171+
channels = data->channels;
172+
for (channel_id = 0; channels > 0; channel_id++) {
173+
/* Check if it is right channel id */
174+
if ((channels & ADC_CHANNEL_BIT_MASK) != 0) {
175+
fsp_err = R_ADC_Read(&data->adc, channel_id,
176+
&sample_buffer[data->buf_id]);
177+
if (FSP_SUCCESS != fsp_err) {
178+
break;
179+
}
180+
/* Do not return negative value for single-ended configuration */
181+
if (sample_buffer[data->buf_id] < 0) {
182+
sample_buffer[data->buf_id] = 0;
183+
}
184+
data->buf_id = data->buf_id + 1;
185+
186+
fsp_err = R_ADC_ScanStop(&data->adc);
187+
if (FSP_SUCCESS != fsp_err) {
188+
break;
189+
}
135190
}
136-
data->buf_id = data->buf_id + 1;
191+
192+
channels = channels >> 1;
193+
}
194+
adc_context_on_sampling_done(&data->ctx, dev);
195+
}
196+
197+
else if (p_args->event == ADC_EVENT_CALIBRATION_COMPLETE) {
198+
k_sem_give(&data->calibrate_sem);
199+
}
200+
}
201+
202+
/**
203+
* Voltage reference covert handler
204+
*/
205+
static int adc_map_vref(const struct adc_ra_config *cfg, adc_extended_cfg_t *extend)
206+
{
207+
switch (cfg->variant) {
208+
case ADC_VARIANT_ADC16:
209+
switch (cfg->reference) {
210+
case RA_ADC_REF_INTERNAL:
211+
extend->adc_vref_control = ADC_VREF_CONTROL_2_5V_OUTPUT;
212+
return 0;
213+
case RA_ADC_REF_EXTERNAL:
214+
extend->adc_vref_control = ADC_VREF_CONTROL_VREFH;
215+
return 0;
216+
default:
217+
LOG_ERR("Reference %d not supported", cfg->reference);
218+
return -ENOTSUP;
219+
}
220+
221+
case ADC_VARIANT_ADC12:
222+
switch (cfg->reference) {
223+
case RA_ADC_REF_VDD:
224+
extend->adc_vref_control = ADC_VREF_CONTROL_AVCC0_AVSS0;
225+
return 0;
226+
case RA_ADC_REF_EXTERNAL:
227+
extend->adc_vref_control = ADC_VREF_CONTROL_VREFH0_VREFL0;
228+
return 0;
229+
case RA_ADC_REF_INTERNAL:
230+
extend->adc_vref_control = ADC_VREF_CONTROL_IVREF_AVSS0;
231+
return 0;
232+
default:
233+
LOG_ERR("Reference %d not supported", cfg->reference);
234+
return -ENOTSUP;
137235
}
138236

139-
channels = channels >> 1;
237+
default:
238+
LOG_ERR("Variant %d not supported", cfg->variant);
239+
return -ENOTSUP;
140240
}
141-
adc_scan_end_isr();
142-
adc_context_on_sampling_done(&data->ctx, dev);
143241
}
144242

145243
/**
@@ -187,9 +285,18 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
187285
{
188286
const struct adc_ra_config *config = dev->config;
189287
struct adc_ra_data *data = dev->data;
288+
fsp_err_t fsp_err = FSP_SUCCESS;
190289
int err;
191290

192-
if (sequence->resolution > ADC_RA_MAX_RESOLUTION || sequence->resolution == 0) {
291+
if (config->variant == ADC_VARIANT_ADC16) {
292+
uint8_t expected = config->resolution - 1;
293+
294+
if (sequence->resolution != expected) {
295+
LOG_ERR("unsupported resolution %d for single-ended mode, must be %d",
296+
sequence->resolution, expected);
297+
return -ENOTSUP;
298+
}
299+
} else if (sequence->resolution != config->resolution) {
193300
LOG_ERR("unsupported resolution %d", sequence->resolution);
194301
return -ENOTSUP;
195302
}
@@ -207,6 +314,21 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
207314

208315
data->buf_id = 0;
209316
data->buf = sequence->buffer;
317+
318+
if (config->variant == ADC_VARIANT_ADC16) {
319+
if (!sequence->calibrate) {
320+
return -ENOTSUP;
321+
}
322+
323+
/* Start calibration process */
324+
k_sem_reset(&data->calibrate_sem);
325+
fsp_err = R_ADC_Calibrate(&data->adc, NULL);
326+
if (FSP_SUCCESS != fsp_err) {
327+
return -EIO;
328+
}
329+
k_sem_take(&data->calibrate_sem, K_FOREVER);
330+
}
331+
210332
adc_context_start_read(&data->ctx, sequence);
211333

212334
adc_context_wait_for_completion(&data->ctx);
@@ -293,12 +415,21 @@ static int adc_ra_init(const struct device *dev)
293415
struct adc_ra_data *data = dev->data;
294416
int ret;
295417
fsp_err_t fsp_err = FSP_SUCCESS;
418+
adc_extended_cfg_t *extend = (adc_extended_cfg_t *)data->f_config.p_extend;
419+
420+
/* Override reference voltage */
421+
ret = adc_map_vref(config, extend);
422+
if (ret < 0) {
423+
return ret;
424+
}
296425

297426
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
298427
if (ret < 0) {
299428
return ret;
300429
}
301430

431+
k_sem_init(&data->calibrate_sem, 0, 1);
432+
302433
/* Open ADC module */
303434
fsp_err = R_ADC_Open(&data->adc, &data->f_config);
304435
if (FSP_SUCCESS != fsp_err) {
@@ -307,28 +438,38 @@ static int adc_ra_init(const struct device *dev)
307438

308439
config->irq_configure();
309440

441+
if (config->variant == ADC_VARIANT_ADC16) {
442+
/* Start calibration process */
443+
fsp_err = R_ADC_Calibrate(&data->adc, NULL);
444+
if (FSP_SUCCESS != fsp_err) {
445+
return -EIO;
446+
}
447+
k_sem_take(&data->calibrate_sem, K_FOREVER);
448+
}
449+
310450
adc_context_unlock_unconditionally(&data->ctx);
311451
return 0;
312452
}
313453

314-
#define EVENT_ADC_SCAN_END(idx) BSP_PRV_IELS_ENUM(CONCAT(EVENT_ADC, idx, _SCAN_END))
454+
#define EVENT_ADC_SCAN_END(unit) BSP_PRV_IELS_ENUM(CONCAT(EVENT_ADC, unit, _SCAN_END))
315455

316456
#define IRQ_CONFIGURE_FUNC(idx) \
317457
static void adc_ra_configure_func_##idx(void) \
318458
{ \
319-
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = EVENT_ADC_SCAN_END(idx); \
459+
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = \
460+
EVENT_ADC_SCAN_END(DT_PROP(DT_DRV_INST(idx), unit)); \
320461
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); \
462+
DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_scan_end_isr, NULL, \
463+
0); \
323464
irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \
324465
}
325466

326467
#define IRQ_CONFIGURE_DEFINE(idx) .irq_configure = adc_ra_configure_func_##idx
327468

328-
#define ADC_RA_INIT(idx) \
469+
#define ADC_RA_INIT_VARIANT(idx, VARIANT, RES_NUM, RES_ENUM) \
329470
IRQ_CONFIGURE_FUNC(idx) \
330471
PINCTRL_DT_INST_DEFINE(idx); \
331-
static const adc_extended_cfg_t g_adc_cfg_extend_##idx = { \
472+
static adc_extended_cfg_t g_adc_cfg_extend_##idx = { \
332473
.add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \
333474
.clearing = ADC_CLEAR_AFTER_READ_ON, \
334475
.trigger_group_b = ADC_START_SOURCE_DISABLED, \
@@ -345,9 +486,13 @@ static int adc_ra_init(const struct device *dev)
345486
.channel_setup = adc_ra_channel_setup, \
346487
.read = adc_ra_read, \
347488
.ref_internal = DT_INST_PROP(idx, vref_mv), \
348-
IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
489+
IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
349490
static const struct adc_ra_config adc_ra_config_##idx = { \
350491
.channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \
492+
.variant = VARIANT, \
493+
.reference = DT_INST_ENUM_IDX(idx, reference), \
494+
.resolution = RES_NUM, \
495+
.sampling_time_ns = DT_INST_PROP_OR(idx, sampling_time_ns, UNSPECIFIED), \
351496
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
352497
IRQ_CONFIGURE_DEFINE(idx), \
353498
}; \
@@ -358,13 +503,13 @@ static int adc_ra_init(const struct device *dev)
358503
.dev = DEVICE_DT_INST_GET(idx), \
359504
.f_config = \
360505
{ \
361-
.unit = idx, \
506+
.unit = DT_INST_PROP(idx, unit), \
362507
.mode = ADC_MODE_SINGLE_SCAN, \
363-
.resolution = ADC_RESOLUTION_12_BIT, \
508+
.resolution = RES_ENUM, \
364509
.alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \
365510
.trigger = 0, \
366-
.p_callback = NULL, \
367-
.p_context = NULL, \
511+
.p_callback = renesas_ra_adc_callback, \
512+
.p_context = (void *)DEVICE_DT_GET(DT_DRV_INST(idx)), \
368513
.p_extend = &g_adc_cfg_extend_##idx, \
369514
.scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
370515
.scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \
@@ -386,4 +531,10 @@ static int adc_ra_init(const struct device *dev)
386531
DEVICE_DT_INST_DEFINE(idx, adc_ra_init, NULL, &adc_ra_data_##idx, &adc_ra_config_##idx, \
387532
POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, &adc_ra_api_##idx)
388533

389-
DT_INST_FOREACH_STATUS_OKAY(ADC_RA_INIT);
534+
#define DT_DRV_COMPAT renesas_ra_adc12
535+
DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_RA_INIT_VARIANT, ADC_VARIANT_ADC12, 12, ADC_RESOLUTION_12_BIT)
536+
#undef DT_DRV_COMPAT
537+
538+
#define DT_DRV_COMPAT renesas_ra_adc16
539+
DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_RA_INIT_VARIANT, ADC_VARIANT_ADC16, 16, ADC_RESOLUTION_16_BIT)
540+
#undef DT_DRV_COMPAT

0 commit comments

Comments
 (0)