diff options
Diffstat (limited to 'stm32/app/adc.c')
-rw-r--r-- | stm32/app/adc.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/stm32/app/adc.c b/stm32/app/adc.c new file mode 100644 index 0000000..ee6a4f3 --- /dev/null +++ b/stm32/app/adc.c @@ -0,0 +1,121 @@ +#include "project.h" + +#define T do { printf("%s:%d\r\n",__FILE__,__LINE__); } while (0) + +void adc_dump (void) +{ + printf ("ADC_SR %x ADC_CR1 %x ADC_CR2 %x\r\n", (unsigned) ADC_SR (ADC1), + (unsigned) ADC_CR1 (ADC1), + (unsigned) ADC_CR2 (ADC1)); + +} + + +volatile unsigned timeout; + + +void adc_tick (void) +{ + if (timeout) timeout--; +} + + +static int adc_wait (volatile uint32_t *reg, uint32_t wait_while_set, uint32_t wait_while_clear, unsigned ms) +{ + timeout = MS_TO_TICKS (ms); + + + while ((*reg) & wait_while_set) + if (!timeout) { + printf ("QADC timeout\r\n"); + return -1; + } + + + while ((~ (*reg)) & wait_while_clear) + if (!timeout) { + printf ("QADC timeout\r\n"); + return -1; + } + + + return 0; +} + + + +int adc_calibrate (void) +{ + adc_off (ADC1); + adc_power_on (ADC1); + delay_ms (5); + + ADC_CR2 (ADC1) |= ADC_CR2_RSTCAL; + + if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_CAL, 0, 2)) return -1; + + ADC_CR2 (ADC1) |= ADC_CR2_CAL; + + if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_CAL, 0, 2)) return -1; + + return 0; +} + + + + +unsigned adc_convert (unsigned channel) +{ + uint8_t ch = channel; + + adc_calibrate(); + + adc_set_regular_sequence (ADC1, 1, &ch); + + /* Start conversion on regular channels. */ + ADC_CR2 (ADC1) |= ADC_CR2_SWSTART; + + if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_SWSTART, 0, 2)) + return 0; + + if (adc_wait (&ADC_SR (ADC1), 0, ADC_SR_EOC, 2)) + return 0; + + return adc_read_regular (ADC1); +} + +void adc_init (void) +{ + /* main set ADC clock is 9Mhz */ + + adc_dump(); + + adc_off (ADC1); + rcc_periph_clock_enable (RCC_ADC1); +#if 0 + rcc_peripheral_reset (&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_peripheral_clear_reset (&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); +#endif + + adc_set_dual_mode (ADC_CR1_DUALMOD_IND); + adc_disable_scan_mode (ADC1); + adc_enable_temperature_sensor (ADC1); + adc_set_single_conversion_mode (ADC1); + + adc_set_sample_time (ADC1, ADC_CHANNEL0, ADC_SMPR_SMP_239DOT5CYC); + adc_set_sample_time (ADC1, ADC_CHANNEL17, ADC_SMPR_SMP_239DOT5CYC); /*Want 17.1uS , which is 154 cycles */ + adc_enable_external_trigger_regular (ADC1, ADC_CR2_EXTSEL_SWSTART); + + adc_set_right_aligned (ADC1); + + + adc_dump(); + + adc_calibrate(); + + adc_dump(); + + + +} + |