aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--hwdef-sofirn-sp10-pro.c63
-rw-r--r--hwdef-sofirn-sp10-pro.h (renamed from hwdef-Sofirn_SP10-Pro.h)115
-rw-r--r--spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h62
3 files changed, 158 insertions, 82 deletions
diff --git a/hwdef-sofirn-sp10-pro.c b/hwdef-sofirn-sp10-pro.c
new file mode 100644
index 0000000..42844a7
--- /dev/null
+++ b/hwdef-sofirn-sp10-pro.c
@@ -0,0 +1,63 @@
+// Sofirn SP10 Pro PWM helper functions
+// Copyright (C) 2023 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+void set_level_zero();
+
+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
+ },
+};
+
+
+void set_level_zero() {
+ CH1_PWM = 0;
+ CH2_PWM = 0;
+ PWM_CNT = 0; // reset phase
+ BST_ENABLE_PORT &= ~(1 << BST_ENABLE_PIN); // boost off
+}
+
+// single set of LEDs with 2 stacked power channels
+void set_level_main(uint8_t level) {
+ PWM_DATATYPE ch1_pwm = PWM_GET(pwm1_levels, level);
+ PWM_DATATYPE ch2_pwm = PWM_GET(pwm2_levels, level);
+ // pulse frequency modulation, a.k.a. dynamic PWM
+ uint16_t top = PWM_GET16(pwm_tops, level);
+
+ BST_ENABLE_PORT |= (1 << BST_ENABLE_PIN); // boost on
+
+ CH1_PWM = ch1_pwm;
+ CH2_PWM = ch2_pwm;
+ PWM_TOP = top;
+
+ // force reset phase when turning on from zero
+ // (because otherwise the initial response is inconsistent)
+ if (! actual_level) PWM_CNT = 0;
+}
+
+bool gradual_tick_main(uint8_t gt) {
+ PWM_DATATYPE pwm1 = PWM_GET(pwm1_levels, gt);
+ PWM_DATATYPE pwm2 = PWM_GET(pwm2_levels, gt);
+
+ // ch1 sometimes makes huge leaps; don't make it gradual
+ // if either current or new level is in the leap zone, just leap
+ if ((CH1_PWM + pwm1) > 128) CH1_PWM = pwm1;
+ else GRADUAL_ADJUST_SIMPLE(pwm1, CH1_PWM);
+
+ 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-Sofirn_SP10-Pro.h b/hwdef-sofirn-sp10-pro.h
index 6bc26ea..5ed22c7 100644
--- a/hwdef-Sofirn_SP10-Pro.h
+++ b/hwdef-sofirn-sp10-pro.h
@@ -1,5 +1,5 @@
// Sofirn SP10 Pro pinout
-// Copyright (C) 2022-2023 (FIXME)
+// Copyright (C) 2022-2023 (original author TBD), Selene ToyKeeper
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
@@ -12,56 +12,64 @@
* PA1 : Boost Enable
*/
-
-#define LAYOUT_DEFINED
-
-#ifdef ATTINY
-#undef ATTINY
-#endif
#define ATTINY 1616
#include <avr/io.h>
-#ifndef SWITCH_PIN
-#define SWITCH_PIN 3
-#define SWITCH_PORT VPORTB.IN
-#define SWITCH_ISC_REG PORTB.PIN3CTRL
-#define SWITCH_VECT PORTB_PORT_vect
-#define SWITCH_INTFLG VPORTB.INTFLAGS
-#endif
+#define HWDEF_C_FILE hwdef-sofirn-sp10-pro.c
-#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
+// channel modes:
+// * 0. low+high PWM stacked
+#define NUM_CHANNEL_MODES 1
+enum CHANNEL_MODES {
+ CM_MAIN = 0,
+};
-// Small channel
-#ifndef PWM1_PIN
-#define PWM1_PIN PB5
-#define PWM1_LVL TCA0.SINGLE.CMP2BUF // PB5 is Alternate MUX for TCA Compare 2
-#endif
+#define DEFAULT_CHANNEL_MODE CM_MAIN
-// Big channel
-#ifndef PWM2_PIN
-#define PWM2_PIN PB0
-#define PWM2_LVL TCA0.SINGLE.CMP0BUF // PB0 is TCA Compare 0
-#endif
+// right-most bit first, modes are in fedcba9876543210 order
+#define CHANNEL_MODES_ENABLED 0b00000001
+
+
+#define PWM_CHANNELS 2 // old, remove this
+
+#define PWM_BITS 16 // data type needs 16 bits, not 8
+#define PWM_GET PWM_GET16
+#define PWM_DATATYPE uint16_t // is used for PWM_TOPS (which goes way over 255)
+#define PWM_DATATYPE2 uint32_t // only needs 32-bit if ramp values go over 255
+#define PWM1_DATATYPE uint16_t // low PWM ramp
+#define PWM2_DATATYPE uint16_t // high PWM ramp
// 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 PWM1_PHASE_RESET_OFF // force reset while shutting off
-#define PWM1_PHASE_RESET_ON // force reset while turning on
-//#define PWM1_PHASE_SYNC // manual sync while changing level
-
-#define LED_ENABLE_PIN PIN1_bp
-#define LED_ENABLE_PORT PORTA_OUT
-//#define LED_OFF_DELAY 4 // only needed when PWM1_PHASE_RESET_OFF not used
-
-#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened
-#define DUAL_VOLTAGE_FLOOR 21 // for AA/14500 boost drivers, don't indicate low voltage if below this level
+#define PWM_TOP TCA0.SINGLE.PERBUF // holds the TOP value for for variable-resolution PWM
+#define PWM_CNT TCA0.SINGLE.CNT // for resetting phase after each TOP adjustment
+#define PWM_TOP_INIT 255 // highest value used in top half of ramp (unused?)
+
+// Small channel
+#define CH1_PIN PB5
+#define CH1_PWM TCA0.SINGLE.CMP2BUF // PB5 is Alternate MUX for TCA Compare 2
+
+// Big channel
+#define CH2_PIN PB0
+#define CH2_PWM TCA0.SINGLE.CMP0BUF // PB0 is TCA Compare 0
+
+// boost enable
+#define BST_ENABLE_PIN PIN1_bp
+#define BST_ENABLE_PORT PORTA_OUT
+
+// e-switch
+#define SWITCH_PIN 3
+#define SWITCH_PORT VPORTB.IN
+#define SWITCH_ISC_REG PORTB.PIN3CTRL
+#define SWITCH_VECT PORTB_PORT_vect
+#define SWITCH_INTFLG VPORTB.INTFLAGS
+#define SWITCH_PCINT PCINT0
+#define PCINT_vect PCINT0_vect // ISR for PCINT[7:0]
+
+// Voltage divider battLVL
+#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is regulated
+#define DUAL_VOLTAGE_FLOOR 21 // for AA/14500 boost drivers, don't indicate low voltage if below this level
#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
+#define ADMUX_VOLTAGE_DIVIDER ADC_MUXPOS_AIN9_gc // which ADC channel to read
// Raw ADC readings at 4.4V and 2.2V
// calibrate the voltage readout here
@@ -77,15 +85,15 @@
-// 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
- _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );
+ _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
+ VPORTB.DIR = PIN0_bm // big PWM channel
+ | PIN5_bm; // small PWM channel
//VPORTC.DIR = ...;
// enable pullups on the input pins to reduce power
@@ -101,7 +109,8 @@ inline void hwdef_setup() {
//PORTB.PIN0CTRL = PORT_PULLUPEN_bm; // Big PWM channel
PORTB.PIN1CTRL = PORT_PULLUPEN_bm;
PORTB.PIN2CTRL = PORT_PULLUPEN_bm;
- PORTB.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc; // Switch
+ PORTB.PIN3CTRL = PORT_PULLUPEN_bm
+ | PORT_ISC_BOTHEDGES_gc; // e-switch
//PORTB.PIN4CTRL = PORT_PULLUPEN_bm; // Voltage divider
//PORTB.PIN5CTRL = PORT_PULLUPEN_bm; // Small PWM channel
@@ -119,9 +128,12 @@ inline void hwdef_setup() {
// 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_DSBOTTOM_gc;
- PWM1_TOP = PWM_TOP;
- TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
+ TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm
+ | TCA_SINGLE_CMP2EN_bm
+ | TCA_SINGLE_WGMODE_DSBOTTOM_gc;
+ PWM_TOP = PWM_TOP_INIT;
+ TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc
+ | TCA_SINGLE_ENABLE_bm;
}
@@ -140,3 +152,6 @@ FUSES = {
.BOOTEND = FUSE_BOOTEND_DEFAULT, // Boot Section End
};
+
+#define LAYOUT_DEFINED
+
diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h b/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h
index 3a02fc2..d9ac882 100644
--- a/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h
+++ b/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h
@@ -4,48 +4,37 @@
#pragma once
#define MODEL_NUMBER "0631"
-#include "hwdef-Sofirn_SP10-Pro.h"
+#include "hwdef-sofirn-sp10-pro.h"
// ATTINY: 1616
-// don't blink during the ramp or at the ceiling
-#ifdef BLINK_AT_RAMP_MIDDLE
-#undef BLINK_AT_RAMP_MIDDLE
-#endif
-#ifdef BLINK_AT_RAMP_CEIL
-#undef BLINK_AT_RAMP_CEIL
-#endif
-
-#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 RAMP_SIZE 150
+#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 DEFAULT_LEVEL 50
-#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 150
+#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
+#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
+#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)
@@ -78,6 +67,15 @@
// enable 2 click turbo (replaces USE_2C_MAX_TURBO)
#define DEFAULT_2C_STYLE 1
+// don't blink during the ramp or at the ceiling
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
+#endif
+#ifdef BLINK_AT_RAMP_CEIL
+#undef BLINK_AT_RAMP_CEIL
+#endif
+
+
// enable factory reset on 13H without loosening tailcap
#define USE_SOFT_FACTORY_RESET