4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
6
6
7
- #define DT_DRV_COMPAT renesas_ra_adc
8
-
9
7
#include <zephyr/drivers/adc.h>
10
8
#include <zephyr/drivers/clock_control.h>
11
9
#include <zephyr/drivers/pinctrl.h>
14
12
#include <zephyr/sys/util_internal.h>
15
13
#include <instances/r_adc.h>
16
14
15
+ #include "rp_adc.h"
16
+
17
17
#include <zephyr/irq.h>
18
18
19
19
LOG_MODULE_REGISTER (adc_ra , CONFIG_ADC_LOG_LEVEL );
20
20
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_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 );
32
42
33
43
/**
34
44
* @brief RA ADC config
@@ -40,6 +50,14 @@ struct adc_ra_config {
40
50
uint32_t channel_available_mask ;
41
51
/** pinctrl configs */
42
52
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 ;
43
61
/** function pointer to irq setup */
44
62
void (* irq_configure )(void );
45
63
};
@@ -66,8 +84,20 @@ struct adc_ra_data {
66
84
uint32_t channels ;
67
85
/** Buffer id */
68
86
uint16_t buf_id ;
87
+ /** Calibration process semaphore */
88
+ struct k_sem calibrate_sem ;
69
89
};
70
90
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
+
71
101
/**
72
102
* @brief Setup channels before starting to scan ADC
73
103
*
@@ -83,6 +113,8 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann
83
113
fsp_err_t fsp_err = FSP_SUCCESS ;
84
114
struct adc_ra_data * data = dev -> data ;
85
115
const struct adc_ra_config * config = dev -> config ;
116
+ adc_sample_state_t sample_state ;
117
+ uint32_t sample_states = 0 ;
86
118
87
119
if (!((config -> channel_available_mask & (1 << channel_cfg -> channel_id )) != 0 )) {
88
120
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
104
136
return - EINVAL ;
105
137
}
106
138
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
+
107
151
data -> f_channel_cfg .scan_mask |= (1U << channel_cfg -> channel_id );
108
152
/* Configure ADC channel specific settings */
109
153
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
114
158
return 0 ;
115
159
}
116
160
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 )
121
162
{
163
+ const struct device * dev = p_args -> p_context ;
122
164
struct adc_ra_data * data = dev -> data ;
123
165
fsp_err_t fsp_err = FSP_SUCCESS ;
124
166
adc_channel_t channel_id = 0 ;
125
167
uint32_t channels = 0 ;
126
168
int16_t * sample_buffer = (int16_t * )data -> buf ;
127
169
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
+ }
135
190
}
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 ;
137
235
}
138
236
139
- channels = channels >> 1 ;
237
+ default :
238
+ LOG_ERR ("Variant %d not supported" , cfg -> variant );
239
+ return - ENOTSUP ;
140
240
}
141
- adc_scan_end_isr ();
142
- adc_context_on_sampling_done (& data -> ctx , dev );
143
241
}
144
242
145
243
/**
@@ -187,9 +285,18 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
187
285
{
188
286
const struct adc_ra_config * config = dev -> config ;
189
287
struct adc_ra_data * data = dev -> data ;
288
+ fsp_err_t fsp_err = FSP_SUCCESS ;
190
289
int err ;
191
290
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 ) {
193
300
LOG_ERR ("unsupported resolution %d" , sequence -> resolution );
194
301
return - ENOTSUP ;
195
302
}
@@ -207,6 +314,21 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence
207
314
208
315
data -> buf_id = 0 ;
209
316
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
+
210
332
adc_context_start_read (& data -> ctx , sequence );
211
333
212
334
adc_context_wait_for_completion (& data -> ctx );
@@ -293,12 +415,21 @@ static int adc_ra_init(const struct device *dev)
293
415
struct adc_ra_data * data = dev -> data ;
294
416
int ret ;
295
417
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
+ }
296
425
297
426
ret = pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_DEFAULT );
298
427
if (ret < 0 ) {
299
428
return ret ;
300
429
}
301
430
431
+ k_sem_init (& data -> calibrate_sem , 0 , 1 );
432
+
302
433
/* Open ADC module */
303
434
fsp_err = R_ADC_Open (& data -> adc , & data -> f_config );
304
435
if (FSP_SUCCESS != fsp_err ) {
@@ -307,28 +438,38 @@ static int adc_ra_init(const struct device *dev)
307
438
308
439
config -> irq_configure ();
309
440
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
+
310
450
adc_context_unlock_unconditionally (& data -> ctx );
311
451
return 0 ;
312
452
}
313
453
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))
315
455
316
456
#define IRQ_CONFIGURE_FUNC (idx ) \
317
457
static void adc_ra_configure_func_##idx(void) \
318
458
{ \
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)); \
320
461
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); \
323
464
irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \
324
465
}
325
466
326
467
#define IRQ_CONFIGURE_DEFINE (idx ) .irq_configure = adc_ra_configure_func_##idx
327
468
328
- #define ADC_RA_INIT (idx ) \
469
+ #define ADC_RA_INIT_VARIANT (idx , VARIANT , RES_NUM , RES_ENUM ) \
329
470
IRQ_CONFIGURE_FUNC(idx) \
330
471
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 = { \
332
473
.add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \
333
474
.clearing = ADC_CLEAR_AFTER_READ_ON, \
334
475
.trigger_group_b = ADC_START_SOURCE_DISABLED, \
@@ -345,9 +486,13 @@ static int adc_ra_init(const struct device *dev)
345
486
.channel_setup = adc_ra_channel_setup, \
346
487
.read = adc_ra_read, \
347
488
.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))}; \
349
490
static const struct adc_ra_config adc_ra_config_##idx = { \
350
491
.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), \
351
496
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
352
497
IRQ_CONFIGURE_DEFINE(idx), \
353
498
}; \
@@ -358,13 +503,13 @@ static int adc_ra_init(const struct device *dev)
358
503
.dev = DEVICE_DT_INST_GET(idx), \
359
504
.f_config = \
360
505
{ \
361
- .unit = idx, \
506
+ .unit = DT_INST_PROP( idx, unit), \
362
507
.mode = ADC_MODE_SINGLE_SCAN, \
363
- .resolution = ADC_RESOLUTION_12_BIT, \
508
+ .resolution = RES_ENUM, \
364
509
.alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \
365
510
.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)), \
368
513
.p_extend = &g_adc_cfg_extend_##idx, \
369
514
.scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
370
515
.scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \
@@ -386,4 +531,10 @@ static int adc_ra_init(const struct device *dev)
386
531
DEVICE_DT_INST_DEFINE(idx, adc_ra_init, NULL, &adc_ra_data_##idx, &adc_ra_config_##idx, \
387
532
POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, &adc_ra_api_##idx)
388
533
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