Example #1
0
int adc_disable_watchdog(void)
{
	int ret;

	if (!adc_powered())
		return EC_ERROR_UNKNOWN;

	mutex_lock(&adc_lock);
	ret = adc_disable_watchdog_no_lock();
	mutex_unlock(&adc_lock);
	return ret;
}
Example #2
0
int adc_read_all_channels(int *data)
{
	int i;
	int16_t raw_data[ADC_CH_COUNT];
	const struct adc_t *adc;
	int restore_watchdog = 0;
	int ret = EC_SUCCESS;

	if (!adc_powered())
		return EC_ERROR_UNKNOWN;

	mutex_lock(&adc_lock);

	if (adc_watchdog_enabled()) {
		restore_watchdog = 1;
		adc_disable_watchdog_no_lock();
	}

	adc_configure_all();

	dma_clear_isr(STM32_DMAC_ADC);
	dma_start_rx(&dma_adc_option, ADC_CH_COUNT, raw_data);

	/* Start conversion */
	STM32_ADC_CR2 |= (1 << 0); /* ADON */

	if (dma_wait(STM32_DMAC_ADC)) {
		ret = EC_ERROR_UNKNOWN;
		goto exit_all_channels;
	}

	for (i = 0; i < ADC_CH_COUNT; ++i) {
		adc = adc_channels + i;
		data[i] = raw_data[i] * adc->factor_mul / adc->factor_div +
			  adc->shift;
	}

exit_all_channels:
	dma_disable(STM32_DMAC_ADC);

	if (restore_watchdog)
		adc_enable_watchdog_no_lock();

	mutex_unlock(&adc_lock);
	return ret;
}
Example #3
0
int adc_enable_watchdog(int ain_id, int high, int low)
{
	int ret;

	if (!adc_powered())
		return EC_ERROR_UNKNOWN;

	mutex_lock(&adc_lock);

	watchdog_ain_id = ain_id;

	/* Set thresholds */
	STM32_ADC_HTR = high & 0xfff;
	STM32_ADC_LTR = low & 0xfff;

	ret = adc_enable_watchdog_no_lock();
	mutex_unlock(&adc_lock);
	return ret;
}
Example #4
0
int adc_read_channel(enum adc_channel ch)
{
	const struct adc_t *adc = adc_channels + ch;
	int value;
	int restore_watchdog = 0;
	timestamp_t deadline;

	if (!adc_powered())
		return EC_ERROR_UNKNOWN;

	mutex_lock(&adc_lock);

	if (adc_watchdog_enabled()) {
		restore_watchdog = 1;
		adc_disable_watchdog_no_lock();
	}

	adc_configure(adc->channel);

	/* Clear EOC bit */
	STM32_ADC_SR &= ~(1 << 1);

	/* Start conversion */
	STM32_ADC_CR2 |= (1 << 0); /* ADON */

	/* Wait for EOC bit set */
	deadline.val = get_time().val + ADC_SINGLE_READ_TIMEOUT;
	value = ADC_READ_ERROR;
	do {
		if (adc_conversion_ended()) {
			value = STM32_ADC_DR & ADC_READ_MAX;
			break;
		}
	} while (!timestamp_expired(deadline, NULL));

	if (restore_watchdog)
		adc_enable_watchdog_no_lock();

	mutex_unlock(&adc_lock);
	return (value == ADC_READ_ERROR) ? ADC_READ_ERROR :
	       value * adc->factor_mul / adc->factor_div + adc->shift;
}
Example #5
0
static void adc_init(void)
{
	/*
	 * Enable ADC clock.
	 * APB2 clock is 16MHz. ADC clock prescaler is /2.
	 * So the ADC clock is 8MHz.
	 */
	STM32_RCC_APB2ENR |= (1 << 9);

	/*
	 * ADC clock is divided with respect to AHB, so no delay needed
	 * here. If ADC clock is the same as AHB, a dummy read on ADC
	 * register is needed here.
	 */

	if (!adc_powered()) {
		/* Power on ADC module */
		STM32_ADC_CR2 |= (1 << 0);  /* ADON */

		/* Reset calibration */
		STM32_ADC_CR2 |= (1 << 3);  /* RSTCAL */
		while (STM32_ADC_CR2 & (1 << 3))
			;

		/* A/D Calibrate */
		STM32_ADC_CR2 |= (1 << 2);  /* CAL */
		while (STM32_ADC_CR2 & (1 << 2))
			;
	}

	/* Set right alignment */
	STM32_ADC_CR2 &= ~(1 << 11);

	/*
	 * Set sample time of all channels to 13.5 cycles.
	 * Conversion takes 15.75 us.
	 */
	STM32_ADC_SMPR1 = 0x00492492;
	STM32_ADC_SMPR2 = 0x12492492;
}
Example #6
0
static void adc_init(void)
{
	/*
	 * Enable ADC clock.
	 * APB2 clock is 16MHz. ADC clock prescaler is /2.
	 * So the ADC clock is 8MHz.
	 */
	STM32_RCC_APB2ENR |= (1 << 9);

	/*
	 * ADC clock is divided with respect to AHB, so no delay needed
	 * here. If ADC clock is the same as AHB, a dummy read on ADC
	 * register is needed here.
	 */

	if (!adc_powered()) {
		/* Power on ADC module */
		STM32_ADC_CR2 |= (1 << 0);  /* ADON */

		/* Reset calibration */
		STM32_ADC_CR2 |= (1 << 3);  /* RSTCAL */
		while (STM32_ADC_CR2 & (1 << 3))
			;

		/* A/D Calibrate */
		STM32_ADC_CR2 |= (1 << 2);  /* CAL */
		while (STM32_ADC_CR2 & (1 << 2))
			;
	}

	/* Set right alignment */
	STM32_ADC_CR2 &= ~(1 << 11);

	/* Set sample time of all channels */
	STM32_ADC_SMPR1 = SMPR1_EXPAND(CONFIG_ADC_SAMPLE_TIME);
	STM32_ADC_SMPR2 = SMPR2_EXPAND(CONFIG_ADC_SAMPLE_TIME);
}