aboutsummaryrefslogtreecommitdiff
path: root/hw/lumintop
diff options
context:
space:
mode:
Diffstat (limited to 'hw/lumintop')
-rw-r--r--hw/lumintop/blf-gt/anduril.h7
-rw-r--r--hw/lumintop/blf-gt/hwdef.h12
-rw-r--r--hw/lumintop/fw3a/hwdef.h4
-rw-r--r--hw/lumintop/fw3x-lume1/README.md26
-rw-r--r--hw/lumintop/fw3x-lume1/anduril.h60
-rw-r--r--hw/lumintop/fw3x-lume1/hwdef.c110
-rw-r--r--hw/lumintop/fw3x-lume1/hwdef.h101
-rw-r--r--hw/lumintop/fw3x-lume1/rgbswap/anduril.h11
-rw-r--r--hw/lumintop/fw3x-lume1/rgbswap/model1
9 files changed, 243 insertions, 89 deletions
diff --git a/hw/lumintop/blf-gt/anduril.h b/hw/lumintop/blf-gt/anduril.h
index 2fc359e..cc2f940 100644
--- a/hw/lumintop/blf-gt/anduril.h
+++ b/hw/lumintop/blf-gt/anduril.h
@@ -54,7 +54,14 @@
#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_FLOOR
+#define USE_SMOOTH_STEPS
+
// too big, turn off extra features
//#undef USE_TACTICAL_MODE
#undef USE_SOS_MODE
+#undef USE_BEACON_MODE
+#undef USE_RAMP_AFTER_MOON_CONFIG
+//#undef USE_RAMP_SPEED_CONFIG
+//#undef USE_VOLTAGE_CORRECTION
+#undef USE_2C_STYLE_CONFIG
diff --git a/hw/lumintop/blf-gt/hwdef.h b/hw/lumintop/blf-gt/hwdef.h
index bf3790d..68197ac 100644
--- a/hw/lumintop/blf-gt/hwdef.h
+++ b/hw/lumintop/blf-gt/hwdef.h
@@ -16,9 +16,7 @@
* and its output gets PWM'd by pin 5.
*/
-#include <avr/io.h>
-
-#define HWDEF_C_FILE hank/emisar-d4/hwdef.c
+#define HWDEF_C hank/emisar-d4/hwdef.c
// channel modes
// * 0. main LEDs
@@ -69,14 +67,18 @@ enum CHANNEL_MODES {
//#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL)
// 1.1V reference, no left-adjust, ADC1/PB2
#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | VOLTAGE_CHANNEL)
+
+#undef voltage_raw2cooked
+#define voltage_raw2cooked mcu_vdivider_raw2cooked
+
#define ADC_PRSCL 0x07 // clk/128
// Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line)
#ifndef ADC_44
-#define ADC_44 (184*4)
+#define ADC_44 (184*4*4)
#endif
#ifndef ADC_22
-#define ADC_22 (92*4)
+#define ADC_22 (92*4*4)
#endif
#define FAST 0xA3 // fast PWM both channels
diff --git a/hw/lumintop/fw3a/hwdef.h b/hw/lumintop/fw3a/hwdef.h
index 649dc19..7809fa9 100644
--- a/hw/lumintop/fw3a/hwdef.h
+++ b/hw/lumintop/fw3a/hwdef.h
@@ -12,9 +12,7 @@
* ----
*/
-#include <avr/io.h>
-
-#define HWDEF_C_FILE lumintop/fw3a/hwdef.c
+#define HWDEF_C lumintop/fw3a/hwdef.c
// channel modes
// * 0. FET+7+1 stacked
diff --git a/hw/lumintop/fw3x-lume1/README.md b/hw/lumintop/fw3x-lume1/README.md
new file mode 100644
index 0000000..8609c49
--- /dev/null
+++ b/hw/lumintop/fw3x-lume1/README.md
@@ -0,0 +1,26 @@
+# Lumintop FW3X Lume1
+
+A BLF FW3A with a new driver from LoneOceans. The new driver adds efficient
+constant-current power regulation, RGB aux LEDs, and an upgraded temperature
+sensor.
+
+## Notes of interest
+
+**Flashing firmware**: The MOSI and MISO pin are swapped, compared to a Hanklight.
+LoneOceans sent a fixed driver design to Lumintop, but the new design didn't
+get produced. So to flash firmware, swap the wires for those two pins first.
+
+**RGB mixup**: Lumintop seems to have swapped the wires for aux R and aux B.
+This was fixed in firmware in 2023-12, but some lights were fixed in hardware
+before that, so the firmware fix might cause the colors to be swapped again.
+
+**Turbo**: The driver uses regulation for levels 1 to 149, and level 150 is a
+direct-drive FET. This is by design, and the FET cannot be ramped smoothly up
+and down. Turbo is a single level at the top of the ramp, with a big sudden
+drop to the next level.
+
+**Moon**: This light has a pretty bright preflash at moon level, and the
+output is unstable so there is very visible ripple. The user can either raise
+the ramp floor to a level high enough to avoid these issues, or learn to live
+with the ripple and preflash.
+
diff --git a/hw/lumintop/fw3x-lume1/anduril.h b/hw/lumintop/fw3x-lume1/anduril.h
index b208fbc..cd06c6a 100644
--- a/hw/lumintop/fw3x-lume1/anduril.h
+++ b/hw/lumintop/fw3x-lume1/anduril.h
@@ -8,10 +8,9 @@
* For more information: www.loneoceans.com/labs/
* Datasheets:
* - 1634: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8303-8-bit-AVR-Microcontroller-tinyAVR-ATtiny1634_Datasheet.pdf
- * - 85: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
*/
-#include "lumintop/fw3x-lume1/hwdef.h"
+#define HWDEF_H lumintop/fw3x-lume1/hwdef.h
// set this light for 50C thermal ceiling
#undef DEFAULT_THERM_CEIL
@@ -20,60 +19,61 @@
// this light has three aux LED channels: R, G, B
#define USE_AUX_RGB_LEDS
-// it has no independent LED in the button unlike emisar d4
-//#define USE_BUTTON_LED
-
// the aux LEDs are front-facing, so turn them off while main LEDs are on
#ifdef USE_INDICATOR_LED_WHILE_RAMPING
#undef USE_INDICATOR_LED_WHILE_RAMPING
#endif
-// ../../bin/level_calc.py cube 1 149 7135 0 0.5 1000, with 0 appended to the end.
-// for FET PWM (PWM2), all values are 0, except for last value of 1023
-// (with max_pwm set to 1023)
#define RAMP_SIZE 150
-//#define PWM1_LEVELS 0,0,0,0,1,1,1,1,2,2,2,3,3,4,4,5,5,6,7,7,8,9,10,11,12,13,14,15,16,17,19,20,22,23,25,26,28,30,32,34,36,38,40,42,45,47,49,52,55,58,60,63,66,70,73,76,80,83,87,91,94,98,102,107,111,115,120,124,129,134,139,144,150,155,160,166,172,178,184,190,196,203,209,216,223,230,237,244,252,259,267,275,283,291,299,308,316,325,334,343,353,362,372,382,392,402,412,423,433,444,455,466,478,489,501,513,525,538,550,563,576,589,602,616,630,644,658,672,687,701,716,731,747,762,778,794,810,827,844,861,878,895,913,930,948,967,985,1004,1023,0
-#define PWM1_LEVELS 1,1,1,1,2,2,2,2,3,3,3,4,4,5,5,6,6,7,8,8,9,10,11,12,13,14,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,56,58,61,64,67,70,74,77,80,84,88,91,95,99,103,108,112,116,121,125,130,135,140,145,150,156,161,167,173,178,184,191,197,203,210,217,223,230,238,245,252,260,268,275,283,292,300,308,317,326,335,344,353,363,372,382,392,402,413,423,434,445,456,467,478,490,502,514,526,538,551,563,576,589,603,616,630,644,658,672,687,702,717,732,747,763,778,794,811,827,844,861,878,895,913,931,949,967,985,1004,1023,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,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,1023
+
+// level_calc.py 5.01 1 149 7135 0 0.2 2000 --pwm 32640
+// regulated channel: 16-bit PWM+DSM for low lows and very smooth ramp
+#define PWM1_LEVELS 0,1,2,3,4,5,6,7,9,10,12,14,17,19,22,25,29,33,37,41,46,51,57,63,70,77,85,93,103,112,123,134,146,159,172,187,203,219,237,256,276,297,319,343,368,394,422,452,483,516,551,587,625,666,708,753,799,848,900,954,1010,1069,1131,1195,1263,1333,1407,1483,1563,1647,1734,1825,1919,2017,2119,2226,2336,2451,2571,2694,2823,2957,3095,3239,3388,3542,3702,3868,4040,4217,4401,4591,4788,4992,5202,5419,5644,5876,6115,6362,6617,6880,7152,7432,7721,8018,8325,8641,8967,9302,9647,10003,10369,10745,11133,11531,11941,12363,12796,13241,13699,14169,14652,15148,15657,16180,16717,17268,17834,18414,19009,19620,20246,20888,21546,22221,22913,23621,24348,25091,25853,26634,27433,28251,29089,29946,30823,31721,32640,0
+// DD FET: 8-bit PWM (but hardware can only handle 0 and MAX)
+#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,255
#define DEFAULT_LEVEL 56
#define MAX_1x7135 149
-// TODO: test if underclocking works on lume1
-//#define HALFSPEED_LEVEL 14
-//#define QUARTERSPEED_LEVEL 5
-// don't slow down at low levels; this isn't that sort of light
-// (it needs to stay at full speed for the 10-bit PWM to work)
-#ifdef USE_DYNAMIC_UNDERCLOCKING
-#undef USE_DYNAMIC_UNDERCLOCKING
-#endif
-
-// the entire ramp is regulated except turbo; don't blink halfway up
-#ifdef BLINK_AT_RAMP_MIDDLE
-#undef BLINK_AT_RAMP_MIDDLE
-#endif
+#define MIN_THERM_STEPDOWN 50
+#define HALFSPEED_LEVEL 21
+#define QUARTERSPEED_LEVEL 11
#define RAMP_SMOOTH_FLOOR 1
#define RAMP_SMOOTH_CEIL 149
-// turn on BuckBoost from level 1 to 149, but not 150
-// Level 150 is when BuckBoost is off and FET is ON 100%
-#define LED_ENABLE_PIN_LEVEL_MIN 1
-#define LED_ENABLE_PIN_LEVEL_MAX 149
// 10 33 56 79 102 125 [149]
#define RAMP_DISCRETE_FLOOR 10
-#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 7
#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
#define SIMPLE_UI_CEIL 120
#define SIMPLE_UI_STEPS 5
+// show each channel while it scroll by in the menu
+#define USE_CONFIG_COLORS
+
+// blink numbers on the main LEDs by default (but allow user to change it)
+#define DEFAULT_BLINK_CHANNEL CM_MAIN
+
// slow down party strobe; this driver can't pulse for too short a time
-#define PARTY_STROBE_ONTIME 4
+#define PARTY_STROBE_ONTIME 1
+
+// use aux red + aux blue for police strobe
+#define USE_POLICE_COLOR_STROBE_MODE
+#define POLICE_STROBE_USES_AUX
+#define POLICE_COLOR_STROBE_CH1 CM_AUXRED
+#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU
// stop panicking at ~85% regulated power or ~750 lm
#define THERM_FASTER_LEVEL 140
#define THERM_CAL_OFFSET 0 // not needed due to external sensor
+// don't blink while ramping
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
+#endif
+
+
// can't reset the normal way because power is connected before the button
#define USE_SOFT_FACTORY_RESET
diff --git a/hw/lumintop/fw3x-lume1/hwdef.c b/hw/lumintop/fw3x-lume1/hwdef.c
index 71cd799..306a58c 100644
--- a/hw/lumintop/fw3x-lume1/hwdef.c
+++ b/hw/lumintop/fw3x-lume1/hwdef.c
@@ -1,10 +1,11 @@
-// FW3X Lume1 PWM helper functions
+// FW3X Lume1 helper functions
// Copyright (C) 2023 Selene ToyKeeper
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "fsm/chan-rgbaux.c"
+
void set_level_zero();
void set_level_main(uint8_t level);
@@ -21,6 +22,12 @@ Channel channels[] = {
void set_level_zero() {
+ // disable timer overflow interrupt
+ // (helps improve button press handling from Off state)
+ DSM_INTCTRL &= ~DSM_OVF_bm;
+
+ // turn off all LEDs
+ ch1_dsm_lvl = 0;
CH1_PWM = 0;
CH2_PWM = 0;
PWM_CNT = 0; // reset phase
@@ -29,32 +36,109 @@ void set_level_zero() {
// single set of LEDs with 2 stacked power channels, regulated + DD FET
void set_level_main(uint8_t level) {
- CH1_ENABLE_PORT |= (1 << CH1_ENABLE_PIN); // enable regulator
+ if (level == actual_level - 1) return; // prevent flicker on no-op
- PWM_DATATYPE ch1_pwm = PWM_GET(pwm1_levels, level);
- PWM_DATATYPE ch2_pwm = PWM_GET(pwm2_levels, level);
+ PWM1_DATATYPE ch1 = PWM1_GET(level);
+ PWM2_DATATYPE ch2 = PWM2_GET(level);
- CH1_PWM = ch1_pwm;
- CH2_PWM = ch2_pwm;
+ // set delta-sigma soft levels
+ ch1_dsm_lvl = ch1;
+
+ // set hardware PWM levels and init dsm loop
+ CH1_PWM = ch1_pwm = ch1 >> 7;
+ CH2_PWM = ch2;
+
+ // enable timer overflow interrupt so DSM can work
+ DSM_INTCTRL |= DSM_OVF_bm;
// force reset phase when turning on from zero
// (for faster, more consistent initial response)
if (! actual_level) PWM_CNT = 0;
+
+ // don't enable ch1 and ch2 at the same time
+ if (ch2) CH1_ENABLE_PORT &= ~(1 << CH1_ENABLE_PIN); // disable regulator
+ else CH1_ENABLE_PORT |= (1 << CH1_ENABLE_PIN); // enable regulator
}
+// delta-sigma modulation of PWM outputs
+// happens on each Timer overflow (every 512 cpu clock cycles)
+// uses 8-bit pwm w/ 7-bit dsm (0b 0PPP PPPP PDDD DDDD)
+ISR(DSM_vect) {
+ // set new hardware values first,
+ // for best timing (reduce effect of interrupt jitter)
+ CH1_PWM = ch1_pwm;
+
+ // calculate next values, now that timing matters less
+
+ // accumulate error
+ ch1_dsm += (ch1_dsm_lvl & 0x007f);
+ // next PWM = base PWM value + carry bit
+ ch1_pwm = (ch1_dsm_lvl >> 7) + (ch1_dsm > 0x7f);
+ // clear carry bit
+ ch1_dsm &= 0x7f;
+}
+
+
bool gradual_tick_main(uint8_t gt) {
// 150/150 is full FET + zero regulated,
// 149/150 is zero FET + full regulated,
// so don't try to gradually adjust between
- if ((RAMP_SIZE == actual_level) || (gt >= RAMP_SIZE-1)) {
- set_level(gt + 1);
- return true;
- }
+ // if target is in the top 2 levels, just let the parent handle it
+ if (gt >= RAMP_SIZE-2) return true;
- PWM_DATATYPE pwm1 = PWM_GET(pwm1_levels, gt);
- GRADUAL_ADJUST_SIMPLE(pwm1, CH1_PWM);
+ PWM1_DATATYPE ch1 = PWM1_GET(gt);
- if (pwm1 == CH1_PWM) return true; // done
+ // adjust multiple times based on current brightness
+ // (so it adjusts faster/coarser when bright, slower/finer when dim)
+
+ // higher shift = slower/finer adjustments
+ const uint8_t shift = 9; // ((255 << 7) >> 9) = 63 max
+ uint8_t steps;
+
+ steps = ch1_dsm_lvl >> shift;
+ for (uint8_t i=0; i<=steps; i++)
+ GRADUAL_ADJUST_SIMPLE(ch1, ch1_dsm_lvl);
+
+ if ((ch1 == ch1_dsm_lvl)
+ ) {
+ return true; // done
+ }
return false; // not done yet
}
+////////// external temperature sensor //////////
+
+#ifdef ADMUX_THERM_EXTERNAL_SENSOR
+
+void hwdef_set_admux_therm() {
+ // put the ADC in temperature mode
+ // ADCSRB: [VDEN, VDPD, -, -, ADLAR, ADTS2, ADTS1, ADTS0]
+ ADCSRB = (1 << ADLAR); // left-adjust, free-running
+ // DS table 19-3, 19-4
+ // [refs1, refs0, refen, adc0en, mux3, mux2, mux1, mux0]
+ // refs=0b00 : VCC (2.5V)
+ // mux=0b1011 : ADC11 (pin PC2)
+ ADMUX = ADMUX_THERM_EXTERNAL_SENSOR;
+ // other stuff is already set, so no need to re-set it
+}
+
+uint16_t temp_raw2cooked(uint16_t measurement) {
+ // In: (raw ADC average) << 6
+ // Out: Kelvin << 6
+ /* notes from old versions of the code...
+ // Used for Lume1 Driver: MCP9700 - T_Celsius = 100*(VOUT - 0.5V)
+ // ADC is 2.5V reference, 0 to 1023
+ // due to floating point, this calculation takes 916 extra bytes
+ // (should use an integer equivalent instead)
+ //#define EXTERN_TEMP_FORMULA(m) (((m)-205)/4.09)
+ //int16_t celsius = (((measurement-205)/4.09)) + THERM_CAL_OFFSET + (int16_t)therm_cal_offset;
+ */
+
+ // this formula could probably be simplified... but meh, it works
+ uint16_t k6 = ((uint32_t)(measurement - (205 << 6)) * 100 / 409)
+ + (273 << 6); // convert back from C to K
+ return k6;
+}
+
+#endif
+
diff --git a/hw/lumintop/fw3x-lume1/hwdef.h b/hw/lumintop/fw3x-lume1/hwdef.h
index 943921f..021c4cf 100644
--- a/hw/lumintop/fw3x-lume1/hwdef.h
+++ b/hw/lumintop/fw3x-lume1/hwdef.h
@@ -8,9 +8,9 @@
*
* Pin / Name / Function in Lume1 Rev B
* 1 PA6 Regulated PWM (PWM1B)
- * 2 PA5 R: red aux LED (PWM0B)
+ * 2 PA5 B: blue aux LED (PWM0B) (or red)
* 3 PA4 G: green aux LED
- * 4 PA3 B: blue aux LED
+ * 4 PA3 R: red aux LED (or blue)
* 5 PA2 e-switch (PCINT2)
* 6 PA1 Jumper 1
* 7 PA0 Jumper 2
@@ -34,9 +34,7 @@
* Another pin is used for DD FET control.
*/
-#include <avr/io.h>
-
-#define HWDEF_C_FILE lumintop/fw3x-lume1/hwdef.c
+#define HWDEF_C lumintop/fw3x-lume1/hwdef.c
// allow using aux LEDs as extra channel modes
#include "fsm/chan-rgbaux.h"
@@ -56,29 +54,38 @@ enum CHANNEL_MODES {
#define CHANNEL_MODES_ENABLED 0b0000000000000001
-#define PWM_CHANNELS 2 // old, remove this
-
-// Added for Lume1 Buck Boost Driver
-#define PWM_BITS 16 // 0 to 1023 at 3.9 kHz, not 0 to 255 at 15.6 kHz
-#define PWM_GET PWM_GET16
+#define PWM_BITS 16 // 0 to 32640 (0 to 255 PWM + 0 to 127 DSM) at constant kHz
#define PWM_DATATYPE uint16_t
#define PWM_DATATYPE2 uint32_t // only needs 32-bit if ramp values go over 255
#define PWM1_DATATYPE uint16_t // regulated ramp
-#define PWM2_DATATYPE uint16_t // DD FET ramp
+#define PWM1_GET(x) PWM_GET16(pwm1_levels, x)
+#define PWM2_DATATYPE uint8_t // DD FET ramp
+#define PWM2_GET(x) PWM_GET8(pwm2_levels, x)
// PWM parameters of both channels are tied together because they share a counter
#define PWM_TOP ICR1 // holds the TOP value for variable-resolution PWM
-#define PWM_TOP_INIT 1023
-#define PWM_CNT TCNT1 // for dynamic PWM, reset phase
+#define PWM_TOP_INIT 255
+#define PWM_CNT TCNT1 // for checking / resetting phase
+// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM)
+#define DSM_TOP (255<<7) // 15-bit resolution leaves 1 bit for carry
+
+// timer interrupt for DSM
+#define DSM_vect TIMER1_OVF_vect
+#define DSM_INTCTRL TIMSK
+#define DSM_OVF_bm (1<<TOIE1)
+
+#define DELAY_FACTOR 85 // less time in delay() because more time spent in interrupts
-// regulated channel
+// regulated channel uses PWM+DSM
+uint16_t ch1_dsm_lvl;
+uint8_t ch1_pwm, ch1_dsm;
#define CH1_PIN PA6 // pin 1, Buck Boost CTRL pin or 7135-eqv PWM
#define CH1_PWM OCR1B // OCR1B is the output compare register for PA6
#define CH1_ENABLE_PIN PA7 // pin 20, BuckBoost Enable
#define CH1_ENABLE_PORT PORTA // control port for PA7
-// DD FET channel
-#define CH2_PIN PB3 // pin 16, FET PWM Pin, but only used as on (1023) or off (0)
+// DD FET channel is on/off only (PWM=0, or PWM=MAX)
+#define CH2_PIN PB3 // pin 16, FET PWM Pin, but only used as on (255) or off (0)
#define CH2_PWM OCR1A // OCR1A is the output compare register for PB3
/* // For Jumpers X1 to X4, no SW support yet
@@ -95,7 +102,7 @@ enum CHANNEL_MODES {
#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0]
#define SWITCH_PORT PINA // PINA or PINB or PINC
#define SWITCH_PUE PUEA // pullup group A
-#define PCINT_vect PCINT0_vect // ISR for PCINT[7:0]
+#define SWITCH_VECT PCINT0_vect // ISR for PCINT[7:0]
#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened
#define VOLTAGE_PIN PB0 // Pin 19 PB0 ADC5
@@ -113,16 +120,19 @@ enum CHANNEL_MODES {
#define ADMUX_VOLTAGE_DIVIDER 0b00000101
#define ADC_PRSCL 0x06 // clk/64
+#undef voltage_raw2cooked
+#define voltage_raw2cooked mcu_vdivider_raw2cooked
+
// Raw ADC readings at 4.4V and 2.2V
// calibrate the voltage readout here
// estimated / calculated values are:
// [(Vbatt)*(R2/(R2+R1)) / 2.5V] * 1023
// R1 = R2 = 100kR
#ifndef ADC_44
-#define ADC_44 900
+#define ADC_44 (4*900)
#endif
#ifndef ADC_22
-#define ADC_22 450
+#define ADC_22 (4*450)
#endif
// Default ADMUX_THERM for Temperature is: 0b10001110 in arch/mcu.h
@@ -132,18 +142,26 @@ enum CHANNEL_MODES {
// Modified fsm-adc.c to use different ADMUX and ADC_temperature_handler()
// based on USE_EXTERNAL_TEMP_SENSOR
// See line 34 and line 209
-#define USE_EXTERNAL_TEMP_SENSOR
-#define ADMUX_THERM_EXTERNAL_SENSOR 0b00001011 // VCC reference (2.5V), Channel PC2
-// Used for Lume1 Driver: MCP9700 - T_Celsius = 100*(VOUT - 0.5V)
-// ADC is 2.5V reference, 0 to 1023
-// FIXME: due to floating point, this calculation takes 916 extra bytes
-// (should use an integer equivalent instead)
-#define EXTERN_TEMP_FORMULA(m) (((m)-205)/4.09)
+//#define USE_EXTERNAL_TEMP_SENSOR
+
+// override the default temperature sensor code
+#undef hwdef_set_admux_therm
+void hwdef_set_admux_therm();
+#undef temp_raw2cooked
+uint16_t temp_raw2cooked(uint16_t measurement);
+// VCC reference (2.5V), Channel PC2
+#define ADMUX_THERM_EXTERNAL_SENSOR 0b00001011
// this driver allows for 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
+#ifdef FW3X_RGB_SWAP // wiring fixed by end user
+ #define AUXLED_R_PIN PA5 // pin 2
+ #define AUXLED_G_PIN PA4 // pin 3
+ #define AUXLED_B_PIN PA3 // pin 4
+#else // Lumintop's factory wiring
+ #define AUXLED_R_PIN PA3 // pin 4
+ #define AUXLED_G_PIN PA4 // pin 3
+ #define AUXLED_B_PIN PA5 // pin 2
+#endif
#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
@@ -173,24 +191,31 @@ inline void hwdef_setup() {
PUEC = (1 << JUMPER4_PIN);
*/
- // configure PWM for 10 bit at 3.9kHz
+ // 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)
+ // PWM for both channels
+ // WGM1[3:0]: 1,0,1,0: PWM, Phase Correct, adjustable (DS table 12-5)
+ // WGM1[3:0]: 1,1,1,0: PWM, Fast, adjustable (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<<WGM11) | (1<<WGM10) // 10-bit (TOP=0x03FF) (DS table 12-5)
- | (1<<COM1A1) | (0<<COM1A0) // PWM 1A Clear OC1A on Compare Match
- | (1<<COM1B1) | (0<<COM1B0) // PWM 1B Clear OC1B on Compare Match
- ;
- TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6)
- | (0<<WGM13) | (0<<WGM12) // PWM, Phase Correct, 10-bit
- ;
+ TCCR1A = (1<<WGM11) | (0<<WGM10) // adjustable PWM (TOP=ICR1) (DS table 12-5)
+ | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4)
+ | (1<<COM1B1) | (0<<COM1B0) // PWM 1B in normal direction (DS table 12-4)
+ ;
+ TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6)
+ //| (1<<WGM13) | (1<<WGM12) // fast adjustable PWM (DS table 12-5)
+ | (1<<WGM13) | (0<<WGM12) // phase-correct adjustable PWM (DS table 12-5)
+ ;
// set PWM resolution
PWM_TOP = PWM_TOP_INIT;
+ // set up interrupt for delta-sigma modulation
+ // (moved to hwdef.c functions so it can be enabled/disabled based on ramp level)
+ //DSM_INTCTRL |= DSM_OVF_bm; // interrupt once for each timer cycle
+
// set up e-switch
SWITCH_PUE = (1 << SWITCH_PIN); // pull-up for e-switch
SWITCH_PCMSK = (1 << SWITCH_PCINT); // enable pin change interrupt
diff --git a/hw/lumintop/fw3x-lume1/rgbswap/anduril.h b/hw/lumintop/fw3x-lume1/rgbswap/anduril.h
new file mode 100644
index 0000000..2fba7ff
--- /dev/null
+++ b/hw/lumintop/fw3x-lume1/rgbswap/anduril.h
@@ -0,0 +1,11 @@
+// FW3X (RGB aux swapped) config options for Anduril
+// Copyright (C) 2023 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
+#pragma once
+
+// Lumintop swapped red and blue wires. Some people fixed the wiring.
+// Then the firmware fixed the pinouts to match Lumintop's wiring.
+// This firmware exists for people who fixed their wiring.
+#define FW3X_RGB_SWAP
+#include "lumintop/fw3x-lume1/anduril.h"
+
diff --git a/hw/lumintop/fw3x-lume1/rgbswap/model b/hw/lumintop/fw3x-lume1/rgbswap/model
new file mode 100644
index 0000000..44505ce
--- /dev/null
+++ b/hw/lumintop/fw3x-lume1/rgbswap/model
@@ -0,0 +1 @@
+0315
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.