aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/anduril/anduril.c90
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k1.h58
-rw-r--r--spaghetti-monster/fsm-adc.c8
-rw-r--r--spaghetti-monster/fsm-ramping.c39
-rw-r--r--spaghetti-monster/fsm-ramping.h64
5 files changed, 199 insertions, 60 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index bc2f9c6..cb48b45 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -96,6 +96,10 @@
//#define USE_SOS_MODE_IN_FF_GROUP // put SOS in the "boring strobes" mode
//#define USE_SOS_MODE_IN_BLINKY_GROUP // put SOS in the blinkies mode group
+// cut clock speed at very low modes for better efficiency
+// (defined here so config files can override it)
+#define USE_DYNAMIC_UNDERCLOCKING
+
/***** specific settings for known driver types *****/
#include "tk.h"
#include incfile(CONFIGFILE)
@@ -135,7 +139,6 @@
#endif
#endif
#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending
-#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency
// full FET strobe can be a bit much... use max regulated level instead,
// if there's a bright enough regulated level
@@ -320,7 +323,9 @@ void blip();
void indicator_blink(uint8_t arg);
#endif
#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY)
+uint8_t setting_rgb_mode_now = 0;
void rgb_led_update(uint8_t mode, uint8_t arg);
+void rgb_led_voltage_readout(uint8_t bright);
/*
* 0: R
* 1: RG
@@ -332,6 +337,15 @@ void rgb_led_update(uint8_t mode, uint8_t arg);
* 7: rainbow
* 8: voltage
*/
+const PROGMEM uint8_t rgb_led_colors[] = {
+ 0b00000001, // 0: red
+ 0b00000101, // 1: yellow
+ 0b00000100, // 2: green
+ 0b00010100, // 3: cyan
+ 0b00010000, // 4: blue
+ 0b00010001, // 5: purple
+ 0b00010101, // 6: white
+};
#define RGB_LED_NUM_COLORS 10
#define RGB_LED_NUM_PATTERNS 4
#ifndef RGB_LED_OFF_DEFAULT
@@ -683,6 +697,7 @@ uint8_t off_state(Event event, uint16_t arg) {
}
// 7 clicks (hold last): change RGB aux LED color
else if (event == EV_click7_hold) {
+ setting_rgb_mode_now = 1;
if (0 == (arg & 0x3f)) {
uint8_t mode = (rgb_led_off_mode & 0x0f) + 1;
mode = mode % RGB_LED_NUM_COLORS;
@@ -693,6 +708,7 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
else if (event == EV_click7_hold_release) {
+ setting_rgb_mode_now = 0;
save_config();
return MISCHIEF_MANAGED;
}
@@ -1261,8 +1277,12 @@ inline void party_tactical_strobe_mode_iter(uint8_t st) {
if (0) {} // placeholde0
#ifdef USE_PARTY_STROBE_MODE
else if (st == party_strobe_e) { // party strobe
+ #ifdef PARTY_STROBE_ONTIME
+ nice_delay_ms(PARTY_STROBE_ONTIME);
+ #else
if (del < 42) delay_zero();
else nice_delay_ms(1);
+ #endif
}
#endif
#ifdef USE_TACTICAL_STROBE_MODE
@@ -1784,6 +1804,7 @@ uint8_t lockout_state(Event event, uint16_t arg) {
}
// click, click, hold: change RGB aux LED color
else if (event == EV_click3_hold) {
+ setting_rgb_mode_now = 1;
if (0 == (arg & 0x3f)) {
uint8_t mode = (rgb_led_lockout_mode & 0x0f) + 1;
mode = mode % RGB_LED_NUM_COLORS;
@@ -1795,6 +1816,7 @@ uint8_t lockout_state(Event event, uint16_t arg) {
}
// click, click, hold, release: save new color
else if (event == EV_click3_hold_release) {
+ setting_rgb_mode_now = 0;
save_config();
return MISCHIEF_MANAGED;
}
@@ -1850,9 +1872,14 @@ uint8_t momentary_state(Event event, uint16_t arg) {
}
}
else {
- if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
+ if (arg > TICKS_PER_SECOND*5) { // sleep after 5 seconds
go_to_standby = 1; // sleep while light is off
- // TODO: lighted button should use lockout config?
+ // turn off lighted button
+ #ifdef USE_INDICATOR_LED
+ indicator_led(0);
+ #elif defined(USE_AUX_RGB_LEDS)
+ rgb_led_update(0, 0);
+ #endif
}
}
return MISCHIEF_MANAGED;
@@ -1980,6 +2007,9 @@ uint8_t muggle_state(Event event, uint16_t arg) {
// turn off, but don't go to the main "off" state
if (muggle_off_mode) {
if (arg > TICKS_PER_SECOND*1) { // sleep after 1 second
+ #ifdef USE_AUX_RGB_LEDS_WHILE_ON
+ rgb_led_set(0);
+ #endif
go_to_standby = 1; // sleep while light is off
}
}
@@ -2317,6 +2347,27 @@ void indicator_blink(uint8_t arg) {
#endif
#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY)
+uint8_t voltage_to_rgb() {
+ uint8_t levels[] = {
+ // voltage, color
+ 0, 0, // 0, R
+ 33, 1, // 1, R+G
+ 35, 2, // 2, G
+ 37, 3, // 3, G+B
+ 39, 4, // 4, B
+ 41, 5, // 5, R + B
+ 44, 6, // 6, R+G+B // skip; looks too similar to G+B
+ 255, 6, // 7, R+G+B
+ };
+ uint8_t volts = voltage;
+ if (volts < 29) return 0;
+
+ uint8_t i;
+ for (i = 0; volts >= levels[i]; i += 2) {}
+ uint8_t color_num = levels[(i - 2) + 1];
+ return pgm_read_byte(rgb_led_colors + color_num);
+}
+
// do fancy stuff with the RGB aux LEDs
// mode: 0bPPPPCCCC where PPPP is the pattern and CCCC is the color
// arg: time slice number
@@ -2342,18 +2393,10 @@ void rgb_led_update(uint8_t mode, uint8_t arg) {
if ((! go_to_standby) && (pattern > 2)) { pattern = 2; }
- uint8_t colors[] = {
- 0b00000001, // 0: red
- 0b00000101, // 1: yellow
- 0b00000100, // 2: green
- 0b00010100, // 3: cyan
- 0b00010000, // 4: blue
- 0b00010001, // 5: purple
- 0b00010101, // 6: white
- };
+ const uint8_t *colors = rgb_led_colors;
uint8_t actual_color = 0;
if (color < 7) { // normal color
- actual_color = colors[color];
+ actual_color = pgm_read_byte(colors + color);
}
else if (color == 7) { // rainbow
uint8_t speed = 0x03; // awake speed
@@ -2361,19 +2404,20 @@ void rgb_led_update(uint8_t mode, uint8_t arg) {
if (0 == (arg & speed)) {
rainbow = (rainbow + 1) % 6;
}
- actual_color = colors[rainbow];
+ actual_color = pgm_read_byte(colors + rainbow);
}
else { // voltage
// show actual voltage while asleep...
if (go_to_standby) {
+ actual_color = voltage_to_rgb();
// choose a color based on battery voltage
- if (volts >= 38) actual_color = colors[4];
- else if (volts >= 33) actual_color = colors[2];
- else actual_color = colors[0];
+ //if (volts >= 38) actual_color = pgm_read_byte(colors + 4);
+ //else if (volts >= 33) actual_color = pgm_read_byte(colors + 2);
+ //else actual_color = pgm_read_byte(colors + 0);
}
// ... but during preview, cycle colors quickly
else {
- actual_color = colors[((arg>>1) % 3) << 1];
+ actual_color = pgm_read_byte(colors + (((arg>>1) % 3) << 1));
}
}
@@ -2414,6 +2458,12 @@ void rgb_led_update(uint8_t mode, uint8_t arg) {
button_led_set(button_led_result);
#endif
}
+
+void rgb_led_voltage_readout(uint8_t bright) {
+ uint8_t color = voltage_to_rgb();
+ if (bright) color = color << 1;
+ rgb_led_set(color);
+}
#endif
@@ -2651,6 +2701,10 @@ void loop() {
StatePtr state = current_state;
+ #ifdef USE_AUX_RGB_LEDS_WHILE_ON
+ if (! setting_rgb_mode_now) rgb_led_voltage_readout(1);
+ #endif
+
if (0) {}
#ifdef USE_VERSION_CHECK
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1.h b/spaghetti-monster/anduril/cfg-noctigon-k1.h
new file mode 100644
index 0000000..59eb32e
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-noctigon-k1.h
@@ -0,0 +1,58 @@
+// Noctigon K1 config options for Anduril
+// (originally known as Emisar D1S v2)
+#include "hwdef-Noctigon_K1.h"
+// ATTINY: 1634
+
+// this light can safely run a bit hotter than most
+#undef DEFAULT_THERM_CEIL
+#define DEFAULT_THERM_CEIL 55
+
+// this light has three aux LED channels: R, G, B
+#define USE_AUX_RGB_LEDS
+#define USE_AUX_RGB_LEDS_WHILE_ON
+#define USE_INDICATOR_LED_WHILE_RAMPING
+#define RGB_LED_OFF_DEFAULT 0x18 // low, voltage
+#define RGB_LED_LOCKOUT_DEFAULT 0x37 // blinking, rainbow
+
+// enable blinking aux LEDs
+#define TICK_DURING_STANDBY
+#define STANDBY_TICK_SPEED 3 // every 0.128 s
+
+
+// ../../bin/level_calc.py cube 1 150 7135 1 4 1300
+// (with max_pwm set to 1023)
+#define RAMP_LENGTH 150
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,23,24,26,27,29,31,32,34,36,38,40,43,45,47,49,52,54,57,60,62,65,68,71,74,77,81,84,87,91,95,98,102,106,110,114,118,122,127,131,136,141,145,150,155,160,166,171,176,182,188,193,199,205,211,218,224,231,237,244,251,258,265,272,280,287,295,303,310,319,327,335,344,352,361,370,379,388,397,407,416,426,436,446,457,467,477,488,499,510,521,533,544,556,568,580,592,604,617,629,642,655,668,682,695,709,723,737,751,766,781,795,810,826,841,857,872,888,904,921,937,954,971,988,1005,1023
+#define MAX_1x7135 50
+
+// the entire ramp is regulated; don't blink halfway up
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
+#endif
+
+// 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
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 130
+// 10, 30, [50], 70, 90, 110, 130
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR
+#define MUGGLE_CEILING 70
+
+// stop panicking at ~70% power or ~600 lm
+#define THERM_FASTER_LEVEL 130
+#define THERM_CAL_OFFSET 5
+
+// easier access to thermal config mode, for Noctigon
+#define USE_TENCLICK_THERMAL_CONFIG
+
+// slow down party strobe; this driver can't pulse for 1ms or less
+#define PARTY_STROBE_ONTIME 2
+
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index 59d624b..eef3baf 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -81,10 +81,10 @@ inline void ADC_on()
set_admux_voltage();
#ifdef USE_VOLTAGE_DIVIDER
// disable digital input on divider pin to reduce power consumption
- DIDR0 |= (1 << VOLTAGE_ADC_DIDR);
+ VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC);
#else
// disable digital input on VCC pin to reduce power consumption
- //DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin
+ //VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); // FIXME: unsure how to handle for VCC pin
#endif
#if (ATTINY == 1634)
//ACSRA |= (1 << ACD); // turn off analog comparator to save power
@@ -111,8 +111,8 @@ inline void ADC_off() {
#ifdef USE_VOLTAGE_DIVIDER
static inline uint8_t calc_voltage_divider(uint16_t value) {
- // use 9.7 fixed-point to get sufficient precision
- uint16_t adc_per_volt = ((ADC_44<<7) - (ADC_22<<7)) / (44-22);
+ // use fixed-point to get sufficient precision
+ uint16_t adc_per_volt = ((ADC_44<<5) - (ADC_22<<5)) / (44-22);
// shift incoming value into a matching position
uint8_t result = ((value>>1) / adc_per_volt) + VOLTAGE_FUDGE_FACTOR;
return result;
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index 8515885..20500cc 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -68,16 +68,25 @@ void set_level(uint8_t level) {
#if PWM_CHANNELS >= 4
PWM4_LVL = 0;
#endif
+ // disable the power channel, if relevant
+ #ifdef LED_ENABLE_PIN
+ LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN);
+ #endif
} else {
level --;
+ // enable the power channel, if relevant
+ #ifdef LED_ENABLE_PIN
+ LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN);
+ #endif
+
#ifdef USE_TINT_RAMPING
#ifndef TINT_RAMPING_CORRECTION
#define TINT_RAMPING_CORRECTION 26 // 140% brightness at middle tint
#endif
// calculate actual PWM levels based on a single-channel ramp
// and a global tint value
- uint8_t brightness = pgm_read_byte(pwm1_levels + level);
+ uint8_t brightness = PWM_GET(pwm1_levels, level);
uint8_t warm_PWM, cool_PWM;
// auto-tint modes
@@ -110,16 +119,16 @@ void set_level(uint8_t level) {
#else
#if PWM_CHANNELS >= 1
- PWM1_LVL = pgm_read_byte(pwm1_levels + level);
+ PWM1_LVL = PWM_GET(pwm1_levels, level);
#endif
#if PWM_CHANNELS >= 2
- PWM2_LVL = pgm_read_byte(pwm2_levels + level);
+ PWM2_LVL = PWM_GET(pwm2_levels, level);
#endif
#if PWM_CHANNELS >= 3
- PWM3_LVL = pgm_read_byte(pwm3_levels + level);
+ PWM3_LVL = PWM_GET(pwm3_levels, level);
#endif
#if PWM_CHANNELS >= 4
- PWM4_LVL = pgm_read_byte(pwm4_levels + level);
+ PWM4_LVL = PWM_GET(pwm4_levels, level);
#endif
#endif // ifdef USE_TINT_RAMPING
@@ -143,43 +152,43 @@ void gradual_tick() {
gt --; // convert 1-based number to 0-based
- uint8_t target;
+ PWM_DATATYPE target;
#if PWM_CHANNELS >= 1
- target = pgm_read_byte(pwm1_levels + gt);
+ 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 == 255)) PWM1_LVL = 255;
+ && (target == PWM_TOP)) PWM1_LVL = PWM_TOP;
else if (PWM1_LVL < target) PWM1_LVL ++;
else if (PWM1_LVL > target) PWM1_LVL --;
#endif
#if PWM_CHANNELS >= 2
- target = pgm_read_byte(pwm2_levels + gt);
+ target = PWM_GET(pwm2_levels, gt);
if (PWM2_LVL < target) PWM2_LVL ++;
else if (PWM2_LVL > target) PWM2_LVL --;
#endif
#if PWM_CHANNELS >= 3
- target = pgm_read_byte(pwm3_levels + gt);
+ target = PWM_GET(pwm3_levels, gt);
if (PWM3_LVL < target) PWM3_LVL ++;
else if (PWM3_LVL > target) PWM3_LVL --;
#endif
#if PWM_CHANNELS >= 4
- target = pgm_read_byte(pwm4_levels + gt);
+ target = PWM_GET(pwm4_levels, gt);
if (PWM4_LVL < target) PWM4_LVL ++;
else if (PWM4_LVL > target) PWM4_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 == pgm_read_byte(pwm1_levels + gt))
+ if ((PWM1_LVL == PWM_GET(pwm1_levels, gt))
#if PWM_CHANNELS >= 2
- && (PWM2_LVL == pgm_read_byte(pwm2_levels + gt))
+ && (PWM2_LVL == PWM_GET(pwm2_levels, gt))
#endif
#if PWM_CHANNELS >= 3
- && (PWM3_LVL == pgm_read_byte(pwm3_levels + gt))
+ && (PWM3_LVL == PWM_GET(pwm3_levels, gt))
#endif
#if PWM_CHANNELS >= 4
- && (PWM4_LVL == pgm_read_byte(pwm4_levels + gt))
+ && (PWM4_LVL == PWM_GET(pwm4_levels, gt))
#endif
)
{
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index dcc3b74..c650e21 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -38,18 +38,36 @@ inline void set_level_gradually(uint8_t lvl);
void gradual_tick();
#endif
+// auto-detect the data type for PWM tables
+#ifndef PWM_BITS
+#define PWM_BITS 8
+#define PWM_TOP 255
+#endif
+#if PWM_BITS <= 8
+#define PWM_DATATYPE uint8_t
+#define PWM_TOP 255
+#define PWM_GET(x,y) pgm_read_byte(x+y)
+#else
+#define PWM_DATATYPE uint16_t
+#define PWM_TOP 1023 // 10 bits by default
+// pointer plus 2*y bytes
+//#define PWM_GET(x,y) pgm_read_word(x+(2*y))
+// nope, the compiler was already doing the math correctly
+#define PWM_GET(x,y) pgm_read_word(x+y)
+#endif
+
// use UI-defined ramp tables if they exist
#ifdef PWM1_LEVELS
-PROGMEM const uint8_t pwm1_levels[] = { PWM1_LEVELS };
+PROGMEM const PWM_DATATYPE pwm1_levels[] = { PWM1_LEVELS };
#endif
#ifdef PWM2_LEVELS
-PROGMEM const uint8_t pwm2_levels[] = { PWM2_LEVELS };
+PROGMEM const PWM_DATATYPE pwm2_levels[] = { PWM2_LEVELS };
#endif
#ifdef PWM3_LEVELS
-PROGMEM const uint8_t pwm3_levels[] = { PWM3_LEVELS };
+PROGMEM const PWM_DATATYPE pwm3_levels[] = { PWM3_LEVELS };
#endif
#ifdef PWM4_LEVELS
-PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS };
+PROGMEM const PWM_DATATYPE pwm4_levels[] = { PWM4_LEVELS };
#endif
// default / example ramps
@@ -57,31 +75,31 @@ PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS };
#if PWM_CHANNELS == 1
#if RAMP_LENGTH == 50
// ../../bin/level_calc.py 1 50 7135 3 0.25 980
- PROGMEM const uint8_t pwm1_levels[] = { 3,3,3,3,4,4,4,5,5,6,7,8,9,11,12,14,16,18,20,23,25,28,32,35,39,43,47,52,57,62,68,74,80,87,94,102,110,118,127,136,146,156,167,178,189,201,214,227,241,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,4,4,4,5,5,6,7,8,9,11,12,14,16,18,20,23,25,28,32,35,39,43,47,52,57,62,68,74,80,87,94,102,110,118,127,136,146,156,167,178,189,201,214,227,241,255 };
#elif RAMP_LENGTH == 75
// ../../bin/level_calc.py 1 75 7135 3 0.25 980
- PROGMEM const uint8_t pwm1_levels[] = { 3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,7,8,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,29,31,33,36,38,41,44,47,50,53,56,59,63,67,71,75,79,83,88,93,98,103,108,113,119,125,131,137,143,150,157,164,171,178,186,194,202,210,219,227,236,246,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,7,8,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,29,31,33,36,38,41,44,47,50,53,56,59,63,67,71,75,79,83,88,93,98,103,108,113,119,125,131,137,143,150,157,164,171,178,186,194,202,210,219,227,236,246,255 };
#elif RAMP_LENGTH == 150
// ../../bin/level_calc.py 1 150 7135 3 0.25 980
- PROGMEM const uint8_t pwm1_levels[] = { 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,12,12,13,13,14,15,15,16,17,17,18,19,19,20,21,22,23,24,24,25,26,27,28,29,31,32,33,34,35,36,38,39,40,42,43,44,46,47,49,50,52,53,55,57,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,89,91,93,96,98,101,103,106,109,111,114,117,120,123,125,128,131,134,138,141,144,147,151,154,157,161,164,168,171,175,179,183,186,190,194,198,202,206,210,215,219,223,228,232,236,241,246,250,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,12,12,13,13,14,15,15,16,17,17,18,19,19,20,21,22,23,24,24,25,26,27,28,29,31,32,33,34,35,36,38,39,40,42,43,44,46,47,49,50,52,53,55,57,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,89,91,93,96,98,101,103,106,109,111,114,117,120,123,125,128,131,134,138,141,144,147,151,154,157,161,164,168,171,175,179,183,186,190,194,198,202,206,210,215,219,223,228,232,236,241,246,250,255 };
#endif
#elif PWM_CHANNELS == 2
#if RAMP_LENGTH == 50
// ../../bin/level_calc.py 2 50 7135 4 0.33 150 FET 1 10 1500
- PROGMEM const uint8_t pwm1_levels[] = { 4,5,6,8,10,13,17,22,28,35,44,54,65,78,93,109,128,149,171,197,224,255,255,255,255,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 };
- PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,20,26,31,37,44,51,58,65,73,82,91,100,110,121,132,143,155,168,181,194,209,224,239,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,5,6,8,10,13,17,22,28,35,44,54,65,78,93,109,128,149,171,197,224,255,255,255,255,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 };
+ PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,20,26,31,37,44,51,58,65,73,82,91,100,110,121,132,143,155,168,181,194,209,224,239,255 };
#define MAX_1x7135 22
#elif RAMP_LENGTH == 75
// ../../bin/level_calc.py 2 75 7135 4 0.33 150 FET 1 10 1500
- PROGMEM const uint8_t pwm1_levels[] = { 4,4,5,6,7,8,10,12,14,17,20,24,28,32,37,43,49,56,64,72,82,91,102,114,126,139,153,168,184,202,220,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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 };
- PROGMEM const uint8_t 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,2,5,7,10,13,16,19,23,26,30,34,38,42,47,51,56,61,66,72,77,83,89,95,101,108,115,122,129,136,144,152,160,168,177,186,195,204,214,224,234,244,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,4,5,6,7,8,10,12,14,17,20,24,28,32,37,43,49,56,64,72,82,91,102,114,126,139,153,168,184,202,220,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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 };
+ PROGMEM const PWM_DATATYPE 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,2,5,7,10,13,16,19,23,26,30,34,38,42,47,51,56,61,66,72,77,83,89,95,101,108,115,122,129,136,144,152,160,168,177,186,195,204,214,224,234,244,255 };
#define MAX_1x7135 33
#elif RAMP_LENGTH == 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
- PROGMEM const uint8_t 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 };
- PROGMEM const uint8_t 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 };
+ PROGMEM const PWM_DATATYPE 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 };
+ PROGMEM const PWM_DATATYPE 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 HALFSPEED_LEVEL 14
#define QUARTERSPEED_LEVEL 5
@@ -89,25 +107,25 @@ PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS };
#elif PWM_CHANNELS == 3
#if RAMP_LENGTH == 50
// ../../bin/level_calc.py 3 50 7135 4 0.33 150 7135 4 1 840 FET 1 10 2000
- PROGMEM const uint8_t pwm1_levels[] = { 4,5,6,8,11,15,20,26,34,43,54,67,82,99,118,140,165,192,221,254,255,255,255,255,255,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 };
- PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,17,25,33,42,52,62,73,85,97,111,125,140,157,174,192,210,230,251,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const uint8_t pwm3_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,14,34,54,76,98,122,146,172,198,226,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,5,6,8,11,15,20,26,34,43,54,67,82,99,118,140,165,192,221,254,255,255,255,255,255,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 };
+ PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,17,25,33,42,52,62,73,85,97,111,125,140,157,174,192,210,230,251,255,255,255,255,255,255,255,255,255,255,0 };
+ PROGMEM const PWM_DATATYPE pwm3_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,14,34,54,76,98,122,146,172,198,226,255 };
#define MAX_1x7135 20
#define MAX_Nx7135 39
#elif RAMP_LENGTH == 75
// ../../bin/level_calc.py 3 75 7135 4 0.33 150 7135 4 1 840 FET 1 10 2000
- PROGMEM const uint8_t pwm1_levels[] = { 4,4,5,6,7,9,11,14,16,20,24,28,34,40,46,54,62,71,81,92,104,117,130,146,162,179,198,218,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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 };
- PROGMEM const uint8_t 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,5,9,14,18,23,29,34,40,47,53,60,67,75,83,91,99,108,117,127,137,148,158,170,181,193,206,219,232,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const uint8_t pwm3_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,3,15,28,42,55,70,84,99,115,131,147,164,181,199,217,236,255 };
+ PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,4,5,6,7,9,11,14,16,20,24,28,34,40,46,54,62,71,81,92,104,117,130,146,162,179,198,218,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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 };
+ PROGMEM const PWM_DATATYPE 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,5,9,14,18,23,29,34,40,47,53,60,67,75,83,91,99,108,117,127,137,148,158,170,181,193,206,219,232,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
+ PROGMEM const PWM_DATATYPE pwm3_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,3,15,28,42,55,70,84,99,115,131,147,164,181,199,217,236,255 };
#define MAX_1x7135 30
#define MAX_Nx7135 59
#elif RAMP_LENGTH == 150
// ../../bin/level_calc.py 1 65 7135 1 0.8 150
// ... mixed with this:
// ../../../bin/level_calc.py 3 150 7135 1 0.33 150 7135 1 1 850 FET 1 10 1500
- PROGMEM const uint8_t 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 };
- PROGMEM const uint8_t 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,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const uint8_t pwm3_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,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255 };
+ PROGMEM const PWM_DATATYPE 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 };
+ PROGMEM const PWM_DATATYPE 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,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
+ PROGMEM const PWM_DATATYPE pwm3_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,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255 };
#define MAX_1x7135 65
#define MAX_Nx7135 130
#define HALFSPEED_LEVEL 14
@@ -119,7 +137,7 @@ PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS };
#endif
// RAMP_SIZE / MAX_LVL
-#define RAMP_SIZE sizeof(pwm1_levels)
+#define RAMP_SIZE (sizeof(pwm1_levels)/sizeof(PWM_DATATYPE))
#define MAX_LEVEL RAMP_SIZE
void set_level(uint8_t level);
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.