void adc_config(void) { LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); /* ADC might be in deep sleep, needs to be woken up twice in that case */ LL_ADC_Enable(ADC1); LL_mDelay(1); LL_ADC_Enable(ADC1); LL_mDelay(1); LL_ADC_StartCalibration(ADC1); while (LL_ADC_IsCalibrationOnGoing(ADC1)); LL_ADC_SetSequencersScanMode(ADC1, LL_ADC_SEQ_SCAN_DISABLE); LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE); LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE); }
static int adc_stm32_init(struct device *dev) { struct adc_stm32_data *data = dev->driver_data; const struct adc_stm32_cfg *config = dev->config->config_info; struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); ADC_TypeDef *adc = (ADC_TypeDef *)config->base; LOG_DBG("Initializing...."); data->dev = dev; #if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) /* * All conversion time for all channels on one ADC instance for F0 and * L0 series chips has to be the same. This additional variable is for * checking if the conversion time selection of all channels on one ADC * instance is the same. */ data->acq_time_index = -1; #endif if (clock_control_on(clk, (clock_control_subsys_t *) &config->pclken) != 0) { return -EIO; } #if defined(CONFIG_SOC_SERIES_STM32L4X) /* * L4 series STM32 needs to be awaken from deep sleep mode, and restore * its calibration parameters if there are some previously stored * calibration parameters. */ LL_ADC_DisableDeepPowerDown(adc); #endif /* * F3 and L4 ADC modules need some time to be stabilized before * performing any enable or calibration actions. */ #if defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) LL_ADC_EnableInternalRegulator(adc); k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) LL_ADC_SetClock(adc, LL_ADC_CLOCK_SYNC_PCLK_DIV4); #elif defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(), LL_ADC_CLOCK_SYNC_PCLK_DIV4); #endif #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \ !defined(CONFIG_SOC_SERIES_STM32F4X) && \ !defined(CONFIG_SOC_SERIES_STM32F7X) && \ !defined(CONFIG_SOC_SERIES_STM32F1X) /* * Calibration of F1 series has to be started after ADC Module is * enabled. */ adc_stm32_calib(dev); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) if (LL_ADC_IsActiveFlag_ADRDY(adc)) { LL_ADC_ClearFlag_ADRDY(adc); } /* * These two series STM32 has one internal voltage reference source * to be enabled. */ LL_ADC_SetCommonPathInternalCh(ADC, LL_ADC_PATH_INTERNAL_VREFINT); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) /* * ADC modules on these series have to wait for some cycles to be * enabled. */ u32_t adc_rate, wait_cycles; if (clock_control_get_rate(clk, (clock_control_subsys_t *) &config->pclken, &adc_rate) < 0) { LOG_ERR("ADC clock rate get error."); } wait_cycles = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / adc_rate * LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES; for (int i = wait_cycles; i >= 0; i--) ; #endif LL_ADC_Enable(adc); #ifdef CONFIG_SOC_SERIES_STM32L4X /* * Enabling ADC modules in L4 series may fail if they are still not * stabilized, this will wait for a short time to ensure ADC modules * are properly enabled. */ u32_t countTimeout = 0; while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0) { if (LL_ADC_IsEnabled(adc) == 0UL) { LL_ADC_Enable(adc); countTimeout++; if (countTimeout == 10) { return -ETIMEDOUT; } } } #endif config->irq_cfg_func(); #ifdef CONFIG_SOC_SERIES_STM32F1X /* Calibration of F1 must starts after two cycles after ADON is set. */ LL_ADC_StartCalibration(adc); LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE); #endif adc_context_unlock_unconditionally(&data->ctx); return 0; }