Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Guyer <sam.guyer@gmail.com>2020-12-30 21:38:39 +0300
committerGitHub <noreply@github.com>2020-12-30 21:38:39 +0300
commit41652f2045ec9df7d5faf5b35efac280e13837f5 (patch)
treebf30a4b44c3ba0608b6690a1c78659a2f4bf8c9e
parent82e2c4a5f2914632ab7d20f0f88c611a83974eb7 (diff)
parent51d2891cff0264dcb17c05939b09a27a47f87447 (diff)
Merge pull request #1163 from samguyer/master
Fix for a bug that was limiting parallelism
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.cpp35
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.h61
2 files changed, 40 insertions, 56 deletions
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.cpp b/src/platforms/esp/32/clockless_rmt_esp32.cpp
index 658f6daa..ca8aec47 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.cpp
+++ b/src/platforms/esp/32/clockless_rmt_esp32.cpp
@@ -34,7 +34,12 @@ CMinWait<50> gWait;
static bool gInitialized = false;
-ESP32RMTController::ESP32RMTController(int DATA_PIN, int T1, int T2, int T3)
+// -- Stored values for FASTLED_RMT_MAX_CHANNELS and FASTLED_RMT_MEM_BLOCKS
+int ESP32RMTController::gMaxChannel;
+int ESP32RMTController::gMemBlocks;
+
+
+ESP32RMTController::ESP32RMTController(int DATA_PIN, int T1, int T2, int T3, int maxChannel, int memBlocks)
: mPixelData(0),
mSize(0),
mCur(0),
@@ -43,6 +48,10 @@ ESP32RMTController::ESP32RMTController(int DATA_PIN, int T1, int T2, int T3)
mBufferSize(0),
mCurPulse(0)
{
+ // -- Store the max channel and mem blocks parameters
+ gMaxChannel = maxChannel;
+ gMemBlocks = memBlocks;
+
// -- Precompute rmt items corresponding to a zero bit and a one bit
// according to the timing values given in the template instantiation
// T1H
@@ -75,11 +84,11 @@ ESP32RMTController::ESP32RMTController(int DATA_PIN, int T1, int T2, int T3)
// -- Get or create the buffer for the pixel data
// We can't allocate it ahead of time because we don't have
// the PixelController object until show is called.
-uint32_t * ESP32RMTController::getPixelBuffer(int size_in_bytes)
+uint8_t * ESP32RMTController::getPixelBuffer(int size_in_bytes)
{
if (mPixelData == 0) {
- mSize = ((size_in_bytes-1) / sizeof(uint32_t)) + 1;
- mPixelData = (uint32_t *) calloc( mSize, sizeof(uint32_t));
+ mSize = size_in_bytes;
+ mPixelData = (uint8_t *) malloc(mSize);
}
return mPixelData;
}
@@ -90,15 +99,15 @@ void ESP32RMTController::init(gpio_num_t pin)
{
if (gInitialized) return;
- for (int i = 0; i < FASTLED_RMT_MAX_CHANNELS; i++) {
+ for (int i = 0; i < gMaxChannel; i += gMemBlocks) {
gOnChannel[i] = NULL;
// -- RMT configuration for transmission
rmt_config_t rmt_tx;
rmt_tx.channel = rmt_channel_t(i);
rmt_tx.rmt_mode = RMT_MODE_TX;
- rmt_tx.gpio_num = pin; // The particular pin will be assigned later
- rmt_tx.mem_block_num = FASTLED_RMT_MEM_BLOCKS;
+ rmt_tx.gpio_num = pin;
+ rmt_tx.mem_block_num = gMemBlocks;
rmt_tx.clk_div = DIVIDER;
rmt_tx.tx_config.loop_en = false;
rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
@@ -167,11 +176,11 @@ void IRAM_ATTR ESP32RMTController::showPixels()
// -- First, fill all the available channels
int channel = 0;
- while (channel < FASTLED_RMT_MAX_CHANNELS && gNext < gNumControllers) {
+ while (channel < gMaxChannel && gNext < gNumControllers) {
ESP32RMTController::startNext(channel);
// -- Important: when we use more than one memory block, we need to
// skip the channels that would otherwise overlap in memory.
- channel += FASTLED_RMT_MEM_BLOCKS;
+ channel += gMemBlocks;
}
// -- Wait here while the data is sent. The interrupt handler
@@ -318,7 +327,7 @@ void IRAM_ATTR ESP32RMTController::interruptHandler(void *arg)
uint8_t channel;
bool stuff_to_do = false;
- for (channel = 0; channel < FASTLED_RMT_MAX_CHANNELS; channel++) {
+ for (channel = 0; channel < gMaxChannel; channel++) {
int tx_done_bit = channel * 3;
int tx_next_bit = channel + 24;
@@ -376,16 +385,16 @@ void IRAM_ATTR ESP32RMTController::fillNext(bool check_time)
// -- Use locals for speed
volatile register uint32_t * pItem = mRMT_mem_ptr;
- for (register int i = 0; i < PULSES_PER_FILL/32; i++) {
+ for (register int i = 0; i < PULSES_PER_FILL/8; i++) {
if (mCur < mSize) {
// -- Get the next four bytes of pixel data
- register uint32_t pixeldata = mPixelData[mCur];
+ register uint32_t pixeldata = mPixelData[mCur] << 24;
mCur++;
// Shift bits out, MSB first, setting RMTMEM.chan[n].data32[x] to the
// rmt_item32_t value corresponding to the buffered bit value
- for (register uint32_t j = 0; j < 32; j++) {
+ for (register uint32_t j = 0; j < 8; j++) {
*pItem++ = (pixeldata & 0x80000000L) ? one_val : zero_val;
// Replaces: RMTMEM.chan[mRMT_channel].data32[mCurPulse].val = val;
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.h b/src/platforms/esp/32/clockless_rmt_esp32.h
index 2e723179..3a10f9ca 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.h
+++ b/src/platforms/esp/32/clockless_rmt_esp32.h
@@ -183,10 +183,9 @@ __attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
#define FASTLED_RMT_MAX_CONTROLLERS 32
#endif
-// -- Number of RMT channels to use (up to 8, but 4 by default)
-// Redefine this value to 1 to force serial output
+// -- Max RMT channel (default to 8)
#ifndef FASTLED_RMT_MAX_CHANNELS
-#define FASTLED_RMT_MAX_CHANNELS (8/FASTLED_RMT_MEM_BLOCKS)
+#define FASTLED_RMT_MAX_CHANNELS 8
#endif
class ESP32RMTController
@@ -210,7 +209,7 @@ private:
uint32_t mLastFill;
// -- Pixel data
- uint32_t * mPixelData;
+ uint8_t * mPixelData;
int mSize;
int mCur;
@@ -225,18 +224,23 @@ private:
uint16_t mBufferSize; // bytes
int mCurPulse;
+ // -- These values need to be real variables, so we can access them
+ // in the cpp file
+ static int gMaxChannel;
+ static int gMemBlocks;
+
public:
// -- Constructor
// Mainly just stores the template parameters from the LEDController as
// member variables.
- ESP32RMTController(int DATA_PIN, int T1, int T2, int T3);
+ ESP32RMTController(int DATA_PIN, int T1, int T2, int T3, int maxChannel, int memBlocks);
// -- Get max cycles per fill
uint32_t IRAM_ATTR getMaxCyclesPerFill() const { return mMaxCyclesPerFill; }
// -- Get or create the pixel data buffer
- uint32_t * getPixelBuffer(int size_in_bytes);
+ uint8_t * getPixelBuffer(int size_in_bytes);
// -- Initialize RMT subsystem
// This only needs to be done once. The particular pin is not important,
@@ -308,12 +312,11 @@ private:
public:
ClocklessController()
- : mRMTController(DATA_PIN, T1, T2, T3)
+ : mRMTController(DATA_PIN, T1, T2, T3, FASTLED_RMT_MAX_CHANNELS, FASTLED_RMT_MEM_BLOCKS)
{}
void init()
{
- // mRMTController = new ESP32RMTController(DATA_PIN, T1, T2, T3);
}
virtual uint16_t getMaxRefreshRate() const { return 400; }
@@ -329,43 +332,15 @@ protected:
{
// -- Make sure the buffer is allocated
int size_in_bytes = pixels.size() * 3;
- uint32_t * pData = mRMTController.getPixelBuffer(size_in_bytes);
+ uint8_t * pData = mRMTController.getPixelBuffer(size_in_bytes);
- // -- Read out the pixel data using the pixel controller methods that
- // perform the scaling and adjustments
- int count = 0;
- int which = 0;
+ // -- This might be faster
while (pixels.has(1)) {
- // -- Get the next four bytes of data
- uint8_t four[4] = {0,0,0,0};
- for (int i = 0; i < 4; i++) {
- switch (which) {
- case 0:
- four[i] = pixels.loadAndScale0();
- break;
- case 1:
- four[i] = pixels.loadAndScale1();
- break;
- case 2:
- four[i] = pixels.loadAndScale2();
- pixels.advanceData();
- pixels.stepDithering();
- break;
- }
- // -- Move to the next color
- which++;
- if (which > 2) which = 0;
-
- // -- Stop if there's no more data
- if ( ! pixels.has(1)) break;
- }
-
- // -- Pack the four bytes into a 32-bit value with the right bit order
- uint8_t a = four[0];
- uint8_t b = four[1];
- uint8_t c = four[2];
- uint8_t d = four[3];
- pData[count++] = a << 24 | b << 16 | c << 8 | d;
+ *pData++ = pixels.loadAndScale0();
+ *pData++ = pixels.loadAndScale1();
+ *pData++ = pixels.loadAndScale2();
+ pixels.advanceData();
+ pixels.stepDithering();
}
}