aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSelene ToyKeeper2023-07-18 14:44:40 -0600
committerSelene ToyKeeper2023-07-18 14:44:40 -0600
commit6c7c99b1be9a684e3a6ccc533f46979b39f7a529 (patch)
treebe94359c376f25939b5b71627e002b3d11e765bb
parentlowercase'd sofirn-lt1s-pro files (diff)
downloadanduril-6c7c99b1be9a684e3a6ccc533f46979b39f7a529.tar.gz
anduril-6c7c99b1be9a684e3a6ccc533f46979b39f7a529.tar.bz2
anduril-6c7c99b1be9a684e3a6ccc533f46979b39f7a529.zip
converted Emisar D4 and BLF Q8 to multi-channel,
and enabled previously-removed tactical mode on the Q8 since there seems to be enough space now (also lowercased their hwdef files)
-rw-r--r--hwdef-Emisar_D4.h48
-rw-r--r--hwdef-blf-q8.h (renamed from hwdef-BLF_Q8.h)2
-rw-r--r--hwdef-emisar-d4.c59
-rw-r--r--hwdef-emisar-d4.h104
-rw-r--r--hwdef-emisar-d4v2.c2
-rw-r--r--spaghetti-monster/anduril/cfg-blf-q8.h9
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4.h8
-rw-r--r--spaghetti-monster/chan-aux.h16
-rw-r--r--spaghetti-monster/fsm-channels.h10
-rw-r--r--spaghetti-monster/fsm-main.c88
10 files changed, 248 insertions, 98 deletions
diff --git a/hwdef-Emisar_D4.h b/hwdef-Emisar_D4.h
deleted file mode 100644
index fdb42a1..0000000
--- a/hwdef-Emisar_D4.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Emisar D4 driver layout
-// Copyright (C) 2017-2023 Selene ToyKeeper
-// SPDX-License-Identifier: GPL-3.0-or-later
-#pragma once
-
-/*
- * ----
- * Reset -|1 8|- VCC
- * eswitch -|2 7|-
- * AUX LED -|3 6|- PWM (FET)
- * GND -|4 5|- PWM (1x7135)
- * ----
- */
-
-#define LAYOUT_DEFINED
-
-#define PWM_CHANNELS 2
-
-//#define AUXLED_PIN PB4 // pin 3
-
-#ifndef SWITCH_PIN
-#define SWITCH_PIN PB3 // pin 2
-#define SWITCH_PCINT PCINT3 // pin 2 pin change interrupt
-#endif
-
-#ifndef PWM1_PIN
-#define PWM1_PIN PB0 // pin 5, 1x7135 PWM
-#define PWM1_LVL OCR0A // OCR0A is the output compare register for PB0
-#endif
-#ifndef PWM2_PIN
-#define PWM2_PIN PB1 // pin 6, FET PWM
-#define PWM2_LVL OCR0B // OCR0B is the output compare register for PB1
-#endif
-
-// (FIXME: remove? not used?)
-//#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
-//#define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2
-//#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
-#define ADC_PRSCL 0x07 // clk/128
-
-// average drop across diode on this hardware
-#ifndef VOLTAGE_FUDGE_FACTOR
-#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V
-#endif
-
-#define FAST 0xA3 // fast PWM both channels
-#define PHASE 0xA1 // phase-correct PWM both channels
-
diff --git a/hwdef-BLF_Q8.h b/hwdef-blf-q8.h
index da55bd4..cdf311d 100644
--- a/hwdef-BLF_Q8.h
+++ b/hwdef-blf-q8.h
@@ -16,5 +16,5 @@
#endif
// Q8 driver is the same as a D4, basically
-#include "hwdef-Emisar_D4.h"
+#include "hwdef-emisar-d4.h"
diff --git a/hwdef-emisar-d4.c b/hwdef-emisar-d4.c
new file mode 100644
index 0000000..6069530
--- /dev/null
+++ b/hwdef-emisar-d4.c
@@ -0,0 +1,59 @@
+// Emisar D4 PWM helper functions
+// Copyright (C) 2017-2023 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+//#ifdef AUXLED_PIN
+#if 0
+#include "chan-aux.c"
+#else
+#define AUX_CHANNELS
+#endif
+
+void set_level_main(uint8_t level);
+bool gradual_tick_main(uint8_t gt);
+
+
+Channel channels[] = {
+ { // main LEDs
+ .set_level = set_level_main,
+ .gradual_tick = gradual_tick_main
+ },
+ AUX_CHANNELS
+};
+
+
+// TODO: implement delta-sigma modulation for better low modes
+
+// single set of LEDs with 2 stacked power channels, DDFET+1 or DDFET+linear
+void set_level_main(uint8_t level) {
+ if (level == 0) {
+ CH1_PWM = 0;
+ CH2_PWM = 0;
+ return;
+ }
+
+ level --; // PWM array index = level - 1
+ PWM_DATATYPE ch1_pwm = PWM_GET(pwm1_levels, level);
+ PWM_DATATYPE ch2_pwm = PWM_GET(pwm2_levels, level);
+
+ CH1_PWM = ch1_pwm;
+ CH2_PWM = ch2_pwm;
+}
+
+bool gradual_tick_main(uint8_t gt) {
+ PWM_DATATYPE pwm1 = PWM_GET(pwm1_levels, gt);
+ PWM_DATATYPE pwm2 = PWM_GET(pwm2_levels, gt);
+
+ GRADUAL_ADJUST_STACKED(pwm1, CH1_PWM, PWM_TOP_INIT);
+ GRADUAL_ADJUST_SIMPLE (pwm2, CH2_PWM);
+
+ if ( (pwm1 == CH1_PWM)
+ && (pwm2 == CH2_PWM)
+ ) {
+ return true; // done
+ }
+ return false; // not done yet
+}
+
diff --git a/hwdef-emisar-d4.h b/hwdef-emisar-d4.h
new file mode 100644
index 0000000..b3a7500
--- /dev/null
+++ b/hwdef-emisar-d4.h
@@ -0,0 +1,104 @@
+// Emisar D4 driver layout
+// Copyright (C) 2017-2023 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+/*
+ * ----
+ * Reset -|1 8|- VCC
+ * eswitch -|2 7|-
+ * AUX LED -|3 6|- PWM (FET)
+ * GND -|4 5|- PWM (1x7135)
+ * ----
+ */
+
+#define ATTINY 85
+#include <avr/io.h>
+
+#define HWDEF_C_FILE hwdef-emisar-d4.c
+
+// allow using aux LEDs as extra channel modes (when they exist)
+//#ifdef AUXLED_PIN
+#if 0
+#include "chan-aux.h"
+#else
+#define NUM_AUX_CHANNEL_MODES 0
+#endif
+
+// channel modes
+// * 0. FET+7135 stacked
+// * 1. button LED (only on some derivative models, like BLF Q8)
+#define NUM_CHANNEL_MODES (1 + NUM_AUX_CHANNEL_MODES)
+enum CHANNEL_MODES {
+ CM_MAIN = 0,
+ CM_AUX,
+};
+
+#define DEFAULT_CHANNEL_MODE CM_MAIN
+
+// right-most bit first, modes are in fedcba9876543210 order
+#define CHANNEL_MODES_ENABLED 0b00000001
+
+
+#define PWM_CHANNELS 2 // old, remove this
+
+#define PWM_BITS 8 // attiny85 only supports up to 8 bits
+#define PWM_GET PWM_GET8
+#define PWM_DATATYPE uint8_t
+#define PWM_DATATYPE2 uint16_t
+#define PWM1_DATATYPE uint8_t // 1x7135 ramp
+#define PWM2_DATATYPE uint8_t // DD FET ramp
+
+#define PWM_TOP_INIT 255 // highest value used in top half of ramp
+
+//#define AUXLED_PIN PB4 // pin 3
+
+// 1x7135 channel
+#ifndef CH1_PIN
+#define CH1_PIN PB0 // pin 5, 1x7135 PWM
+#define CH1_PWM OCR0A // OCR0A is the output compare register for PB0
+#endif
+
+// DD FET channel
+#ifndef CH2_PIN
+#define CH2_PIN PB1 // pin 6, FET PWM
+#define CH2_PWM OCR0B // OCR0B is the output compare register for PB1
+#endif
+
+// e-switch
+#ifndef SWITCH_PIN
+#define SWITCH_PIN PB3 // pin 2
+#define SWITCH_PCINT PCINT3 // pin 2 pin change interrupt
+#endif
+
+// (FIXME: remove? not used?)
+//#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
+//#define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2
+//#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
+#define ADC_PRSCL 0x07 // clk/128
+
+// average drop across diode on this hardware
+#ifndef VOLTAGE_FUDGE_FACTOR
+#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V
+#endif
+
+#define FAST 0xA3 // fast PWM both channels
+#define PHASE 0xA1 // phase-correct PWM both channels
+
+
+inline void hwdef_setup() {
+ // configure PWM channels
+ DDRB = (1 << CH1_PIN)
+ | (1 << CH2_PIN);
+
+ TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
+ TCCR0A = PHASE;
+
+ // configure e-switch
+ PORTB = (1 << SWITCH_PIN); // e-switch is the only input
+ PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
+}
+
+
+#define LAYOUT_DEFINED
+
diff --git a/hwdef-emisar-d4v2.c b/hwdef-emisar-d4v2.c
index c4ae5dd..ada4eb8 100644
--- a/hwdef-emisar-d4v2.c
+++ b/hwdef-emisar-d4v2.c
@@ -11,7 +11,7 @@ bool gradual_tick_main(uint8_t gt);
Channel channels[] = {
- { // channel 1 only
+ { // main LEDs
.set_level = set_level_main,
.gradual_tick = gradual_tick_main
},
diff --git a/spaghetti-monster/anduril/cfg-blf-q8.h b/spaghetti-monster/anduril/cfg-blf-q8.h
index 166c8ca..7eda018 100644
--- a/spaghetti-monster/anduril/cfg-blf-q8.h
+++ b/spaghetti-monster/anduril/cfg-blf-q8.h
@@ -4,7 +4,9 @@
#pragma once
#define MODEL_NUMBER "0611"
-#include "hwdef-BLF_Q8.h"
+#include "hwdef-blf-q8.h"
+
+#define RAMP_SIZE 150
// the button lights up
#define USE_INDICATOR_LED
@@ -18,10 +20,11 @@
// ../../bin/level_calc.py 1 65 7135 1 0.8 150
// ... mixed with this:
// ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
-#define RAMP_LENGTH 150
#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
#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,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255
+
#define MAX_1x7135 65
+#define DEFAULT_LEVEL 65
#define HALFSPEED_LEVEL 14
#define QUARTERSPEED_LEVEL 5
@@ -57,4 +60,4 @@
//#undef USE_VOLTAGE_CORRECTION
//#undef USE_2C_STYLE_CONFIG
//#undef USE_TACTICAL_STROBE_MODE
-#undef USE_TACTICAL_MODE
+//#undef USE_TACTICAL_MODE
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4.h b/spaghetti-monster/anduril/cfg-emisar-d4.h
index 15a72ac..4ae5694 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4.h
@@ -4,16 +4,20 @@
#pragma once
#define MODEL_NUMBER "0111"
-#include "hwdef-Emisar_D4.h"
+#include "hwdef-emisar-d4.h"
#include "hank-cfg.h"
+// ATTINY: 85
+
+#define RAMP_SIZE 150
// ../../bin/level_calc.py 1 65 7135 1 0.8 150
// ... mixed with this:
// ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
-#define RAMP_LENGTH 150
#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
#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,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255
+
#define MAX_1x7135 65
+#define DEFAULT_LEVEL 65
#define HALFSPEED_LEVEL 14
#define QUARTERSPEED_LEVEL 6
diff --git a/spaghetti-monster/chan-aux.h b/spaghetti-monster/chan-aux.h
index c8264bd..ff599b8 100644
--- a/spaghetti-monster/chan-aux.h
+++ b/spaghetti-monster/chan-aux.h
@@ -3,6 +3,22 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
+#define NUM_AUX_CHANNEL_MODES 1
+
+// include / exclude field based on compile options
+#ifdef USE_CHANNEL_MODE_ARGS
+ #define AUX_HAS_ARGS , .has_args = 0
+#else
+ #define AUX_HAS_ARGS
+#endif
+
+#define AUX_CHANNELS \
+ { \
+ .set_level = set_level_aux, \
+ .gradual_tick = gradual_tick_null \
+ AUX_HAS_ARGS \
+ }
+
void set_level_aux(uint8_t level);
bool gradual_tick_null(uint8_t gt);
diff --git a/spaghetti-monster/fsm-channels.h b/spaghetti-monster/fsm-channels.h
index b86e9ba..ba2d3fa 100644
--- a/spaghetti-monster/fsm-channels.h
+++ b/spaghetti-monster/fsm-channels.h
@@ -14,11 +14,19 @@ typedef SetLevelFunc * SetLevelFuncPtr;
typedef bool GradualTickFunc(uint8_t gt);
typedef GradualTickFunc * GradualTickFuncPtr;
+// TODO: implement custom 3H handlers
+typedef void ChannelArgFunc();
+typedef ChannelArgFunc * ChannelArgFuncPtr;
+
typedef struct Channel {
SetLevelFuncPtr set_level;
#ifdef USE_SET_LEVEL_GRADUALLY
GradualTickFuncPtr gradual_tick;
#endif
+ #ifdef USE_CUSTOM_3H_HANDLERS
+ // TODO: implement custom 3H handlers
+ ChannelArgFuncPtr ramp_channel_arg;
+ #endif
#ifdef USE_CHANNEL_MODE_ARGS
bool has_args;
//uint8_t arg; // is in the config struct, not here
@@ -30,7 +38,7 @@ Channel channels[]; // values are defined in the hwdef-*.c
// TODO: size-optimize the case with only 1 channel mode?
// (the arrays and stuff shouldn't be needed)
-#ifdef USE_CFG
+#if defined(USE_CFG) && (NUM_CHANNEL_MODES > 1)
#define CH_MODE cfg.channel_mode
#else
// current multi-channel mode
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index 4116d3f..066188c 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -26,48 +26,52 @@ ISR(TIMER1_COMPA_vect) {
// FIXME: hw_setup() shouldn't be here ... move it entirely to hwdef files
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
static inline void hw_setup() {
- // configure PWM channels
- #if PWM_CHANNELS >= 1
- 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
- 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);
- //OCR1C = 255; // Set ceiling value to maximum
- TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 2<<CS10;
- GTCCR = (2<<COM1B0) | (1<<PWM1B);
- // set up an interrupt to control PWM4 pin
- TIMSK |= (1<<OCIE1A) | (1<<TOIE1);
- #endif
-
- // configure e-switch
- PORTB = (1 << SWITCH_PIN); // e-switch is the only input
- PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
+ #if !defined(USE_GENERIC_HWDEF_SETUP)
+ hwdef_setup();
+ #else
+ // configure PWM channels
+ #if PWM_CHANNELS >= 1
+ 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
+ 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);
+ //OCR1C = 255; // Set ceiling value to maximum
+ TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 2<<CS10;
+ GTCCR = (2<<COM1B0) | (1<<PWM1B);
+ // set up an interrupt to control PWM4 pin
+ TIMSK |= (1<<OCIE1A) | (1<<TOIE1);
+ #endif
+
+ // configure e-switch
+ PORTB = (1 << SWITCH_PIN); // e-switch is the only input
+ PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
+ #endif // ifdef USE_GENERIC_HWDEF_SETUP
}
#elif (ATTINY == 1634) || defined(AVRXMEGA3) // ATTINY816, 817, etc
static inline void hw_setup() {