diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp | 50 | ||||
| -rw-r--r-- | src/ESP32-HUB75-MatrixPanel-I2S-DMA.h | 10 |
2 files changed, 44 insertions, 16 deletions
diff --git a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp index b0457cf..c049c73 100644 --- a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp +++ b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp @@ -8,6 +8,16 @@ static const char* TAG = "MatrixPanel"; */ #define getRowDataPtr(row, _dpth, buff_id) &(dma_buff.rowBits[row]->data[_dpth * dma_buff.rowBits[row]->width + buff_id*(dma_buff.rowBits[row]->width * dma_buff.rowBits[row]->colour_depth)]) +// 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 +#if defined (ESP32_THE_ORIG) + #define ESP32_TX_FIFO_POSITION_ADJUST(x_coord) (x_coord & 1U ? (x_coord-1):(x_coord+1)) +#else + #define ESP32_TX_FIFO_POSITION_ADJUST(x_coord) x_coord +#endif + + bool MatrixPanel_I2S_DMA::allocateDMAmemory() { @@ -240,15 +250,17 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg) * Let's put it into IRAM to avoid situations when it could be flushed out of instruction cache * and had to be read from spi-flash over and over again. * Yes, it is always a tradeoff between memory/speed/size, but compared to DMA-buffer size is not a big deal + * + * Note: Cannot pass a negative co-ord as it makes no sense in the DMA bit array lookup. */ -void IRAM_ATTR MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t y_coord, uint8_t red, uint8_t green, uint8_t blue) +void IRAM_ATTR MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint16_t x_coord, uint16_t y_coord, uint8_t red, uint8_t green, uint8_t blue) { if ( !initialized ) return; /* 1) Check that the co-ordinates are within range, or it'll break everything big time. * Valid co-ordinates are from 0 to (MATRIX_XXXX-1) */ - if ( x_coord < 0 || y_coord < 0 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) { + if ( x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) { return; } @@ -274,14 +286,16 @@ void IRAM_ATTR MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16 * so we have to check for this and check the correct position of the MATRIX_DATA_STORAGE_TYPE * data. */ - +/* #if defined (ESP32_THE_ORIG) // 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 x_coord & 1U ? --x_coord : ++x_coord; #endif - +*/ + x_coord = ESP32_TX_FIFO_POSITION_ADJUST(x_coord); + uint16_t _colourbitclear = BITMASK_RGB1_CLEAR, _colourbitoffset = 0; @@ -417,7 +431,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164 row[x_pixel] = abcde & (0x18 << BITS_ADDR_OFFSET); // mask out the bottom 3 bits which are the clk di bk inputs } else { - row[x_pixel] = abcde; + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel)] = abcde; } // ESP_LOGI(TAG, "x pixel 1: %d", x_pixel); } while(x_pixel!=dma_buff.rowBits[row_idx]->width && x_pixel); @@ -433,7 +447,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164 row[x_pixel] = abcde & (0x18 << BITS_ADDR_OFFSET); // mask out the bottom 3 bits which are the clk di bk inputs } else { - row[x_pixel] = abcde; + row[ESP32_TX_FIFO_POSITION_ADJUST(x_pixel)] = abcde; } //row[x_pixel] = abcde; // ESP_LOGI(TAG, "x pixel 2: %d", x_pixel); @@ -465,6 +479,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ // switch pointer to a row for a specific color index row = dma_buff.rowBits[row_idx]->getDataPtr(colouridx, _buff_id); + /* #if defined(ESP32_THE_ORIG) // 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 @@ -474,13 +489,17 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ // -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 #endif + */ + row[ESP32_TX_FIFO_POSITION_ADJUST(dma_buff.rowBits[row_idx]->width - 1)] |= BIT_LAT; // -1 pixel to compensate array index starting at 0 + + //ESP32_TX_FIFO_POSITION_ADJUST(dma_buff.rowBits[row_idx]->width - 1) // need to disable OE before/after latch to hide row transition // Should be one clock or more before latch, otherwise can get ghosting uint8_t _blank = m_cfg.latch_blanking; do { --_blank; - + /* #if defined(ESP32_THE_ORIG) // Original ESP32 WROOM FIFO Ordering Sucks uint8_t _blank_row_tx_fifo_tmp = 0 + _blank; @@ -494,6 +513,11 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ 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 #endif + */ + + row[ESP32_TX_FIFO_POSITION_ADJUST(0 + _blank)] |= BIT_OE; + row[ESP32_TX_FIFO_POSITION_ADJUST(dma_buff.rowBits[row_idx]->width - _blank - 1)] |= BIT_OE; // (LAT pulse is (width-2) -1 pixel to compensate array index starting at 0 + } while (_blank); @@ -535,11 +559,11 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){ --x_coord; // clear OE bit for all other pixels - row[x_coord] &= BITMASK_OE_CLEAR; + row[ESP32_TX_FIFO_POSITION_ADJUST(x_coord)] &= BITMASK_OE_CLEAR; // Brightness control via OE toggle - disable matrix output at specified x_coord if((colouridx > lsbMsbTransitionBit || !colouridx) && ((x_coord) >= brt)){ - row[x_coord] |= BIT_OE; // Disable output after this point. + row[ESP32_TX_FIFO_POSITION_ADJUST(x_coord)] |= BIT_OE; // Disable output after this point. continue; } // special case for the bits *after* LSB through (lsbMsbTransitionBit) - OE is output after data is shifted, so need to set OE to fractional brightness @@ -547,7 +571,7 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){ // divide brightness in half for each bit below lsbMsbTransitionBit int lsbBrightness = brt >> (lsbMsbTransitionBit - colouridx + 1); if((x_coord) >= lsbBrightness) { - row[x_coord] |= BIT_OE; // Disable output after this point. + row[ESP32_TX_FIFO_POSITION_ADJUST(x_coord)] |= BIT_OE; // Disable output after this point. continue; } } @@ -560,7 +584,7 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){ uint8_t _blank = m_cfg.latch_blanking; do { --_blank; - +/* #if defined(ESP32_THE_ORIG) // Original ESP32 WROOM FIFO Ordering Sucks uint8_t _blank_row_tx_fifo_tmp = 0 + _blank; @@ -569,6 +593,10 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){ #else row[0 + _blank] |= BIT_OE; #endif +*/ + + row[ESP32_TX_FIFO_POSITION_ADJUST(0 + _blank)] |= BIT_OE; + //row[0 + _blank] |= BIT_OE; // no need, has been done already diff --git a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h index 34ccb2f..425f850 100644 --- a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h +++ b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.h @@ -113,8 +113,8 @@ #define BITMASK_CTRL_CLEAR (0b1110000000111111) // inverted bitmask for control bits ABCDE,LAT,OE in pixel vector #define BITMASK_OE_CLEAR (0b1111111101111111) // inverted bitmask for control bit OE in pixel vector -// How many clock cycles to blank OE before/after LAT signal change, default is 1 clock -#define DEFAULT_LAT_BLANKING 1 +// How many clock cycles to blank OE before/after LAT signal change, default is 2 clocks +#define DEFAULT_LAT_BLANKING 2 // Max clock cycles to blank OE before/after LAT signal change #define MAX_LAT_BLANKING 4 @@ -280,7 +280,7 @@ struct HUB75_I2S_CFG { shift_driver _drv = SHIFTREG, bool _dbuff = false, clk_speed _i2sspeed = HZ_10M, - uint8_t _latblk = 1, // Anything > 1 seems to cause artefacts on ICS panels + uint8_t _latblk = DEFAULT_LAT_BLANKING, // Anything > 1 seems to cause artefacts on ICS panels bool _clockphase = true, uint8_t _min_refresh_rate = 85 ) : mx_width(_w), @@ -406,7 +406,7 @@ class MatrixPanel_I2S_DMA { /** * A wrapper to fill whatever selected DMA buffer / screen with black */ - inline void clearScreen(){ updateMatrixDMABuffer(0,0,0); }; + inline void clearScreen(){ clearFrameBuffer(back_buffer_id); /*updateMatrixDMABuffer(0,0,0);*/ }; #ifndef NO_FAST_FUNCTIONS /** @@ -582,7 +582,7 @@ class MatrixPanel_I2S_DMA { void clearFrameBuffer(bool _buff_id = 0); /* Update a specific pixel in the DMA buffer to a colour */ - void updateMatrixDMABuffer(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8_t blue); + void updateMatrixDMABuffer(uint16_t x, uint16_t y, uint8_t red, uint8_t green, uint8_t blue); /* Update the entire DMA buffer (aka. The RGB Panel) a certain colour (wipe the screen basically) */ void updateMatrixDMABuffer(uint8_t red, uint8_t green, uint8_t blue); |
