From b237440d63803a16e7bf298096cddab7d1d9bf9d Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Mon, 19 Aug 2019 17:47:40 -0700 Subject: [PATCH] Esp32 update i2s (#283) * Update NeoEsp32I2sMethod.h * Esp32i2sFixes * Improve Apa106 RMT timing --- keywords.txt | 16 ++++++++++++++++ src/internal/Esp32_i2s.c | 6 +++--- src/internal/Esp32_i2s.h | 2 ++ src/internal/NeoEsp32I2sMethod.h | 31 +++++++++++++++++++++---------- src/internal/NeoEsp32RmtMethod.h | 4 ++-- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/keywords.txt b/keywords.txt index 4d51c8c..4734aca 100644 --- a/keywords.txt +++ b/keywords.txt @@ -27,8 +27,10 @@ NeoWs2812xMethod KEYWORD1 NeoWs2812Method KEYWORD1 NeoSk6812Method KEYWORD1 NeoLc8812Method KEYWORD1 +NeoApa106Method KEYWORD1 NeoEsp8266DmaWs2812xMethod KEYWORD1 NeoEsp8266DmaSk6812Method KEYWORD1 +NeoEsp8266DmaApa106Method KEYWORD1 NeoEsp8266Dma800KbpsMethod KEYWORD1 NeoEsp8266Dma400KbpsMethod KEYWORD1 NeoEsp8266Uart0Ws2813Method KEYWORD1 @@ -36,6 +38,7 @@ NeoEsp8266Uart0Ws2812xMethod KEYWORD1 NeoEsp8266Uart0Ws2812Method KEYWORD1 NeoEsp8266Uart0Sk6812Method KEYWORD1 NeoEsp8266Uart0Lc8812Method KEYWORD1 +NeoEsp8266Uart0Apa106Method KEYWORD1 NeoEsp8266Uart0800KbpsMethod KEYWORD1 NeoEsp8266Uart0400KbpsMethod KEYWORD1 NeoEsp8266AsyncUart0Ws2813Method KEYWORD1 @@ -43,6 +46,7 @@ NeoEsp8266AsyncUart0Ws2812xMethod KEYWORD1 NeoEsp8266AsyncUart0Ws2812Method KEYWORD1 NeoEsp8266AsyncUart0Sk6812Method KEYWORD1 NeoEsp8266AsyncUart0Lc8812Method KEYWORD1 +NeoEsp8266AsyncUart0Apa106Method KEYWORD1 NeoEsp8266AsyncUart0800KbpsMethod KEYWORD1 NeoEsp8266AsyncUart0400KbpsMethod KEYWORD1 NeoEsp8266Uart1Ws2813Method KEYWORD1 @@ -50,6 +54,7 @@ NeoEsp8266Uart1Ws2812xMethod KEYWORD1 NeoEsp8266Uart1Ws2812Method KEYWORD1 NeoEsp8266Uart1Sk6812Method KEYWORD1 NeoEsp8266Uart1Lc8812Method KEYWORD1 +NeoEsp8266Uart1Apa106Method KEYWORD1 NeoEsp8266Uart1800KbpsMethod KEYWORD1 NeoEsp8266Uart1400KbpsMethod KEYWORD1 NeoEsp8266AsyncUart1Ws2813Method KEYWORD1 @@ -57,6 +62,7 @@ NeoEsp8266AsyncUart1Ws2812xMethod KEYWORD1 NeoEsp8266AsyncUart1Ws2812Method KEYWORD1 NeoEsp8266AsyncUart1Sk6812Method KEYWORD1 NeoEsp8266AsyncUart1Lc8812Method KEYWORD1 +NeoEsp8266AsyncUart1Apa106Method KEYWORD1 NeoEsp8266AsyncUart1800KbpsMethod KEYWORD1 NeoEsp8266AsyncUart1400KbpsMethod KEYWORD1 NeoEsp8266BitBangWs2813Method KEYWORD1 @@ -64,38 +70,47 @@ NeoEsp8266BitBangWs2812xMethod KEYWORD1 NeoEsp8266BitBangWs2812Method KEYWORD1 NeoEsp8266BitBangSk6812Method KEYWORD1 NeoEsp8266BitBangLc8812Method KEYWORD1 +NeoEsp8266BitBangApa106Method KEYWORD1 NeoEsp8266BitBang800KbpsMethod KEYWORD1 NeoEsp8266BitBang400KbpsMethod KEYWORD1 NeoEsp32Rmt0Ws2812xMethod KEYWORD1 NeoEsp32Rmt0Sk6812Method KEYWORD1 +NeoEsp32Rmt0Apa106Method KEYWORD1 NeoEsp32Rmt0800KbpsMethod KEYWORD1 NeoEsp32Rmt0400KbpsMethod KEYWORD1 NeoEsp32Rmt1Ws2812xMethod KEYWORD1 NeoEsp32Rmt1Sk6812Method KEYWORD1 +NeoEsp32Rmt1Apa106Method KEYWORD1 NeoEsp32Rmt1800KbpsMethod KEYWORD1 NeoEsp32Rmt1400KbpsMethod KEYWORD1 NeoEsp32Rmt2Ws2812xMethod KEYWORD1 NeoEsp32Rmt2Sk6812Method KEYWORD1 +NeoEsp32Rmt2Apa106Method KEYWORD1 NeoEsp32Rmt2800KbpsMethod KEYWORD1 NeoEsp32Rmt2400KbpsMethod KEYWORD1 NeoEsp32Rmt3Ws2812xMethod KEYWORD1 NeoEsp32Rmt3Sk6812Method KEYWORD1 +NeoEsp32Rmt3Apa106Method KEYWORD1 NeoEsp32Rmt3800KbpsMethod KEYWORD1 NeoEsp32Rmt3400KbpsMethod KEYWORD1 NeoEsp32Rmt4Ws2812xMethod KEYWORD1 NeoEsp32Rmt4Sk6812Method KEYWORD1 +NeoEsp32Rmt4Apa106Method KEYWORD1 NeoEsp32Rmt4800KbpsMethod KEYWORD1 NeoEsp32Rmt4400KbpsMethod KEYWORD1 NeoEsp32Rmt5Ws2812xMethod KEYWORD1 NeoEsp32Rmt5Sk6812Method KEYWORD1 +NeoEsp32Rmt5Apa106Method KEYWORD1 NeoEsp32Rmt5800KbpsMethod KEYWORD1 NeoEsp32Rmt5400KbpsMethod KEYWORD1 NeoEsp32Rmt6Ws2812xMethod KEYWORD1 NeoEsp32Rmt6Sk6812Method KEYWORD1 +NeoEsp32Rmt6Apa106Method KEYWORD1 NeoEsp32Rmt6800KbpsMethod KEYWORD1 NeoEsp32Rmt6400KbpsMethod KEYWORD1 NeoEsp32Rmt7Ws2812xMethod KEYWORD1 NeoEsp32Rmt7Sk6812Method KEYWORD1 +NeoEsp32Rmt7Apa106Method KEYWORD1 NeoEsp32Rmt7800KbpsMethod KEYWORD1 NeoEsp32Rmt7400KbpsMethod KEYWORD1 NeoEsp32BitBangWs2813Method KEYWORD1 @@ -103,6 +118,7 @@ NeoEsp32BitBangWs2812xMethod KEYWORD1 NeoEsp32BitBangWs2812Method KEYWORD1 NeoEsp32BitBangSk6812Method KEYWORD1 NeoEsp32BitBangLc8812Method KEYWORD1 +NeoEsp32BitBangApa106Method KEYWORD1 NeoEsp32BitBang800KbpsMethod KEYWORD1 NeoEsp32BitBang400KbpsMethod KEYWORD1 DotStarMethod KEYWORD1 diff --git a/src/internal/Esp32_i2s.c b/src/internal/Esp32_i2s.c index 0c0612b..092170e 100644 --- a/src/internal/Esp32_i2s.c +++ b/src/internal/Esp32_i2s.c @@ -45,7 +45,7 @@ #define ESP32_REG(addr) (*((volatile uint32_t*)(0x3FF00000+(addr)))) #define I2S_DMA_QUEUE_SIZE 16 -#define I2S_DMA_MAX_DATA_LEN 4092// maximum bytes in one dma item + #define I2S_DMA_SILENCE_LEN 256 // bytes typedef struct i2s_dma_item_s { @@ -142,7 +142,7 @@ bool i2sInitDmaItems(uint8_t bus_num) { } } - I2S[bus_num].tx_queue = xQueueCreate(I2S[bus_num].dma_count - 3, sizeof(i2s_dma_item_t*)); + I2S[bus_num].tx_queue = xQueueCreate(I2S[bus_num].dma_count, sizeof(i2s_dma_item_t*)); if (I2S[bus_num].tx_queue == NULL) {// memory error log_e("MEM ERROR!"); free(I2S[bus_num].dma_items); @@ -273,7 +273,7 @@ bool i2sWriteDone(uint8_t bus_num) { if (bus_num > 1) { return false; } - return (I2S[bus_num].dma_items[0].data == I2S[bus_num].silence_buf && I2S[bus_num].dma_items[1].data == I2S[bus_num].silence_buf); + return (I2S[bus_num].dma_items[I2S[bus_num].dma_count - 1].data == I2S[bus_num].silence_buf); } void i2sInit(uint8_t bus_num, uint32_t bits_per_sample, uint32_t sample_rate, i2s_tx_chan_mod_t chan_mod, i2s_tx_fifo_mod_t fifo_mod, size_t dma_count, size_t dma_len) { diff --git a/src/internal/Esp32_i2s.h b/src/internal/Esp32_i2s.h index a779e8c..0027369 100644 --- a/src/internal/Esp32_i2s.h +++ b/src/internal/Esp32_i2s.h @@ -8,6 +8,8 @@ extern "C" { #include "esp_err.h" +#define I2S_DMA_MAX_DATA_LEN 4092// maximum bytes in one dma item + typedef enum { I2S_CHAN_STEREO, I2S_CHAN_RIGHT_TO_LEFT, I2S_CHAN_LEFT_TO_RIGHT, I2S_CHAN_RIGHT_ONLY, I2S_CHAN_LEFT_ONLY } i2s_tx_chan_mod_t; diff --git a/src/internal/NeoEsp32I2sMethod.h b/src/internal/NeoEsp32I2sMethod.h index 2883e94..d7856a1 100644 --- a/src/internal/NeoEsp32I2sMethod.h +++ b/src/internal/NeoEsp32I2sMethod.h @@ -35,37 +35,47 @@ extern "C" } const uint16_t c_dmaBytesPerPixelBytes = 4; -const uint16_t c_dmaBytesPer50us = 20; -const uint32_t c_dmaI2sSampleRate = 100000; class NeoEsp32I2sSpeedWs2812x { public: - const static uint16_t I2sSampleRateDiv = 1; + const static uint32_t I2sSampleRate = 100000; + const static uint16_t ByteSendTimeUs = 10; const static uint16_t ResetTimeUs = 300; }; class NeoEsp32I2sSpeedSk6812 { public: - const static uint16_t I2sSampleRateDiv = 1; + const static uint32_t I2sSampleRate = 100000; + const static uint16_t ByteSendTimeUs = 10; const static uint16_t ResetTimeUs = 80; }; class NeoEsp32I2sSpeed800Kbps { public: - const static uint16_t I2sSampleRateDiv = 1; + const static uint32_t I2sSampleRate = 100000; + const static uint16_t ByteSendTimeUs = 10; const static uint16_t ResetTimeUs = 50; }; class NeoEsp32I2sSpeed400Kbps { public: - const static uint16_t I2sSampleRateDiv = 2; + const static uint32_t I2sSampleRate = 50000; + const static uint16_t ByteSendTimeUs = 20; const static uint16_t ResetTimeUs = 50; }; +class NeoEsp32I2sSpeedApa106 +{ +public: + const static uint32_t I2sSampleRate = 76000; + const static uint16_t ByteSendTimeUs = 14; + const static uint16_t ResetTimeUs = 50; +}; + class NeoEsp32I2sBusZero { public: @@ -85,7 +95,7 @@ public: _pin(pin) { uint16_t dmaPixelSize = c_dmaBytesPerPixelBytes * elementSize; - uint16_t resetSize = (c_dmaBytesPer50us * T_SPEED::ResetTimeUs / 50 / T_SPEED::I2sSampleRateDiv); + uint16_t resetSize = c_dmaBytesPerPixelBytes * T_SPEED::ResetTimeUs / T_SPEED::ByteSendTimeUs; _pixelsSize = pixelCount * elementSize; _i2sBufferSize = pixelCount * dmaPixelSize + resetSize; @@ -124,7 +134,8 @@ public: void Initialize() { - i2sInit(T_BUS::I2sBusNumber, 16, c_dmaI2sSampleRate / T_SPEED::I2sSampleRateDiv, I2S_CHAN_STEREO, I2S_FIFO_16BIT_DUAL, 4, 0); + size_t dmaCount = (_i2sBufferSize + I2S_DMA_MAX_DATA_LEN - 1) / I2S_DMA_MAX_DATA_LEN; + i2sInit(T_BUS::I2sBusNumber, 16, T_SPEED::I2sSampleRate, I2S_CHAN_STEREO, I2S_FIFO_16BIT_DUAL, dmaCount, 0); i2sSetPins(T_BUS::I2sBusNumber, _pin, -1, -1, -1); } @@ -184,13 +195,13 @@ typedef NeoEsp32I2sMethodBase NeoEs typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Sk6812Method; typedef NeoEsp32I2sMethodBase NeoEsp32I2s0800KbpsMethod; typedef NeoEsp32I2sMethodBase NeoEsp32I2s0400KbpsMethod; -typedef NeoEsp32I2s0400KbpsMethod NeoEsp32I2s0Apa106Method; +typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Apa106Method; typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Ws2812xMethod; typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Sk6812Method; typedef NeoEsp32I2sMethodBase NeoEsp32I2s1800KbpsMethod; typedef NeoEsp32I2sMethodBase NeoEsp32I2s1400KbpsMethod; -typedef NeoEsp32I2s1400KbpsMethod NeoEsp32I2s1Apa106Method; +typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Apa106Method; // I2s Bus 1 method is the default method for Esp32 typedef NeoEsp32I2s1Ws2812xMethod NeoWs2813Method; diff --git a/src/internal/NeoEsp32RmtMethod.h b/src/internal/NeoEsp32RmtMethod.h index 7e37f0f..86669e5 100644 --- a/src/internal/NeoEsp32RmtMethod.h +++ b/src/internal/NeoEsp32RmtMethod.h @@ -106,8 +106,8 @@ public: class NeoEsp32RmtSpeedApa106 : public NeoEsp32RmtSpeedBase { public: - const static uint32_t RmtBit0 = Item32Val(400, 1400); - const static uint32_t RmtBit1 = Item32Val(1400, 400); + const static uint32_t RmtBit0 = Item32Val(400, 1250); + const static uint32_t RmtBit1 = Item32Val(1250, 400); const static uint16_t RmtDurationReset = FromNs(50000); // 50us };