diff options
| author | Selene ToyKeeper | 2023-04-13 20:38:25 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2023-04-13 20:38:25 -0600 |
| commit | 55541be4a505da3df7d1a2b8bf3b5295b0af58f7 (patch) | |
| tree | fc1e7f22ffe1c51087117b28766ff266895228e3 /hw | |
| parent | merging gchart's changes, part 1... (diff) | |
| download | anduril-55541be4a505da3df7d1a2b8bf3b5295b0af58f7.tar.gz anduril-55541be4a505da3df7d1a2b8bf3b5295b0af58f7.tar.bz2 anduril-55541be4a505da3df7d1a2b8bf3b5295b0af58f7.zip | |
refactor progress checkpoint ... got Sofirn LT1S Pro and Emisar D4v2 working
with the new channel mode system ... but there's a lot more left to do
Diffstat (limited to '')
| -rw-r--r-- | hwdef-Emisar_D4v2.h | 97 | ||||
| -rw-r--r-- | hwdef-Sofirn_LT1S-Pro.c | 67 | ||||
| -rw-r--r-- | hwdef-Sofirn_LT1S-Pro.h | 109 |
3 files changed, 208 insertions, 65 deletions
diff --git a/hwdef-Emisar_D4v2.h b/hwdef-Emisar_D4v2.h index e118ed5..51e30f8 100644 --- a/hwdef-Emisar_D4v2.h +++ b/hwdef-Emisar_D4v2.h @@ -1,7 +1,8 @@ -#ifndef HWDEF_EMISAR_D4V2_H -#define HWDEF_EMISAR_D4V2_H +#pragma once -/* Emisar D4v2 driver layout (attiny1634) +/* hwdef for Emisar D4v2 (attiny1634) + * Copyright (C) 2019 Selene ToyKeeper + * SPDX-License-Identifier: GPL-3.0-or-later * * Pin / Name / Function * 1 PA6 FET PWM (PWM1B) @@ -33,6 +34,16 @@ #define ATTINY 1634 #include <avr/io.h> +// TODO: add aux red and aux blue as disabled channel modes, +// so they can be used for the police strobe? +#define NUM_CHANNEL_MODES 1 +#define DEFAULT_CHANNEL_MODE 0 +#define SET_LEVEL_MODES set_level_2ch_stacked +#define GRADUAL_TICK_MODES gradual_tick_2ch_stacked +// no special handlers needed, can use common handlers +#define USE_SET_LEVEL_2CH_STACKED +#define USE_GRADUAL_TICK_2CH_STACKED + #define PWM_CHANNELS 2 #define SWITCH_PIN PA2 // pin 5 @@ -41,12 +52,17 @@ #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, 1x7135 PWM -#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 +#define LOW_PWM_PIN PB3 // pin 16, 1x7135 PWM +#define LOW_PWM_LVL OCR1A // OCR1A is the output compare register for PB3 +#define PWM1_BITS 8 -#define PWM2_PIN PA6 // pin 1, FET PWM -#define PWM2_LVL OCR1B // OCR1B is the output compare register for PB1 +#define HIGH_PWM_PIN PA6 // pin 1, FET PWM +#define HIGH_PWM_LVL OCR1B // OCR1B is the output compare register for PB1 +#define PWM2_BITS 8 +// only using 8-bit on this light +#define PWM_GET PWM_GET8 +#define PWM_DATATYPE uint8_t #define ADC_PRSCL 0x07 // clk/128 @@ -68,37 +84,46 @@ #define BUTTON_LED_DDR DDRA // for all "PA" pins #define BUTTON_LED_PUE PUEA // for all "PA" pins -// with so many pins, doing this all with #ifdefs gets awkward... -// ... so just hardcode it in each hwdef file instead +// this light has three aux LED channels: R, G, B +#define USE_AUX_RGB_LEDS +// it also has an independent LED in the button +#define USE_BUTTON_LED +// the aux LEDs are front-facing, so turn them off while main LEDs are on +// TODO: the whole "indicator LED" thing needs to be refactored into +// "aux LED(s)" and "button LED(s)" since they work a bit differently +#ifdef USE_INDICATOR_LED_WHILE_RAMPING +#undef USE_INDICATOR_LED_WHILE_RAMPING +#endif + inline void hwdef_setup() { - // enable output ports - // 7135 - DDRB = (1 << PWM1_PIN); - // FET, aux R/G/B, button LED - DDRA = (1 << PWM2_PIN) - | (1 << AUXLED_R_PIN) - | (1 << AUXLED_G_PIN) - | (1 << AUXLED_B_PIN) - | (1 << BUTTON_LED_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 - TCCR1A = (0<<WGM11) | (1<<WGM10) // 8-bit (TOP=0xFF) (DS table 12-5) - | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4) - | (1<<COM1B1) | (0<<COM1B0) // PWM 1B in normal direction (DS table 12-4) - ; - TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6) - | (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 + // enable output ports + // 7135 + DDRB = (1 << LOW_PWM_PIN); + // FET, aux R/G/B, button LED + DDRA = (1 << HIGH_PWM_PIN) + | (1 << AUXLED_R_PIN) + | (1 << AUXLED_G_PIN) + | (1 << AUXLED_B_PIN) + | (1 << BUTTON_LED_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 + TCCR1A = (0<<WGM11) | (1<<WGM10) // 8-bit (TOP=0xFF) (DS table 12-5) + | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4) + | (1<<COM1B1) | (0<<COM1B0) // PWM 1B in normal direction (DS table 12-4) + ; + TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6) + | (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-Sofirn_LT1S-Pro.c b/hwdef-Sofirn_LT1S-Pro.c new file mode 100644 index 0000000..3c31c96 --- /dev/null +++ b/hwdef-Sofirn_LT1S-Pro.c @@ -0,0 +1,67 @@ +// BLF LT1S Pro hwdef functions +// Copyright (C) 2023 Selene ToyKeeper +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + + +// "auto tint" channel mode +void set_level_auto_3ch_blend(uint8_t level) { + BLEND_PWM_DATATYPE vpwm; + + if (level == 0) { + vpwm = 0; + } else { + level --; // PWM array index = level - 1 + vpwm = PWM_GET(blend_pwm_levels, level); + } + + // tint goes from 0 (red) to 127 (warm white) to 255 (cool white) + uint8_t mytint; + mytint = 255 * (uint16_t)level / RAMP_SIZE; + + BLEND_PWM_DATATYPE a, b, c; + + // red is high at 0, low at 255 + a = (((PWM_DATATYPE2)(255 - mytint) + * (PWM_DATATYPE2)vpwm) + 127) / 255; + // warm white is low at 0 and 255, high at 127 + b = (((PWM_DATATYPE2)triangle_wave(mytint) + * (PWM_DATATYPE2)vpwm) + 127) / 255; + // cool white is low at 0, high at 255 + c = (((PWM_DATATYPE2)mytint + * (PWM_DATATYPE2)vpwm) + 127) / 255; + + RED_PWM_LVL = a; + WARM_PWM_LVL = b; + COOL_PWM_LVL = c; +} + + +// "white + red" channel mode +void set_level_red_white_blend(uint8_t level) { + // set the warm+cool white LEDs first + channel_mode = CM_WHITE; + set_level_2ch_blend(level); + channel_mode = CM_WHITE_RED; + + BLEND_PWM_DATATYPE vpwm; + + // set the red LED as a ratio of the white output level + if (level == 0) { + vpwm = 0; + } else { + level --; // PWM array index = level - 1 + vpwm = PWM_GET(blend_pwm_levels, level); + } + + // 0 = no red + // 255 = red at 100% of white channel PWM + uint8_t ratio = channel_mode_args[channel_mode]; + + PWM_DATATYPE red_pwm; + red_pwm = (((PWM_DATATYPE2)ratio * (PWM_DATATYPE2)vpwm) + 127) / 255; + + RED_PWM_LVL = red_pwm; +} + diff --git a/hwdef-Sofirn_LT1S-Pro.h b/hwdef-Sofirn_LT1S-Pro.h index ce6ee3a..c52364f 100644 --- a/hwdef-Sofirn_LT1S-Pro.h +++ b/hwdef-Sofirn_LT1S-Pro.h @@ -1,6 +1,3 @@ -#ifndef HWDEF_SOFIRN_LT1S_PRO_H -#define HWDEF_SOFIRN_LT1S_PRO_H - /* BLF LT1S Pro driver layout using the Attiny1616 Driver pinout: @@ -13,8 +10,10 @@ Driver pinout: */ +#pragma once -#define LAYOUT_DEFINED + +#define HWDEF_C_FILE hwdef-Sofirn_LT1S-Pro.c #ifdef ATTINY #undef ATTINY @@ -22,40 +21,85 @@ Driver pinout: #define ATTINY 1616 #include <avr/io.h> +// channel modes: +// * 0. warm/cool white blend +// * 1. auto 3ch blend (red -> warm -> cool by ramp level) +// * 2. red only +// * 3. red + white blend +#define NUM_CHANNEL_MODES 4 +//#define CHANNEL_MODES_ENABLED 1,1,1,1 +#define CHANNEL_MODES_ENABLED 0b00001111 +#define CM_WHITE 0 +#define CM_AUTO 1 +#define CM_RED 2 +#define CM_WHITE_RED 3 + +// TODO: blend mode should enable this automatically? +#define USE_CHANNEL_MODES +// TODO: blend mode should enable this automatically? +#define USE_CHANNEL_MODE_ARGS +// TODO: or maybe if args are defined, the USE_ should be auto-set? +#define CHANNEL_MODE_ARGS 128,0,0,255 +#define SET_LEVEL_MODES set_level_2ch_blend, \ + set_level_auto_3ch_blend, \ + set_level_1ch, \ + set_level_red_white_blend +// TODO: gradual ticking for thermal regulation +#define GRADUAL_TICK_MODES gradual_tick_2ch_blend, \ + gradual_tick_auto_3ch_blend, \ + gradual_tick_1ch, \ + gradual_tick_red_white_blend +// can use some of the common handlers +#define USE_SET_LEVEL_2CH_BLEND +//#define USE_SET_LEVEL_AUTO_3CH_BLEND +#define USE_SET_LEVEL_1CH +//#define USE_SET_LEVEL_RED_WHITE_BLEND +// TODO: +//#define USE_GRADUAL_TICK_2CH_BLEND +//#define USE_GRADUAL_TICK_AUTO_3CH_BLEND +//#define USE_GRADUAL_TICK_1CH +//#define USE_GRADUAL_TICK_RED_WHITE_BLEND + +#define DEFAULT_CHANNEL_MODE CM_AUTO + +#define FACTORY_RESET_WARN_CHANNEL CM_RED +#define FACTORY_RESET_SUCCESS_CHANNEL CM_WHITE + +#define POLICE_COLOR_STROBE_CH1 CM_RED +#define POLICE_COLOR_STROBE_CH2 CM_WHITE + +// TODO: remove this as soon as it's not needed #define PWM_CHANNELS 1 -#ifndef SWITCH_PIN #define SWITCH_PIN PIN5_bp #define SWITCH_PORT VPORTA.IN #define SWITCH_ISC_REG PORTA.PIN2CTRL #define SWITCH_VECT PORTA_PORT_vect #define SWITCH_INTFLG VPORTA.INTFLAGS -#endif - -// usually PWM1_LVL would be a hardware register, but we need to abstract -// it out to a soft brightness value, in order to handle tint ramping -// (this allows smooth thermal regulation to work, and makes things -// otherwise simpler and easier) -uint8_t PWM1_LVL; // warm tint channel -#ifndef PWM1_PIN -#define PWM1_PIN PB0 // -#define TINT1_LVL TCA0.SINGLE.CMP0 // CMP1 is the output compare register for PB0 -#endif +#define WARM_PWM_PIN PB0 +#define WARM_PWM_LVL TCA0.SINGLE.CMP0 // CMP1 is the output compare register for PB0 // cold tint channel -#ifndef PWM2_PIN -#define PWM2_PIN PB1 // -#define TINT2_LVL TCA0.SINGLE.CMP1 // CMP0 is the output compare register for PB1 -#endif +#define COOL_PWM_PIN PB1 +#define COOL_PWM_LVL TCA0.SINGLE.CMP1 // CMP0 is the output compare register for PB1 // red channel -#ifndef PWM3_PIN -#define PWM3_PIN PB0 // -#define PWM3_LVL TCA0.SINGLE.CMP2 // CMP2 is the output compare register for PB2 -#endif +#define RED_PWM_PIN PB0 // +#define RED_PWM_LVL TCA0.SINGLE.CMP2 // CMP2 is the output compare register for PB2 + +// translate cfg names to FSM names +#define LOW_PWM_LEVELS RED_PWM_LEVELS +#define LOW_PWM_LVL RED_PWM_LVL +#define LOW_PWM_PIN RED_PWM_PIN + +// only using 8-bit on this light +#define PWM_GET PWM_GET8 +#define PWM_DATATYPE uint8_t +#define BLEND_PWM_DATATYPE uint8_t + // average drop across diode on this hardware #ifndef VOLTAGE_FUDGE_FACTOR @@ -64,14 +108,20 @@ uint8_t PWM1_LVL; // lighted button -#ifndef AUXLED_PIN #define AUXLED_PIN PIN5_bp #define AUXLED_PORT PORTB -#endif + +// the button lights up +#define USE_INDICATOR_LED +// the button is visible while main LEDs are on +#define USE_INDICATOR_LED_WHILE_RAMPING + + +// custom channel modes +void set_level_auto_3ch_blend(uint8_t level); +void set_level_red_white_blend(uint8_t level); -// with so many pins, doing this all with #ifdefs gets awkward... -// ... so just hardcode it in each hwdef file instead inline void hwdef_setup() { // set up the system clock to run at 10 MHz instead of the default 3.33 MHz @@ -111,4 +161,5 @@ inline void hwdef_setup() { } -#endif +#define LAYOUT_DEFINED + |
