Loading src/system.cc +133 −63 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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); } if (blue) { PORTB |= _BV(PB2); 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 { PORTB &= ~_BV(PB2); TCCR0A = 0; TCCR0B = 0; TCCR1A = 0; TCCR1B = 0; TIMSK = 0; } } void System::loop() { switch (mode) { case OFF: warmwhite = red = green = blue = 0; PORTD &= ~BIT_WW; PORTB = 0; break; case WARMWHITE: warmwhite = 255; red = green = blue = 0; PORTD |= BIT_WW; break; case RED: red = 255; warmwhite = green = blue = 0; PORTD &= ~BIT_WW; PORTB = BIT_RED; break; case GREEN: green = 255; warmwhite = red = blue = 0; PORTB = BIT_GREEN; break; case BLUE: blue = 255; warmwhite = red = green = 0; PORTB = BIT_BLUE; break; case YELLOW: red = green = 255; warmwhite = blue = 0; PORTB = BIT_RED | BIT_GREEN; break; case MAGENTA: red = blue = 255; warmwhite = green = 0; PORTB = BIT_RED | BIT_BLUE; break; case CYAN: green = blue = 255; warmwhite = red = 0; PORTB = BIT_GREEN | BIT_BLUE; break; case SUN: warmwhite = red = green = blue = 255; PORTD |= BIT_WW; PORTB = BIT_RED | BIT_GREEN | BIT_BLUE; break; default: break; } set_outputs(); } if (mode == OFF && !btn_debounce) { sleep(); } else { if (mode == FASTRGB) { anim_step = anim_step_fine; } else if (mode == SLOWRGB) { anim_step = anim_step_coarse; } 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); } if (mode == FASTRGB || mode == SLOWRGB || btn_debounce) { idle(); } else { sleep(); } } Loading @@ -147,6 +202,7 @@ void System::next_mode(void) { if (!btn_debounce) { mode = (BCMode)((mode + 1) % MODE_ENUM_MAX); mode_changed = 1; } } Loading @@ -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))) { Loading src/system.h +6 −3 Original line number Diff line number Diff line Loading @@ -12,11 +12,12 @@ class System { uint8_t red; uint8_t green; uint8_t blue; void set_outputs(); uint8_t mode_changed; public: uint8_t anim_step_fine; uint8_t anim_step_coarse; void initialize(void); void loop(void); Loading @@ -33,6 +34,8 @@ class System { MAGENTA, CYAN, SUN, FASTRGB, SLOWRGB, MODE_ENUM_MAX, }; Loading @@ -44,7 +47,7 @@ class System { void debounce_start(void); System() { btn_debounce = 0; mode = OFF; is_charging = 0; }; System() { btn_debounce = 0; mode = OFF; is_charging = 0; mode_changed = 0; }; }; extern System blinkencat; Loading Loading
src/system.cc +133 −63 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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); } if (blue) { PORTB |= _BV(PB2); 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 { PORTB &= ~_BV(PB2); TCCR0A = 0; TCCR0B = 0; TCCR1A = 0; TCCR1B = 0; TIMSK = 0; } } void System::loop() { switch (mode) { case OFF: warmwhite = red = green = blue = 0; PORTD &= ~BIT_WW; PORTB = 0; break; case WARMWHITE: warmwhite = 255; red = green = blue = 0; PORTD |= BIT_WW; break; case RED: red = 255; warmwhite = green = blue = 0; PORTD &= ~BIT_WW; PORTB = BIT_RED; break; case GREEN: green = 255; warmwhite = red = blue = 0; PORTB = BIT_GREEN; break; case BLUE: blue = 255; warmwhite = red = green = 0; PORTB = BIT_BLUE; break; case YELLOW: red = green = 255; warmwhite = blue = 0; PORTB = BIT_RED | BIT_GREEN; break; case MAGENTA: red = blue = 255; warmwhite = green = 0; PORTB = BIT_RED | BIT_BLUE; break; case CYAN: green = blue = 255; warmwhite = red = 0; PORTB = BIT_GREEN | BIT_BLUE; break; case SUN: warmwhite = red = green = blue = 255; PORTD |= BIT_WW; PORTB = BIT_RED | BIT_GREEN | BIT_BLUE; break; default: break; } set_outputs(); } if (mode == OFF && !btn_debounce) { sleep(); } else { if (mode == FASTRGB) { anim_step = anim_step_fine; } else if (mode == SLOWRGB) { anim_step = anim_step_coarse; } 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); } if (mode == FASTRGB || mode == SLOWRGB || btn_debounce) { idle(); } else { sleep(); } } Loading @@ -147,6 +202,7 @@ void System::next_mode(void) { if (!btn_debounce) { mode = (BCMode)((mode + 1) % MODE_ENUM_MAX); mode_changed = 1; } } Loading @@ -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))) { Loading
src/system.h +6 −3 Original line number Diff line number Diff line Loading @@ -12,11 +12,12 @@ class System { uint8_t red; uint8_t green; uint8_t blue; void set_outputs(); uint8_t mode_changed; public: uint8_t anim_step_fine; uint8_t anim_step_coarse; void initialize(void); void loop(void); Loading @@ -33,6 +34,8 @@ class System { MAGENTA, CYAN, SUN, FASTRGB, SLOWRGB, MODE_ENUM_MAX, }; Loading @@ -44,7 +47,7 @@ class System { void debounce_start(void); System() { btn_debounce = 0; mode = OFF; is_charging = 0; }; System() { btn_debounce = 0; mode = OFF; is_charging = 0; mode_changed = 0; }; }; extern System blinkencat; Loading