From 5f6bb2bda2dd4eccbdfba94e5d35cedc8c0c42dc Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 25 Apr 2023 01:07:15 -0600 Subject: updated D4Sv2-tintramp -> Emisar 2-channel build target ... ... and reworked how gradual_tick() works ... and updated LT1S Pro to use new method --- hwdef-Sofirn_LT1S-Pro.c | 99 +++++-------- hwdef-Sofirn_LT1S-Pro.h | 10 +- hwdef-emisar-2ch.c | 161 +++++++++++++++++++++ hwdef-emisar-2ch.h | 222 +++++++++++++++++++++++++++++ spaghetti-monster/anduril/cfg-emisar-2ch.h | 114 +++++++++++++++ spaghetti-monster/fsm-ramping.c | 13 +- spaghetti-monster/fsm-ramping.h | 13 +- tk.h | 8 ++ 8 files changed, 555 insertions(+), 85 deletions(-) create mode 100644 hwdef-emisar-2ch.c create mode 100644 hwdef-emisar-2ch.h create mode 100644 spaghetti-monster/anduril/cfg-emisar-2ch.h diff --git a/hwdef-Sofirn_LT1S-Pro.c b/hwdef-Sofirn_LT1S-Pro.c index dd93f93..f5af65a 100644 --- a/hwdef-Sofirn_LT1S-Pro.c +++ b/hwdef-Sofirn_LT1S-Pro.c @@ -155,24 +155,28 @@ void set_level_red_white_blend(uint8_t level) { ///// "gradual tick" functions for smooth thermal regulation ///// -void gradual_tick_red() { - GRADUAL_TICK_SETUP(); - - GRADUAL_ADJUST_1CH(pwm1_levels, RED_PWM_LVL); +///// bump each channel toward a target value ///// +bool gradual_adjust(uint16_t red, uint16_t warm, uint16_t cool) { + GRADUAL_ADJUST_SIMPLE(red, RED_PWM_LVL ); + GRADUAL_ADJUST_SIMPLE(warm, WARM_PWM_LVL); + GRADUAL_ADJUST_SIMPLE(cool, COOL_PWM_LVL); - if ((RED_PWM_LVL == PWM_GET(pwm1_levels, gt))) - { - GRADUAL_IS_ACTUAL(); + // check for completion + if ((red == RED_PWM_LVL ) + && (warm == WARM_PWM_LVL) + && (cool == COOL_PWM_LVL)) { + return true; // done } + return false; // not done yet } +bool gradual_tick_red(uint8_t gt) { + uint16_t red = PWM_GET(pwm1_levels, gt); + return gradual_adjust(red, 0, 0); +} -void gradual_tick_white_blend() { - uint8_t gt = gradual_target; - if (gt < actual_level) gt = actual_level - 1; - else if (gt > actual_level) gt = actual_level + 1; - gt --; +bool gradual_tick_white_blend(uint8_t gt) { // figure out what exact PWM levels we're aiming for PWM_DATATYPE warm_PWM, cool_PWM; PWM_DATATYPE brightness = PWM_GET(pwm1_levels, gt); @@ -181,27 +185,12 @@ void gradual_tick_white_blend() { calc_2ch_blend(&warm_PWM, &cool_PWM, brightness, top, blend); - // move up/down if necessary - GRADUAL_ADJUST_SIMPLE(warm_PWM, WARM_PWM_LVL); - GRADUAL_ADJUST_SIMPLE(cool_PWM, COOL_PWM_LVL); - - // check for completion - if ( (WARM_PWM_LVL == warm_PWM) - && (COOL_PWM_LVL == cool_PWM) - ) - { - GRADUAL_IS_ACTUAL(); - } + return gradual_adjust(0, warm_PWM, cool_PWM); } // same as white blend, but tint is calculated from the ramp level -void gradual_tick_auto_2ch_blend() { - uint8_t gt = gradual_target; - if (gt < actual_level) gt = actual_level - 1; - else if (gt > actual_level) gt = actual_level + 1; - gt --; - +bool gradual_tick_auto_2ch_blend(uint8_t gt) { // figure out what exact PWM levels we're aiming for PWM_DATATYPE warm_PWM, cool_PWM; PWM_DATATYPE brightness = PWM_GET(pwm1_levels, gt); @@ -210,53 +199,29 @@ void gradual_tick_auto_2ch_blend() { calc_2ch_blend(&warm_PWM, &cool_PWM, brightness, top, blend); - // move up/down if necessary - GRADUAL_ADJUST_SIMPLE(warm_PWM, WARM_PWM_LVL); - GRADUAL_ADJUST_SIMPLE(cool_PWM, COOL_PWM_LVL); - - // check for completion - if ( (WARM_PWM_LVL == warm_PWM) - && (COOL_PWM_LVL == cool_PWM) - ) - { - GRADUAL_IS_ACTUAL(); - } + return gradual_adjust(0, warm_PWM, cool_PWM); } -void gradual_tick_auto_3ch_blend() { - uint8_t gt = gradual_target; - if (gt < actual_level) gt = actual_level - 1; - else if (gt > actual_level) gt = actual_level + 1; - gt --; - +bool gradual_tick_auto_3ch_blend(uint8_t gt) { // figure out what exact PWM levels we're aiming for PWM_DATATYPE red, warm, cool; calc_auto_3ch_blend(&red, &warm, &cool, gt); + return gradual_adjust(red, warm, cool); +} - // move up/down if necessary - GRADUAL_ADJUST_SIMPLE(red, RED_PWM_LVL); - GRADUAL_ADJUST_SIMPLE(warm, WARM_PWM_LVL); - GRADUAL_ADJUST_SIMPLE(cool, COOL_PWM_LVL); - // check for completion - if ( (RED_PWM_LVL == red) - && (WARM_PWM_LVL == warm) - && (COOL_PWM_LVL == cool) - ) - { - GRADUAL_IS_ACTUAL(); - } -} +bool gradual_tick_red_white_blend(uint8_t gt) { + // figure out what exact PWM levels we're aiming for + PWM_DATATYPE red, warm, cool; + PWM_DATATYPE brightness = PWM_GET(pwm1_levels, gt); + PWM_DATATYPE top = PWM_GET(pwm_tops, gt); + uint8_t blend = cfg.channel_mode_args[CM_WHITE]; + uint8_t ratio = cfg.channel_mode_args[cfg.channel_mode]; + red = (((PWM_DATATYPE2)ratio * (PWM_DATATYPE2)brightness) + 127) / 255; + calc_2ch_blend(&warm, &cool, brightness, top, blend); -void gradual_tick_red_white_blend() { - // do the white blend thing... - cfg.channel_mode = CM_WHITE; - gradual_tick_white_blend(); - cfg.channel_mode = CM_WHITE_RED; - // ... and then update red to the closest ramp level - // (coarse red adjustments aren't visible here anyway) - set_level_red(actual_level); + return gradual_adjust(red, warm, cool); } diff --git a/hwdef-Sofirn_LT1S-Pro.h b/hwdef-Sofirn_LT1S-Pro.h index af0e6f0..a63f906 100644 --- a/hwdef-Sofirn_LT1S-Pro.h +++ b/hwdef-Sofirn_LT1S-Pro.h @@ -115,11 +115,11 @@ void set_level_auto_2ch_blend(uint8_t level); void set_level_auto_3ch_blend(uint8_t level); void set_level_red_white_blend(uint8_t level); -void gradual_tick_red(); -void gradual_tick_white_blend(); -void gradual_tick_auto_2ch_blend(); -void gradual_tick_auto_3ch_blend(); -void gradual_tick_red_white_blend(); +bool gradual_tick_red(uint8_t gt); +bool gradual_tick_white_blend(uint8_t gt); +bool gradual_tick_auto_2ch_blend(uint8_t gt); +bool gradual_tick_auto_3ch_blend(uint8_t gt); +bool gradual_tick_red_white_blend(uint8_t gt); inline void hwdef_setup() { diff --git a/hwdef-emisar-2ch.c b/hwdef-emisar-2ch.c new file mode 100644 index 0000000..53117e0 --- /dev/null +++ b/hwdef-emisar-2ch.c @@ -0,0 +1,161 @@ +// Emisar 2-channel generic w/ tint ramping +// Copyright (C) 2021-2023 Selene ToyKeeper +// SPDX-License-Identifier: GPL-3.0-or-later +#pragma once + +// set new values for both channels, +// handling any possible combination +// and any before/after state +void set_pwms(uint16_t ch1_pwm, uint16_t ch2_pwm, uint16_t top) { + bool was_on = (CH1_PWM>0) | (CH2_PWM>0); + bool now_on = (ch1_pwm>0) | (ch2_pwm>0); + + if (! now_on) { + CH1_PWM = 0; + CH2_PWM = 0; + PWM_TOP = PWM_TOP_INIT; + PWM_CNT = 0; + CH1_ENABLE_PORT &= ~(1 << CH1_ENABLE_PIN); // disable opamp + CH2_ENABLE_PORT &= ~(1 << CH2_ENABLE_PIN); // disable opamp + return; + } + + if (ch1_pwm) + CH1_ENABLE_PORT |= (1 << CH1_ENABLE_PIN); // enable opamp + else + CH1_ENABLE_PORT &= ~(1 << CH1_ENABLE_PIN); // disable opamp + + if (ch2_pwm) + CH2_ENABLE_PORT |= (1 << CH2_ENABLE_PIN); // enable opamp + else + CH2_ENABLE_PORT &= ~(1 << CH2_ENABLE_PIN); // disable opamp + + CH1_PWM = ch1_pwm; + CH2_PWM = ch2_pwm; + + // manual phase sync when changing level while already on + if (was_on && now_on) while(PWM_CNT > (top - 32)) {} + + PWM_TOP = top; + + // reset phase when turning on or off + //if ((! was_on) | (! now_on)) PWM_CNT = 0; + if (! was_on) PWM_CNT = 0; +} + +void set_level_ch1(uint8_t level) { + if (0 == level) + return set_pwms(0, 0, PWM_TOP_INIT); + + level --; + uint16_t pwm = PWM_GET(pwm1_levels, level); + uint16_t top = PWM_GET(pwm_tops, level); + set_pwms(pwm, 0, top); +} + +void set_level_ch2(uint8_t level) { + if (0 == level) + return set_pwms(0, 0, PWM_TOP_INIT); + + level --; + uint16_t pwm = PWM_GET(pwm1_levels, level); + uint16_t top = PWM_GET(pwm_tops, level); + set_pwms(0, pwm, top); +} + +void set_level_both(uint8_t level) { + if (0 == level) + return set_pwms(0, 0, PWM_TOP_INIT); + + level --; + uint16_t pwm = PWM_GET(pwm1_levels, level); + uint16_t top = PWM_GET(pwm_tops, level); + set_pwms(pwm, pwm, top); +} + +void set_level_blend(uint8_t level) { + if (0 == level) + return set_pwms(0, 0, PWM_TOP_INIT); + + level --; + PWM_DATATYPE ch1_pwm, ch2_pwm; + PWM_DATATYPE brightness = PWM_GET(pwm1_levels, level); + PWM_DATATYPE top = PWM_GET(pwm_tops, level); + uint8_t blend = cfg.channel_mode_args[cfg.channel_mode]; + + calc_2ch_blend(&ch1_pwm, &ch2_pwm, brightness, top, blend); + + set_pwms(ch1_pwm, ch2_pwm, top); +} + +void set_level_auto(uint8_t level) { + if (0 == level) + return set_pwms(0, 0, PWM_TOP_INIT); + + level --; + PWM_DATATYPE ch1_pwm, ch2_pwm; + PWM_DATATYPE brightness = PWM_GET(pwm1_levels, level); + PWM_DATATYPE top = PWM_GET(pwm_tops, level); + uint8_t blend = 255 * (uint16_t)level / RAMP_SIZE; + if (cfg.channel_mode_args[cfg.channel_mode] & 0b01000000) + blend = 255 - blend; + + calc_2ch_blend(&ch1_pwm, &ch2_pwm, brightness, top, blend); + + set_pwms(ch1_pwm, ch2_pwm, top); +} + + +///// bump each channel toward a target value ///// +bool gradual_adjust(uint16_t ch1_pwm, uint16_t ch2_pwm) { + GRADUAL_ADJUST_SIMPLE(ch1_pwm, CH1_PWM); + GRADUAL_ADJUST_SIMPLE(ch2_pwm, CH2_PWM); + + // check for completion + if ((ch1_pwm == CH1_PWM) + && (ch2_pwm == CH2_PWM)) { + return true; // done + } + return false; // not done yet +} + +bool gradual_tick_ch1(uint8_t gt) { + uint16_t pwm = PWM_GET(pwm1_levels, gt); + return gradual_adjust(pwm, 0); +} + +bool gradual_tick_ch2(uint8_t gt) { + uint16_t pwm = PWM_GET(pwm1_levels, gt); + return gradual_adjust(0, pwm); +} + +bool gradual_tick_both(uint8_t gt) { + uint16_t pwm = PWM_GET(pwm1_levels, gt); + return gradual_adjust(pwm, pwm); +} + +bool gradual_tick_blend(uint8_t gt) { + PWM_DATATYPE ch1_pwm, ch2_pwm; + PWM_DATATYPE brightness = PWM_GET(pwm1_levels, gt); + PWM_DATATYPE top = PWM_GET(pwm_tops, gt); + uint8_t blend = cfg.channel_mode_args[cfg.channel_mode]; + + calc_2ch_blend(&ch1_pwm, &ch2_pwm, brightness, top, blend); + + return gradual_adjust(ch1_pwm, ch2_pwm); +} + +bool gradual_tick_auto(uint8_t gt) { + PWM_DATATYPE ch1_pwm, ch2_pwm; + PWM_DATATYPE brightness = PWM_GET(pwm1_levels, gt); + PWM_DATATYPE top = PWM_GET(pwm_tops, gt); + uint8_t blend = 255 * (uint16_t)gt / RAMP_SIZE; + if (cfg.channel_mode_args[cfg.channel_mode] & 0b01000000) + blend = 255 - blend; + + calc_2ch_blend(&ch1_pwm, &ch2_pwm, brightness, top, blend); + + return gradual_adjust(ch1_pwm, ch2_pwm); +} + + diff --git a/hwdef-emisar-2ch.h b/hwdef-emisar-2ch.h new file mode 100644 index 0000000..8b0ffc0 --- /dev/null +++ b/hwdef-emisar-2ch.h @@ -0,0 +1,222 @@ +// Emisar 2-channel generic w/ tint ramping +// Copyright (C) 2021-2023 Selene ToyKeeper +// SPDX-License-Identifier: GPL-3.0-or-later +#pragma once + +/* + * Pin / Name / Function + * 1 PA6 ch2 LED PWM (linear) (PWM1B) + * 2 PA5 R: red aux LED (PWM0B) + * 3 PA4 G: green aux LED + * 4 PA3 B: blue aux LED + * 5 PA2 button LED + * 6 PA1 Opamp 2 enable (channel 2 LEDs) + * 7 PA0 Opamp 1 enable (channel 1 LEDs) + * 8 GND GND + * 9 VCC VCC + * 10 PC5 (none) + * 11 PC4 (none) + * 12 PC3 RESET + * 13 PC2 (none) + * 14 PC1 SCK + * 15 PC0 [unused: ch1 LED PWM (FET) (PWM0A, 8-bit)] + * 16 PB3 ch1 LED PWM (linear) (PWM1A) + * 17 PB2 MISO + * 18 PB1 MOSI / battery voltage (ADC6) + * 19 PB0 (none) + * 20 PA7 e-switch (PCINT7) + * ADC12 thermal sensor + */ + +#define HWDEF_C_FILE hwdef-emisar-2ch.c + +#define ATTINY 1634 +#include + +// channel modes: +// * 0. channel 1 only +// * 1. channel 2 only +// * 2. both channels, tied together +// * 3. both channels, manual blend, max 200% power? +// * 4. both channels, auto blend, reversible +#define NUM_CHANNEL_MODES 5 +#define CM_CH1 0 +#define CM_CH2 1 +#define CM_BOTH 2 +#define CM_BLEND 3 +#define CM_AUTO 4 + +#define CHANNEL_MODES_ENABLED 0b00011111 +#define CHANNEL_HAS_ARGS 0b00011000 +// _, _, _, 128=middle CCT, 0=warm-to-cool +#define CHANNEL_MODE_ARGS 0,0,0,128,0 + +#define USE_CHANNEL_MODES +#define USE_CHANNEL_MODE_ARGS +#define SET_LEVEL_MODES set_level_ch1, \ + set_level_ch2, \ + set_level_both, \ + set_level_blend, \ + set_level_auto +// gradual ticking for thermal regulation +#define GRADUAL_TICK_MODES gradual_tick_ch1, \ + gradual_tick_ch2, \ + gradual_tick_both, \ + gradual_tick_blend, \ + gradual_tick_auto +// can use some of the common handlers +#define USE_CALC_2CH_BLEND + + +#define PWM_CHANNELS 1 // old, remove this + +#define PWM_BITS 16 // 0 to 16383 at variable Hz, not 0 to 255 at 16 kHz +#define PWM_GET PWM_GET16 +#define PWM_DATATYPE uint16_t +#define PWM_DATATYPE2 uint32_t // only needs 32-bit if ramp values go over 255 +#define PWM1_DATATYPE uint16_t // regular ramp table +#define PWM2_DATATYPE uint16_t // max "200% power" ramp table +//#define PWM3_DATATYPE uint8_t // DD FET ramp table (8-bit only) + +// PWM parameters of both channels are tied together because they share a counter +#define PWM_TOP ICR1 // holds the TOP value for for variable-resolution PWM +#define PWM_TOP_INIT 511 +#define PWM_CNT TCNT1 // for dynamic PWM, reset phase + +#define CH1_PIN PB3 // pin 16, Opamp reference +#define CH1_PWM OCR1A // OCR1A is the output compare register for PB3 +#define CH1_ENABLE_PIN PA0 // pin 7, Opamp power +#define CH1_ENABLE_PORT PORTA // control port for PA0 + +#define CH2_PIN PA6 // pin 1, 2nd LED Opamp reference +#define CH2_PWM OCR1B // OCR1B is the output compare register for PA6 +#define CH2_ENABLE_PIN PA1 // pin 6, Opamp power +#define CH2_ENABLE_PORT PORTA // control port for PA1 + +//#define CH3_PIN PC0 // pin 15, DD FET PWM +//#define CH3_LVL OCR0A // OCR0A is the output compare register for PC0 + + +#ifndef SWITCH_PIN +#define SWITCH_PIN PA7 // pin 20 +#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt +#define SWITCH_PCIE PCIE0 // PCIE1 is for PCINT[7:0] +#define SWITCH_PCMSK PCMSK0 // PCMSK1 is for PCINT[7:0] +#define SWITCH_PORT PINA // PINA or PINB or PINC +#define SWITCH_PUE PUEA // pullup group A +#define PCINT_vect PCINT0_vect // ISR for PCINT[7:0] +#endif + +#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 0x07 // clk/128 + +// Raw ADC readings at 4.4V and 2.2V +// calibrate the voltage readout here +// estimated / calculated values are: +// (voltage - D1) * (R2/(R2+R1) * 1024 / 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 + +// 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 + +#define BUTTON_LED_PIN PA2 // pin 5 +#define BUTTON_LED_PORT PORTA // for all "PA" pins +#define BUTTON_LED_DDR DDRA // for all "PA" pins +#define BUTTON_LED_PUE PUEA // for all "PA" pins + + +void set_level_ch1(uint8_t level); +void set_level_ch2(uint8_t level); +void set_level_both(uint8_t level); +void set_level_blend(uint8_t level); +void set_level_auto(uint8_t level); + +bool gradual_tick_ch1(uint8_t gt); +bool gradual_tick_ch2(uint8_t gt); +bool gradual_tick_both(uint8_t gt); +bool gradual_tick_blend(uint8_t gt); +bool gradual_tick_auto(uint8_t gt); + + +// 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 + //DDRC = (1 << CH3_PIN); + DDRB = (1 << CH1_PIN); + DDRA = (1 << CH2_PIN) + | (1 << AUXLED_R_PIN) + | (1 << AUXLED_G_PIN) + | (1 << AUXLED_B_PIN) + | (1 << BUTTON_LED_PIN) + | (1 << CH1_ENABLE_PIN) + | (1 << CH2_ENABLE_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 + // Linear opamp PWM for both main and 2nd LEDs (10-bit) + // WGM1[3:0]: 1,0,1,0: PWM, Phase Correct, adjustable (DS table 12-5) + // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6) + // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4) + // COM1B[1:0]: 1,0: PWM OC1B in the normal direction (DS table 12-4) + TCCR1A = (1< actual_level) gt = actual_level + 1; + gt --; + // call the relevant hardware-specific function GradualTickFuncPtr gradual_tick_func = gradual_tick_modes[CH_MODE]; - gradual_tick_func(); + bool done = gradual_tick_func(gt); + + if (done) { + uint8_t orig = gradual_target; + set_level(gt + 1); + gradual_target = orig; + } } diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index a9e333e..7b3722d 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -32,7 +32,7 @@ SetLevelFuncPtr channel_modes[NUM_CHANNEL_MODES]; #ifdef USE_SET_LEVEL_GRADUALLY // the gradual tick mechanism may be different per channel -typedef void GradualTickFunc(); +typedef bool GradualTickFunc(uint8_t gt); typedef GradualTickFunc * GradualTickFuncPtr; // TODO: move to progmem GradualTickFuncPtr gradual_tick_modes[NUM_CHANNEL_MODES]; @@ -101,12 +101,7 @@ inline void set_level_gradually(uint8_t lvl); void gradual_tick(); // reduce repetition with macros -// common code at the beginning of every gradual tick handler #define GRADUAL_TICK_SETUP() \ - uint8_t gt = gradual_target; \ - if (gt < actual_level) gt = actual_level - 1; \ - else if (gt > actual_level) gt = actual_level + 1; \ - gt --; \ PWM_DATATYPE target; // tick to a specific value @@ -132,12 +127,6 @@ void gradual_tick(); if (PWM < target) PWM ++; \ else if (PWM > target) PWM --; -// do this when output exactly matches a ramp level -#define GRADUAL_IS_ACTUAL() \ - uint8_t orig = gradual_target; \ - set_level(gt + 1); \ - gradual_target = orig; - #endif // ifdef USE_SET_LEVEL_GRADUALLY // auto-detect the data type for PWM tables diff --git a/tk.h b/tk.h index d618134..785808d 100644 --- a/tk.h +++ b/tk.h @@ -9,6 +9,14 @@ // but which don't need to be repeated in every source file //// +// AVR GCC has no boolean type by default +// (this isn't native bool, but it's mostly okay) +#define bool uint8_t +#define false 0 +#define true 1 +#define FALSE 0 +#define TRUE 1 + // create a way to include files defined at the command line, // like with "gcc -DCONFIGFILE=foo.h" #define incfile2(s) #s -- cgit v1.2.3