aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/level_calc.py8
-rw-r--r--hwdef-BLF_Q8-T1616.h14
-rw-r--r--hwdef-Sofirn_SP10-Pro.h (renamed from hwdef-Sofirn_SP10S.h)62
-rw-r--r--hwdef-gchart-fet1-t1616.h17
-rw-r--r--hwdef-thefreeman-lin16dac.h109
-rw-r--r--spaghetti-monster/anduril/MODELS3
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern-t1616.h3
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern.h6
-rw-r--r--spaghetti-monster/anduril/cfg-blf-q8-t1616.h14
-rw-r--r--spaghetti-monster/anduril/cfg-blf-q8.h14
-rw-r--r--spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h73
-rw-r--r--spaghetti-monster/anduril/cfg-sofirn-sp10s.h28
-rw-r--r--spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h45
-rw-r--r--spaghetti-monster/anduril/factory-reset.c5
-rw-r--r--spaghetti-monster/anduril/ramp-mode.c10
-rw-r--r--spaghetti-monster/anduril/strobe-modes.c2
-rw-r--r--spaghetti-monster/anduril/strobe-modes.h7
-rw-r--r--spaghetti-monster/anduril/version.h5
-rw-r--r--spaghetti-monster/fsm-main.c13
-rw-r--r--spaghetti-monster/fsm-ramping.c8
-rw-r--r--tk-attiny.h16
21 files changed, 366 insertions, 96 deletions
diff --git a/bin/level_calc.py b/bin/level_calc.py
index 2998b44..60416db 100755
--- a/bin/level_calc.py
+++ b/bin/level_calc.py
@@ -65,10 +65,16 @@ def main(args):
dpwm_steps = int(parts[1])
dpwn_max = int(parts[2])
dpwn_min = int(parts[3])
+ dpwm_shape = 'linear'
+ if parts[4]:
+ dpwm_shape = float(parts[4])
max_pwms = [dpwn_min] * answers.num_levels
for i in range(dpwm_steps):
span = dpwn_max - dpwn_min
- x = dpwn_min + (span * (float(dpwm_steps - i) / dpwm_steps))
+ if dpwm_shape == 'linear':
+ x = dpwn_min + (span * (float(dpwm_steps - i) / dpwm_steps))
+ else: # variable curve
+ x = dpwn_min + (span * ((float(dpwm_steps - i) / dpwm_steps) ** dpwm_shape))
max_pwms[i] = int(x)
max_pwm = dpwn_min
diff --git a/hwdef-BLF_Q8-T1616.h b/hwdef-BLF_Q8-T1616.h
index 2a0e6ff..d6ad760 100644
--- a/hwdef-BLF_Q8-T1616.h
+++ b/hwdef-BLF_Q8-T1616.h
@@ -61,8 +61,8 @@ Driver pinout:
// ... so just hardcode it in each hwdef file instead
inline void hwdef_setup() {
- // set up the system clock to run at 5 MHz instead of the default 3.33 MHz
- _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm );
+ // set up the system clock to run at 10 MHz instead of the default 3.33 MHz
+ _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );
//VPORTA.DIR = ...;
VPORTB.DIR = PIN0_bm | PIN1_bm | PIN5_bm; // Outputs: Aux LED and PWMs
@@ -91,8 +91,14 @@ inline void hwdef_setup() {
PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
// set up the PWM
- // TODO: add references to MCU documentation
- TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc;
+ // https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny1614-16-17-DataSheet-DS40002204A.pdf
+ // PB0 is TCA0:WO0, use TCA_SINGLE_CMP0EN_bm
+ // PB1 is TCA0:WO1, use TCA_SINGLE_CMP1EN_bm
+ // PB2 is TCA0:WO2, use TCA_SINGLE_CMP2EN_bm
+ // For Fast (Single Slope) PWM use TCA_SINGLE_WGMODE_SINGLESLOPE_gc
+ // For Phase Correct (Dual Slope) PWM use TCA_SINGLE_WGMODE_DSBOTTOM_gc
+ // See the manual for other pins, clocks, configs, portmux, etc
+ TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_DSBOTTOM_gc;
TCA0.SINGLE.PER = 255;
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
}
diff --git a/hwdef-Sofirn_SP10S.h b/hwdef-Sofirn_SP10-Pro.h
index 0ee3332..bb10f2f 100644
--- a/hwdef-Sofirn_SP10S.h
+++ b/hwdef-Sofirn_SP10-Pro.h
@@ -1,28 +1,14 @@
-#ifndef HWDEF_SOFIRN_SP10S_H
-#define HWDEF_SOFIRN_SP10S_H
+#ifndef HWDEF_SOFIRN_SP10_H
+#define HWDEF_SOFIRN_SP10_H
-// TODO: rename to sofirn-sp10s-gchart?
-
-/* gChart's PIC12 to ATTINY1616 v1 adapter for the SP10S
-https://oshpark.com/shared_projects/b4IZEGSy
-
-PIC12 Pinout:
-1 - VDD
-2 - No Connect
-3 - Low Channel FET (series 4.7K Ohms)
-4 - Switch
-5 - High Channel FET (main PWM)
-6 - Voltage Divider (300K:100K Ohms)
-7 - Boost chip enable
-8 - GND
+/* Sofirn SP10 Pro pinout
ATTINY1616 Mapping:
-2 - PA5 : (no connect)
-3 - PB5 : TCA0 - WO2 Alternate MUX
-4 - PB3 : (switch)
-5 - PB0 : TCA0 - WO0
-6 - PB4 : ADC0 - AIN9
-7 - PA1 : (boost enable)
+PB5 : PWM small channel (TCA0 - WO2 Alternate MUX)
+PB3 : eSwitch
+PB0 : PWM big channel (TCA0 - WO0)
+PB4 : Voltage divider (ADC0 - AIN9)
+PA1 : Boost Enable
*/
@@ -44,25 +30,33 @@ ATTINY1616 Mapping:
#endif
#define PWM_CHANNELS 2
+#define PWM_BITS 16 // data type needs 16 bits, not 8
+#define PWM_TOP 255 // highest value used in top half of ramp
+#define USE_DYN_PWM // dynamic frequency and speed
// Small channel
#ifndef PWM1_PIN
#define PWM1_PIN PB5
-#define PWM1_LVL TCA0.SINGLE.CMP2 // PB5 is Alternate MUX for TCA Compare 2
+#define PWM1_LVL TCA0.SINGLE.CMP2BUF // PB5 is Alternate MUX for TCA Compare 2
#endif
// Big channel
#ifndef PWM2_PIN
#define PWM2_PIN PB0
-#define PWM2_LVL TCA0.SINGLE.CMP0 // PB0 is TCA Compare 0
+#define PWM2_LVL TCA0.SINGLE.CMP0BUF // PB0 is TCA Compare 0
#endif
+// PWM parameters of both channels are tied together because they share a counter
+#define PWM1_TOP TCA0.SINGLE.PERBUF // holds the TOP value for for variable-resolution PWM
+// not necessary when double-buffered "BUF" registers are used
+//#define PWM1_CNT TCA0.SINGLE.CNT // for resetting phase after each TOP adjustment
+
#define LED_ENABLE_PIN PIN1_bp
#define LED_ENABLE_PORT PORTA_OUT
#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened
#define DUAL_VOLTAGE_FLOOR 20 // for AA/14500 boost drivers, don't indicate low voltage if below this level
-#define DUAL_VOLTAGE_LOW_LOW 07 // the lower voltage range's danger zone 0.7 volts
+#define DUAL_VOLTAGE_LOW_LOW 7 // the lower voltage range's danger zone 0.7 volts (NiMH)
#define ADMUX_VOLTAGE_DIVIDER ADC_MUXPOS_AIN9_gc // which ADC channel to read
// Raw ADC readings at 4.4V and 2.2V
@@ -83,8 +77,8 @@ ATTINY1616 Mapping:
// ... so just hardcode it in each hwdef file instead
inline void hwdef_setup() {
- // set up the system clock to run at 5 MHz instead of the default 3.33 MHz
- _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm );
+ // set up the system clock to run at 10 MHz instead of the default 3.33 MHz
+ _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );
VPORTA.DIR = PIN1_bm; // Boost enable pin
VPORTB.DIR = PIN0_bm | PIN5_bm; // PWM pins as output
@@ -107,16 +101,22 @@ inline void hwdef_setup() {
//PORTB.PIN4CTRL = PORT_PULLUPEN_bm; // Voltage divider
//PORTB.PIN5CTRL = PORT_PULLUPEN_bm; // Small PWM channel
- //PORTC.PIN0CTRL = PORT_PULLUPEN_bm; connected to the ADC via airwire
+ PORTC.PIN0CTRL = PORT_PULLUPEN_bm;
PORTC.PIN1CTRL = PORT_PULLUPEN_bm;
PORTC.PIN2CTRL = PORT_PULLUPEN_bm;
PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
// set up the PWM
- // TODO: add references to MCU documentation
+ // https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny1614-16-17-DataSheet-DS40002204A.pdf
+ // PB0 is TCA0:WO0, use TCA_SINGLE_CMP0EN_bm
+ // PB1 is TCA0:WO1, use TCA_SINGLE_CMP1EN_bm
+ // PB2 is TCA0:WO2, use TCA_SINGLE_CMP2EN_bm
+ // For Fast (Single Slope) PWM use TCA_SINGLE_WGMODE_SINGLESLOPE_gc
+ // For Phase Correct (Dual Slope) PWM use TCA_SINGLE_WGMODE_DSBOTTOM_gc
+ // See the manual for other pins, clocks, configs, portmux, etc
PORTMUX.CTRLC = PORTMUX_TCA02_ALTERNATE_gc; // Use alternate pin for TCA0:WO2
- TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP2EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc;
- TCA0.SINGLE.PER = 255;
+ TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP2EN_bm | TCA_SINGLE_WGMODE_DSBOTTOM_gc;
+ PWM1_TOP = PWM_TOP;
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
}
diff --git a/hwdef-gchart-fet1-t1616.h b/hwdef-gchart-fet1-t1616.h
index 365ecd7..2435b99 100644
--- a/hwdef-gchart-fet1-t1616.h
+++ b/hwdef-gchart-fet1-t1616.h
@@ -60,8 +60,8 @@ Read voltage from VCC pin, has diode with ~0.4v drop
// ... so just hardcode it in each hwdef file instead
inline void hwdef_setup() {
- // set up the system clock to run at 5 MHz instead of the default 3.33 MHz
- _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm );
+ // set up the system clock to run at 10 MHz instead of the default 3.33 MHz
+ _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );
//VPORTA.DIR = 0b00000010;
VPORTB.DIR = PIN0_bm | PIN1_bm | PIN3_bm;
@@ -90,11 +90,14 @@ inline void hwdef_setup() {
PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
// set up the PWM
- // TODO: add references to MCU documentation
- // TODO: measure 5 MHz fast PWM vs 10 MHz phase-correct, to see if it
- // still has issues at 0/255 and 255/255 like older models did
- // (and maybe switch to phase-correct@10MHz)
- TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc;
+ // https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny1614-16-17-DataSheet-DS40002204A.pdf
+ // PB0 is TCA0:WO0, use TCA_SINGLE_CMP0EN_bm
+ // PB1 is TCA0:WO1, use TCA_SINGLE_CMP1EN_bm
+ // PB2 is TCA0:WO2, use TCA_SINGLE_CMP2EN_bm
+ // For Fast (Single Slope) PWM use TCA_SINGLE_WGMODE_SINGLESLOPE_gc
+ // For Phase Correct (Dual Slope) PWM use TCA_SINGLE_WGMODE_DSBOTTOM_gc
+ // See the manual for other pins, clocks, configs, portmux, etc
+ TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_DSBOTTOM_gc;
TCA0.SINGLE.PER = 255;
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
}
diff --git a/hwdef-thefreeman-lin16dac.h b/hwdef-thefreeman-lin16dac.h
new file mode 100644
index 0000000..0999c4c
--- /dev/null
+++ b/hwdef-thefreeman-lin16dac.h
@@ -0,0 +1,109 @@
+#ifndef HWDEF_THEFREEMAN_LIN18_H
+#define HWDEF_THEFREEMAN_LIN18_H
+
+/* thefreeman's Linear 16 driver using DAC control
+
+PA6 - DAC for LED brightness control
+PA7 - Op-amp enable pin
+PB5 - Aux LED
+PB4 - Switch pin, internal pullup
+PB3 - HDR control, set High to enable the high power channel, set Low for low power
+Read voltage from VCC pin, has PFET so no drop
+
+*/
+
+
+#define LAYOUT_DEFINED
+
+#ifdef ATTINY
+#undef ATTINY
+#endif
+#define ATTINY 1616
+#include <avr/io.h>
+
+#define PWM_CHANNELS 1
+#define USE_DYN_PWM // dynamic frequency and speed
+
+#ifndef SWITCH_PIN
+#define SWITCH_PIN PIN4_bp
+#define SWITCH_PORT VPORTB.IN
+#define SWITCH_ISC_REG PORTB.PIN2CTRL
+#define SWITCH_VECT PORTB_PORT_vect
+#define SWITCH_INTFLG VPORTB.INTFLAGS
+#endif
+
+
+#define PWM1_LVL DAC0.DATA // use this for DAC voltage output
+
+// PWM parameters of both channels are tied together because they share a counter
+#define PWM1_TOP VREF.CTRLA // holds the TOP value for for variable-resolution PWM
+
+// For enabling / disabling the HDR high-range channel
+#define LED_ENABLE_PIN PIN3_bp
+#define LED_ENABLE_PORT PORTB_OUT
+#define LED_ENABLE_PIN_LEVEL_MIN 35
+#define LED_ENABLE_PIN_LEVEL_MAX 150
+
+// For turning on and off the op-amp
+#define LED2_ENABLE_PIN PIN7_bp
+#define LED2_ENABLE_PORT PORTA_OUT
+
+
+// average drop across diode on this hardware
+#ifndef VOLTAGE_FUDGE_FACTOR
+#define VOLTAGE_FUDGE_FACTOR 0 // using a PFET so no appreciable drop
+#endif
+
+// lighted button
+#ifndef AUXLED_PIN
+#define AUXLED_PIN PIN5_bp
+#define AUXLED_PORT PORTB
+#endif
+
+
+// with so many pins, doing this all with #ifdefs gets awkward...
+// ... so just hardcode it in each hwdef file instead
+inline void hwdef_setup() {
+
+ // set up the system clock to run at 10 MHz instead of the default 3.33 MHz
+ // TODO: for this DAC controlled-light, try to decrease the clock speed or use the ULP
+ _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );
+
+ VPORTA.DIR = PIN6_bm | PIN7_bm;
+ VPORTB.DIR = PIN3_bm;
+ //VPORTC.DIR = 0b00000000;
+
+ // enable pullups on the input pins to reduce power
+ PORTA.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN3CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN4CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN5CTRL = PORT_PULLUPEN_bm;
+ //PORTA.PIN6CTRL = PORT_PULLUPEN_bm; // DAC ouput
+ //PORTA.PIN7CTRL = PORT_PULLUPEN_bm; // Op-amp enable pin
+
+ PORTB.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTB.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTB.PIN2CTRL = PORT_PULLUPEN_bm;
+ //PORTB.PIN3CTRL = PORT_PULLUPEN_bm; // HDR channel selection
+ PORTB.PIN4CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc; // switch
+ //PORTB.PIN5CTRL = PORT_PULLUPEN_bm; // Aux LED
+
+ PORTC.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
+
+ // set up the DAC
+ // https://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny1614-16-17-DataSheet-DS40002204A.pdf
+ // DAC ranges from 0V to (255 * Vref) / 256
+ VREF.CTRLA |= VREF_DAC0REFSEL_2V5_gc; // also VREF_DAC0REFSEL_0V55_gc and VREF_DAC0REFSEL_1V1_gc and VREF_DAC0REFSEL_2V5_gc
+ VREF.CTRLB |= VREF_DAC0REFEN_bm;
+ DAC0.CTRLA = DAC_ENABLE_bm | DAC_OUTEN_bm;
+ DAC0.DATA = 255; // set the output voltage
+
+}
+
+
+#endif
diff --git a/spaghetti-monster/anduril/MODELS b/spaghetti-monster/anduril/MODELS
index def1f4f..d2d509a 100644
--- a/spaghetti-monster/anduril/MODELS
+++ b/spaghetti-monster/anduril/MODELS
@@ -1,5 +1,6 @@
Model Name MCU
----- ---- ---
+0000 thefreeman-lin16dac attiny1616
0111 emisar-d4 attiny85
0112 emisar-d4-219c attiny85
0113 emisar-d4v2 attiny1634
@@ -56,7 +57,7 @@ Model Name MCU
0614 sofirn-sp36-t1616 attiny1616
0621 blf-lantern attiny85
0622 blf-lantern-t1616 attiny1616
-0631 sofirn-sp10s attiny1616
+0631 sofirn-sp10-pro attiny1616
1618 gchart-fet1-t1616 attiny1616
Duplicates:
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h b/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h
index 56c7275..06d5395 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h
@@ -50,6 +50,9 @@
#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
#define SIMPLE_UI_STEPS RAMP_DISCRETE_STEPS
+// Allow 3C in Simple UI for switching between smooth and stepped ramping
+#define USE_SIMPLE_UI_RAMPING_TOGGLE
+
#define USE_SOS_MODE
#define USE_SOS_MODE_IN_BLINKY_GROUP
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h
index edbdca4..56ed410 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern.h
@@ -50,11 +50,17 @@
#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 5
+// Allow 3C in Simple UI for switching between smooth and stepped ramping
+#define USE_SIMPLE_UI_RAMPING_TOGGLE
+
// LT1 can handle heat well, so don't limit simple mode
#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
#define SIMPLE_UI_STEPS RAMP_DISCRETE_STEPS
+// also at Sofirn's request, enable 2 click turbo (Anduril 1 style)
+#define DEFAULT_2C_STYLE 1
+
#define USE_SOS_MODE
#define USE_SOS_MODE_IN_BLINKY_GROUP
diff --git a/spaghetti-monster/anduril/cfg-blf-q8-t1616.h b/spaghetti-monster/anduril/cfg-blf-q8-t1616.h
index 002e8e3..30a3368 100644
--- a/spaghetti-monster/anduril/cfg-blf-q8-t1616.h
+++ b/spaghetti-monster/anduril/cfg-blf-q8-t1616.h
@@ -29,11 +29,21 @@
#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-// safe limit ~50% power
+// at Sofirn's request, use max (150) for the Simple UI ceiling
#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
-#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#define SIMPLE_UI_CEIL 150
#define SIMPLE_UI_STEPS 5
+// also at Sofirn's request, enable 2 click turbo (Anduril 1 style)
+#define DEFAULT_2C_STYLE 1
+
+// enable SOS in the blinkies group
+#define USE_SOS_MODE
+#define USE_SOS_MODE_IN_BLINKY_GROUP
+
+// Allow 3C in Simple UI for switching between smooth and stepped ramping
+#define USE_SIMPLE_UI_RAMPING_TOGGLE
+
// stop panicking at ~75% power or ~3000 lm, this light has high thermal mass
#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high
diff --git a/spaghetti-monster/anduril/cfg-blf-q8.h b/spaghetti-monster/anduril/cfg-blf-q8.h
index 851d930..f657adb 100644
--- a/spaghetti-monster/anduril/cfg-blf-q8.h
+++ b/spaghetti-monster/anduril/cfg-blf-q8.h
@@ -28,11 +28,21 @@
#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
-// safe limit ~50% power
+// at Sofirn's request, use max (150) for the Simple UI ceiling
#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
-#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#define SIMPLE_UI_CEIL 150
#define SIMPLE_UI_STEPS 5
+// also at Sofirn's request, enable 2 click turbo (Anduril 1 style)
+#define DEFAULT_2C_STYLE 1
+
+// enable SOS in the blinkies group
+#define USE_SOS_MODE
+#define USE_SOS_MODE_IN_BLINKY_GROUP
+
+// Allow 3C in Simple UI for switching between smooth and stepped ramping
+#define USE_SIMPLE_UI_RAMPING_TOGGLE
+
// stop panicking at ~75% power or ~3000 lm, this light has high thermal mass
#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high
diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h b/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h
new file mode 100644
index 0000000..bcfc80e
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h
@@ -0,0 +1,73 @@
+// Sofirn SP10 Pro config options for Anduril
+#define MODEL_NUMBER "0631"
+#include "hwdef-Sofirn_SP10-Pro.h"
+// ATTINY: 1616
+
+#undef BLINK_AT_RAMP_MIDDLE
+
+#define USE_DYNAMIC_UNDERCLOCKING
+
+// 1....15: level_calc.py 3.01 1 15 7135 1 0.1 2 --pwm dyn:15:64:64
+// 16..150: level_calc.py 5.01 1 135 7135 1 2 800 --pwm dyn:49:3072:255:3.0
+#define RAMP_LENGTH 150
+#define USE_DYN_PWM
+#define _PWM1_LEVELS_ 1,2,4,6,9,12,15,19,23,28,34,41,48,55,64
+#define _PWM1_TOPS_ 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
+#define _PWM2_LEVELS_ 1,1,2,2,3,3,4,4,5,5,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,10,10,10,11,11,12,13,13,14,15,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35,37,38,39,41,42,44,46,47,49,51,53,55,57,59,61,63,65,67,70,72,74,77,79,82,85,88,90,93,96,99,103,106,109,113,116,120,123,127,131,135,139,143,147,151,156,160,165,170,175,180,185,190,195,201,206,212,218,223,230,236,242,248,255
+#define _PWM2_TOPS_ 3072,1960,2372,1476,2097,1572,1920,1570,1777,1524,1646,1454,1286,1369,1234,1115,1011,918,837,894,823,759,702,650,603,560,522,487,455,425,398,374,351,330,310,292,275,259,280,265,251,266,253,240,252,240,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+#define PWM1_LEVELS _PWM1_LEVELS_,_PWM2_TOPS_
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,_PWM2_LEVELS_
+#define PWM_TOPS _PWM1_TOPS_,_PWM2_TOPS_
+
+#define MAX_1x7135 15
+#define HALFSPEED_LEVEL 15
+#define QUARTERSPEED_LEVEL 15
+#define DEFAULT_LEVEL 75
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 150
+// 1 25 50 [75] 100 125 150
+#define RAMP_DISCRETE_FLOOR 1
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+// at Sofirn's request, use max (150) for the Simple UI ceiling
+// 15 48 [82] 116 150
+#define SIMPLE_UI_FLOOR MAX_1x7135
+#define SIMPLE_UI_CEIL 150
+#define SIMPLE_UI_STEPS 5
+
+// turn on at ~6 lm by default (level 50/150, or ramp step 2/5 or 3/7)
+// (also sets lockout mode 2H to a useful level)
+#define DEFAULT_MANUAL_MEMORY 50
+// reset to default after being off for 10 minutes
+#define DEFAULT_MANUAL_MEMORY_TIMER 10
+
+// enable SOS in the blinkies group
+#define USE_SOS_MODE
+#define USE_SOS_MODE_IN_BLINKY_GROUP
+
+// Allow 3C in Simple UI for switching between smooth and stepped ramping
+#define USE_SIMPLE_UI_RAMPING_TOGGLE
+
+// and finally, set the default ramp style to Stepped
+#undef RAMP_STYLE
+#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped
+
+// stop panicking at ~30% power
+#define THERM_FASTER_LEVEL 105
+#define MIN_THERM_STEPDOWN 65 // must be > end of dynamic PWM range
+
+// slow down party strobe; this driver can't pulse for too short a time
+//#define PARTY_STROBE_ONTIME 8
+#define STROBE_OFF_LEVEL 1 // keep the regulator chip on between pulses
+
+// the default of 26 looks a bit flat, so increase it
+#define CANDLE_AMPLITUDE 50
+
+// enable 2 click turbo (replaces USE_2C_MAX_TURBO)
+#define DEFAULT_2C_STYLE 1
+
+// enable factory reset on 13H without loosening tailcap
+#define USE_SOFT_FACTORY_RESET
+
diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp10s.h b/spaghetti-monster/anduril/cfg-sofirn-sp10s.h
deleted file mode 100644
index 06720b6..0000000
--- a/spaghetti-monster/anduril/cfg-sofirn-sp10s.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// gChart's custom SP10S driver config options for Anduril
-#define MODEL_NUMBER "0631"
-#include "hwdef-Sofirn_SP10S.h"
-// ATTINY: 1616
-
-#undef BLINK_AT_RAMP_MIDDLE
-
-#define USE_DYNAMIC_UNDERCLOCKING
-
-#define RAMP_LENGTH 150
-#define PWM1_LEVELS 20,30,41,54,69,87,106,128,152,179,209,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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
-#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,10,10,11,12,12,13,14,14,15,16,17,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35,36,38,39,41,42,43,45,46,48,50,51,53,55,56,58,60,62,64,66,68,70,72,74,76,78,80,83,85,87,90,92,94,97,99,102,105,107,110,113,116,119,121,124,127,130,133,137,140,143,146,150,153,156,160,164,167,171,174,178,182,186,190,194,198,202,206,210,214,219,223,227,232,236,241,246,250,255
-
-#define MAX_1x7135 13
-#define HALFSPEED_LEVEL 14
-#define QUARTERSPEED_LEVEL 6
-
-#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 120
-#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
-#define RAMP_DISCRETE_STEPS 7
-
-// stop panicking at ~30% power
-#define THERM_FASTER_LEVEL 105
-
-// enable 2 click turbo
-#define DEFAULT_2C_STYLE 1
diff --git a/spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h b/spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h
new file mode 100644
index 0000000..64dcd8c
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h
@@ -0,0 +1,45 @@
+// thefreeman's Linear 16 driver using DAC control
+#define MODEL_NUMBER "0000" // TBD
+#include "hwdef-thefreeman-lin16dac.h"
+// ATTINY: 1616
+
+// the button lights up
+#define USE_INDICATOR_LED
+// the button is visible while main LEDs are on
+#define USE_INDICATOR_LED_WHILE_RAMPING
+// off mode: low (1)
+// lockout: blinking (3)
+#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1)
+
+#undef BLINK_AT_RAMP_MIDDLE
+
+// We're abusing the Dynamic PWM functionality to set the VREF instead of PWM TOP.
+// We don't want the Gradual functionality to mess with the PWM_TOP value.
+#ifdef USE_SET_LEVEL_GRADUALLY
+#undef USE_SET_LEVEL_GRADUALLY
+#endif
+
+// level_calc.py ninth 2 150 7135 1 0.03 6.4 7135 1 6.3 1600
+#define RAMP_LENGTH 150
+#define USE_DYN_PWM
+
+// PWM1: DAC Data, PWM Tops: VREF selector
+#define PWM1_LEVELS 25,25,33,41,41,50,58,66,75,83,92,108,117,133,150,167,192,209,234,58,64,71,80,90,99,110,121,134,149,163,180,198,218,241,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,5,5,6,6,7,7,8,8,9,10,11,11,12,13,14,15,16,18,19,20,22,23,25,26,28,30,32,34,36,39,41,44,47,50,53,56,59,63,67,71,75,79,84,89,94,100,105,112,118,124,131,139,146,154,163,172,181,191,201,212,223,234,246,57,60,63,66,69,73,76,80,84,88,93,97,102,107,112,117,123,129,135,141,147,154,161,169,176,184,193,201,210,220,229,239,250,255
+#define PWM_TOPS 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18
+
+#define MAX_1x7135 34
+#define HALFSPEED_LEVEL 14
+#define QUARTERSPEED_LEVEL 6
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 120
+// 10, 28, 46, [65], 83, 101, 120
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+// stop panicking at ~30% power
+#define THERM_FASTER_LEVEL 123
+
+// enable 2 click turbo
+#define DEFAULT_2C_STYLE 1
diff --git a/spaghetti-monster/anduril/factory-reset.c b/spaghetti-monster/anduril/factory-reset.c
index 5377b09..ecb4cc2 100644
--- a/spaghetti-monster/anduril/factory-reset.c
+++ b/spaghetti-monster/anduril/factory-reset.c
@@ -43,7 +43,10 @@ void factory_reset() {
}
// explode, if button pressed long enough
if (reset) {
- #if defined(USE_THERMAL_REGULATION) && defined(USE_THERM_AUTOCALIBRATE)
+ // AVR 1-Series has factory calibrated thermal sensor, always remove the offset on reset
+ #if defined(USE_THERMAL_REGULATION) && defined(AVRXMEGA3)
+ thermal_config_save(1,temperature - therm_cal_offset); // this will cancel out the offset
+ #elif defined(USE_THERMAL_REGULATION) && defined(USE_THERM_AUTOCALIBRATE)
// auto-calibrate temperature... assume current temperature is 21 C
thermal_config_save(1, 21);
#endif
diff --git a/spaghetti-monster/anduril/ramp-mode.c b/spaghetti-monster/anduril/ramp-mode.c
index 8c49b11..6e8ba88 100644
--- a/spaghetti-monster/anduril/ramp-mode.c
+++ b/spaghetti-monster/anduril/ramp-mode.c
@@ -370,7 +370,8 @@ uint8_t steady_state(Event event, uint16_t arg) {
#endif // ifdef USE_THERMAL_REGULATION
////////// Every action below here is blocked in the simple UI //////////
- #ifdef USE_SIMPLE_UI
+ // That is, unless we specifically want to enable 3C for smooth/stepped selection in Simple UI
+ #if defined(USE_SIMPLE_UI) && !defined(USE_SIMPLE_UI_RAMPING_TOGGLE)
if (simple_ui_active) {
return EVENT_NOT_HANDLED;
}
@@ -392,6 +393,13 @@ uint8_t steady_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
+ // If we allowed 3C in Simple UI, now block further actions
+ #if defined(USE_SIMPLE_UI) && defined(USE_SIMPLE_UI_RAMPING_TOGGLE)
+ if (simple_ui_active) {
+ return EVENT_NOT_HANDLED;
+ }
+ #endif
+
#ifndef USE_TINT_RAMPING
// 3H: momentary turbo (on lights with no tint ramping)
else if (event == EV_click3_hold) {
diff --git a/spaghetti-monster/anduril/strobe-modes.c b/spaghetti-monster/anduril/strobe-modes.c
index d5f12c0..e8d1dbb 100644
--- a/spaghetti-monster/anduril/strobe-modes.c
+++ b/spaghetti-monster/anduril/strobe-modes.c
@@ -215,7 +215,7 @@ inline void party_tactical_strobe_mode_iter(uint8_t st) {
nice_delay_ms(del >> 1);
}
#endif
- set_level(0);
+ set_level(STROBE_OFF_LEVEL);
nice_delay_ms(del); // no return check necessary on final delay
}
#endif
diff --git a/spaghetti-monster/anduril/strobe-modes.h b/spaghetti-monster/anduril/strobe-modes.h
index e2389ba..c6cfb53 100644
--- a/spaghetti-monster/anduril/strobe-modes.h
+++ b/spaghetti-monster/anduril/strobe-modes.h
@@ -62,6 +62,13 @@ strobe_mode_te strobe_type = 0;
#endif
#endif
+// some drivers need to keep the regulator chip on between pulses,
+// so set this to 1 to keep the light on at moon mode between pulses,
+// and thus keep the regulator powered up for the next flash
+#ifndef STROBE_OFF_LEVEL
+#define STROBE_OFF_LEVEL 0
+#endif
+
// party and tactical strobes
#ifdef USE_STROBE_STATE
uint8_t strobe_state(Event event, uint16_t arg);
diff --git a/spaghetti-monster/anduril/version.h b/spaghetti-monster/anduril/version.h
index 8cf3c90..6bd781e 100644
--- a/spaghetti-monster/anduril/version.h
+++ b/spaghetti-monster/anduril/version.h
@@ -1,4 +1 @@
-// this file is replaced automatically by the build script
-// set your own date here if you're not using the build script
-// otherwise, default to first human contact with the moon
-#define VERSION_NUMBER "19690720"
+#define VERSION_NUMBER "20220409"
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index 7031009..30b8a67 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -46,19 +46,30 @@ static inline void hw_setup() {
DDRB |= (1 << PWM1_PIN);
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
TCCR0A = PHASE;
+ #if (PWM1_PIN == PB4) // Second PWM counter is ... weird
+ TCCR1 = _BV (CS10);
+ GTCCR = _BV (COM1B1) | _BV (PWM1B);
+ OCR1C = 255; // Set ceiling value to maximum
+ #endif
#endif
// tint ramping needs second channel enabled,
// despite PWM_CHANNELS being only 1
#if (PWM_CHANNELS >= 2) || defined(USE_TINT_RAMPING)
DDRB |= (1 << PWM2_PIN);
+ #if (PWM2_PIN == PB4) // Second PWM counter is ... weird
+ TCCR1 = _BV (CS10);
+ GTCCR = _BV (COM1B1) | _BV (PWM1B);
+ OCR1C = 255; // Set ceiling value to maximum
+ #endif
#endif
#if PWM_CHANNELS >= 3
- // Second PWM counter is ... weird
DDRB |= (1 << PWM3_PIN);
+ #if (PWM3_PIN == PB4) // Second PWM counter is ... weird
TCCR1 = _BV (CS10);
GTCCR = _BV (COM1B1) | _BV (PWM1B);
OCR1C = 255; // Set ceiling value to maximum
#endif
+ #endif
#if PWM_CHANNELS >= 4
// 4th PWM channel is ... not actually supported in hardware :(
DDRB |= (1 << PWM4_PIN);
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index 49e173f..abbfbde 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -146,8 +146,8 @@ void set_level(uint8_t level) {
// the timing of changing the TOP value (section 12.8.4))
// (but don't wait when turning on from zero, because
// it'll reset the phase below anyway)
- // to be safe, allow at least 64 cycles to update TOP
- while(prev_level && (PWM1_CNT > (top - 64))) {}
+ // to be safe, allow at least 32 cycles to update TOP
+ while(prev_level && (PWM1_CNT > (top - 32))) {}
#endif
// pulse frequency modulation, a.k.a. dynamic PWM
PWM1_TOP = top;
@@ -155,13 +155,13 @@ void set_level(uint8_t level) {
// repeat for other channels if necessary
#ifdef PMW2_TOP
#ifdef PWM2_CNT
- while(prev_level && (PWM2_CNT > (top - 64))) {}
+ while(prev_level && (PWM2_CNT > (top - 32))) {}
#endif
PWM2_TOP = top;
#endif
#ifdef PMW3_TOP
#ifdef PWM3_CNT
- while(prev_level && (PWM3_CNT > (top - 64))) {}
+ while(prev_level && (PWM3_CNT > (top - 32))) {}
#endif
PWM3_TOP = top;
#endif
diff --git a/tk-attiny.h b/tk-attiny.h
index ae70afd..110507b 100644
--- a/tk-attiny.h
+++ b/tk-attiny.h
@@ -73,7 +73,7 @@
//#define VOLTAGE_ADC_DIDR DIDR0 // set this in hwdef
#elif (ATTINY == 412) || (ATTINY == 416) || (ATTINY == 417) || (ATTINY == 816) || (ATTINY == 817) || (ATTINY == 1616) || (ATTINY == 1617) || (ATTINY == 3216) || (ATTINY == 3217)
#define AVRXMEGA3
- #define F_CPU 5000000UL
+ #define F_CPU 10000000UL
#define BOGOMIPS (F_CPU/4000)
#define EEPSIZE 128
#define DELAY_ZERO_TIME 1020
@@ -155,14 +155,14 @@
}
typedef enum
{
- // Actual clock is 20 MHz, but assume that 5 MHz is the top speed and work from there
+ // Actual clock is 20 MHz, but assume that 10 MHz is the top speed and work from there
// TODO: measure PWM speed and power use at 1.25/2.5/5/10 MHz, to determine which speeds are optimal
- clock_div_1 = (CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm), // 5 MHz
- clock_div_2 = (CLKCTRL_PDIV_8X_gc | CLKCTRL_PEN_bm), // 2.5 MHz
- clock_div_4 = (CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm), // 1.25 MHz
- clock_div_8 = (CLKCTRL_PDIV_32X_gc | CLKCTRL_PEN_bm), // 625 kHz
- clock_div_16 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz, max without changing to the 32 kHz ULP
- clock_div_32 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz
+ clock_div_1 = (CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm), // 10 MHz
+ clock_div_2 = (CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm), // 5 MHz
+ clock_div_4 = (CLKCTRL_PDIV_8X_gc | CLKCTRL_PEN_bm), // 2.5 MHz
+ clock_div_8 = (CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm), // 1.25 MHz
+ clock_div_16 = (CLKCTRL_PDIV_32X_gc | CLKCTRL_PEN_bm), // 625 kHz
+ clock_div_32 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz, max without changing to the 32 kHz ULP
clock_div_64 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz
clock_div_128 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz
clock_div_256 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm) // 312 kHz