aboutsummaryrefslogtreecommitdiff
path: root/fsm
diff options
context:
space:
mode:
Diffstat (limited to 'fsm')
-rw-r--r--fsm/adc.c58
-rw-r--r--fsm/adc.h10
-rw-r--r--fsm/chan-aux.c2
-rw-r--r--fsm/chan-rgbaux.c14
-rw-r--r--fsm/eeprom.c8
-rw-r--r--fsm/eeprom.h8
-rw-r--r--fsm/misc.c58
-rw-r--r--fsm/misc.h3
-rw-r--r--fsm/ramping.c35
-rw-r--r--fsm/ramping.h3
10 files changed, 150 insertions, 49 deletions
diff --git a/fsm/adc.c b/fsm/adc.c
index fbe84a1..e0bacb6 100644
--- a/fsm/adc.c
+++ b/fsm/adc.c
@@ -209,8 +209,8 @@ static void ADC_voltage_handler() {
#endif
else measurement = adc_smooth[0];
- // convert raw ADC value to FSM voltage units: Volts * 40
- // 0 .. 200 = 0.0V .. 5.0V
+ // convert raw ADC value to FSM voltage units: Volts * 50
+ // 0 .. 250 = 0.0V .. 5.0V
voltage = voltage_raw2cooked(measurement)
+ (VOLTAGE_FUDGE_FACTOR << 1)
#ifdef USE_VOLTAGE_CORRECTION
@@ -392,46 +392,46 @@ static void ADC_temperature_handler() {
#ifdef USE_BATTCHECK
#ifdef BATTCHECK_4bars
PROGMEM const uint8_t voltage_blinks[] = {
- 4*30,
- 4*35,
- 4*38,
- 4*40,
- 4*42,
- 255,
+ 30*dV,
+ 35*dV,
+ 38*dV,
+ 40*dV,
+ 42*dV,
+ 255,
};
#endif
#ifdef BATTCHECK_6bars
PROGMEM const uint8_t voltage_blinks[] = {
- 4*30,
- 4*34,
- 4*36,
- 4*38,
- 4*40,
- 4*41,
- 4*43,
- 255,
+ 30*dV,
+ 34*dV,
+ 36*dV,
+ 38*dV,
+ 40*dV,
+ 41*dV,
+ 43*dV,
+ 255,
};
#endif
#ifdef BATTCHECK_8bars
PROGMEM const uint8_t voltage_blinks[] = {
- 4*30,
- 4*33,
- 4*35,
- 4*37,
- 4*38,
- 4*39,
- 4*40,
- 4*41,
- 4*42,
- 255,
+ 30*dV,
+ 33*dV,
+ 35*dV,
+ 37*dV,
+ 38*dV,
+ 39*dV,
+ 40*dV,
+ 41*dV,
+ 42*dV,
+ 255,
};
#endif
void battcheck() {
#ifdef BATTCHECK_VpT
- blink_num(voltage / 4);
+ blink_num(voltage / dV);
#ifdef USE_EXTRA_BATTCHECK_DIGIT
- // 0 1 2 3 --> 0 2 5 7, representing x.x00 x.x25 x.x50 x.x75
- blink_num(((voltage % 4)<<1) + ((voltage % 4)>>1));
+ // 0.02V precision, 0 1 2 3 4 remainder -> .00 .02 .04 .06 .08V
+ blink_num((voltage % dV) * (10/dV));
#endif
#else
uint8_t i;
diff --git a/fsm/adc.h b/fsm/adc.h
index 02e33f8..5dec6c5 100644
--- a/fsm/adc.h
+++ b/fsm/adc.h
@@ -4,6 +4,10 @@
#pragma once
+// voltage is 0.00V to 5.10V in 0.02V steps, from 0 to 255
+// so one deci-Volt is 5 steps
+#define dV 5
+
#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)
@@ -15,13 +19,13 @@ volatile uint8_t adc_reset = 2;
#ifndef VOLTAGE_WARNING_SECONDS
#define VOLTAGE_WARNING_SECONDS 5
#endif
-// low-battery threshold in volts * 10
+// low-battery threshold in volts * 50
#ifndef VOLTAGE_LOW
-#define VOLTAGE_LOW (4*29)
+#define VOLTAGE_LOW (29*dV)
#endif
// battery is low but not critical
#ifndef VOLTAGE_RED
-#define VOLTAGE_RED (4*33)
+#define VOLTAGE_RED (33*dV)
#endif
// MCU sees voltage 0.X volts lower than actual, add X/2 to readings
#ifndef VOLTAGE_FUDGE_FACTOR
diff --git a/fsm/chan-aux.c b/fsm/chan-aux.c
index e04e6a2..239316a 100644
--- a/fsm/chan-aux.c
+++ b/fsm/chan-aux.c
@@ -4,7 +4,7 @@
#pragma once
void set_level_aux(uint8_t level) {
- indicator_led(!(!(level)) << 1); // high (or off)
+ indicator_led((!(!(level)) << 1) + 1); // high (level > 0) or low
}
bool gradual_tick_null(uint8_t gt) { return true; } // do nothing
diff --git a/fsm/chan-rgbaux.c b/fsm/chan-rgbaux.c
index 19d18a6..a66c29e 100644
--- a/fsm/chan-rgbaux.c
+++ b/fsm/chan-rgbaux.c
@@ -4,31 +4,31 @@
#pragma once
void set_level_auxred(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b000010); // red, high (or off)
+ rgb_led_set(0b000001 << !(!(level))); // red, high (level > 0) or low
}
void set_level_auxyel(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b001010); // red+green, high (or off)
+ rgb_led_set(0b000101 << !(!(level))); // red+green, high (level > 0) or low
}
void set_level_auxgrn(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b001000); // green, high (or off)
+ rgb_led_set(0b000100 << !(!(level))); // green, high (level > 0) or low
}
void set_level_auxcyn(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b101000); // green+blue, high (or off)
+ rgb_led_set(0b010100 << !(!(level))); // green+blue, high (level > 0) or low
}
void set_level_auxblu(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b100000); // blue, high (or off)
+ rgb_led_set(0b010000 << !(!(level))); // blue, high (level > 0) or low
}
void set_level_auxprp(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b100010); // red+blue, high (or off)
+ rgb_led_set(0b010001 << !(!(level))); // red+blue, high (level > 0) or low
}
void set_level_auxwht(uint8_t level) {
- rgb_led_set(!(!(level)) * 0b101010); // red+green+blue, high (or off)
+ rgb_led_set(0b010101 << !(!(level))); // red+green+blue, high (level > 0) or low
}
bool gradual_tick_null(uint8_t gt) { return true; } // do nothing
diff --git a/fsm/eeprom.c b/fsm/eeprom.c
index 8f8bd67..436a736 100644
--- a/fsm/eeprom.c
+++ b/fsm/eeprom.c
@@ -14,7 +14,7 @@ uint8_t eeprom[EEPROM_BYTES];
#endif
uint8_t load_eeprom() {
- #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN)
+ #ifdef USE_EEP_DELAY
delay_4ms(2); // wait for power to stabilize
#endif
@@ -32,7 +32,7 @@ uint8_t load_eeprom() {
}
void save_eeprom() {
- #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN)
+ #ifdef USE_EEP_DELAY
delay_4ms(2); // wait for power to stabilize
#endif
@@ -54,7 +54,7 @@ uint8_t eeprom_wl[EEPROM_WL_BYTES];
uint8_t * eep_wl_prev_offset;
uint8_t load_eeprom_wl() {
- #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN)
+ #ifdef USE_EEP_DELAY
delay_4ms(2); // wait for power to stabilize
#endif
@@ -83,7 +83,7 @@ uint8_t load_eeprom_wl() {
}
void save_eeprom_wl() {
- #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN)
+ #ifdef USE_EEP_DELAY
delay_4ms(2); // wait for power to stabilize
#endif
diff --git a/fsm/eeprom.h b/fsm/eeprom.h
index 1e10fd2..d5f0363 100644
--- a/fsm/eeprom.h
+++ b/fsm/eeprom.h
@@ -55,3 +55,11 @@
// if this marker isn't found, the eeprom is assumed to be blank
#define EEP_MARKER 0b10100101
+// wait a few ms before eeprom operations, to wait for power to stabilize
+// (otherwise reads or writes can get corrupt data)
+// (not necessary on some hardware,
+// but enabled by default when there's space)
+#if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) || (ROM_SIZE > 10000)
+ #define USE_EEP_DELAY
+#endif
+
diff --git a/fsm/misc.c b/fsm/misc.c
index fa8ddd7..915dbd4 100644
--- a/fsm/misc.c
+++ b/fsm/misc.c
@@ -65,6 +65,16 @@ uint8_t blink_digit(uint8_t num) {
return nice_delay_ms(BLINK_SPEED * 8 / 12);
}
+#ifdef USE_LONG_BLINK_FOR_NEGATIVE_SIGN
+void blink_negative() {
+ // "negative" symbol gets a single long blink
+ uint8_t ontime = BLINK_SPEED * 2 / 12;
+ set_level(BLINK_BRIGHTNESS);
+ nice_delay_ms(ontime * 3);
+ set_level(0);
+ nice_delay_ms(ontime * 5);
+}
+#endif
#endif
#ifdef USE_BLINK_BIG_NUM
@@ -245,6 +255,50 @@ void rgb_led_set(uint8_t value) {
// FIXME: move this logic to arch/*
#if (MCU==0x1616) || (MCU==0x32dd20) // ATTINY816, 817, etc
+ // FIXME: this *really* needs to be moved to somewhere hardware-specific
+ #ifdef AUXLED_RGB_DIFFERENT_PORTS
+
+ case 0: // LED off
+ if (i == 0) {
+ AUXLED_R_PORT.DIRSET = (1 << pin);
+ AUXLED_R_PORT.OUTCLR = (1 << pin);
+ } else if (i == 1) {
+ AUXLED_G_PORT.DIRSET = (1 << pin);
+ AUXLED_G_PORT.OUTCLR = (1 << pin);
+ } else if (i == 2) {
+ AUXLED_B_PORT.DIRSET = (1 << pin);
+ AUXLED_B_PORT.OUTCLR = (1 << pin);
+ }
+ break;
+
+ case 1: // LED low
+ if (i == 0) {
+ AUXLED_R_PORT.DIRCLR = (1 << pin);
+ *((uint8_t *)&AUXLED_R_PORT + 0x10 + pin) = PORT_PULLUPEN_bm;
+ } else if (i == 1) {
+ AUXLED_G_PORT.DIRCLR = (1 << pin);
+ *((uint8_t *)&AUXLED_G_PORT + 0x10 + pin) = PORT_PULLUPEN_bm;
+ } else if (i == 2) {
+ AUXLED_B_PORT.DIRCLR = (1 << pin);
+ *((uint8_t *)&AUXLED_B_PORT + 0x10 + pin) = PORT_PULLUPEN_bm;
+ }
+ break;
+
+ default: // LED high
+ if (i==0) {
+ AUXLED_R_PORT.DIRSET = (1 << pin);
+ AUXLED_R_PORT.OUTSET = (1 << pin);
+ } else if (i==1) {
+ AUXLED_G_PORT.DIRSET = (1 << pin);
+ AUXLED_G_PORT.OUTSET = (1 << pin);
+ } else if (i==2) {
+ AUXLED_B_PORT.DIRSET = (1 << pin);
+ AUXLED_B_PORT.OUTSET = (1 << pin);
+ }
+ break;
+
+ #else // not ifdef AUXLED_RGB_DIFFERENT_PORTS
+
case 0: // LED off
AUXLED_RGB_PORT.DIRSET = (1 << pin); // set as output
AUXLED_RGB_PORT.OUTCLR = (1 << pin); // set output low
@@ -258,8 +312,10 @@ void rgb_led_set(uint8_t value) {
AUXLED_RGB_PORT.DIRSET = (1 << pin); // set as output
AUXLED_RGB_PORT.OUTSET = (1 << pin); // set as high
break;
+
+ #endif
- #else
+ #else // not #if (MCU==0x1616) || (MCU==0x32dd20)
case 0: // LED off
AUXLED_RGB_DDR &= 0xff ^ (1 << pin);
diff --git a/fsm/misc.h b/fsm/misc.h
index ba1f8d9..0b13496 100644
--- a/fsm/misc.h
+++ b/fsm/misc.h
@@ -28,6 +28,9 @@ void auto_clock_speed();
#ifdef USE_BLINK_NUM
//#define USE_BLINK
uint8_t blink_num(uint8_t num);
+#ifdef USE_LONG_BLINK_FOR_NEGATIVE_SIGN
+void blink_negative();
+#endif
#endif
/*
diff --git a/fsm/ramping.c b/fsm/ramping.c
index adc8acb..f8ca4ec 100644
--- a/fsm/ramping.c
+++ b/fsm/ramping.c
@@ -8,14 +8,20 @@
#ifdef HAS_AUX_LEDS
inline void set_level_aux_leds(uint8_t level) {
+ #ifdef USE_AUX_THRESHOLD_CONFIG
+ #define AUX_BRIGHTNESS ((level > cfg.button_led_low_ramp_level) \
+ << (level > cfg.button_led_high_ramp_level))
+ #else
+ #define AUX_BRIGHTNESS ((level > 0) + (level > DEFAULT_LEVEL))
+ #endif
#ifdef USE_INDICATOR_LED_WHILE_RAMPING
// use side-facing aux LEDs while main LEDs are on
if (! go_to_standby) {
#ifdef USE_INDICATOR_LED
- indicator_led((level > 0) + (level > DEFAULT_LEVEL));
+ indicator_led(AUX_BRIGHTNESS);
#endif
#ifdef USE_BUTTON_LED
- button_led_set((level > 0) + (level > DEFAULT_LEVEL));
+ button_led_set(AUX_BRIGHTNESS);
#endif
}
#else // turn off front-facing aux LEDs while main LEDs are on
@@ -27,12 +33,15 @@ inline void set_level_aux_leds(uint8_t level) {
#ifdef USE_AUX_RGB_LEDS
rgb_led_set(0);
#ifdef USE_BUTTON_LED
- button_led_set((level > 0) + (level > DEFAULT_LEVEL));
+ button_led_set(AUX_BRIGHTNESS);
#endif
#endif
}
#endif
#endif
+ #ifdef AUX_BRIGHTNESS
+ #undef AUX_BRIGHTNESS
+ #endif
}
#endif // ifdef HAS_AUX_LEDS
@@ -41,15 +50,28 @@ inline void set_level_aux_leds(uint8_t level) {
#include "anduril/aux-leds.h" // for rgb_led_voltage_readout()
inline void set_level_aux_rgb_leds(uint8_t level) {
if (! go_to_standby) {
+ #ifdef USE_AUX_THRESHOLD_CONFIG
+ if (level > cfg.button_led_low_ramp_level) {
+ rgb_led_voltage_readout(level > cfg.button_led_high_ramp_level);
+ }
+ #else
if (level > 0) {
rgb_led_voltage_readout(level > USE_AUX_RGB_LEDS_WHILE_ON);
- } else {
+ }
+ #endif
+ else {
rgb_led_set(0);
}
// some drivers can be wired with RGB or single color to button
// ... so support both even though only one is connected
#ifdef USE_BUTTON_LED
+ #ifdef USE_AUX_THRESHOLD_CONFIG
+ button_led_set(
+ (level > cfg.button_led_low_ramp_level)
+ << (level > cfg.button_led_high_ramp_level));
+ #else
button_led_set((level > 0) + (level > DEFAULT_LEVEL));
+ #endif
#endif
}
}
@@ -57,6 +79,11 @@ inline void set_level_aux_rgb_leds(uint8_t level) {
void set_level(uint8_t level) {
+ #ifdef USE_RAMP_LEVEL_HARD_LIMIT
+ if (ramp_level_hard_limit && (level > ramp_level_hard_limit))
+ level = ramp_level_hard_limit;
+ #endif
+
#ifdef USE_JUMP_START
// maybe "jump start" the engine, if it's prone to slow starts
// (pulse the output high for a moment to wake up the power regulator)
diff --git a/fsm/ramping.h b/fsm/ramping.h
index c4b7d48..f542bd2 100644
--- a/fsm/ramping.h
+++ b/fsm/ramping.h
@@ -10,6 +10,9 @@
uint8_t actual_level = 0;
// the level used before actual
uint8_t prev_level = 0;
+#ifdef USE_RAMP_LEVEL_HARD_LIMIT
+uint8_t ramp_level_hard_limit = 0;
+#endif
void set_level(uint8_t level);
//void set_level_smooth(uint8_t level);