aboutsummaryrefslogtreecommitdiff
path: root/fsm/adc.h
diff options
context:
space:
mode:
Diffstat (limited to 'fsm/adc.h')
-rw-r--r--fsm/adc.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/fsm/adc.h b/fsm/adc.h
new file mode 100644
index 0000000..1bb67ed
--- /dev/null
+++ b/fsm/adc.h
@@ -0,0 +1,112 @@
+// fsm-adc.h: ADC (voltage, temperature) functions for SpaghettiMonster.
+// Copyright (C) 2017-2023 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#if defined(USE_LVP) || defined(USE_THERMAL_REGULATION)
+// use raw value instead of lowpassed value for the next N measurements
+// (2 = 1 for voltage + 1 for temperature)
+volatile uint8_t adc_reset = 2;
+#endif
+
+#ifdef USE_LVP
+// default 5 seconds between low-voltage warning events
+#ifndef VOLTAGE_WARNING_SECONDS
+#define VOLTAGE_WARNING_SECONDS 5
+#endif
+// low-battery threshold in volts * 10
+#ifndef VOLTAGE_LOW
+#define VOLTAGE_LOW 29
+#endif
+// battery is low but not critical
+#ifndef VOLTAGE_RED
+#define VOLTAGE_RED 33
+#endif
+// MCU sees voltage 0.X volts lower than actual, add X/2 to readings
+#ifndef VOLTAGE_FUDGE_FACTOR
+#ifdef USE_VOLTAGE_DIVIDER
+#define VOLTAGE_FUDGE_FACTOR 0
+#else
+#define VOLTAGE_FUDGE_FACTOR 5
+#endif
+#endif
+
+#ifdef TICK_DURING_STANDBY
+volatile uint8_t adc_active_now = 0; // sleep LVP needs a different sleep mode
+#endif
+volatile uint8_t irq_adc = 0; // ADC interrupt happened?
+uint8_t adc_sample_count = 0; // skip the first sample; it's junk
+uint8_t adc_channel = 0; // 0=voltage, 1=temperature
+uint16_t adc_raw[2]; // last ADC measurements (0=voltage, 1=temperature)
+uint16_t adc_smooth[2]; // lowpassed ADC measurements (0=voltage, 1=temperature)
+// ADC code is split into two parts:
+// - ISR: runs immediately at each interrupt, does the bare minimum because time is critical here
+// - deferred: the bulk of the logic runs later when time isn't so critical
+uint8_t adc_deferred_enable = 0; // stop waiting and run the deferred code
+void adc_deferred(); // do the actual ADC-related calculations
+
+static inline void ADC_voltage_handler();
+uint8_t voltage = 0;
+#ifdef USE_VOLTAGE_CORRECTION
+ #ifdef USE_CFG
+ #define VOLT_CORR cfg.voltage_correction
+ #else
+ // same 0.05V units as fudge factor,
+ // but 7 is neutral, and the expected range is from 1 to 13
+ uint8_t voltage_correction = 7;
+ #define VOLT_CORR voltage_correction
+ #endif
+#endif
+#ifdef USE_LVP
+void low_voltage();
+#endif
+
+#ifdef USE_BATTCHECK
+void battcheck();
+#ifdef BATTCHECK_VpT
+#define USE_BLINK_NUM
+#endif
+#if defined(BATTCHECK_8bars) || defined(BATTCHECK_6bars) || defined(BATTCHECK_4bars)
+#define USE_BLINK_DIGIT
+#endif
+#endif
+#endif // ifdef USE_LVP
+
+
+#ifdef USE_THERMAL_REGULATION
+// try to keep temperature below 45 C
+#ifndef DEFAULT_THERM_CEIL
+#define DEFAULT_THERM_CEIL 45
+#endif
+// don't allow user to set ceiling above 70 C
+#ifndef MAX_THERM_CEIL
+#define MAX_THERM_CEIL 70
+#endif
+// Local per-MCU calibration value
+#ifndef THERM_CAL_OFFSET
+#define THERM_CAL_OFFSET 0
+#endif
+// temperature now, in C (ish)
+int16_t temperature;
+#ifdef USE_CFG
+ #define TH_CEIL cfg.therm_ceil
+ #define TH_CAL cfg.therm_cal_offset
+#else
+ #define TH_CEIL therm_ceil
+ #define TH_CAL therm_cal_offset
+ uint8_t therm_ceil = DEFAULT_THERM_CEIL;
+ int8_t therm_cal_offset = 0;
+#endif
+static inline void ADC_temperature_handler();
+#endif // ifdef USE_THERMAL_REGULATION
+
+
+inline void ADC_on();
+inline void ADC_off();
+inline void ADC_start_measurement();
+
+#ifdef TICK_DURING_STANDBY
+inline void adc_sleep_mode();
+#endif
+