diff options
| -rwxr-xr-x | bin/level_calc.py | 8 | ||||
| -rw-r--r-- | hwdef-BLF_GT.h | 8 | ||||
| -rw-r--r-- | hwdef-Mateminco_MF01S.h | 8 | ||||
| -rw-r--r-- | hwdef-Noctigon_K1.h | 136 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 90 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-noctigon-k1.h | 58 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-adc.c | 8 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 39 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.h | 64 | ||||
| -rw-r--r-- | tk-attiny.h | 4 |
10 files changed, 354 insertions, 69 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 f0ac103..99adc8f 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 @@ -44,10 +46,10 @@ // 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 +#define ADC_44 (184*4) #endif #ifndef ADC_22 -#define ADC_22 92 +#define ADC_22 (92*4) #endif #define TEMP_CHANNEL 0b00001111 diff --git a/hwdef-Mateminco_MF01S.h b/hwdef-Mateminco_MF01S.h index b89408f..cb5a416 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 @@ -44,10 +46,10 @@ // Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line) #ifndef ADC_44 -#define ADC_44 234 +#define ADC_44 (234*4) #endif #ifndef ADC_22 -#define ADC_22 117 +#define ADC_22 (117*4) #endif #define TEMP_CHANNEL 0b00001111 diff --git a/hwdef-Noctigon_K1.h b/hwdef-Noctigon_K1.h new file mode 100644 index 0000000..031bec0 --- /dev/null +++ b/hwdef-Noctigon_K1.h @@ -0,0 +1,136 @@ +#ifndef HWDEF_NOCTIGON_K1_H +#define HWDEF_NOCTIGON_K1_H + +/* Noctigon K1 driver layout (attiny1634) + * (originally known as Emisar D1S V2) + * + * 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 981 // raw value at 4.40V +#define ADC_44 967 // manually tweaked so 4.16V will blink out 4.2 +#endif +#ifndef ADC_22 +//#define ADC_22 489 // raw value at 2.20V +#define ADC_22 482 // manually tweaked so 4.16V will blink out 4.2 +#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/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); 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 |
