aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/fsm-adc.c76
-rw-r--r--spaghetti-monster/fsm-adc.h4
-rw-r--r--spaghetti-monster/fsm-wdt.c2
3 files changed, 41 insertions, 41 deletions
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index ddf4c65..d447189 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -30,6 +30,7 @@ inline void set_admux_therm() {
#else
#error Unrecognized MCU type
#endif
+ adc_channel = 1;
}
inline void set_admux_voltage() {
@@ -52,6 +53,7 @@ inline void set_admux_voltage() {
#else
#error Unrecognized MCU type
#endif
+ adc_channel = 0;
}
inline void ADC_start_measurement() {
@@ -115,38 +117,37 @@ static inline uint8_t calc_voltage_divider(uint16_t value) {
#endif
#ifdef USE_THERMAL_REGULATION
-#define ADC_STEPS 4
-#else
#define ADC_STEPS 2
+#else
+#define ADC_STEPS 1
#endif
-// save the measurement result, set a flag to show something happened,
-// and count how many times we've triggered since last counter reset
+// happens every time the ADC sampler finishes a measurement
ISR(ADC_vect) {
- #if 0 // the fancy method is probably not even needed
- // count up but wrap around from 255 to 128; not 255 to 0
- // TODO: find a way to do this faster if possible
- uint8_t val = irq_adc; // cache volatile value
- irq_adc = (val + 1) | (val & 0b10000000);
- #else
- irq_adc ++;
+ #ifdef USE_PSEUDO_RAND
+ // real-world entropy makes this a true random, not pseudo
+ pseudo_rand_seed += ADCL;
#endif
- adc_value = ADC; // save this for later use
+
+ if (irq_adc_stable) { // skip first result; it's junk
+ adc_values[adc_channel] = ADC; // save this for later use
+ irq_adc = 1; // a value was saved, so trigger deferred logic
+ }
+ irq_adc_stable = 1;
+
+ // start another measurement
+ // (is explicit because it otherwise doesn't seem to happen during standby mode)
+ ADC_start_measurement();
}
void ADC_inner() {
- // ignore the first measurement; the docs say it's junk
- if (irq_adc < 2) {
- ADC_start_measurement(); // start a second measurement
- return;
- }
+ irq_adc = 0; // event handled
// the ADC triggers repeatedly when it's on, but we only want one value
// (so ignore everything after the first value, until it's manually reset)
if (! adcint_enable) return;
- // if we're actually runnning, reset the status flags / counters
- irq_adc = 0;
+ // disable after one iteration
adcint_enable = 0;
#ifdef TICK_DURING_STANDBY
@@ -156,41 +157,37 @@ void ADC_inner() {
if (go_to_standby) ADC_off();
#endif
- // what is being measured? 0/1 = battery voltage, 2/3 = temperature
+ // what is being measured? 0 = battery voltage, 1 = temperature
static uint8_t adc_step = 0;
- #ifdef USE_PSEUDO_RAND
- // real-world entropy makes this a true random, not pseudo
- pseudo_rand_seed += adc_value;
- #endif
-
- #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP)
- // only measure battery voltage while asleep
- if (go_to_standby) adc_step = 1;
- else
- #endif
-
- adc_step = (adc_step + 1) & (ADC_STEPS-1);
-
#ifdef USE_LVP
- if (adc_step == 1) { // voltage
+ if (0 == adc_step) { // voltage
ADC_voltage_handler();
}
#endif
#ifdef USE_THERMAL_REGULATION
- else if (adc_step == 3) { // temperature
+ else if (1 == adc_step) { // temperature
ADC_temperature_handler();
}
#endif
+ #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP)
+ // only measure battery voltage while asleep
+ if (go_to_standby) adc_step = 0;
+ else
+ #endif
+
+ adc_step = (adc_step + 1) & (ADC_STEPS-1);
+
// set the correct type of measurement for next time
#ifdef USE_THERMAL_REGULATION
#ifdef USE_LVP
- if (adc_step < 2) set_admux_voltage();
+ if (0 == adc_step) set_admux_voltage();
else set_admux_therm();
#else
- set_admux_therm();
+ //set_admux_therm();
+ #error "USE_THERMAL_REGULATION set without USE_LVP"
#endif
#else
#ifdef USE_LVP
@@ -198,6 +195,7 @@ void ADC_inner() {
#endif
#endif
+ irq_adc_stable = 0; // first result is unstable
}
@@ -213,7 +211,7 @@ static inline void ADC_voltage_handler() {
#define LVP_TIMER_START (VOLTAGE_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between LVP warnings
#define LVP_LOWPASS_STRENGTH ADC_CYCLES_PER_SECOND // lowpass for one second
- uint16_t measurement = adc_value; // latest 10-bit ADC reading
+ uint16_t measurement = adc_values[0]; // latest 10-bit ADC reading
#ifdef USE_LVP_AVG
// prime on first execution
@@ -293,7 +291,7 @@ static inline void ADC_temperature_handler() {
#define OVERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds
#define UNDERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds
- uint16_t measurement = adc_value; // latest 10-bit ADC reading
+ uint16_t measurement = adc_values[1]; // latest 10-bit ADC reading
// Convert ADC units to Celsius (ish)
int16_t temp = measurement - 275 + THERM_CAL_OFFSET + (int16_t)therm_cal_offset;
diff --git a/spaghetti-monster/fsm-adc.h b/spaghetti-monster/fsm-adc.h
index 5f4d0c8..6e39750 100644
--- a/spaghetti-monster/fsm-adc.h
+++ b/spaghetti-monster/fsm-adc.h
@@ -40,7 +40,9 @@
#endif
volatile uint8_t irq_adc = 0; // ADC interrupt happened?
-uint16_t adc_value; // last ADC measurement
+volatile uint8_t irq_adc_stable = 0; // have we passed the 1st junk value yet?
+uint8_t adc_channel = 0; // 0=voltage, 1=temperature
+uint16_t adc_values[2]; // last ADC measurements (0=voltage, 1=temperature)
uint8_t adcint_enable = 0; // is the current ADC result needed?
void ADC_inner(); // do the actual ADC-related calculations
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index 3cb7d86..beab1a2 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -185,7 +185,7 @@ void WDT_inner() {
if (go_to_standby) ADC_on();
#endif
ADC_start_measurement();
- irq_adc = 0;
+ irq_adc_stable = 0;
adcint_enable = 1;
}
#endif
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.