int adc_read_channel(enum adc_channel ch) { const struct adc_t *adc = adc_channels + ch; int value; int restore_watchdog = 0; mutex_lock(&adc_lock); if (adc_watchdog_enabled()) { restore_watchdog = 1; adc_disable_watchdog_no_lock(); } adc_configure(adc->channel); /* Clear flags */ STM32_ADC_ISR = 0xe; /* Start conversion */ STM32_ADC_CR |= 1 << 2; /* ADSTART */ /* Wait for end of conversion */ while (!(STM32_ADC_ISR & (1 << 2))) ; /* read converted value */ value = STM32_ADC_DR; if (restore_watchdog) adc_enable_watchdog_no_lock(); mutex_unlock(&adc_lock); return value * adc->factor_mul / adc->factor_div + adc->shift; }
int adc_disable_watchdog(void) { int ret; mutex_lock(&adc_lock); ret = adc_disable_watchdog_no_lock(); mutex_unlock(&adc_lock); return ret; }
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; }
int adc_read_all_channels(int *data) { int i; uint32_t channels = 0; uint32_t raw_data[ADC_CH_COUNT]; const struct adc_t *adc; int restore_watchdog = 0; int ret = EC_SUCCESS; mutex_lock(&adc_lock); if (adc_watchdog_enabled()) { restore_watchdog = 1; adc_disable_watchdog_no_lock(); } /* Select all used channels */ for (i = 0; i < ADC_CH_COUNT; ++i) channels |= 1 << adc_channels[i].channel; STM32_ADC_CHSELR = channels; /* Enable DMA */ STM32_ADC_CFGR1 |= 0x1; dma_clear_isr(STM32_DMAC_ADC); dma_start_rx(&dma_adc_option, ADC_CH_COUNT, raw_data); /* Clear flags */ STM32_ADC_ISR = 0xe; STM32_ADC_CR |= 1 << 2; /* ADSTART */ if (dma_wait(STM32_DMAC_ADC)) { ret = EC_ERROR_UNKNOWN; goto fail; /* goto fail; goto fail; */ } for (i = 0; i < ADC_CH_COUNT; ++i) { adc = adc_channels + i; data[i] = (raw_data[i] & 0xffff) * adc->factor_mul / adc->factor_div + adc->shift; } fail: if (restore_watchdog) adc_enable_watchdog_no_lock(); mutex_unlock(&adc_lock); return ret; }
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; }
int adc_set_watchdog_delay(int delay_ms) { int resume_watchdog = 0; mutex_lock(&adc_lock); if (adc_watchdog_enabled()) { resume_watchdog = 1; adc_disable_watchdog_no_lock(); } watchdog_delay_ms = delay_ms; if (resume_watchdog) adc_enable_watchdog_no_lock(); mutex_unlock(&adc_lock); return EC_SUCCESS; }
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; }