#pragma once // STL includes #include // Local hyperion includes #include "LedRs232Device.h" namespace ws2811 { enum SignalTiming { option_1, option_2, option_3, option_4 }; /** * Enumeration of the signal 'parts' (T 0 high, T 1 high, T 0 low, T 1 low). */ enum TimeOption { T0H, T1H, T0L, T1L }; /** * Returns the required baudrate for a specific signal-timing * * @param timing The WS2811/WS2812/WS2812b option * * @return The required baudrate for the signal timing */ 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; uint8_t bit_2; uint8_t bit_3; uint8_t bit_4; uint8_t bit_5; uint8_t bit_6; uint8_t bit_7; uint8_t bit_8; }; static_assert(sizeof(ByteSignal) == 8, "Incorrect sizeof ByteSignal (expected 8)"); /** * 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 * total length of the high is given as parameter:
* lenHigh=7 => |-------|___| => 1 1111 1100 0 => 252 (start and stop bit are implicite) * * @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 & ledValues); /// Switch the leds off virtual int switchOff(); private: void fillEncodeTable(const ws2811::SignalTiming ledOption); /** Translation table of byte to signal */ std::vector _byteToSignalTable; /// The buffer containing the packed RGB values std::vector _ledBuffer; };