aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/anduril/anduril.c52
-rw-r--r--spaghetti-monster/fsm-adc.c48
-rw-r--r--spaghetti-monster/fsm-adc.h4
-rw-r--r--spaghetti-monster/fsm-ramping.h37
-rw-r--r--tk-attiny.h45
5 files changed, 156 insertions, 30 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 8e298b9..36d29ac 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -23,6 +23,7 @@
#define FSM_EMISAR_D4_DRIVER
//#define FSM_BLF_Q8_DRIVER
//#define FSM_FW3A_DRIVER
+//#define FSM_BLF_GT_DRIVER
#define USE_LVP
#define USE_THERMAL_REGULATION
@@ -62,10 +63,25 @@
#ifdef FSM_BLF_Q8_DRIVER
#define USE_INDICATOR_LED
#define VOLTAGE_FUDGE_FACTOR 7 // add 0.35V
+
#elif defined(FSM_EMISAR_D4_DRIVER)
#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V
+
#elif defined(FSM_FW3A_DRIVER)
#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V
+
+#elif defined(FSM_BLF_GT_DRIVER)
+#define USE_INDICATOR_LED
+#undef BLINK_AT_CHANNEL_BOUNDARIES
+#undef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_FLOOR
+//#undef USE_SET_LEVEL_GRADUALLY
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL POWER_80PX
+#define RAMP_DISCRETE_FLOOR 1
+#define RAMP_DISCRETE_CEIL POWER_80PX
+#define RAMP_DISCRETE_STEPS 7
+
#endif
// try to auto-detect how many eeprom bytes
@@ -162,20 +178,36 @@ void save_config();
void save_config_wl();
#endif
+// default ramp options if not overridden earlier per-driver
+#ifndef RAMP_SMOOTH_FLOOR
+ #define RAMP_SMOOTH_FLOOR 1
+#endif
+#ifndef RAMP_SMOOTH_CEIL
+ #if PWM_CHANNELS == 3
+ #define RAMP_SMOOTH_CEIL MAX_Nx7135
+ #else
+ #define RAMP_SMOOTH_CEIL MAX_LEVEL - 30
+ #endif
+#endif
+#ifndef RAMP_DISCRETE_FLOOR
+ #define RAMP_DISCRETE_FLOOR 20
+#endif
+#ifndef RAMP_DISCRETE_CEIL
+ #define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#endif
+#ifndef RAMP_DISCRETE_STEPS
+ #define RAMP_DISCRETE_STEPS 7
+#endif
+
// brightness control
uint8_t memorized_level = MAX_1x7135;
// smooth vs discrete ramping
volatile uint8_t ramp_style = 0; // 0 = smooth, 1 = discrete
-volatile uint8_t ramp_smooth_floor = 1;
-#if PWM_CHANNELS == 3
-volatile uint8_t ramp_smooth_ceil = MAX_Nx7135;
-volatile uint8_t ramp_discrete_ceil = MAX_Nx7135;
-#else
-volatile uint8_t ramp_smooth_ceil = MAX_LEVEL - 30;
-volatile uint8_t ramp_discrete_ceil = MAX_LEVEL - 30;
-#endif
-volatile uint8_t ramp_discrete_floor = 20;
-volatile uint8_t ramp_discrete_steps = 7;
+volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
+volatile uint8_t ramp_smooth_ceil = RAMP_SMOOTH_CEIL;
+volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR;
+volatile uint8_t ramp_discrete_ceil = RAMP_DISCRETE_CEIL;
+volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS;
uint8_t ramp_discrete_step_size; // don't set this
#ifdef USE_INDICATOR_LED
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index c6f5d2a..6e9f19b 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -20,13 +20,25 @@
#ifndef FSM_ADC_C
#define FSM_ADC_C
+#ifdef USE_VOLTAGE_DIVIDER
+// 1.1V / pin7
+#define ADMUX_VOLTAGE ADMUX_VOLTAGE_DIVIDER
+#else
+// VCC / 1.1V reference
+#define ADMUX_VOLTAGE ADMUX_VCC
+#endif
+
inline void ADC_on()
{
// read voltage on VCC by default
+ ADMUX = ADMUX_VOLTAGE;
+ #ifdef USE_VOLTAGE_DIVIDER
+ // disable digital input on divider pin to reduce power consumption
+ DIDR0 |= (1 << VOLTAGE_ADC_DIDR);
+ #else
// disable digital input on VCC pin to reduce power consumption
//DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin
- // VCC / 1.1V reference
- ADMUX = ADMUX_VCC;
+ #endif
// enable, start, prescale
ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL;
}
@@ -35,6 +47,16 @@ inline void ADC_off() {
ADCSRA &= ~(1<<ADEN); //ADC off
}
+#ifdef USE_VOLTAGE_DIVIDER
+static inline uint8_t calc_voltage_divider(uint16_t value) {
+ // use 9.7 fixed-point to get sufficient precision
+ uint16_t adc_per_volt = ((ADC_44<<7) - (ADC_22<<7)) / (44-22);
+ // incoming value is 14.2 fixed-point, so shift it 2 bits less
+ uint8_t result = ((value<<5) / adc_per_volt) + VOLTAGE_FUDGE_FACTOR;
+ return result;
+}
+#endif
+
// Each full cycle runs 7.8X per second with just voltage enabled,
// or 3.9X per second with voltage and temperature.
#if defined(USE_LVP) && defined(USE_THERMAL_REGULATION)
@@ -109,14 +131,22 @@ ISR(ADC_vect) {
total += measurement;
total = total >> 2;
+ #ifdef USE_VOLTAGE_DIVIDER
+ voltage = calc_voltage_divider(total);
+ #else
voltage = (uint16_t)(1.1*1024*10)/total + VOLTAGE_FUDGE_FACTOR;
+ #endif
}
#else // no USE_LVP_AVG
- // calculate actual voltage: volts * 10
- // ADC = 1.1 * 1024 / volts
- // volts = 1.1 * 1024 / ADC
- //voltage = (uint16_t)(1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR;
- voltage = ((uint16_t)(2*1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR) >> 1;
+ #ifdef USE_VOLTAGE_DIVIDER
+ voltage = calc_voltage_divider(measurement);
+ #else
+ // calculate actual voltage: volts * 10
+ // ADC = 1.1 * 1024 / volts
+ // volts = 1.1 * 1024 / ADC
+ //voltage = (uint16_t)(1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR;
+ voltage = ((uint16_t)(2*1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR) >> 1;
+ #endif
#endif
// if low, callback EV_voltage_low / EV_voltage_critical
// (but only if it has been more than N ticks since last call)
@@ -287,14 +317,14 @@ ISR(ADC_vect) {
// set the correct type of measurement for next time
#ifdef USE_THERMAL_REGULATION
#ifdef USE_LVP
- if (adc_step < 2) ADMUX = ADMUX_VCC;
+ if (adc_step < 2) ADMUX = ADMUX_VOLTAGE;
else ADMUX = ADMUX_THERM;
#else
ADMUX = ADMUX_THERM;
#endif
#else
#ifdef USE_LVP
- ADMUX = ADMUX_VCC;
+ ADMUX = ADMUX_VOLTAGE;
#endif
#endif
}
diff --git a/spaghetti-monster/fsm-adc.h b/spaghetti-monster/fsm-adc.h
index 1b16d01..6256e2c 100644
--- a/spaghetti-monster/fsm-adc.h
+++ b/spaghetti-monster/fsm-adc.h
@@ -32,8 +32,12 @@
#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
volatile uint8_t voltage;
volatile uint8_t adcint_enable; // kludge, because adc auto-retrigger won't turn off
void low_voltage();
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 1657e4a..86742f6 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -60,17 +60,32 @@ void gradual_tick();
PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,7,10,13,16,19,23,26,30,34,38,42,47,51,56,61,66,72,77,83,89,95,101,108,115,122,129,136,144,152,160,168,177,186,195,204,214,224,234,244,255 };
#define MAX_1x7135 33
#elif RAMP_LENGTH == 150
- // ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
- //PROGMEM const uint8_t pwm1_levels[] = { 4,4,4,5,5,5,6,6,7,7,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,30,32,34,37,40,43,46,49,52,56,59,63,67,71,76,80,85,90,95,100,106,112,118,124,130,137,144,151,158,166,173,181,190,198,207,216,225,235,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- //PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 };
- // ../../bin/level_calc.py 1 65 7135 1 0.8 150
- // ... mixed with this:
- // ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
- PROGMEM const uint8_t pwm1_levels[] = { 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 };
- #define MAX_1x7135 65
- #define HALFSPEED_LEVEL 14
- #define QUARTERSPEED_LEVEL 5
+ #ifdef FSM_BLF_GT_DRIVER
+ // First 60 values: level_calc.py 1 60 7135 4 5.0 255
+ // Remainder: all 255 (buck driver at 100% duty cycle)
+ PROGMEM const uint8_t pwm1_levels[] = { 4,5,6,6,7,8,9,11,12,13,15,16,18,19,21,23,25,27,30,32,34,37,40,43,46,49,52,55,59,63,66,70,75,79,83,88,93,98,103,108,114,119,125,131,137,144,150,157,164,171,179,186,194,202,210,219,228,236,246,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 };
+ // First 60 values: all 25 (buck driver at 10% power)
+ // Remainder: values 61-150 of level_calc.py 1 150 7135 1 3 3000
+ PROGMEM const uint8_t pwm2_levels[] = { 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 26,27,28,29,30,31,32,33,35,36,37,38,40,41,42,44,45,47,48,50,51,53,54,56,58,59,61,63,65,67,69,70,72,74,76,79,81,83,85,87,89,92,94,96,99,101,104,106,109,112,114,117,120,123,125,128,131,134,137,140,143,147,150,153,156,160,163,167,170,174,177,181,184,188,192,196,200,204,208,212,216,220,224,228,233,237,241,246,250,255 };
+ #define POWER_80PX 138 // 2.0 Amps out of maximum 2.5 Amps
+ #define MAX_1x7135 60 // where it switches from PWM to current control
+ #define HALFSPEED_LEVEL 17
+ #define QUARTERSPEED_LEVEL 6
+ #else
+ // ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
+ //PROGMEM const uint8_t pwm1_levels[] = { 4,4,4,5,5,5,6,6,7,7,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,30,32,34,37,40,43,46,49,52,56,59,63,67,71,76,80,85,90,95,100,106,112,118,124,130,137,144,151,158,166,173,181,190,198,207,216,225,235,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
+ //PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 };
+ // ../../bin/level_calc.py 1 65 7135 1 0.8 150
+ // ... mixed with this:
+ // ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
+ PROGMEM const uint8_t pwm1_levels[] = { 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
+ PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 };
+ #define MAX_1x7135 65
+ #define HALFSPEED_LEVEL 14
+ #define QUARTERSPEED_LEVEL 5
+ #endif
#endif
#elif PWM_CHANNELS == 3
#if RAMP_LENGTH == 50
diff --git a/tk-attiny.h b/tk-attiny.h
index ea784f5..d81468b 100644
--- a/tk-attiny.h
+++ b/tk-attiny.h
@@ -249,6 +249,51 @@
#endif // ifdef FSM_FW3A_DRIVER
+#ifdef FSM_BLF_GT_DRIVER
+#define DRIVER_TYPE_DEFINED
+/*
+ * ----
+ * Reset -|1 8|- VCC (unused)
+ * eswitch -|2 7|- Voltage divider
+ * AUX LED -|3 6|- Current control (buck level)
+ * GND -|4 5|- PWM (buck output on/off)
+ * ----
+ */
+
+#define PWM_CHANNELS 2
+
+#define AUXLED_PIN PB4 // pin 3
+
+#define SWITCH_PIN PB3 // pin 2
+#define SWITCH_PCINT PCINT3 // pin 2 pin change interrupt
+
+#define PWM1_PIN PB0 // pin 5, 1x7135 PWM
+#define PWM1_LVL OCR0A // OCR0A is the output compare register for PB0
+#define PWM2_PIN PB1 // pin 6, FET PWM
+#define PWM2_LVL OCR0B // OCR0B is the output compare register for PB1
+
+#define USE_VOLTAGE_DIVIDER // use a voltage divider on pin 7, not VCC
+#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
+#define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2
+// 1.1V reference, left-adjust, ADC1/PB2
+//#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL)
+// 1.1V reference, no left-adjust, ADC1/PB2
+#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | VOLTAGE_CHANNEL)
+#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
+#define ADC_PRSCL 0x06 // clk/64
+
+// Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line)
+#define ADC_44 184
+#define ADC_22 92
+
+#define TEMP_CHANNEL 0b00001111
+
+#define FAST 0xA3 // fast PWM both channels
+#define PHASE 0xA1 // phase-correct PWM both channels
+
+#endif // ifdef FSM_BLF_GT_DRIVER
+
+
#ifdef FSM_TKSABER_DRIVER
#define DRIVER_TYPE_DEFINED
/*