From e8701195e66f2d27ffe17fb514eae8173795aaf7 Mon Sep 17 00:00:00 2001 From: Georgiy Bondarenko <69736697+nehilo@users.noreply.github.com> Date: Thu, 4 Mar 2021 22:54:23 +0500 Subject: Initial commit --- Marlin/src/feature/leds/blinkm.cpp | 46 +++++ Marlin/src/feature/leds/blinkm.h | 31 +++ Marlin/src/feature/leds/leds.cpp | 200 +++++++++++++++++++ Marlin/src/feature/leds/leds.h | 253 +++++++++++++++++++++++++ Marlin/src/feature/leds/neopixel.cpp | 172 +++++++++++++++++ Marlin/src/feature/leds/neopixel.h | 182 ++++++++++++++++++ Marlin/src/feature/leds/pca9533.cpp | 127 +++++++++++++ Marlin/src/feature/leds/pca9533.h | 59 ++++++ Marlin/src/feature/leds/pca9632.cpp | 164 ++++++++++++++++ Marlin/src/feature/leds/pca9632.h | 37 ++++ Marlin/src/feature/leds/printer_event_leds.cpp | 82 ++++++++ Marlin/src/feature/leds/printer_event_leds.h | 87 +++++++++ Marlin/src/feature/leds/tempstat.cpp | 55 ++++++ Marlin/src/feature/leds/tempstat.h | 28 +++ 14 files changed, 1523 insertions(+) create mode 100644 Marlin/src/feature/leds/blinkm.cpp create mode 100644 Marlin/src/feature/leds/blinkm.h create mode 100644 Marlin/src/feature/leds/leds.cpp create mode 100644 Marlin/src/feature/leds/leds.h create mode 100644 Marlin/src/feature/leds/neopixel.cpp create mode 100644 Marlin/src/feature/leds/neopixel.h create mode 100644 Marlin/src/feature/leds/pca9533.cpp create mode 100644 Marlin/src/feature/leds/pca9533.h create mode 100644 Marlin/src/feature/leds/pca9632.cpp create mode 100644 Marlin/src/feature/leds/pca9632.h create mode 100644 Marlin/src/feature/leds/printer_event_leds.cpp create mode 100644 Marlin/src/feature/leds/printer_event_leds.h create mode 100644 Marlin/src/feature/leds/tempstat.cpp create mode 100644 Marlin/src/feature/leds/tempstat.h (limited to 'Marlin/src/feature/leds') diff --git a/Marlin/src/feature/leds/blinkm.cpp b/Marlin/src/feature/leds/blinkm.cpp new file mode 100644 index 0000000..868eb4b --- /dev/null +++ b/Marlin/src/feature/leds/blinkm.cpp @@ -0,0 +1,46 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * blinkm.cpp - Control a BlinkM over i2c + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(BLINKM) + +#include "blinkm.h" +#include "leds.h" +#include + +void blinkm_set_led_color(const LEDColor &color) { + Wire.begin(); + Wire.beginTransmission(I2C_ADDRESS(0x09)); + Wire.write('o'); //to disable ongoing script, only needs to be used once + Wire.write('n'); + Wire.write(color.r); + Wire.write(color.g); + Wire.write(color.b); + Wire.endTransmission(); +} + +#endif // BLINKM diff --git a/Marlin/src/feature/leds/blinkm.h b/Marlin/src/feature/leds/blinkm.h new file mode 100644 index 0000000..29a9e78 --- /dev/null +++ b/Marlin/src/feature/leds/blinkm.h @@ -0,0 +1,31 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * blinkm.h - Control a BlinkM over i2c + */ + +struct LEDColor; +typedef LEDColor LEDColor; + +void blinkm_set_led_color(const LEDColor &color); diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp new file mode 100644 index 0000000..ef9099f --- /dev/null +++ b/Marlin/src/feature/leds/leds.cpp @@ -0,0 +1,200 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * leds.cpp - Marlin RGB LED general support + */ + +#include "../../inc/MarlinConfig.h" + +#if HAS_COLOR_LEDS + +#include "leds.h" + +#if ENABLED(BLINKM) + #include "blinkm.h" +#endif + +#if ENABLED(PCA9632) + #include "pca9632.h" +#endif + +#if ENABLED(PCA9533) + #include "pca9533.h" +#endif + +#if ENABLED(LED_COLOR_PRESETS) + const LEDColor LEDLights::defaultLEDColor = MakeLEDColor( + LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE, + LED_USER_PRESET_WHITE, LED_USER_PRESET_BRIGHTNESS + ); +#endif + +#if EITHER(LED_CONTROL_MENU, PRINTER_EVENT_LEDS) + LEDColor LEDLights::color; + bool LEDLights::lights_on; +#endif + +LEDLights leds; + +void LEDLights::setup() { + #if EITHER(RGB_LED, RGBW_LED) + if (PWM_PIN(RGB_LED_R_PIN)) SET_PWM(RGB_LED_R_PIN); else SET_OUTPUT(RGB_LED_R_PIN); + if (PWM_PIN(RGB_LED_G_PIN)) SET_PWM(RGB_LED_G_PIN); else SET_OUTPUT(RGB_LED_G_PIN); + if (PWM_PIN(RGB_LED_B_PIN)) SET_PWM(RGB_LED_B_PIN); else SET_OUTPUT(RGB_LED_B_PIN); + #if ENABLED(RGBW_LED) + if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN); + #endif + #endif + TERN_(NEOPIXEL_LED, neo.init()); + TERN_(PCA9533, PCA9533_init()); + TERN_(LED_USER_PRESET_STARTUP, set_default()); +} + +void LEDLights::set_color(const LEDColor &incol + #if ENABLED(NEOPIXEL_LED) + , bool isSequence/*=false*/ + #endif +) { + + #if ENABLED(NEOPIXEL_LED) + + const uint32_t neocolor = LEDColorWhite() == incol + ? neo.Color(NEO_WHITE) + : neo.Color(incol.r, incol.g, incol.b, incol.w); + static uint16_t nextLed = 0; + + #ifdef NEOPIXEL_BKGD_LED_INDEX + if (NEOPIXEL_BKGD_LED_INDEX == nextLed) { + if (++nextLed >= neo.pixels()) nextLed = 0; + return; + } + #endif + + neo.set_brightness(incol.i); + + if (isSequence) { + neo.set_pixel_color(nextLed, neocolor); + neo.show(); + if (++nextLed >= neo.pixels()) nextLed = 0; + return; + } + + neo.set_color(neocolor); + + #endif + + #if ENABLED(BLINKM) + + // This variant uses i2c to send the RGB components to the device. + blinkm_set_led_color(incol); + + #endif + + #if EITHER(RGB_LED, RGBW_LED) + + // This variant uses 3-4 separate pins for the RGB(W) components. + // If the pins can do PWM then their intensity will be set. + #define UPDATE_RGBW(C,c) do { \ + if (PWM_PIN(RGB_LED_##C##_PIN)) \ + analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \ + else \ + WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); \ + }while(0) + UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b); + #if ENABLED(RGBW_LED) + UPDATE_RGBW(W,w); + #endif + + #endif + + // Update I2C LED driver + TERN_(PCA9632, PCA9632_set_led_color(incol)); + TERN_(PCA9533, PCA9533_set_rgb(incol.r, incol.g, incol.b)); + + #if EITHER(LED_CONTROL_MENU, PRINTER_EVENT_LEDS) + // Don't update the color when OFF + lights_on = !incol.is_off(); + if (lights_on) color = incol; + #endif +} + +#if ENABLED(LED_CONTROL_MENU) + void LEDLights::toggle() { if (lights_on) set_off(); else update(); } +#endif + +#ifdef LED_BACKLIGHT_TIMEOUT + + millis_t LEDLights::led_off_time; // = 0 + + void LEDLights::update_timeout(const bool power_on) { + const millis_t ms = millis(); + if (power_on) + reset_timeout(ms); + else if (ELAPSED(ms, led_off_time)) + set_off(); + } + +#endif + +#if ENABLED(NEOPIXEL2_SEPARATE) + + #if ENABLED(NEO2_COLOR_PRESETS) + const LEDColor LEDLights2::defaultLEDColor = MakeLEDColor( + NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, + NEO2_USER_PRESET_WHITE, NEO2_USER_PRESET_BRIGHTNESS + ); + #endif + + #if ENABLED(LED_CONTROL_MENU) + LEDColor LEDLights2::color; + bool LEDLights2::lights_on; + #endif + + LEDLights2 leds2; + + void LEDLights2::setup() { + neo2.init(); + TERN_(NEO2_USER_PRESET_STARTUP, set_default()); + } + + void LEDLights2::set_color(const LEDColor &incol) { + const uint32_t neocolor = LEDColorWhite() == incol + ? neo2.Color(NEO2_WHITE) + : neo2.Color(incol.r, incol.g, incol.b, incol.w); + neo2.set_brightness(incol.i); + neo2.set_color(neocolor); + + #if ENABLED(LED_CONTROL_MENU) + // Don't update the color when OFF + lights_on = !incol.is_off(); + if (lights_on) color = incol; + #endif + } + + #if ENABLED(LED_CONTROL_MENU) + void LEDLights2::toggle() { if (lights_on) set_off(); else update(); } + #endif + +#endif // NEOPIXEL2_SEPARATE + +#endif // HAS_COLOR_LEDS diff --git a/Marlin/src/feature/leds/leds.h b/Marlin/src/feature/leds/leds.h new file mode 100644 index 0000000..57b21d5 --- /dev/null +++ b/Marlin/src/feature/leds/leds.h @@ -0,0 +1,253 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * leds.h - Marlin general RGB LED support + */ + +#include "../../inc/MarlinConfigPre.h" + +#include + +#if ENABLED(NEOPIXEL_LED) + #include "neopixel.h" +#endif + +// A white component can be passed +#if ANY(RGBW_LED, NEOPIXEL_LED, PCA9632_RGBW) + #define HAS_WHITE_LED 1 +#endif + +/** + * LEDcolor type for use with leds.set_color + */ +typedef struct LEDColor { + uint8_t r, g, b + #if HAS_WHITE_LED + , w + #if ENABLED(NEOPIXEL_LED) + , i + #endif + #endif + ; + + LEDColor() : r(255), g(255), b(255) + #if HAS_WHITE_LED + , w(255) + #if ENABLED(NEOPIXEL_LED) + , i(NEOPIXEL_BRIGHTNESS) + #endif + #endif + {} + + LEDColor(uint8_t r, uint8_t g, uint8_t b + #if HAS_WHITE_LED + , uint8_t w=0 + #if ENABLED(NEOPIXEL_LED) + , uint8_t i=NEOPIXEL_BRIGHTNESS + #endif + #endif + ) : r(r), g(g), b(b) + #if HAS_WHITE_LED + , w(w) + #if ENABLED(NEOPIXEL_LED) + , i(i) + #endif + #endif + {} + + LEDColor(const uint8_t (&rgbw)[4]) : r(rgbw[0]), g(rgbw[1]), b(rgbw[2]) + #if HAS_WHITE_LED + , w(rgbw[3]) + #if ENABLED(NEOPIXEL_LED) + , i(NEOPIXEL_BRIGHTNESS) + #endif + #endif + {} + + LEDColor& operator=(const uint8_t (&rgbw)[4]) { + r = rgbw[0]; g = rgbw[1]; b = rgbw[2]; + TERN_(HAS_WHITE_LED, w = rgbw[3]); + return *this; + } + + LEDColor& operator=(const LEDColor &right) { + if (this != &right) memcpy(this, &right, sizeof(LEDColor)); + return *this; + } + + bool operator==(const LEDColor &right) { + if (this == &right) return true; + return 0 == memcmp(this, &right, sizeof(LEDColor)); + } + + bool operator!=(const LEDColor &right) { return !operator==(right); } + + bool is_off() const { + return 3 > r + g + b + TERN0(HAS_WHITE_LED, w); + } +} LEDColor; + +/** + * Color helpers and presets + */ +#if HAS_WHITE_LED + #if ENABLED(NEOPIXEL_LED) + #define MakeLEDColor(R,G,B,W,I) LEDColor(R, G, B, W, I) + #else + #define MakeLEDColor(R,G,B,W,I) LEDColor(R, G, B, W) + #endif +#else + #define MakeLEDColor(R,G,B,W,I) LEDColor(R, G, B) +#endif + +#define LEDColorOff() LEDColor( 0, 0, 0) +#define LEDColorRed() LEDColor(255, 0, 0) +#if ENABLED(LED_COLORS_REDUCE_GREEN) + #define LEDColorOrange() LEDColor(255, 25, 0) + #define LEDColorYellow() LEDColor(255, 75, 0) +#else + #define LEDColorOrange() LEDColor(255, 80, 0) + #define LEDColorYellow() LEDColor(255, 255, 0) +#endif +#define LEDColorGreen() LEDColor( 0, 255, 0) +#define LEDColorBlue() LEDColor( 0, 0, 255) +#define LEDColorIndigo() LEDColor( 0, 255, 255) +#define LEDColorViolet() LEDColor(255, 0, 255) +#if HAS_WHITE_LED && DISABLED(RGB_LED) + #define LEDColorWhite() LEDColor( 0, 0, 0, 255) +#else + #define LEDColorWhite() LEDColor(255, 255, 255) +#endif + +class LEDLights { +public: + LEDLights() {} // ctor + + static void setup(); // init() + + static void set_color(const LEDColor &color + #if ENABLED(NEOPIXEL_LED) + , bool isSequence=false + #endif + ); + + static inline void set_color(uint8_t r, uint8_t g, uint8_t b + #if HAS_WHITE_LED + , uint8_t w=0 + #endif + #if ENABLED(NEOPIXEL_LED) + , uint8_t i=NEOPIXEL_BRIGHTNESS + , bool isSequence=false + #endif + ) { + set_color(MakeLEDColor(r, g, b, w, i) + #if ENABLED(NEOPIXEL_LED) + , isSequence + #endif + ); + } + + static inline void set_off() { set_color(LEDColorOff()); } + static inline void set_green() { set_color(LEDColorGreen()); } + static inline void set_white() { set_color(LEDColorWhite()); } + + #if ENABLED(LED_COLOR_PRESETS) + static const LEDColor defaultLEDColor; + static inline void set_default() { set_color(defaultLEDColor); } + static inline void set_red() { set_color(LEDColorRed()); } + static inline void set_orange() { set_color(LEDColorOrange()); } + static inline void set_yellow() { set_color(LEDColorYellow()); } + static inline void set_blue() { set_color(LEDColorBlue()); } + static inline void set_indigo() { set_color(LEDColorIndigo()); } + static inline void set_violet() { set_color(LEDColorViolet()); } + #endif + + #if ENABLED(PRINTER_EVENT_LEDS) + static inline LEDColor get_color() { return lights_on ? color : LEDColorOff(); } + #endif + + #if EITHER(LED_CONTROL_MENU, PRINTER_EVENT_LEDS) + static LEDColor color; // last non-off color + static bool lights_on; // the last set color was "on" + #endif + + #if ENABLED(LED_CONTROL_MENU) + static void toggle(); // swap "off" with color + static inline void update() { set_color(color); } + #endif + + #ifdef LED_BACKLIGHT_TIMEOUT + private: + static millis_t led_off_time; + public: + static inline void reset_timeout(const millis_t &ms) { + led_off_time = ms + LED_BACKLIGHT_TIMEOUT; + if (!lights_on) set_default(); + } + static void update_timeout(const bool power_on); + #endif +}; + +extern LEDLights leds; + +#if ENABLED(NEOPIXEL2_SEPARATE) + + class LEDLights2 { + public: + LEDLights2() {} + + static void setup(); // init() + + static void set_color(const LEDColor &color); + + inline void set_color(uint8_t r, uint8_t g, uint8_t b, uint8_t w=0, uint8_t i=NEOPIXEL2_BRIGHTNESS) { + set_color(MakeLEDColor(r, g, b, w, i)); + } + + static inline void set_off() { set_color(LEDColorOff()); } + static inline void set_green() { set_color(LEDColorGreen()); } + static inline void set_white() { set_color(LEDColorWhite()); } + + #if ENABLED(NEO2_COLOR_PRESETS) + static const LEDColor defaultLEDColor; + static inline void set_default() { set_color(defaultLEDColor); } + static inline void set_red() { set_color(LEDColorRed()); } + static inline void set_orange() { set_color(LEDColorOrange()); } + static inline void set_yellow() { set_color(LEDColorYellow()); } + static inline void set_blue() { set_color(LEDColorBlue()); } + static inline void set_indigo() { set_color(LEDColorIndigo()); } + static inline void set_violet() { set_color(LEDColorViolet()); } + #endif + + #if ENABLED(NEOPIXEL2_SEPARATE) + static LEDColor color; // last non-off color + static bool lights_on; // the last set color was "on" + static void toggle(); // swap "off" with color + static inline void update() { set_color(color); } + #endif + }; + + extern LEDLights2 leds2; + +#endif // NEOPIXEL2_SEPARATE diff --git a/Marlin/src/feature/leds/neopixel.cpp b/Marlin/src/feature/leds/neopixel.cpp new file mode 100644 index 0000000..27bbeb3 --- /dev/null +++ b/Marlin/src/feature/leds/neopixel.cpp @@ -0,0 +1,172 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Marlin RGB LED general support + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(NEOPIXEL_LED) + +#include "neopixel.h" + +#if EITHER(NEOPIXEL_STARTUP_TEST, NEOPIXEL2_STARTUP_TEST) + #include "../../core/utility.h" +#endif + +Marlin_NeoPixel neo; +int8_t Marlin_NeoPixel::neoindex; + +Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800) + #if CONJOINED_NEOPIXEL + , Marlin_NeoPixel::adaneo2(NEOPIXEL_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE + NEO_KHZ800) + #endif +; + +#ifdef NEOPIXEL_BKGD_LED_INDEX + + void Marlin_NeoPixel::set_color_background() { + uint8_t background_color[4] = NEOPIXEL_BKGD_COLOR; + set_pixel_color(NEOPIXEL_BKGD_LED_INDEX, adaneo1.Color(background_color[0], background_color[1], background_color[2], background_color[3])); + } + +#endif + +void Marlin_NeoPixel::set_color(const uint32_t color) { + if (neoindex >= 0) { + set_pixel_color(neoindex, color); + neoindex = -1; + } + else { + for (uint16_t i = 0; i < pixels(); ++i) { + #ifdef NEOPIXEL_BKGD_LED_INDEX + if (i == NEOPIXEL_BKGD_LED_INDEX && color != 0x000000) { + set_color_background(); + continue; + } + #endif + set_pixel_color(i, color); + } + } + show(); +} + +void Marlin_NeoPixel::set_color_startup(const uint32_t color) { + for (uint16_t i = 0; i < pixels(); ++i) + set_pixel_color(i, color); + show(); +} + +void Marlin_NeoPixel::init() { + neoindex = -1; // -1 .. NEOPIXEL_PIXELS-1 range + set_brightness(NEOPIXEL_BRIGHTNESS); // 0 .. 255 range + begin(); + show(); // initialize to all off + + #if ENABLED(NEOPIXEL_STARTUP_TEST) + set_color_startup(adaneo1.Color(255, 0, 0, 0)); // red + safe_delay(500); + set_color_startup(adaneo1.Color(0, 255, 0, 0)); // green + safe_delay(500); + set_color_startup(adaneo1.Color(0, 0, 255, 0)); // blue + safe_delay(500); + #endif + + #ifdef NEOPIXEL_BKGD_LED_INDEX + set_color_background(); + #endif + + #if ENABLED(LED_USER_PRESET_STARTUP) + set_color(adaneo1.Color(LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE, LED_USER_PRESET_WHITE)); + #else + set_color(adaneo1.Color(0, 0, 0, 0)); + #endif +} + +#if 0 +bool Marlin_NeoPixel::set_led_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w, const uint8_t p) { + const uint32_t color = adaneo1.Color(r, g, b, w); + set_brightness(p); + #if DISABLED(NEOPIXEL_IS_SEQUENTIAL) + set_color(color); + return false; + #else + static uint16_t nextLed = 0; + set_pixel_color(nextLed, color); + show(); + if (++nextLed >= pixels()) nextLed = 0; + return true; + #endif +} +#endif + +#if ENABLED(NEOPIXEL2_SEPARATE) + + Marlin_NeoPixel2 neo2; + + int8_t Marlin_NeoPixel2::neoindex; + Adafruit_NeoPixel Marlin_NeoPixel2::adaneo(NEOPIXEL2_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE); + + void Marlin_NeoPixel2::set_color(const uint32_t color) { + if (neoindex >= 0) { + set_pixel_color(neoindex, color); + neoindex = -1; + } + else { + for (uint16_t i = 0; i < pixels(); ++i) + set_pixel_color(i, color); + } + show(); + } + + void Marlin_NeoPixel2::set_color_startup(const uint32_t color) { + for (uint16_t i = 0; i < pixels(); ++i) + set_pixel_color(i, color); + show(); + } + + void Marlin_NeoPixel2::init() { + neoindex = -1; // -1 .. NEOPIXEL2_PIXELS-1 range + set_brightness(NEOPIXEL2_BRIGHTNESS); // 0 .. 255 range + begin(); + show(); // initialize to all off + + #if ENABLED(NEOPIXEL2_STARTUP_TEST) + set_color_startup(adaneo.Color(255, 0, 0, 0)); // red + safe_delay(500); + set_color_startup(adaneo.Color(0, 255, 0, 0)); // green + safe_delay(500); + set_color_startup(adaneo.Color(0, 0, 255, 0)); // blue + safe_delay(500); + #endif + + #if ENABLED(NEO2_USER_PRESET_STARTUP) + set_color(adaneo.Color(NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, NEO2_USER_PRESET_WHITE)); + #else + set_color(adaneo.Color(0, 0, 0, 0)); + #endif + } + +#endif // NEOPIXEL2_SEPARATE + +#endif // NEOPIXEL_LED diff --git a/Marlin/src/feature/leds/neopixel.h b/Marlin/src/feature/leds/neopixel.h new file mode 100644 index 0000000..acf2e7f --- /dev/null +++ b/Marlin/src/feature/leds/neopixel.h @@ -0,0 +1,182 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * NeoPixel support + */ + +// ------------------------ +// Includes +// ------------------------ + +#include "../../inc/MarlinConfig.h" + +#include +#include + +// ------------------------ +// Defines +// ------------------------ + +#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE && DISABLED(NEOPIXEL2_SEPARATE) + #define MULTIPLE_NEOPIXEL_TYPES 1 +#endif + +#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES) + #define CONJOINED_NEOPIXEL 1 +#endif + +#if NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR + #define NEOPIXEL_IS_RGB 1 +#else + #define NEOPIXEL_IS_RGBW 1 +#endif + +#if NEOPIXEL_IS_RGB + #define NEO_WHITE 255, 255, 255, 0 +#else + #define NEO_WHITE 0, 0, 0, 255 +#endif + +// ------------------------ +// Function prototypes +// ------------------------ + +class Marlin_NeoPixel { +private: + static Adafruit_NeoPixel adaneo1 + #if CONJOINED_NEOPIXEL + , adaneo2 + #endif + ; + +public: + static int8_t neoindex; + + static void init(); + static void set_color_startup(const uint32_t c); + + static void set_color(const uint32_t c); + + #ifdef NEOPIXEL_BKGD_LED_INDEX + static void set_color_background(); + #endif + + static inline void begin() { + adaneo1.begin(); + TERN_(CONJOINED_NEOPIXEL, adaneo2.begin()); + } + + static inline void set_pixel_color(const uint16_t n, const uint32_t c) { + #if ENABLED(NEOPIXEL2_INSERIES) + if (n >= NEOPIXEL_PIXELS) adaneo2.setPixelColor(n - (NEOPIXEL_PIXELS), c); + else adaneo1.setPixelColor(n, c); + #else + adaneo1.setPixelColor(n, c); + #if MULTIPLE_NEOPIXEL_TYPES + adaneo2.setPixelColor(n, c); + #endif + #endif + } + + static inline void set_brightness(const uint8_t b) { + adaneo1.setBrightness(b); + TERN_(CONJOINED_NEOPIXEL, adaneo2.setBrightness(b)); + } + + static inline void show() { + // Some platforms cannot maintain PWM output when NeoPixel disables interrupts for long durations. + TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT()); + adaneo1.show(); + #if PIN_EXISTS(NEOPIXEL2) + #if CONJOINED_NEOPIXEL + adaneo2.show(); + #else + IF_DISABLED(NEOPIXEL2_SEPARATE, adaneo1.setPin(NEOPIXEL2_PIN)); + adaneo1.show(); + adaneo1.setPin(NEOPIXEL_PIN); + #endif + #endif + TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT()); + } + + #if 0 + bool set_led_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w, const uint8_t p); + #endif + + // Accessors + static inline uint16_t pixels() { TERN(NEOPIXEL2_INSERIES, return adaneo1.numPixels() * 2, return adaneo1.numPixels()); } + static inline uint8_t brightness() { return adaneo1.getBrightness(); } + static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { + return adaneo1.Color(r, g, b, w); + } +}; + +extern Marlin_NeoPixel neo; + +// Neo pixel channel 2 +#if ENABLED(NEOPIXEL2_SEPARATE) + + #if NEOPIXEL2_TYPE == NEO_RGB || NEOPIXEL2_TYPE == NEO_RBG || NEOPIXEL2_TYPE == NEO_GRB || NEOPIXEL2_TYPE == NEO_GBR || NEOPIXEL2_TYPE == NEO_BRG || NEOPIXEL2_TYPE == NEO_BGR + #define NEOPIXEL2_IS_RGB 1 + #else + #define NEOPIXEL2_IS_RGBW 1 + #endif + + #if NEOPIXEL2_IS_RGB + #define NEO2_WHITE 255, 255, 255, 0 + #else + #define NEO2_WHITE 0, 0, 0, 255 + #endif + + class Marlin_NeoPixel2 { + private: + static Adafruit_NeoPixel adaneo; + + public: + static int8_t neoindex; + + static void init(); + static void set_color_startup(const uint32_t c); + + static void set_color(const uint32_t c); + + static inline void begin() { adaneo.begin(); } + static inline void set_pixel_color(const uint16_t n, const uint32_t c) { adaneo.setPixelColor(n, c); } + static inline void set_brightness(const uint8_t b) { adaneo.setBrightness(b); } + static inline void show() { + adaneo.show(); + adaneo.setPin(NEOPIXEL2_PIN); + } + + // Accessors + static inline uint16_t pixels() { return adaneo.numPixels();} + static inline uint8_t brightness() { return adaneo.getBrightness(); } + static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { + return adaneo.Color(r, g, b, w); + } + }; + + extern Marlin_NeoPixel2 neo2; + +#endif // NEOPIXEL2_SEPARATE diff --git a/Marlin/src/feature/leds/pca9533.cpp b/Marlin/src/feature/leds/pca9533.cpp new file mode 100644 index 0000000..0fd4d66 --- /dev/null +++ b/Marlin/src/feature/leds/pca9533.cpp @@ -0,0 +1,127 @@ +/* + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * PCA9533 LED controller driver (MightyBoard, FlashForge Creator Pro, etc.) + * by @grauerfuchs - 1 Apr 2020 + */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(PCA9533) + +#include "pca9533.h" +#include + +void PCA9533_init() { + Wire.begin(); + PCA9533_reset(); +} + +static void PCA9533_writeAllRegisters(uint8_t psc0, uint8_t pwm0, uint8_t psc1, uint8_t pwm1, uint8_t ls0){ + uint8_t data[6] = { PCA9533_REG_PSC0 | PCA9533_REGM_AI, psc0, pwm0, psc1, pwm1, ls0 }; + Wire.beginTransmission(PCA9533_Addr >> 1); + Wire.write(data, 6); + Wire.endTransmission(); + delayMicroseconds(1); +} + +static void PCA9533_writeRegister(uint8_t reg, uint8_t val){ + uint8_t data[2] = { reg, val }; + Wire.beginTransmission(PCA9533_Addr >> 1); + Wire.write(data, 2); + Wire.endTransmission(); + delayMicroseconds(1); +} + +// Reset (clear) all registers +void PCA9533_reset() { + PCA9533_writeAllRegisters(0, 0, 0, 0, 0); +} + +// Turn all LEDs off +void PCA9533_setOff() { + PCA9533_writeRegister(PCA9533_REG_SEL, 0); +} + +void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue) { + uint8_t r_pwm0 = 0; // Register data - PWM value + uint8_t r_pwm1 = 0; // Register data - PWM value + + uint8_t op_g = 0, op_r = 0, op_b = 0; // Opcodes - Green, Red, Blue + + // Light theory! GREEN takes priority because + // it's the most visible to the human eye. + if (green == 0) op_g = PCA9533_LED_OP_OFF; + else if (green == 255) op_g = PCA9533_LED_OP_ON; + else { r_pwm0 = green; op_g = PCA9533_LED_OP_PWM0; } + + // RED + if (red == 0) op_r = PCA9533_LED_OP_OFF; + else if (red == 255) op_r = PCA9533_LED_OP_ON; + else if (r_pwm0 == 0 || r_pwm0 == red) { + r_pwm0 = red; op_r = PCA9533_LED_OP_PWM0; + } + else { + r_pwm1 = red; op_r = PCA9533_LED_OP_PWM1; + } + + // BLUE + if (blue == 0) op_b = PCA9533_LED_OP_OFF; + else if (blue == 255) op_b = PCA9533_LED_OP_ON; + else if (r_pwm0 == 0 || r_pwm0 == blue) { + r_pwm0 = blue; op_b = PCA9533_LED_OP_PWM0; + } + else if (r_pwm1 == 0 || r_pwm1 == blue) { + r_pwm1 = blue; op_b = PCA9533_LED_OP_PWM1; + } + else { + /** + * Conflict. 3 values are requested but only 2 channels exist. + * G is on channel 0 and R is on channel 1, so work from there. + * Find the closest match, average the values, then use the free channel. + */ + uint8_t dgb = ABS(green - blue), + dgr = ABS(green - red), + dbr = ABS(blue - red); + if (dgb < dgr && dgb < dbr) { // Mix with G on channel 0. + op_b = PCA9533_LED_OP_PWM0; + r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)blue) / 2); + } + else if (dbr <= dgr && dbr <= dgb) { // Mix with R on channel 1. + op_b = PCA9533_LED_OP_PWM1; + r_pwm1 = uint8_t(((uint16_t)red + (uint16_t)blue) / 2); + } + else { // Mix R+G on 0 and put B on 1. + op_r = PCA9533_LED_OP_PWM0; + r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)red) / 2); + op_b = PCA9533_LED_OP_PWM1; + r_pwm1 = blue; + } + } + + // Write the changes to the hardware + PCA9533_writeAllRegisters(0, r_pwm0, 0, r_pwm1, + (op_g << PCA9533_LED_OFS_GRN) | (op_r << PCA9533_LED_OFS_RED) | (op_b << PCA9533_LED_OFS_BLU) + ); +} + +#endif // PCA9533 diff --git a/Marlin/src/feature/leds/pca9533.h b/Marlin/src/feature/leds/pca9533.h new file mode 100644 index 0000000..431058c --- /dev/null +++ b/Marlin/src/feature/leds/pca9533.h @@ -0,0 +1,59 @@ +/* + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/* + * Driver for the PCA9533 LED controller found on the MightyBoard + * used by FlashForge Creator Pro, MakerBot, etc. + * Written 2020 APR 01 by grauerfuchs + */ +#include + +#define ENABLE_I2C_PULLUPS + +// Chip address (for Wire) +#define PCA9533_Addr 0xC4 + +// Control registers +#define PCA9533_REG_READ 0x00 +#define PCA9533_REG_PSC0 0x01 +#define PCA9533_REG_PWM0 0x02 +#define PCA9533_REG_PSC1 0x03 +#define PCA9533_REG_PWM1 0x04 +#define PCA9533_REG_SEL 0x05 +#define PCA9533_REGM_AI 0x10 + +// LED selector operation +#define PCA9533_LED_OP_OFF 0B00 +#define PCA9533_LED_OP_ON 0B01 +#define PCA9533_LED_OP_PWM0 0B10 +#define PCA9533_LED_OP_PWM1 0B11 + +// Select register bit offsets for LED colors +#define PCA9533_LED_OFS_RED 0 +#define PCA9533_LED_OFS_GRN 2 +#define PCA9533_LED_OFS_BLU 4 + +void PCA9533_init(); +void PCA9533_reset(); +void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue); +void PCA9533_setOff(); diff --git a/Marlin/src/feature/leds/pca9632.cpp b/Marlin/src/feature/leds/pca9632.cpp new file mode 100644 index 0000000..bb30e0b --- /dev/null +++ b/Marlin/src/feature/leds/pca9632.cpp @@ -0,0 +1,164 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Driver for the Philips PCA9632 LED driver. + * Written by Robert Mendon Feb 2017. + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(PCA9632) + +#include "pca9632.h" +#include "leds.h" +#include + +#define PCA9632_MODE1_VALUE 0b00000001 //(ALLCALL) +#define PCA9632_MODE2_VALUE 0b00010101 //(DIMMING, INVERT, CHANGE ON STOP,TOTEM) +#define PCA9632_LEDOUT_VALUE 0b00101010 + +/* Register addresses */ +#define PCA9632_MODE1 0x00 +#define PCA9632_MODE2 0x01 +#define PCA9632_PWM0 0x02 +#define PCA9632_PWM1 0x03 +#define PCA9632_PWM2 0x04 +#define PCA9632_PWM3 0x05 +#define PCA9632_GRPPWM 0x06 +#define PCA9632_GRPFREQ 0x07 +#define PCA9632_LEDOUT 0x08 +#define PCA9632_SUBADR1 0x09 +#define PCA9632_SUBADR2 0x0A +#define PCA9632_SUBADR3 0x0B +#define PCA9632_ALLCALLADDR 0x0C + +#define PCA9632_NO_AUTOINC 0x00 +#define PCA9632_AUTO_ALL 0x80 +#define PCA9632_AUTO_IND 0xA0 +#define PCA9632_AUTOGLO 0xC0 +#define PCA9632_AUTOGI 0xE0 + +// Red=LED0 Green=LED1 Blue=LED2 White=LED3 +#ifndef PCA9632_RED + #define PCA9632_RED 0x00 +#endif +#ifndef PCA9632_GRN + #define PCA9632_GRN 0x02 +#endif +#ifndef PCA9632_BLU + #define PCA9632_BLU 0x04 +#endif +#if HAS_WHITE_LED && !defined(PCA9632_WHT) + #define PCA9632_WHT 0x06 +#endif + +// If any of the color indexes are greater than 0x04 they can't use auto increment +#if !defined(PCA9632_NO_AUTO_INC) && (PCA9632_RED > 0x04 || PCA9632_GRN > 0x04 || PCA9632_BLU > 0x04 || PCA9632_WHT > 0x04) + #define PCA9632_NO_AUTO_INC +#endif + +#define LED_OFF 0x00 +#define LED_ON 0x01 +#define LED_PWM 0x02 + +#define PCA9632_ADDRESS 0b01100000 + +byte PCA_init = 0; + +static void PCA9632_WriteRegister(const byte addr, const byte regadd, const byte value) { + Wire.beginTransmission(I2C_ADDRESS(addr)); + Wire.write(regadd); + Wire.write(value); + Wire.endTransmission(); +} + +static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const byte vr, const byte vg, const byte vb + #if ENABLED(PCA9632_RGBW) + , const byte vw + #endif +) { + #if DISABLED(PCA9632_NO_AUTO_INC) + uint8_t data[4]; + data[0] = PCA9632_AUTO_IND | regadd; + data[1 + (PCA9632_RED >> 1)] = vr; + data[1 + (PCA9632_GRN >> 1)] = vg; + data[1 + (PCA9632_BLU >> 1)] = vb; + Wire.beginTransmission(I2C_ADDRESS(addr)); + Wire.write(data, sizeof(data)); + Wire.endTransmission(); + #else + PCA9632_WriteRegister(addr, regadd + (PCA9632_RED >> 1), vr); + PCA9632_WriteRegister(addr, regadd + (PCA9632_GRN >> 1), vg); + PCA9632_WriteRegister(addr, regadd + (PCA9632_BLU >> 1), vb); + #if ENABLED(PCA9632_RGBW) + PCA9632_WriteRegister(addr, regadd + (PCA9632_WHT >> 1), vw); + #endif + #endif +} + +#if 0 + static byte PCA9632_ReadRegister(const byte addr, const byte regadd) { + Wire.beginTransmission(I2C_ADDRESS(addr)); + Wire.write(regadd); + const byte value = Wire.read(); + Wire.endTransmission(); + return value; + } +#endif + +void PCA9632_set_led_color(const LEDColor &color) { + Wire.begin(); + if (!PCA_init) { + PCA_init = 1; + PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE1, PCA9632_MODE1_VALUE); + PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE); + } + + const byte LEDOUT = (color.r ? LED_PWM << PCA9632_RED : 0) + | (color.g ? LED_PWM << PCA9632_GRN : 0) + | (color.b ? LED_PWM << PCA9632_BLU : 0) + #if ENABLED(PCA9632_RGBW) + | (color.w ? LED_PWM << PCA9632_WHT : 0) + #endif + ; + + PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, color.r, color.g, color.b + #if ENABLED(PCA9632_RGBW) + , color.w + #endif + ); + PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_LEDOUT, LEDOUT); +} + +#if ENABLED(PCA9632_BUZZER) + + void PCA9632_buzz(const long, const uint16_t) { + uint8_t data[] = PCA9632_BUZZER_DATA; + Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS)); + Wire.write(data, sizeof(data)); + Wire.endTransmission(); + } + +#endif // PCA9632_BUZZER + +#endif // PCA9632 diff --git a/Marlin/src/feature/leds/pca9632.h b/Marlin/src/feature/leds/pca9632.h new file mode 100644 index 0000000..fb59a8c --- /dev/null +++ b/Marlin/src/feature/leds/pca9632.h @@ -0,0 +1,37 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Driver for the Philips PCA9632 LED driver. + * Written by Robert Mendon Feb 2017. + */ + +struct LEDColor; +typedef LEDColor LEDColor; + +void PCA9632_set_led_color(const LEDColor &color); + +#if ENABLED(PCA9632_BUZZER) + #include + void PCA9632_buzz(const long, const uint16_t); +#endif diff --git a/Marlin/src/feature/leds/printer_event_leds.cpp b/Marlin/src/feature/leds/printer_event_leds.cpp new file mode 100644 index 0000000..3a6b91a --- /dev/null +++ b/Marlin/src/feature/leds/printer_event_leds.cpp @@ -0,0 +1,82 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * feature/leds/printer_event_leds.cpp - LED color changing based on printer status + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(PRINTER_EVENT_LEDS) + +#include "printer_event_leds.h" + +PrinterEventLEDs printerEventLEDs; + +#if HAS_LEDS_OFF_FLAG + bool PrinterEventLEDs::leds_off_after_print; // = false +#endif + +#if HAS_TEMP_HOTEND || HAS_HEATED_BED + + uint8_t PrinterEventLEDs::old_intensity = 0; + + inline uint8_t pel_intensity(const float &start, const float ¤t, const float &target) { + if (uint16_t(start) == uint16_t(target)) return 255; + return (uint8_t)map(constrain(current, start, target), start, target, 0.f, 255.f); + } + + inline void pel_set_rgb(const uint8_t r, const uint8_t g, const uint8_t b) { + leds.set_color( + MakeLEDColor(r, g, b, 0, neo.brightness()) + #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) + , true + #endif + ); + } + +#endif + +#if HAS_TEMP_HOTEND + + void PrinterEventLEDs::onHotendHeating(const float &start, const float ¤t, const float &target) { + const uint8_t blue = pel_intensity(start, current, target); + if (blue != old_intensity) { + old_intensity = blue; + pel_set_rgb(255, 0, 255 - blue); + } + } + +#endif + +#if HAS_HEATED_BED + + void PrinterEventLEDs::onBedHeating(const float &start, const float ¤t, const float &target) { + const uint8_t red = pel_intensity(start, current, target); + if (red != old_intensity) { + old_intensity = red; + pel_set_rgb(red, 0, 255); + } + } +#endif + +#endif // PRINTER_EVENT_LEDS diff --git a/Marlin/src/feature/leds/printer_event_leds.h b/Marlin/src/feature/leds/printer_event_leds.h new file mode 100644 index 0000000..86ec292 --- /dev/null +++ b/Marlin/src/feature/leds/printer_event_leds.h @@ -0,0 +1,87 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * feature/leds/printer_event_leds.h - LED color changing based on printer status + */ + +#include "leds.h" +#include "../../inc/MarlinConfig.h" + +class PrinterEventLEDs { +private: + static uint8_t old_intensity; + + #if HAS_LEDS_OFF_FLAG + static bool leds_off_after_print; + #endif + + static inline void set_done() { + #if ENABLED(LED_COLOR_PRESETS) + leds.set_default(); + #else + leds.set_off(); + #endif + } + +public: + #if HAS_TEMP_HOTEND + static inline LEDColor onHotendHeatingStart() { old_intensity = 0; return leds.get_color(); } + static void onHotendHeating(const float &start, const float ¤t, const float &target); + #endif + + #if HAS_HEATED_BED + static inline LEDColor onBedHeatingStart() { old_intensity = 127; return leds.get_color(); } + static void onBedHeating(const float &start, const float ¤t, const float &target); + #endif + + #if HAS_TEMP_HOTEND || HAS_HEATED_BED + static inline void onHeatingDone() { leds.set_white(); } + static inline void onPidTuningDone(LEDColor c) { leds.set_color(c); } + #endif + + #if ENABLED(SDSUPPORT) + + static inline void onPrintCompleted() { + leds.set_green(); + #if HAS_LEDS_OFF_FLAG + leds_off_after_print = true; + #else + safe_delay(2000); + set_done(); + #endif + } + + static inline void onResumeAfterWait() { + #if HAS_LEDS_OFF_FLAG + if (leds_off_after_print) { + set_done(); + leds_off_after_print = false; + } + #endif + } + + #endif // SDSUPPORT +}; + +extern PrinterEventLEDs printerEventLEDs; diff --git a/Marlin/src/feature/leds/tempstat.cpp b/Marlin/src/feature/leds/tempstat.cpp new file mode 100644 index 0000000..880258f --- /dev/null +++ b/Marlin/src/feature/leds/tempstat.cpp @@ -0,0 +1,55 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Marlin RGB LED general support + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(TEMP_STAT_LEDS) + +#include "tempstat.h" +#include "../../module/temperature.h" + +void handle_status_leds() { + static int8_t old_red = -1; // Invalid value to force LED initialization + static millis_t next_status_led_update_ms = 0; + if (ELAPSED(millis(), next_status_led_update_ms)) { + next_status_led_update_ms += 500; // Update every 0.5s + float max_temp = TERN0(HAS_HEATED_BED, _MAX(thermalManager.degTargetBed(), thermalManager.degBed())); + HOTEND_LOOP() + max_temp = _MAX(max_temp, thermalManager.degHotend(e), thermalManager.degTargetHotend(e)); + const int8_t new_red = (max_temp > 55.0) ? HIGH : (max_temp < 54.0 || old_red < 0) ? LOW : old_red; + if (new_red != old_red) { + old_red = new_red; + #if PIN_EXISTS(STAT_LED_RED) + WRITE(STAT_LED_RED_PIN, new_red); + #endif + #if PIN_EXISTS(STAT_LED_BLUE) + WRITE(STAT_LED_BLUE_PIN, !new_red); + #endif + } + } +} + +#endif // TEMP_STAT_LEDS diff --git a/Marlin/src/feature/leds/tempstat.h b/Marlin/src/feature/leds/tempstat.h new file mode 100644 index 0000000..a8b919b --- /dev/null +++ b/Marlin/src/feature/leds/tempstat.h @@ -0,0 +1,28 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Marlin general RGB LED support + */ + +void handle_status_leds(); -- cgit v1.2.3