summaryrefslogtreecommitdiffstats
path: root/boiler-monster/stm32/app/adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'boiler-monster/stm32/app/adc.c')
-rw-r--r--boiler-monster/stm32/app/adc.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/boiler-monster/stm32/app/adc.c b/boiler-monster/stm32/app/adc.c
new file mode 100644
index 0000000..2cfc4e3
--- /dev/null
+++ b/boiler-monster/stm32/app/adc.c
@@ -0,0 +1,154 @@
+#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;
+}
+
+
+
+int adc_convert_start (unsigned channel)
+{
+ uint8_t ch = channel;
+
+ adc_set_regular_sequence (ADC1, 1, &ch);
+
+ /* Start conversion on regular channels. */
+ ADC_CR2 (ADC1) |= ADC_CR2_SWSTART;
+
+#if 0
+ if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_SWSTART, 0, 2))
+ return -1;
+#endif
+
+ return 0;
+}
+
+
+
+int adc_convert_done(void)
+{
+
+ if (ADC_SR(ADC1) & ADC_SR_EOC)
+ return 1;
+
+ return 0;
+}
+
+unsigned adc_convert_get(void)
+{
+ return adc_read_regular (ADC1);
+}
+
+
+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();
+
+
+
+}
+