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); }
/** * @brief Initialize some features of ADC group regular. * @note These parameters have an impact on ADC scope: ADC group regular. * Refer to corresponding unitary functions into * @ref ADC_LL_EF_Configuration_ADC_Group_Regular * (functions with prefix "REG"). * @note The setting of these parameters by function @ref LL_ADC_Init() * is conditioned to ADC state: * ADC instance must be disabled. * This condition is applied to all ADC features, for efficiency * and compatibility over all STM32 families. However, the different * features can be set under different ADC state conditions * (setting possible with ADC enabled without conversion on going, * ADC enabled with conversion on going, ...) * Each feature can be updated afterwards with a unitary function * and potentially with ADC in a different state than disabled, * refer to description of each function for setting * conditioned to ADC state. * @note After using this function, other features must be configured * using LL unitary functions. * The minimum configuration remaining to be done is: * - Set ADC group regular or group injected sequencer: * map channel on the selected sequencer rank. * Refer to function @ref LL_ADC_REG_SetSequencerRanks(). * - Set ADC channel sampling time * Refer to function LL_ADC_SetChannelSamplingTime(); * @param ADCx ADC instance * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure * @retval An ErrorStatus enumeration value: * - SUCCESS: ADC registers are initialized * - ERROR: ADC registers are not initialized */ ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct) { ErrorStatus status = SUCCESS; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(ADCx)); assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource)); assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength)); if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) { assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont)); } assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode)); assert_param(IS_LL_ADC_REG_DATA_TRANSFER_MODE(ADC_REG_InitStruct->DataTransferMode)); assert_param(IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(ADC_REG_InitStruct->Overrun)); /* Note: Hardware constraint (refer to description of this function): */ /* ADC instance must be disabled. */ if(LL_ADC_IsEnabled(ADCx) == 0UL) { /* Configuration of ADC hierarchical scope: */ /* - ADC group regular */ /* - Set ADC group regular trigger source */ /* - Set ADC group regular sequencer length */ /* - Set ADC group regular sequencer discontinuous mode */ /* - Set ADC group regular continuous mode */ /* - Set ADC group regular conversion data transfer: no transfer or */ /* transfer by DMA, and DMA requests mode */ /* - Set ADC group regular overrun behavior */ /* Note: On this STM32 serie, ADC trigger edge is set to value 0x0 by */ /* setting of trigger source to SW start. */ if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) { MODIFY_REG(ADCx->CFGR, ADC_CFGR_EXTSEL | ADC_CFGR_EXTEN | ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_CONT | ADC_CFGR_DMNGT | ADC_CFGR_OVRMOD , ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->SequencerDiscont | ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DataTransferMode | ADC_REG_InitStruct->Overrun ); } else { MODIFY_REG(ADCx->CFGR, ADC_CFGR_EXTSEL | ADC_CFGR_EXTEN | ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_CONT | ADC_CFGR_DMNGT | ADC_CFGR_OVRMOD , ADC_REG_InitStruct->TriggerSource | LL_ADC_REG_SEQ_DISCONT_DISABLE | ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DataTransferMode | ADC_REG_InitStruct->Overrun ); } /* Set ADC group regular sequencer length and scan direction */ LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength); } else { /* Initialization error: ADC instance is not disabled. */ status = ERROR; } return status; }
/** * @brief Initialize some features of ADC group regular. * @note These parameters have an impact on ADC scope: ADC group regular. * Refer to corresponding unitary functions into * @ref ADC_LL_EF_Configuration_ADC_Group_Regular * (functions with prefix "REG"). * @note The setting of these parameters by function @ref LL_ADC_Init() * is conditioned to ADC state: * ADC instance must be disabled. * This condition is applied to all ADC features, for efficiency * and compatibility over all STM32 families. However, the different * features can be set under different ADC state conditions * (setting possible with ADC enabled without conversion on going, * ADC enabled with conversion on going, ...) * Each feature can be updated afterwards with a unitary function * and potentially with ADC in a different state than disabled, * refer to description of each function for setting * conditioned to ADC state. * @note After using this function, other features must be configured * using LL unitary functions. * The minimum configuration remaining to be done is: * - Set ADC group regular or group injected sequencer: * map channel on the selected sequencer rank. * Refer to function @ref LL_ADC_REG_SetSequencerRanks(). * - Set ADC channel sampling time * Refer to function LL_ADC_SetChannelSamplingTime(); * @param ADCx ADC instance * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure * @retval An ErrorStatus enumeration value: * - SUCCESS: ADC registers are initialized * - ERROR: ADC registers are not initialized */ ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct) { ErrorStatus status = SUCCESS; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(ADCx)); #if defined(ADC3) assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADCx, ADC_REG_InitStruct->TriggerSource)); #else assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource)); #endif assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength)); if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) { assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont)); } assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode)); assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer)); /* Note: Hardware constraint (refer to description of this function): */ /* ADC instance must be disabled. */ if(LL_ADC_IsEnabled(ADCx) == 0U) { /* Configuration of ADC hierarchical scope: */ /* - ADC group regular */ /* - Set ADC group regular trigger source */ /* - Set ADC group regular sequencer length */ /* - Set ADC group regular sequencer discontinuous mode */ /* - Set ADC group regular continuous mode */ /* - Set ADC group regular conversion data transfer: no transfer or */ /* transfer by DMA, and DMA requests mode */ /* Note: On this STM32 serie, ADC trigger edge is set when starting */ /* ADC conversion. */ /* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */ if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) { MODIFY_REG(ADCx->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM , ADC_REG_InitStruct->SequencerLength | ADC_REG_InitStruct->SequencerDiscont ); } else { MODIFY_REG(ADCx->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM , ADC_REG_InitStruct->SequencerLength | LL_ADC_REG_SEQ_DISCONT_DISABLE ); } MODIFY_REG(ADCx->CR2, ADC_CR2_EXTSEL | ADC_CR2_CONT | ADC_CR2_DMA , ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DMATransfer ); /* Set ADC group regular sequencer length and scan direction */ /* Note: Hardware constraint (refer to description of this function): */ /* Note: If ADC instance feature scan mode is disabled */ /* (refer to ADC instance initialization structure */ /* parameter @ref SequencersScanMode */ /* or function @ref LL_ADC_SetSequencersScanMode() ), */ /* this parameter is discarded. */ LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength); } else { /* Initialization error: ADC instance is not disabled. */ status = ERROR; } return status; }
static int start_read(struct device *dev, const struct adc_sequence *sequence) { const struct adc_stm32_cfg *config = dev->config->config_info; struct adc_stm32_data *data = dev->driver_data; ADC_TypeDef *adc = (ADC_TypeDef *)config->base; u8_t resolution; int err; switch (sequence->resolution) { #if !defined(CONFIG_SOC_SERIES_STM32F1X) case 6: resolution = table_resolution[0]; break; case 8: resolution = table_resolution[1]; break; case 10: resolution = table_resolution[2]; break; #endif case 12: resolution = table_resolution[3]; break; default: LOG_ERR("Invalid resolution"); return -EINVAL; } u32_t channels = sequence->channels; data->buffer = sequence->buffer; u8_t index; index = find_lsb_set(channels) - 1; u32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(index); #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) LL_ADC_REG_SetSequencerChannels(adc, channel); #else LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel); LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]); #endif data->channel_count = 1; err = check_buffer_size(sequence, data->channel_count); if (err) { return err; } #if !defined(CONFIG_SOC_SERIES_STM32F1X) LL_ADC_SetResolution(adc, resolution); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) LL_ADC_EnableIT_EOC(adc); #elif defined(CONFIG_SOC_SERIES_STM32F1X) LL_ADC_EnableIT_EOS(adc); #else LL_ADC_EnableIT_EOCS(adc); #endif adc_context_start_read(&data->ctx, sequence); return adc_context_wait_for_completion(&data->ctx); }