[UNTESTED] Add support for apa104 led type

This commit is contained in:
penfold42 2018-03-01 17:31:04 +11:00
parent e438bc62a6
commit e190a51cfc
5 changed files with 175 additions and 1 deletions

View File

@ -470,7 +470,7 @@ $(document).ready(function() {
// create led device selection // create led device selection
ledDevices = serverInfo.ledDevices.available ledDevices = serverInfo.ledDevices.available
devRPiSPI = ['apa102', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'ws2812spi']; devRPiSPI = ['apa102', 'apa104', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'ws2812spi'];
devRPiPWM = ['ws281x']; devRPiPWM = ['ws281x'];
devRPiGPIO = ['piblaster']; devRPiGPIO = ['piblaster'];
devNET = ['atmoorb', 'fadecandy', 'philipshue', 'tinkerforge', 'tpm2net', 'udpe131', 'udpartnet', 'udph801', 'udpraw']; devNET = ['atmoorb', 'fadecandy', 'philipshue', 'tinkerforge', 'tpm2net', 'udpe131', 'udpartnet', 'udph801', 'udpraw'];

View File

@ -29,6 +29,7 @@
<file alias="schema-udpraw">schemas/schema-udpraw.json</file> <file alias="schema-udpraw">schemas/schema-udpraw.json</file>
<file alias="schema-ws2801">schemas/schema-ws2801.json</file> <file alias="schema-ws2801">schemas/schema-ws2801.json</file>
<file alias="schema-ws2812spi">schemas/schema-ws2812spi.json</file> <file alias="schema-ws2812spi">schemas/schema-ws2812spi.json</file>
<file alias="schema-apa104">schemas/schema-apa104.json</file>
<file alias="schema-ws281x">schemas/schema-ws281x.json</file> <file alias="schema-ws281x">schemas/schema-ws281x.json</file>
<file alias="schema-karate">schemas/schema-karate.json</file> <file alias="schema-karate">schemas/schema-karate.json</file>
</qresource> </qresource>

View File

@ -0,0 +1,95 @@
#include "LedDeviceAPA104.h"
/*
From the data sheet:
(TH+TL=1.25μs±600ns)
T0H, 0 code, high level time, 350ns ±150ns
T0L, 0 code, low level time, 1360ns ±150ns
T1H, 1 code, high level time, 360ns ±150ns
T1L, 1 code, low level time, 45ns ±150ns
WT, Wait for the processing time, NA
Trst, Reset code,low level time, 24µs
To normalise the pulse times so they fit in 4 SPI bits:
On the assumption that the "low" time doesnt matter much
A SPI bit time of 0.40uS = 2.5 Mbit/sec
T0 is sent as 1000
T1 is sent as 1110
With a bit of excel testing, we can work out the maximum and minimum speeds:
2000000 MIN
2235000 AVG
2470000 MAX
Wait time:
Not Applicable for WS2812
Reset time:
using the max of 2470000, the bit time is 405nS
Reset time is 24uS = 59 bits = 8 bytes
*/
LedDeviceAPA104::LedDeviceAPA104(const QJsonObject &deviceConfig)
: ProviderSpi()
, SPI_BYTES_PER_COLOUR(4)
, SPI_FRAME_END_LATCH_BYTES(116)
, bitpair_to_byte {
0b10001000,
0b10001100,
0b11001000,
0b11001100,
}
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceAPA104::construct(const QJsonObject &deviceConfig)
{
return new LedDeviceAPA104(deviceConfig);
}
bool LedDeviceAPA104::init(const QJsonObject &deviceConfig)
{
_baudRate_Hz = 2235000;
if ( !ProviderSpi::init(deviceConfig) )
{
return false;
}
WarningIf(( _baudRate_Hz < 2000000 || _baudRate_Hz > 2470000 ), _log, "SPI rate %d outside recommended range (2000000 -> 2470000)", _baudRate_Hz);
_ledBuffer.resize(_ledRGBCount * SPI_BYTES_PER_COLOUR + SPI_FRAME_END_LATCH_BYTES, 0x00);
return true;
}
int LedDeviceAPA104::write(const std::vector<ColorRgb> &ledValues)
{
unsigned spi_ptr = 0;
const int SPI_BYTES_PER_LED = sizeof(ColorRgb) * SPI_BYTES_PER_COLOUR;
for (const ColorRgb& color : ledValues)
{
uint32_t colorBits = ((unsigned int)color.red << 16)
| ((unsigned int)color.green << 8)
| color.blue;
for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--)
{
_ledBuffer[spi_ptr+j] = bitpair_to_byte[ colorBits & 0x3 ];
colorBits >>= 2;
}
spi_ptr += SPI_BYTES_PER_LED;
}
for (int j=0; j < SPI_FRAME_END_LATCH_BYTES; j++)
{
_ledBuffer[spi_ptr++] = 0;
}
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -0,0 +1,43 @@
#pragma once
// hyperion incluse
#include "ProviderSpi.h"
///
/// Implementation of the LedDevice interface for writing to APA104 led device via spi.
///
class LedDeviceAPA104 : public ProviderSpi
{
public:
///
/// Constructs specific LedDevice
///
/// @param deviceConfig json device config
///
LedDeviceAPA104(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);
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);
const int SPI_BYTES_PER_COLOUR;
const int SPI_FRAME_END_LATCH_BYTES;
uint8_t bitpair_to_byte[4];
};

View File

@ -0,0 +1,35 @@
{
"type":"object",
"required":true,
"properties":{
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {
"type": "integer",
"title":"edt_dev_spec_baudrate_title",
"default": 2235000,
"propertyOrder" : 2
},
"invert": {
"type": "boolean",
"title":"edt_dev_spec_invert_title",
"default": false,
"propertyOrder" : 3
},
"latchTime": {
"type": "integer",
"title":"edt_dev_spec_latchtime_title",
"default": 1,
"append" : "edt_append_ms",
"minimum": 1,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 4
}
},
"additionalProperties": true
}