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