From 8c7ee88332652e7e79f6c1e4baacabe2183f7e8e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 2 Mar 2021 12:54:03 +0000 Subject: working, with hybrid FLL/PLL, new refclk input and support for max7219 displays, neo 5 and neo 7 and a bazillion other fixes --- app/adc.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 app/adc.c (limited to 'app/adc.c') diff --git a/app/adc.c b/app/adc.c new file mode 100644 index 0000000..821bac9 --- /dev/null +++ b/app/adc.c @@ -0,0 +1,137 @@ +#include "project.h" + + +#define POT GPIO3 +#define POT_PORT GPIOC + +#define POT_CHANNEL ADC_CHANNEL13 +#define VREF_CHANNEL ADC_CHANNEL17 + +#define ADC_TIMEOUT 1000 + +static enum { + WAIT_VREF, + WAIT_POT +} state = WAIT_VREF; + + +static uint32_t adc_stamp; +static uint16_t pot, vref; + +uint8_t pot_brightness = 0x8; + + +static void start_conversion (uint8_t ch) +{ + adc_stamp = ticks; + adc_set_regular_sequence (ADC1, 1, &ch); + adc_start_conversion_regular (ADC1); +} + +static void calculate_and_set_brightness (void) +{ + static uint32_t spot, svref; + uint32_t v; + + /* dumb IIR with 16x gain */ + spot *= 15; + spot >>= 4; + spot += pot ; + + svref *= 15; + svref >>= 4; + svref += vref ; + + + if (svref > 65535) svref = 65535; + + if (spot > 65535) spot = 65535; + + v = spot << 16; + v /= svref; + v <<= 8; + v /= 12014; // vref is 1.2v FSD is 3.3v, 15 brightness levels so (65536 * (3.3/1.2) /15 ) + + v >>= 8; + + + if (v > 15) v = 15; + + pot_brightness = v; +} + + +void adc_dispatch (void) +{ + uint32_t now = ticks; + uint32_t ago; + + ago = now - adc_stamp; + + if (ago > ADC_TIMEOUT) { + adc_off (ADC1); + adc_power_on (ADC1); + state = WAIT_VREF; + start_conversion (VREF_CHANNEL); + return; + } + + if (!adc_eoc (ADC1)) + return; + + switch (state) { + case WAIT_VREF: + vref = adc_read_regular (ADC1); + start_conversion (POT_CHANNEL); + state = WAIT_POT; + break; + + case WAIT_POT: + pot = adc_read_regular (ADC1); + start_conversion (VREF_CHANNEL); + calculate_and_set_brightness(); + + /* fall through */ + default: + state = WAIT_VREF; + } +} + + + + + + + + + + + + + + +void adc_init (void) +{ + rcc_periph_clock_enable (RCC_ADC1); + + MAP_ANALOG_INPUT (POT); + + adc_off (ADC1); + adc_disable_scan_mode (ADC1); + adc_enable_temperature_sensor(); + + adc_set_single_conversion_mode (ADC1); + adc_enable_temperature_sensor(); /*Enables reference*/ + adc_set_sample_time (ADC1, POT_CHANNEL, ADC_SMPR_SMP_480CYC); + adc_set_sample_time (ADC1, VREF_CHANNEL, ADC_SMPR_SMP_480CYC); + adc_enable_external_trigger_regular (ADC1, 0, ADC_CR2_EXTEN_DISABLED); + adc_set_right_aligned (ADC1); + adc_eoc_after_group (ADC1); + + adc_power_on (ADC1); + adc_enable_temperature_sensor(); /*Enables reference*/ + + state = WAIT_VREF; + start_conversion (VREF_CHANNEL); +} + -- cgit v1.2.3