/** * @file adc_measure_adv.c * @date 2016-08-18 * * NOTE: * This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. * * @cond *********************************************************************************************************************** * ADC_MEASUREMENT_ADV v4.0.14 - Incorporates advanced features of the Versatile Analog to Digital Converter * to measure analog inputs. * * Copyright (c) 2015-2016, Infineon Technologies AG * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes * with Infineon Technologies AG (dave@infineon.com). *********************************************************************************************************************** * * Change History * -------------- * * 2015-10-09: * - Initial version for DAVEv4.
* * 2015-10-20: * - Documentation updated.
* * 2015-12-15: * - Added support for XMC4300 devices.
* * 2016-01-18: * - 1.Internal consumption of request source.
* - 2.Support for synchronized conversion reduced from 8 master channels to 4 .
* - 3.Converted the SetBoundary() API from public API to private API .
* - 4.Updated all APIs for the Internal consumption of request source.
* * 2016-02-05: * - Documentation updated.
* * 2016-03-18: * - Added consumption of the GLOBAL ICLASS -1 for Sync. Conversions.
* - Added consumption of the result register-0 for subtraction mode.
* - Removed ADC_MEASUREMENT_ADV_SetUniformConversion().
* - New API ADC_MEASUREMENT_ADV_SetIclass() added to configure the GLOBAL ICLASS for Slaves.
* * 2016-04-26: * - The synchronized conversion in a master slave configuration is currently not supported.
* * 2016-06-17: * - The synchronized conversion is supported.
* - Modified the Sync initialization sequence to configure the EVAL bits in the slave groups.
* * 2016-08-18: * - Minimum sample time at low frequencies changed to incorporate Errata ADC_AI.H006 and ADC_AI.H007. * * @endcond * */ /*********************************************************************************************************************** * HEADER FILES **********************************************************************************************************************/ #include "adc_measurement_adv.h" /*********************************************************************************************************************** * MACROS **********************************************************************************************************************/ /* Pointer to the VADC GLOBAL*/ #define ADC_MEASUREMENT_ADV_GLOBAL_PTR ((XMC_VADC_GLOBAL_t *) (void *) VADC) /* Max value possible with 10 bit resolution is 1023*/ #define ADC_MEASUREMENT_ADV_10_BIT_MAX_VALUE ((uint32_t)1023) #if (XMC_VADC_SHS_AVAILABLE == 1U) /* Pointer to the SHS unit */ #define ADC_MEASUREMENT_ADV_SHS_PTR ((XMC_VADC_GLOBAL_SHS_t *) (void *) SHS0) #endif /** One result register is reserved for FIFO tail and for the FIFO head. * This needs to be subtracted from the total required FIFO stages. These head and tail result registers needs different * settings based on the UI. The macro is hence helpful to determine the number of intermediate stages for the FIFO * buffer. Each of the intermediate stages need to only set the GxRCR.FEN bit. */ #define ADC_MEASUREMENT_ADV_RESERVED_REGISTERS ((uint32_t)2) /** The number of result registers needed for each channel depends on the FIFO selected. * Always the ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle varies with the FIFO selection. * This Macro depicts the configuration for the Head of the FIFO i.e ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle[0]. * It always represents the head result register(with FIFO) or the result register (without FIFO) configuration. */ #define ADC_MEASUREMENT_ADV_HEAD_RESULT_REG_CONFIG ((uint32_t)0) /** The number of result registers needed for each channel depends on the FIFO selected. * Always the ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle varies with the FIFO selection. * This Macro depicts the configuration for the tail of the FIFO i.e ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle[1]. * It always represents the tail result register of the FIFO. */ #define ADC_MEASUREMENT_ADV_TAIL_RESULT_REG_CONFIG ((uint32_t)1) /* Configure the slave input class as global input class 1*/ #define ADC_MEASUREMENT_ADV_GLOBICLASS1 ((uint32_t)1) /* Since the SCU is different for various devices a macro is defined here to enable check of clock-ungating*/ #if UC_FAMILY == XMC1 #define ADC_MEASUREMENT_ADV_CHECK_CLOCK_GATING ((uint32_t)1) #endif /*********************************************************************************************************************** * LOCAL DATA **********************************************************************************************************************/ /* Array of Group pointers*/ XMC_VADC_GROUP_t *const group_ptrs[XMC_VADC_MAXIMUM_NUM_GROUPS] = { (VADC_G_TypeDef*)(void*) VADC_G0, (VADC_G_TypeDef*)(void*) VADC_G1 #if (XMC_VADC_MAXIMUM_NUM_GROUPS > 2U) ,(VADC_G_TypeDef*)(void*) VADC_G2, (VADC_G_TypeDef*)(void*) VADC_G3 #endif }; #ifdef ADC_MEASUREMENT_ADV_FIFO_USED /** * Intermediate FIFO stages needs only the GxRCR.FEN bit to be set.Hence this is generated as a static constant. */ static const XMC_VADC_RESULT_CONFIG_t ADC_MEASUREMENT_ADV_fifo_intermediate_stage = { .data_reduction_control = 0, .post_processing_mode = 0, .wait_for_read_mode = 0, .part_of_fifo = (bool)true, .event_gen_enable = 0 }; #endif /*Anonymous structure/union guard start*/ #if defined(__CC_ARM) #pragma push #pragma anon_unions #elif defined(__TASKING__) #pragma warning 586 #endif /* Private structure to determine the ALIAS*/ typedef struct ADC_MEASUREMENT_ADV_ALIAS { union { struct { uint32_t alias0 : 5; /* ALIAS for Channel 0*/ uint32_t : 3; uint32_t alias1 : 5; /* ALIAS for channel 1*/ uint32_t : 19; }; uint32_t alias; }; }ADC_MEASUREMENT_ADV_ALIAS_t; /*Anonymous structure/union guard end*/ #if defined(__CC_ARM) #pragma pop #elif defined(__TASKING__) #pragma warning restore #endif /*********************************************************************************************************************** * LOCAL ROUTINES **********************************************************************************************************************/ #if defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED) || defined (ADC_MEASUREMENT_ADV_ADC_SCAN_USED) /* Local function to insert an entry into the H/W*/ __STATIC_INLINE void ADC_MEASUREMENT_ADV_lInsertEntry(const ADC_MEASUREMENT_ADV_t *const handle_ptr, uint8_t ch_num) { #if defined( ADC_MEASUREMENT_ADV_SCAN_USED) && defined(ADC_MEASUREMENT_ADV_ADC_SCAN_USED) #if defined (ADC_MEASUREMENT_ADV_QUEUE_USED) && defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED) if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN == handle_ptr->req_src) #endif { ADC_SCAN_InsertScanEntry(handle_ptr->scan_handle, handle_ptr->scan_entries[ch_num]); } #endif #if defined(ADC_MEASUREMENT_ADV_QUEUE_USED) && defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED) #if defined(ADC_MEASUREMENT_ADV_SCAN_USED) && defined(ADC_MEASUREMENT_ADV_ADC_SCAN_USED) else #endif { ADC_QUEUE_InsertQueueEntry(handle_ptr->queue_handle, handle_ptr->queue_entries[ch_num]); } #endif } #endif /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ XMC_VADC_CHANNEL_CONV_t ADC_MEASUREMENT_ADV_lGetIclass(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { XMC_VADC_CHANNEL_CONV_t req_iclass; #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN != handle_ptr->req_src) #endif { req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->local_scan_handle->iclass_num; } #endif #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED else #endif { /* Call the function to initialise Clock and ADC global functional units*/ req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->scan_handle->iclass_num; } #endif } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE != handle_ptr->req_src) #endif { req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->local_queue_handle->iclass_num; } #endif #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED else #endif { req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->queue_handle->iclass_num; } #endif } #endif return (req_iclass); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifdef ADC_MEASUREMENT_ADV_SYNC_USED /* Helper function to configure the eval bits in the slave*/ void ADC_MEASUREMENT_ADV_lSyncEvalConfig(uint32_t master_group, uint32_t slave_selected, uint32_t sync_group) { int8_t group_index; sync_group |= (1U << master_group); sync_group &= ~(1U << slave_selected); for( group_index = XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index >= (int32_t)0 ; group_index--) { if ( (bool)false != (bool)((sync_group >> group_index) & 0x1 )) { XMC_VADC_GROUP_SetSyncSlaveReadySignal(group_ptrs[slave_selected], slave_selected, group_index); } } } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Helper function to execute the sync init sequence*/ void ADC_MEASUREMENT_ADV_lSyncSequencer(const ADC_MEASUREMENT_ADV_t *const handle_ptr, uint32_t sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_t sequence) { int8_t group_index; for( group_index = XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index >= (int32_t)0 ; group_index--) { if ( (bool)false != (bool)((sync_group >> group_index) & 0x1 )) { switch( sequence) { case ADC_MEASUREMENT_ADV_SYNC_SEQ_POWER_DOWN: XMC_VADC_GROUP_SetPowerMode(group_ptrs[group_index],XMC_VADC_GROUP_POWERMODE_OFF); break; case ADC_MEASUREMENT_ADV_SYNC_SEQ_STSEL_CONFIG: XMC_VADC_GROUP_SetSyncSlave(group_ptrs[group_index], handle_ptr->group_index, group_index); XMC_VADC_GROUP_CheckSlaveReadiness(group_ptrs[handle_ptr->group_index],group_index); break; case ADC_MEASUREMENT_ADV_SYNC_SEQ_EVAL_CONFIG: ADC_MEASUREMENT_ADV_lSyncEvalConfig(handle_ptr->group_index, group_index, sync_group); default: break; } } } } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Initialization of the all the sync related functions */ __STATIC_INLINE void ADC_MEASUREMENT_ADV_lSyncInit(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { uint8_t sync_group; /* shift to get the 4 bit position needed to or it with the slave groups */ sync_group = handle_ptr->sync_slaves | ( 1 << handle_ptr->group_index); ADC_MEASUREMENT_ADV_lSyncSequencer(handle_ptr, sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_POWER_DOWN); sync_group = handle_ptr->sync_slaves; ADC_MEASUREMENT_ADV_lSyncSequencer(handle_ptr, sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_STSEL_CONFIG); ADC_MEASUREMENT_ADV_lSyncSequencer(handle_ptr, sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_EVAL_CONFIG); /* Configure the iclass settings needed for the sync slaves*/ if( (bool) false != handle_ptr->configure_globiclass1) { ADC_MEASUREMENT_ADV_SetIclass(handle_ptr); } XMC_VADC_GROUP_SetSyncMaster(group_ptrs[handle_ptr->group_index]); XMC_VADC_GROUP_SetPowerMode(group_ptrs[handle_ptr->group_index],XMC_VADC_GROUP_POWERMODE_NORMAL); } #endif /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED __STATIC_INLINE ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_lScanInit(ADC_MEASUREMENT_ADV_SCAN_t *const handle_ptr, uint8_t group_index) { ADC_MEASUREMENT_ADV_STATUS_t status; /*Initialization of APP 'ADCGroup'*/ status = (ADC_MEASUREMENT_ADV_STATUS_t) GLOBAL_ADC_Init(ADC_MEASUREMENT_ADV_GLOBAL_HANDLE); XMC_VADC_GROUP_InputClassInit(group_ptrs[group_index], handle_ptr->iclass_config_handle, XMC_VADC_GROUP_CONV_STD, (uint32_t)handle_ptr->iclass_num); /*Initialization of scan request source*/ XMC_VADC_GROUP_ScanInit(group_ptrs[group_index], handle_ptr->scan_config_handle); /* Configure the gating mode for Scan*/ XMC_VADC_GROUP_ScanSetGatingMode(group_ptrs[group_index], handle_ptr->gating_mode); /*Interrupt Configuration*/ if ((bool)true == handle_ptr->rs_intr_handle.interrupt_enable) { #if (UC_FAMILY == XMC1) NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id, handle_ptr->rs_intr_handle.priority); #else NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), handle_ptr->rs_intr_handle.priority,handle_ptr->rs_intr_handle.sub_priority)); #endif #ifdef ADC_MEASUREMENT_ADV_NON_DEFAULT_IRQ_SOURCE_SELECTED XMC_SCU_SetInterruptControl(handle_ptr->rs_intr_handle.node_id, ((handle_ptr->rs_intr_handle.node_id << 8) | handle_ptr->rs_intr_handle.irqctrl)); #endif /* Connect RS Events to NVIC nodes */ XMC_VADC_GROUP_ScanSetReqSrcEventInterruptNode(group_ptrs[group_index], handle_ptr->srv_req_node); } return (status); } #endif /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED __STATIC_INLINE ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_lQueueInit(ADC_MEASUREMENT_ADV_QUEUE_t *const handle_ptr, uint8_t group_index) { ADC_MEASUREMENT_ADV_STATUS_t status; /*Initialization of APP 'GLOBAL_ADC'*/ status = (ADC_MEASUREMENT_ADV_STATUS_t) GLOBAL_ADC_Init(ADC_MEASUREMENT_ADV_GLOBAL_HANDLE); /*Class Configuration*/ XMC_VADC_GROUP_InputClassInit(group_ptrs[group_index],handle_ptr->iclass_config_handle, XMC_VADC_GROUP_CONV_STD,handle_ptr->iclass_num); /* Initialize the Queue hardware */ XMC_VADC_GROUP_QueueInit(group_ptrs[group_index],handle_ptr->queue_config_handle); /* Configure the gating mode for queue*/ XMC_VADC_GROUP_QueueSetGatingMode(group_ptrs[group_index], handle_ptr->gating_mode); /*Interrupt Configuration*/ if ((bool)true == handle_ptr->rs_intr_handle.interrupt_enable) { #if (UC_FAMILY == XMC1) NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id, handle_ptr->rs_intr_handle.priority); #else NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), handle_ptr->rs_intr_handle.priority,handle_ptr->rs_intr_handle.sub_priority)); #endif #ifdef ADC_MEASUREMENT_ADV_NON_DEFAULT_IRQ_SOURCE_SELECTED XMC_SCU_SetInterruptControl(handle_ptr->rs_intr_handle.node_id, ((handle_ptr->rs_intr_handle.node_id << 8) | handle_ptr->rs_intr_handle.irqctrl)); #endif /* Connect RS Events to NVIC nodes */ XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode(group_ptrs[group_index], (XMC_VADC_SR_t)handle_ptr->srv_req_node); } return (status); } #endif /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Local function to do the request source initialization.*/ __STATIC_INLINE ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_lRequestSrcInit(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { ADC_MEASUREMENT_ADV_STATUS_t status; #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN != handle_ptr->req_src) #endif { status = ADC_MEASUREMENT_ADV_lScanInit(handle_ptr->local_scan_handle,handle_ptr->group_index); } #endif #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED else #endif { /* Call the function to initialise Clock and ADC global functional units*/ status = (ADC_MEASUREMENT_ADV_STATUS_t) ADC_SCAN_Init(handle_ptr->scan_handle); } #endif } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE != handle_ptr->req_src) #endif { status = ADC_MEASUREMENT_ADV_lQueueInit(handle_ptr->local_queue_handle,handle_ptr->group_index); } #endif #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED else #endif { /* Call the function to initialise Clock and ADC global functional units*/ status = (ADC_MEASUREMENT_ADV_STATUS_t) ADC_QUEUE_Init(handle_ptr->queue_handle); } #endif } #endif return (status); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED /* Local function to insert the queue entries into the hardware.*/ __STATIC_INLINE void ADC_MEASUREMENT_ADV_lQueueInsertEntries(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { uint32_t entry_index; XMC_VADC_GROUP_t *queue_group_ptr = group_ptrs[handle_ptr->group_index]; const XMC_VADC_QUEUE_ENTRY_t **const entries_array = handle_ptr->local_queue_entries; for(entry_index = 0; entry_index < handle_ptr->total_number_of_entries; entry_index++) { XMC_VADC_GROUP_QueueInsertChannel(queue_group_ptr, *entries_array[entry_index]); } } #endif /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ __STATIC_INLINE bool ADC_MEASUREMENT_ADV_lArbitrationStatus(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { bool clock_reset_check; bool arbitration_status; #if !defined(CLOCK_GATING_SUPPORTED) || !defined(ADC_MEASUREMENT_ADV_CHECK_CLOCK_GATING) clock_reset_check = (bool)false; #endif arbitration_status = (bool)false; /* To check if the arbiter is already enabled. Before checking this ensure that clock and reset states are correct */ #if defined(CLOCK_GATING_SUPPORTED) && defined(ADC_MEASUREMENT_ADV_CHECK_CLOCK_GATING) clock_reset_check = !XMC_SCU_CLOCK_IsPeripheralClockGated(XMC_SCU_PERIPHERAL_CLOCK_VADC); #endif #ifdef PERIPHERAL_RESET_SUPPORTED clock_reset_check |= !XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_VADC); #endif if(clock_reset_check != (bool)false) { #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { arbitration_status = XMC_VADC_GROUP_ScanIsArbitrationSlotEnabled(group_ptrs[handle_ptr->group_index]); } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { arbitration_status = XMC_VADC_GROUP_QueueIsArbitrationSlotEnabled(group_ptrs[handle_ptr->group_index]); } #endif } return (arbitration_status); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ __STATIC_INLINE void ADC_MEASUREMENT_ADV_lDisableArbitration(const ADC_MEASUREMENT_ADV_t *const handle_ptr, bool arbitration_status) { if(arbitration_status == (bool)false) { #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { XMC_VADC_GROUP_ScanDisableArbitrationSlot(group_ptrs[handle_ptr->group_index]); } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { XMC_VADC_GROUP_QueueDisableArbitrationSlot(group_ptrs[handle_ptr->group_index]); } #endif } } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Insert channels into the hardware*/ void ADC_MEASUREMENT_ADV_lInsertChannels(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { XMC_ASSERT("ADC_MEASUREMENT_ADV_InsertChannels:Invalid handle_ptr", (handle_ptr != NULL)) #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN != handle_ptr->req_src) #endif { XMC_VADC_GROUP_ScanAddMultipleChannels(group_ptrs[handle_ptr->group_index], handle_ptr->local_scan_handle->insert_mask); } #endif #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED else #endif { ADC_SCAN_AllEntriesInserted(handle_ptr->scan_handle); } #endif } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE != handle_ptr->req_src) #endif { ADC_MEASUREMENT_ADV_lQueueInsertEntries(handle_ptr); } #endif #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED else #endif { ADC_QUEUE_AllEntriesInserted(handle_ptr->queue_handle); } #endif } #endif } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Select the boundary for a channel and configure its value as well.*/ void ADC_MEASUREMENT_ADV_lSetBoundary(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, XMC_VADC_CHANNEL_BOUNDARY_t boundary_select, uint32_t boundary_value) { XMC_ASSERT("ADC_MEASUREMENT_ADV_SetBoundary:Invalid handle_ptr", (handle_ptr != NULL)) switch(boundary_select) { case XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND0: case XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND1: XMC_VADC_GROUP_SetIndividualBoundary(group_ptrs[handle_ptr->group_index], boundary_select, (uint16_t)boundary_value); break; case XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND0: case XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND1: XMC_VADC_GLOBAL_SetIndividualBoundary(ADC_MEASUREMENT_ADV_GLOBAL_PTR, boundary_select, (uint16_t)boundary_value); break; } } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifndef ADC_MEASUREMENT_ADV_SYNC_USED /* Address the errata for the incorrect conversion.*/ void ADC_MEASUREMENT_ADV_lSyncADCClocks(void) { int32_t group_index; for (group_index = (int32_t)XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index >= (int32_t)0 ; group_index--) { XMC_VADC_GROUP_SetPowerMode(group_ptrs[group_index],XMC_VADC_GROUP_POWERMODE_OFF); } for (group_index = (int32_t)XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index > (int32_t)0 ; group_index--) { XMC_VADC_GROUP_SetSyncSlave(group_ptrs[group_index], (uint32_t)0, (uint32_t)group_index); XMC_VADC_GROUP_CheckSlaveReadiness(group_ptrs[0U], (uint32_t)group_index); } XMC_VADC_GROUP_SetSyncMaster(group_ptrs[0U]); XMC_VADC_GROUP_SetPowerMode(group_ptrs[0U],XMC_VADC_GROUP_POWERMODE_NORMAL); } #endif /********************************************************************************************************************** * API IMPLEMENTATION **********************************************************************************************************************/ /*This function returns the version of the ADC_MEASUREMENT App*/ DAVE_APP_VERSION_t ADC_MEASUREMENT_ADV_GetAppVersion(void) { DAVE_APP_VERSION_t version; version.major = (uint8_t) ADC_MEASUREMENT_ADV_MAJOR_VERSION; version.minor = (uint8_t) ADC_MEASUREMENT_ADV_MINOR_VERSION; version.patch = (uint8_t) ADC_MEASUREMENT_ADV_PATCH_VERSION; return version; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Enables the arbiter of the selected request source*/ void ADC_MEASUREMENT_ADV_StartADC(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { XMC_VADC_GROUP_ScanEnableArbitrationSlot(group_ptrs[handle_ptr->group_index]); } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { XMC_VADC_GROUP_QueueEnableArbitrationSlot(group_ptrs[handle_ptr->group_index]); } #endif } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Disables the arbiter of the selected request source*/ void ADC_MEASUREMENT_ADV_StopADC(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { XMC_VADC_GROUP_ScanDisableArbitrationSlot(group_ptrs[handle_ptr->group_index]); } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { XMC_VADC_GROUP_QueueDisableArbitrationSlot(group_ptrs[handle_ptr->group_index]); } #endif } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Starts the ADC conversions by causing a software start of conversion*/ void ADC_MEASUREMENT_ADV_SoftwareTrigger(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { XMC_ASSERT("ADC_MEASUREMENT_ADV_StartConversion:Invalid handle_ptr", (handle_ptr != NULL)) #ifdef ADC_MEASUREMENT_ADV_SCAN_USED #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src) #endif { XMC_VADC_GROUP_ScanTriggerConversion(group_ptrs[handle_ptr->group_index]); } #endif #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED #ifdef ADC_MEASUREMENT_ADV_SCAN_USED else #endif { XMC_VADC_GROUP_QueueTriggerConversion(group_ptrs[handle_ptr->group_index]); } #endif } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Enables the NVIC(if needed) when scan/queue request source is consumed internally in the APP. */ void ADC_MEASUREMENT_ADC_lNvicEnable(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED if (((bool)true == handle_ptr->local_scan_handle->rs_intr_handle.interrupt_enable) && (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN == handle_ptr->req_src)) { NVIC_EnableIRQ((IRQn_Type)handle_ptr->local_scan_handle->rs_intr_handle.node_id); } #endif #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED if (((bool)true == handle_ptr->local_queue_handle->rs_intr_handle.interrupt_enable) && (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_QUEUE == handle_ptr->req_src)) { NVIC_EnableIRQ((IRQn_Type)handle_ptr->local_queue_handle->rs_intr_handle.node_id); } #endif } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Configures the result results . */ __STATIC_INLINE void ADC_MEASUREMENT_ADC_lResultInit(const ADC_MEASUREMENT_ADV_CHANNEL_t *indexed) { #ifdef ADC_MEASUREMENT_ADV_FIFO_USED uint8_t fifo_num_of_intermediate_stages; uint8_t fifo_index; uint8_t fifo_head; #endif #ifdef ADC_MEASUREMENT_ADV_FIFO_USED /* If FIFO is selected for the particular channel then do the FIFO initializations*/ if ( (uint32_t)0 != indexed->max_fifo_required) { /*Excluding the head and tail from the total number of FIFO elements needed*/ fifo_num_of_intermediate_stages = indexed->max_fifo_required - ADC_MEASUREMENT_ADV_RESERVED_REGISTERS; fifo_head = (uint8_t)indexed->ch_handle->result_reg_number; for (fifo_index = 1; fifo_index <= fifo_num_of_intermediate_stages; fifo_index++) { XMC_VADC_GROUP_ResultInit(group_ptrs[indexed->group_index], (uint32_t)fifo_head - fifo_index, &ADC_MEASUREMENT_ADV_fifo_intermediate_stage); } /* For the FIFO Tail configuration*/ XMC_VADC_GROUP_ResultInit(group_ptrs[indexed->group_index], (uint32_t)indexed->result_fifo_tail_number, indexed->res_handle[ADC_MEASUREMENT_ADV_TAIL_RESULT_REG_CONFIG]); } #endif /* Initialize for configured result registers For FIFO Head configuration*/ XMC_VADC_GROUP_ResultInit(group_ptrs[indexed->group_index], (uint32_t)indexed->ch_handle->result_reg_number, indexed->res_handle[ADC_MEASUREMENT_ADV_HEAD_RESULT_REG_CONFIG]); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Initialization routine to call ADC LLD API's */ ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_Init(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { XMC_ASSERT("ADC_MEASUREMENT_ADV_Init:Invalid handle_ptr", (handle_ptr != NULL)) const ADC_MEASUREMENT_ADV_CHANNEL_t *indexed; uint8_t ch_num; uint8_t total_number_of_channels; ADC_MEASUREMENT_ADV_STATUS_t status; #ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_NON_DEFAULT uint8_t channel_number; #endif bool arbitration_status = (bool)false; if (ADC_MEASUREMENT_ADV_STATUS_UNINITIALIZED == *handle_ptr->init_state) { arbitration_status = ADC_MEASUREMENT_ADV_lArbitrationStatus(handle_ptr); /* Initialize the scan/queue request source.*/ status = ADC_MEASUREMENT_ADV_lRequestSrcInit(handle_ptr); /* Disable the Arbitration if no other instance has enabled it*/ ADC_MEASUREMENT_ADV_lDisableArbitration(handle_ptr,arbitration_status); #ifdef ADC_MEASUREMENT_ADV_SYNC_USED #ifdef ADC_MEASUREMENT_ADV_SYNC_NOT_ALL_USED if ((uint32_t)0 != handle_ptr->sync_slaves) #endif { /* Configure the Sync conversion operation */ ADC_MEASUREMENT_ADV_lSyncInit(handle_ptr); } #else ADC_MEASUREMENT_ADV_lSyncADCClocks(); #endif /* Initialize the SR lines for the Channel event and the Result event, if required*/ #ifdef ADC_MEASUREMENT_ADV_MUX_USED #ifdef ADC_MEASUREMENT_ADV_MUX_NOT_ALL_USED if (handle_ptr->event_config != NULL) #endif { (handle_ptr->event_config)(); } #endif total_number_of_channels = (uint8_t)handle_ptr->total_number_of_channels; for (ch_num = (uint8_t)0; ch_num < (uint8_t)total_number_of_channels; ch_num++) { indexed = handle_ptr->channel_array[ch_num]; /* Initialize for configured channels*/ XMC_VADC_GROUP_ChannelInit(group_ptrs[indexed->group_index],(uint32_t)indexed->ch_num, indexed->ch_handle); #if (XMC_VADC_SHS_AVAILABLE == 1U) #ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_NON_DEFAULT channel_number = indexed->ch_num; #ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_ALIAS if (indexed->ch_handle->alias_channel != XMC_VADC_CHANNEL_ALIAS_DISABLED) { channel_number = indexed->ch_handle->alias_channel; } #endif XMC_VADC_GLOBAL_SHS_SetGainFactor(ADC_MEASUREMENT_ADV_SHS_PTR, (uint8_t)indexed->shs_gain_factor, (XMC_VADC_GROUP_INDEX_t)indexed->group_index, channel_number); #endif #endif /* Result Init both with and without FIFO */ ADC_MEASUREMENT_ADC_lResultInit(indexed); #ifdef ADC_MEASUREMENT_ADV_ANALOG_IO_USED /* ANALOG_IO initialization for the channel*/ #ifndef ADC_MEASUREMENT_ADV_ANALOG_IO_ALL_CHANNELS_USED if(indexed->analog_io_config != NULL) #endif { status |= (ADC_MEASUREMENT_ADV_STATUS_t) ANALOG_IO_Init(indexed->analog_io_config); } #endif } #if defined(ADC_MEASUREMENT_ADV_ADC_SCAN_USED) || defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED) /* Load the queue/scan entries into ADC_QUEUE/ADC_SCAN. * This would load the scan/ queue entries into the software buffers in the ADC_SCAN/ADC_QUEUE APPs. * A call to this API would only configure the ADC_SCAN/ADC_QUEUE software buffers and will not be * programmed into the Hardware. The programming into the hardware is taken care by another API. */ #if defined(ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED) || defined(ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED) if( (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN == handle_ptr->req_src) || (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE == handle_ptr->req_src)) #endif { for (ch_num = (uint8_t)0; ch_num < (uint8_t)handle_ptr->total_number_of_entries; ch_num++) { ADC_MEASUREMENT_ADV_lInsertEntry(handle_ptr,ch_num); } } #endif /* Enables the NVIC node if NVIC node is consumed inside the APP*/ ADC_MEASUREMENT_ADC_lNvicEnable(handle_ptr); /* Load the queue/scan entries into the hardware */ ADC_MEASUREMENT_ADV_lInsertChannels(handle_ptr); /*Start the arbiter of the ADC request source after the initialization. */ #ifdef ADC_MEASUREMENT_ADV_START_ADC #ifdef ADC_MEASUREMENT_ADV_NOT_ALL_REQ_START if ((bool)false != handle_ptr->start_at_initialization) #endif { ADC_MEASUREMENT_ADV_StartADC(handle_ptr); } #endif *handle_ptr->init_state = status; } return (*handle_ptr->init_state); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Set the Fast compare value*/ ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_SetFastCompareValue(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, uint16_t compare_value) { ADC_MEASUREMENT_ADV_STATUS_t status; XMC_ASSERT("ADC_MEASUREMENT_ADV_SetFastCompareValue:Invalid handle_ptr", (handle_ptr != NULL)) status = ADC_MEASUREMENT_ADV_STATUS_FAILURE; if ( (uint32_t)compare_value <= ADC_MEASUREMENT_ADV_10_BIT_MAX_VALUE) { XMC_VADC_GROUP_SetResultFastCompareValue(group_ptrs[handle_ptr->group_index], (uint32_t) handle_ptr->ch_handle->result_reg_number, (XMC_VADC_RESULT_SIZE_t)compare_value); status = ADC_MEASUREMENT_ADV_STATUS_SUCCESS; } return (status); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Set the Subtraction value */ void ADC_MEASUREMENT_ADV_SetSubtractionValue(const ADC_MEASUREMENT_ADV_t *const handle_ptr, ADC_MEASUREMENT_ADV_SUBTRATION_t subtraction_alignment, uint16_t subtraction_value) { uint32_t groups; uint8_t i; XMC_ASSERT("ADC_MEASUREMENT_ADV_SetSubtractionValue:Invalid handle_ptr", (handle_ptr != NULL)) #ifdef ADC_MEASUREMENT_ADV_SYNC_USED groups = handle_ptr->sync_slaves; #else groups = (uint32_t)0; #endif groups |= (uint32_t)((uint32_t)1 << (uint32_t)handle_ptr->group_index); for ( i = (uint8_t)0; i < (uint8_t)XMC_VADC_MAXIMUM_NUM_GROUPS ; i++) { if ( (bool)false != (bool)((groups >> i) & (uint32_t)0x1 )) { XMC_VADC_GROUP_SetResultSubtractionValue(group_ptrs[i], (uint16_t)(subtraction_value << (uint32_t)subtraction_alignment)); } } } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Configure the resolution and sampling time in an iclass */ void ADC_MEASUREMENT_ADV_ConfigureChannelClass(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, const XMC_VADC_GROUP_CLASS_t *config) { XMC_ASSERT("ADC_MEASUREMENT_ADV_ConfigureChannelClass:Invalid class configuration", (config != NULL)) XMC_VADC_GROUP_InputClassInit(group_ptrs[handle_ptr->group_index], *config, XMC_VADC_GROUP_CONV_STD, (uint32_t)handle_ptr->ch_handle->input_class); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Sets the alternate reference for a particular channel*/ void ADC_MEASUREMENT_ADV_SetAlternateReference(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, const XMC_VADC_CHANNEL_REF_t reference_select) { XMC_ASSERT("ADC_MEASUREMENT_ADV_SetAlternateReference:Invalid handle_ptr", (handle_ptr != NULL)) XMC_VADC_GROUP_ChannelSetInputReference(group_ptrs[handle_ptr->group_index], (uint32_t)handle_ptr->ch_num, reference_select); } #if (XMC_VADC_SHS_AVAILABLE == 1U) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Sets the gain ratio for a particular channel*/ void ADC_MEASUREMENT_ADV_SetChannelGain(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, const ADC_MEASUREMENT_ADV_GAIN_t gain_factor) { uint8_t channel_number; XMC_ASSERT("ADC_MEASUREMENT_ADV_SetChannelGain:Invalid handle_ptr", (handle_ptr != NULL)) channel_number = handle_ptr->ch_num; #ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_ALIAS if (handle_ptr->ch_handle->alias_channel != XMC_VADC_CHANNEL_ALIAS_DISABLED) { channel_number = (uint8_t) handle_ptr->ch_handle->alias_channel; } #endif XMC_VADC_GLOBAL_SHS_SetGainFactor(ADC_MEASUREMENT_ADV_SHS_PTR, (uint8_t)gain_factor, (XMC_VADC_GROUP_INDEX_t)handle_ptr->group_index, (uint32_t)channel_number); } #endif /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Select the boundary for the channel*/ void ADC_MEASUREMENT_ADV_SelectBoundary(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, XMC_VADC_BOUNDARY_SELECT_t boundary, XMC_VADC_CHANNEL_BOUNDARY_t boundary_selection) { XMC_ASSERT("ADC_MEASUREMENT_ADV_SelectBoundary:Invalid handle_ptr", (handle_ptr != NULL)) XMC_VADC_GROUP_ChannelSetBoundarySelection(group_ptrs[handle_ptr->group_index], (uint32_t)handle_ptr->ch_num, boundary, boundary_selection); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* configure the upper boundary for a channel.*/ void ADC_MEASUREMENT_ADV_SetBoundaryUpper(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, uint32_t boundary_value) { uint32_t boundary_select; XMC_ASSERT("ADC_MEASUREMENT_ADV_SetBoundary:Invalid handle_ptr", (handle_ptr != NULL)) boundary_select = handle_ptr->ch_handle->upper_boundary_select; ADC_MEASUREMENT_ADV_lSetBoundary(handle_ptr, (XMC_VADC_CHANNEL_BOUNDARY_t)boundary_select, boundary_value); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* configure the lower boundary for a channel.*/ void ADC_MEASUREMENT_ADV_SetBoundaryLower(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr, uint32_t boundary_value) { uint32_t boundary_select; XMC_ASSERT("ADC_MEASUREMENT_ADV_SetBoundary:Invalid handle_ptr", (handle_ptr != NULL)) boundary_select = handle_ptr->ch_handle->lower_boundary_select; ADC_MEASUREMENT_ADV_lSetBoundary(handle_ptr, (XMC_VADC_CHANNEL_BOUNDARY_t)boundary_select, boundary_value); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Aliased channel number is returned if the channel has alias enabled */ XMC_VADC_CHANNEL_ALIAS_t ADC_MEASUREMENT_ADV_GetAliasValue(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr) { XMC_VADC_CHANNEL_ALIAS_t return_value; ADC_MEASUREMENT_ADV_ALIAS_t alias_value; XMC_ASSERT("ADC_MEASUREMENT_ADV_GetAliasValue:Invalid handle_ptr", (handle_ptr != NULL)) alias_value.alias = XMC_VADC_GROUP_GetAlias(group_ptrs[handle_ptr->group_index]); if ((uint8_t)0 == handle_ptr->ch_num ) { return_value = (XMC_VADC_CHANNEL_ALIAS_t)alias_value.alias0; if ((uint32_t)0 == alias_value.alias0) { return_value = XMC_VADC_CHANNEL_ALIAS_DISABLED; } } else if ((uint8_t)1 == handle_ptr->ch_num ) { return_value = (XMC_VADC_CHANNEL_ALIAS_t)alias_value.alias1; if ((uint32_t)1 == alias_value.alias1) { return_value = XMC_VADC_CHANNEL_ALIAS_DISABLED; } } else { return_value = XMC_VADC_CHANNEL_ALIAS_DISABLED; } return(return_value); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifdef ADC_MEASUREMENT_ADV_SYNC_USED /* Enables uniform conversion configurations across slaves*/ void ADC_MEASUREMENT_ADV_SetIclass(const ADC_MEASUREMENT_ADV_t *const handle_ptr) { XMC_VADC_CHANNEL_CONV_t req_iclass; XMC_VADC_GROUP_CLASS_t conv_class; XMC_VADC_GLOBAL_CLASS_t conv_class_global; XMC_ASSERT("ADC_MEASUREMENT_ADV_SetIclass:Invalid handle_ptr", (handle_ptr != NULL)) req_iclass = ADC_MEASUREMENT_ADV_lGetIclass(handle_ptr); conv_class = XMC_VADC_GROUP_GetInputClass(group_ptrs[handle_ptr->group_index], req_iclass); conv_class_global.globiclass = conv_class.g_iclass0; XMC_VADC_GLOBAL_InputClassInit(ADC_MEASUREMENT_ADV_GLOBAL_PTR, conv_class_global, XMC_VADC_GROUP_CONV_STD, (uint32_t)ADC_MEASUREMENT_ADV_GLOBICLASS1); } #endif