1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /***********************************************************************************************************************
8 * Includes <System Includes> , "Project Includes"
9 **********************************************************************************************************************/
10
11 #include "bsp_api.h"
12
13 /* Configuration for this package. */
14 #include "r_adc_cfg.h"
15
16 /* Private header file for this package. */
17 #include "r_adc.h"
18
19 /**********************************************************************************************************************
20 * Macro definitions
21 **********************************************************************************************************************/
22
23 #define ADC_PRV_USEC_PER_SEC (1000000U)
24 #define ADC_PRV_MIN_ADCLK_HZ (1000000U)
25 #define ADC_MAX_CALIBRATION_CLOCKS_MILLISECS (780U)
26
27 #define ADC_PRV_HZ_PER_KHZ (1000U)
28
29 #define ADC_SHIFT_LEFT_ALIGNED_32_BIT (16U)
30
31 #define ADC_OPEN (0x52414443U)
32
33 #define ADC_ADADC_AVEE_BIT (0x80U)
34
35 /* Sample and hold bypass applies to these channels. */
36 #define ADC_MASK_SAMPLE_HOLD_BYPASS_CHANNELS (0x7U)
37
38 /* Sample and hold bypass starts at bit 8. */
39 #define ADC_MASK_SAMPLE_HOLD_BYPASS_SHIFT (8U)
40
41 /* Value for ADPGADCR0 to disable PGA */
42 #define ADC_ADPGADCR0_DISABLE_PGA (0x0000)
43
44 /* Value for ADPGACR to disable PGA */
45 #define ADC_ADPGACR_DISABLE_PGA (0x9999)
46
47 /* Position of ADCALEXE to start calibration-CALEXE bit */
48 #define ADC_ADCALEXE_SET_CALEXE (0x80U)
49
50 /* Position of ADCALEXE calibration-CALMON bit */
51 #define ADC_ADCALEXE_CALIBRATION_STATUS (0x40U)
52
53 /* Value of ADICR with interrupt at end of calibration */
54 #define ADC_ADICR_CALIBRATION_INTERRUPT_ENABLED (0x03U)
55
56 /* Value of ADICR with no interrupt at end of calibration */
57 #define ADC_ADICR_CALIBRATION_INTERRUPT_DISABLED (0x00U)
58
59 /* Stabilization time when BGR is enabled */
60 #define ADC_BGR_STABILIZATION_DELAY_US (150U)
61
62 /* Bit set in adc_vref_control if the internal voltage reference is used for VREFH. */
63 #define ADC_PRV_ADHVREFCNT_VREF_INTERNAL_BIT_1 (1U << 1)
64
65 #define ADC_PRV_ADCSR_ADST_TRGE_MASK (R_ADC0_ADCSR_ADST_Msk | R_ADC0_ADCSR_TRGE_Msk)
66 #define ADC_PRV_ADCSR_CLEAR_ADST_TRGE (~ADC_PRV_ADCSR_ADST_TRGE_MASK)
67
68 #define ADC_PRV_TSCR_TSN_ENABLE (R_TSN_CTRL_TSCR_TSEN_Msk | R_TSN_CTRL_TSCR_TSOE_Msk)
69
70 #define ADC_PRV_ADBUF_ENABLED (1U)
71
72 #define ADC_MASK_FIRST_SENSOR_BIT (29U)
73
74 /***********************************************************************************************************************
75 * Typedef definitions
76 **********************************************************************************************************************/
77
78 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
79 typedef void (BSP_CMSE_NONSECURE_CALL * adc_prv_ns_callback)(adc_callback_args_t * p_args);
80 #elif defined(__GNUC__)
81 typedef BSP_CMSE_NONSECURE_CALL void (*volatile adc_prv_ns_callback)(adc_callback_args_t * p_args);
82 #endif
83
84 /***********************************************************************************************************************
85 * Private global variables and functions
86 **********************************************************************************************************************/
87 #if ADC_CFG_PARAM_CHECKING_ENABLE
88 static fsp_err_t r_adc_open_cfg_check(adc_cfg_t const * const p_cfg);
89 static fsp_err_t r_adc_open_cfg_resolution_check(adc_cfg_t const * const p_cfg);
90 static fsp_err_t r_adc_sample_state_cfg_check(adc_instance_ctrl_t * p_instance_ctrl, adc_sample_state_t * p_sample);
91
92 static fsp_err_t r_adc_scan_cfg_check_sample_hold(adc_instance_ctrl_t * const p_instance_ctrl,
93 adc_channel_cfg_t const * const p_channel_cfg);
94
95 static fsp_err_t r_adc_scan_cfg_check_sensors(adc_instance_ctrl_t * const p_instance_ctrl,
96 adc_channel_cfg_t const * const p_channel_cfg);
97
98 #endif
99
100 static void r_adc_open_sub(adc_instance_ctrl_t * const p_instance_ctrl, adc_cfg_t const * const p_cfg);
101
102 static void r_adc_sensor_cfg(adc_instance_ctrl_t * const p_instance_ctrl,
103 adc_channel_cfg_t const * const p_channel_cfg);
104
105 #if ADC_CFG_PARAM_CHECKING_ENABLE
106
107 static fsp_err_t r_adc_scan_cfg_check(adc_instance_ctrl_t * const p_instance_ctrl,
108 adc_channel_cfg_t const * const p_channel_cfg);
109
110 #endif
111
112 static void r_adc_scan_cfg(adc_instance_ctrl_t * const p_instance_ctrl,
113 adc_channel_cfg_t const * const p_channel_cfg);
114 static void r_adc_sensor_sample_state_calculation(uint32_t * const p_sample_states);
115 void adc_scan_end_b_isr(void);
116 void adc_scan_end_isr(void);
117 void adc_window_compare_isr(void);
118 static void r_adc_irq_enable(IRQn_Type irq, uint8_t ipl, void * p_context);
119 static void r_adc_irq_disable(IRQn_Type irq);
120 static int32_t r_adc_lowest_channel_get(uint32_t adc_mask);
121 static void r_adc_scan_end_common_isr(adc_event_t event);
122
123 #if ADC_CFG_PARAM_CHECKING_ENABLE
124
125 /** Mask of valid channels on this MCU. */
126 static const uint32_t g_adc_valid_channels[] =
127 {
128 BSP_FEATURE_ADC_UNIT_0_CHANNELS,
129 #if BSP_FEATURE_ADC_UNIT_1_CHANNELS
130 BSP_FEATURE_ADC_UNIT_1_CHANNELS
131 #endif
132 };
133 #endif
134
135 /***********************************************************************************************************************
136 * Global Variables
137 **********************************************************************************************************************/
138
139 /** ADC Implementation of ADC. */
140 const adc_api_t g_adc_on_adc =
141 {
142 .open = R_ADC_Open,
143 .scanCfg = R_ADC_ScanCfg,
144 .infoGet = R_ADC_InfoGet,
145 .scanStart = R_ADC_ScanStart,
146 .scanGroupStart = R_ADC_ScanGroupStart,
147 .scanStop = R_ADC_ScanStop,
148 .scanStatusGet = R_ADC_StatusGet,
149 .read = R_ADC_Read,
150 .read32 = R_ADC_Read32,
151 .close = R_ADC_Close,
152 .calibrate = R_ADC_Calibrate,
153 .offsetSet = R_ADC_OffsetSet,
154 .callbackSet = R_ADC_CallbackSet,
155 };
156
157 /*******************************************************************************************************************//**
158 * @addtogroup ADC
159 * @{
160 **********************************************************************************************************************/
161
162 /***********************************************************************************************************************
163 * Functions
164 **********************************************************************************************************************/
165
166 /*******************************************************************************************************************//**
167 * Sets the operational mode, trigger sources, interrupt priority, and configurations for the peripheral as a whole.
168 * If interrupt is enabled, the function registers a callback function pointer for notifying the user whenever a scan
169 * has completed.
170 *
171 * @retval FSP_SUCCESS Module is ready for use.
172 * @retval FSP_ERR_ASSERTION An input argument is invalid.
173 * @retval FSP_ERR_ALREADY_OPEN The instance control structure has already been opened.
174 * @retval FSP_ERR_IRQ_BSP_DISABLED A callback is provided, but the interrupt is not enabled.
175 * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The requested unit does not exist on this MCU.
176 * @retval FSP_ERR_INVALID_HW_CONDITION The ADC clock must be at least 1 MHz
177 **********************************************************************************************************************/
R_ADC_Open(adc_ctrl_t * p_ctrl,adc_cfg_t const * const p_cfg)178 fsp_err_t R_ADC_Open (adc_ctrl_t * p_ctrl, adc_cfg_t const * const p_cfg)
179 {
180 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
181
182 /* Perform parameter checking */
183 #if ADC_CFG_PARAM_CHECKING_ENABLE
184
185 /* Verify the pointers are valid */
186 FSP_ASSERT(NULL != p_instance_ctrl);
187
188 /* Verify the configuration parameters are valid */
189 fsp_err_t err = r_adc_open_cfg_check(p_cfg);
190 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
191
192 /* Check for valid argument values for options that are unique to the IP */
193 err = r_adc_open_cfg_resolution_check(p_cfg);
194 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
195
196 /* Verify this unit has not already been initialized */
197 FSP_ERROR_RETURN(ADC_OPEN != p_instance_ctrl->opened, FSP_ERR_ALREADY_OPEN);
198
199 /* If a callback is used, then make sure an interrupt is enabled */
200 adc_extended_cfg_t const * p_extend = (adc_extended_cfg_t const *) p_cfg->p_extend;
201 if (NULL != p_cfg->p_callback)
202 {
203 FSP_ERROR_RETURN((p_cfg->scan_end_irq >= 0) || (p_extend->window_a_irq >= 0) || (p_extend->window_b_irq >= 0),
204 FSP_ERR_IRQ_BSP_DISABLED);
205
206 /* Group B interrupts are never required since group B can be configured in continuous scan mode when group A
207 * has priority over group B. */
208 }
209
210 #else
211 adc_extended_cfg_t const * p_extend = (adc_extended_cfg_t const *) p_cfg->p_extend;
212 #endif
213
214 /* Save configurations. */
215 p_instance_ctrl->p_cfg = p_cfg;
216 p_instance_ctrl->p_callback = p_cfg->p_callback;
217 p_instance_ctrl->p_context = p_cfg->p_context;
218 p_instance_ctrl->p_callback_memory = NULL;
219
220 /* Calculate the register base address. */
221 uint32_t address_gap = (uint32_t) R_ADC1 - (uint32_t) R_ADC0;
222 p_instance_ctrl->p_reg = (R_ADC0_Type *) ((uint32_t) R_ADC0 + (address_gap * p_cfg->unit));
223
224 /* Initialize the hardware based on the configuration. */
225 r_adc_open_sub(p_instance_ctrl, p_cfg);
226
227 /* Enable interrupts */
228 r_adc_irq_enable(p_cfg->scan_end_irq, p_cfg->scan_end_ipl, p_instance_ctrl);
229 r_adc_irq_enable(p_cfg->scan_end_b_irq, p_cfg->scan_end_b_ipl, p_instance_ctrl);
230 r_adc_irq_enable(p_extend->window_a_irq, p_extend->window_a_ipl, p_instance_ctrl);
231 r_adc_irq_enable(p_extend->window_b_irq, p_extend->window_b_ipl, p_instance_ctrl);
232
233 /* Invalid scan mask (initialized for later). */
234 p_instance_ctrl->scan_mask = 0U;
235
236 /* Mark driver as opened by initializing it to "RADC" in its ASCII equivalent for this unit. */
237 p_instance_ctrl->opened = ADC_OPEN;
238
239 /* Return the error code */
240 return FSP_SUCCESS;
241 }
242
243 /*******************************************************************************************************************//**
244 * Configures the ADC scan parameters. Channel specific settings are set in this function. Pass a pointer to
245 * @ref adc_channel_cfg_t to p_channel_cfg.
246 *
247 * @note This starts group B scans if adc_channel_cfg_t::priority_group_a is set to ADC_GROUP_A_GROUP_B_CONTINUOUS_SCAN.
248 *
249 * @retval FSP_SUCCESS Channel specific settings applied.
250 * @retval FSP_ERR_ASSERTION An input argument is invalid.
251 * @retval FSP_ERR_NOT_OPEN Unit is not open.
252 **********************************************************************************************************************/
R_ADC_ScanCfg(adc_ctrl_t * p_ctrl,void const * const p_channel_cfg)253 fsp_err_t R_ADC_ScanCfg (adc_ctrl_t * p_ctrl, void const * const p_channel_cfg)
254 {
255 adc_channel_cfg_t const * p_adc_channel_cfg = (adc_channel_cfg_t const *) p_channel_cfg;
256 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
257 fsp_err_t err = FSP_SUCCESS;
258
259 #if ADC_CFG_PARAM_CHECKING_ENABLE
260 FSP_ASSERT(NULL != p_instance_ctrl);
261 FSP_ASSERT(NULL != p_adc_channel_cfg);
262 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
263
264 err = r_adc_scan_cfg_check(p_instance_ctrl, p_adc_channel_cfg);
265 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
266 #endif
267
268 /* Configure the hardware based on the configuration */
269 r_adc_scan_cfg(p_instance_ctrl, p_adc_channel_cfg);
270
271 /* Save the scan mask locally; this is required for the infoGet function. */
272 p_instance_ctrl->scan_mask = p_adc_channel_cfg->scan_mask;
273
274 /* Return the error code */
275 return err;
276 }
277
278 /*******************************************************************************************************************//**
279 * Updates the user callback and has option of providing memory for callback structure.
280 * Implements adc_api_t::callbackSet
281 *
282 * @retval FSP_SUCCESS Callback updated successfully.
283 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
284 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
285 * @retval FSP_ERR_NO_CALLBACK_MEMORY p_callback is non-secure and p_callback_memory is either secure or NULL.
286 **********************************************************************************************************************/
R_ADC_CallbackSet(adc_ctrl_t * const p_api_ctrl,void (* p_callback)(adc_callback_args_t *),void const * const p_context,adc_callback_args_t * const p_callback_memory)287 fsp_err_t R_ADC_CallbackSet (adc_ctrl_t * const p_api_ctrl,
288 void ( * p_callback)(adc_callback_args_t *),
289 void const * const p_context,
290 adc_callback_args_t * const p_callback_memory)
291 {
292 adc_instance_ctrl_t * p_ctrl = (adc_instance_ctrl_t *) p_api_ctrl;
293
294 #if (ADC_CFG_PARAM_CHECKING_ENABLE)
295 FSP_ASSERT(p_ctrl);
296 FSP_ASSERT(p_callback);
297 FSP_ERROR_RETURN(ADC_OPEN == p_ctrl->opened, FSP_ERR_NOT_OPEN);
298 #endif
299
300 /* Store callback and context */
301
302 #if BSP_TZ_SECURE_BUILD
303
304 /* Get security state of p_callback */
305 bool callback_is_secure =
306 (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
307
308 #if ADC_CFG_PARAM_CHECKING_ENABLE
309
310 /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
311 adc_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
312 CMSE_AU_NONSECURE);
313 FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
314 #endif
315
316 p_ctrl->p_callback = callback_is_secure ? p_callback :
317 (void (*)(adc_callback_args_t *))cmse_nsfptr_create(p_callback);
318 #else
319 p_ctrl->p_callback = p_callback;
320 #endif
321
322 p_ctrl->p_context = p_context;
323 p_ctrl->p_callback_memory = p_callback_memory;
324
325 return FSP_SUCCESS;
326 }
327
328 /*******************************************************************************************************************//**
329 * Starts a software scan or enables the hardware trigger for a scan depending on how the triggers were configured in
330 * the R_ADC_Open call. If the unit was configured for ELC or external hardware triggering, then this function allows
331 * the trigger signal to get to the ADC unit. The function is not able to control the generation of the trigger itself.
332 * If the unit was configured for software triggering, then this function starts the software triggered scan.
333 *
334 * @pre Call R_ADC_ScanCfg after R_ADC_Open before starting a scan.
335 *
336 * @pre On MCUs that support calibration, call R_ADC_Calibrate and wait for calibration to complete before starting
337 * a scan.
338 *
339 * @retval FSP_SUCCESS Scan started (software trigger) or hardware triggers enabled.
340 * @retval FSP_ERR_ASSERTION An input argument is invalid.
341 * @retval FSP_ERR_NOT_OPEN Unit is not open.
342 * @retval FSP_ERR_NOT_INITIALIZED Unit is not initialized.
343 * @retval FSP_ERR_IN_USE Another scan is still in progress (software trigger).
344 **********************************************************************************************************************/
R_ADC_ScanStart(adc_ctrl_t * p_ctrl)345 fsp_err_t R_ADC_ScanStart (adc_ctrl_t * p_ctrl)
346 {
347 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
348
349 /* Perform parameter checking */
350 #if ADC_CFG_PARAM_CHECKING_ENABLE
351
352 /* Verify the pointers are valid */
353 FSP_ASSERT(NULL != p_instance_ctrl);
354 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
355 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
356 if (ADC_GROUP_A_GROUP_B_CONTINUOUS_SCAN != p_instance_ctrl->p_reg->ADGSPCR)
357 {
358 FSP_ERROR_RETURN(0U == p_instance_ctrl->p_reg->ADCSR_b.ADST, FSP_ERR_IN_USE);
359 }
360 #endif
361
362 /* Enable hardware trigger or start software scan depending on mode. */
363 p_instance_ctrl->p_reg->ADCSR = p_instance_ctrl->scan_start_adcsr;
364
365 return FSP_SUCCESS;
366 }
367
368 /*******************************************************************************************************************//**
369 * @ref adc_api_t::scanStart is not supported on the ADCH. Use scanStart instead.
370 *
371 * @retval FSP_ERR_UNSUPPORTED Function not supported in this implementation.
372 **********************************************************************************************************************/
R_ADC_ScanGroupStart(adc_ctrl_t * p_ctrl,adc_group_mask_t group_id)373 fsp_err_t R_ADC_ScanGroupStart (adc_ctrl_t * p_ctrl, adc_group_mask_t group_id)
374 {
375 FSP_PARAMETER_NOT_USED(p_ctrl);
376 FSP_PARAMETER_NOT_USED(group_id);
377
378 /* Return the unsupported error. */
379 return FSP_ERR_UNSUPPORTED;
380 }
381
382 /*******************************************************************************************************************//**
383 * Stops the software scan or disables the unit from being triggered by the hardware trigger (ELC or external) based on
384 * what type of trigger the unit was configured for in the R_ADC_Open function. Stopping a hardware triggered scan via
385 * this function does not abort an ongoing scan, but prevents the next scan from occurring. Stopping a software
386 * triggered scan aborts an ongoing scan.
387 *
388 * @retval FSP_SUCCESS Scan stopped (software trigger) or hardware triggers disabled.
389 * @retval FSP_ERR_ASSERTION An input argument is invalid.
390 * @retval FSP_ERR_NOT_OPEN Unit is not open.
391 * @retval FSP_ERR_NOT_INITIALIZED Unit is not initialized.
392 **********************************************************************************************************************/
R_ADC_ScanStop(adc_ctrl_t * p_ctrl)393 fsp_err_t R_ADC_ScanStop (adc_ctrl_t * p_ctrl)
394 {
395 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
396
397 /* Perform parameter checking */
398 #if ADC_CFG_PARAM_CHECKING_ENABLE
399
400 /* Verify the pointers are valid */
401 FSP_ASSERT(NULL != p_instance_ctrl);
402 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
403 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
404 #endif
405
406 /* Disable hardware trigger or stop software scan depending on mode. */
407 p_instance_ctrl->p_reg->ADCSR = 0U;
408
409 return FSP_SUCCESS;
410 }
411
412 /*******************************************************************************************************************//**
413 * Provides the status of any scan process that was started, including scans started by ELC or external triggers and
414 * calibration scans on MCUs that support calibration.
415 *
416 * @retval FSP_SUCCESS Module status stored in the provided pointer p_status
417 * @retval FSP_ERR_ASSERTION An input argument is invalid.
418 * @retval FSP_ERR_NOT_OPEN Unit is not open.
419 **********************************************************************************************************************/
R_ADC_StatusGet(adc_ctrl_t * p_ctrl,adc_status_t * p_status)420 fsp_err_t R_ADC_StatusGet (adc_ctrl_t * p_ctrl, adc_status_t * p_status)
421 {
422 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
423
424 #if ADC_CFG_PARAM_CHECKING_ENABLE
425 FSP_ASSERT(NULL != p_instance_ctrl);
426 FSP_ASSERT(NULL != p_status);
427 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
428 #endif
429
430 /* Read the status of the ADST bit. ADST is set when a scan is in progress, including calibration scans. */
431 p_status->state = (adc_state_t) p_instance_ctrl->p_reg->ADCSR_b.ADST;
432
433 /* Return the error code */
434 return FSP_SUCCESS;
435 }
436
437 /*******************************************************************************************************************//**
438 * Reads conversion results from a single channel or sensor.
439 *
440 * @retval FSP_SUCCESS Data read into provided p_data.
441 * @retval FSP_ERR_ASSERTION An input argument is invalid.
442 * @retval FSP_ERR_NOT_OPEN Unit is not open.
443 * @retval FSP_ERR_NOT_INITIALIZED Unit is not initialized.
444 **********************************************************************************************************************/
R_ADC_Read(adc_ctrl_t * p_ctrl,adc_channel_t const reg_id,uint16_t * const p_data)445 fsp_err_t R_ADC_Read (adc_ctrl_t * p_ctrl, adc_channel_t const reg_id, uint16_t * const p_data)
446 {
447 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
448
449 /* Perform parameter checking. */
450 #if ADC_CFG_PARAM_CHECKING_ENABLE
451
452 /* Verify the pointers are valid */
453 FSP_ASSERT(NULL != p_instance_ctrl);
454 FSP_ASSERT(NULL != p_data);
455 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
456 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
457
458 /* Verify that the channel is valid for this MCU */
459 if ((reg_id >= ADC_CHANNEL_0) && ((uint32_t) reg_id <= 31U))
460 {
461 uint32_t requested_channel_mask = (1U << (uint32_t) reg_id);
462 FSP_ASSERT(0 != (requested_channel_mask & g_adc_valid_channels[p_instance_ctrl->p_cfg->unit]));
463 }
464 else
465 {
466 FSP_ASSERT((reg_id == ADC_CHANNEL_TEMPERATURE) || (reg_id == ADC_CHANNEL_VOLT) ||
467 (reg_id == ADC_CHANNEL_DUPLEX) || (reg_id == ADC_CHANNEL_DUPLEX_A) ||
468 (reg_id == ADC_CHANNEL_DUPLEX_B));
469 }
470
471 /* Data is not available to be read from ADDRn registers when ADBUF is enabled. Read API cannot be used with ADBUF enabled. */
472 adc_extended_cfg_t * p_extend = (adc_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
473 FSP_ASSERT(1U != p_extend->enable_adbuf);
474 #endif
475
476 /* Read the data from the requested ADC conversion register and return it */
477 *p_data = p_instance_ctrl->p_reg->ADDR[reg_id];
478
479 /* Return the error code */
480 return FSP_SUCCESS;
481 }
482
483 /*******************************************************************************************************************//**
484 * Reads conversion results from a single channel or sensor register into a 32-bit result.
485 *
486 * @retval FSP_SUCCESS Data read into provided p_data.
487 * @retval FSP_ERR_ASSERTION An input argument is invalid.
488 * @retval FSP_ERR_NOT_OPEN Unit is not open.
489 * @retval FSP_ERR_NOT_INITIALIZED Unit is not initialized.
490 **********************************************************************************************************************/
R_ADC_Read32(adc_ctrl_t * p_ctrl,adc_channel_t const reg_id,uint32_t * const p_data)491 fsp_err_t R_ADC_Read32 (adc_ctrl_t * p_ctrl, adc_channel_t const reg_id, uint32_t * const p_data)
492 {
493 uint16_t result = 0U;
494 uint32_t result_32 = 0U;
495
496 #if ADC_CFG_PARAM_CHECKING_ENABLE
497 FSP_ASSERT(NULL != p_data);
498 #endif
499
500 fsp_err_t err = R_ADC_Read(p_ctrl, reg_id, &result);
501 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
502
503 result_32 = result;
504
505 /* Left shift the result into the upper 16 bits if the unit is configured for left alignment. */
506 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
507 if (ADC_ALIGNMENT_LEFT == p_instance_ctrl->p_cfg->alignment)
508 {
509 result_32 <<= ADC_SHIFT_LEFT_ALIGNED_32_BIT;
510 }
511
512 *p_data = result_32;
513
514 return FSP_SUCCESS;
515 }
516
517 /*******************************************************************************************************************//**
518 * Sets the sample state count for individual channels. This only needs to be set for special use cases. Normally, use
519 * the default values out of reset.
520 *
521 * @note The sample states for the temperature and voltage sensor are set in R_ADC_ScanCfg.
522 *
523 * @retval FSP_SUCCESS Sample state count updated.
524 * @retval FSP_ERR_ASSERTION An input argument is invalid.
525 * @retval FSP_ERR_NOT_INITIALIZED Unit is not initialized.
526 * @retval FSP_ERR_NOT_OPEN Unit is not open.
527 **********************************************************************************************************************/
R_ADC_SampleStateCountSet(adc_ctrl_t * p_ctrl,adc_sample_state_t * p_sample)528 fsp_err_t R_ADC_SampleStateCountSet (adc_ctrl_t * p_ctrl, adc_sample_state_t * p_sample)
529 {
530 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
531 fsp_err_t err = FSP_SUCCESS;
532
533 /* Perform parameter checking */
534 #if ADC_CFG_PARAM_CHECKING_ENABLE
535
536 /* Verify the pointers are valid */
537 FSP_ASSERT(NULL != p_instance_ctrl);
538 FSP_ASSERT(NULL != p_sample);
539 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
540 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
541
542 /* Verify arguments are legal */
543 err = r_adc_sample_state_cfg_check(p_instance_ctrl, p_sample);
544 if (FSP_SUCCESS != err)
545 {
546 return err;
547 }
548 #endif
549
550 /* Set the sample state count for the specified register */
551 p_instance_ctrl->p_reg->ADSSTR[p_sample->reg_id] = p_sample->num_states;
552
553 /* Return the error code */
554 return err;
555 }
556
557 /*******************************************************************************************************************//**
558 * Returns the address of the lowest number configured channel and the total number of bytes to be read in order to
559 * read the results of the configured channels and return the ELC Event name. If no channels are configured, then a
560 * length of 0 is returned.
561 *
562 * Also provides the temperature sensor slope and the calibration data for the sensor if available on this MCU.
563 * Otherwise, invalid calibration data of 0xFFFFFFFF will be returned.
564 *
565 * @note In group mode, information is returned for group A only. Calculating information for group B is not currently
566 * supported.
567 *
568 * @retval FSP_SUCCESS Information stored in p_adc_info.
569 * @retval FSP_ERR_ASSERTION An input argument is invalid.
570 * @retval FSP_ERR_NOT_OPEN Unit is not open.
571 **********************************************************************************************************************/
R_ADC_InfoGet(adc_ctrl_t * p_ctrl,adc_info_t * p_adc_info)572 fsp_err_t R_ADC_InfoGet (adc_ctrl_t * p_ctrl, adc_info_t * p_adc_info)
573 {
574 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
575 fsp_err_t err = FSP_SUCCESS;
576 uint32_t adc_mask = 0;
577
578 #if ADC_CFG_PARAM_CHECKING_ENABLE
579 FSP_ASSERT(NULL != p_instance_ctrl);
580 FSP_ASSERT(NULL != p_adc_info);
581 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
582 #endif
583
584 /* Retrieve the scan mask of active channels from the control structure */
585 adc_mask = p_instance_ctrl->scan_mask;
586
587 /* If at least one channel is configured, determine the highest and lowest configured channels. */
588 if (adc_mask != 0U)
589 {
590 /* Determine the lowest channel that is configured. The lowest sensor is the temperature sensor, at -3 from
591 * channel 0. To get all channels in register order, shift up by 3, then add in the sensors in the bottom
592 * 2 bits. */
593 uint32_t adc_mask_in_order = adc_mask & ~(uint32_t) ADC_MASK_SENSORS;
594 adc_mask_in_order <<= 3U;
595 adc_mask_in_order |= adc_mask >> ADC_MASK_FIRST_SENSOR_BIT;
596 int32_t lowest_channel = r_adc_lowest_channel_get(adc_mask_in_order);
597 p_adc_info->p_address = &p_instance_ctrl->p_reg->ADDR[lowest_channel - 3];
598
599 /* Determine the highest channel that is configured. */
600 int32_t highest_channel = 31 - __CLZ(adc_mask_in_order);
601
602 /* Determine the size of data that must be read to read all the channels between and including the
603 * highest and lowest channels.*/
604 p_adc_info->length = (uint32_t) ((highest_channel - lowest_channel) + 1);
605 }
606 else
607 {
608 /* If no channels are configured, set the return length 0. */
609 p_adc_info->length = 0U;
610 }
611
612 p_adc_info->transfer_size = TRANSFER_SIZE_2_BYTE;
613
614 #if BSP_FEATURE_ADC_UNIT_1_CHANNELS
615
616 /* Specify the peripheral name in the ELC list */
617 p_adc_info->elc_event =
618 (elc_event_t) ((uint32_t) ELC_EVENT_ADC0_SCAN_END +
619 (p_instance_ctrl->p_cfg->unit *
620 ((uint32_t) ELC_EVENT_ADC1_SCAN_END - (uint32_t) ELC_EVENT_ADC0_SCAN_END)));
621 #else
622 p_adc_info->elc_event = ELC_EVENT_ADC0_SCAN_END;
623 #endif
624
625 p_adc_info->elc_peripheral = (elc_peripheral_t) (ELC_PERIPHERAL_ADC0 + (2U * p_instance_ctrl->p_cfg->unit));
626
627 /* Set Temp Sensor calibration data to invalid value */
628 p_adc_info->calibration_data = UINT32_MAX;
629
630 /* If calibration register is available, retrieve it from the MCU */
631 #if 1U == BSP_FEATURE_ADC_TSN_CALIBRATION_AVAILABLE
632 #if 1U == BSP_FEATURE_ADC_TSN_CALIBRATION32_AVAILABLE
633
634 /* Read into memory. */
635 uint32_t data = R_TSN_CAL->TSCDR;
636
637 /* Read the temperature calibration data from ROM. */
638 p_adc_info->calibration_data = (data & BSP_FEATURE_ADC_TSN_CALIBRATION32_MASK);
639 #else
640
641 /* Read into memory to prevent compiler warning when performing "|" on volatile register data. */
642 uint32_t high = R_TSN->TSCDRH;
643 uint32_t low = R_TSN->TSCDRL;
644
645 /* Read the calibration data from ROM and shift to fit into result variable. */
646 p_adc_info->calibration_data = ((high << 8) | low);
647 #endif
648 #endif
649
650 /* Provide the previously retrieved slope information */
651 p_adc_info->slope_microvolts = BSP_FEATURE_ADC_TSN_SLOPE;
652
653 return err;
654 }
655
656 /*******************************************************************************************************************//**
657 * This function ends any scan in progress, disables interrupts, and removes power to the A/D peripheral.
658 *
659 * @retval FSP_SUCCESS Module closed.
660 * @retval FSP_ERR_ASSERTION An input argument is invalid.
661 * @retval FSP_ERR_NOT_OPEN Unit is not open.
662 **********************************************************************************************************************/
R_ADC_Close(adc_ctrl_t * p_ctrl)663 fsp_err_t R_ADC_Close (adc_ctrl_t * p_ctrl)
664 {
665 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
666
667 #if ADC_CFG_PARAM_CHECKING_ENABLE
668 FSP_ASSERT(NULL != p_instance_ctrl);
669 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
670 #endif
671
672 /* Mark driver as closed */
673 p_instance_ctrl->opened = 0U;
674 p_instance_ctrl->initialized = 0U;
675
676 /* Disable interrupts. */
677 adc_extended_cfg_t * p_extend = (adc_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
678 r_adc_irq_disable(p_instance_ctrl->p_cfg->scan_end_irq);
679 r_adc_irq_disable(p_instance_ctrl->p_cfg->scan_end_b_irq);
680 r_adc_irq_disable(p_extend->window_a_irq);
681 r_adc_irq_disable(p_extend->window_b_irq);
682
683 /* Disable triggers. */
684 p_instance_ctrl->p_reg->ADSTRGR = 0U;
685
686 /* Stop the ADC. */
687 p_instance_ctrl->p_reg->ADCSR = 0U;
688
689 #if BSP_FEATURE_ADC_HAS_SAMPLE_HOLD_REG
690
691 /* Disable sample and hold before entering module stop state to reduce power consumption (reference section 47.6.8
692 * "Available Functions and Register Settings of AN000 to AN002, AN007, AN100 to AN102, and AN107" in the RA6M3
693 * manual R01UH0886EJ0100. */
694 p_instance_ctrl->p_reg->ADSHCR = 0U;
695 #endif
696
697 #if BSP_FEATURE_ADC_HAS_VREFAMPCNT
698
699 /* If VREFADC is selected as the high-potential reference voltage revert it to reduce power consumption. */
700 p_instance_ctrl->p_reg->VREFAMPCNT = 0U;
701 #endif
702
703 R_BSP_MODULE_STOP(FSP_IP_ADC, p_instance_ctrl->p_cfg->unit);
704
705 /* Return the error code */
706 return FSP_SUCCESS;
707 }
708
709 /*******************************************************************************************************************//**
710 * Initiates calibration of the ADC on MCUs that require calibration. This function must be called before starting
711 * a scan on MCUs that require calibration.
712 *
713 * Calibration is complete when the callback is called with ADC_EVENT_CALIBRATION_COMPLETE or when R_ADC_StatusGet
714 * returns ADC_STATUS_IDLE. Reference Figure 32.35 "Software flow and operation example of calibration operation."
715 * in the RA2A1 manual R01UH0888EJ0100.
716 *
717 * ADC calibration time: 12 PCLKB + 774,930 ADCLK. (Reference Table 32.16 "Required calibration time (shown
718 * as the number of ADCLK and PCLKB cycles)" in the RA2A1 manual R01UH0888EJ0100. The lowest supported ADCLK
719 * is 1MHz.
720 *
721 * Calibration will take a minimum of 24 milliseconds at 32 MHz PCLKB and ADCLK. This wait could take up to 780
722 * milliseconds for a 1 MHz PCLKD (ADCLK).
723 *
724 * @param[in] p_ctrl Pointer to the instance control structure
725 * @param[in] p_extend Unused argument. Pass NULL.
726 *
727 * @retval FSP_SUCCESS Calibration successfully initiated.
728 * @retval FSP_ERR_INVALID_HW_CONDITION A scan is in progress or hardware triggers are enabled.
729 * @retval FSP_ERR_UNSUPPORTED Calibration not supported on this MCU.
730 * @retval FSP_ERR_ASSERTION An input argument is invalid.
731 * @retval FSP_ERR_NOT_OPEN Unit is not open.
732 **********************************************************************************************************************/
R_ADC_Calibrate(adc_ctrl_t * const p_ctrl,void const * p_extend)733 fsp_err_t R_ADC_Calibrate (adc_ctrl_t * const p_ctrl, void const * p_extend)
734 {
735 FSP_PARAMETER_NOT_USED(p_extend);
736
737 #if BSP_FEATURE_ADC_CALIBRATION_REG_AVAILABLE
738 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) p_ctrl;
739 #if ADC_CFG_PARAM_CHECKING_ENABLE
740 FSP_ASSERT(NULL != p_ctrl);
741 FSP_ERROR_RETURN(ADC_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
742 #endif
743
744 /* ADC Calibration can only happen if there is no ongoing scan and if the scan trigger is disabled */
745 FSP_ERROR_RETURN(!(p_instance_ctrl->p_reg->ADCSR & ADC_PRV_ADCSR_ADST_TRGE_MASK), FSP_ERR_INVALID_HW_CONDITION);
746
747 /* Set the normal mode interrupt request to occur when calibration is complete */
748 p_instance_ctrl->p_reg->ADICR = ADC_ADICR_CALIBRATION_INTERRUPT_ENABLED;
749
750 /* Initiate calibration */
751 p_instance_ctrl->p_reg->ADCALEXE = ADC_ADCALEXE_SET_CALEXE;
752
753 return FSP_SUCCESS;
754 #else
755 FSP_PARAMETER_NOT_USED(p_ctrl);
756 FSP_ERROR_LOG(FSP_ERR_UNSUPPORTED);
757
758 return FSP_ERR_UNSUPPORTED;
759 #endif
760 }
761
762 /*******************************************************************************************************************//**
763 * @ref adc_api_t::offsetSet is not supported on the ADC.
764 *
765 * @retval FSP_ERR_UNSUPPORTED Function not supported in this implementation.
766 **********************************************************************************************************************/
R_ADC_OffsetSet(adc_ctrl_t * const p_ctrl,adc_channel_t const reg_id,int32_t offset)767 fsp_err_t R_ADC_OffsetSet (adc_ctrl_t * const p_ctrl, adc_channel_t const reg_id, int32_t offset)
768 {
769 FSP_PARAMETER_NOT_USED(p_ctrl);
770 FSP_PARAMETER_NOT_USED(reg_id);
771 FSP_PARAMETER_NOT_USED(offset);
772
773 /* Return the unsupported error. */
774 return FSP_ERR_UNSUPPORTED;
775 }
776
777 /*******************************************************************************************************************//**
778 * @} (end addtogroup ADC)
779 **********************************************************************************************************************/
780
781 /***********************************************************************************************************************
782 * Private Functions
783 **********************************************************************************************************************/
784
785 #if ADC_CFG_PARAM_CHECKING_ENABLE
786
787 /*******************************************************************************************************************//**
788 * Checks the sample state configuration.
789 *
790 * @param[in] p_instance_ctrl Pointer to instance control structure
791 * @param[in] p_sample Pointer to sample state configuration
792 *
793 * @retval FSP_SUCCESS No configuration errors detected
794 * @retval FSP_ERR_ASSERTION An input argument is invalid.
795 **********************************************************************************************************************/
r_adc_sample_state_cfg_check(adc_instance_ctrl_t * p_instance_ctrl,adc_sample_state_t * p_sample)796 static fsp_err_t r_adc_sample_state_cfg_check (adc_instance_ctrl_t * p_instance_ctrl, adc_sample_state_t * p_sample)
797 {
798 /* Used to prevent compiler warning */
799 FSP_PARAMETER_NOT_USED(p_instance_ctrl);
800
801 adc_sample_state_reg_t reg_id = p_sample->reg_id;
802
803 /* Verify the requested channel exists on the MCU. */
804 if (reg_id >= ADC_SAMPLE_STATE_CHANNEL_0)
805 {
806 uint32_t requested_channel_mask = (1U << (uint32_t) reg_id);
807 FSP_ASSERT(0 != (requested_channel_mask & g_adc_valid_channels[p_instance_ctrl->p_cfg->unit]));
808 }
809
810 /* Verify the requested sample states is not less than the minimum. */
811 FSP_ASSERT(p_sample->num_states >= ADC_SAMPLE_STATE_COUNT_MIN);
812
813 return FSP_SUCCESS;
814 }
815
816 #endif
817
818 #if ADC_CFG_PARAM_CHECKING_ENABLE
819
820 /*******************************************************************************************************************//**
821 * Validates the configuration arguments for illegal combinations or options.
822 *
823 * @param[in] p_cfg Pointer to configuration structure
824 *
825 * @retval FSP_SUCCESS No configuration errors detected
826 * @retval FSP_ERR_ASSERTION An input argument is invalid.
827 * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT ADC unit not present on this MCU
828 * @retval FSP_ERR_INVALID_HW_CONDITION The ADC clock must be at least 1 MHz
829 **********************************************************************************************************************/
r_adc_open_cfg_check(adc_cfg_t const * const p_cfg)830 static fsp_err_t r_adc_open_cfg_check (adc_cfg_t const * const p_cfg)
831 {
832 FSP_ASSERT(NULL != p_cfg);
833
834 /* Verify the unit exists on the MCU. */
835 FSP_ERROR_RETURN(((1U << p_cfg->unit) & BSP_FEATURE_ADC_VALID_UNIT_MASK), FSP_ERR_IP_CHANNEL_NOT_PRESENT);
836
837 /* Verify the ADC clock frequency is at least 1 MHz (reference "Frequency" row of table "60.5 ADC12
838 * Characteristics" in the RA6M3 manual R01UH0886EJ0100. The maximum frequency is the maximum frequency supported
839 * by the ADCLK, so it is not verified here. */
840 uint32_t freq_hz = R_FSP_SystemClockHzGet(BSP_FEATURE_ADC_CLOCK_SOURCE);
841 FSP_ERROR_RETURN(freq_hz >= ADC_PRV_MIN_ADCLK_HZ, FSP_ERR_INVALID_HW_CONDITION);
842
843 /* Check for valid argument values for addition/averaging. Reference section 47.2.10 "A/D-Converted Value
844 * Addition/Average Count Select Register (ADADC)" in the RA6M3 manual R01UH0886EJ0100 and section 32.2.11
845 * "A/D-Converted Value Average Count Select Register (ADADC)" in the RA2A1 manual R01UH0888EJ0100. */
846 adc_extended_cfg_t const * p_cfg_extend = (adc_extended_cfg_t const *) p_cfg->p_extend;
847 if (ADC_ADD_OFF != p_cfg_extend->add_average_count)
848 {
849 #if BSP_FEATURE_ADC_ADDITION_SUPPORTED
850
851 /* The ADC12 and ADC14 do not support averaging 8 or 16 samples. */
852 FSP_ASSERT(p_cfg_extend->add_average_count <= ADC_ADD_AVERAGE_FOUR);
853 #else
854
855 /* The ADC16 supports averaging only, it does not support addition. */
856 FSP_ASSERT(0U != (ADC_ADADC_AVEE_BIT & p_cfg_extend->add_average_count));
857 #endif
858 }
859
860 /* If 16 time addition is used only 12 bit accuracy can be selected. Reference Note 1 of section 47.2.10
861 * "A/D-Converted Value Addition/Average Count Select Register (ADADC)" in the RA6M3 manual R01UH0886EJ0100. */
862 if (ADC_ADD_SIXTEEN == p_cfg_extend->add_average_count)
863 {
864 FSP_ASSERT(ADC_RESOLUTION_12_BIT == p_cfg->resolution);
865 }
866
867 /* Only synchronous triggers (ELC) allowed in group scan mode (reference TRSA documentation in section 47.2.12
868 * "A/D Conversion Start Trigger Select Register (ADSTRGR)" in the RA6M3 manual R01UH0886EJ0100. */
869 if ((ADC_MODE_GROUP_SCAN == p_cfg->mode) || (ADC_DOUBLE_TRIGGER_DISABLED != p_cfg_extend->double_trigger_mode))
870 {
871 FSP_ASSERT((ADC_START_SOURCE_DISABLED != p_cfg_extend->trigger) &&
872 (ADC_START_SOURCE_ASYNC_EXTERNAL != p_cfg_extend->trigger));
873
874 if ((ADC_MODE_GROUP_SCAN == p_cfg->mode))
875 {
876 FSP_ASSERT((ADC_START_SOURCE_DISABLED != p_cfg_extend->trigger_group_b) && \
877 (ADC_START_SOURCE_ASYNC_EXTERNAL != p_cfg_extend->trigger_group_b));
878 }
879 }
880
881 return FSP_SUCCESS;
882 }
883
884 #endif
885
886 #if ADC_CFG_PARAM_CHECKING_ENABLE
887
888 /*******************************************************************************************************************//**
889 * This function validates the resolution configuration arguments for illegal combinations or options.
890 *
891 * @param[in] p_cfg Pointer to configuration structure
892 *
893 * @retval FSP_SUCCESS No configuration errors detected
894 * @retval FSP_ERR_ASSERTION An input argument is invalid.
895 **********************************************************************************************************************/
r_adc_open_cfg_resolution_check(adc_cfg_t const * const p_cfg)896 static fsp_err_t r_adc_open_cfg_resolution_check (adc_cfg_t const * const p_cfg)
897 {
898 #if 12U == BSP_FEATURE_ADC_MAX_RESOLUTION_BITS
899 #if BSP_FEATURE_ADC_HAS_ADCER_ADPRC
900
901 /* Resolution options for ADC12 (reference section 47.2.11 "A/D Control Extended Register (ADCER)" in the RA6M3
902 * manual R01UH0886EJ0100. */
903 FSP_ASSERT((ADC_RESOLUTION_12_BIT == p_cfg->resolution) ||
904 (ADC_RESOLUTION_10_BIT == p_cfg->resolution) ||
905 (ADC_RESOLUTION_8_BIT == p_cfg->resolution));
906 #else
907 FSP_ASSERT(ADC_RESOLUTION_12_BIT == p_cfg->resolution);
908 #endif
909 #endif
910
911 #if 14U == BSP_FEATURE_ADC_MAX_RESOLUTION_BITS
912
913 /* Resolution options for ADC14 (reference section 35.2.11 "A/D Control Extended Register (ADCER)" in the RA4M1
914 * manual R01UH0886EJ0100. */
915 FSP_ASSERT((ADC_RESOLUTION_12_BIT == p_cfg->resolution) ||
916 (ADC_RESOLUTION_14_BIT == p_cfg->resolution));
917 #endif
918
919 #if 16U == BSP_FEATURE_ADC_MAX_RESOLUTION_BITS
920
921 /* ADC16 only offers 16-bit resolution (reference Table 32.1 "ADC16 specifications (1 of 2)" in the RA2A1 manual
922 * R01UH0888EJ0100. */
923 FSP_ASSERT(ADC_RESOLUTION_16_BIT == p_cfg->resolution);
924 #endif
925
926 return FSP_SUCCESS;
927 }
928
929 #endif
930
931 #if ADC_CFG_PARAM_CHECKING_ENABLE
932
933 /*******************************************************************************************************************//**
934 * Checks the sample and hold arguments
935 *
936 * @param[in] p_instance_ctrl Pointer to instance control block
937 * @param[in] p_channel_cfg Pointer to channel configuration
938 *
939 * @retval FSP_SUCCESS No configuration errors detected
940 * @retval FSP_ERR_ASSERTION An input argument is invalid.
941 **********************************************************************************************************************/
r_adc_scan_cfg_check_sample_hold(adc_instance_ctrl_t * const p_instance_ctrl,adc_channel_cfg_t const * const p_channel_cfg)942 static fsp_err_t r_adc_scan_cfg_check_sample_hold (adc_instance_ctrl_t * const p_instance_ctrl,
943 adc_channel_cfg_t const * const p_channel_cfg)
944 {
945 #if !BSP_FEATURE_ADC_HAS_SAMPLE_HOLD_REG
946
947 /* If the MCU does not have sample and hold, verify the sample and hold feature is not used. */
948 FSP_ASSERT(0U == p_channel_cfg->sample_hold_mask);
949 FSP_PARAMETER_NOT_USED(p_instance_ctrl);
950 #else
951 if (0U != p_channel_cfg->sample_hold_mask)
952 {
953 /* Sample and Hold channels can only be 0, 1, 2 and must have at least minimum state count specified (reference
954 * section 47.2.15 "A/D Sample and Hold Circuit Control Register (ADSHCR)" in the RA6M3 manual
955 * R01UH0886EJ0100. */
956 FSP_ASSERT(p_channel_cfg->sample_hold_mask <= ADC_SAMPLE_HOLD_CHANNELS);
957 FSP_ASSERT(p_channel_cfg->sample_hold_states >= ADC_SAMPLE_STATE_HOLD_COUNT_MIN);
958
959 uint32_t b_mask = p_channel_cfg->sample_hold_mask & p_channel_cfg->scan_mask_group_b;
960 if (ADC_MODE_GROUP_SCAN == p_instance_ctrl->p_cfg->mode)
961 {
962 if (ADC_GROUP_A_PRIORITY_OFF != p_channel_cfg->priority_group_a)
963 {
964 /* Sample and hold channels cannot be in GroupB if GroupA priority enabled. (reference SHANS[2:0] bits
965 * in section 47.2.15 "A/D Sample and Hold Circuit Control Register (ADSHCR)" in the RA6M3 manual
966 * R01UH0886EJ0100.*/
967 FSP_ASSERT(0 == b_mask);
968 }
969 }
970 }
971 #endif
972
973 return FSP_SUCCESS;
974 }
975
976 /*******************************************************************************************************************//**
977 * Enforces constraints on Window Compare function usage per section 47.3.5.3 "Constraints on the compare function" in
978 * the RA6M3 User's Manual (R01UH0886EJ0100)
979 *
980 * @param[in] p_window_cfg Pointer to window compare configuration
981 *
982 * @retval FSP_SUCCESS No configuration errors detected
983 * @retval FSP_ERR_ASSERTION An input argument is invalid.
984 **********************************************************************************************************************/
r_adc_scan_cfg_check_window_compare(adc_window_cfg_t const * const p_window_cfg)985 static fsp_err_t r_adc_scan_cfg_check_window_compare (adc_window_cfg_t const * const p_window_cfg)
986 {
987 if (p_window_cfg)
988 {
989 uint32_t compare_cfg = p_window_cfg->compare_cfg;
990 if (0U != compare_cfg)
991 {
992 if ((compare_cfg & R_ADC0_ADCMPCR_CMPAE_Msk) && (compare_cfg & R_ADC0_ADCMPCR_CMPBE_Msk))
993 {
994 /* Ensure channels selected for Window A do not conflict with Window B */
995 uint32_t compare_b_ch = p_window_cfg->compare_b_channel;
996 compare_b_ch -= compare_b_ch > 31 ? 4 : 0;
997 FSP_ASSERT(!(p_window_cfg->compare_mask & (uint32_t) (1 << compare_b_ch)));
998 }
999
1000 if (compare_cfg & R_ADC0_ADCMPCR_WCMPE_Msk)
1001 {
1002 /* Ensure lower reference values are less than or equal to the high reference values */
1003 FSP_ASSERT((p_window_cfg->compare_ref_low <= p_window_cfg->compare_ref_high) &&
1004 (p_window_cfg->compare_b_ref_low <= p_window_cfg->compare_b_ref_high));
1005 }
1006 }
1007 }
1008
1009 return FSP_SUCCESS;
1010 }
1011
1012 #endif
1013
1014 #if ADC_CFG_PARAM_CHECKING_ENABLE
1015
1016 /*******************************************************************************************************************//**
1017 * This function checks the Temperature and Voltage sensor arguments
1018 *
1019 * @param[in] p_instance_ctrl Pointer to instance control block
1020 * @param[in] p_channel_cfg Pointer to channel configuration
1021 *
1022 * @retval FSP_SUCCESS No configuration errors detected
1023 * @retval FSP_ERR_ASSERTION Sensor configuration has been selected for Group B on an MCU which does not allow
1024 * Group B configuration or sensor is used in Normal/Group A with the double trigger
1025 * not enabled or MCU does not allow both the sensors to be used simultaneously
1026 **********************************************************************************************************************/
r_adc_scan_cfg_check_sensors(adc_instance_ctrl_t * const p_instance_ctrl,adc_channel_cfg_t const * const p_channel_cfg)1027 static fsp_err_t r_adc_scan_cfg_check_sensors (adc_instance_ctrl_t * const p_instance_ctrl,
1028 adc_channel_cfg_t const * const p_channel_cfg)
1029 {
1030 /* Some MCUs have nothing to check here. */
1031 FSP_PARAMETER_NOT_USED(p_channel_cfg);
1032
1033 #if !BSP_FEATURE_ADC_GROUP_B_SENSORS_ALLOWED
1034
1035 /* Sensors are not supported in Group B in some MCUs. Reference section 32.2.14 "A/D Conversion Extended Input
1036 * Control Register (ADEXICR)" of the RA2A1 manual R01UH0888EJ0100. */
1037 FSP_ASSERT(0U == (p_channel_cfg->scan_mask_group_b & ADC_MASK_SENSORS));
1038 #endif
1039
1040 #if BSP_FEATURE_ADC_SENSORS_EXCLUSIVE
1041 uint32_t sensor_mask = p_channel_cfg->scan_mask & ADC_MASK_SENSORS;
1042 if (0U != sensor_mask)
1043 {
1044 /* If the temperature sensor or the internal voltage reference is used, then none of the channels can be used
1045 * at the same time. The temperature sensor and the internal voltage reference can only be used in single scan
1046 * mode. Reference TSSA and OCSA bits in section 35.2.13 "A/D Conversion Extended Input Control Register
1047 * (ADEXICR)" of the RA4M1 manual R01UH0887EJ0100. */
1048 FSP_ASSERT(ADC_MASK_SENSORS != sensor_mask);
1049 FSP_ASSERT(p_channel_cfg->scan_mask == sensor_mask);
1050 FSP_ASSERT(ADC_MODE_SINGLE_SCAN == p_instance_ctrl->p_cfg->mode);
1051 }
1052 #endif
1053
1054 /* When using double-trigger modes the sensors must not be configured or used in Group A. */
1055 adc_extended_cfg_t const * p_cfg_extend = (adc_extended_cfg_t const *) p_instance_ctrl->p_cfg->p_extend;
1056 if (ADC_DOUBLE_TRIGGER_DISABLED != p_cfg_extend->double_trigger_mode)
1057 {
1058 FSP_ASSERT(0U == (p_channel_cfg->scan_mask & ADC_MASK_SENSORS));
1059 }
1060
1061 return FSP_SUCCESS;
1062 }
1063
1064 #endif
1065
1066 /*******************************************************************************************************************//**
1067 * The Open function applies power to the A/D peripheral, sets the operational mode, trigger sources, and
1068 * configurations common to all channels and sensors.
1069 *
1070 * @param[in] p_instance_ctrl Pointer to instance control block
1071 * @param[in] p_cfg Pointer to configuration structure
1072 **********************************************************************************************************************/
r_adc_open_sub(adc_instance_ctrl_t * const p_instance_ctrl,adc_cfg_t const * const p_cfg)1073 static void r_adc_open_sub (adc_instance_ctrl_t * const p_instance_ctrl, adc_cfg_t const * const p_cfg)
1074 {
1075 adc_extended_cfg_t const * p_cfg_extend = (adc_extended_cfg_t const *) p_cfg->p_extend;
1076
1077 /* Determine the value for ADCSR:
1078 * * The configured mode is set in ADCSR.ADCS.
1079 * * Low-power conversion mode must be selected when internal reference voltage is selected as the high-potential
1080 * reference voltage.
1081 * * ADCSR.GBADIE is always set by this driver. It will only trigger an interrupt in group mode if the group B
1082 * interrupt is enabled.
1083 * * If double-trigger mode is selected ADCSR.DBLANS is set to the chosen double-trigger scan channel and
1084 * ADCSR.DBLE is set to 1; otherwise, both are set to 0.
1085 * * The configured trigger mode is set in ADCSR.EXTRG and ADCSR.TRGE.
1086 * * The value to set in ADCSR to start a scan is stored in the control structure. ADCSR.ADST is set in
1087 * R_ADC_ScanStart if software trigger mode is used.
1088 */
1089 uint32_t adcsr = (uint32_t) (p_cfg->mode << R_ADC0_ADCSR_ADCS_Pos);
1090 adcsr |= (uint32_t) (R_ADC0_ADCSR_GBADIE_Msk | R_ADC0_ADCSR_TRGE_Msk);
1091 adcsr |= ((uint32_t) (ADC_START_SOURCE_ASYNC_EXTERNAL == p_cfg_extend->trigger) << R_ADC0_ADCSR_EXTRG_Pos); // Only check GroupA. GroupB is never external.
1092 adcsr |= ((uint32_t) (ADC_START_SOURCE_DISABLED != p_cfg_extend->trigger) << R_ADC0_ADCSR_TRGE_Pos); // Only check GroupA. GroupB is never external.
1093
1094 #if BSP_FEATURE_ADC_HAS_ADHVREFCNT
1095 if (ADC_PRV_ADHVREFCNT_VREF_INTERNAL_BIT_1 & p_cfg_extend->adc_vref_control)
1096 {
1097 adcsr |= R_ADC0_ADCSR_ADHSC_Msk;
1098 }
1099 #endif
1100
1101 if (ADC_DOUBLE_TRIGGER_DISABLED != p_cfg_extend->double_trigger_mode)
1102 {
1103 adcsr |= R_ADC0_ADCSR_DBLE_Msk;
1104 }
1105 else if (ADC_START_SOURCE_DISABLED == p_cfg_extend->trigger)
1106 {
1107 adcsr |= R_ADC0_ADCSR_ADST_Msk;
1108 }
1109 else
1110 {
1111 /* Do nothing. */
1112 }
1113
1114 p_instance_ctrl->scan_start_adcsr = (uint16_t) adcsr;
1115
1116 /* The default value for ADSTRGR is 0 out of reset. Update it only if the ADC is triggered on ELC events. */
1117
1118 /* Set ADSTRGR per the following:
1119 * Extended double-trigger mode:
1120 * - Normal (Group A): ELC_PERIPHERAL_ADCn and ELC_PERIPHERAL_ADCn_B
1121 * - Group B: None
1122 * All other modes:
1123 * - Normal (Group A): ELC_PERIPHERAL_ADCn
1124 * - Group B: ELC_PERIPHERAL_ADCn_B
1125 */
1126 uint32_t adstrgr =
1127 ((R_ADC0_ADSTRGR_TRSA_Msk & ((uint32_t) p_cfg_extend->trigger << R_ADC0_ADSTRGR_TRSA_Pos)) | \
1128 (R_ADC0_ADSTRGR_TRSB_Msk & ((uint32_t) p_cfg_extend->trigger_group_b << R_ADC0_ADSTRGR_TRSB_Pos)));
1129
1130 /* Determine the value for ADCER:
1131 * * The resolution is set as configured in ADCER.ADPRC (on MCUs that have this bitfield).
1132 * * The alignment is set as configured in ADCER.ADFMT (on MCUs that have this bitfield).
1133 * * The clearing option is set as configured in ADCER.ACE.
1134 * * Always select data range of 0 - 32767 in ADCER.INV (on MCUs that have this bitfield).
1135 * * Always disable self-diagnosis (unsupported in this module).
1136 */
1137 uint32_t adcer = 0U;
1138 #if BSP_FEATURE_ADC_HAS_ADCER_ADPRC
1139 adcer |= (uint32_t) p_cfg->resolution << R_ADC0_ADCER_ADPRC_Pos;
1140 #endif
1141 #if BSP_FEATURE_ADC_HAS_ADCER_ADRFMT
1142 adcer |= (uint32_t) p_cfg->alignment << R_ADC0_ADCER_ADRFMT_Pos;
1143 #endif
1144 adcer |= (uint32_t) p_cfg_extend->clearing << R_ADC0_ADCER_ACE_Pos;
1145
1146 #if BSP_FEATURE_ADC_CALIBRATION_REG_AVAILABLE
1147 adcer |= 1U << R_ADC0_ADCER_ADINV_Pos;
1148 #endif
1149
1150 /* Determine the value for ADADC:
1151 * * The addition/averaging modes are set as configured in ADADC.ADC and ADADC.AVEE.
1152 * * On MCUs that do not have the ADADC.AVEE bit (addition not supported), the ADADC.AVEE bit is cleared.
1153 */
1154 uint32_t adadc = p_cfg_extend->add_average_count;
1155 #if !BSP_FEATURE_ADC_ADDITION_SUPPORTED
1156 adadc &= ~ADC_ADADC_AVEE_BIT;
1157 #endif
1158
1159 /* Apply clock to peripheral. */
1160 R_BSP_MODULE_START(FSP_IP_ADC, p_cfg->unit);
1161
1162 /* Set the predetermined values for ADCSR, ADSTRGR, ADCER, and ADADC without setting ADCSR.ADST or ADCSR.TRGE.
1163 * ADCSR.ADST or ADCSR.TRGE are set as configured in R_ADC_ScanStart. */
1164 p_instance_ctrl->p_reg->ADCSR = (uint16_t) (adcsr & ADC_PRV_ADCSR_CLEAR_ADST_TRGE);
1165 p_instance_ctrl->p_reg->ADSTRGR = (uint16_t) adstrgr;
1166 p_instance_ctrl->p_reg->ADCER = (uint16_t) adcer;
1167 p_instance_ctrl->p_reg->ADADC = (uint8_t) adadc;
1168
1169 #if BSP_FEATURE_ADC_HAS_PGA
1170
1171 /* Disable the unused ADC PGA feature (on MCUs where it is available) since the feature is enabled out of reset on
1172 * some MCUs and disabled on others and affects the operation of the normal ADC channels that are multiplexed with
1173 * the PGA. */
1174 p_instance_ctrl->p_reg->ADPGADCR0 = ADC_ADPGADCR0_DISABLE_PGA;
1175 p_instance_ctrl->p_reg->ADPGACR = ADC_ADPGACR_DISABLE_PGA;
1176 #endif
1177
1178 #if BSP_FEATURE_ADC_CALIBRATION_REG_AVAILABLE
1179
1180 /* Use ADC in single-ended mode. */
1181 p_instance_ctrl->p_reg->ADANIM = 0U;
1182 #endif
1183
1184 #if BSP_FEATURE_ADC_HAS_VREFAMPCNT
1185
1186 /* If VREFADC is selected as the high-potential reference voltage. */
1187 if (ADC_VREF_CONTROL_VREFH != p_cfg_extend->adc_vref_control)
1188 {
1189 /* Configure Reference Voltage controls
1190 * Reference section "32.6 Selecting Reference Voltage" in the RA2A1 manual R01UH0888EJ0100. */
1191 p_instance_ctrl->p_reg->VREFAMPCNT =
1192 (uint8_t) (p_cfg_extend->adc_vref_control &
1193 (R_ADC0_VREFAMPCNT_BGREN_Msk | R_ADC0_VREFAMPCNT_VREFADCG_Msk));
1194
1195 R_BSP_SoftwareDelay(ADC_BGR_STABILIZATION_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
1196
1197 /* Enable Over current detection and VREFADC output */
1198 p_instance_ctrl->p_reg->VREFAMPCNT = (uint8_t) (p_cfg_extend->adc_vref_control);
1199 }
1200 #endif
1201
1202 #if BSP_FEATURE_ADC_HAS_ADHVREFCNT
1203
1204 /* If the internal voltage is set as VREFH, discharge the VREF node for 1 us before setting ADHVREFCNT.HVSEL to 2.
1205 * Reference section 35.7 "A/D Conversion Procedure when Selecting Internal Reference Voltage as High-Potential
1206 * Reference Voltage" in the RA4M1 manual R01UH0887EJ0100.
1207 *
1208 * Also wait 5 us before using the ADC. This wait is the responsibility of the application. */
1209 if (ADC_PRV_ADHVREFCNT_VREF_INTERNAL_BIT_1 & p_cfg_extend->adc_vref_control)
1210 {
1211 p_instance_ctrl->p_reg->ADHVREFCNT = (uint8_t) (p_cfg_extend->adc_vref_control | R_ADC0_ADHVREFCNT_HVSEL_Msk);
1212
1213 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
1214 }
1215 p_instance_ctrl->p_reg->ADHVREFCNT = (uint8_t) p_cfg_extend->adc_vref_control;
1216 #endif
1217
1218 #if BSP_FEATURE_ADC_HAS_ADBUF
1219 uint8_t adbuf = 0;
1220 if (1U == p_cfg_extend->enable_adbuf)
1221 {
1222 adbuf = R_ADC0_ADBUFEN_BUFEN_Msk;
1223 }
1224 p_instance_ctrl->p_reg->ADBUFEN = adbuf;
1225 #endif
1226 }
1227
1228 /*******************************************************************************************************************//**
1229 * This function set the sensor bits taking into account group inclusion and addition/average mode.
1230 * This function must only be called if it has been verified that sensors are used in this configuration
1231 *
1232 * @param[in] p_instance_ctrl Pointer to instance control block
1233 * @param[in] p_channel_cfg Pointer to channel configuration
1234 **********************************************************************************************************************/
r_adc_sensor_cfg(adc_instance_ctrl_t * const p_instance_ctrl,adc_channel_cfg_t const * const p_channel_cfg)1235 static void r_adc_sensor_cfg (adc_instance_ctrl_t * const p_instance_ctrl,
1236 adc_channel_cfg_t const * const p_channel_cfg)
1237 {
1238 /* Calculate sample states required for temperature and voltage sensor at the current ADCLK speed. */
1239 uint32_t sample_states = 0U;
1240 r_adc_sensor_sample_state_calculation(&sample_states);
1241
1242 /* Check if the temperature sensor channel is enabled */
1243 uint32_t combined_scan_mask = p_channel_cfg->scan_mask | p_channel_cfg->scan_mask_group_b;
1244 uint32_t adexicr = 0U;
1245 if (combined_scan_mask & ADC_MASK_TEMPERATURE)
1246 {
1247 #if BSP_FEATURE_ADC_TSN_CONTROL_AVAILABLE
1248
1249 /* Power on the temperature sensor. This is only needed for TSNs that have the control register */
1250 R_BSP_MODULE_START(FSP_IP_TSN, 0U);
1251
1252 /* Enable the temperature sensor output to the ADC */
1253 R_TSN_CTRL->TSCR = ADC_PRV_TSCR_TSN_ENABLE;
1254 #endif
1255
1256 /* Set sample state register to the calculated value */
1257 p_instance_ctrl->p_reg->ADSSTRT = (uint8_t) sample_states;
1258
1259 #if BSP_FEATURE_ADC_GROUP_B_SENSORS_ALLOWED
1260 if (p_channel_cfg->scan_mask & ADC_MASK_TEMPERATURE)
1261 {
1262 /* Scan the temperature sensor in normal/group A. */
1263 adexicr |= R_ADC0_ADEXICR_TSSA_Msk;
1264 }
1265 else
1266 {
1267 /* Scan the temperature sensor in group B */
1268 adexicr |= R_ADC0_ADEXICR_TSSB_Msk;
1269 }
1270
1271 #else
1272
1273 /* Scan the temperature sensor in normal/group A. */
1274 adexicr |= R_ADC0_ADEXICR_TSSA_Msk;
1275 #endif
1276
1277 /* Enable temperature addition mode if configured. */
1278 if (p_channel_cfg->add_mask & ADC_MASK_TEMPERATURE)
1279 {
1280 adexicr |= R_ADC0_ADEXICR_TSSAD_Msk;
1281 }
1282 }
1283
1284 /* Check if the voltage sensor channel is enabled */
1285 if (combined_scan_mask & ADC_MASK_VOLT)
1286 {
1287 /*sample state registers are set to the calculated value */
1288 p_instance_ctrl->p_reg->ADSSTRO = (uint8_t) sample_states;
1289 #if BSP_FEATURE_ADC_GROUP_B_SENSORS_ALLOWED
1290 if (p_channel_cfg->scan_mask & ADC_MASK_VOLT)
1291 {
1292 /* Scan the internal reference voltage in normal/group A. */
1293 adexicr |= R_ADC0_ADEXICR_OCSA_Msk;
1294 }
1295 else
1296 {
1297 /* Scan the internal reference voltage in group B. */
1298 adexicr |= R_ADC0_ADEXICR_OCSB_Msk;
1299 }
1300
1301 #else
1302
1303 /* Scan the internal reference voltage in normal/group A. */
1304 adexicr |= R_ADC0_ADEXICR_OCSA_Msk;
1305 #endif
1306
1307 /* Enable temperature addition mode if configured. */
1308 if (p_channel_cfg->add_mask & ADC_MASK_VOLT)
1309 {
1310 adexicr |= R_ADC0_ADEXICR_OCSAD_Msk;
1311 }
1312 }
1313
1314 p_instance_ctrl->p_reg->ADEXICR = (uint16_t) adexicr;
1315 }
1316
1317 /*******************************************************************************************************************//**
1318 * This function calculates the sample states value for the internal sensors and returns an error if the calculated
1319 * value is outside the limit supported by the hardware
1320 *
1321 * @param[out] p_sample_states: The calculates sample state count.
1322 **********************************************************************************************************************/
r_adc_sensor_sample_state_calculation(uint32_t * const p_sample_states)1323 static void r_adc_sensor_sample_state_calculation (uint32_t * const p_sample_states)
1324 {
1325 /* Calculate sample state values such that the sample time for the temperature and voltage sensor is the
1326 * minimum defined by the hardware manual. The minimum is 4.15 microseconds for MF3 devices and
1327 * 5 microseconds for RV40. The sample states will be calculated to allow sampling for this duration. */
1328
1329 /* Retrieve the clock source and frequency used by the ADC peripheral and sampling time required for the sensor. */
1330 uint32_t freq_hz = R_FSP_SystemClockHzGet(BSP_FEATURE_ADC_CLOCK_SOURCE);
1331
1332 /* Calculate sample states required for the current ADC conversion clock (reference section 47.2.14 "A/D Sampling
1333 * State Register n (ADSSTRn) (n = 00 to 07, L, T, O)" in the RA6M3 manual R01UH0886EJ0100.
1334 *
1335 * sample_states = required_sample_time / adclk_period
1336 * = required_sample_time (nsec) * adclk_frequency (kHz) / 1000000 (usec / sec) + 1
1337 * (refactored to avoid overflowing 32 bits, 1 added to round up)
1338 */
1339 uint32_t sample_states = ((BSP_FEATURE_ADC_SENSOR_MIN_SAMPLING_TIME * (freq_hz / ADC_PRV_HZ_PER_KHZ)) /
1340 ADC_PRV_USEC_PER_SEC) + 1U;
1341
1342 /* The fastest ADC conversion clock is 60 MHz, and the associated sampling time is 4.15 microseconds. The number
1343 * of sample states in this case is 0.00000415 / (1 / 60000000) = 249. This is the maximum number of sample states
1344 * required for the on chip sensors, so this calculation will never overflow 8 bits (255). */
1345
1346 /* If sample states are less than the min number of states required, then set them to the minimum. */
1347 if (sample_states < ADC_SAMPLE_STATE_COUNT_MIN)
1348 {
1349 sample_states = ADC_SAMPLE_STATE_COUNT_MIN;
1350 }
1351
1352 *p_sample_states = sample_states;
1353 }
1354
1355 #if ADC_CFG_PARAM_CHECKING_ENABLE
1356
1357 /*******************************************************************************************************************//**
1358 * This function does extensive checking on channel mask settings based upon operational mode.
1359 *
1360 * @param[in] p_instance_ctrl Pointer to instance control block
1361 * @param[in] p_channel_cfg Pointer to channel configuration
1362 *
1363 * @retval FSP_SUCCESS No configuration errors detected
1364 * @retval FSP_ERR_ASSERTION An input argument is invalid.
1365 **********************************************************************************************************************/
r_adc_scan_cfg_check(adc_instance_ctrl_t * const p_instance_ctrl,adc_channel_cfg_t const * const p_channel_cfg)1366 static fsp_err_t r_adc_scan_cfg_check (adc_instance_ctrl_t * const p_instance_ctrl,
1367 adc_channel_cfg_t const * const p_channel_cfg)
1368 {
1369 fsp_err_t err;
1370 uint16_t unit = p_instance_ctrl->p_cfg->unit;
1371
1372 /* Verify at least one channel is selected for normal / group A. */
1373 uint32_t valid_channels = g_adc_valid_channels[unit] | ADC_MASK_TEMPERATURE | ADC_MASK_VOLT;
1374 FSP_ASSERT((0U != p_channel_cfg->scan_mask) && (0U == (p_channel_cfg->scan_mask & (~valid_channels))));
1375
1376 if (ADC_MODE_GROUP_SCAN == p_instance_ctrl->p_cfg->mode)
1377 {
1378 /* Verify at least one channel is selected for group B. */
1379 FSP_ASSERT((0U != p_channel_cfg->scan_mask_group_b) &&
1380 (0U == (p_channel_cfg->scan_mask_group_b & (~valid_channels))));
1381
1382 /* Cannot have the same channel in both groups. */
1383 FSP_ASSERT(0 == (p_channel_cfg->scan_mask & p_channel_cfg->scan_mask_group_b));
1384 }
1385 else
1386 {
1387 /* If group mode is not enabled, no channels can be selected for group B. */
1388 FSP_ASSERT(ADC_MASK_OFF == p_channel_cfg->scan_mask_group_b);
1389 }
1390
1391 /* Verify sensor configuration. */
1392 err = r_adc_scan_cfg_check_sensors(p_instance_ctrl, p_channel_cfg);
1393 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1394
1395 /* Verify that if addition is enabled, then at least one channel is selected. */
1396 adc_extended_cfg_t const * p_cfg_extend = (adc_extended_cfg_t const *) p_instance_ctrl->p_cfg->p_extend;
1397 if (ADC_ADD_OFF != p_cfg_extend->add_average_count)
1398 {
1399 /* Addition mask should not include bits from inactive channels.
1400 * This also serves as a check for valid channels in the addition mask */
1401 uint32_t tmp_mask = p_channel_cfg->scan_mask_group_b | p_channel_cfg->scan_mask;
1402 FSP_ASSERT((0U == (p_channel_cfg->add_mask & ~tmp_mask)) && (0U != p_channel_cfg->add_mask));
1403 }
1404 else
1405 {
1406 /* Channels cannot be selected for addition if addition is not used. */
1407 FSP_ASSERT(ADC_MASK_OFF == p_channel_cfg->add_mask);
1408 }
1409
1410 /* Check sample and hold settings. */
1411 err = r_adc_scan_cfg_check_sample_hold(p_instance_ctrl, p_channel_cfg);
1412 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1413
1414 /* Check window compare settings. */
1415 err = r_adc_scan_cfg_check_window_compare(p_channel_cfg->p_window_cfg);
1416
1417 return err;
1418 }
1419
1420 #endif
1421
1422 /*******************************************************************************************************************//**
1423 * This function does extensive checking on channel mask settings based upon operational mode. Mask registers are
1424 * initialized and interrupts enabled in peripheral. Interrupts are also enabled in ICU if corresponding priority
1425 * is not 0.
1426 *
1427 * @param[in] p_instance_ctrl Pointer to instance control block
1428 * @param[in] p_channel_cfg Pointer to channel configuration
1429 **********************************************************************************************************************/
r_adc_scan_cfg(adc_instance_ctrl_t * const p_instance_ctrl,adc_channel_cfg_t const * const p_channel_cfg)1430 static void r_adc_scan_cfg (adc_instance_ctrl_t * const p_instance_ctrl, adc_channel_cfg_t const * const p_channel_cfg)
1431 {
1432 /* Set mask for Group A channels. */
1433 uint32_t scan_mask = p_channel_cfg->scan_mask & ~(uint32_t) ADC_MASK_SENSORS;
1434 adc_extended_cfg_t const * p_cfg_extend = (adc_extended_cfg_t const *) p_instance_ctrl->p_cfg->p_extend;
1435
1436 /* Set other channel masks. */
1437 uint32_t scan_mask_group_b = p_channel_cfg->scan_mask_group_b & ~(uint32_t) ADC_MASK_SENSORS;
1438 uint32_t add_mask = p_channel_cfg->add_mask & ~(uint32_t) ADC_MASK_SENSORS;
1439
1440 p_instance_ctrl->p_reg->ADANSA[0] = (uint16_t) (scan_mask);
1441 p_instance_ctrl->p_reg->ADANSB[0] = (uint16_t) (scan_mask_group_b);
1442 p_instance_ctrl->p_reg->ADADS[0] = (uint16_t) (add_mask);
1443 p_instance_ctrl->p_reg->ADANSA[1] = (uint16_t) ((scan_mask >> 16));
1444 p_instance_ctrl->p_reg->ADANSB[1] = (uint16_t) ((scan_mask_group_b >> 16));
1445 p_instance_ctrl->p_reg->ADADS[1] = (uint16_t) ((add_mask >> 16));
1446
1447 /* Configure voltage and/or temperature sensors, if used. */
1448 r_adc_sensor_cfg(p_instance_ctrl, p_channel_cfg);
1449
1450 #if BSP_FEATURE_ADC_HAS_SAMPLE_HOLD_REG
1451
1452 /* Configure sample and hold. */
1453 uint32_t adshcr = p_channel_cfg->sample_hold_states;
1454 adshcr |= (p_channel_cfg->sample_hold_mask & ADC_MASK_SAMPLE_HOLD_BYPASS_CHANNELS) <<
1455 ADC_MASK_SAMPLE_HOLD_BYPASS_SHIFT;
1456 p_instance_ctrl->p_reg->ADSHCR = (uint16_t) adshcr;
1457 #endif
1458
1459 /* Get window compare configuration */
1460 adc_window_cfg_t * p_window_cfg = p_channel_cfg->p_window_cfg;
1461
1462 uint16_t adcmpcr = 0;
1463
1464 if (p_window_cfg)
1465 {
1466 /* Save window compare config */
1467 adcmpcr = (uint16_t) p_window_cfg->compare_cfg;
1468
1469 if (p_window_cfg->compare_cfg & R_ADC0_ADCMPCR_CMPAE_Msk)
1470 {
1471 /* Set Window A boundary values */
1472 p_instance_ctrl->p_reg->ADCMPCR = p_window_cfg->compare_cfg & UINT16_MAX;
1473 p_instance_ctrl->p_reg->ADCMPDR0 = p_window_cfg->compare_ref_low;
1474 p_instance_ctrl->p_reg->ADCMPDR1 = p_window_cfg->compare_ref_high;
1475
1476 /* Set Window A channel mask */
1477 uint32_t compare_mask = p_window_cfg->compare_mask;
1478 p_instance_ctrl->p_reg->ADCMPANSR[0] = compare_mask & UINT16_MAX;
1479 p_instance_ctrl->p_reg->ADCMPANSR[1] = (uint16_t) (((uint32_t) ~ADC_MASK_SENSORS & compare_mask) >> 16);
1480 p_instance_ctrl->p_reg->ADCMPANSER =
1481 (uint8_t) ((ADC_MASK_SENSORS & compare_mask) >> ADC_MASK_FIRST_SENSOR_BIT);
1482
1483 /* Set Window A channel inequality mode mask */
1484 uint32_t compare_mode_mask = p_window_cfg->compare_mode_mask;
1485 p_instance_ctrl->p_reg->ADCMPLR[0] = compare_mode_mask & UINT16_MAX;
1486 p_instance_ctrl->p_reg->ADCMPLR[1] = (uint16_t) (((uint32_t) ~ADC_MASK_SENSORS & compare_mode_mask) >> 16);
1487 p_instance_ctrl->p_reg->ADCMPLER =
1488 (uint8_t) ((ADC_MASK_SENSORS & compare_mode_mask) >> ADC_MASK_FIRST_SENSOR_BIT);
1489 }
1490
1491 if (p_window_cfg->compare_cfg & R_ADC0_ADCMPCR_CMPBE_Msk)
1492 {
1493 /* Set Window B channel and mode */
1494 p_instance_ctrl->p_reg->ADCMPBNSR = (uint8_t) ((adc_window_b_mode_t) p_window_cfg->compare_b_channel |
1495 p_window_cfg->compare_b_mode);
1496
1497 /* Set Window B boundary values */
1498 p_instance_ctrl->p_reg->ADWINLLB = p_window_cfg->compare_b_ref_low;
1499 p_instance_ctrl->p_reg->ADWINULB = p_window_cfg->compare_b_ref_high;
1500 }
1501 }
1502
1503 /* Set window compare config */
1504 p_instance_ctrl->p_reg->ADCMPCR = adcmpcr;
1505
1506 /* Set group A priority action (not interrupt priority!)
1507 * This will also start the Group B scans if configured for ADC_GROUP_A_GROUP_B_CONTINUOUS_SCAN.
1508 */
1509 p_instance_ctrl->p_reg->ADGSPCR = (uint16_t) p_channel_cfg->priority_group_a;
1510
1511 /* In double-trigger mode set the channel select bits to the highest selected channel number then return. */
1512 if (ADC_DOUBLE_TRIGGER_DISABLED != p_cfg_extend->double_trigger_mode)
1513 {
1514 uint32_t adcsr = p_instance_ctrl->p_reg->ADCSR;
1515 adcsr = (adcsr & ~R_ADC0_ADCSR_DBLANS_Msk) + (31U - __CLZ(scan_mask));
1516
1517 p_instance_ctrl->p_reg->ADCSR = (uint16_t) adcsr;
1518 p_instance_ctrl->scan_start_adcsr |= (uint16_t) adcsr;
1519 }
1520
1521 p_instance_ctrl->initialized = ADC_OPEN;
1522 }
1523
1524 /*******************************************************************************************************************//**
1525 * Disables and clears context for the requested IRQ.
1526 *
1527 * @param[in] irq IRQ to enable
1528 * @param[in] ipl Interrupt priority
1529 * @param[in] p_context Pointer to interrupt context
1530 **********************************************************************************************************************/
r_adc_irq_enable(IRQn_Type irq,uint8_t ipl,void * p_context)1531 static void r_adc_irq_enable (IRQn_Type irq, uint8_t ipl, void * p_context)
1532 {
1533 if (irq >= 0)
1534 {
1535 R_BSP_IrqCfgEnable(irq, ipl, p_context);
1536 }
1537 }
1538
1539 /*******************************************************************************************************************//**
1540 * Disables and clears context for the requested IRQ.
1541 *
1542 * @param[in] irq IRQ to disable
1543 **********************************************************************************************************************/
r_adc_irq_disable(IRQn_Type irq)1544 static void r_adc_irq_disable (IRQn_Type irq)
1545 {
1546 if (irq >= 0)
1547 {
1548 R_BSP_IrqDisable(irq);
1549 R_FSP_IsrContextSet(irq, NULL);
1550 }
1551 }
1552
1553 /*******************************************************************************************************************//**
1554 * Returns the lowest channel index that is configured in order to read the results of the configured channels.
1555 *
1556 * @param[in] adc_mask scan mask of active channels retrieved from the control structure
1557 *
1558 * @retval adc_mask_count index value of lowest channel
1559 **********************************************************************************************************************/
r_adc_lowest_channel_get(uint32_t adc_mask)1560 static int32_t r_adc_lowest_channel_get (uint32_t adc_mask)
1561 {
1562 /* Initialize the mask result */
1563 uint32_t adc_mask_result = 0U;
1564 int32_t adc_mask_count = -1;
1565 while (0U == adc_mask_result)
1566 {
1567 /* Increment channel until a channel is found in the mask. */
1568 adc_mask_count++;
1569 adc_mask_result = (uint32_t) (adc_mask & (1U << adc_mask_count));
1570 }
1571
1572 return adc_mask_count;
1573 }
1574
1575 /*******************************************************************************************************************//**
1576 * Calls user callback.
1577 *
1578 * @param[in] p_ctrl Pointer to ADC instance control block
1579 * @param[in] p_args Pointer to arguments on stack
1580 **********************************************************************************************************************/
r_adc_call_callback(adc_instance_ctrl_t * p_ctrl,adc_callback_args_t * p_args)1581 static void r_adc_call_callback (adc_instance_ctrl_t * p_ctrl, adc_callback_args_t * p_args)
1582 {
1583 adc_callback_args_t args;
1584
1585 /* Store callback arguments in memory provided by user if available. This allows callback arguments to be
1586 * stored in non-secure memory so they can be accessed by a non-secure callback function. */
1587 adc_callback_args_t * p_args_memory = p_ctrl->p_callback_memory;
1588 if (NULL == p_args_memory)
1589 {
1590 /* Use provided args struct on stack */
1591 p_args_memory = p_args;
1592 }
1593 else
1594 {
1595 /* Save current arguments on the stack in case this is a nested interrupt. */
1596 args = *p_args_memory;
1597
1598 /* Copy the stacked args to callback memory */
1599 *p_args_memory = *p_args;
1600 }
1601
1602 #if BSP_TZ_SECURE_BUILD
1603
1604 /* p_callback can point to a secure function or a non-secure function. */
1605 if (!cmse_is_nsfptr(p_ctrl->p_callback))
1606 {
1607 /* If p_callback is secure, then the project does not need to change security state. */
1608 p_ctrl->p_callback(p_args_memory);
1609 }
1610 else
1611 {
1612 /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
1613 adc_prv_ns_callback p_callback = (adc_prv_ns_callback) (p_ctrl->p_callback);
1614 p_callback(p_args_memory);
1615 }
1616
1617 #else
1618
1619 /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
1620 p_ctrl->p_callback(p_args_memory);
1621 #endif
1622
1623 if (NULL != p_ctrl->p_callback_memory)
1624 {
1625 /* Restore callback memory in case this is a nested interrupt. */
1626 *p_ctrl->p_callback_memory = args;
1627 }
1628 }
1629
1630 /*******************************************************************************************************************//**
1631 * Clears interrupt flag and calls a callback to notify application of the event.
1632 *
1633 * @param[in] event Event that triggered the ISR
1634 **********************************************************************************************************************/
r_adc_scan_end_common_isr(adc_event_t event)1635 static void r_adc_scan_end_common_isr (adc_event_t event)
1636 {
1637 /* Save context if RTOS is used */
1638 FSP_CONTEXT_SAVE
1639
1640 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) R_FSP_IsrContextGet(R_FSP_CurrentIrqGet());
1641
1642 /* Clear the BSP IRQ Flag */
1643 R_BSP_IrqStatusClear(R_FSP_CurrentIrqGet());
1644
1645 adc_callback_args_t args;
1646 args.event = event;
1647 #if BSP_FEATURE_ADC_CALIBRATION_REG_AVAILABLE
1648
1649 /* Store the correct event into the callback argument */
1650 if (ADC_ADICR_CALIBRATION_INTERRUPT_DISABLED != p_instance_ctrl->p_reg->ADICR)
1651 {
1652 args.event = ADC_EVENT_CALIBRATION_COMPLETE;
1653
1654 /* Restore the interrupt source to disable interrupts after calibration is done. */
1655 p_instance_ctrl->p_reg->ADICR = 0U;
1656 }
1657 #endif
1658
1659 /* Store the unit number into the callback argument */
1660 args.unit = p_instance_ctrl->p_cfg->unit;
1661
1662 /* Initialize the channel to 0. It is not used in this implementation. */
1663 args.channel = ADC_CHANNEL_0;
1664
1665 /* Populate the context field. */
1666 args.p_context = p_instance_ctrl->p_context;
1667
1668 /* If a callback was provided, call it with the argument */
1669 if (NULL != p_instance_ctrl->p_callback)
1670 {
1671 r_adc_call_callback(p_instance_ctrl, &args);
1672 }
1673
1674 /* Restore context if RTOS is used */
1675 FSP_CONTEXT_RESTORE
1676 }
1677
1678 /*******************************************************************************************************************//**
1679 * This function implements the unit 0 interrupt handler for normal/Group A/double trigger scan complete.
1680 **********************************************************************************************************************/
adc_scan_end_isr(void)1681 void adc_scan_end_isr (void)
1682 {
1683 r_adc_scan_end_common_isr(ADC_EVENT_SCAN_COMPLETE);
1684 }
1685
1686 /*******************************************************************************************************************//**
1687 * This function implements the interrupt handler for Group B scan complete.
1688 **********************************************************************************************************************/
adc_scan_end_b_isr(void)1689 void adc_scan_end_b_isr (void)
1690 {
1691 r_adc_scan_end_common_isr(ADC_EVENT_SCAN_COMPLETE_GROUP_B);
1692 }
1693
1694 /*******************************************************************************************************************//**
1695 * This function implements the interrupt handler for window compare events.
1696 **********************************************************************************************************************/
adc_window_compare_isr(void)1697 void adc_window_compare_isr (void)
1698 {
1699 /* Save context if RTOS is used */
1700 FSP_CONTEXT_SAVE
1701
1702 IRQn_Type irq = R_FSP_CurrentIrqGet();
1703
1704 adc_instance_ctrl_t * p_instance_ctrl = (adc_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1705 adc_extended_cfg_t * p_extend = (adc_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
1706
1707 adc_callback_args_t args;
1708 args.event = (irq == p_extend->window_a_irq) ? ADC_EVENT_WINDOW_COMPARE_A : ADC_EVENT_WINDOW_COMPARE_B;
1709
1710 /* Store the unit number into the callback argument */
1711 args.unit = p_instance_ctrl->p_cfg->unit;
1712
1713 if (ADC_EVENT_WINDOW_COMPARE_A == args.event)
1714 {
1715 args.channel = (adc_channel_t) 0;
1716
1717 R_ADC0_Type * p_reg = p_instance_ctrl->p_reg;
1718
1719 /* Get all Window A status registers */
1720 uint16_t adcmpsr0 = p_reg->ADCMPSR[0];
1721 uint16_t adcmpsr1 = p_reg->ADCMPSR[1];
1722 uint8_t adcmpser = p_reg->ADCMPSER;
1723
1724 /* Get the lowest channel that meets Window A criteria */
1725 uint32_t lowest_channel = __CLZ(__RBIT(adcmpsr0 + (uint32_t) (adcmpsr1 << 16) + (uint32_t) (adcmpser << 29)));
1726
1727 /* Clear the status flag corresponding to the lowest channel */
1728 if (lowest_channel < 16)
1729 {
1730 p_reg->ADCMPSR[0] = (uint16_t) (adcmpsr0 & ~(1 << (lowest_channel & 0xF)));
1731 }
1732 else if (lowest_channel < 29)
1733 {
1734 p_reg->ADCMPSR[1] = (uint16_t) (adcmpsr1 & ~(1 << (lowest_channel & 0xF)));
1735 }
1736 else
1737 {
1738 p_reg->ADCMPSER = (uint8_t) (adcmpser & ~(lowest_channel & 0x3));
1739 }
1740
1741 args.channel = (adc_channel_t) lowest_channel;
1742
1743 if (args.channel > 29)
1744 {
1745 /* Adjust sensor channels to align with the adc_channel_t enumeration */
1746 args.channel = (adc_channel_t) (ADC_CHANNEL_TEMPERATURE + (args.channel - 29));
1747 }
1748 }
1749 else
1750 {
1751 /* Get channel selected for Window B */
1752 args.channel = (adc_channel_t) p_instance_ctrl->p_reg->ADCMPBNSR_b.CMPCHB;
1753
1754 if (args.channel > 31)
1755 {
1756 /* Adjust sensor channels to align with the adc_channel_t enumeration */
1757 args.channel = (adc_channel_t) (ADC_CHANNEL_TEMPERATURE + (args.channel & 0xF));
1758 }
1759
1760 /* Clear IRQ */
1761 p_instance_ctrl->p_reg->ADCMPBSR_b.CMPSTB = 0;
1762 }
1763
1764 /* Populate the context field. */
1765 args.p_context = p_instance_ctrl->p_context;
1766
1767 /* If a callback was provided, call it with the argument */
1768 if (NULL != p_instance_ctrl->p_callback)
1769 {
1770 r_adc_call_callback(p_instance_ctrl, &args);
1771 }
1772
1773 R_BSP_IrqStatusClear(irq);
1774
1775 /* Restore context if RTOS is used */
1776 FSP_CONTEXT_RESTORE
1777 }
1778