Backport tx fifo byte ordering fix for ESP32-WROOM-32
This commit is contained in:
parent
2f8f465cc6
commit
f5681b2983
2 changed files with 67 additions and 22 deletions
|
@ -1,6 +1,5 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
|
#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
|
||||||
//#include "xtensa/core-macros.h"
|
|
||||||
|
|
||||||
// Credits: Louis Beaudoin <https://github.com/pixelmatix/SmartMatrix/tree/teensylc>
|
// Credits: Louis Beaudoin <https://github.com/pixelmatix/SmartMatrix/tree/teensylc>
|
||||||
// and Sprite_TM: https://www.esp32.com/viewtopic.php?f=17&t=3188 and https://www.esp32.com/viewtopic.php?f=13&t=3256
|
// and Sprite_TM: https://www.esp32.com/viewtopic.php?f=17&t=3188 and https://www.esp32.com/viewtopic.php?f=13&t=3256
|
||||||
|
@ -484,10 +483,14 @@ void IRAM_ATTR MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP32_S2
|
||||||
// We need to update the correct uint16_t in the rowBitStruct array, that gets sent out in parallel
|
// We need to update the correct uint16_t in the rowBitStruct array, that gets sent out in parallel
|
||||||
// 16 bit parallel mode - Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
// 16 bit parallel mode - Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
||||||
|
// Irrelevant for ESP32-S2 the way the FIFO ordering works is different - refer to page 679 of S2 technical reference manual
|
||||||
x_coord & 1U ? --x_coord : ++x_coord;
|
x_coord & 1U ? --x_coord : ++x_coord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint16_t _colorbitclear = BITMASK_RGB1_CLEAR, _colorbitoffset = 0;
|
uint16_t _colorbitclear = BITMASK_RGB1_CLEAR, _colorbitoffset = 0;
|
||||||
|
|
||||||
if (y_coord >= ROWS_PER_FRAME){ // if we are drawing to the bottom part of the panel
|
if (y_coord >= ROWS_PER_FRAME){ // if we are drawing to the bottom part of the panel
|
||||||
|
@ -661,24 +664,46 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){
|
||||||
|
|
||||||
|
|
||||||
// let's set LAT/OE control bits for specific pixels in each color_index subrows
|
// let's set LAT/OE control bits for specific pixels in each color_index subrows
|
||||||
|
// Need to consider the original ESP32's (WROOM) DMA TX FIFO reordering of bytes...
|
||||||
uint8_t coloridx = dma_buff.rowBits[row_idx]->color_depth;
|
uint8_t coloridx = dma_buff.rowBits[row_idx]->color_depth;
|
||||||
do {
|
do {
|
||||||
--coloridx;
|
--coloridx;
|
||||||
|
|
||||||
// switch pointer to a row for a specific color index
|
// switch pointer to a row for a specific color index
|
||||||
row = dma_buff.rowBits[row_idx]->getDataPtr(coloridx, _buff_id);
|
row = dma_buff.rowBits[row_idx]->getDataPtr(coloridx, _buff_id);
|
||||||
|
|
||||||
// drive latch while shifting out last bit of RGB data
|
#ifdef ESP32_S2
|
||||||
row[dma_buff.rowBits[row_idx]->width - 2] |= BIT_LAT; // -1 pixel to compensate array index starting at 0
|
// -1 works better on ESP32-S2 ? Because bytes get sent out in order...
|
||||||
//row[dma_buff.rowBits[row_idx]->width - 1] |= BIT_LAT; // -1 pixel to compensate array index starting at 0
|
row[dma_buff.rowBits[row_idx]->width - 1] |= BIT_LAT; // -1 pixel to compensate array index starting at 0
|
||||||
|
#else
|
||||||
|
// We need to update the correct uint16_t in the rowBitStruct array, that gets sent out in parallel
|
||||||
|
// 16 bit parallel mode - Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
||||||
|
// Irrelevant for ESP32-S2 the way the FIFO ordering works is different - refer to page 679 of S2 technical reference manual
|
||||||
|
row[dma_buff.rowBits[row_idx]->width - 2] |= BIT_LAT; // -2 in the DMA array is actually -1 when it's reordered by TX FIFO
|
||||||
|
#endif
|
||||||
|
|
||||||
// need to disable OE before/after latch to hide row transition
|
// need to disable OE before/after latch to hide row transition
|
||||||
// Should be one clock or more before latch, otherwise can get ghosting
|
// Should be one clock or more before latch, otherwise can get ghosting
|
||||||
uint8_t _blank = m_cfg.latch_blanking;
|
uint8_t _blank = m_cfg.latch_blanking;
|
||||||
do {
|
do {
|
||||||
--_blank;
|
--_blank;
|
||||||
row[0 + _blank] |= BIT_OE;
|
|
||||||
row[dma_buff.rowBits[row_idx]->width - _blank - 3 ] |= BIT_OE; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0
|
#ifdef ESP32_S2
|
||||||
|
row[0 + _blank] |= BIT_OE;
|
||||||
|
row[dma_buff.rowBits[row_idx]->width - _blank - 1 ] |= BIT_OE; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Original ESP32 WROOM FIFO Ordering Sucks
|
||||||
|
uint8_t _blank_row_tx_fifo_tmp = 0 + _blank;
|
||||||
|
(_blank_row_tx_fifo_tmp & 1U) ? --_blank_row_tx_fifo_tmp : ++_blank_row_tx_fifo_tmp;
|
||||||
|
row[_blank_row_tx_fifo_tmp] |= BIT_OE;
|
||||||
|
|
||||||
|
_blank_row_tx_fifo_tmp = dma_buff.rowBits[row_idx]->width - _blank - 1; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0
|
||||||
|
(_blank_row_tx_fifo_tmp & 1U) ? --_blank_row_tx_fifo_tmp : ++_blank_row_tx_fifo_tmp;
|
||||||
|
row[_blank_row_tx_fifo_tmp] |= BIT_OE;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} while (_blank);
|
} while (_blank);
|
||||||
|
|
||||||
} while(coloridx);
|
} while(coloridx);
|
||||||
|
@ -741,7 +766,17 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){
|
||||||
uint8_t _blank = m_cfg.latch_blanking;
|
uint8_t _blank = m_cfg.latch_blanking;
|
||||||
do {
|
do {
|
||||||
--_blank;
|
--_blank;
|
||||||
row[0 + _blank] |= BIT_OE;
|
|
||||||
|
#ifdef ESP32_S2
|
||||||
|
row[0 + _blank] |= BIT_OE;
|
||||||
|
#else
|
||||||
|
// Original ESP32 WROOM FIFO Ordering Sucks
|
||||||
|
uint8_t _blank_row_tx_fifo_tmp = 0 + _blank;
|
||||||
|
(_blank_row_tx_fifo_tmp & 1U) ? --_blank_row_tx_fifo_tmp : ++_blank_row_tx_fifo_tmp;
|
||||||
|
row[_blank_row_tx_fifo_tmp] |= BIT_OE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//row[0 + _blank] |= BIT_OE;
|
||||||
// no need, has been done already
|
// no need, has been done already
|
||||||
//row[dma_buff.rowBits[row_idx]->width - _blank - 3 ] |= BIT_OE; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0
|
//row[dma_buff.rowBits[row_idx]->width - _blank - 3 ] |= BIT_OE; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0
|
||||||
} while (_blank);
|
} while (_blank);
|
||||||
|
@ -860,8 +895,14 @@ void MatrixPanel_I2S_DMA::hlineDMA(int16_t x_coord, int16_t y_coord, int16_t l,
|
||||||
int16_t _l = l;
|
int16_t _l = l;
|
||||||
do { // iterate pixels in a row
|
do { // iterate pixels in a row
|
||||||
int16_t _x = x_coord + --_l;
|
int16_t _x = x_coord + --_l;
|
||||||
|
|
||||||
|
#ifdef ESP32_S2
|
||||||
|
// ESP 32 doesn't need byte flipping for TX FIFO.
|
||||||
|
uint16_t &v = p[_x];
|
||||||
|
#else
|
||||||
// Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
// Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
||||||
uint16_t &v = p[_x & 1U ? --_x : ++_x];
|
uint16_t &v = p[_x & 1U ? --_x : ++_x];
|
||||||
|
#endif
|
||||||
|
|
||||||
v &= _colorbitclear; // reset color bits
|
v &= _colorbitclear; // reset color bits
|
||||||
v |= RGB_output_bits; // set new color bits
|
v |= RGB_output_bits; // set new color bits
|
||||||
|
@ -896,8 +937,10 @@ void MatrixPanel_I2S_DMA::vlineDMA(int16_t x_coord, int16_t y_coord, int16_t l,
|
||||||
blue = lumConvTab[blue];
|
blue = lumConvTab[blue];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
#ifndef ESP32_S2
|
||||||
|
// Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
||||||
x_coord & 1U ? --x_coord : ++x_coord;
|
x_coord & 1U ? --x_coord : ++x_coord;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t color_depth_idx = PIXEL_COLOR_DEPTH_BITS;
|
uint8_t color_depth_idx = PIXEL_COLOR_DEPTH_BITS;
|
||||||
do { // Iterating through color depth bits (8 iterations)
|
do { // Iterating through color depth bits (8 iterations)
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
#ifndef _ESP32_RGB_64_32_MATRIX_PANEL_I2S_DMA
|
#ifndef _ESP32_RGB_64_32_MATRIX_PANEL_I2S_DMA
|
||||||
#define _ESP32_RGB_64_32_MATRIX_PANEL_I2S_DMA
|
#define _ESP32_RGB_64_32_MATRIX_PANEL_I2S_DMA
|
||||||
|
|
||||||
/***************************************************************************************/
|
/*******************************************************************************************
|
||||||
/* COMPILE-TIME OPTIONS - Provide as part of PlatformIO project build_flags. */
|
* COMPILE-TIME OPTIONS - MUST BE PROVIDED as part of PlatformIO project build_flags. *
|
||||||
/***************************************************************************************/
|
* Changing the values just here won't work - as defines needs to persist beyond the scope *
|
||||||
|
* of just this file. *
|
||||||
|
*******************************************************************************************/
|
||||||
/* Enable serial debugging of the library, to see how memory is allocated etc. */
|
/* Enable serial debugging of the library, to see how memory is allocated etc. */
|
||||||
//#define SERIAL_DEBUG 1
|
//#define SERIAL_DEBUG 1
|
||||||
|
|
||||||
|
/* Do NOT build additional methods optimized for fast drawing,
|
||||||
/*
|
* i.e. Adafruits drawFastHLine, drawFastVLine, etc... */
|
||||||
* Do NOT build additional methods optimized for fast drawing,
|
|
||||||
* i.e. Adafruits drawFastHLine, drawFastVLine, etc...
|
|
||||||
*/
|
|
||||||
//#define NO_FAST_FUNCTIONS
|
//#define NO_FAST_FUNCTIONS
|
||||||
|
|
||||||
/* Use GFX_Root (https://github.com/mrfaptastic/GFX_Root) instead of Adafruit_GFX library.
|
/* Use GFX_Root (https://github.com/mrfaptastic/GFX_Root) instead of Adafruit_GFX library.
|
||||||
|
@ -21,7 +20,6 @@
|
||||||
*/
|
*/
|
||||||
//#define USE_GFX_ROOT 1
|
//#define USE_GFX_ROOT 1
|
||||||
|
|
||||||
|
|
||||||
/* Physical / Chained HUB75(s) RGB pixel WIDTH and HEIGHT.
|
/* Physical / Chained HUB75(s) RGB pixel WIDTH and HEIGHT.
|
||||||
*
|
*
|
||||||
* This library has been tested with a 64x32 and 64x64 RGB panels.
|
* This library has been tested with a 64x32 and 64x64 RGB panels.
|
||||||
|
@ -87,11 +85,16 @@
|
||||||
// #define NO_CIE1931
|
// #define NO_CIE1931
|
||||||
|
|
||||||
/***************************************************************************************/
|
/***************************************************************************************/
|
||||||
/* Library Includes! */
|
/* Core ESP32 hardware / idf includes! */
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "esp32_i2s_parallel_v2.h"
|
|
||||||
|
#ifdef ESP32_S2
|
||||||
|
#include "esp32-s2_i2s_parallel_v1.h"
|
||||||
|
#else
|
||||||
|
#include "esp32_i2s_parallel_v2.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_GFX_ROOT
|
#ifdef USE_GFX_ROOT
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
|
@ -101,7 +104,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************/
|
/***************************************************************************************/
|
||||||
/* Definitions below should NOT be ever changed without rewriting library logic */
|
/* Definitions below should NOT be ever changed without rewriting library logic */
|
||||||
#define ESP32_I2S_DMA_MODE I2S_PARALLEL_WIDTH_16 // From esp32_i2s_parallel_v2.h = 16 bits in parallel
|
#define ESP32_I2S_DMA_MODE I2S_PARALLEL_WIDTH_16 // From esp32_i2s_parallel_v2.h = 16 bits in parallel
|
||||||
|
|
Loading…
Reference in a new issue