14
14
#include <zephyr/sys/util_internal.h>
15
15
#include <instances/r_adc.h>
16
16
17
+ #include "rp_adc.h"
18
+
17
19
#include <zephyr/irq.h>
18
20
19
21
LOG_MODULE_REGISTER (adc_ra , CONFIG_ADC_LOG_LEVEL );
20
22
21
23
#define ADC_CONTEXT_USES_KERNEL_TIMER
22
24
#include "adc_context.h"
23
25
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
30
34
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 );
32
47
33
48
/**
34
49
* @brief RA ADC config
@@ -40,6 +55,14 @@ struct adc_ra_config {
40
55
uint32_t channel_available_mask ;
41
56
/** pinctrl configs */
42
57
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 ;
43
66
/** function pointer to irq setup */
44
67
void (* irq_configure )(void );
45
68
};
@@ -66,8 +89,20 @@ struct adc_ra_data {
66
89
uint32_t channels ;
67
90
/** Buffer id */
68
91
uint16_t buf_id ;
92
+ /** Calibration process semaphore */
93
+ struct k_sem calibrate_sem ;
69
94
};
70
95
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
+
71
106
/**
72
107
* @brief Setup channels before starting to scan ADC
73
108
*
@@ -83,6 +118,8 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
83
118
fsp_err_t fsp_err = FSP_SUCCESS ;
84
119
struct adc_ra_data * data = dev -> data ;
85
120
const struct adc_ra_config * config = dev -> config ;
121
+ adc_sample_state_t sample_state ;
122
+ uint32_t sample_states = 0 ;
86
123
87
124
if (!((config -> channel_available_mask & (1 << channel_cfg -> channel_id )) != 0 )) {
88
125
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
104
141
return - EINVAL ;
105
142
}
106
143
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
+
107
156
data -> f_channel_cfg .scan_mask |= (1U << channel_cfg -> channel_id );
108
157
/* Configure ADC channel specific settings */
109
158
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
114
163
return 0 ;
115
164
}
116
165
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 )
121
167
{
168
+ const struct device * dev = p_args -> p_context ;
122
169
struct adc_ra_data * data = dev -> data ;
123
170
fsp_err_t fsp_err = FSP_SUCCESS ;
124
171
adc_channel_t channel_id = 0 ;
125
172
uint32_t channels = 0 ;
126
173
int16_t * sample_buffer = (int16_t * )data -> buf ;
127
174
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
+ }
135
195
}
136
- data -> buf_id = data -> buf_id + 1 ;
196
+
197
+ channels = channels >> 1 ;
137
198
}
199
+ adc_context_on_sampling_done (& data -> ctx , dev );
200
+ }
138
201
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 ;
140
245
}
141
- adc_scan_end_isr ();
142
- adc_context_on_sampling_done (& data -> ctx , dev );
143
246
}
144
247
145
248
/**
@@ -187,9 +290,18 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
187
290
{
188
291
const struct adc_ra_config * config = dev -> config ;
189
292
struct adc_ra_data * data = dev -> data ;
293
+ fsp_err_t fsp_err = FSP_SUCCESS ;
190
294
int err ;
191
295
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 ) {
193
305
LOG_ERR ("unsupported resolution %d" , sequence -> resolution );
194
306
return - ENOTSUP ;
195
307
}
@@ -207,6 +319,21 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
207
319
208
320
data -> buf_id = 0 ;
209
321
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
+
210
337
adc_context_start_read (& data -> ctx , sequence );
211
338
212
339
adc_context_wait_for_completion (& data -> ctx );
@@ -293,12 +420,21 @@ static int adc_ra_init(const struct device *dev)
293
420
struct adc_ra_data * data = dev -> data ;
294
421
int ret ;
295
422
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
+ }
296
430
297
431
ret = pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_DEFAULT );
298
432
if (ret < 0 ) {
299
433
return ret ;
300
434
}
301
435
436
+ k_sem_init (& data -> calibrate_sem , 0 , 1 );
437
+
302
438
/* Open ADC module */
303
439
fsp_err = R_ADC_Open (& data -> adc , & data -> f_config );
304
440
if (FSP_SUCCESS != fsp_err ) {
@@ -307,19 +443,29 @@ static int adc_ra_init(const struct device *dev)
307
443
308
444
config -> irq_configure ();
309
445
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
+
310
455
adc_context_unlock_unconditionally (& data -> ctx );
311
456
return 0 ;
312
457
}
313
458
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))
315
460
316
461
#define IRQ_CONFIGURE_FUNC (idx ) \
317
462
static void adc_ra_configure_func_##idx(void) \
318
463
{ \
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)); \
320
466
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); \
323
469
irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \
324
470
}
325
471
@@ -328,7 +474,7 @@ static int adc_ra_init(const struct device *dev)
328
474
#define ADC_RA_INIT (idx ) \
329
475
IRQ_CONFIGURE_FUNC(idx) \
330
476
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 = { \
332
478
.add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \
333
479
.clearing = ADC_CLEAR_AFTER_READ_ON, \
334
480
.trigger_group_b = ADC_START_SOURCE_DISABLED, \
@@ -345,9 +491,13 @@ static int adc_ra_init(const struct device *dev)
345
491
.channel_setup = adc_ra_channel_setup, \
346
492
.read = adc_ra_read, \
347
493
.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))}; \
349
495
static const struct adc_ra_config adc_ra_config_##idx = { \
350
496
.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), \
351
501
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
352
502
IRQ_CONFIGURE_DEFINE(idx), \
353
503
}; \
@@ -358,13 +508,13 @@ static int adc_ra_init(const struct device *dev)
358
508
.dev = DEVICE_DT_INST_GET(idx), \
359
509
.f_config = \
360
510
{ \
361
- .unit = idx, \
511
+ .unit = DT_INST_PROP( idx, unit), \
362
512
.mode = ADC_MODE_SINGLE_SCAN, \
363
- .resolution = ADC_RESOLUTION_12_BIT, \
513
+ .resolution = UTIL_CAT(ADC_RES_, DT_INST_PROP(idx, variant)), \
364
514
.alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \
365
515
.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)), \
368
518
.p_extend = &g_adc_cfg_extend_##idx, \
369
519
.scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
370
520
.scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \
0 commit comments