Fasterhardwarespi (#137)

* Improved HW SPI sending

* update version
This commit is contained in:
Michael Miller
2016-11-09 10:25:27 -08:00
committed by GitHub
parent b41674dec0
commit 94f5ad3dd7
3 changed files with 46 additions and 31 deletions

View File

@@ -8,7 +8,7 @@
"type": "git", "type": "git",
"url": "https://github.com/Makuna/NeoPixelBus" "url": "https://github.com/Makuna/NeoPixelBus"
}, },
"version": "2.2.3", "version": "2.2.4",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*" "platforms": "*"
} }

View File

@@ -1,5 +1,5 @@
name=NeoPixelBus by Makuna name=NeoPixelBus by Makuna
version=2.2.3 version=2.2.4
author=Michael C. Miller (makuna@live.com) author=Michael C. Miller (makuna@live.com)
maintainer=Michael C. Miller (makuna@live.com) maintainer=Michael C. Miller (makuna@live.com)
sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) and DotStars (ADA102) easy. sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) and DotStars (ADA102) easy.

View File

@@ -32,16 +32,18 @@ class DotStarSpiMethod
{ {
public: public:
DotStarSpiMethod(uint16_t pixelCount, size_t elementSize) : DotStarSpiMethod(uint16_t pixelCount, size_t elementSize) :
_sizePixels(pixelCount * elementSize) _sizeData(pixelCount * elementSize),
_sizeSendBuffer(calcBufferSize(pixelCount * elementSize))
{ {
_pixels = (uint8_t*)malloc(_sizePixels); _sendBuffer = (uint8_t*)malloc(_sizeSendBuffer);
memset(_pixels, 0, _sizePixels); memset(_sendBuffer, 0, _sizeSendBuffer);
setEndFrameBytes();
} }
~DotStarSpiMethod() ~DotStarSpiMethod()
{ {
SPI.end(); SPI.end();
free(_pixels); free(_sendBuffer);
} }
bool IsReadyToUpdate() const bool IsReadyToUpdate() const
@@ -66,43 +68,56 @@ public:
void Update() void Update()
{ {
// start frame // due to API inconsistencies need to call different methods on SPI
for (int startFrameByte = 0; startFrameByte < 4; startFrameByte++) #if defined(ARDUINO_ARCH_ESP8266)
{ SPI.writeBytes(_sendBuffer, _sizeSendBuffer);
SPI.transfer(0x00); #else
} SPI.transfer(_sendBuffer, _sizeSendBuffer);
#endif
// data
uint8_t* data = _pixels;
const uint8_t* endData = _pixels + _sizePixels;
while (data < endData)
{
SPI.transfer(*data++);
}
// end frame
// one bit for every two pixels with no less than 1 byte
const uint16_t countEndFrameBytes = ((_sizePixels / 4) + 15) / 16;
for (uint16_t endFrameByte = 0; endFrameByte < countEndFrameBytes; endFrameByte++)
{
SPI.transfer(0xff);
}
} }
uint8_t* getPixels() const uint8_t* getPixels() const
{ {
return _pixels; return _sendBuffer + _countStartFrame;
}; };
size_t getPixelsSize() const size_t getPixelsSize() const
{ {
return _sizePixels; return _sizeData;
}; };
private: private:
const size_t _sizePixels; // Size of '_pixels' buffer below const size_t _countStartFrame = 4;
const size_t _sizeData; // size of actuall pixel data within _sendBuffer
const size_t _sizeSendBuffer; // Size of '_sendBuffer' buffer below
uint8_t* _pixels; // Holds LED color values uint8_t* _sendBuffer; // Holds SPI send Buffer, including LED color values
size_t calcBufferSize(size_t sizePixels) const
{
const size_t countEndFrameBytes = calcEndFrameSize(sizePixels);
// start frame + data + end frame
const size_t bufferSize = _countStartFrame + sizePixels + countEndFrameBytes;
return bufferSize;
}
size_t calcEndFrameSize(size_t sizePixels) const
{
// end frame
// one bit for every two pixels with no less than 1 byte
return ((sizePixels / 4) + 15) / 16;
}
void setEndFrameBytes()
{
uint8_t* pEndFrame = _sendBuffer + _countStartFrame + _sizeData;
uint8_t* pEndFrameStop = pEndFrame + calcEndFrameSize(_sizeData);
while (pEndFrame != pEndFrameStop)
{
*pEndFrame++ = 0xff;
}
}
}; };