mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
ed5455458b
* Handle Exceptions in main & Pythoninit * Have SSDPDiscover generic again * Have SSDPDiscover generic again * Change Info- to Debug logs as technical service messages * Nanoleaf - When switched on, ensure UDP mode * Include SQL Database in Cross-Compile instructions * Fix Clazy (QT code checker) and clang Warnings * Stop LedDevice:write for disabled device * Nanoleaf: Fix uint printfs * NanoLeaf: Fix indents to tabs * NanoLeaf - Add debug verbosity switches * Device switchability support, FileDevice with timestamp support * Nanoleaf Light Panels now support External Control V2 * Enhance LedDeviceFile by Timestamp + fix readyness * Stop color stream, if LedDevice disabled * Nanoleaf - remove switchability * Fix MultiColorAdjustment, if led-range is greater lednum * Fix logging * LedFileDevice/LedDevice - add testing support * New "Led Test" effect * LedDeviceFile - Add chrono include + Allow Led rewrites for testing * Stabilize Effects for LedDevices where latchtime = 0 * Update LedDeviceFile, allow latchtime = 0 * Distangle LinearColorSmoothing and LEDDevice, Fix Effect configuration updates * Updates LedDeviceFile - Initialize via Open * Updates LedDeviceNanoleaf - Initialize via Open, Remove throwing exceptions * Updates ProviderUDP - Remove throwing exceptions * Framebuffer - Use precise timer * TestSpi - Align to LedDevice updates * Pretty Print CrossCompileHowTo as markdown-file * Ensure that output is only written when LedDevice is ready * Align APA102 Device to new device staging * Logger - Remove clang warnings on extra semicolon * Devices SPI - Align to Device stages and methods * Fix cppcheck and clang findings * Add Code-Template for new Devices * Align devices to stages and methods, clean-up some code * Allow to reopen LedDevice without restart * Revert change "Remove Connect (PriorityMuxer::visiblePriorityChanged -> Hyperion::update) due to double writes" * Remove visiblePriorityChanged from LedDevice to decouple LedDevice from hyperion logic * Expose LedDevice getLedCount and align signedness
115 lines
5.0 KiB
C++
115 lines
5.0 KiB
C++
#pragma once
|
|
|
|
// Local hyperion includes
|
|
#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
|
|
///
|
|
explicit LedDeviceLpd8806(const QJsonObject &deviceConfig);
|
|
|
|
/// constructs leddevice
|
|
static LedDevice* construct(const QJsonObject &deviceConfig);
|
|
|
|
///
|
|
/// Sets configuration
|
|
///
|
|
/// @param deviceConfig the json device config
|
|
/// @return true if success
|
|
virtual bool init(const QJsonObject &deviceConfig) override;
|
|
|
|
protected:
|
|
///
|
|
/// Opens and initiatialises the output device
|
|
///
|
|
/// @return Zero on succes (i.e. device is ready and enabled) else negative
|
|
///
|
|
virtual int open() override;
|
|
|
|
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) override;
|
|
};
|