示例#1
0
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);
}
示例#2
0
static int start_read(struct device *dev, const struct adc_sequence *sequence)
{
	int error = 0;
	u32_t selected_channels = sequence->channels;
	u8_t active_channels;
	u8_t channel_id;
	nrf_adc_config_resolution_t nrf_resolution;

	/* Signal an error if channel selection is invalid (no channels or
	 * a non-existing one is selected).
	 */
	if (!selected_channels ||
	    (selected_channels &
			~BIT_MASK(CONFIG_ADC_NRFX_ADC_CHANNEL_COUNT))) {
		LOG_ERR("Invalid selection of channels");
		return -EINVAL;
	}

	if (sequence->oversampling != 0) {
		LOG_ERR("Oversampling is not supported");
		return -EINVAL;
	}

	switch (sequence->resolution) {
	case  8:
		nrf_resolution = NRF_ADC_CONFIG_RES_8BIT;
		break;
	case  9:
		nrf_resolution = NRF_ADC_CONFIG_RES_9BIT;
		break;
	case 10:
		nrf_resolution = NRF_ADC_CONFIG_RES_10BIT;
		break;
	default:
		LOG_ERR("ADC resolution value %d is not valid",
			    sequence->resolution);
		return -EINVAL;
	}

	active_channels = 0;
	nrfx_adc_all_channels_disable();

	/* Enable the channels selected for the pointed sequence.
	 */
	channel_id = 0;
	while (selected_channels) {
		if (selected_channels & BIT(0)) {
			/* The nrfx driver requires setting the resolution
			 * for each enabled channel individually.
			 */
			m_channels[channel_id].config.resolution =
				nrf_resolution;
			nrfx_adc_channel_enable(&m_channels[channel_id]);
			++active_channels;
		}
		selected_channels >>= 1;
		++channel_id;
	}

	error = check_buffer_size(sequence, active_channels);
	if (error) {
		return error;
	}

	m_data.buffer = sequence->buffer;
	m_data.active_channels = active_channels;

	adc_context_start_read(&m_data.ctx, sequence);

	if (!error) {
		error = adc_context_wait_for_completion(&m_data.ctx);
		adc_context_release(&m_data.ctx, error);
	}

	return error;
}