From a6c7fea89b03e0bbeb97e2c1a89bbd59214ff02f Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Wed, 14 Oct 2020 21:17:15 -0600 Subject: copied KR4 hwdef to K9.3 --- hwdef-Noctigon_K9.3.h | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 hwdef-Noctigon_K9.3.h diff --git a/hwdef-Noctigon_K9.3.h b/hwdef-Noctigon_K9.3.h new file mode 100644 index 0000000..feb49e6 --- /dev/null +++ b/hwdef-Noctigon_K9.3.h @@ -0,0 +1,150 @@ +#ifndef HWDEF_NOCTIGON_KR4_H +#define HWDEF_NOCTIGON_KR4_H + +/* Noctigon KR4 / D4V2.5 driver layout (attiny1634) + * + * Pin / Name / Function + * 1 PA6 FET PWM (direct drive) (PWM1B) + * 2 PA5 R: red aux LED (PWM0B) + * 3 PA4 G: green aux LED + * 4 PA3 B: blue aux LED + * 5 PA2 button LED (D4V2.5 only) + * 6 PA1 (none) + * 7 PA0 (none) + * 8 GND GND + * 9 VCC VCC + * 10 PC5 (none) + * 11 PC4 (none) + * 12 PC3 RESET + * 13 PC2 (none) + * 14 PC1 SCK + * 15 PC0 (none) PWM0A + * 16 PB3 main LED PWM (linear) (PWM1A) + * 17 PB2 MISO / e-switch (PCINT10) + * 18 PB1 MOSI / battery voltage (ADC6) + * 19 PB0 Opamp power + * 20 PA7 (none) + * ADC12 thermal sensor + * + * Main LED power uses one pin to turn the Opamp on/off, + * and one pin to control Opamp power level. + * Main brightness control uses the power level pin, with 4 kHz 10-bit PWM. + * The on/off pin is only used to turn the main LED on and off, + * not to change brightness. + * Some models also have a direct-drive FET for turbo. + */ + +#ifdef ATTINY +#undef ATTINY +#endif +#define ATTINY 1634 +#include + +#define PWM_CHANNELS 2 +#define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz +#define PWM_TOP 1023 + +#define SWITCH_PIN PB2 // pin 17 +#define SWITCH_PCINT PCINT10 // pin 17 pin change interrupt +#define SWITCH_PCIE PCIE1 // PCIE1 is for PCINT[11:8] +#define SWITCH_PCMSK PCMSK1 // PCMSK1 is for PCINT[11:8] +#define SWITCH_PORT PINB // PINA or PINB or PINC +#define PCINT_vect PCINT1_vect // ISR for PCINT[11:8] + +// the button tends to short out the voltage divider, +// so ignore voltage while the button is being held +//#define NO_LVP_WHILE_BUTTON_PRESSED + + +#define PWM1_PIN PB3 // pin 16, Opamp reference +#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 + +#define PWM2_PIN PA6 // pin 1, DD FET PWM +#define PWM2_LVL OCR1B // OCR1B is the output compare register for PA6 + +#define LED_ENABLE_PIN PB0 // pin 19, Opamp power +#define LED_ENABLE_PORT PORTB // control port for PB0 + + +#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened +#define VOLTAGE_PIN PB1 // Pin 18 / PB1 / ADC6 +// pin to ADC mappings are in DS table 19-4 +#define VOLTAGE_ADC ADC6D // digital input disable pin for PB1 +// DIDR0/DIDR1 mappings are in DS section 19.13.5, 19.13.6 +#define VOLTAGE_ADC_DIDR DIDR1 // DIDR channel for ADC6D +// DS tables 19-3, 19-4 +// Bit 7 6 5 4 3 2 1 0 +// REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0 +// MUX[3:0] = 0, 1, 1, 0 for ADC6 / PB1 +// divided by ... +// REFS[1:0] = 1, 0 for internal 1.1V reference +// other bits reserved +#define ADMUX_VOLTAGE_DIVIDER 0b10000110 +#define ADC_PRSCL 0x07 // clk/128 + +// Raw ADC readings at 4.4V and 2.2V +// calibrate the voltage readout here +// estimated / calculated values are: +// (voltage - D1) * (R2/(R2+R1) * 1024 / 1.1) +// D1, R1, R2 = 0, 330, 100 +#ifndef ADC_44 +//#define ADC_44 981 // raw value at 4.40V +#define ADC_44 967 // manually tweaked so 4.16V will blink out 4.2 +#endif +#ifndef ADC_22 +//#define ADC_22 489 // raw value at 2.20V +#define ADC_22 482 // manually tweaked so 4.16V will blink out 4.2 +#endif + +// this light has aux LEDs under the optic +#define AUXLED_R_PIN PA5 // pin 2 +#define AUXLED_G_PIN PA4 // pin 3 +#define AUXLED_B_PIN PA3 // pin 4 +#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC +#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC +#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC + +#define BUTTON_LED_PIN PA2 // pin 5 +#define BUTTON_LED_PORT PORTA // for all "PA" pins +#define BUTTON_LED_DDR DDRA // for all "PA" pins +#define BUTTON_LED_PUE PUEA // for all "PA" pins + +// with so many pins, doing this all with #ifdefs gets awkward... +// ... so just hardcode it in each hwdef file instead +inline void hwdef_setup() { + // enable output ports + // Opamp level and Opamp on/off + DDRB = (1 << PWM1_PIN) + | (1 << LED_ENABLE_PIN); + // DD FET PWM, aux R/G/B, button LED + DDRA = (1 << PWM2_PIN) + | (1 << AUXLED_R_PIN) + | (1 << AUXLED_G_PIN) + | (1 << AUXLED_B_PIN) + | (1 << BUTTON_LED_PIN) + ; + + // configure PWM + // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter + // pre-scale for timer: N = 1 + // WGM1[3:0]: 0,0,1,1: PWM, Phase Correct, 10-bit (DS table 12-5) + // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6) + // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4) + // COM1B[1:0]: 1,0: PWM OC1B in the normal direction (DS table 12-4) + TCCR1A = (1< -#define PWM_CHANNELS 2 +#define PWM_CHANNELS 2 // 3 actually, but only 2 for main LEDs #define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz #define PWM_TOP 1023 -#define SWITCH_PIN PB2 // pin 17 -#define SWITCH_PCINT PCINT10 // pin 17 pin change interrupt -#define SWITCH_PCIE PCIE1 // PCIE1 is for PCINT[11:8] -#define SWITCH_PCMSK PCMSK1 // PCMSK1 is for PCINT[11:8] -#define SWITCH_PORT PINB // PINA or PINB or PINC -#define PCINT_vect PCINT1_vect // ISR for PCINT[11:8] - -// the button tends to short out the voltage divider, -// so ignore voltage while the button is being held -//#define NO_LVP_WHILE_BUTTON_PRESSED - +#define SWITCH_PIN PA7 // pin 20 +#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt +#define SWITCH_PCIE PCIE0 // PCIE1 is for PCINT[7:0] +#define SWITCH_PCMSK PCMSK0 // PCMSK1 is for PCINT[7:0] +#define SWITCH_PORT PINA // PINA or PINB or PINC +#define PCINT_vect PCINT0_vect // ISR for PCINT[7:0] #define PWM1_PIN PB3 // pin 16, Opamp reference #define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 -#define PWM2_PIN PA6 // pin 1, DD FET PWM -#define PWM2_LVL OCR1B // OCR1B is the output compare register for PA6 +#define PWM2_PIN PC0 // pin 15, DD FET PWM +#define PWM2_LVL OCR0A // OCR0A is the output compare register for PC0 + +#define PWM3_PIN PA6 // pin 1, 2nd LED Opamp reference +#define PWM3_LVL OCR1B // OCR1B is the output compare register for PA6 -#define LED_ENABLE_PIN PB0 // pin 19, Opamp power -#define LED_ENABLE_PORT PORTB // control port for PB0 +#define LED_ENABLE_PIN PA0 // pin 7, Opamp power +#define LED_ENABLE_PORT PORTA // control port for PA0 + +#define LED2_ENABLE_PIN PA1 // pin 6, Opamp power +#define LED2_ENABLE_PORT PORTA // control port for PA1 #define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened @@ -113,20 +114,21 @@ // ... so just hardcode it in each hwdef file instead inline void hwdef_setup() { // enable output ports - // Opamp level and Opamp on/off - DDRB = (1 << PWM1_PIN) - | (1 << LED_ENABLE_PIN); - // DD FET PWM, aux R/G/B, button LED - DDRA = (1 << PWM2_PIN) + DDRC = (1 << PWM2_PIN); + DDRB = (1 << PWM1_PIN); + DDRA = (1 << PWM3_PIN) | (1 << AUXLED_R_PIN) | (1 << AUXLED_G_PIN) | (1 << AUXLED_B_PIN) | (1 << BUTTON_LED_PIN) + | (1 << LED_ENABLE_PIN); + | (1 << LED2_ENABLE_PIN); ; // configure PWM // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter // pre-scale for timer: N = 1 + // Linear opamp PWM for both main and 2nd LEDs (10-bit) // WGM1[3:0]: 0,0,1,1: PWM, Phase Correct, 10-bit (DS table 12-5) // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6) // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4) @@ -139,9 +141,21 @@ inline void hwdef_setup() { | (0< -#define PWM_CHANNELS 2 // 3 actually, but only 2 for main LEDs +#define PWM_CHANNELS 3 // 2 for main LEDs, 1 for 2nd LEDs #define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz #define PWM_TOP 1023 diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index f632229..549fe46 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -85,12 +85,16 @@ // (include this one last) #include "load-save-config-fsm.h" - /********* bring in FSM / SpaghettiMonster *********/ #define USE_IDLE_MODE // reduce power use while awake and no tasks are pending #include "spaghetti-monster.h" +/********* does this build target have special code to include? *********/ +#ifdef OVERRIDES_FILE +#include incfile(OVERRIDES_FILE) +#endif + /********* Include all the regular app headers *********/ diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c new file mode 100644 index 0000000..5e3350a --- /dev/null +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c @@ -0,0 +1,36 @@ +#ifdef USE_SET_LEVEL_GRADUALLY +//#undef USE_SET_LEVEL_GRADUALLY +#endif + +inline void set_level_override(uint8_t level) { + if (level == 0) { + PWM1_LVL = 0; + PWM2_LVL = 0; + PWM3_LVL = 0; + // disable the power channel + LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); + LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); + } else { + level --; + + if (! tint) { // main LEDs + // enable this power channel + LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); + // disable other power channel + LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); + // set levels + PWM1_LVL = PWM_GET(pwm1_levels, level); + PWM2_LVL = (uint8_t)(PWM_GET(pwm2_levels, level) >> 2); + PWM3_LVL = 0; + } else { // 2nd LEDs + // disable other power channel + LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); + // enable this power channel + LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN); + // set levels + PWM1_LVL = 0; + PWM2_LVL = 0; + PWM3_LVL = PWM_GET(pwm3_levels, level); + } + } +} diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h index 8276ec8..123dabe 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -2,6 +2,11 @@ #define MODEL_NUMBER "0261" #include "hwdef-Noctigon_K9.3.h" // ATTINY: 1634 +// this model requires some special code +#define OVERRIDES_FILE cfg-noctigon-k9.3.c +#define OVERRIDE_SET_LEVEL +inline void set_level_override(uint8_t level); + // this light has three aux LED channels: R, G, B #define USE_AUX_RGB_LEDS @@ -20,6 +25,10 @@ #define TICK_DURING_STANDBY #define STANDBY_TICK_SPEED 3 // every 0.128 s +// has two channels of independent LEDs +#define USE_TINT_RAMPING +// ... but it doesn't make sense to ramp between; only toggle +#define TINT_RAMP_TOGGLE_ONLY // main LEDs // max regulated: ~1750 lm @@ -35,6 +44,7 @@ #define PWM3_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023 #define DEFAULT_LEVEL 46 #define MAX_1x7135 120 +#define MAX_Nx7135 MAX_1x7135 #define HALFSPEED_LEVEL 10 #define QUARTERSPEED_LEVEL 2 @@ -64,3 +74,4 @@ // for consistency with KR4 (not otherwise necessary though) #define USE_SOFT_FACTORY_RESET + diff --git a/spaghetti-monster/anduril/tint-ramping.c b/spaghetti-monster/anduril/tint-ramping.c index 0196bc7..0b077ef 100644 --- a/spaghetti-monster/anduril/tint-ramping.c +++ b/spaghetti-monster/anduril/tint-ramping.c @@ -22,6 +22,32 @@ #include "tint-ramping.h" +#ifdef TINT_RAMP_TOGGLE_ONLY + +uint8_t tint_ramping_state(Event event, uint16_t arg) { + // click, click, hold: change the tint + if (event == EV_click3_hold) { + // toggle once on first frame; ignore other frames + if (! arg) { + tint = !tint; + set_level(actual_level); + blink_once(); + } + return EVENT_HANDLED; + } + + // click, click, hold, release: save config + else if (event == EV_click3_hold_release) { + // remember tint after battery change + save_config(); + return EVENT_HANDLED; + } + + return EVENT_NOT_HANDLED; +} + +#else // no TINT_RAMP_TOGGLE_ONLY + uint8_t tint_ramping_state(Event event, uint16_t arg) { static int8_t tint_ramp_direction = 1; static uint8_t prev_tint = 0; @@ -82,6 +108,8 @@ uint8_t tint_ramping_state(Event event, uint16_t arg) { return EVENT_NOT_HANDLED; } +#endif // ifdef TINT_RAMP_TOGGLE_ONLY + #endif diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 5ea4a47..16bffe3 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -54,6 +54,10 @@ void set_level(uint8_t level) { #endif #endif + #ifdef OVERRIDE_SET_LEVEL + set_level_override(level); + #else + //TCCR0A = PHASE; if (level == 0) { #if PWM_CHANNELS >= 1 @@ -139,6 +143,7 @@ void set_level(uint8_t level) { #endif // ifdef USE_TINT_RAMPING } + #endif // ifdef OVERRIDE_SET_LEVEL #ifdef USE_DYNAMIC_UNDERCLOCKING auto_clock_speed(); #endif -- cgit v1.2.3 From 2789e3893de182fe1bf66aa9da1ba5f93d78098b Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Thu, 15 Oct 2020 17:07:09 -0600 Subject: made gradual_tick() work on K9.3 (via override), fixed strobe config, made blink_once() more configurable (and more reliable on K9.3) --- spaghetti-monster/anduril/cfg-noctigon-k9.3.c | 79 +++++++++++++++++++++++++-- spaghetti-monster/anduril/cfg-noctigon-k9.3.h | 8 ++- spaghetti-monster/anduril/misc.c | 5 +- spaghetti-monster/fsm-ramping.c | 4 +- 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c index 5e3350a..5cb027a 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c @@ -1,13 +1,28 @@ -#ifdef USE_SET_LEVEL_GRADUALLY +/* + * K9.3 has unusual power channels, so it must override some of FSM's code. + * There are two sets of LEDs: + * 1. Main LEDs: (9 x white LEDs) + * PWM1 (10-bit, linear) + * PWM2 (8-bit, FET, only used on some K9.3 models) + * 2. 2nd LEDs: (3 x white or color LEDs) + * PWM3 (10-bit, linear) + * + * The two sets are not used at the same time... just one or the other, + * depending on the "tint" variable. (0 = main LEDs, other value = 2nd LEDs) + */ +// if the gradual adjustment mechanism doesn't work, disable it here: +//#ifdef USE_SET_LEVEL_GRADUALLY //#undef USE_SET_LEVEL_GRADUALLY -#endif +//#endif +// this is inserted into fsm-ramping.c :: set_level() +// (it overrides part of the function, but not all of it) inline void set_level_override(uint8_t level) { - if (level == 0) { + if (level == 0) { // off PWM1_LVL = 0; PWM2_LVL = 0; PWM3_LVL = 0; - // disable the power channel + // disable both power channels LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); } else { @@ -20,7 +35,9 @@ inline void set_level_override(uint8_t level) { LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); // set levels PWM1_LVL = PWM_GET(pwm1_levels, level); - PWM2_LVL = (uint8_t)(PWM_GET(pwm2_levels, level) >> 2); + #ifndef K93_NO_FET + PWM2_LVL = (uint8_t)(PWM_GET(pwm2_levels, level) >> 2); // 8 bits + #endif PWM3_LVL = 0; } else { // 2nd LEDs // disable other power channel @@ -34,3 +51,55 @@ inline void set_level_override(uint8_t level) { } } } + +// override fsm-ramping.c :: gradual_tick() +// (because the power handling on this light is weird) +// call this every frame or every few frames to change brightness very smoothly +void gradual_tick() { + // go by only one ramp level at a time instead of directly to the target + uint8_t gt = gradual_target; + if (gt < actual_level) gt = actual_level - 1; + else if (gt > actual_level) gt = actual_level + 1; + + gt --; // convert 1-based number to 0-based + + PWM_DATATYPE target; + + if (! tint) { // main LED channel + target = PWM_GET(pwm1_levels, gt); + if ((gt < actual_level) // special case for FET-only turbo + && (PWM1_LVL == 0) // (bypass adjustment period for first step) + && (target == PWM_TOP)) PWM1_LVL = PWM_TOP; + else if (PWM1_LVL < target) PWM1_LVL ++; + else if (PWM1_LVL > target) PWM1_LVL --; + + #ifndef K93_NO_FET // skip this on E21A model + target = PWM_GET(pwm2_levels, gt) >> 2; // 8 bits, not 10 + if (PWM2_LVL < target) PWM2_LVL ++; + else if (PWM2_LVL > target) PWM2_LVL --; + #endif + + // did we go far enough to hit the next defined ramp level? + // if so, update the main ramp level tracking var + if ((PWM1_LVL == PWM_GET(pwm1_levels, gt)) + #ifndef K93_NO_FET + && (PWM2_LVL == (PWM_GET(pwm2_levels, gt) >> 2)) + #endif + ) + { actual_level = gt + 1; } + } else { // 2nd LED channel + target = PWM_GET(pwm3_levels, gt); + if (PWM3_LVL < target) PWM3_LVL ++; + else if (PWM3_LVL > target) PWM3_LVL --; + + // did we go far enough to hit the next defined ramp level? + // if so, update the main ramp level tracking var + if ( PWM3_LVL == PWM_GET(pwm3_levels, gt) ) + { actual_level = gt + 1; } + } + + #ifdef USE_DYNAMIC_UNDERCLOCKING + auto_clock_speed(); + #endif +} + diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h index 123dabe..e4524ec 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -5,6 +5,7 @@ // this model requires some special code #define OVERRIDES_FILE cfg-noctigon-k9.3.c #define OVERRIDE_SET_LEVEL +#define OVERRIDE_GRADUAL_TICK inline void set_level_override(uint8_t level); @@ -66,9 +67,12 @@ inline void set_level_override(uint8_t level); //#define THERM_NEXT_WARNING_THRESHOLD 16 // accumulate less error before adjusting //#define THERM_RESPONSE_MAGNITUDE 128 // bigger adjustments +// use the brightest setting for strobe +#define STROBE_BRIGHTNESS MAX_LEVEL // slow down party strobe; this driver can't pulse for 1ms or less -// (only needed on no-FET build) -//#define PARTY_STROBE_ONTIME 2 +#define PARTY_STROBE_ONTIME 2 + +#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow #define THERM_CAL_OFFSET 5 diff --git a/spaghetti-monster/anduril/misc.c b/spaghetti-monster/anduril/misc.c index 63b8f48..523bbf0 100644 --- a/spaghetti-monster/anduril/misc.c +++ b/spaghetti-monster/anduril/misc.c @@ -38,13 +38,16 @@ void blink_confirm(uint8_t num) { // make a short, visible pulse // (either brighter or darker, depending on current brightness) +#ifndef BLINK_ONCE_TIME +#define BLINK_ONCE_TIME 10 +#endif void blink_once() { uint8_t brightness = actual_level; uint8_t bump = brightness + (MAX_LEVEL/6); if (bump > MAX_LEVEL) bump = 0; set_level(bump); - delay_4ms(10/4); + delay_4ms(BLINK_ONCE_TIME/4); set_level(brightness); } diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 16bffe3..f092204 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -154,6 +154,7 @@ inline void set_level_gradually(uint8_t lvl) { gradual_target = lvl; } +#ifndef OVERRIDE_GRADUAL_TICK // call this every frame or every few frames to change brightness very smoothly void gradual_tick() { // go by only one ramp level at a time instead of directly to the target @@ -209,7 +210,8 @@ void gradual_tick() { auto_clock_speed(); #endif } -#endif +#endif // ifdef OVERRIDE_GRADUAL_TICK +#endif // ifdef USE_SET_LEVEL_GRADUALLY #endif // ifdef USE_RAMPING #endif -- cgit v1.2.3 From 5f2d12b7b225bdf291cea76cf1ba5fc8796150b6 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Fri, 16 Oct 2020 22:10:35 -0600 Subject: start tint at 0 instead of 128 on lights with toggle instead of ramp --- spaghetti-monster/fsm-ramping.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index f177db9..8fd89c7 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -27,7 +27,11 @@ uint8_t actual_level = 0; #ifdef USE_TINT_RAMPING +#ifdef TINT_RAMP_TOGGLE_ONLY +uint8_t tint = 0; +#else uint8_t tint = 128; +#endif #define USE_TRIANGLE_WAVE #endif -- cgit v1.2.3 From f8c6e2edd5fbfc9e54d6072e1ab53dd887968ad5 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Fri, 16 Oct 2020 22:11:25 -0600 Subject: added K9.3-noFET build target (for models with E21A as main LEDs) --- .../anduril/cfg-noctigon-k9.3-nofet.h | 54 ++++++++++++++++++++++ spaghetti-monster/anduril/cfg-noctigon-k9.3.h | 2 +- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h new file mode 100644 index 0000000..e91ebc4 --- /dev/null +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h @@ -0,0 +1,54 @@ +// Noctigon K9.3 (noFET) config options for Anduril +#include "cfg-noctigon-k9.3.h" +#undef MODEL_NUMBER +#define MODEL_NUMBER "0262" +// ATTINY: 1634 + +// don't use the highest power channel +#define K93_NO_FET + +// main LEDs +#undef PWM1_LEVELS +#undef PWM2_LEVELS +#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023 +// FET channel: unused, all zeroes +#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +// 2nd LEDs +#undef PWM3_LEVELS +#define PWM3_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023 +#undef DEFAULT_LEVEL +#define DEFAULT_LEVEL 50 +#undef MAX_1x7135 +#undef MAX_Nx7135 +#define MAX_1x7135 150 +#define MAX_Nx7135 MAX_1x7135 + +#undef RAMP_SMOOTH_FLOOR +#undef RAMP_SMOOTH_CEIL +#undef RAMP_DISCRETE_FLOOR +#undef RAMP_DISCRETE_CEIL +#undef RAMP_DISCRETE_STEPS + +#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable(?) +#define RAMP_SMOOTH_CEIL 130 +// 10, 30, [50], 70, 90, 110, 130 (plus [150] on turbo) +#define RAMP_DISCRETE_FLOOR 10 +#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL +#define RAMP_DISCRETE_STEPS 7 + +// safe limit same as full UI +#undef SIMPLE_UI_FLOOR +#undef SIMPLE_UI_CEIL +#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR +#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL + + +// make candle mode wobble more +#define CANDLE_AMPLITUDE 32 + +// stop panicking at ~90% power or ~1600 lm +#undef THERM_FASTER_LEVEL +#define THERM_FASTER_LEVEL 143 +#undef MIN_THERM_STEPDOWN +#define MIN_THERM_STEPDOWN DEFAULT_LEVEL + diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h index e4524ec..76ddb05 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -49,7 +49,7 @@ inline void set_level_override(uint8_t level); #define HALFSPEED_LEVEL 10 #define QUARTERSPEED_LEVEL 2 -#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable +#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable (?) #define RAMP_SMOOTH_CEIL 120 // 10, 28, [46], 65, 83, 101, [120] #define RAMP_DISCRETE_FLOOR 10 -- cgit v1.2.3 From fdecdb45ba4b14d3980e8863360d724d4ce98880 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Fri, 16 Oct 2020 22:12:35 -0600 Subject: swapped PWM1 and PWM3 channels on K9.3, because I may have had them backward --- hwdef-Noctigon_K9.3.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hwdef-Noctigon_K9.3.h b/hwdef-Noctigon_K9.3.h index 6032b4c..ae9f907 100644 --- a/hwdef-Noctigon_K9.3.h +++ b/hwdef-Noctigon_K9.3.h @@ -4,7 +4,7 @@ /* Noctigon K9.3 driver layout (attiny1634) * * Pin / Name / Function - * 1 PA6 2nd LED PWM (linear) (PWM1B) + * 1 PA6 main LED PWM (linear) (PWM1B) * 2 PA5 R: red aux LED (PWM0B) * 3 PA4 G: green aux LED * 4 PA3 B: blue aux LED @@ -19,7 +19,7 @@ * 13 PC2 (none) * 14 PC1 SCK * 15 PC0 main LED PWM (FET) (PWM0A) - * 16 PB3 main LED PWM (linear) (PWM1A) + * 16 PB3 2nd LED PWM (linear) (PWM1A) * 17 PB2 MISO * 18 PB1 MOSI / battery voltage (ADC6) * 19 PB0 (none) @@ -51,20 +51,20 @@ #define SWITCH_PORT PINA // PINA or PINB or PINC #define PCINT_vect PCINT0_vect // ISR for PCINT[7:0] -#define PWM1_PIN PB3 // pin 16, Opamp reference -#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 +#define PWM1_PIN PA6 // pin 1, 2nd LED Opamp reference +#define PWM1_LVL OCR1B // OCR1B is the output compare register for PA6 #define PWM2_PIN PC0 // pin 15, DD FET PWM #define PWM2_LVL OCR0A // OCR0A is the output compare register for PC0 -#define PWM3_PIN PA6 // pin 1, 2nd LED Opamp reference -#define PWM3_LVL OCR1B // OCR1B is the output compare register for PA6 +#define PWM3_PIN PB3 // pin 16, Opamp reference +#define PWM3_LVL OCR1A // OCR1A is the output compare register for PB3 -#define LED_ENABLE_PIN PA0 // pin 7, Opamp power -#define LED_ENABLE_PORT PORTA // control port for PA0 +#define LED_ENABLE_PIN PA1 // pin 6, Opamp power +#define LED_ENABLE_PORT PORTA // control port for PA1 -#define LED2_ENABLE_PIN PA1 // pin 6, Opamp power -#define LED2_ENABLE_PORT PORTA // control port for PA1 +#define LED2_ENABLE_PIN PA0 // pin 7, Opamp power +#define LED2_ENABLE_PORT PORTA // control port for PA0 #define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened @@ -115,8 +115,8 @@ inline void hwdef_setup() { // enable output ports DDRC = (1 << PWM2_PIN); - DDRB = (1 << PWM1_PIN); - DDRA = (1 << PWM3_PIN) + DDRB = (1 << PWM3_PIN); + DDRA = (1 << PWM1_PIN) | (1 << AUXLED_R_PIN) | (1 << AUXLED_G_PIN) | (1 << AUXLED_B_PIN) -- cgit v1.2.3 From b482e423e3615e0908edf838b522789f640d0698 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sun, 18 Oct 2020 21:56:43 -0600 Subject: nope, the pins weren't swapped... the wires on the prototype were reversed (code was correct before, but the test hardware was wrong) --- hwdef-Noctigon_K9.3.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hwdef-Noctigon_K9.3.h b/hwdef-Noctigon_K9.3.h index ae9f907..6032b4c 100644 --- a/hwdef-Noctigon_K9.3.h +++ b/hwdef-Noctigon_K9.3.h @@ -4,7 +4,7 @@ /* Noctigon K9.3 driver layout (attiny1634) * * Pin / Name / Function - * 1 PA6 main LED PWM (linear) (PWM1B) + * 1 PA6 2nd LED PWM (linear) (PWM1B) * 2 PA5 R: red aux LED (PWM0B) * 3 PA4 G: green aux LED * 4 PA3 B: blue aux LED @@ -19,7 +19,7 @@ * 13 PC2 (none) * 14 PC1 SCK * 15 PC0 main LED PWM (FET) (PWM0A) - * 16 PB3 2nd LED PWM (linear) (PWM1A) + * 16 PB3 main LED PWM (linear) (PWM1A) * 17 PB2 MISO * 18 PB1 MOSI / battery voltage (ADC6) * 19 PB0 (none) @@ -51,20 +51,20 @@ #define SWITCH_PORT PINA // PINA or PINB or PINC #define PCINT_vect PCINT0_vect // ISR for PCINT[7:0] -#define PWM1_PIN PA6 // pin 1, 2nd LED Opamp reference -#define PWM1_LVL OCR1B // OCR1B is the output compare register for PA6 +#define PWM1_PIN PB3 // pin 16, Opamp reference +#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 #define PWM2_PIN PC0 // pin 15, DD FET PWM #define PWM2_LVL OCR0A // OCR0A is the output compare register for PC0 -#define PWM3_PIN PB3 // pin 16, Opamp reference -#define PWM3_LVL OCR1A // OCR1A is the output compare register for PB3 +#define PWM3_PIN PA6 // pin 1, 2nd LED Opamp reference +#define PWM3_LVL OCR1B // OCR1B is the output compare register for PA6 -#define LED_ENABLE_PIN PA1 // pin 6, Opamp power -#define LED_ENABLE_PORT PORTA // control port for PA1 +#define LED_ENABLE_PIN PA0 // pin 7, Opamp power +#define LED_ENABLE_PORT PORTA // control port for PA0 -#define LED2_ENABLE_PIN PA0 // pin 7, Opamp power -#define LED2_ENABLE_PORT PORTA // control port for PA0 +#define LED2_ENABLE_PIN PA1 // pin 6, Opamp power +#define LED2_ENABLE_PORT PORTA // control port for PA1 #define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened @@ -115,8 +115,8 @@ inline void hwdef_setup() { // enable output ports DDRC = (1 << PWM2_PIN); - DDRB = (1 << PWM3_PIN); - DDRA = (1 << PWM1_PIN) + DDRB = (1 << PWM1_PIN); + DDRA = (1 << PWM3_PIN) | (1 << AUXLED_R_PIN) | (1 << AUXLED_G_PIN) | (1 << AUXLED_B_PIN) -- cgit v1.2.3 From fa6155c367f14ebe229ce8c6248429a45b3605d2 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Thu, 22 Oct 2020 02:56:00 -0600 Subject: enabled memory timer and resetting tint after timeout on K9.3 (unsure if I'll keep it this way though, or if the old way was better) --- spaghetti-monster/anduril/cfg-noctigon-k9.3.h | 4 ++++ spaghetti-monster/anduril/off-mode.c | 3 +++ spaghetti-monster/anduril/ramp-mode.h | 10 ++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h index 76ddb05..fd162fe 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -49,6 +49,10 @@ inline void set_level_override(uint8_t level); #define HALFSPEED_LEVEL 10 #define QUARTERSPEED_LEVEL 2 +#define USE_MANUAL_MEMORY_TIMER_FOR_TINT +#define DEFAULT_MANUAL_MEMORY DEFAULT_LEVEL +#define DEFAULT_MANUAL_MEMORY_TIMER 10 + #define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable (?) #define RAMP_SMOOTH_CEIL 120 // 10, 28, [46], 65, 83, 101, [120] diff --git a/spaghetti-monster/anduril/off-mode.c b/spaghetti-monster/anduril/off-mode.c index 5ebaa1d..34d9e6d 100644 --- a/spaghetti-monster/anduril/off-mode.c +++ b/spaghetti-monster/anduril/off-mode.c @@ -133,6 +133,9 @@ uint8_t off_state(Event event, uint16_t arg) { && (off_time >= (manual_memory_timer * SLEEP_TICKS_PER_MINUTE)) #endif ) { + #if defined(USE_MANUAL_MEMORY_TIMER_FOR_TINT) && defined(USE_TINT_RAMPING) && defined(TINT_RAMP_TOGGLE_ONLY) + tint = 0; + #endif set_level(nearest_level(manual_memory)); } else #endif diff --git a/spaghetti-monster/anduril/ramp-mode.h b/spaghetti-monster/anduril/ramp-mode.h index b772407..ed806bd 100644 --- a/spaghetti-monster/anduril/ramp-mode.h +++ b/spaghetti-monster/anduril/ramp-mode.h @@ -148,9 +148,15 @@ void set_level_and_therm_target(uint8_t level); // brightness control uint8_t memorized_level = DEFAULT_LEVEL; #ifdef USE_MANUAL_MEMORY -uint8_t manual_memory = 0; +#ifndef DEFAULT_MANUAL_MEMORY +#define DEFAULT_MANUAL_MEMORY 0 +#endif +uint8_t manual_memory = DEFAULT_MANUAL_MEMORY; #ifdef USE_MANUAL_MEMORY_TIMER -uint8_t manual_memory_timer = 0; +#ifndef DEFAULT_MANUAL_MEMORY_TIMER +#define DEFAULT_MANUAL_MEMORY_TIMER 0 +#endif +uint8_t manual_memory_timer = DEFAULT_MANUAL_MEMORY_TIMER; #endif #endif #ifdef USE_SIMPLE_UI -- cgit v1.2.3 From 9f693768d56541f4be2ce5bc211e34be14e6ea79 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sun, 13 Dec 2020 23:55:09 -0700 Subject: noctigon k9.3: default to aux RGB rainbow mode, and automatic memory --- spaghetti-monster/anduril/cfg-noctigon-k9.3.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h index fd162fe..4d3d3d9 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -11,6 +11,7 @@ inline void set_level_override(uint8_t level); // this light has three aux LED channels: R, G, B #define USE_AUX_RGB_LEDS +#define RGB_LED_OFF_DEFAULT 0x18 // low, rainbow // the aux LEDs are front-facing, so turn them off while main LEDs are on //#define USE_AUX_RGB_LEDS_WHILE_ON // it also has an independent LED in the button @@ -50,8 +51,8 @@ inline void set_level_override(uint8_t level); #define QUARTERSPEED_LEVEL 2 #define USE_MANUAL_MEMORY_TIMER_FOR_TINT -#define DEFAULT_MANUAL_MEMORY DEFAULT_LEVEL -#define DEFAULT_MANUAL_MEMORY_TIMER 10 +//#define DEFAULT_MANUAL_MEMORY DEFAULT_LEVEL +//#define DEFAULT_MANUAL_MEMORY_TIMER 10 #define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable (?) #define RAMP_SMOOTH_CEIL 120 -- cgit v1.2.3 From 0132c47f0ca6725593f9b43a4984df29f7a90cc4 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 25 Jan 2021 00:02:10 -0700 Subject: bug pseudo-fix: K9.3 lockout mode failed in blinking single-color mode because of what appears to be compiler jank or a race condition or some other highly unusual issue (fixed by eating up extra clock cycles in the affected code path) --- spaghetti-monster/anduril/aux-leds.c | 9 +++++++++ spaghetti-monster/anduril/cfg-noctigon-k9.3.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/spaghetti-monster/anduril/aux-leds.c b/spaghetti-monster/anduril/aux-leds.c index c819bd7..73d163e 100644 --- a/spaghetti-monster/anduril/aux-leds.c +++ b/spaghetti-monster/anduril/aux-leds.c @@ -99,6 +99,15 @@ void rgb_led_update(uint8_t mode, uint8_t arg) { const uint8_t *colors = rgb_led_colors; uint8_t actual_color = 0; if (color < 7) { // normal color + #ifdef USE_K93_LOCKOUT_KLUDGE + // FIXME: jank alert: this is dumb + // this clause does nothing; it just uses up clock cycles + // because without it, the K9.3's lockout mode fails and returns + // to "off" after ~5 to 15 seconds when configured for a blinking + // single color, even though there is no code path from lockout to + // "off", and it doesn't act like a reboot either (no boot-up blink) + rainbow = (rainbow + 1 + pseudo_rand() % 5) % 6; + #endif actual_color = pgm_read_byte(colors + color); } else if (color == 7) { // disco diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h index 4d3d3d9..e61ea13 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -84,3 +84,6 @@ inline void set_level_override(uint8_t level); // for consistency with KR4 (not otherwise necessary though) #define USE_SOFT_FACTORY_RESET + +// work around bizarre bug: lockout mode fails when set to solid color blinking +#define USE_K93_LOCKOUT_KLUDGE -- cgit v1.2.3 From e3886bb569ccb89fb1198bab08c5f7d5fc0e2583 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 25 Jan 2021 00:03:02 -0700 Subject: removed redundant function call, added missing comment --- spaghetti-monster/anduril/cfg-noctigon-k9.3.c | 3 --- spaghetti-monster/fsm-ramping.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c index 5cb027a..5ce5c5a 100644 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c @@ -98,8 +98,5 @@ void gradual_tick() { { actual_level = gt + 1; } } - #ifdef USE_DYNAMIC_UNDERCLOCKING - auto_clock_speed(); - #endif } diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 0768f8d..d6a14ef 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -135,7 +135,7 @@ void set_level(uint8_t level) { PWM1_LVL = warm_PWM; PWM2_LVL = cool_PWM; - #else + #else // ifdef USE_TINT_RAMPING #if PWM_CHANNELS >= 1 PWM1_LVL = PWM_GET(pwm1_levels, level); -- cgit v1.2.3 From b02057175d97ca45723f64492049b89873cf0709 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 25 Jan 2021 01:09:35 -0700 Subject: updated MODELS file with missing K9.3-nofet build target --- spaghetti-monster/anduril/MODELS | 1 + 1 file changed, 1 insertion(+) diff --git a/spaghetti-monster/anduril/MODELS b/spaghetti-monster/anduril/MODELS index 173620a..52fa200 100644 --- a/spaghetti-monster/anduril/MODELS +++ b/spaghetti-monster/anduril/MODELS @@ -19,6 +19,7 @@ Model numbers: 0252 noctigon-k1-sbt90 0253 noctigon-k1-12v 0261 noctigon-k9.3 +0262 noctigon-k9.3-nofet 0311 fw3a 0312 fw3a-219 0313 fw3a-nofet -- cgit v1.2.3