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/MODELS2
-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/fsm-main.c13
-rw-r--r--spaghetti-monster/fsm-ramping.c8
-rw-r--r--tk-attiny.h16
20 files changed, 364 insertions, 92 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 79a6a4a..3256b43 100644
--- a/spaghetti-monster/anduril/MODELS
+++ b/spaghetti-monster/anduril/MODELS
@@ -59,4 +59,4 @@ Model Name MCU
Duplicates:
-Missing:
+Missing: \ No newline at end of file
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/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
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.