forked from Makuna/NeoPixelBus
Lpd8806 (#291)
* SpecificMethod * DotStar and Lpd8806 SPI speeds selectable
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Arduino NeoPixel library
|
Arduino NeoPixel library
|
||||||
|
|
||||||
A library to control one wire protocol RGB and RGBW leds like APA106, SK6812, WS2811, WS2812 and WS2813 that are commonly refered to as NeoPixels and two wire protocol RGB like APA102 commonly refered to as DotStars.
|
A library to control one wire protocol RGB and RGBW leds like APA106, SK6812, WS2811, WS2812 and WS2813 that are commonly refered to as NeoPixels and two wire protocol RGB like Lpd8806 and APA102 commonly refered to as DotStars.
|
||||||
Supports most Arduino platforms.
|
Supports most Arduino platforms.
|
||||||
This is the most functional library for the Esp8266 as it provides solutions for all Esp8266 module types even when WiFi is used.
|
This is the most functional library for the Esp8266 as it provides solutions for all Esp8266 module types even when WiFi is used.
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ NeoBrgFeature KEYWORD1
|
|||||||
NeoRbgFeature KEYWORD1
|
NeoRbgFeature KEYWORD1
|
||||||
DotStarBgrFeature KEYWORD1
|
DotStarBgrFeature KEYWORD1
|
||||||
DotStarLbgrFeature KEYWORD1
|
DotStarLbgrFeature KEYWORD1
|
||||||
|
Lpd8806GrbFeature KEYWORD1
|
||||||
Neo800KbpsMethod KEYWORD1
|
Neo800KbpsMethod KEYWORD1
|
||||||
Neo400KbpsMethod KEYWORD1
|
Neo400KbpsMethod KEYWORD1
|
||||||
NeoWs2813Method KEYWORD1
|
NeoWs2813Method KEYWORD1
|
||||||
@@ -123,6 +124,14 @@ NeoEsp32BitBang800KbpsMethod KEYWORD1
|
|||||||
NeoEsp32BitBang400KbpsMethod KEYWORD1
|
NeoEsp32BitBang400KbpsMethod KEYWORD1
|
||||||
DotStarMethod KEYWORD1
|
DotStarMethod KEYWORD1
|
||||||
DotStarSpiMethod KEYWORD1
|
DotStarSpiMethod KEYWORD1
|
||||||
|
DotStarSpi20MhzMethod KEYWORD1
|
||||||
|
DotStarSpi10MhzMethod KEYWORD1
|
||||||
|
DotStarSpi2MhzMethod KEYWORD1
|
||||||
|
Lpd8806Method KEYWORD1
|
||||||
|
Lpd8806SpiMethod KEYWORD1
|
||||||
|
Lpd8806Spi20MhzMethod KEYWORD1
|
||||||
|
Lpd8806Spi10MhzMethod KEYWORD1
|
||||||
|
Lpd8806Spi2MhzMethod KEYWORD1
|
||||||
NeoPixelAnimator KEYWORD1
|
NeoPixelAnimator KEYWORD1
|
||||||
AnimUpdateCallback KEYWORD1
|
AnimUpdateCallback KEYWORD1
|
||||||
AnimationParam KEYWORD1
|
AnimationParam KEYWORD1
|
||||||
|
22
library.json
22
library.json
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "NeoPixelBus",
|
"name": "NeoPixelBus",
|
||||||
"keywords": "NeoPixel, WS2811, WS2812, WS2813, SK6812, DotStar, APA102, APA106, RGB, RGBW",
|
"keywords": "NeoPixel, WS2811, WS2812, WS2813, SK6812, DotStar, APA102, APA106, LPD8806, RGB, RGBW",
|
||||||
"description": "A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102) easy. Supports most Arduino platforms. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.",
|
"description": "A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102, LPD8806) easy. Supports most Arduino platforms. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.",
|
||||||
"homepage": "https://github.com/Makuna/NeoPixelBus/wiki",
|
"homepage": "https://github.com/Makuna/NeoPixelBus/wiki",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Makuna/NeoPixelBus"
|
"url": "https://github.com/Makuna/NeoPixelBus"
|
||||||
},
|
},
|
||||||
"version": "2.5.1",
|
"version": "2.5.1",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "*"
|
"platforms": "*"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ name=NeoPixelBus by Makuna
|
|||||||
version=2.5.1
|
version=2.5.1
|
||||||
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 (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102) easy.
|
sentence=A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102, LPD8806) easy.
|
||||||
paragraph=Supports most Arduino platforms, including Esp8266 and Esp32. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. Supports Matrix layout of pixels. Includes Gamma corretion object. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.
|
paragraph=Supports most Arduino platforms, including Esp8266 and Esp32. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. Supports Matrix layout of pixels. Includes Gamma corretion object. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.
|
||||||
category=Display
|
category=Display
|
||||||
url=https://github.com/Makuna/NeoPixelBus/wiki
|
url=https://github.com/Makuna/NeoPixelBus/wiki
|
||||||
|
@@ -46,6 +46,7 @@ License along with NeoPixel. If not, see
|
|||||||
|
|
||||||
#include "internal/NeoColorFeatures.h"
|
#include "internal/NeoColorFeatures.h"
|
||||||
#include "internal/DotStarColorFeatures.h"
|
#include "internal/DotStarColorFeatures.h"
|
||||||
|
#include "internal/Lpd8806ColorFeatures.h"
|
||||||
|
|
||||||
#include "internal/Layouts.h"
|
#include "internal/Layouts.h"
|
||||||
#include "internal/NeoTopology.h"
|
#include "internal/NeoTopology.h"
|
||||||
@@ -63,37 +64,34 @@ License along with NeoPixel. If not, see
|
|||||||
#include "internal/NeoEase.h"
|
#include "internal/NeoEase.h"
|
||||||
#include "internal/NeoGamma.h"
|
#include "internal/NeoGamma.h"
|
||||||
|
|
||||||
|
#include "internal/DotStarGenericMethod.h"
|
||||||
|
#include "internal/Lpd8806GenericMethod.h"
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP8266)
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
|
||||||
#include "internal/NeoEsp8266DmaMethod.h"
|
#include "internal/NeoEsp8266DmaMethod.h"
|
||||||
#include "internal/NeoEsp8266UartMethod.h"
|
#include "internal/NeoEsp8266UartMethod.h"
|
||||||
#include "internal/NeoEspBitBangMethod.h"
|
#include "internal/NeoEspBitBangMethod.h"
|
||||||
#include "internal/DotStarGenericMethod.h"
|
|
||||||
|
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
|
|
||||||
#include "internal/NeoEsp32I2sMethod.h"
|
#include "internal/NeoEsp32I2sMethod.h"
|
||||||
#include "internal/NeoEsp32RmtMethod.h"
|
#include "internal/NeoEsp32RmtMethod.h"
|
||||||
#include "internal/NeoEspBitBangMethod.h"
|
#include "internal/NeoEspBitBangMethod.h"
|
||||||
#include "internal/DotStarGenericMethod.h"
|
|
||||||
|
|
||||||
#elif defined(__arm__) // must be before ARDUINO_ARCH_AVR due to Teensy incorrectly having it set
|
#elif defined(__arm__) // must be before ARDUINO_ARCH_AVR due to Teensy incorrectly having it set
|
||||||
|
|
||||||
#include "internal/NeoArmMethod.h"
|
#include "internal/NeoArmMethod.h"
|
||||||
#include "internal/DotStarGenericMethod.h"
|
|
||||||
|
|
||||||
#elif defined(ARDUINO_ARCH_AVR)
|
#elif defined(ARDUINO_ARCH_AVR)
|
||||||
|
|
||||||
#include "internal/NeoAvrMethod.h"
|
#include "internal/NeoAvrMethod.h"
|
||||||
#include "internal/DotStarAvrMethod.h"
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Platform Currently Not Supported, please add an Issue at Github/Makuna/NeoPixelBus"
|
#error "Platform Currently Not Supported, please add an Issue at Github/Makuna/NeoPixelBus"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__AVR_ATtiny85__)
|
|
||||||
#include "internal/DotStarSpiMethod.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus
|
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus
|
||||||
|
@@ -1,153 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
NeoPixel library helper functions for DotStars on AVR (APA102).
|
|
||||||
|
|
||||||
Written by Michael C. Miller.
|
|
||||||
|
|
||||||
I invest time and resources providing this open source code,
|
|
||||||
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
This file is part of the Makuna/NeoPixelBus library.
|
|
||||||
|
|
||||||
NeoPixelBus is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as
|
|
||||||
published by the Free Software Foundation, either version 3 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
NeoPixelBus is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with NeoPixel. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// must also check for arm due to Teensy incorrectly having ARDUINO_ARCH_AVR set
|
|
||||||
#if defined(ARDUINO_ARCH_AVR) && !defined(__arm__)
|
|
||||||
|
|
||||||
class DotStarAvrMethod
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DotStarAvrMethod(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
|
|
||||||
_pinClock(pinClock),
|
|
||||||
_pinData(pinData),
|
|
||||||
_sizePixels(pixelCount * elementSize)
|
|
||||||
{
|
|
||||||
pinMode(pinClock, OUTPUT);
|
|
||||||
pinMode(pinData, OUTPUT);
|
|
||||||
|
|
||||||
_pixels = (uint8_t*)malloc(_sizePixels);
|
|
||||||
memset(_pixels, 0, _sizePixels);
|
|
||||||
|
|
||||||
_portClock = portOutputRegister(digitalPinToPort(_pinClock));
|
|
||||||
_pinMaskClock = digitalPinToBitMask(_pinClock);
|
|
||||||
_portData = portOutputRegister(digitalPinToPort(_pinData));
|
|
||||||
_pinMaskData = digitalPinToBitMask(_pinData);
|
|
||||||
}
|
|
||||||
|
|
||||||
~DotStarAvrMethod()
|
|
||||||
{
|
|
||||||
pinMode(_pinClock, INPUT);
|
|
||||||
pinMode(_pinData, INPUT);
|
|
||||||
|
|
||||||
free(_pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsReadyToUpdate() const
|
|
||||||
{
|
|
||||||
return true; // dot stars don't have a required delay
|
|
||||||
}
|
|
||||||
|
|
||||||
void Initialize()
|
|
||||||
{
|
|
||||||
digitalWrite(_pinClock, LOW);
|
|
||||||
digitalWrite(_pinData, LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(bool)
|
|
||||||
{
|
|
||||||
// start frame
|
|
||||||
for (int startFrameByte = 0; startFrameByte < 4; startFrameByte++)
|
|
||||||
{
|
|
||||||
_transmitByte(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
// data
|
|
||||||
uint8_t* data = _pixels;
|
|
||||||
const uint8_t* endData = _pixels + _sizePixels;
|
|
||||||
while (data < endData)
|
|
||||||
{
|
|
||||||
_transmitByte(*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++)
|
|
||||||
{
|
|
||||||
_transmitByte(0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set clock and data back to low between updates
|
|
||||||
digitalWrite(_pinData, LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* getPixels() const
|
|
||||||
{
|
|
||||||
return _pixels;
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t getPixelsSize() const
|
|
||||||
{
|
|
||||||
return _sizePixels;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
const uint8_t _pinClock; // output pin number for clock line
|
|
||||||
const uint8_t _pinData; // output pin number for data line
|
|
||||||
const size_t _sizePixels; // Size of '_pixels' buffer below
|
|
||||||
|
|
||||||
uint8_t* _pixels; // Holds LED color values
|
|
||||||
|
|
||||||
volatile uint8_t* _portData; // Output PORT register
|
|
||||||
uint8_t _pinMaskData; // Output PORT bitmask
|
|
||||||
volatile uint8_t* _portClock; // Output PORT register
|
|
||||||
uint8_t _pinMaskClock; // Output PORT bitmask
|
|
||||||
|
|
||||||
void _transmitByte(uint8_t data)
|
|
||||||
{
|
|
||||||
for (int bit = 7; bit >= 0; bit--)
|
|
||||||
{
|
|
||||||
// set data bit on pin
|
|
||||||
// digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
|
|
||||||
if (data & 0x80)
|
|
||||||
{
|
|
||||||
*_portData |= _pinMaskData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*_portData &= ~_pinMaskData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// set clock high as data is ready
|
|
||||||
// digitalWrite(_pinClock, HIGH);
|
|
||||||
*_portClock |= _pinMaskClock;
|
|
||||||
|
|
||||||
// done between clock toggle to give a little time
|
|
||||||
data <<= 1;
|
|
||||||
|
|
||||||
// set clock low as data pin is changed
|
|
||||||
// digitalWrite(_pinClock, LOW);
|
|
||||||
*_portClock &= ~_pinMaskClock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef DotStarAvrMethod DotStarMethod;
|
|
||||||
|
|
||||||
#endif
|
|
@@ -26,26 +26,33 @@ License along with NeoPixel. If not, see
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class DotStarGenericMethod
|
// must also check for arm due to Teensy incorrectly having ARDUINO_ARCH_AVR set
|
||||||
|
#if defined(ARDUINO_ARCH_AVR) && !defined(__arm__)
|
||||||
|
#include "TwoWireBitBangImpleAvr.h"
|
||||||
|
#else
|
||||||
|
#include "TwoWireBitBangImple.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T_TWOWIRE> class DotStarMethodBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DotStarGenericMethod(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
|
DotStarMethodBase(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
|
||||||
_pinClock(pinClock),
|
_sizePixels(pixelCount * elementSize),
|
||||||
_pinData(pinData),
|
_sizeEndFrame((pixelCount + 15) / 16), // 16 = div 2 (bit for every two pixels) div 8 (bits to bytes)
|
||||||
_sizePixels(pixelCount * elementSize)
|
_wire(pinClock, pinData)
|
||||||
{
|
{
|
||||||
pinMode(pinClock, OUTPUT);
|
|
||||||
pinMode(pinData, OUTPUT);
|
|
||||||
|
|
||||||
_pixels = (uint8_t*)malloc(_sizePixels);
|
_pixels = (uint8_t*)malloc(_sizePixels);
|
||||||
memset(_pixels, 0, _sizePixels);
|
memset(_pixels, 0, _sizePixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DotStarGenericMethod()
|
DotStarMethodBase(uint16_t pixelCount, size_t elementSize) :
|
||||||
{
|
DotStarMethodBase(SCK, MOSI, pixelCount, elementSize)
|
||||||
pinMode(_pinClock, INPUT);
|
{
|
||||||
pinMode(_pinData, INPUT);
|
}
|
||||||
|
|
||||||
|
~DotStarMethodBase()
|
||||||
|
{
|
||||||
free(_pixels);
|
free(_pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,38 +61,38 @@ public:
|
|||||||
return true; // dot stars don't have a required delay
|
return true; // dot stars don't have a required delay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||||
|
{
|
||||||
|
_wire.begin(sck, miso, mosi, ss);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
digitalWrite(_pinClock, LOW);
|
_wire.begin();
|
||||||
digitalWrite(_pinData, LOW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(bool)
|
void Update(bool)
|
||||||
{
|
{
|
||||||
|
const uint8_t startFrame[4] = { 0x00 };
|
||||||
|
|
||||||
|
_wire.beginTransaction();
|
||||||
|
|
||||||
// start frame
|
// start frame
|
||||||
for (int startFrameByte = 0; startFrameByte < 4; startFrameByte++)
|
_wire.transmitBytes(startFrame, sizeof(startFrame));
|
||||||
{
|
|
||||||
_transmitByte(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
// data
|
// data
|
||||||
uint8_t* data = _pixels;
|
_wire.transmitBytes(_pixels, _sizePixels);
|
||||||
const uint8_t* endData = _pixels + _sizePixels;
|
|
||||||
while (data < endData)
|
|
||||||
{
|
|
||||||
_transmitByte(*data++);
|
|
||||||
}
|
|
||||||
|
|
||||||
// end frame
|
// end frame
|
||||||
// one bit for every two pixels with no less than 1 byte
|
// one bit for every two pixels with no less than 1 byte
|
||||||
const uint16_t countEndFrameBytes = ((_sizePixels / 4) + 15) / 16;
|
for (size_t endFrameByte = 0; endFrameByte < _sizeEndFrame; endFrameByte++)
|
||||||
for (uint16_t endFrameByte = 0; endFrameByte < countEndFrameBytes; endFrameByte++)
|
{
|
||||||
{
|
_wire.transmitByte(0xff);
|
||||||
_transmitByte(0xff);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// set clock and data back to low between updates
|
_wire.endTransaction();
|
||||||
digitalWrite(_pinData, LOW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* getPixels() const
|
uint8_t* getPixels() const
|
||||||
@@ -99,30 +106,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint8_t _pinClock; // output pin number for clock line
|
const size_t _sizePixels; // Size of '_pixels' buffer below
|
||||||
const uint8_t _pinData; // output pin number for data line
|
const size_t _sizeEndFrame;
|
||||||
const size_t _sizePixels; // Size of '_pixels' buffer below
|
|
||||||
|
|
||||||
|
T_TWOWIRE _wire;
|
||||||
uint8_t* _pixels; // Holds LED color values
|
uint8_t* _pixels; // Holds LED color values
|
||||||
|
|
||||||
void _transmitByte(uint8_t data)
|
|
||||||
{
|
|
||||||
for (int bit = 7; bit >= 0; bit--)
|
|
||||||
{
|
|
||||||
// set data bit on pin
|
|
||||||
digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
|
|
||||||
|
|
||||||
// set clock high as data is ready
|
|
||||||
digitalWrite(_pinClock, HIGH);
|
|
||||||
|
|
||||||
data <<= 1;
|
|
||||||
|
|
||||||
// set clock low as data pin is changed
|
|
||||||
digitalWrite(_pinClock, LOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DotStarGenericMethod DotStarMethod;
|
typedef DotStarMethodBase<TwoWireBitBangImple> DotStarMethod;
|
||||||
|
|
||||||
|
#if !defined(__AVR_ATtiny85__)
|
||||||
|
#include "TwoWireSpiImple.h"
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> DotStarSpi20MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> DotStarSpi10MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> DotStarSpi2MhzMethod;
|
||||||
|
typedef DotStarSpi10MhzMethod DotStarSpiMethod;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,133 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
NeoPixel library helper functions for DotStars using SPI hardware (APA102).
|
|
||||||
|
|
||||||
Written by Michael C. Miller.
|
|
||||||
|
|
||||||
I invest time and resources providing this open source code,
|
|
||||||
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
This file is part of the Makuna/NeoPixelBus library.
|
|
||||||
|
|
||||||
NeoPixelBus is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as
|
|
||||||
published by the Free Software Foundation, either version 3 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
NeoPixelBus is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with NeoPixel. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
class DotStarSpiMethod
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DotStarSpiMethod(uint16_t pixelCount, size_t elementSize) :
|
|
||||||
_sizeData(pixelCount * elementSize),
|
|
||||||
_sizeSendBuffer(calcBufferSize(pixelCount * elementSize))
|
|
||||||
{
|
|
||||||
_sendBuffer = (uint8_t*)malloc(_sizeSendBuffer);
|
|
||||||
memset(_sendBuffer, 0, _sizeSendBuffer);
|
|
||||||
setEndFrameBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
~DotStarSpiMethod()
|
|
||||||
{
|
|
||||||
SPI.end();
|
|
||||||
free(_sendBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsReadyToUpdate() const
|
|
||||||
{
|
|
||||||
return true; // dot stars don't have a required delay
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
|
||||||
{
|
|
||||||
SPI.begin(sck, miso, mosi, ss);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Initialize()
|
|
||||||
{
|
|
||||||
SPI.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(bool)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(20000000L, MSBFIRST, SPI_MODE0));
|
|
||||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
|
||||||
// ESPs have a method to write without inplace overwriting the send buffer
|
|
||||||
// since we don't care what gets received, use it for performance
|
|
||||||
SPI.writeBytes(_sendBuffer, _sizeSendBuffer);
|
|
||||||
|
|
||||||
#else
|
|
||||||
// default ARDUINO transfer inplace overwrites the send buffer
|
|
||||||
// which is bad, so we have to send one byte at a time
|
|
||||||
uint8_t* out = _sendBuffer;
|
|
||||||
uint8_t* end = out + _sizeSendBuffer;
|
|
||||||
while (out < end)
|
|
||||||
{
|
|
||||||
SPI.transfer(*out++);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* getPixels() const
|
|
||||||
{
|
|
||||||
return _sendBuffer + _countStartFrame;
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t getPixelsSize() const
|
|
||||||
{
|
|
||||||
return _sizeData;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
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* _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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
167
src/internal/Lpd8806ColorFeatures.h
Normal file
167
src/internal/Lpd8806ColorFeatures.h
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
Lpd8806ColorFeatures provides feature classes to describe color order and
|
||||||
|
color depth for NeoPixelBus template class when used with DotStar like chips
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
|
I invest time and resources providing this open source code,
|
||||||
|
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
This file is part of the Makuna/NeoPixelBus library.
|
||||||
|
|
||||||
|
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
NeoPixelBus is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with NeoPixel. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Lpd88063Elements
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const size_t PixelSize = 3;
|
||||||
|
|
||||||
|
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
|
||||||
|
{
|
||||||
|
return pPixels + indexPixel * PixelSize;
|
||||||
|
}
|
||||||
|
static const uint8_t* getPixelAddress(const uint8_t* pPixels, uint16_t indexPixel)
|
||||||
|
{
|
||||||
|
return pPixels + indexPixel * PixelSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void replicatePixel(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
|
||||||
|
{
|
||||||
|
uint8_t* pEnd = pPixelDest + (count * PixelSize);
|
||||||
|
while (pPixelDest < pEnd)
|
||||||
|
{
|
||||||
|
*pPixelDest++ = pPixelSrc[0];
|
||||||
|
*pPixelDest++ = pPixelSrc[1];
|
||||||
|
*pPixelDest++ = pPixelSrc[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void movePixelsInc(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
|
||||||
|
{
|
||||||
|
uint8_t* pEnd = pPixelDest + (count * PixelSize);
|
||||||
|
while (pPixelDest < pEnd)
|
||||||
|
{
|
||||||
|
*pPixelDest++ = *pPixelSrc++;
|
||||||
|
*pPixelDest++ = *pPixelSrc++;
|
||||||
|
*pPixelDest++ = *pPixelSrc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
|
||||||
|
{
|
||||||
|
uint8_t* pEnd = pPixelDest + (count * PixelSize);
|
||||||
|
const uint8_t* pSrc = (const uint8_t*)pPixelSrc;
|
||||||
|
while (pPixelDest < pEnd)
|
||||||
|
{
|
||||||
|
*pPixelDest++ = pgm_read_byte(pSrc++);
|
||||||
|
*pPixelDest++ = pgm_read_byte(pSrc++);
|
||||||
|
*pPixelDest++ = pgm_read_byte(pSrc++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void movePixelsDec(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
|
||||||
|
{
|
||||||
|
uint8_t* pDestBack = pPixelDest + (count * PixelSize);
|
||||||
|
const uint8_t* pSrcBack = pPixelSrc + (count * PixelSize);
|
||||||
|
while (pDestBack > pPixelDest)
|
||||||
|
{
|
||||||
|
*--pDestBack = *--pSrcBack;
|
||||||
|
*--pDestBack = *--pSrcBack;
|
||||||
|
*--pDestBack = *--pSrcBack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef RgbColor ColorObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lpd8806BrgFeature : public Lpd88063Elements
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
|
||||||
|
{
|
||||||
|
uint8_t* p = getPixelAddress(pPixels, indexPixel);
|
||||||
|
|
||||||
|
*p++ = (color.B >> 1) | 0x80;
|
||||||
|
*p++ = (color.R >> 1) | 0x80;
|
||||||
|
*p = (color.G >> 1) | 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ColorObject retrievePixelColor(uint8_t* pPixels, uint16_t indexPixel)
|
||||||
|
{
|
||||||
|
ColorObject color;
|
||||||
|
uint8_t* p = getPixelAddress(pPixels, indexPixel);
|
||||||
|
|
||||||
|
color.B = (*p++) << 1;
|
||||||
|
color.R = (*p++) << 1;
|
||||||
|
color.G = (*p) << 1;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
|
||||||
|
{
|
||||||
|
ColorObject color;
|
||||||
|
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
|
||||||
|
|
||||||
|
color.B = (pgm_read_byte(p++)) << 1;
|
||||||
|
color.R = (pgm_read_byte(p++)) << 1;
|
||||||
|
color.G = (pgm_read_byte(p)) << 1;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lpd8806GrbFeature : public Lpd88063Elements
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
|
||||||
|
{
|
||||||
|
uint8_t* p = getPixelAddress(pPixels, indexPixel);
|
||||||
|
|
||||||
|
*p++ = (color.G >> 1) | 0x80;
|
||||||
|
*p++ = (color.R >> 1) | 0x80;
|
||||||
|
*p = (color.B >> 1) | 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ColorObject retrievePixelColor(uint8_t* pPixels, uint16_t indexPixel)
|
||||||
|
{
|
||||||
|
ColorObject color;
|
||||||
|
uint8_t* p = getPixelAddress(pPixels, indexPixel);
|
||||||
|
|
||||||
|
color.G = (*p++) << 1;
|
||||||
|
color.R = (*p++) << 1;
|
||||||
|
color.B = (*p) << 1;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
|
||||||
|
{
|
||||||
|
ColorObject color;
|
||||||
|
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
|
||||||
|
|
||||||
|
color.G = (pgm_read_byte(p++)) << 1;
|
||||||
|
color.R = (pgm_read_byte(p++)) << 1;
|
||||||
|
color.B = (pgm_read_byte(p)) << 1;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
127
src/internal/Lpd8806GenericMethod.h
Normal file
127
src/internal/Lpd8806GenericMethod.h
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for LPD8806 using general Pins
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
|
I invest time and resources providing this open source code,
|
||||||
|
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
This file is part of the Makuna/NeoPixelBus library.
|
||||||
|
|
||||||
|
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
NeoPixelBus is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with NeoPixel. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// must also check for arm due to Teensy incorrectly having ARDUINO_ARCH_AVR set
|
||||||
|
#if defined(ARDUINO_ARCH_AVR) && !defined(__arm__)
|
||||||
|
#include "TwoWireBitBangImpleAvr.h"
|
||||||
|
#else
|
||||||
|
#include "TwoWireBitBangImple.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T_TWOWIRE> class Lpd8806MethodBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Lpd8806MethodBase(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
|
||||||
|
_sizePixels(pixelCount * elementSize),
|
||||||
|
_sizeFrame((pixelCount + 31) / 32),
|
||||||
|
_wire(pinClock, pinData)
|
||||||
|
{
|
||||||
|
_pixels = (uint8_t*)malloc(_sizePixels);
|
||||||
|
memset(_pixels, 0, _sizePixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lpd8806MethodBase(uint16_t pixelCount, size_t elementSize) :
|
||||||
|
Lpd8806MethodBase(SCK, MOSI, pixelCount, elementSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Lpd8806MethodBase()
|
||||||
|
{
|
||||||
|
free(_pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsReadyToUpdate() const
|
||||||
|
{
|
||||||
|
return true; // dot stars don't have a required delay
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||||
|
{
|
||||||
|
_wire.begin(sck, miso, mosi, ss);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
_wire.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(bool)
|
||||||
|
{
|
||||||
|
_wire.beginTransaction();
|
||||||
|
|
||||||
|
// start frame
|
||||||
|
for (size_t frameByte = 0; frameByte < _sizeFrame; frameByte++)
|
||||||
|
{
|
||||||
|
_wire.transmitByte(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// data
|
||||||
|
_wire.transmitBytes(_pixels, _sizePixels);
|
||||||
|
|
||||||
|
// end frame
|
||||||
|
for (size_t frameByte = 0; frameByte < _sizeFrame; frameByte++)
|
||||||
|
{
|
||||||
|
_wire.transmitByte(0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
_wire.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* getPixels() const
|
||||||
|
{
|
||||||
|
return _pixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t getPixelsSize() const
|
||||||
|
{
|
||||||
|
return _sizePixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
const size_t _sizePixels; // Size of '_pixels' buffer below
|
||||||
|
const size_t _sizeFrame;
|
||||||
|
|
||||||
|
T_TWOWIRE _wire;
|
||||||
|
uint8_t* _pixels; // Holds LED color values
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Lpd8806MethodBase<TwoWireBitBangImple> Lpd8806Method;
|
||||||
|
|
||||||
|
#if !defined(__AVR_ATtiny85__)
|
||||||
|
#include "TwoWireSpiImple.h"
|
||||||
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> Lpd8806Spi20MhzMethod;
|
||||||
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> Lpd8806Spi10MhzMethod;
|
||||||
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> Lpd8806Spi2MhzMethod;
|
||||||
|
typedef Lpd8806Spi10MhzMethod Lpd8806SpiMethod;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
92
src/internal/TwoWireBitBangImple.h
Normal file
92
src/internal/TwoWireBitBangImple.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
|
I invest time and resources providing this open source code,
|
||||||
|
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
This file is part of the Makuna/NeoPixelBus library.
|
||||||
|
|
||||||
|
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
NeoPixelBus is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with NeoPixel. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
class TwoWireBitBangImple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TwoWireBitBangImple(uint8_t pinClock, uint8_t pinData) :
|
||||||
|
_pinClock(pinClock),
|
||||||
|
_pinData(pinData)
|
||||||
|
{
|
||||||
|
pinMode(pinClock, OUTPUT);
|
||||||
|
pinMode(pinData, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
~TwoWireBitBangImple()
|
||||||
|
{
|
||||||
|
pinMode(_pinClock, INPUT);
|
||||||
|
pinMode(_pinData, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void begin()
|
||||||
|
{
|
||||||
|
digitalWrite(_pinClock, LOW);
|
||||||
|
digitalWrite(_pinData, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void beginTransaction()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void endTransaction()
|
||||||
|
{
|
||||||
|
digitalWrite(_pinData, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitByte(uint8_t data)
|
||||||
|
{
|
||||||
|
for (int bit = 7; bit >= 0; bit--)
|
||||||
|
{
|
||||||
|
// set data bit on pin
|
||||||
|
digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
|
||||||
|
|
||||||
|
// set clock high as data is ready
|
||||||
|
digitalWrite(_pinClock, HIGH);
|
||||||
|
|
||||||
|
data <<= 1;
|
||||||
|
|
||||||
|
// set clock low as data pin is changed
|
||||||
|
digitalWrite(_pinClock, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitBytes(const uint8_t* data, size_t dataSize)
|
||||||
|
{
|
||||||
|
const uint8_t* endData = data + dataSize;
|
||||||
|
while (data < endData)
|
||||||
|
{
|
||||||
|
transmitByte(*data++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint8_t _pinClock; // output pin number for clock line
|
||||||
|
const uint8_t _pinData; // output pin number for data line
|
||||||
|
};
|
112
src/internal/TwoWireBitBangImpleAvr.h
Normal file
112
src/internal/TwoWireBitBangImpleAvr.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
|
I invest time and resources providing this open source code,
|
||||||
|
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
This file is part of the Makuna/NeoPixelBus library.
|
||||||
|
|
||||||
|
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
NeoPixelBus is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with NeoPixel. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
class TwoWireBitBangImple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TwoWireBitBangImple(uint8_t pinClock, uint8_t pinData) :
|
||||||
|
_pinClock(pinClock),
|
||||||
|
_pinData(pinData)
|
||||||
|
{
|
||||||
|
pinMode(pinClock, OUTPUT);
|
||||||
|
pinMode(pinData, OUTPUT);
|
||||||
|
|
||||||
|
_portClock = portOutputRegister(digitalPinToPort(_pinClock));
|
||||||
|
_pinMaskClock = digitalPinToBitMask(_pinClock);
|
||||||
|
_portData = portOutputRegister(digitalPinToPort(_pinData));
|
||||||
|
_pinMaskData = digitalPinToBitMask(_pinData);
|
||||||
|
}
|
||||||
|
|
||||||
|
~TwoWireBitBangImple()
|
||||||
|
{
|
||||||
|
pinMode(_pinClock, INPUT);
|
||||||
|
pinMode(_pinData, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void begin()
|
||||||
|
{
|
||||||
|
digitalWrite(_pinClock, LOW);
|
||||||
|
digitalWrite(_pinData, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void beginTransaction()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void endTransaction()
|
||||||
|
{
|
||||||
|
digitalWrite(_pinData, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitByte(uint8_t data)
|
||||||
|
{
|
||||||
|
for (int bit = 7; bit >= 0; bit--)
|
||||||
|
{
|
||||||
|
// set data bit on pin
|
||||||
|
// digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
|
||||||
|
if (data & 0x80)
|
||||||
|
{
|
||||||
|
*_portData |= _pinMaskData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*_portData &= ~_pinMaskData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set clock high as data is ready
|
||||||
|
// digitalWrite(_pinClock, HIGH);
|
||||||
|
*_portClock |= _pinMaskClock;
|
||||||
|
|
||||||
|
data <<= 1;
|
||||||
|
|
||||||
|
// set clock low as data pin is changed
|
||||||
|
// digitalWrite(_pinClock, LOW);
|
||||||
|
*_portClock &= ~_pinMaskClock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitBytes(const uint8_t* data, size_t dataSize)
|
||||||
|
{
|
||||||
|
const uint8_t* endData = data + dataSize;
|
||||||
|
while (data < endData)
|
||||||
|
{
|
||||||
|
transmitByte(*data++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint8_t _pinClock; // output pin number for clock line
|
||||||
|
const uint8_t _pinData; // output pin number for data line
|
||||||
|
|
||||||
|
volatile uint8_t* _portData; // Output PORT register
|
||||||
|
uint8_t _pinMaskData; // Output PORT bitmask
|
||||||
|
volatile uint8_t* _portClock; // Output PORT register
|
||||||
|
uint8_t _pinMaskClock; // Output PORT bitmask
|
||||||
|
};
|
109
src/internal/TwoWireSpiImple.h
Normal file
109
src/internal/TwoWireSpiImple.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
|
I invest time and resources providing this open source code,
|
||||||
|
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
This file is part of the Makuna/NeoPixelBus library.
|
||||||
|
|
||||||
|
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
NeoPixelBus is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with NeoPixel. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
class SpiSpeed20Mhz
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t Clock = 20000000L;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpiSpeed10Mhz
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t Clock = 10000000L;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpiSpeed2Mhz
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t Clock = 2000000L;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T_SPISPEED> class TwoWireSpiImple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TwoWireSpiImple(uint8_t, uint8_t) // clock and data pins ignored for hardware SPI
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~TwoWireSpiImple()
|
||||||
|
{
|
||||||
|
SPI.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
// for cases where hardware SPI can have pins changed
|
||||||
|
void begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||||
|
{
|
||||||
|
SPI.begin(sck, miso, mosi, ss);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void begin()
|
||||||
|
{
|
||||||
|
SPI.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void beginTransaction()
|
||||||
|
{
|
||||||
|
SPI.beginTransaction(SPISettings(T_SPISPEED::Clock, MSBFIRST, SPI_MODE0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void endTransaction()
|
||||||
|
{
|
||||||
|
SPI.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitByte(uint8_t data)
|
||||||
|
{
|
||||||
|
SPI.transfer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitBytes(const uint8_t* data, size_t dataSize)
|
||||||
|
{
|
||||||
|
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||||
|
// ESPs have a method to write without inplace overwriting the send buffer
|
||||||
|
// since we don't care what gets received, use it for performance
|
||||||
|
// FIX: but for what ever reason on Esp32, its not const
|
||||||
|
SPI.writeBytes(const_cast<uint8_t*>(data), dataSize);
|
||||||
|
|
||||||
|
#else
|
||||||
|
// default ARDUINO transfer inplace overwrites the send buffer
|
||||||
|
// which is bad in this case, so we have to send one byte at a time
|
||||||
|
const uint8_t* endData = data + dataSize;
|
||||||
|
while (data < endData)
|
||||||
|
{
|
||||||
|
SPI.transfer(*data++);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
Reference in New Issue
Block a user