forked from Makuna/NeoPixelBus
ESP32 Hardware SPI Improvements - Options for using both SPI peripherals, and DMA (#441)
* Fix header file comment * Add TwoWireHspiImpl and Example * Add start of TwoWireEsp32DmaSpiImple (Currently just able to use HSPI and VSPI in parallel, no DMA) * Update names for TwoWireEsp32DmaSpi and set set spi_bus using template not constructor * Update example with new functionality and bugfixes * DotStarEsp32DmaSpiMethod - * Add 5MHz option to all SPI-based classes * DotStarGenericMethod - Give option to use Vspi alias of Spi class if wanting to specify which SPI peripheral is used on the ESP32 - Add missing DotStarHspiHzMethod * TwoWireHspiImple - bring up to date with applySettings() method * DotStarTest_Esp32Advanced example - update to show how to change clock speed at runtime - Remove commented out pins cluttering up example * DotStarTest_Esp32DmaSpi example - Co-authored-by: Louis Beaudoin <louis@embedded-creations.com>
This commit is contained in:
@@ -0,0 +1,159 @@
|
|||||||
|
// DotStarTest_Esp32Advanced - This example only works on the ESP32
|
||||||
|
// This example will cycle between showing four pixels as Red, Green, Blue, White
|
||||||
|
// and then showing those pixels as Black. This example uses Hardware SPI on the ESP32
|
||||||
|
// with options to use alternate pins for SPI and drive two SPI ports using the alternate
|
||||||
|
// additional SPI hardware available on the ESP32.
|
||||||
|
//
|
||||||
|
// There is serial output of the current state so you can confirm and follow along
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
#define USE_DEFAULT_SPI_PORT 1
|
||||||
|
#define USE_ALTERNATE_SPI_PORT 1
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
const uint16_t PixelCount = 4; // this example assumes 4 pixels, making it smaller will cause a failure
|
||||||
|
|
||||||
|
// It's usually better to use alternate pins. If set to false, strip will use GPIO 18 for Clock, GPIO 23 for Data, and pin 5 will output a chip select signal
|
||||||
|
const bool useSpiAlternatePins = true;
|
||||||
|
|
||||||
|
// If you set useSpiAlternatePins true, then these pins will be used instead. Any output-capable GPIO can be used.
|
||||||
|
const uint8_t DotClockPin = 18;
|
||||||
|
const uint8_t DotDataPin = 23;
|
||||||
|
const int8_t DotChipSelectPin = -1; // -1 means the chip select signal won't be output, freeing up one pin compared to useSpiAlternatePins=false
|
||||||
|
|
||||||
|
// for software bit bang (only use if neither SPI peripheral is available)
|
||||||
|
//NeoPixelBus<DotStarBgrFeature, DotStarMethod> strip(PixelCount, DotClockPin, DotDataPin);
|
||||||
|
|
||||||
|
// for hardware SPI (best performance) with default SPI peripheral
|
||||||
|
NeoPixelBus<DotStarBgrFeature, DotStarSpiMethod> strip(PixelCount);
|
||||||
|
|
||||||
|
// DotStarSpiMethod defaults to 10MHz clock speed. For other speeds, replace "DotStarSpiMethod" with another method specifying speed, e.g. "DotStarSpi2MhzMethod" (see wiki for more details)
|
||||||
|
|
||||||
|
// to change the SPI clock speed during runtime, use the "Hz" clock setting, e.g. DotStarSpiHzMethod, which default to 10MHz but supports updating during runtime
|
||||||
|
//NeoPixelBus<DotStarBgrFeature, DotStarSpiHzMethod> strip(PixelCount);
|
||||||
|
//#define SET_CLOCK_SPEED_DURING_RUNTIME // only define if using "Hz" clock method
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
const uint16_t PixelCount2 = 4; // this example assumes 4 pixels, making it smaller will cause a failure
|
||||||
|
|
||||||
|
// It's usually better to use alternate pins. If set to false, strip2 will use GPIO 14 for Clock, GPIO 13 for Data, and pin 15 will output a chip select signal
|
||||||
|
const bool useSpiAlternatePins2 = true;
|
||||||
|
|
||||||
|
// If you set useSpiAlternatePins2 true, then these pins will be used instead. Any output-capable GPIO can be used.
|
||||||
|
const uint8_t DotClockPin2 = 14;
|
||||||
|
const uint8_t DotDataPin2 = 13;
|
||||||
|
const int8_t DotChipSelectPin2 = -1; // -1 means the chip select signal won't be output, freeing up one pin compared to useSpiAlternatePins2=false
|
||||||
|
|
||||||
|
// for hardware SPI (best performance) with alternate SPI peripheral
|
||||||
|
NeoPixelBus<DotStarBgrFeature, DotStarHspiMethod> strip2(PixelCount2);
|
||||||
|
|
||||||
|
// DotStarHspiMethod defaults to 10MHz clock speed. For other speeds, replace "DotStarSpiMethod" with another method specifying speed, e.g. "DotStarHspi2MhzMethod" (see wiki for more details)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define colorSaturation 128
|
||||||
|
|
||||||
|
// Note that both DotStarSpiMethod and DotStarHspiMethod can be used with DotStarLbgrFeature and DotStarWbgrFeature but to keep things simple those are excluded from this example, see DotStarTest for more details
|
||||||
|
|
||||||
|
RgbColor red(colorSaturation, 0, 0);
|
||||||
|
RgbColor green(0, colorSaturation, 0);
|
||||||
|
RgbColor blue(0, 0, colorSaturation);
|
||||||
|
RgbColor white(colorSaturation);
|
||||||
|
RgbColor black(0);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); // wait for serial attach
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Initializing...");
|
||||||
|
Serial.flush();
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
if (useSpiAlternatePins)
|
||||||
|
{
|
||||||
|
strip.Begin(DotClockPin, DotDataPin, DotDataPin, DotChipSelectPin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strip.Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
strip.ClearTo(black); // this resets all the DotStars to an off state
|
||||||
|
strip.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
if (useSpiAlternatePins2)
|
||||||
|
{
|
||||||
|
strip2.Begin(DotClockPin2, DotDataPin2, DotDataPin2, DotChipSelectPin2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strip2.Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
strip2.ClearTo(black); // this resets all the DotStars to an off state
|
||||||
|
strip2.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Running...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
Serial.println("Default SPI Colors R, G, B, W...");
|
||||||
|
// set the colors,
|
||||||
|
strip.SetPixelColor(0, red);
|
||||||
|
strip.SetPixelColor(1, green);
|
||||||
|
strip.SetPixelColor(2, blue);
|
||||||
|
strip.SetPixelColor(3, white);
|
||||||
|
strip.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
Serial.println("Alt SPI Colors W, B, G, R...");
|
||||||
|
// set the colors,
|
||||||
|
strip2.SetPixelColor(0, white);
|
||||||
|
strip2.SetPixelColor(1, blue);
|
||||||
|
strip2.SetPixelColor(2, green);
|
||||||
|
strip2.SetPixelColor(3, red);
|
||||||
|
strip2.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
Serial.println("Off ...");
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
#ifdef SET_CLOCK_SPEED_DURING_RUNTIME
|
||||||
|
uint32_t clockspeed = 5000000UL;
|
||||||
|
strip.SetMethodSettings(NeoSpiSettings(clockspeed));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// turn off the pixels
|
||||||
|
strip.SetPixelColor(0, black);
|
||||||
|
strip.SetPixelColor(1, black);
|
||||||
|
strip.SetPixelColor(2, black);
|
||||||
|
strip.SetPixelColor(3, black);
|
||||||
|
strip.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
// turn off the pixels
|
||||||
|
strip2.SetPixelColor(0, black);
|
||||||
|
strip2.SetPixelColor(1, black);
|
||||||
|
strip2.SetPixelColor(2, black);
|
||||||
|
strip2.SetPixelColor(3, black);
|
||||||
|
strip2.Show();
|
||||||
|
#endif
|
||||||
|
}
|
@@ -0,0 +1,148 @@
|
|||||||
|
// DotStarTest_Esp32Advanced - This example only works on the ESP32
|
||||||
|
// This example will cycle between showing four pixels as Red, Green, Blue, White
|
||||||
|
// and then showing those pixels as Black. This example uses DMA to drive Hardware SPI on the ESP32
|
||||||
|
// with options to use alternate pins for SPI and drive two SPI ports
|
||||||
|
//
|
||||||
|
// There is serial output of the current state so you can confirm and follow along
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
#define USE_DEFAULT_SPI_PORT 1
|
||||||
|
#define USE_ALTERNATE_SPI_PORT 1
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
const uint16_t PixelCount = 4; // this example assumes 4 pixels, making it smaller will cause a failure
|
||||||
|
|
||||||
|
// It's usually better to use alternate pins. If set to false, strip will use GPIO 18 for Clock, GPIO 23 for Data, and pin 5 will output a chip select signal
|
||||||
|
const bool useSpiAlternatePins = true;
|
||||||
|
|
||||||
|
// If you set useSpiAlternatePins true, then these pins will be used instead. Any output-capable GPIO can be used.
|
||||||
|
const uint8_t DotClockPin = 18;
|
||||||
|
const uint8_t DotDataPin = 23;
|
||||||
|
const int8_t DotChipSelectPin = -1; // -1 means the chip select signal won't be output, freeing up one pin compared to useSpiAlternatePins=false
|
||||||
|
|
||||||
|
// for software bit bang (only use if neither SPI peripheral is available)
|
||||||
|
//NeoPixelBus<DotStarBgrFeature, DotStarMethod> strip(PixelCount, DotClockPin, DotDataPin);
|
||||||
|
|
||||||
|
// for hardware SPI (best performance) with default SPI peripheral
|
||||||
|
NeoPixelBus<DotStarBgrFeature, DotStarEsp32DmaVspiMethod> strip(PixelCount);
|
||||||
|
|
||||||
|
// DotStarEsp32DmaVspiMethod defaults to 10MHz clock speed. For other speeds, replace "DotStarSpiMethod" with another method specifying speed, e.g. "DotStarSpi2MhzMethod" (see wiki for more details)
|
||||||
|
// See DotStarTest_Esp32Advanced example for how to set clock speed at runtime
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
const uint16_t PixelCount2 = 4; // this example assumes 4 pixels, making it smaller will cause a failure
|
||||||
|
|
||||||
|
// It's usually better to use alternate pins. If set to false, strip2 will use GPIO 14 for Clock, GPIO 13 for Data, and pin 15 will output a chip select signal
|
||||||
|
const bool useSpiAlternatePins2 = true;
|
||||||
|
|
||||||
|
// If you set useSpiAlternatePins2 true, then these pins will be used instead. Any output-capable GPIO can be used.
|
||||||
|
const uint8_t DotClockPin2 = 14;
|
||||||
|
const uint8_t DotDataPin2 = 13;
|
||||||
|
const int8_t DotChipSelectPin2 = -1; // -1 means the chip select signal won't be output, freeing up one pin compared to useSpiAlternatePins2=false
|
||||||
|
|
||||||
|
// for hardware SPI (best performance) with alternate SPI peripheral
|
||||||
|
NeoPixelBus<DotStarBgrFeature, DotStarEsp32DmaHspiMethod> strip2(PixelCount2);
|
||||||
|
|
||||||
|
// DotStarEsp32DmaHspiMethod defaults to 10MHz clock speed. For other speeds, replace "DotStarSpiMethod" with another method specifying speed, e.g. "DotStarHspi2MhzMethod" (see wiki for more details)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define colorSaturation 128
|
||||||
|
|
||||||
|
// Note that both DotStarEsp32DmaVspiMethod and DotStarEsp32DmaHspiMethod can be used with DotStarLbgrFeature and DotStarWbgrFeature but to keep things simple those are excluded from this example, see DotStarTest for more details
|
||||||
|
|
||||||
|
RgbColor red(colorSaturation, 0, 0);
|
||||||
|
RgbColor green(0, colorSaturation, 0);
|
||||||
|
RgbColor blue(0, 0, colorSaturation);
|
||||||
|
RgbColor white(colorSaturation);
|
||||||
|
RgbColor black(0);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); // wait for serial attach
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Initializing...");
|
||||||
|
Serial.flush();
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
if (useSpiAlternatePins)
|
||||||
|
{
|
||||||
|
strip.Begin(DotClockPin, DotDataPin, DotDataPin, DotChipSelectPin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strip.Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
strip.ClearTo(black); // this resets all the DotStars to an off state
|
||||||
|
strip.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
if (useSpiAlternatePins2)
|
||||||
|
{
|
||||||
|
strip2.Begin(DotClockPin2, DotDataPin2, DotDataPin2, DotChipSelectPin2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strip2.Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
strip2.ClearTo(black); // this resets all the DotStars to an off state
|
||||||
|
strip2.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Running...");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
Serial.println("Default SPI Colors R, G, B, W...");
|
||||||
|
// set the colors,
|
||||||
|
strip.SetPixelColor(0, red);
|
||||||
|
strip.SetPixelColor(1, green);
|
||||||
|
strip.SetPixelColor(2, blue);
|
||||||
|
strip.SetPixelColor(3, white);
|
||||||
|
strip.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
Serial.println("Alt SPI Colors W, B, G, R...");
|
||||||
|
// set the colors,
|
||||||
|
strip2.SetPixelColor(0, white);
|
||||||
|
strip2.SetPixelColor(1, blue);
|
||||||
|
strip2.SetPixelColor(2, green);
|
||||||
|
strip2.SetPixelColor(3, red);
|
||||||
|
strip2.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Serial.println("Off ...");
|
||||||
|
|
||||||
|
#if (USE_DEFAULT_SPI_PORT == 1)
|
||||||
|
// turn off the pixels
|
||||||
|
strip.SetPixelColor(0, black);
|
||||||
|
strip.SetPixelColor(1, black);
|
||||||
|
strip.SetPixelColor(2, black);
|
||||||
|
strip.SetPixelColor(3, black);
|
||||||
|
strip.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (USE_ALTERNATE_SPI_PORT == 1)
|
||||||
|
// turn off the pixels
|
||||||
|
strip2.SetPixelColor(0, black);
|
||||||
|
strip2.SetPixelColor(1, black);
|
||||||
|
strip2.SetPixelColor(2, black);
|
||||||
|
strip2.SetPixelColor(3, black);
|
||||||
|
strip2.Show();
|
||||||
|
#endif
|
||||||
|
}
|
@@ -104,6 +104,7 @@ License along with NeoPixel. If not, see
|
|||||||
#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/DotStarEsp32DmaSpiMethod.h"
|
||||||
|
|
||||||
#elif defined(ARDUINO_ARCH_NRF52840) // must be before __arm__
|
#elif defined(ARDUINO_ARCH_NRF52840) // must be before __arm__
|
||||||
|
|
||||||
@@ -172,13 +173,20 @@ public:
|
|||||||
ClearTo(0);
|
ClearTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by DotStartSpiMethod if pins can be configured
|
// used by DotStarSpiMethod/DotStarEsp32DmaSpiMethod if pins can be configured
|
||||||
void Begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
void Begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||||
{
|
{
|
||||||
_method.Initialize(sck, miso, mosi, ss);
|
_method.Initialize(sck, miso, mosi, ss);
|
||||||
ClearTo(0);
|
ClearTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting quad SPI
|
||||||
|
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t ss)
|
||||||
|
{
|
||||||
|
_method.Initialize(sck, dat0, dat1, dat2, dat3, ss);
|
||||||
|
ClearTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
void Show(bool maintainBufferConsistency = true)
|
void Show(bool maintainBufferConsistency = true)
|
||||||
{
|
{
|
||||||
if (!IsDirty())
|
if (!IsDirty())
|
||||||
|
335
src/internal/DotStarEsp32DmaSpiMethod.h
Normal file
335
src/internal/DotStarEsp32DmaSpiMethod.h
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for DotStars using Esp32, DMA and SPI (APA102).
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
DotStarEsp32DmaSpiMethod written by Louis Beaudoin (Pixelvation)
|
||||||
|
|
||||||
|
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 "driver/spi_master.h"
|
||||||
|
|
||||||
|
class Esp32VspiBus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const spi_host_device_t SpiHostDevice = VSPI_HOST;
|
||||||
|
static const int dmaChannel = 1; // arbitrary assignment, but based on the fact there are only two DMA channels and two available SPI ports, we need to split them somehow
|
||||||
|
static const int parallelBits = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Esp32HspiBus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const spi_host_device_t SpiHostDevice = HSPI_HOST;
|
||||||
|
static const int dmaChannel = 2; // arbitrary assignment, but based on the fact there are only two DMA channels and two available SPI ports, we need to split them somehow
|
||||||
|
static const int parallelBits = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Esp32Vspi2BitBus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const spi_host_device_t SpiHostDevice = VSPI_HOST;
|
||||||
|
static const int dmaChannel = 1; // arbitrary assignment, but based on the fact there are only two DMA channels and two available SPI ports, we need to split them somehow
|
||||||
|
static const int parallelBits = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Esp32Hspi2BitBus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const spi_host_device_t SpiHostDevice = HSPI_HOST;
|
||||||
|
static const int dmaChannel = 2; // arbitrary assignment, but based on the fact there are only two DMA channels and two available SPI ports, we need to split them somehow
|
||||||
|
static const int parallelBits = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Esp32Vspi4BitBus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const spi_host_device_t SpiHostDevice = VSPI_HOST;
|
||||||
|
static const int dmaChannel = 1; // arbitrary assignment, but based on the fact there are only two DMA channels and two available SPI ports, we need to split them somehow
|
||||||
|
static const int parallelBits = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Esp32Hspi4BitBus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const spi_host_device_t SpiHostDevice = HSPI_HOST;
|
||||||
|
static const int dmaChannel = 2; // arbitrary assignment, but based on the fact there are only two DMA channels and two available SPI ports, we need to split them somehow
|
||||||
|
static const int parallelBits = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T_SPISPEED, typename T_SPIBUS> class DotStarEsp32DmaSpiMethod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename T_SPISPEED::SettingsObject SettingsObject;
|
||||||
|
|
||||||
|
DotStarEsp32DmaSpiMethod(uint16_t pixelCount, size_t elementSize, size_t settingsSize) :
|
||||||
|
_sizePixelData(pixelCount * elementSize + settingsSize),
|
||||||
|
_sizeEndFrame((pixelCount + 15) / 16) // 16 = div 2 (bit for every two pixels) div 8 (bits to bytes)
|
||||||
|
{
|
||||||
|
_spiBufferSize = _sizeStartFrame + _sizePixelData + _sizeEndFrame;
|
||||||
|
|
||||||
|
// must have a 4 byte aligned buffer for i2s
|
||||||
|
uint32_t alignment = _spiBufferSize % 4;
|
||||||
|
if (alignment)
|
||||||
|
{
|
||||||
|
_spiBufferSize += 4 - alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
_data = static_cast<uint8_t*>(malloc(_spiBufferSize));
|
||||||
|
_dmadata = static_cast<uint8_t*>(heap_caps_malloc(_spiBufferSize, MALLOC_CAP_DMA));
|
||||||
|
|
||||||
|
// data cleared later in NeoPixelBus::Begin()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support constructor specifying pins by ignoring pins
|
||||||
|
DotStarEsp32DmaSpiMethod(uint8_t, uint8_t, uint16_t pixelCount, size_t elementSize, size_t settingsSize) :
|
||||||
|
DotStarEsp32DmaSpiMethod(pixelCount, elementSize, settingsSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~DotStarEsp32DmaSpiMethod()
|
||||||
|
{
|
||||||
|
if (_spiHandle)
|
||||||
|
{
|
||||||
|
DeInitSpiDevice();
|
||||||
|
esp_err_t ret = spi_bus_free(T_SPIBUS::SpiHostDevice);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
free(_data);
|
||||||
|
free(_dmadata);
|
||||||
|
_spiHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsReadyToUpdate() const
|
||||||
|
{
|
||||||
|
spi_transaction_t t;
|
||||||
|
spi_transaction_t * tptr = &t;
|
||||||
|
esp_err_t ret = spi_device_get_trans_result(_spiHandle, &tptr, 0);
|
||||||
|
|
||||||
|
// We know the previous transaction completed if we got ESP_OK, and we know there's no transactions queued if tptr is unmodified
|
||||||
|
return (ret == ESP_OK || tptr == &t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t ss)
|
||||||
|
{
|
||||||
|
memset(_data, 0x00, _sizeStartFrame);
|
||||||
|
memset(_data + _sizeStartFrame + _sizePixelData, 0x00, _spiBufferSize - (_sizeStartFrame + _sizePixelData));
|
||||||
|
|
||||||
|
_ssPin = ss;
|
||||||
|
|
||||||
|
esp_err_t ret;
|
||||||
|
spi_bus_config_t buscfg;
|
||||||
|
memset(&buscfg, 0x00, sizeof(buscfg));
|
||||||
|
|
||||||
|
buscfg.miso_io_num = dat1;
|
||||||
|
buscfg.mosi_io_num = dat0;
|
||||||
|
buscfg.sclk_io_num = sck;
|
||||||
|
buscfg.quadwp_io_num = dat2;
|
||||||
|
buscfg.quadhd_io_num = dat3;
|
||||||
|
buscfg.max_transfer_sz = _spiBufferSize;
|
||||||
|
|
||||||
|
//Initialize the SPI bus
|
||||||
|
ret=spi_bus_initialize(T_SPIBUS::SpiHostDevice, &buscfg, T_SPIBUS::dmaChannel);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
InitSpiDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||||
|
{
|
||||||
|
Initialize(sck, mosi, miso, -1, -1, ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If pins aren't specified, initialize bus with just the default SCK and MOSI pins for the SPI peripheral (no SS, no >1-bit pins)
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
if (T_SPIBUS::SpiHostDevice == VSPI_HOST)
|
||||||
|
{
|
||||||
|
Initialize(SCK, -1, MOSI, -1, -1, -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Initialize(14, -1, 13, -1, -1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(bool)
|
||||||
|
{
|
||||||
|
while(!IsReadyToUpdate());
|
||||||
|
|
||||||
|
memcpy(_dmadata, _data, _spiBufferSize);
|
||||||
|
|
||||||
|
memset(&_spiTransaction, 0, sizeof(spi_transaction_t));
|
||||||
|
_spiTransaction.length = (_spiBufferSize) * 8; // in bits not bytes!
|
||||||
|
if (T_SPIBUS::parallelBits == 1)
|
||||||
|
{
|
||||||
|
_spiTransaction.flags = 0;
|
||||||
|
}
|
||||||
|
if (T_SPIBUS::parallelBits == 2)
|
||||||
|
{
|
||||||
|
_spiTransaction.flags = SPI_TRANS_MODE_DIO;
|
||||||
|
}
|
||||||
|
if (T_SPIBUS::parallelBits == 4)
|
||||||
|
{
|
||||||
|
_spiTransaction.flags = SPI_TRANS_MODE_QIO;
|
||||||
|
}
|
||||||
|
_spiTransaction.tx_buffer = _dmadata;
|
||||||
|
|
||||||
|
esp_err_t ret = spi_device_queue_trans(_spiHandle, &_spiTransaction, 0); //Transmit!
|
||||||
|
assert(ret == ESP_OK); //Should have had no issues.
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* getData() const
|
||||||
|
{
|
||||||
|
return _data + _sizeStartFrame;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t getDataSize() const
|
||||||
|
{
|
||||||
|
return _sizePixelData;
|
||||||
|
};
|
||||||
|
|
||||||
|
void applySettings(const SettingsObject& settings)
|
||||||
|
{
|
||||||
|
_speed.applySettings(settings);
|
||||||
|
if (_spiHandle)
|
||||||
|
{
|
||||||
|
DeInitSpiDevice();
|
||||||
|
InitSpiDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitSpiDevice()
|
||||||
|
{
|
||||||
|
spi_device_interface_config_t devcfg = {};
|
||||||
|
|
||||||
|
devcfg.clock_speed_hz = _speed.Clock;
|
||||||
|
devcfg.mode = 0; //SPI mode 0
|
||||||
|
devcfg.spics_io_num = _ssPin; //CS pin
|
||||||
|
devcfg.queue_size = 1;
|
||||||
|
if (T_SPIBUS::parallelBits == 1)
|
||||||
|
{
|
||||||
|
devcfg.flags=0;
|
||||||
|
}
|
||||||
|
if (T_SPIBUS::parallelBits >= 2)
|
||||||
|
{
|
||||||
|
devcfg.flags=SPI_DEVICE_HALFDUPLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Allocate the LEDs on the SPI bus
|
||||||
|
esp_err_t ret=spi_bus_add_device(T_SPIBUS::SpiHostDevice, &devcfg, &_spiHandle);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeInitSpiDevice()
|
||||||
|
{
|
||||||
|
while(!IsReadyToUpdate());
|
||||||
|
esp_err_t ret = spi_bus_remove_device(_spiHandle);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t _sizeStartFrame = 4;
|
||||||
|
const size_t _sizePixelData; // Size of '_data' buffer below, minus (_sizeStartFrame + _sizeEndFrame)
|
||||||
|
const size_t _sizeEndFrame;
|
||||||
|
|
||||||
|
size_t _spiBufferSize;
|
||||||
|
uint8_t* _data; // Holds start/end frames and LED color values
|
||||||
|
uint8_t* _dmadata; // Holds start/end frames and LED color values
|
||||||
|
spi_device_handle_t _spiHandle = NULL;
|
||||||
|
spi_transaction_t _spiTransaction;
|
||||||
|
T_SPISPEED _speed;
|
||||||
|
int8_t _ssPin;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clock Speed and Default Definitions for DotStarEsp32DmaVspi
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed40Mhz, Esp32VspiBus> DotStarEsp32DmaVspi40MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed20Mhz, Esp32VspiBus> DotStarEsp32DmaVspi20MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed10Mhz, Esp32VspiBus> DotStarEsp32DmaVspi10MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed5Mhz, Esp32VspiBus> DotStarEsp32DmaVspi5MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed2Mhz, Esp32VspiBus> DotStarEsp32DmaVspi2MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed1Mhz, Esp32VspiBus> DotStarEsp32DmaVspi1MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed500Khz, Esp32VspiBus> DotStarEsp32DmaVspi500KhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeedHz, Esp32VspiBus> DotStarEsp32DmaVspiHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarEsp32DmaVspi10MhzMethod DotStarEsp32DmaVspiMethod;
|
||||||
|
|
||||||
|
// Clock Speed and Default Definitions for DotStarEsp32DmaHspi
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed40Mhz, Esp32HspiBus> DotStarEsp32DmaHspi40MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed20Mhz, Esp32HspiBus> DotStarEsp32DmaHspi20MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed10Mhz, Esp32HspiBus> DotStarEsp32DmaHspi10MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed5Mhz, Esp32HspiBus> DotStarEsp32DmaHspi5MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed2Mhz, Esp32HspiBus> DotStarEsp32DmaHspi2MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed1Mhz, Esp32HspiBus> DotStarEsp32DmaHspi1MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed500Khz, Esp32HspiBus> DotStarEsp32DmaHspi500KhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeedHz, Esp32HspiBus> DotStarEsp32DmaHspiHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarEsp32DmaHspi10MhzMethod DotStarEsp32DmaHspiMethod;
|
||||||
|
|
||||||
|
// Clock Speed and Default Definitions for DotStarEsp32DmaVspi2Bit
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed40Mhz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit40MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed20Mhz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit20MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed10Mhz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit10MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed5Mhz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit5MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed2Mhz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit2MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed1Mhz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit1MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed500Khz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2Bit500KhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeedHz,Esp32Vspi2BitBus> DotStarEsp32DmaVspi2BitHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarEsp32DmaVspi2Bit10MhzMethod DotStarEsp32DmaVspi2BitMethod;
|
||||||
|
|
||||||
|
// Clock Speed and Default Definitions for DotStarEsp32DmaHspi2Bit
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed40Mhz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit40MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed20Mhz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit20MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed10Mhz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit10MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed5Mhz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit5MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed2Mhz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit2MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed1Mhz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit1MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed500Khz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2Bit500KhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeedHz,Esp32Hspi2BitBus> DotStarEsp32DmaHspi2BitHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarEsp32DmaHspi2Bit10MhzMethod DotStarEsp32DmaHspi2BitMethod;
|
||||||
|
|
||||||
|
// Clock Speed and Default Definitions for DotStarEsp32DmaVspi4Bit
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed40Mhz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit40MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed20Mhz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit20MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed10Mhz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit10MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed5Mhz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit5MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed2Mhz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit2MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed1Mhz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit1MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed500Khz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4Bit500KhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeedHz,Esp32Vspi4BitBus> DotStarEsp32DmaVspi4BitHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarEsp32DmaVspi4Bit10MhzMethod DotStarEsp32DmaVspi4BitMethod;
|
||||||
|
|
||||||
|
// Clock Speed and Default Definitions for DotStarEsp32DmaHspi4Bit
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed40Mhz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit40MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed20Mhz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit20MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed10Mhz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit10MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed5Mhz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit5MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed2Mhz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit2MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed1Mhz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit1MhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeed500Khz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4Bit500KhzMethod;
|
||||||
|
typedef DotStarEsp32DmaSpiMethod<SpiSpeedHz,Esp32Hspi4BitBus> DotStarEsp32DmaHspi4BitHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarEsp32DmaHspi4Bit10MhzMethod DotStarEsp32DmaHspi4BitMethod;
|
@@ -134,14 +134,37 @@ typedef DotStarMethodBase<TwoWireBitBangImple> DotStarMethod;
|
|||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed40Mhz>> DotStarSpi40MhzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed40Mhz>> DotStarSpi40MhzMethod;
|
||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> DotStarSpi20MhzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> DotStarSpi20MhzMethod;
|
||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> DotStarSpi10MhzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> DotStarSpi10MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed5Mhz>> DotStarSpi5MhzMethod;
|
||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> DotStarSpi2MhzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> DotStarSpi2MhzMethod;
|
||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> DotStarSpi1MhzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> DotStarSpi1MhzMethod;
|
||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed500Khz>> DotStarSpi500KhzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed500Khz>> DotStarSpi500KhzMethod;
|
||||||
|
|
||||||
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeedHz>> DotStarSpiHzMethod;
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeedHz>> DotStarSpiHzMethod;
|
||||||
|
|
||||||
typedef DotStarSpi10MhzMethod DotStarSpiMethod;
|
typedef DotStarSpi10MhzMethod DotStarSpiMethod;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
// Give option to use Vspi alias of Spi class if wanting to specify which SPI peripheral is used on the ESP32
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed40Mhz>> DotStarVspi40MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> DotStarVspi20MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> DotStarVspi10MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed5Mhz>> DotStarVspi5MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> DotStarVspi2MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> DotStarVspi1MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed500Khz>> DotStarVspi500KhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeedHz>> DotStarVspiHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarSpi10MhzMethod DotStarVspiMethod;
|
||||||
|
|
||||||
|
#include "TwoWireHspiImple.h"
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed40Mhz>> DotStarHspi40MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed20Mhz>> DotStarHspi20MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed10Mhz>> DotStarHspi10MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed5Mhz>> DotStarHspi5MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed2Mhz>> DotStarHspi2MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed1Mhz>> DotStarHspi1MhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeed500Khz>> DotStarHspi500KhzMethod;
|
||||||
|
typedef DotStarMethodBase<TwoWireHspiImple<SpiSpeedHz>> DotStarHspiHzMethod;
|
||||||
|
|
||||||
|
typedef DotStarHspi10MhzMethod DotStarHspiMethod;
|
||||||
|
#endif
|
||||||
|
@@ -129,6 +129,7 @@ typedef Lpd6803MethodBase<TwoWireBitBangImple> Lpd6803Method;
|
|||||||
#include "TwoWireSpiImple.h"
|
#include "TwoWireSpiImple.h"
|
||||||
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> Lpd6803Spi20MhzMethod;
|
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> Lpd6803Spi20MhzMethod;
|
||||||
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> Lpd6803Spi10MhzMethod;
|
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> Lpd6803Spi10MhzMethod;
|
||||||
|
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed5Mhz>> Lpd6803Spi5MhzMethod;
|
||||||
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> Lpd6803Spi2MhzMethod;
|
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> Lpd6803Spi2MhzMethod;
|
||||||
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> Lpd6803Spi1MhzMethod;
|
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> Lpd6803Spi1MhzMethod;
|
||||||
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> Lpd6803Spi500KhzMethod;
|
typedef Lpd6803MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> Lpd6803Spi500KhzMethod;
|
||||||
|
@@ -129,6 +129,7 @@ typedef Lpd8806MethodBase<TwoWireBitBangImple> Lpd8806Method;
|
|||||||
#include "TwoWireSpiImple.h"
|
#include "TwoWireSpiImple.h"
|
||||||
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> Lpd8806Spi20MhzMethod;
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> Lpd8806Spi20MhzMethod;
|
||||||
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> Lpd8806Spi10MhzMethod;
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> Lpd8806Spi10MhzMethod;
|
||||||
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed5Mhz>> Lpd8806Spi5MhzMethod;
|
||||||
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> Lpd8806Spi2MhzMethod;
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> Lpd8806Spi2MhzMethod;
|
||||||
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> Lpd8806Spi1MhzMethod;
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> Lpd8806Spi1MhzMethod;
|
||||||
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> Lpd8806Spi500KhzMethod;
|
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> Lpd8806Spi500KhzMethod;
|
||||||
|
@@ -125,6 +125,7 @@ typedef P9813MethodBase<TwoWireBitBangImple> P9813Method;
|
|||||||
#include "TwoWireSpiImple.h"
|
#include "TwoWireSpiImple.h"
|
||||||
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> P9813Spi20MhzMethod;
|
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> P9813Spi20MhzMethod;
|
||||||
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> P9813Spi10MhzMethod;
|
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> P9813Spi10MhzMethod;
|
||||||
|
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed5Mhz>> P9813Spi5MhzMethod;
|
||||||
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> P9813Spi2MhzMethod;
|
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> P9813Spi2MhzMethod;
|
||||||
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> P9813Spi1MhzMethod;
|
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> P9813Spi1MhzMethod;
|
||||||
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> P9813Spi500KhzMethod;
|
typedef P9813MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> P9813Spi500KhzMethod;
|
||||||
|
92
src/internal/TwoWireHspiImple.h
Normal file
92
src/internal/TwoWireHspiImple.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for DotStars using ESP32's alternate SPI (HSPI) (APA102/LPD8806).
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
Minor changes adapting TwoWireSpiImple to support HSPI by Louis Beaudoin (Pixelvation)
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
template<typename T_SPISPEED> class TwoWireHspiImple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename T_SPISPEED::SettingsObject SettingsObject;
|
||||||
|
|
||||||
|
TwoWireHspiImple(uint8_t, uint8_t) // clock and data pins ignored for hardware SPI
|
||||||
|
{
|
||||||
|
_hspi = new SPIClass(HSPI);
|
||||||
|
}
|
||||||
|
|
||||||
|
~TwoWireHspiImple()
|
||||||
|
{
|
||||||
|
_hspi->end();
|
||||||
|
delete _hspi;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
_hspi->begin(sck, miso, mosi, ss);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void begin()
|
||||||
|
{
|
||||||
|
_hspi->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void beginTransaction()
|
||||||
|
{
|
||||||
|
_hspi->beginTransaction(SPISettings(_speed.Clock, MSBFIRST, SPI_MODE0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void endTransaction()
|
||||||
|
{
|
||||||
|
_hspi->endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitByte(uint8_t data)
|
||||||
|
{
|
||||||
|
_hspi->transfer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitBytes(const uint8_t* data, size_t dataSize)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
_hspi->writeBytes(const_cast<uint8_t*>(data), dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void applySettings(const SettingsObject& settings)
|
||||||
|
{
|
||||||
|
_speed.applySettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SPIClass * _hspi = NULL;
|
||||||
|
T_SPISPEED _speed;
|
||||||
|
};
|
@@ -1,5 +1,5 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
|
NeoPixel library helper functions for DotStars using SPI (APA102/LPD8806).
|
||||||
|
|
||||||
Written by Michael C. Miller.
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
@@ -61,6 +61,17 @@ public:
|
|||||||
static const uint32_t Clock = 10000000L;
|
static const uint32_t Clock = 10000000L;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SpiSpeed5Mhz
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef NeoNoSettings SettingsObject;
|
||||||
|
SpiSpeed5Mhz() {};
|
||||||
|
|
||||||
|
static void applySettings(const SettingsObject& settings) {}
|
||||||
|
|
||||||
|
static const uint32_t Clock = 5000000L;
|
||||||
|
};
|
||||||
|
|
||||||
class SpiSpeed2Mhz
|
class SpiSpeed2Mhz
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -131,6 +131,7 @@ typedef Ws2801MethodBase<TwoWireBitBangImple> NeoWs2801Method;
|
|||||||
#include "TwoWireSpiImple.h"
|
#include "TwoWireSpiImple.h"
|
||||||
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> NeoWs2801Spi20MhzMethod;
|
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> NeoWs2801Spi20MhzMethod;
|
||||||
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> NeoWs2801Spi10MhzMethod;
|
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> NeoWs2801Spi10MhzMethod;
|
||||||
|
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed5Mhz>> NeoWs2801Spi5MhzMethod;
|
||||||
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> NeoWs2801Spi2MhzMethod;
|
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> NeoWs2801Spi2MhzMethod;
|
||||||
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> NeoWs2801Spi1MhzMethod;
|
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed1Mhz>> NeoWs2801Spi1MhzMethod;
|
||||||
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> NeoWs2801Spi500KhzMethod;
|
typedef Ws2801MethodBase<TwoWireSpiImple<SpiSpeed500Khz>> NeoWs2801Spi500KhzMethod;
|
||||||
|
Reference in New Issue
Block a user