diff options
| author | Selene ToyKeeper | 2022-04-09 02:46:15 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2022-04-09 02:46:15 -0600 |
| commit | 3a0f2bb9fa050bf9a0e8dd38cf32d316e1b18f56 (patch) | |
| tree | 0bfc60c84622b2b23593a76e6dae2d94ad8078be | |
| parent | k9.3 tint-toggle build is broken, generate a better fail error (until it's fi... (diff) | |
| parent | merged anduril2 branch for upstream changes (diff) | |
| download | anduril-3a0f2bb9fa050bf9a0e8dd38cf32d316e1b18f56.tar.gz anduril-3a0f2bb9fa050bf9a0e8dd38cf32d316e1b18f56.tar.bz2 anduril-3a0f2bb9fa050bf9a0e8dd38cf32d316e1b18f56.zip | |
merged sofirn sp10-pro branch (should have done it months ago, but forgot)
Diffstat (limited to '')
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 |
