hyperion.ng/libsrc/leddevice/LedDeviceLpd8806.h
Paulchen Panther 464de381a0 JsonCpp to QTJson (Final Part) (#273)
* Update CMakeLists.txt

* Update Hyperion.h

* Update LedDevice.h

* Update LedDeviceFactory.h

* Update Hyperion.cpp

* Update LedString.cpp

* Update JsonClientConnection.cpp

* Update LedDeviceAdalight.cpp

* Update LedDeviceAdalight.h

* Update LedDeviceAPA102.cpp

* Update LedDeviceAdalightApa102.h

* Update LedDeviceAdalightApa102.cpp

* Update LedDeviceAPA102.h

* Update LedDeviceAtmo.cpp

* Update LedDeviceAtmo.h

* Update LedDeviceAtmoOrb.cpp

* Update LedDeviceAtmoOrb.h

* Update LedDeviceDMX.cpp

* Update LedDeviceDMX.h

* Update LedDeviceFactory.cpp

* Update LedDeviceFadeCandy.cpp

* Update LedDeviceFadeCandy.h

* Update LedDeviceFile.cpp

* Update LedDeviceFile.h

* Update LedDeviceHyperionUsbasp.cpp

* Update LedDeviceHyperionUsbasp.h

* Update LedDeviceLightpack.cpp

* Update LedDeviceLightpack.h

* Update LedDeviceLpd6803.cpp

* Update LedDeviceLpd6803.h

* Update LedDeviceLpd8806.cpp

* Update LedDeviceLpd8806.h

* Update LedDeviceMultiLightpack.cpp

* Update LedDeviceMultiLightpack.h

* Update LedDeviceP9813.cpp

* Update LedDeviceP9813.h

* Update LedDevicePaintpack.cpp

* Update LedDevicePaintpack.h

* Update LedDevicePhilipsHue.cpp

* Update LedDevicePhilipsHue.h

* Update LedDevicePiBlaster.cpp

* Update LedDevicePiBlaster.h

* Update LedDeviceRawHID.cpp

* Update LedDeviceRawHID.h

* Update LedDeviceSedu.cpp

* Update LedDeviceSedu.h

* Update LedDeviceSk6812SPI.cpp

* Update LedDeviceSk6812SPI.h

* Update LedDeviceTinkerforge.cpp

* Update LedDeviceTinkerforge.h

* Update LedDeviceTpm2.cpp

* Update LedDeviceTpm2.h

* Update LedDeviceTpm2net.cpp

* Update LedDeviceTpm2net.h

* Update LedDeviceUdpE131.cpp

* Update LedDeviceUdpE131.h

* Update LedDeviceUdpH801.cpp

* Update LedDeviceUdpH801.h

* Update LedDeviceUdpRaw.cpp

* Update LedDeviceUdpRaw.h

* Update LedDeviceWs2801.cpp

* Update LedDeviceWs2801.h

* Update LedDeviceWS2812b.cpp

* Update LedDeviceWS2812b.h

* Update LedDeviceWs2812SPI.cpp

* Update LedDeviceWs2812SPI.h

* Update LedDeviceWS281x.cpp

* Update LedDeviceWS281x.h

* Update ProviderHID.cpp

* Update ProviderHID.h

* Update ProviderRs232.cpp

* Update ProviderRs232.h

* Update ProviderSpi.cpp

* Update ProviderSpi.h

* Update ProviderUdp.cpp

* Update ProviderUdp.h

* Update LedDevice.cpp

* Update CMakeLists.txt

* Update hyperiond.cpp

* Update hyperiond.h

* Update TestSpi.cpp

* Delete AUTHORS

* Delete CMakeLists.txt

* Delete LICENSE

* Delete json_batchallocator.h

* Delete json_internalarray.inl

* Delete json_internalmap.inl

* Delete json_reader.cpp

* Delete json_tool.h

* Delete json_value.cpp

* Delete json_valueiterator.inl

* Delete json_writer.cpp

* Delete sconscript

* Delete autolink.h

* Delete config.h

* Delete features.h

* Delete forwards.h

* Delete json.h

* Delete reader.h

* Delete value.h

* Delete writer.h
2016-10-13 21:59:58 +02:00

102 lines
4.6 KiB
C++

#pragma once
// Local hyperion incluse
#include "ProviderSpi.h"
///
/// Implementation of the LedDevice interface for writing to LPD8806 led device.
///
/// The following description is copied from 'adafruit' (github.com/adafruit/LPD8806)
///
/// Clearing up some misconceptions about how the LPD8806 drivers work:
///
/// The LPD8806 is not a FIFO shift register. The first data out controls the
/// LED *closest* to the processor (unlike a typical shift register, where the
/// first data out winds up at the *furthest* LED). Each LED driver 'fills up'
/// with data and then passes through all subsequent bytes until a latch
/// condition takes place. This is actually pretty common among LED drivers.
///
/// All color data bytes have the high bit (128) set, with the remaining
/// seven bits containing a brightness value (0-127). A byte with the high
/// bit clear has special meaning (explained later).
///
/// The rest gets bizarre...
///
/// The LPD8806 does not perform an in-unison latch (which would display the
/// newly-transmitted data all at once). Rather, each individual byte (even
/// the separate G, R, B components of each LED) is latched AS IT ARRIVES...
/// or more accurately, as the first bit of the subsequent byte arrives and
/// is passed through. So the strip actually refreshes at the speed the data
/// is issued, not instantaneously (this can be observed by greatly reducing
/// the data rate). This has implications for POV displays and light painting
/// applications. The 'subsequent' rule also means that at least one extra
/// byte must follow the last pixel, in order for the final blue LED to latch.
///
/// To reset the pass-through behavior and begin sending new data to the start
/// of the strip, a number of zero bytes must be issued (remember, all color
/// data bytes have the high bit set, thus are in the range 128 to 255, so the
/// zero is 'special'). This should be done before each full payload of color
/// values to the strip. Curiously, zero bytes can only travel one meter (32
/// LEDs) down the line before needing backup; the next meter requires an
/// extra zero byte, and so forth. Longer strips will require progressively
/// more zeros. *(see note below)
///
/// In the interest of efficiency, it's possible to combine the former EOD
/// extra latch byte and the latter zero reset...the same data can do double
/// duty, latching the last blue LED while also resetting the strip for the
/// next payload.
///
/// So: reset byte(s) of suitable length are issued once at startup to 'prime'
/// the strip to a known ready state. After each subsequent LED color payload,
/// these reset byte(s) are then issued at the END of each payload, both to
/// latch the last LED and to prep the strip for the start of the next payload
/// (even if that data does not arrive immediately). This avoids a tiny bit
/// of latency as the new color payload can begin issuing immediately on some
/// signal, such as a timer or GPIO trigger.
///
/// Technically these zero byte(s) are not a latch, as the color data (save
/// for the last byte) is already latched. It's a start-of-data marker, or
/// an indicator to clear the thing-that's-not-a-shift-register. But for
/// conversational consistency with other LED drivers, we'll refer to it as
/// a 'latch' anyway.
///
/// This has been validated independently with multiple customers'
/// hardware. Please do not report as a bug or issue pull requests for
/// this. Fewer zeros sometimes gives the *illusion* of working, the first
/// payload will correctly load and latch, but subsequent frames will drop
/// data at the end. The data shortfall won't always be visually apparent
/// depending on the color data loaded on the prior and subsequent frames.
/// Tested. Confirmed. Fact.
///
///
/// The summary of the story is that the following needs to be writen on the spi-device:
/// 1RRRRRRR 1GGGGGGG 1BBBBBBB 1RRRRRRR 1GGGGGGG ... ... 1GGGGGGG 1BBBBBBB 00000000 00000000 ...
/// |---------led_1----------| |---------led_2-- -led_n----------| |----clear data--
///
/// The number of zeroes in the 'clear data' is (#led/32 + 1)bytes (or *8 for bits)
///
class LedDeviceLpd8806 : public ProviderSpi
{
public:
///
/// Constructs specific LedDevice
///
/// @param deviceConfig json device config
///
LedDeviceLpd8806(const QJsonObject &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const QJsonObject &deviceConfig);
virtual bool init(const QJsonObject &deviceConfig);
private:
///
/// Writes the led color values to the led-device
///
/// @param ledValues The color-value per led
/// @return Zero on succes else negative
///
virtual int write(const std::vector<ColorRgb> &ledValues);
};