#include "Kaleidoscope-LEDControl.h" #include "Kaleidoscope-Focus.h" LEDMode *LEDControl_::modes[LED_MAX_MODES]; uint8_t LEDControl_::previousMode, LEDControl_::mode; uint16_t LEDControl_::syncDelay = 16; uint32_t LEDControl_::syncTimer; void LEDMode::activate(void) { LEDControl.activate(this); } void LEDMode::begin(void) { Kaleidoscope.use(&LEDControl, NULL); LEDControl.mode_add(this); } LEDControl_::LEDControl_(void) { mode = previousMode = 0; memset(modes, 0, LED_MAX_MODES * sizeof(modes[0])); } void LEDControl_::next_mode(void) { mode++; if (mode >= LED_MAX_MODES) { mode = 0; return; } if (modes[mode]) return; mode = 0; } void LEDControl_::update(void) { if (previousMode != mode) { set_all_leds_to({0, 0, 0}); if (modes[mode]) (modes[mode]->init)(); } if (modes[mode]) (modes[mode]->update)(); previousMode = mode; } void LEDControl_::init_mode(void) { if (modes[mode]) (modes[mode]->init)(); } void LEDControl_::set_mode(uint8_t mode_) { if (mode_ < LED_MAX_MODES) mode = mode_; } uint8_t LEDControl_::get_mode(void) { return mode; } void LEDControl_::activate(LEDMode *mode) { for (uint8_t i = 0; i < LED_MAX_MODES; i++) { if (modes[i] == mode) return set_mode(i); } } int8_t LEDControl_::mode_add(LEDMode *mode) { for (int i = 0; i < LED_MAX_MODES; i++) { if (modes[i]) continue; modes[i] = mode; return i; } return -1; } void LEDControl_::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { cRGB color; color.r = r; color.g = g; color.b = b; set_all_leds_to(color); } void LEDControl_::set_all_leds_to(cRGB color) { for (uint8_t i = 0; i < LED_COUNT; i++) { setCrgbAt(i, color); } } void LEDControl_::setCrgbAt(uint8_t i, cRGB crgb) { KeyboardHardware.setCrgbAt(i, crgb); } void LEDControl_::setCrgbAt(byte row, byte col, cRGB color) { KeyboardHardware.setCrgbAt(row, col, color); } cRGB LEDControl_::getCrgbAt(uint8_t i) { return KeyboardHardware.getCrgbAt(i); } void LEDControl_::syncLeds(void) { KeyboardHardware.syncLeds(); } void LEDControl_::begin(void) { set_all_leds_to({0, 0, 0}); for (uint8_t i = 0; i < LED_MAX_MODES; i++) { if (modes[i]) (modes[i]->setup)(); } event_handler_hook_use(eventHandler); loop_hook_use(loopHook); syncTimer = millis() + syncDelay; } Key LEDControl_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) return mappedKey; if (keyToggledOn(keyState)) LEDControl.next_mode(); return Key_NoKey; } void LEDControl_::loopHook(bool postClear) { if (postClear) return; if (millis() > syncTimer) { syncLeds(); syncTimer = millis() + syncDelay; } update(); } bool LEDControl_::focusHook(const char *command) { enum { SETALL, MODE, AT, THEME, } subCommand; if (strncmp_P(command, PSTR("led."), 4) != 0) return false; if (strcmp_P(command + 4, PSTR("at")) == 0) subCommand = AT; else if (strcmp_P(command + 4, PSTR("setAll")) == 0) subCommand = SETALL; else if (strcmp_P(command + 4, PSTR("mode")) == 0) subCommand = MODE; else if (strcmp_P(command + 4, PSTR("theme")) == 0) subCommand = THEME; else return false; switch (subCommand) { case AT: { uint8_t idx = Serial.parseInt(); if (Serial.peek() == '\n') { cRGB c = LEDControl.getCrgbAt(idx); Focus.printColor(c.r, c.g, c.b); Serial.println(); } else { cRGB c; c.r = Serial.parseInt(); c.g = Serial.parseInt(); c.b = Serial.parseInt(); LEDControl.setCrgbAt(idx, c); } break; } case SETALL: { cRGB c; c.r = Serial.parseInt(); c.g = Serial.parseInt(); c.b = Serial.parseInt(); LEDControl.set_all_leds_to(c); break; } case MODE: { char peek = Serial.peek(); if (peek == '\n') { Serial.println(LEDControl.get_mode()); } else if (peek == 'n') { LEDControl.next_mode(); Serial.read(); } else if (peek == 'p') { // TODO(algernon) Serial.read(); } else { uint8_t mode = Serial.parseInt(); LEDControl.set_mode(mode); } break; } case THEME: { if (Serial.peek() == '\n') { for (uint8_t idx = 0; idx < LED_COUNT; idx++) { cRGB c = LEDControl.getCrgbAt(idx); Focus.printColor(c.r, c.g, c.b); Focus.printSpace(); } Serial.println(); break; } uint8_t idx = 0; while (idx < LED_COUNT && Serial.peek() != '\n') { cRGB color; color.r = Serial.parseInt(); color.g = Serial.parseInt(); color.b = Serial.parseInt(); LEDControl.setCrgbAt(idx, color); idx++; } break; } } return true; } LEDControl_ LEDControl;