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 "r_adc_c.h"
12 
13 /**********************************************************************************************************************
14  * Macro definitions
15  **********************************************************************************************************************/
16 
17 #define ADC_C_OPEN                               (0x41444343U)
18 
19 /* A/D converter stabilization wait time. */
20 #define ADC_C_STABILIZATION_DELAY_US             (1U)
21 #define ADC_C_FRQ_DIV_RATIO                      (4U)
22 #define ADC_C_IDLE_TIME                          (0U)
23 #define ADC_C_PRV_ADM0_CLEAR_ADCE                (~R_ADC_C_ADM0_ADCE_Msk)
24 #define ADC_C_DATA_SIZE_BUFFER_MODE_4            (4U)
25 #define ADC_C_INTERRUPT_CHANNEL_BUFFER_MODE_4    (0x8U)
26 #define ADC_C_4_BUFFER_CHANNEL_MASK              (0xFU)
27 
28 /***********************************************************************************************************************
29  * Typedef definitions
30  **********************************************************************************************************************/
31 
32 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
33 typedef void (BSP_CMSE_NONSECURE_CALL * adc_prv_ns_callback)(adc_callback_args_t * p_args);
34 #elif defined(__GNUC__)
35 typedef BSP_CMSE_NONSECURE_CALL void (*volatile adc_prv_ns_callback)(adc_callback_args_t * p_args);
36 #endif
37 
38 /***********************************************************************************************************************
39  * Private global variables and functions
40  **********************************************************************************************************************/
41 
42 static void r_adc_c_open_sub(adc_c_instance_ctrl_t * const p_instance_ctrl, adc_cfg_t const * const p_cfg);
43 static void r_adc_c_scan_cfg(adc_c_instance_ctrl_t * const     p_instance_ctrl,
44                              adc_c_channel_cfg_t const * const p_channel_cfg);
45 void           adc_c_scan_end_isr(void);
46 static void    r_adc_c_irq_enable(IRQn_Type irq, uint8_t ipl, void * p_context);
47 static void    r_adc_c_irq_disable(IRQn_Type irq);
48 static int32_t r_adc_c_lowest_channel_get(uint32_t adc_mask);
49 static int32_t r_adc_c_highest_channel_get(uint32_t adc_mask);
50 
51 /***********************************************************************************************************************
52  * Global Variables
53  **********************************************************************************************************************/
54 
55 /** ADC Implementation of ADC. */
56 const adc_api_t g_adc_on_adc =
57 {
58     .open           = R_ADC_C_Open,
59     .scanCfg        = R_ADC_C_ScanCfg,
60     .infoGet        = R_ADC_C_InfoGet,
61     .scanStart      = R_ADC_C_ScanStart,
62     .scanGroupStart = R_ADC_C_ScanGroupStart,
63     .scanStop       = R_ADC_C_ScanStop,
64     .scanStatusGet  = R_ADC_C_StatusGet,
65     .read           = R_ADC_C_Read,
66     .read32         = R_ADC_C_Read32,
67     .close          = R_ADC_C_Close,
68     .calibrate      = R_ADC_C_Calibrate,
69     .offsetSet      = R_ADC_C_OffsetSet,
70     .callbackSet    = R_ADC_C_CallbackSet,
71 };
72 
73 /*******************************************************************************************************************//**
74  * @addtogroup ADC_C
75  * @{
76  **********************************************************************************************************************/
77 
78 /***********************************************************************************************************************
79  * Functions
80  **********************************************************************************************************************/
81 
82 /*******************************************************************************************************************//**
83  * Initializes the ADC module and applies configurations.
84  *
85  * @retval FSP_SUCCESS                     Module is ready for use.
86  * @retval FSP_ERR_ASSERTION               An input argument is invalid.
87  * @retval FSP_ERR_ALREADY_OPEN            The instance control structure has already been opened.
88  * @retval FSP_ERR_IRQ_BSP_DISABLED        A callback is provided, but the interrupt is not enabled.
89  **********************************************************************************************************************/
R_ADC_C_Open(adc_ctrl_t * p_ctrl,adc_cfg_t const * const p_cfg)90 fsp_err_t R_ADC_C_Open (adc_ctrl_t * p_ctrl, adc_cfg_t const * const p_cfg)
91 {
92     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
93 
94     /*  Perform parameter checking */
95 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
96 
97     /* Verify the pointers are valid */
98     FSP_ASSERT(NULL != p_instance_ctrl);
99 
100     /* Verify the configuration parameters are valid   */
101     FSP_ASSERT(NULL != p_cfg);
102 
103     /* Verify this unit has not already been initialized   */
104     FSP_ERROR_RETURN(ADC_C_OPEN != p_instance_ctrl->opened, FSP_ERR_ALREADY_OPEN);
105 
106     /* If a callback is used, then make sure an interrupt is enabled */
107     if (NULL != p_cfg->p_callback)
108     {
109         FSP_ERROR_RETURN((p_cfg->scan_end_irq >= 0), FSP_ERR_IRQ_BSP_DISABLED);
110     }
111 #endif
112 
113     /* Save configurations. */
114     p_instance_ctrl->p_cfg             = p_cfg;
115     p_instance_ctrl->p_callback        = p_cfg->p_callback;
116     p_instance_ctrl->p_context         = p_cfg->p_context;
117     p_instance_ctrl->p_callback_memory = NULL;
118 
119     /* Calculate the register base address. */
120     p_instance_ctrl->p_reg = R_ADC_C;
121 
122     /* Initialize the hardware based on the configuration. */
123     r_adc_c_open_sub(p_instance_ctrl, p_cfg);
124 
125     /* Enable interrupts */
126     r_adc_c_irq_enable(p_cfg->scan_end_irq, p_cfg->scan_end_ipl, p_instance_ctrl);
127 
128     /* Invalid scan mask (initialized for later). */
129     p_instance_ctrl->scan_mask = 0U;
130 
131     /* Mark driver as opened by initializing it to "ADCC" in its ASCII equivalent for this unit. */
132     p_instance_ctrl->opened = ADC_C_OPEN;
133 
134     /* Return the error code */
135     return FSP_SUCCESS;
136 }
137 
138 /*******************************************************************************************************************//**
139  * Configures the ADC_C scan parameters. Channel specific settings are set in this function. Pass a pointer to
140  * @ref adc_c_channel_cfg_t to p_channel_cfg.
141  *
142  *
143  * @retval FSP_SUCCESS                 Channel specific settings applied.
144  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
145  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
146  **********************************************************************************************************************/
R_ADC_C_ScanCfg(adc_ctrl_t * p_ctrl,void const * const p_channel_cfg)147 fsp_err_t R_ADC_C_ScanCfg (adc_ctrl_t * p_ctrl, void const * const p_channel_cfg)
148 {
149     adc_c_channel_cfg_t const * p_adc_channel_cfg = (adc_c_channel_cfg_t const *) p_channel_cfg;
150     adc_c_instance_ctrl_t     * p_instance_ctrl   = (adc_c_instance_ctrl_t *) p_ctrl;
151     fsp_err_t err = FSP_SUCCESS;
152 
153 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
154     FSP_ASSERT(NULL != p_instance_ctrl);
155     FSP_ASSERT(NULL != p_adc_channel_cfg);
156     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
157 
158     /* Multiple analog input channel selection is prohibited in select mode. */
159     FSP_ASSERT(!((ADC_C_OPERATING_MODE_SELECT == p_instance_ctrl->operating_mode) &&
160                  ((ADC_C_MASK_CHANNEL_0 | ADC_C_MASK_CHANNEL_1) == p_adc_channel_cfg->scan_mask)));
161 #endif
162 
163     /* Configure the hardware based on the configuration. */
164     r_adc_c_scan_cfg(p_instance_ctrl, p_adc_channel_cfg);
165 
166     /* Save the scan mask locally; this is required for the infoGet function. */
167     p_instance_ctrl->scan_mask = p_adc_channel_cfg->scan_mask;
168 
169     /* Return the error code. */
170     return err;
171 }
172 
173 /*******************************************************************************************************************//**
174  * Updates the user callback and has option of providing memory for callback structure.
175  * Implements adc_api_t::callbackSet
176  *
177  * @retval  FSP_SUCCESS                  Callback updated successfully.
178  * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
179  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
180  * @retval  FSP_ERR_NO_CALLBACK_MEMORY   p_callback is non-secure and p_callback_memory is either secure or NULL.
181  **********************************************************************************************************************/
R_ADC_C_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)182 fsp_err_t R_ADC_C_CallbackSet (adc_ctrl_t * const          p_api_ctrl,
183                                void (                    * p_callback)(adc_callback_args_t *),
184                                void const * const          p_context,
185                                adc_callback_args_t * const p_callback_memory)
186 {
187     adc_c_instance_ctrl_t * p_ctrl = (adc_c_instance_ctrl_t *) p_api_ctrl;
188 
189 #if (ADC_C_CFG_PARAM_CHECKING_ENABLE)
190     FSP_ASSERT(p_ctrl);
191     FSP_ASSERT(p_callback);
192     FSP_ERROR_RETURN(ADC_C_OPEN == p_ctrl->opened, FSP_ERR_NOT_OPEN);
193 #endif
194 
195     /* Store callback and context */
196 
197 #if BSP_TZ_SECURE_BUILD
198 
199     /* Get security state of p_callback */
200     bool callback_is_secure =
201         (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
202 
203  #if ADC_C_CFG_PARAM_CHECKING_ENABLE
204 
205     /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
206     adc_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
207                                                                                       CMSE_AU_NONSECURE);
208     FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
209  #endif
210 
211     p_ctrl->p_callback = callback_is_secure ? p_callback :
212                          (void (*)(adc_callback_args_t *))cmse_nsfptr_create(p_callback);
213 #else
214     p_ctrl->p_callback = p_callback;
215 #endif
216 
217     p_ctrl->p_context         = p_context;
218     p_ctrl->p_callback_memory = p_callback_memory;
219 
220     return FSP_SUCCESS;
221 }
222 
223 /*******************************************************************************************************************//**
224  * Start A/D conversion.
225  *
226  * @pre Call R_ADC_C_ScanCfg after R_ADC_C_Open before starting a scan.
227  *
228  * @retval FSP_SUCCESS                 Scan started (software trigger) or hardware triggers enabled.
229  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
230  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
231  * @retval FSP_ERR_NOT_INITIALIZED     Unit is not initialized.
232  * @retval FSP_ERR_IN_USE              Another scan is still in progress (software trigger).
233  **********************************************************************************************************************/
R_ADC_C_ScanStart(adc_ctrl_t * p_ctrl)234 fsp_err_t R_ADC_C_ScanStart (adc_ctrl_t * p_ctrl)
235 {
236     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
237 
238     /* Perform parameter checking  */
239 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
240 
241     /* Verify the pointers are valid */
242     FSP_ASSERT(NULL != p_instance_ctrl);
243     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
244     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
245     FSP_ERROR_RETURN(0U == p_instance_ctrl->p_reg->ADM0_b.ADCE, FSP_ERR_IN_USE);
246 #endif
247 
248     /* Start A/D conversion. */
249     p_instance_ctrl->p_reg->ADM0 = p_instance_ctrl->scan_start;
250 
251     return FSP_SUCCESS;
252 }
253 
254 /*******************************************************************************************************************//**
255  * @ref adc_api_t::scanGroupStart is not supported. Use scanStart instead.
256  *
257  * @retval FSP_ERR_UNSUPPORTED         Function not supported in this implementation.
258  **********************************************************************************************************************/
R_ADC_C_ScanGroupStart(adc_ctrl_t * p_ctrl,adc_group_mask_t group_id)259 fsp_err_t R_ADC_C_ScanGroupStart (adc_ctrl_t * p_ctrl, adc_group_mask_t group_id)
260 {
261     FSP_PARAMETER_NOT_USED(p_ctrl);
262     FSP_PARAMETER_NOT_USED(group_id);
263 
264     /* Return the unsupported error. */
265     return FSP_ERR_UNSUPPORTED;
266 }
267 
268 /*******************************************************************************************************************//**
269  * Stop A/D conversion.
270  *
271  * @retval FSP_SUCCESS                 Scan stopped (software trigger) or hardware triggers disabled.
272  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
273  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
274  * @retval FSP_ERR_NOT_INITIALIZED     Unit is not initialized.
275  **********************************************************************************************************************/
R_ADC_C_ScanStop(adc_ctrl_t * p_ctrl)276 fsp_err_t R_ADC_C_ScanStop (adc_ctrl_t * p_ctrl)
277 {
278     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
279 
280     /*  Perform parameter checking */
281 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
282 
283     /* Verify the pointers are valid */
284     FSP_ASSERT(NULL != p_instance_ctrl);
285     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
286     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
287 #endif
288 
289     /* Stop A/D conversion. */
290     p_instance_ctrl->p_reg->ADM0 = (uint32_t) (p_instance_ctrl->scan_start & ADC_C_PRV_ADM0_CLEAR_ADCE);
291 
292     /* Read ADM0 register to confirm that A/D conversion is stopped. */
293     FSP_HARDWARE_REGISTER_WAIT(p_instance_ctrl->p_reg->ADM0_b.ADCE, 0U);
294 
295     return FSP_SUCCESS;
296 }
297 
298 /*******************************************************************************************************************//**
299  * Get current ADC_C status and store it in provided pointer p_status.
300  *
301  * @retval FSP_SUCCESS                 Module status stored in the provided pointer p_status
302  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
303  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
304  **********************************************************************************************************************/
R_ADC_C_StatusGet(adc_ctrl_t * p_ctrl,adc_status_t * p_status)305 fsp_err_t R_ADC_C_StatusGet (adc_ctrl_t * p_ctrl, adc_status_t * p_status)
306 {
307     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
308 
309 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
310     FSP_ASSERT(NULL != p_instance_ctrl);
311     FSP_ASSERT(NULL != p_status);
312     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
313 #endif
314 
315     /* Read the status of the ADBSY bit. ADBSY is set when a scan is in progress. */
316     p_status->state = (adc_state_t) p_instance_ctrl->p_reg->ADM0_b.ADBSY;
317 
318     /* Return the error code */
319     return FSP_SUCCESS;
320 }
321 
322 /*******************************************************************************************************************//**
323  * Reads conversion results from a single channel or sensor.
324  *
325  * @retval FSP_SUCCESS                 Data read into provided p_data.
326  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
327  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
328  * @retval FSP_ERR_NOT_INITIALIZED     Unit is not initialized.
329  **********************************************************************************************************************/
R_ADC_C_Read(adc_ctrl_t * p_ctrl,adc_channel_t const reg_id,uint16_t * const p_data)330 fsp_err_t R_ADC_C_Read (adc_ctrl_t * p_ctrl, adc_channel_t const reg_id, uint16_t * const p_data)
331 {
332     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
333 
334     /* Perform parameter checking. */
335 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
336 
337     /* Verify the pointers are valid */
338     FSP_ASSERT(NULL != p_instance_ctrl);
339     FSP_ASSERT(NULL != p_data);
340     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
341     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
342 
343     /* Verify that the channel is valid for this MCU */
344     uint32_t requested_channel_mask = (1U << (uint32_t) reg_id);
345     FSP_ASSERT(0 != (requested_channel_mask & BSP_FEATURE_ADC_C_VALID_CHANNEL_MASK));
346 #endif
347 
348     /* Read the data from the requested ADC conversion register and return it */
349     *p_data = *((uint16_t *) (&p_instance_ctrl->p_reg->ADCR0 + reg_id));
350 
351     /* Return the error code */
352     return FSP_SUCCESS;
353 }
354 
355 /*******************************************************************************************************************//**
356  * Reads conversion results from a single channel or sensor register into a 32-bit result.
357  *
358  * @retval FSP_SUCCESS                 Data read into provided p_data.
359  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
360  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
361  * @retval FSP_ERR_NOT_INITIALIZED     Unit is not initialized.
362  **********************************************************************************************************************/
R_ADC_C_Read32(adc_ctrl_t * p_ctrl,adc_channel_t const reg_id,uint32_t * const p_data)363 fsp_err_t R_ADC_C_Read32 (adc_ctrl_t * p_ctrl, adc_channel_t const reg_id, uint32_t * const p_data)
364 {
365     uint16_t result    = 0U;
366     uint32_t result_32 = 0U;
367 
368 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
369     FSP_ASSERT(NULL != p_data);
370 #endif
371 
372     fsp_err_t err = R_ADC_C_Read(p_ctrl, reg_id, &result);
373     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
374 
375     result_32 = result;
376     *p_data   = result_32;
377 
378     return FSP_SUCCESS;
379 }
380 
381 /*******************************************************************************************************************//**
382  * Sets the sample state count for individual channels. This only needs to be set for special use cases. Normally, use
383  * the default values out of reset.
384  *
385  * @note The sample states for the temperature and voltage sensor are set in R_ADC_C_ScanCfg.
386  *
387  * @retval FSP_SUCCESS                 Sample state count updated.
388  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
389  * @retval FSP_ERR_NOT_INITIALIZED     Unit is not initialized.
390  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
391  * @retval FSP_ERR_IN_USE              A/D conversion ongoing.
392  **********************************************************************************************************************/
R_ADC_C_SampleStateCountSet(adc_ctrl_t * p_ctrl,uint16_t num_states)393 fsp_err_t R_ADC_C_SampleStateCountSet (adc_ctrl_t * p_ctrl, uint16_t num_states)
394 {
395     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
396     fsp_err_t               err             = FSP_SUCCESS;
397 
398     /* Perform parameter checking */
399 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
400 
401     /* Verify the pointers are valid */
402     FSP_ASSERT(NULL != p_instance_ctrl);
403     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
404     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->initialized, FSP_ERR_NOT_INITIALIZED);
405     FSP_ERROR_RETURN(0 == p_instance_ctrl->p_reg->ADM0_b.ADBSY, FSP_ERR_IN_USE);
406 
407     /* Verify the arguments are within the expected range. */
408     FSP_ASSERT((num_states >= BSP_FEATURE_ADC_C_SAMPLE_STATE_COUNT_MIN) &&
409                (num_states <= BSP_FEATURE_ADC_C_SAMPLE_STATE_COUNT_MAX));
410 #endif
411 
412     /* Set the sample state count for the specified register */
413     uint32_t adm3  = (uint32_t) (ADC_C_IDLE_TIME << R_ADC_C_ADM3_ADIL_Pos) | (uint32_t) (BSP_FEATURE_ADC_C_CONVERSION_TIME << R_ADC_C_ADM3_ADCMP_Pos) | (num_states << R_ADC_C_ADM3_ADSMP_Pos);
414     p_instance_ctrl->p_reg->ADM3 = adm3;
415 
416     /* Return the error code */
417     return err;
418 }
419 
420 /*******************************************************************************************************************//**
421  * Returns the address of the lowest number configured channel and the total number of bytes to be read in order to
422  * read the results of the configured channels. If no channels are configured, then a length of 0 is returned.
423  *
424  *
425  * @retval FSP_SUCCESS                 Information stored in p_adc_info.
426  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
427  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
428  **********************************************************************************************************************/
R_ADC_C_InfoGet(adc_ctrl_t * p_ctrl,adc_info_t * p_adc_info)429 fsp_err_t R_ADC_C_InfoGet (adc_ctrl_t * p_ctrl, adc_info_t * p_adc_info)
430 {
431     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
432     fsp_err_t               err             = FSP_SUCCESS;
433     uint32_t                adc_mask        = 0;
434 
435 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
436     FSP_ASSERT(NULL != p_instance_ctrl);
437     FSP_ASSERT(NULL != p_adc_info);
438     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
439 #endif
440 
441     adc_c_extended_cfg_t * p_extend = (adc_c_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
442 
443     /* Retrieve the scan mask of active channels from the control structure */
444     adc_mask = p_instance_ctrl->scan_mask;
445 
446     if (ADC_C_BUFFER_MODE_4 == p_extend->buffer_mode)
447     {
448         p_adc_info->length    = ADC_C_DATA_SIZE_BUFFER_MODE_4;
449         p_adc_info->p_address = &p_instance_ctrl->p_reg->ADCR0;
450     }
451     else
452     {
453         /* If at least one channel is configured, determine the highest and lowest configured channels. */
454         if (adc_mask != 0U)
455         {
456             uint32_t adc_mask_in_order = adc_mask;
457             int32_t  lowest_channel    = r_adc_c_lowest_channel_get(adc_mask_in_order);
458 
459             p_adc_info->p_address = (uint32_t *) (&p_instance_ctrl->p_reg->ADCR0 + lowest_channel);
460 
461             /* Determine the highest channel that is configured. */
462             int32_t highest_channel = r_adc_c_highest_channel_get(adc_mask_in_order);
463 
464             /* Determine the size of data that must be read to read all the channels between and including the
465              * highest and lowest channels.*/
466             p_adc_info->length = (uint32_t) ((highest_channel - lowest_channel) + 1);
467         }
468         else
469         {
470             /* If no channels are configured, set the return length 0. */
471             p_adc_info->length = 0U;
472         }
473     }
474 
475     p_adc_info->transfer_size = TRANSFER_SIZE_2_BYTE;
476 
477 #if BSP_FEATURE_ADC_C_TSU_CONTROL_AVAILABLE
478 
479     /* Read into memory. */
480     p_adc_info->calibration_data1 = R_TSU->OTPTSUTRIM0_REG_b.OTPTSUTRIM0;
481     p_adc_info->calibration_data2 = R_TSU->OTPTSUTRIM1_REG_b.OTPTSUTRIM1;
482 #else
483 
484     /* Set Temp Sensor calibration data to invalid value */
485     p_adc_info->calibration_data1 = UINT32_MAX;
486     p_adc_info->calibration_data2 = UINT32_MAX;
487 #endif
488 
489     return err;
490 }
491 
492 /*******************************************************************************************************************//**
493  * This function ends any scan in progress, disables interrupts, and removes power to the A/D peripheral.
494  *
495  * @retval FSP_SUCCESS                 Module closed.
496  * @retval FSP_ERR_ASSERTION           An input argument is invalid.
497  * @retval FSP_ERR_NOT_OPEN            Unit is not open.
498  **********************************************************************************************************************/
R_ADC_C_Close(adc_ctrl_t * p_ctrl)499 fsp_err_t R_ADC_C_Close (adc_ctrl_t * p_ctrl)
500 {
501     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) p_ctrl;
502 
503 #if ADC_C_CFG_PARAM_CHECKING_ENABLE
504     FSP_ASSERT(NULL != p_instance_ctrl);
505     FSP_ERROR_RETURN(ADC_C_OPEN == p_instance_ctrl->opened, FSP_ERR_NOT_OPEN);
506 #endif
507 
508     /* Mark driver as closed   */
509     p_instance_ctrl->opened      = 0U;
510     p_instance_ctrl->initialized = 0U;
511 
512     /* Disable interrupts. */
513     r_adc_c_irq_disable(p_instance_ctrl->p_cfg->scan_end_irq);
514 
515     /* Stop the ADC. */
516     p_instance_ctrl->p_reg->ADM0 = 0U;
517 
518     /* Read ADM0 register to confirm that A/D conversion is stopped. */
519     FSP_HARDWARE_REGISTER_WAIT(p_instance_ctrl->p_reg->ADM0_b.ADCE, 0U);
520 
521     /* Clear the interrupt cause flag and trigger detection flag.  */
522     uint32_t adsts = (uint32_t) (1 << R_ADC_C_ADSTS_TRGS_Pos);
523     adsts |= (uint32_t) (BSP_FEATURE_ADC_C_VALID_CHANNEL_MASK << R_ADC_C_ADSTS_INTST_Pos);
524     p_instance_ctrl->p_reg->ADSTS = adsts;
525 
526     R_BSP_MODULE_STOP(FSP_IP_ADC, 0);
527 
528     if (p_instance_ctrl->scan_mask & ADC_C_MASK_CHANNEL_8)
529     {
530 #if BSP_FEATURE_ADC_C_TSU_CONTROL_AVAILABLE
531 
532         /* Set the temperature sensor to place in the standby mode. */
533         R_TSU->TSU_SM = 0;
534 
535         /* Stop the TSU. */
536         R_BSP_MODULE_STOP(FSP_IP_TSU, 0);
537 #endif
538     }
539 
540     /* Return the error code */
541     return FSP_SUCCESS;
542 }
543 
544 /*******************************************************************************************************************//**
545  * @ref adc_api_t::calibrate is not supported.
546  *
547  * @retval FSP_ERR_UNSUPPORTED         Calibration not supported on this MCU.
548  **********************************************************************************************************************/
R_ADC_C_Calibrate(adc_ctrl_t * const p_ctrl,void const * p_extend)549 fsp_err_t R_ADC_C_Calibrate (adc_ctrl_t * const p_ctrl, void const * p_extend)
550 {
551     FSP_PARAMETER_NOT_USED(p_ctrl);
552     FSP_PARAMETER_NOT_USED(p_extend);
553 
554     /* Return the unsupported error. */
555     return FSP_ERR_UNSUPPORTED;
556 }
557 
558 /*******************************************************************************************************************//**
559  * @ref adc_api_t::offsetSet is not supported.
560  *
561  * @retval FSP_ERR_UNSUPPORTED         Function not supported in this implementation.
562  **********************************************************************************************************************/
R_ADC_C_OffsetSet(adc_ctrl_t * const p_ctrl,adc_channel_t const reg_id,int32_t offset)563 fsp_err_t R_ADC_C_OffsetSet (adc_ctrl_t * const p_ctrl, adc_channel_t const reg_id, int32_t offset)
564 {
565     FSP_PARAMETER_NOT_USED(p_ctrl);
566     FSP_PARAMETER_NOT_USED(reg_id);
567     FSP_PARAMETER_NOT_USED(offset);
568 
569     /* Return the unsupported error. */
570     return FSP_ERR_UNSUPPORTED;
571 }
572 
573 /*******************************************************************************************************************//**
574  * @} (end addtogroup ADC_C)
575  **********************************************************************************************************************/
576 
577 /***********************************************************************************************************************
578  * Private Functions
579  **********************************************************************************************************************/
580 
581 /*******************************************************************************************************************//**
582  * The Open function applies power to the A/D peripheral, sets the value for ADM0, ADM1, ADM3, ADIVC, ADFIL.
583  *
584  * @param[in]  p_instance_ctrl         Pointer to instance control block
585  * @param[in]  p_cfg                   Pointer to configuration structure
586  **********************************************************************************************************************/
r_adc_c_open_sub(adc_c_instance_ctrl_t * const p_instance_ctrl,adc_cfg_t const * const p_cfg)587 static void r_adc_c_open_sub (adc_c_instance_ctrl_t * const p_instance_ctrl, adc_cfg_t const * const p_cfg)
588 {
589     adc_c_extended_cfg_t const * p_cfg_extend = (adc_c_extended_cfg_t const *) p_cfg->p_extend;
590 
591     /* Determine the value for ADM0, ADM1, ADM3, ADIVC, ADFIL.:
592      * The value to set in ADCSR to start a scan is stored in the control structure.
593      * ADM0.ADCE is set in R_ADC_ScanStart.
594      *//* Sets the trigger mode. */
595     uint32_t adm1 = (uint32_t) (p_cfg_extend->trigger_mode << R_ADC_C_ADM1_TRG_Pos);
596 
597     /* When using hardware trigger mode, set the hardware trigger signal parameter. */
598     if (ADC_C_TRIGGER_MODE_HARDWARE == p_cfg_extend->trigger_mode)
599     {
600         adm1 |= (uint32_t) (p_cfg_extend->trigger_source << R_ADC_C_ADM1_TRGEN_Pos);
601         adm1 |= (uint32_t) (p_cfg_extend->input_mode << R_ADC_C_ADM1_TRGIN_Pos);
602 
603         /* The trigger edge setting is valid only when the trigger source is ADC_TRG.
604          * Reference section "A/D Converter Mode Register 1 (ADM1)" of the user's manual. */
605         if (ADC_C_ACTIVE_TRIGGER_EXTERNAL == p_cfg_extend->trigger_source)
606         {
607             adm1 |= (uint32_t) (p_cfg_extend->trigger_edge << R_ADC_C_ADM1_EGA_Pos);
608         }
609         /* Otherwise falling edge is always valid. */
610         else
611         {
612             adm1 |= (uint32_t) (ADC_C_TRIGGER_EDGE_FALLING << R_ADC_C_ADM1_EGA_Pos);
613         }
614     }
615     else
616     {
617         /* Do nothing. */
618     }
619 
620     /* Sets the operating mode and buffer mode. */
621     adm1 |= (uint32_t) (p_cfg_extend->operating_mode << R_ADC_C_ADM1_MS_Pos);
622 
623     /* 1-Buffer mode and 4-Buffer mode can be set when using select mode. */
624     if (ADC_C_OPERATING_MODE_SELECT == p_cfg_extend->operating_mode)
625     {
626         adm1 |= (uint32_t) (p_cfg_extend->buffer_mode << R_ADC_C_ADM1_BS_Pos);
627     }
628 
629     /* Repeat mode corresponds to ADC_MODE_CONTINUOUS_SCAN of API,
630      * but since the API value (=2) and repeat mode register setting value (=1) are different,
631      * it is necessary to convert them.
632      * Sets the conversion mode. */
633     adm1 |= (uint32_t) ((p_cfg->mode >> 1U) << R_ADC_C_ADM1_RPS_Pos);
634 
635 #if BSP_FEATURE_ADC_C_HAS_ADIVC
636 
637     /* Sets the frequency division ratio for dividing the frequency of ADC_ADCLK(TSUϕ). */
638     uint32_t adivc = (uint32_t) (ADC_C_FRQ_DIV_RATIO << R_ADC_C_ADIVC_DIVADC_Pos);
639 #endif
640 
641     uint32_t adfil = 0;
642 
643     /* Enables or disables the AD external trigger pin filter. */
644     if (ADC_C_FILTER_STAGE_SETTING_DISABLE != p_cfg_extend->external_trigger_filter)
645     {
646         adfil = (uint32_t) (1 << R_ADC_C_ADFIL_FILONOFF_Pos);
647 
648         /* Set the number of stages of the AD external trigger pin filter. */
649         adfil |= (uint32_t) ((p_cfg_extend->external_trigger_filter - 1) << R_ADC_C_ADFIL_FILNUM_Pos);
650     }
651     else
652     {
653         /* Do nothing. */
654     }
655 
656     /* Set the idle period. */
657     uint32_t adm3 = (uint32_t) (ADC_C_IDLE_TIME << R_ADC_C_ADM3_ADIL_Pos);
658 
659     /* Set the conversion period and sampling period. */
660     adm3 |= (uint32_t) (BSP_FEATURE_ADC_C_CONVERSION_TIME << R_ADC_C_ADM3_ADCMP_Pos);
661     adm3 |= (uint32_t) (p_cfg_extend->sampling_time << R_ADC_C_ADM3_ADSMP_Pos);
662 
663     /* Apply clock to peripheral. */
664     R_BSP_MODULE_START(FSP_IP_ADC, 0);
665 
666     /* The following series of steps refer to "A/D conversion start procedure" in the user's manual. */
667     /* Release from software reset state. */
668     uint32_t adm0 = (uint32_t) (1 << R_ADC_C_ADM0_SRESB_Pos);
669     p_instance_ctrl->p_reg->ADM0 = adm0;
670 
671     /* The waiting time until the reset state of the A/D converter is released is 2 × ADC_ADCLK(TSUϕ) (80 MHz),
672      * but since the minimum waiting time of R_BSP_SoftwareDelay is 1us,
673      * processing is executed with a waiting time of 1us. */
674     R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
675 
676     /* Clear the interrupt cause flag and trigger detection flag.  */
677     uint32_t adsts = (uint32_t) (1 << R_ADC_C_ADSTS_TRGS_Pos);
678     adsts |= (uint32_t) (BSP_FEATURE_ADC_C_VALID_CHANNEL_MASK << R_ADC_C_ADSTS_INTST_Pos);
679     p_instance_ctrl->p_reg->ADSTS = adsts;
680 
681     /* Set the predetermined values for ADM1, ADM3, ADINT, ADIVC, and ADFIL.
682      * ADM0.ADCE are set as configured in R_ADC_ScanStart. */
683     p_instance_ctrl->p_reg->ADM1 = adm1;
684     p_instance_ctrl->p_reg->ADM3 = adm3;
685 #if BSP_FEATURE_ADC_C_HAS_ADIVC
686     p_instance_ctrl->p_reg->ADIVC = adivc;
687 #endif
688     p_instance_ctrl->p_reg->ADFIL = adfil;
689 
690     /* Change from power-saving mode to normal mode. */
691     adm0 |= (uint32_t) (1 << R_ADC_C_ADM0_PWDWNB_Pos);
692     p_instance_ctrl->p_reg->ADM0 = adm0;
693 
694     /* Secure the A/D converter stabilization wait time. */
695     R_BSP_SoftwareDelay(ADC_C_STABILIZATION_DELAY_US, BSP_DELAY_UNITS_MICROSECONDS);
696 
697     /* Set the ADCE bit. */
698     adm0 |= (uint32_t) (R_ADC_C_ADM0_ADCE_Msk);
699 
700     p_instance_ctrl->scan_start = adm0;
701 
702     /* Save the operating mode and buffer mode locally; this is required for the Scancfg function. */
703     p_instance_ctrl->operating_mode = p_cfg_extend->operating_mode;
704     p_instance_ctrl->buffer_mode    = p_cfg_extend->buffer_mode;
705 }
706 
707 /*******************************************************************************************************************//**
708  * This function does extensive checking on channel mask settings based upon operational mode. Mask registers are
709  * initialized and interrupts enabled in peripheral. Interrupts are also enabled in ICU if corresponding priority
710  * is not 0.
711  *
712  * @param[in]  p_instance_ctrl         Pointer to instance control block
713  * @param[in]  p_channel_cfg           Pointer to channel configuration
714  **********************************************************************************************************************/
r_adc_c_scan_cfg(adc_c_instance_ctrl_t * const p_instance_ctrl,adc_c_channel_cfg_t const * const p_channel_cfg)715 static void r_adc_c_scan_cfg (adc_c_instance_ctrl_t * const     p_instance_ctrl,
716                               adc_c_channel_cfg_t const * const p_channel_cfg)
717 {
718     if (p_channel_cfg->scan_mask & ADC_C_MASK_CHANNEL_8)
719     {
720 #if BSP_FEATURE_ADC_C_TSU_CONTROL_AVAILABLE
721 
722         /* Apply clock to peripheral. */
723         R_BSP_MODULE_START(FSP_IP_TSU, 0);
724 
725         /* Set the temperature sensor to place in the normal operating mode. */
726         R_TSU->TSU_SM = R_TSU_TSU_SM_EN_Msk;
727 
728         /* Wait 30us. See the TSU "Operation" section of the RZ microprocessor manual. */
729         R_BSP_SoftwareDelay(BSP_FEATURE_ADC_C_TSU_ENABLE_STABILIZATION_TIME_US, BSP_DELAY_UNITS_MICROSECONDS);
730 
731         /* Enable the temperature sensor. */
732         R_TSU->TSU_SM |= R_TSU_TSU_SM_OE_Msk;
733 
734         /* Wait 1000us. See the TSU "Operation" section of the RZ microprocessor manual. */
735         R_BSP_SoftwareDelay(BSP_FEATURE_ADC_C_TSU_START_STABILIZATION_TIME_MS, BSP_DELAY_UNITS_MILLISECONDS);
736 #endif
737     }
738 
739     /* Set mask for channels. */
740     p_instance_ctrl->p_reg->ADM2 = (uint32_t) (p_channel_cfg->scan_mask & (uint32_t) R_ADC_C_ADM2_CHSEL_Msk);
741 
742     /* Disables the A/D conversion channel select error interrupt. */
743     uint32_t adint = (uint32_t) (0 << R_ADC_C_ADINT_CSEEN_Pos);
744 
745     /* Enable or disable the conversion end interrupt of channel n (n = 0 to 3). */
746     if (ADC_C_INTERRUPT_CHANNEL_SETTING_ENABLE == p_channel_cfg->interrupt_setting)
747     {
748         /* Channel 3 interrupt output is enabled in 4-buffer mode.
749          * Reference section "Example of A/D Conversion in 4-Buffer Mode" of the user's manual.*/
750         if (ADC_C_BUFFER_MODE_4 == p_instance_ctrl->buffer_mode)
751         {
752             if (p_channel_cfg->scan_mask & ADC_C_4_BUFFER_CHANNEL_MASK)
753             {
754                 adint |= (uint32_t) (R_ADC_C_ADCR0_AD3_Msk << R_ADC_C_ADINT_INTEN_Pos);
755             }
756             else if (p_channel_cfg->scan_mask & (ADC_C_4_BUFFER_CHANNEL_MASK << 4))
757             {
758                 adint |= (uint32_t) (R_ADC_C_ADCR0_AD7_Msk << R_ADC_C_ADINT_INTEN_Pos);
759             }
760             else
761             {
762                 adint |= (uint32_t) (R_ADC_C_ADCR0_AD11_Msk << R_ADC_C_ADINT_INTEN_Pos);
763             }
764         }
765         else
766         {
767             uint32_t adc_mask_in_order = p_channel_cfg->scan_mask;
768 
769             /* Determine the highest channel that is configured. */
770             int32_t highest_channel = r_adc_c_highest_channel_get(adc_mask_in_order);
771 
772             /* Highest channel interrupt output is enabled. */
773             adint |= (uint32_t) (1U << highest_channel);
774         }
775     }
776     else
777     {
778         /* Do nothing. */
779     }
780 
781     p_instance_ctrl->p_reg->ADINT = adint;
782 
783     p_instance_ctrl->initialized = ADC_C_OPEN;
784 }
785 
786 /*******************************************************************************************************************//**
787  * Disables and clears context for the requested IRQ.
788  *
789  * @param[in]  irq        IRQ to enable
790  * @param[in]  ipl        Interrupt priority
791  * @param[in]  p_context  Pointer to interrupt context
792  **********************************************************************************************************************/
r_adc_c_irq_enable(IRQn_Type irq,uint8_t ipl,void * p_context)793 static void r_adc_c_irq_enable (IRQn_Type irq, uint8_t ipl, void * p_context)
794 {
795     if (irq >= 0)
796     {
797         R_BSP_IrqCfgEnable(irq, ipl, p_context);
798     }
799 }
800 
801 /*******************************************************************************************************************//**
802  * Disables and clears context for the requested IRQ.
803  *
804  * @param[in]  irq  IRQ to disable
805  **********************************************************************************************************************/
r_adc_c_irq_disable(IRQn_Type irq)806 static void r_adc_c_irq_disable (IRQn_Type irq)
807 {
808     if (irq >= 0)
809     {
810         R_BSP_IrqDisable(irq);
811         R_FSP_IsrContextSet(irq, NULL);
812     }
813 }
814 
815 /*******************************************************************************************************************//**
816  * Returns the lowest channel index that is configured  in order to read the results of the configured channels.
817  *
818  * @param[in]  adc_mask  scan mask of active channels retrieved from the control structure
819  *
820  * @retval  adc_mask_count  index value of lowest channel
821  **********************************************************************************************************************/
r_adc_c_lowest_channel_get(uint32_t adc_mask)822 static int32_t r_adc_c_lowest_channel_get (uint32_t adc_mask)
823 {
824     /* Initialize the mask result */
825     uint32_t adc_mask_result = 0U;
826     int32_t  adc_mask_count  = -1;
827     while (0U == adc_mask_result)
828     {
829         /* Increment channel until a channel is found in the mask. */
830         adc_mask_count++;
831         adc_mask_result = (uint32_t) (adc_mask & (1U << adc_mask_count));
832     }
833 
834     return adc_mask_count;
835 }
836 
837 /*******************************************************************************************************************//**
838  * Returns the highest channel index that is configured  in order to read the results of the configured channels.
839  *
840  * @param[in]  adc_mask  scan mask of active channels retrieved from the control structure
841  *
842  * @retval  adc_mask_count  index value of highest channel
843  **********************************************************************************************************************/
r_adc_c_highest_channel_get(uint32_t adc_mask)844 static int32_t r_adc_c_highest_channel_get (uint32_t adc_mask)
845 {
846     /* Initialize the mask result */
847     uint32_t adc_mask_result = 0U;
848     int32_t  adc_mask_count  = 31;
849     while (0U == adc_mask_result)
850     {
851         /* Decrement channel until a channel is found in the mask. */
852         adc_mask_count--;
853         adc_mask_result = (uint32_t) (adc_mask & (1U << adc_mask_count));
854     }
855 
856     return adc_mask_count;
857 }
858 
859 /*******************************************************************************************************************//**
860  * Calls user callback.
861  *
862  * @param[in]     p_ctrl     Pointer to ADC instance control block
863  * @param[in]     p_args     Pointer to arguments on stack
864  **********************************************************************************************************************/
r_adc_c_call_callback(adc_c_instance_ctrl_t * p_ctrl,adc_callback_args_t * p_args)865 static void r_adc_c_call_callback (adc_c_instance_ctrl_t * p_ctrl, adc_callback_args_t * p_args)
866 {
867     adc_callback_args_t args;
868 
869     /* Store callback arguments in memory provided by user if available.  This allows callback arguments to be
870      * stored in non-secure memory so they can be accessed by a non-secure callback function. */
871     adc_callback_args_t * p_args_memory = p_ctrl->p_callback_memory;
872     if (NULL == p_args_memory)
873     {
874         /* Use provided args struct on stack */
875         p_args_memory = p_args;
876     }
877     else
878     {
879         /* Save current arguments on the stack in case this is a nested interrupt. */
880         args = *p_args_memory;
881 
882         /* Copy the stacked args to callback memory */
883         *p_args_memory = *p_args;
884     }
885 
886 #if BSP_TZ_SECURE_BUILD
887 
888     /* p_callback can point to a secure function or a non-secure function. */
889     if (!cmse_is_nsfptr(p_ctrl->p_callback))
890     {
891         /* If p_callback is secure, then the project does not need to change security state. */
892         p_ctrl->p_callback(p_args_memory);
893     }
894     else
895     {
896         /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
897         adc_prv_ns_callback p_callback = (adc_prv_ns_callback) (p_ctrl->p_callback);
898         p_callback(p_args_memory);
899     }
900 
901 #else
902 
903     /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
904     p_ctrl->p_callback(p_args_memory);
905 #endif
906 
907     if (NULL != p_ctrl->p_callback_memory)
908     {
909         /* Restore callback memory in case this is a nested interrupt. */
910         *p_ctrl->p_callback_memory = args;
911     }
912 }
913 
914 /*******************************************************************************************************************//**
915  * This function implements interrupt handler for scan complete.
916  **********************************************************************************************************************/
adc_c_scan_end_isr(void)917 void adc_c_scan_end_isr (void)
918 {
919     /* Save context if RTOS is used */
920     FSP_CONTEXT_SAVE;
921 
922     IRQn_Type               irq             = R_FSP_CurrentIrqGet();
923     adc_c_instance_ctrl_t * p_instance_ctrl = (adc_c_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
924     adc_c_extended_cfg_t  * p_extend        = (adc_c_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
925 
926     /* Clear the BSP IRQ Flag     */
927     R_BSP_IrqStatusClear(irq);
928 
929     adc_callback_args_t args;
930     args.event = ADC_EVENT_SCAN_COMPLETE;
931 
932     /* Populate the context field. */
933     args.p_context = p_instance_ctrl->p_context;
934 
935     uint32_t adsts = 0;
936 
937     /* Clear the trigger detection flag.  */
938     if (ADC_C_TRIGGER_MODE_HARDWARE == p_extend->trigger_mode)
939     {
940         adsts = (uint32_t) (1 << R_ADC_C_ADSTS_TRGS_Pos);
941     }
942 
943     /* Clear the interrupt cause flag.  */
944     adsts |= (uint32_t) (R_ADC_C_ADSTS_INTST_Msk << R_ADC_C_ADSTS_INTST_Pos);
945     p_instance_ctrl->p_reg->ADSTS = adsts;
946 
947     /* Dummy read the ADSTS bit. */
948     volatile uint32_t dummy = p_instance_ctrl->p_reg->ADSTS;
949     FSP_PARAMETER_NOT_USED(dummy);
950 
951     /* Initialize the unit to 0.  It is not used in this implementation. */
952     args.unit = 0U;
953 
954     /* Initialize the channel to 0.  It is not used in this implementation. */
955     args.channel = ADC_CHANNEL_0;
956 
957     /* If a callback was provided, call it with the argument */
958     if (NULL != p_instance_ctrl->p_callback)
959     {
960         r_adc_c_call_callback(p_instance_ctrl, &args);
961     }
962 
963     /* Restore context if RTOS is used */
964     FSP_CONTEXT_RESTORE;
965 }
966