summaryrefslogtreecommitdiffstats
path: root/app/adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/adc.c')
-rw-r--r--app/adc.c137
1 files changed, 137 insertions, 0 deletions
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);
+}
+