From e9baec681de52ab505e31a4c413ddd41a2ef9458 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 31 May 2018 12:34:59 +0200 Subject: add rgbfade support --- src/system.cc | 196 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 133 insertions(+), 63 deletions(-) (limited to 'src/system.cc') diff --git a/src/system.cc b/src/system.cc index 66b3a53..2cfbda9 100644 --- a/src/system.cc +++ b/src/system.cc @@ -26,6 +26,32 @@ System blinkencat; +#define BIT_WW _BV(PD5) +#define BIT_RED _BV(PB3) +#define BIT_GREEN _BV(PB4) +#define BIT_BLUE _BV(PB2) + +#define PWM_RED OCR1A +#define PWM_GREEN OCR1B +#define PWM_BLUE OCR0A + +/* +const uint8_t pwmtable[32] PROGMEM = { + 0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 16, 19, 23, + 27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215, 255 +}; +*/ + +uint8_t const hsbtable[80] PROGMEM = { + 254, 254, 253, 252, 250, 248, 245, 242, 238, 234, 229, 224, 219, 213, 207, + 201, 194, 188, 181, 174, 167, 160, 153, 146, 139, 133, 126, 119, 113, 106, + 100, 94, 88, 83, 78, 72, 67, 63, 58, 54, 50, 46, 43, 39, 36, 33, 30, 28, 25, + 23, 21, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 2, + 1, 1, 1, 1, 0, 0, 0, 0, 0 +}; + +#define HSBTABLE_LEN 80 + void System::initialize() { @@ -70,76 +96,105 @@ void System::sleep() MCUCR &= ~_BV(SE); } -void System::set_outputs() +void System::loop() { - if (warmwhite) { - PORTD |= _BV(PD5); - } else { - PORTD &= ~_BV(PD5); - } - if (red) { - PORTB |= _BV(PB3); - } else { - PORTB &= ~_BV(PB3); - } - if (green) { - PORTB |= _BV(PB4); - } else { - PORTB &= ~_BV(PB4); + uint8_t anim_step = 0; + if (mode_changed) { + mode_changed = 0; + if (mode == FASTRGB || mode == SLOWRGB) { + PORTD &= ~BIT_WW; + PORTB = 0; + // 8 bit fast PWM on OC0A, OC1A, OC1B + TCCR0A = _BV(COM0A1) | _BV(WGM01) | _BV(WGM00); + TCCR0B = _BV(CS00); + TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10); + TCCR1B = _BV(WGM12) | _BV(CS00); + + // interrupt on Timer 0 overflow + TIMSK = _BV(TOIE0); + } else { + TCCR0A = 0; + TCCR0B = 0; + TCCR1A = 0; + TCCR1B = 0; + TIMSK = 0; + } + switch (mode) { + case OFF: + PORTD &= ~BIT_WW; + PORTB = 0; + break; + case WARMWHITE: + PORTD |= BIT_WW; + break; + case RED: + PORTD &= ~BIT_WW; + PORTB = BIT_RED; + break; + case GREEN: + PORTB = BIT_GREEN; + break; + case BLUE: + PORTB = BIT_BLUE; + break; + case YELLOW: + PORTB = BIT_RED | BIT_GREEN; + break; + case MAGENTA: + PORTB = BIT_RED | BIT_BLUE; + break; + case CYAN: + PORTB = BIT_GREEN | BIT_BLUE; + break; + case SUN: + PORTD |= BIT_WW; + PORTB = BIT_RED | BIT_GREEN | BIT_BLUE; + break; + default: + break; + } } - if (blue) { - PORTB |= _BV(PB2); - } else { - PORTB &= ~_BV(PB2); + + if (mode == FASTRGB) { + anim_step = anim_step_fine; + } else if (mode == SLOWRGB) { + anim_step = anim_step_coarse; } -} -void System::loop() -{ - switch (mode) { - case OFF: - warmwhite = red = green = blue = 0; - break; - case WARMWHITE: - warmwhite = 255; - red = green = blue = 0; - break; - case RED: - red = 255; - warmwhite = green = blue = 0; - break; - case GREEN: - green = 255; - warmwhite = red = blue = 0; - break; - case BLUE: - blue = 255; - warmwhite = red = green = 0; - break; - case YELLOW: - red = green = 255; - warmwhite = blue = 0; - break; - case MAGENTA: - red = blue = 255; - warmwhite = green = 0; - break; - case CYAN: - green = blue = 255; - warmwhite = red = 0; - break; - case SUN: - warmwhite = red = green = blue = 255; - break; - default: - break; + if (mode == FASTRGB || mode == SLOWRGB) { + if (anim_step < HSBTABLE_LEN) { + PWM_RED = pgm_read_byte(&hsbtable[anim_step]); + PWM_GREEN = pgm_read_byte(&hsbtable[HSBTABLE_LEN - 1 - anim_step]); + PWM_BLUE = 0; + } + else if (anim_step < 2*HSBTABLE_LEN) { + PWM_RED = 0; + PWM_GREEN = pgm_read_byte(&hsbtable[anim_step - HSBTABLE_LEN]); + PWM_BLUE = pgm_read_byte(&hsbtable[2*HSBTABLE_LEN - 1 - anim_step]); + } + else if (anim_step < 3*HSBTABLE_LEN) { + PWM_RED = pgm_read_byte(&hsbtable[3*HSBTABLE_LEN - 1 - anim_step]); + PWM_GREEN = 0; + PWM_BLUE = pgm_read_byte(&hsbtable[anim_step - 2*HSBTABLE_LEN]); + } + if (OCR0A) + TCCR0A |= _BV(COM0A1); + else + TCCR0A &= ~_BV(COM0A1); + if (OCR1A) + TCCR1A |= _BV(COM1A1); + else + TCCR1A &= ~_BV(COM1A1); + if (OCR1B) + TCCR1A |= _BV(COM1B1); + else + TCCR1A &= ~_BV(COM1B1); } - set_outputs(); - if (mode == OFF && !btn_debounce) { - sleep(); - } else { + if (mode == FASTRGB || mode == SLOWRGB || btn_debounce) { idle(); + } else { + sleep(); } } @@ -147,6 +202,7 @@ void System::next_mode(void) { if (!btn_debounce) { mode = (BCMode)((mode + 1) % MODE_ENUM_MAX); + mode_changed = 1; } } @@ -171,6 +227,20 @@ ISR(WDT_OVERFLOW_vect) blinkencat.debounce_done(); } +ISR(TIMER0_OVF_vect) +{ + static uint8_t slowdown = 0; + if (++slowdown == 10) { + if (++blinkencat.anim_step_fine == 3*HSBTABLE_LEN) { + blinkencat.anim_step_fine = 0; + if (++blinkencat.anim_step_coarse == 3*HSBTABLE_LEN) { + blinkencat.anim_step_coarse = 0; + } + } + slowdown = 0; + } +} + ISR(PCINT2_vect) { if (!(PIND & _BV(PD2))) { -- cgit v1.2.3