@@ -21,14 +21,27 @@ LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL);
21
21
#define ADC_CONTEXT_USES_KERNEL_TIMER
22
22
#include "adc_context.h"
23
23
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
30
29
31
- void adc_scan_end_isr (void );
30
+ #define ADC_RES_12 ADC_RESOLUTION_12_BIT
31
+ #define ADC_RES_16 ADC_RESOLUTION_16_BIT
32
+
33
+ #define ADC_VARIANT_ADC12 12
34
+ #define ADC_VARIANT_ADC16 16
35
+
36
+ #define ADC_CHANNEL_BIT_MASK (0x01U)
37
+
38
+ enum ra_adc_reference {
39
+ RA_ADC_REF_VDD ,
40
+ RA_ADC_REF_INTERNAL ,
41
+ RA_ADC_REF_EXTERNAL ,
42
+ };
43
+
44
+ extern void adc_scan_end_isr (void );
32
45
33
46
/**
34
47
* @brief RA ADC config
@@ -40,6 +53,12 @@ struct adc_ra_config {
40
53
uint32_t channel_available_mask ;
41
54
/** pinctrl configs */
42
55
const struct pinctrl_dev_config * pcfg ;
56
+ /** Variant support ADC16 or ADC12 */
57
+ uint8_t variant ;
58
+ /** Mapping reference voltage */
59
+ uint32_t reference ;
60
+ /** Resolution support */
61
+ uint8_t resolution ;
43
62
/** function pointer to irq setup */
44
63
void (* irq_configure )(void );
45
64
};
@@ -66,6 +85,8 @@ struct adc_ra_data {
66
85
uint32_t channels ;
67
86
/** Buffer id */
68
87
uint16_t buf_id ;
88
+ /** Calibration process semaphore */
89
+ struct k_sem calibrate_sem ;
69
90
};
70
91
71
92
/**
@@ -114,32 +135,86 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
114
135
return 0 ;
115
136
}
116
137
117
- /**
118
- * Interrupt handler
119
- */
120
- static void adc_ra_isr (const struct device * dev )
138
+ static void renesas_ra_adc_callback (adc_callback_args_t * p_args )
121
139
{
140
+ const struct device * dev = p_args -> p_context ;
122
141
struct adc_ra_data * data = dev -> data ;
123
142
fsp_err_t fsp_err = FSP_SUCCESS ;
124
143
adc_channel_t channel_id = 0 ;
125
144
uint32_t channels = 0 ;
126
145
int16_t * sample_buffer = (int16_t * )data -> buf ;
127
146
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 ;
147
+ if (p_args -> event == ADC_EVENT_SCAN_COMPLETE ) {
148
+ channels = data -> channels ;
149
+ for (channel_id = 0 ; channels > 0 ; channel_id ++ ) {
150
+ /* Check if it is right channel id */
151
+ if ((channels & ADC_CHANNEL_BIT_MASK ) != 0 ) {
152
+ fsp_err = R_ADC_Read (& data -> adc , channel_id ,
153
+ & sample_buffer [data -> buf_id ]);
154
+ if (FSP_SUCCESS != fsp_err ) {
155
+ break ;
156
+ }
157
+ /* Do not return negative value for single-ended configuration */
158
+ if (sample_buffer [data -> buf_id ] < 0 ) {
159
+ sample_buffer [data -> buf_id ] = 0 ;
160
+ }
161
+ data -> buf_id = data -> buf_id + 1 ;
162
+
163
+ fsp_err = R_ADC_ScanStop (& data -> adc );
164
+ if (FSP_SUCCESS != fsp_err ) {
165
+ break ;
166
+ }
135
167
}
136
- data -> buf_id = data -> buf_id + 1 ;
168
+
169
+ channels = channels >> 1 ;
137
170
}
171
+ adc_context_on_sampling_done (& data -> ctx , dev );
172
+ }
138
173
139
- channels = channels >> 1 ;
174
+ else if (p_args -> event == ADC_EVENT_CALIBRATION_COMPLETE ) {
175
+ k_sem_give (& data -> calibrate_sem );
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Voltage reference covert handler
181
+ */
182
+ static int adc_map_vref (const struct adc_ra_config * cfg , adc_extended_cfg_t * extend )
183
+ {
184
+ switch (cfg -> variant ) {
185
+ case ADC_VARIANT_ADC16 :
186
+ switch (cfg -> reference ) {
187
+ case RA_ADC_REF_INTERNAL :
188
+ extend -> adc_vref_control = ADC_VREF_CONTROL_2_5V_OUTPUT ;
189
+ return 0 ;
190
+ case RA_ADC_REF_EXTERNAL :
191
+ extend -> adc_vref_control = ADC_VREF_CONTROL_VREFH ;
192
+ return 0 ;
193
+ default :
194
+ LOG_ERR ("Reference %d not supported" , cfg -> reference );
195
+ return - ENOTSUP ;
196
+ }
197
+
198
+ case ADC_VARIANT_ADC12 :
199
+ switch (cfg -> reference ) {
200
+ case RA_ADC_REF_VDD :
201
+ extend -> adc_vref_control = ADC_VREF_CONTROL_AVCC0_AVSS0 ;
202
+ return 0 ;
203
+ case RA_ADC_REF_EXTERNAL :
204
+ extend -> adc_vref_control = ADC_VREF_CONTROL_VREFH0_VREFL0 ;
205
+ return 0 ;
206
+ case RA_ADC_REF_INTERNAL :
207
+ extend -> adc_vref_control = ADC_VREF_CONTROL_IVREF_AVSS0 ;
208
+ return 0 ;
209
+ default :
210
+ LOG_ERR ("Reference %d not supported" , cfg -> reference );
211
+ return - ENOTSUP ;
212
+ }
213
+
214
+ default :
215
+ LOG_ERR ("Variant %d not supported" , cfg -> variant );
216
+ return - ENOTSUP ;
140
217
}
141
- adc_scan_end_isr ();
142
- adc_context_on_sampling_done (& data -> ctx , dev );
143
218
}
144
219
145
220
/**
@@ -187,9 +262,18 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
187
262
{
188
263
const struct adc_ra_config * config = dev -> config ;
189
264
struct adc_ra_data * data = dev -> data ;
265
+ fsp_err_t fsp_err = FSP_SUCCESS ;
190
266
int err ;
191
267
192
- if (sequence -> resolution > ADC_RA_MAX_RESOLUTION || sequence -> resolution == 0 ) {
268
+ if (config -> variant == ADC_VARIANT_ADC16 ) {
269
+ uint8_t expected = config -> resolution - 1 ;
270
+
271
+ if (sequence -> resolution != expected ) {
272
+ LOG_ERR ("unsupported resolution %d for single-ended mode, must be %d" ,
273
+ sequence -> resolution , expected );
274
+ return - ENOTSUP ;
275
+ }
276
+ } else if (sequence -> resolution != config -> resolution ) {
193
277
LOG_ERR ("unsupported resolution %d" , sequence -> resolution );
194
278
return - ENOTSUP ;
195
279
}
@@ -207,6 +291,21 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
207
291
208
292
data -> buf_id = 0 ;
209
293
data -> buf = sequence -> buffer ;
294
+
295
+ if (config -> variant == ADC_VARIANT_ADC16 ) {
296
+ if (!sequence -> calibrate ) {
297
+ return - ENOTSUP ;
298
+ }
299
+
300
+ /* Start calibration process */
301
+ k_sem_reset (& data -> calibrate_sem );
302
+ fsp_err = R_ADC_Calibrate (& data -> adc , NULL );
303
+ if (FSP_SUCCESS != fsp_err ) {
304
+ return - EIO ;
305
+ }
306
+ k_sem_take (& data -> calibrate_sem , K_FOREVER );
307
+ }
308
+
210
309
adc_context_start_read (& data -> ctx , sequence );
211
310
212
311
adc_context_wait_for_completion (& data -> ctx );
@@ -294,11 +393,20 @@ static int adc_ra_init(const struct device *dev)
294
393
int ret ;
295
394
fsp_err_t fsp_err = FSP_SUCCESS ;
296
395
396
+ /* Override reference voltage */
397
+ adc_extended_cfg_t * extend = (adc_extended_cfg_t * )data -> f_config .p_extend ;
398
+ ret = adc_map_vref (config , extend );
399
+ if (ret < 0 ) {
400
+ return ret ;
401
+ }
402
+
297
403
ret = pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_DEFAULT );
298
404
if (ret < 0 ) {
299
405
return ret ;
300
406
}
301
407
408
+ k_sem_init (& data -> calibrate_sem , 0 , 1 );
409
+
302
410
/* Open ADC module */
303
411
fsp_err = R_ADC_Open (& data -> adc , & data -> f_config );
304
412
if (FSP_SUCCESS != fsp_err ) {
@@ -307,6 +415,15 @@ static int adc_ra_init(const struct device *dev)
307
415
308
416
config -> irq_configure ();
309
417
418
+ if (config -> variant == ADC_VARIANT_ADC16 ) {
419
+ /* Start calibration process */
420
+ fsp_err = R_ADC_Calibrate (& data -> adc , NULL );
421
+ if (FSP_SUCCESS != fsp_err ) {
422
+ return - EIO ;
423
+ }
424
+ k_sem_take (& data -> calibrate_sem , K_FOREVER );
425
+ }
426
+
310
427
adc_context_unlock_unconditionally (& data -> ctx );
311
428
return 0 ;
312
429
}
@@ -318,8 +435,8 @@ static int adc_ra_init(const struct device *dev)
318
435
{ \
319
436
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = EVENT_ADC_SCAN_END(idx); \
320
437
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); \
438
+ DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_scan_end_isr, NULL, \
439
+ 0); \
323
440
irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \
324
441
}
325
442
@@ -345,9 +462,12 @@ static int adc_ra_init(const struct device *dev)
345
462
.channel_setup = adc_ra_channel_setup, \
346
463
.read = adc_ra_read, \
347
464
.ref_internal = DT_INST_PROP(idx, vref_mv), \
348
- IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
465
+ IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
349
466
static const struct adc_ra_config adc_ra_config_##idx = { \
350
467
.channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \
468
+ .variant = DT_INST_PROP(idx, variant), \
469
+ .reference = DT_INST_ENUM_IDX(idx, reference), \
470
+ .resolution = DT_INST_PROP(idx, variant), \
351
471
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
352
472
IRQ_CONFIGURE_DEFINE(idx), \
353
473
}; \
@@ -360,11 +480,11 @@ static int adc_ra_init(const struct device *dev)
360
480
{ \
361
481
.unit = idx, \
362
482
.mode = ADC_MODE_SINGLE_SCAN, \
363
- .resolution = ADC_RESOLUTION_12_BIT, \
483
+ .resolution = UTIL_CAT(ADC_RES_, DT_INST_PROP(idx, variant)), \
364
484
.alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \
365
485
.trigger = 0, \
366
- .p_callback = NULL, \
367
- .p_context = NULL, \
486
+ .p_callback = renesas_ra_adc_callback, \
487
+ .p_context = (void *)DEVICE_DT_GET(DT_DRV_INST(idx)), \
368
488
.p_extend = &g_adc_cfg_extend_##idx, \
369
489
.scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
370
490
.scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \
0 commit comments