adriendesp commented on code in PR #12425: URL: https://github.com/apache/nuttx/pull/12425#discussion_r1620278684
########## arch/arm/src/xmc4/xmc4_vadc.c: ########## @@ -0,0 +1,576 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_vadc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * May include some logic from sample code provided by Infineon: + * + * Copyright (C) 2011-2015 Infineon Technologies AG. All rights reserved. + * + * Infineon Technologies AG (Infineon) is supplying this software for use + * with Infineon's microcontrollers. This file can be freely distributed + * within development tools that are supporting such microcontrollers. + * + * THIS SOFTWARE IS PROVIDED AS IS. NO WARRANTIES, WHETHER EXPRESS, + * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS + * SOFTWARE. INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR + * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <errno.h> +#include <assert.h> + +#include <arch/xmc4/chip.h> + +#include "arm_internal.h" +#include "hardware/xmc4_scu.h" +#include "xmc4_vadc.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static vadc_group_t *const g_xmc_vadc_group_array[XMC_VADC_MAXIMUM_NUM_GROUPS] = { + (vadc_group_t *)VADC_G0, + (vadc_group_t *)VADC_G1, + (vadc_group_t *)VADC_G2, + (vadc_group_t *)VADC_G3 + }; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_vadc_global_enable + * + * Description: + * Ungate the clock to the VADC module (if applicable) and bring the VADC + * module out of reset state. + * Called in xmc4_vadc_global_initialize. + * + ****************************************************************************/ + +void xmc4_vadc_global_enable(void) +{ + #ifdef XMC4_SCU_GATING + /* Check if VADC is gated */ + + if ((getreg32(XMC4_SCU_CGATSTAT0) & SCU_CGAT0_VADC) == 1) + { + /* Disable VADC gating */ + + putreg32(SCU_CGAT0_VADC, XMC4_SCU_CGATCLR0); + } + + /* Set bit in PRCLR0 to de-assert VADC peripheral reset */ + + putreg32(SCU_PR0_VADCRS, XMC4_SCU_PRCLR0); + #else + + /* Set bit in PRCLR0 to de-assert VADC peripheral reset */ + + putreg32(SCU_PR0_VADCRS, XMC4_SCU_PRCLR0); + #endif +} + +/**************************************************************************** + * Name: xmc4_vadc_global_disable + * + * Description: + * Gate the clock to the VADC module (if applicable) and put the VADC + * module into the reset state + * + ****************************************************************************/ + +void xmc4_vadc_global_disable(void) +{ + /* Set bit in PRSET0 to assert VADC peripheral reset */ + + putreg32(SCU_PR0_VADCRS, XMC4_SCU_PRSET0); + + #ifdef XMC4_SCU_GATING + /* Check if VADC is ungated */ + + if ((getreg32(XMC4_SCU_CGATSTAT0) & SCU_CGAT0_VADC) == 0) + { + /* Enable VADC gating */ + + putreg32(SCU_CGAT0_VADC, XMC4_SCU_CGATSET0); + } + #endif +} + +/**************************************************************************** + * Name: xmc4_vadc_global_initialize + * + * Description: + * Initializes the VADC global module with the given configuration structure. + * It initializes global input classes, boundaries , result resources. + * Configures GLOBICLASS,GLOBBOUND,GLOBRCR registers. + * It also configures the global analog and digital clock dividers + * by setting GLOBCFG register. + * + ****************************************************************************/ + +void xmc4_vadc_global_initialize(const vadc_global_config_t *config) +{ + /* Enable the VADC module */ + + xmc4_vadc_global_enable(); + + VADC->CLC = (uint32_t)(config->clc); + + /* Clock configuration, use DIVWC (write control) to write register */ + + VADC->GLOBCFG = (uint32_t)(config->globcfg | (uint32_t)(VADC_GLOBCFG_DIVWC_MASK)); + + /* Global input class 0 configuration */ + + VADC->GLOBICLASS[0] = (uint32_t)(config->class0.iclass); + + /* Global input class 1 configuration */ + + VADC->GLOBICLASS[1] = (uint32_t)(config->class1.iclass); + + /* Global result generation configuration */ + + VADC->GLOBRCR = (uint32_t)(config->globrcr); + + /* Set global boundaries values */ + + VADC->GLOBBOUND = (uint32_t)(config->globbound); +} + +/**************************************************************************** + * Name: xmc4_vadc_group_initialize + * + * Description: + * Initializes the VADC group module with the associated + * configuration structure pointed by config. It initializes group conversion + * class, arbiter configuration, boundary configuration by setting + * GxICLASS,GxARBCFG,GxBOUND, registers. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned to + * indicate the nature of any failure. + * + ****************************************************************************/ + +int xmc4_vadc_group_initialize(vadc_group_t *const group_ptr, const vadc_group_config_t *config) +{ + if (!xmc_vadc_check_group_ptr(group_ptr)) + { + return -EINVAL; + } + + /* Configures the group-specific input classes, + * each channel is assigned to a class in GxCHCTRy + */ + + group_ptr->ICLASS[0] = config->class0.iclass; + group_ptr->ICLASS[1] = config->class1.iclass; + + /* Configures the group arbitration behavior */ + + group_ptr->ARBCFG = config->g_arbcfg; + + /* Configures the group-specific boundaries */ + + group_ptr->BOUND = config->g_bound; + + return OK; +} + +/**************************************************************************** + * Name: xmc4_vadc_group_set_powermode + * + * Description: + * Configures the power mode of a VADC group. For a VADC group to + * actually convert an analog signal, its analog converter must be turned on. + * Configure the register bit field GxARBCFG.ANONC + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned to + * indicate the nature of any failure. + * + ****************************************************************************/ + +int xmc4_vadc_group_set_powermode(vadc_group_t *const group_ptr, const vadc_group_powermode_t power_mode) +{ + if (!xmc_vadc_check_group_ptr(group_ptr) || (power_mode > XMC_VADC_GROUP_POWERMODE_NORMAL)) + { + return -EINVAL; + } + + uint32_t arbcfg = group_ptr->ARBCFG; + + arbcfg &= ~((uint32_t)VADC_GxARBCFG_ANONC_MASK); + arbcfg |= (uint32_t)power_mode; + + group_ptr->ARBCFG = arbcfg; + + return OK; +} + +/**************************************************************************** + * Name: xmc4_vadc_global_start_calibration + * + * Description: + * Start the calibration process and loops until all active groups + * finish calibration. Call xmc4_vadc_global_enable and + * xmc4_vadc_global_initialize before calibration. + * Configures the register bit field GLOBCFG.SUCAL. + * + ****************************************************************************/ + +void xmc4_vadc_global_start_calibration(void) +{ + vadc_group_t * group_ptr; + + /* Start Calibration */ + + VADC->GLOBCFG |= (uint32_t) VADC_GLOBCFG_SUCAL_MASK; + + /* Loop until all groups to finish calibration */ + + for (int i = 0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++) + { + group_ptr = g_xmc_vadc_group_array[i]; + + /* Check if group is active */ + + if ((group_ptr->ARBCFG) & (uint32_t)(VADC_GxARBCFG_ANONS_MASK)) + { + /* Loop until it finish calibration */ + + while ((group_ptr->ARBCFG) & (uint32_t)VADC_GxARBCFG_CAL_MASK) + { + /* NOP */ + } + } + } +} + +/**************************************************************************** + * Name: xmc4_vadc_group_background_enable_arbitrationslot + * + * Description: + * Enables arbitration slot of the Background request source to + * participate in the arbitration round. Even if a load event occurs the + * Background channel can only be converted when the arbiter comes to the + * Background slot. Thus this must be enabled if any conversion need to take + * place. + * Configure the register bit field GxARBPR.ASEN2. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned to + * indicate the nature of any failure. + * + ****************************************************************************/ + +int xmc4_vadc_group_background_enable_arbitrationslot(vadc_group_t *const group_ptr) +{ + if (!xmc_vadc_check_group_ptr(group_ptr)) + { + return -EINVAL; + } + + group_ptr->ARBPR |= (uint32_t)VADC_GxARBPR_ASEN2_MASK; + + return OK; +} + +/**************************************************************************** + * Name: xmc4_vadc_group_background_disable_arbitrationslot + * + * Description: + * Disables arbitration slot of the Background request source to + * participate in the arbitration round. Even if a load event occurs the + * Background channel can only be converted when the arbiter comes to the + * Background slot. Thus this must be enabled if any conversion need to take + * place. + * Configure the register bit field GxARBPR.ASEN2. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned to + * indicate the nature of any failure. + * + ****************************************************************************/ + +int xmc4_vadc_group_background_disable_arbitrationslot(vadc_group_t *const group_ptr) +{ + if (!xmc_vadc_check_group_ptr(group_ptr)) + { + return -EINVAL; + } + + group_ptr->ARBPR &= ~((uint32_t)VADC_GxARBPR_ASEN2_MASK); + + return OK; +} + +/**************************************************************************** + * Name: xmc4_vadc_global_background_initialize + * + * Description: + * Initializes the Background scan functional block. The BACKGROUND + * SCAN request source functional block converts channels of all VADC groups + * that have not been assigned as a priority channel (priority channels can be + * converted only by queue and scan). Related arbitration slot must be + * disabled to configure background request, then re-enabled. + * + ****************************************************************************/ + +void xmc4_vadc_global_background_initialize(const vadc_background_config_t *config) +{ + uint32_t reg; + uint32_t conv_start_mask; + + /* Disable background request source to change its parameters */ + + for (int i = 0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++) + { + xmc4_vadc_group_background_disable_arbitrationslot((vadc_group_t *)g_xmc_vadc_group_array[i]); + } + + /* Set start mode */ + + conv_start_mask = (uint32_t) 0; + if (XMC_VADC_STARTMODE_WFS != (vadc_startmode_t)config->conv_start_mode) + { + conv_start_mask = (uint32_t)VADC_GxARBPR_CSM2_MASK; + } + + /* Configures GxARBPR register for each group */ + + for (int i = 0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++) + { + reg = g_xmc_vadc_group_array[i]->ARBPR; + + /* Program the priority of the request source : Background Scan is source 2 */ + + reg &= ~(uint32_t)(VADC_GxARBPR_PRIO2_MASK); + reg |= (uint32_t)((uint32_t)config->req_src_priority << VADC_GxARBPR_PRIO2_SHIFT); + + /* Program the start mode */ + + reg |= conv_start_mask; + + g_xmc_vadc_group_array[i]->ARBPR = reg; + } + + /* program Background Request Source Control register, use XT and GT write control bitfields */ + + VADC->BRSCTRL = (uint32_t)(config->asctrl | (uint32_t)VADC_BRSCTRL_XTWC_MASK | (uint32_t)VADC_BRSCTRL_GTWC_MASK); + + /* program Background Request Source Mode register */ + + VADC->BRSMR = (uint32_t)((config->asmr) | (uint32_t)((uint32_t)XMC_VADC_GATEMODE_IGNORE << VADC_BRSMR_ENGT_SHIFT)); + if (XMC_VADC_STARTMODE_CNR == (vadc_startmode_t)(config->conv_start_mode)) + { + VADC->BRSMR |= (uint32_t)VADC_BRSMR_RPTDIS_MASK; + } + + /* Re enable request source */ + + for (int i = 0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++) + { + xmc4_vadc_group_background_enable_arbitrationslot((vadc_group_t *)g_xmc_vadc_group_array[i]); Review Comment: not needed indeed -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
