#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_power_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_power_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); }