aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/level_calc.py8
-rw-r--r--hwdef-BLF_GT.h4
-rw-r--r--hwdef-Emisar_D1Sv2.h133
-rw-r--r--hwdef-Mateminco_MF01S.h4
-rw-r--r--spaghetti-monster/anduril/anduril.c85
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d1sv2.h61
-rw-r--r--spaghetti-monster/fsm-adc.c4
-rw-r--r--spaghetti-monster/fsm-ramping.c39
-rw-r--r--spaghetti-monster/fsm-ramping.h64
-rw-r--r--tk-attiny.h4
10 files changed, 344 insertions, 62 deletions
diff --git a/bin/level_calc.py b/bin/level_calc.py
index 74385da..a780405 100755
--- a/bin/level_calc.py
+++ b/bin/level_calc.py
@@ -8,6 +8,8 @@ interactive = False
# supported shapes: ninth, seventh, fifth, cube, square, log
#ramp_shape = 'cube'
+max_pwm = 255
+
def main(args):
"""Calculates PWM levels for visually-linear steps.
@@ -22,7 +24,7 @@ def main(args):
(str, 'type', '7135', 'Type of channel - 7135 or FET:'),
(int, 'pwm_min', 6, 'Lowest visible PWM level:'),
(float, 'lm_min', 0.25, 'How bright is the lowest level, in lumens?'),
- #(int, 'pwm_max', 255, 'Highest PWM level:'),
+ #(int, 'pwm_max', max_pwm, 'Highest PWM level:'),
(float, 'lm_max', 1000, 'How bright is the highest level, in lumens?'),
]
@@ -48,7 +50,7 @@ def main(args):
if not args:
print('===== Channel %s =====' % (chan_num+1))
chan = Empty()
- chan.pwm_max = 255
+ chan.pwm_max = max_pwm
ask(questions_per_channel, chan)
chan.type = chan.type.upper()
if chan.type not in ('7135', 'FET'):
@@ -160,7 +162,7 @@ def multi_pwm(answers, channels):
and (channel.modes[i] >= channel.modes[i-1]) \
and (channels[cnum+1].modes[i] == 0):
i += 1
- print('Ch%i max: %i (%.2f/255)' % (cnum, i, channel.modes[i-1]))
+ print('Ch%i max: %i (%.2f/%s)' % (cnum, i, channel.modes[i-1], max_pwm))
def get_value(text, default, args):
diff --git a/hwdef-BLF_GT.h b/hwdef-BLF_GT.h
index 01dbdbd..dd8d80a 100644
--- a/hwdef-BLF_GT.h
+++ b/hwdef-BLF_GT.h
@@ -34,7 +34,9 @@
#ifndef VOLTAGE_PIN
#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
#define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2
-#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
+#define VOLTAGE_ADC ADC1D // Digital input disable bit corresponding with PB2
+// inherited from tk-attiny.h
+//#define VOLTAGE_ADC_DIDR DIDR0 // DIDR for ADC1
// 1.1V reference, left-adjust, ADC1/PB2
//#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL)
// 1.1V reference, no left-adjust, ADC1/PB2
diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h
new file mode 100644
index 0000000..856643b
--- /dev/null
+++ b/hwdef-Emisar_D1Sv2.h
@@ -0,0 +1,133 @@
+#ifndef HWDEF_EMISAR_D1SV2_H
+#define HWDEF_EMISAR_D1SV2_H
+
+/* Emisar D1Sv2 driver layout (attiny1634)
+ *
+ * Pin / Name / Function
+ * 1 PA6 (none) (PWM1B) (reserved for DD drivers)
+ * 2 PA5 R: red aux LED (PWM0B)
+ * 3 PA4 G: green aux LED
+ * 4 PA3 B: blue aux LED
+ * 5 PA2 (none) (reserved for L: button LED (on some models))
+ * 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 (PWM1A)
+ * 17 PB2 MISO
+ * 18 PB1 MOSI / battery voltage (ADC6)
+ * 19 PB0 Opamp power
+ * 20 PA7 e-switch (PCINT7)
+ * ADC12 thermal sensor
+ *
+ * Main LED power uses one pin to turn the Opamp on/off,
+ * and one pin to control Opamp power level.
+ * All 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.
+ */
+
+#ifdef ATTINY
+#undef ATTINY
+#endif
+#define ATTINY 1634
+#include <avr/io.h>
+
+#define PWM_CHANNELS 1
+#define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz
+#define PWM_TOP 1023
+
+#define SWITCH_PIN PA7 // pin 20
+#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt
+#define SWITCH_PCIE PCIE0 // PCIE0 is for PCINT[7:0]
+#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0]
+#define SWITCH_PORT PINA // PINA or PINB or PINC
+
+#define PWM1_PIN PB3 // pin 16, Opamp reference
+#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3
+
+#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 0x06 // clk/64
+
+// Raw ADC readings at 4.4V and 2.2V
+// calibrate the voltage readout here
+// estimated / calculated values are:
+// (voltage - D1) * (R2/(R2+R1) * 256 / 1.1)
+// D1, R1, R2 = 0, 330, 100
+#ifndef ADC_44
+#define ADC_44 235
+#endif
+#ifndef ADC_22
+#define ADC_22 116
+#endif
+
+#define TEMP_CHANNEL 0b00001111
+
+// 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
+
+// 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);
+ // aux R/G/B
+ DDRA = (1 << AUXLED_R_PIN)
+ | (1 << AUXLED_G_PIN)
+ | (1 << AUXLED_B_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]: 0,0: PWM OC1B disabled (DS table 12-4)
+ TCCR1A = (1<<WGM11) | (1<<WGM10) // 10-bit (TOP=0x03FF) (DS table 12-5)
+ | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4)
+ | (0<<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)
+ | (0<<WGM13) | (0<<WGM12) // phase-correct PWM (DS table 12-5)
+ ;
+
+ // set up e-switch
+ //PORTA = (1 << SWITCH_PIN); // TODO: configure PORTA / PORTB / PORTC?
+ PUEA = (1 << SWITCH_PIN); // pull-up for e-switch
+ SWITCH_PCMSK = (1 << SWITCH_PCINT); // enable pin change interrupt
+}
+
+#define LAYOUT_DEFINED
+
+#endif
diff --git a/hwdef-Mateminco_MF01S.h b/hwdef-Mateminco_MF01S.h
index ab1c5bf..ad6194c 100644
--- a/hwdef-Mateminco_MF01S.h
+++ b/hwdef-Mateminco_MF01S.h
@@ -34,7 +34,9 @@
#ifndef VOLTAGE_PIN
#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
#define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2
-#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
+#define VOLTAGE_ADC ADC1D // Digital input disable bit corresponding with PB2
+// inherited from tk-attiny.h
+//#define VOLTAGE_ADC_DIDR DIDR0 // DIDR for ADC1
// 1.1V reference, left-adjust, ADC1/PB2
//#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL)
// 1.1V reference, no left-adjust, ADC1/PB2
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 48f4ac1..359681f 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -91,6 +91,10 @@
//#define USE_POLICE_STROBE_MODE
//#define USE_SOS_MODE
+// 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)
@@ -130,7 +134,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
@@ -308,7 +311,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
@@ -320,6 +325,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
@@ -668,6 +682,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;
@@ -678,6 +693,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;
}
@@ -1255,8 +1271,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
@@ -1748,6 +1768,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;
@@ -1759,6 +1780,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;
}
@@ -1942,6 +1964,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
}
}
@@ -2277,6 +2302,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
+ // 0, 3, // 3, G+B // skip; looks too similar to R+G+B
+ 38, 4, // 4, B
+ 40, 5, // 5, R + B
+ 42, 6, // 6, R+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
@@ -2296,36 +2342,31 @@ 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
- if (0 == (arg & 0x03)) {
+ uint8_t speed = 0x03; // awake speed
+ if (go_to_standby) speed = 0x0f; // asleep speed
+ 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));
}
}
@@ -2349,6 +2390,12 @@ void rgb_led_update(uint8_t mode, uint8_t arg) {
break;
}
}
+
+void rgb_led_voltage_readout(uint8_t bright) {
+ uint8_t color = voltage_to_rgb();
+ if (bright) color = color << 1;
+ rgb_led_set(color);
+}
#endif
@@ -2586,6 +2633,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-emisar-d1sv2.h b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h
new file mode 100644
index 0000000..33b240d
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h
@@ -0,0 +1,61 @@
+// Emisar D1S v2 config options for Anduril
+#include "hwdef-Emisar_D1Sv2.h"
+// ATTINY: 1634
+
+// 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
+
+// optional, makes initial turbo step-down faster so first peak isn't as hot
+// the D4 runs very very hot, so be extra careful
+//#define THERM_HARD_TURBO_DROP
+
+// stop panicking at ~70% power or ~900 lm
+#define THERM_FASTER_LEVEL 130
+// respond to thermal changes faster
+#define THERMAL_WARNING_SECONDS 3
+#define THERMAL_UPDATE_SPEED 1
+#define THERM_PREDICTION_STRENGTH 4
+
+// easier access to thermal config mode, for Emisar
+#define USE_TENCLICK_THERMAL_CONFIG
+
+// slow down party strobe; this driver can't pulse for 1ms or less
+#define PARTY_STROBE_ONTIME 2
+
+#define THERM_CAL_OFFSET 5
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index 6832e32..a5507a9 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -69,10 +69,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
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index efa07e4..7bee07e 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -65,13 +65,22 @@ 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
// 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
@@ -104,16 +113,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
@@ -137,43 +146,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);
diff --git a/tk-attiny.h b/tk-attiny.h
index 597af4d..76c9c9b 100644
--- a/tk-attiny.h
+++ b/tk-attiny.h
@@ -34,6 +34,7 @@
#define ADMUX_VCC 0b00001100
#define DELAY_ZERO_TIME 252
#define SWITCH_PORT PINB // PINA or PINB or PINC
+ #define VOLTAGE_ADC_DIDR DIDR0 // this MCU only has one DIDR
#elif (ATTINY == 25)
// TODO: Use 6.4 MHz instead of 8 MHz?
#define F_CPU 8000000UL
@@ -44,6 +45,7 @@
#define ADMUX_THERM 0b10001111
#define DELAY_ZERO_TIME 1020
#define SWITCH_PORT PINB // PINA or PINB or PINC
+ #define VOLTAGE_ADC_DIDR DIDR0 // this MCU only has one DIDR
#elif (ATTINY == 85)
// TODO: Use 6.4 MHz instead of 8 MHz?
#define F_CPU 8000000UL
@@ -56,6 +58,7 @@
#define ADMUX_THERM 0b10001111
#define DELAY_ZERO_TIME 1020
#define SWITCH_PORT PINB // PINA or PINB or PINC
+ #define VOLTAGE_ADC_DIDR DIDR0 // this MCU only has one DIDR
#elif (ATTINY == 1634)
#define F_CPU 8000000UL
#define V_REF REFS1
@@ -66,6 +69,7 @@
#define ADMUX_THERM 0b10001110
#define DELAY_ZERO_TIME 1020
//#define SWITCH_PORT PINA // set this in hwdef
+ //#define VOLTAGE_ADC_DIDR DIDR0 // set this in hwdef
#else
#error Hey, you need to define ATTINY.
#endif