diff --git a/libsrc/hyperion/device/LedDeviceWs2811.cpp b/libsrc/hyperion/device/LedDeviceWs2811.cpp index 2f5a4cf7..f7a2674c 100644 --- a/libsrc/hyperion/device/LedDeviceWs2811.cpp +++ b/libsrc/hyperion/device/LedDeviceWs2811.cpp @@ -2,10 +2,141 @@ // Local hyperion includes #include "LedDeviceWs2811.h" -LedDeviceWs2811::LedDeviceWs2811(const std::string & deviceName) : - LedRs232Device(deviceName, ws2811::getBaudrate(ws2811::option_1)) + +ws2811::SignalTiming ws2811::fromString(const std::string& signalTiming, const SignalTiming defaultValue) { - fillEncodeTable(ws2811::option_1); + SignalTiming result = defaultValue; + if (signalTiming == "3755" || signalTiming == "option_3755") + { + result = option_3755; + } + else if (signalTiming == "3773" || signalTiming == "option_3773") + { + result = option_3773; + } + else if (signalTiming == "2855" || signalTiming == "option_2855") + { + result = option_2855; + } + else if (signalTiming == "2882" || signalTiming == "option_2882") + { + result = option_2882; + } + + return result; +} + +unsigned ws2811::getBaudrate(const SpeedMode speedMode) +{ + switch (speedMode) + { + case highspeed: + // Bit length: 125ns + return 8000000; + case lowspeed: + // Bit length: 250ns + return 4000000; + } + + return 0; +} +inline unsigned ws2811::getLength(const SignalTiming timing, const TimeOption option) +{ + switch (timing) + { + case option_3755: + // Reference: http://www.mikrocontroller.net/attachment/180459/WS2812B_preliminary.pdf + // Unit length: 125ns + switch (option) + { + case T0H: + return 3; // 400ns +-150ns + case T0L: + return 7; // 850ns +-150ns + case T1H: + return 7; // 800ns +-150ns + case T1L: + return 3; // 450ns +-150ns + } + case option_3773: + // Reference: www.adafruit.com/datasheets/WS2812.pdf‎ + // Unit length: 125ns + switch (option) + { + case T0H: + return 3; // 350ns +-150ns + case T0L: + return 7; // 800ns +-150ns + case T1H: + return 7; // 700ns +-150ns + case T1L: + return 3; // 600ns +-150ns + } + case option_2855: + // Reference: www.adafruit.com/datasheets/WS2811.pdf‎ + // Unit length: 250ns + switch (option) + { + case T0H: + return 2; // 500ns +-150ns + case T0L: + return 8; // 2000ns +-150ns + case T1H: + return 5; // 1200ns +-150ns + case T1L: + return 5; // 1300ns +-150ns + } + case option_2882: + // Reference: www.szparkson.net/download/WS2811.pdf‎ + // Unit length: 250ns + switch (option) + { + case T0H: + return 2; // 500ns +-150ns + case T0L: + return 8; // 2000ns +-150ns + case T1H: + return 8; // 2000ns +-150ns + case T1L: + return 2; // 500ns +-150ns + } + default: + std::cerr << "Unknown signal timing for ws2811: " << timing << std::endl; + } + return 0; +} + +uint8_t ws2811::bitToSignal(unsigned lenHigh) +{ + // Sanity check on the length of the 'high' signal + assert(0 < lenHigh && lenHigh < 10); + + uint8_t result = 0x00; + for (unsigned i=1; i & ledValues) diff --git a/libsrc/hyperion/device/LedDeviceWs2811.h b/libsrc/hyperion/device/LedDeviceWs2811.h index 532c59be..3070bd35 100644 --- a/libsrc/hyperion/device/LedDeviceWs2811.h +++ b/libsrc/hyperion/device/LedDeviceWs2811.h @@ -8,12 +8,22 @@ namespace ws2811 { + /** + * Enumaration of known signal timings + */ enum SignalTiming { - option_1, - option_2, - option_3, - option_4 + option_3755, + option_3773, + option_2855, + option_2882, + not_a_signaltiming + }; + + enum SpeedMode + { + lowspeed, + highspeed }; /** @@ -28,99 +38,8 @@ namespace ws2811 }; /** - * Returns the required baudrate for a specific signal-timing - * - * @param timing The WS2811/WS2812/WS2812b option - * - * @return The required baudrate for the signal timing + * Structure holding the signal for a signle byte */ - inline unsigned getBaudrate(const SignalTiming timing) - { - switch (timing) - { - case option_1: - case option_2: - // Bit length: 125ns - return 8000000; - case option_3: - case option_4: - // Bit length: 250ns - return 4000000; - } - - return 0; - } - - /** - * The number of 'signal units' (bits) For the subpart of a specific timing scheme - * - * @param timing The controller option - * @param option The signal part - */ - inline unsigned getLength(const SignalTiming timing, const TimeOption option) - { - switch (timing) - { - case option_1: - // Reference: www.adafruit.com/datasheets/WS2812.pdf‎ - // Unit length: 125ns - switch (option) - { - case T0H: - return 3; // 350ns +-150ns - case T0L: - return 7; // 800ns +-150ns - case T1H: - return 6; // 700ns +-150ns - case T1L: - return 4; // 600ns +-150ns - } - case option_3: - // Reference: http://www.mikrocontroller.net/attachment/180459/WS2812B_preliminary.pdf - // Unit length: 125ns - switch (option) - { - case T0H: - return 3; // 400ns +-150ns - case T0L: - return 7; // 850ns +-150ns - case T1H: - return 7; // 800ns +-150ns - case T1L: - return 3; // 450ns +-150ns - } - case option_2: - // Reference: www.adafruit.com/datasheets/WS2811.pdf‎ - // Unit length: 250ns - switch (option) - { - case T0H: - return 2; // 500ns +-150ns - case T0L: - return 8; // 2000ns +-150ns - case T1H: - return 5; // 1200ns +-150ns - case T1L: - return 5; // 1300ns +-150ns - } - case option_4: - // Reference: www.szparkson.net/download/WS2811.pdf‎ - // Unit length: 250ns - switch (option) - { - case T0H: - return 2; // 500ns +-150ns - case T0L: - return 8; // 2000ns +-150ns - case T1H: - return 8; // 2000ns +-150ns - case T1L: - return 2; // 500ns +-150ns - } - } - return 0; - } - struct ByteSignal { uint8_t bit_1; @@ -132,9 +51,36 @@ namespace ws2811 uint8_t bit_7; uint8_t bit_8; }; - + // Make sure the structure is exatly the length we require static_assert(sizeof(ByteSignal) == 8, "Incorrect sizeof ByteSignal (expected 8)"); + /** + * Translates a string to a signal timing + * + * @param signalTiming The string specifying the signal timing + * @param defaultValue The default value (used if the string does not match any known timing) + * + * @return The SignalTiming (or not_a_signaltiming if it did not match) + */ + SignalTiming fromString(const std::string& signalTiming, const SignalTiming defaultValue); + + /** + * Returns the required baudrate for a specific signal-timing + * + * @param SpeedMode The WS2811/WS2812 speed mode (WS2812b only has highspeed) + * + * @return The required baudrate for the signal timing + */ + unsigned getBaudrate(const SpeedMode speedMode); + + /** + * The number of 'signal units' (bits) For the subpart of a specific timing scheme + * + * @param timing The controller option + * @param option The signal part + */ + unsigned getLength(const SignalTiming timing, const TimeOption option); + /** * Constructs a 'bit' based signal with defined 'high' length (and implicite defined 'low' * length. The signal is based on a 10bits bytes (incl. high startbit and low stopbit). The @@ -144,18 +90,7 @@ namespace ws2811 * @param lenHigh The total length of the 'high' length (incl start-bit) * @return The byte representing the high-low signal */ - inline uint8_t bitToSignal(unsigned lenHigh) - { - // Sanity check on the length of the 'high' signal - assert(0 < lenHigh && lenHigh < 10); - - uint8_t result = 0x00; - for (unsigned i=1; i