diff --git a/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp index 0347ad7..0570079 100644 --- a/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp +++ b/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp @@ -415,14 +415,14 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg) }; // Setup I2S - i2s_parallel_driver_install(I2S_NUM_1, &cfg); + i2s_parallel_driver_install(I2S_NUM_0, &cfg); //i2s_parallel_setup_without_malloc(&I2S1, &cfg); // Start DMA Output - i2s_parallel_send_dma(I2S_NUM_1, &dmadesc_a[0]); + i2s_parallel_send_dma(I2S_NUM_0, &dmadesc_a[0]); #if SERIAL_DEBUG - Serial.println(F("configureDMA(): DMA setup completed on I2S1.")); + Serial.println(F("configureDMA(): DMA setup completed on I2S_NUM_0.")); #endif } // end initMatrixDMABuff @@ -603,7 +603,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ int row_idx = dma_buff.rowBits.size(); do { --row_idx; - + ESP32_I2S_DMA_STORAGE_TYPE* row = dma_buff.rowBits[row_idx]->getDataPtr(0, _buff_id); // set pointer to the HEAD of a buffer holding data for the entire matrix row ESP32_I2S_DMA_STORAGE_TYPE abcde = (ESP32_I2S_DMA_STORAGE_TYPE)row_idx; @@ -616,7 +616,15 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ // fill all x_pixels except color_index[0] (LSB) ones, this also clears all color data to 0's black do { --x_pixel; - row[x_pixel] = abcde; + + if ( m_cfg.driver == HUB75_I2S_CFG::SM5266P) { + // modifications here for row shift register type SM5266P + // 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; + } + } while(x_pixel!=dma_buff.rowBits[row_idx]->width); // color_index[0] (LSB) x_pixels must be "marked" with a previous's row address, 'cause it is used to display @@ -624,8 +632,33 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){ abcde = ((ESP32_I2S_DMA_STORAGE_TYPE)row_idx-1) << BITS_ADDR_OFFSET; do { --x_pixel; - row[x_pixel] = abcde; + + if ( m_cfg.driver == HUB75_I2S_CFG::SM5266P) { + // modifications here for row shift register type SM5266P + // 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[x_pixel] = abcde; } while(x_pixel); + + + // modifications here for row shift register type SM5266P + // https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/164 + if ( m_cfg.driver == HUB75_I2S_CFG::SM5266P) { + uint16_t serialCount; + uint16_t latch; + x_pixel = dma_buff.rowBits[row_idx]->width - 16; // come back 8*2 pixels to allow for 8 writes + serialCount = 8; + do{ + serialCount--; + latch = row[x_pixel] | (((((ESP32_I2S_DMA_STORAGE_TYPE)row_idx) % 8) == serialCount) << 1) << BITS_ADDR_OFFSET; // data on 'B' + row[x_pixel++] = latch| (0x05<< BITS_ADDR_OFFSET); // clock high on 'A'and BK high for update + row[x_pixel++] = latch| (0x04<< BITS_ADDR_OFFSET); // clock low on 'A'and BK high for update + } while (serialCount); + } // end SM5266P + // let's set LAT/OE control bits for specific pixels in each color_index subrows uint8_t coloridx = dma_buff.rowBits[row_idx]->color_depth; @@ -721,7 +754,8 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){ /* * overload for compatibility */ -bool MatrixPanel_I2S_DMA::begin(int r1, int g1, int b1, int r2, int g2, int b2, int a, int b, int c, int d, int e, int lat, int oe, int clk){ + /* +bool MatrixPanel_I2S_DMA::begin(int r1, int g1, int b1, int r2, int g2, int b2, int a, int b, int c, int d, int e, int lat, int oe, int clk) { // RGB m_cfg.gpio.r1 = r1; m_cfg.gpio.g1 = g1; m_cfg.gpio.b1 = b1; @@ -736,6 +770,7 @@ bool MatrixPanel_I2S_DMA::begin(int r1, int g1, int b1, int r2, int g2, int b2, return begin(); } +*/ /** * @brief - Sets how many clock cycles to blank OE before/after LAT signal change @@ -772,8 +807,11 @@ void MatrixPanel_I2S_DMA::hlineDMA(int16_t x_coord, int16_t y_coord, int16_t l, if ( x_coord < 0 || y_coord < 0 || l < 1 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) return; - if (x_coord+l > PIXELS_PER_ROW) - l = PIXELS_PER_ROW - x_coord + 1; // reset width to end of row + + l = ( (x_coord + l) >= PIXELS_PER_ROW ) ? (PIXELS_PER_ROW - x_coord):l; + + //if (x_coord+l > PIXELS_PER_ROW) +// l = PIXELS_PER_ROW - x_coord + 1; // reset width to end of row /* LED Brightness Compensation */ #ifndef NO_CIE1931 @@ -846,8 +884,10 @@ void MatrixPanel_I2S_DMA::vlineDMA(int16_t x_coord, int16_t y_coord, int16_t l, if ( x_coord < 0 || y_coord < 0 || l < 1 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height) return; - if (y_coord + l > m_cfg.mx_height) - l = m_cfg.mx_height - y_coord + 1; // reset width to end of col + // check for a length that goes beyond the height of the screen! Array out of bounds dma memory changes = screwed output #163 + l = ( (y_coord + l) >= m_cfg.mx_height ) ? (m_cfg.mx_height - y_coord):l; + //if (y_coord + l > m_cfg.mx_height) + /// l = m_cfg.mx_height - y_coord + 1; // reset width to end of col /* LED Brightness Compensation */ #ifndef NO_CIE1931 diff --git a/ESP32-HUB75-MatrixPanel-I2S-DMA.h b/ESP32-HUB75-MatrixPanel-I2S-DMA.h index ae55622..a5f1bad 100644 --- a/ESP32-HUB75-MatrixPanel-I2S-DMA.h +++ b/ESP32-HUB75-MatrixPanel-I2S-DMA.h @@ -229,7 +229,7 @@ struct HUB75_I2S_CFG { * Enumeration of hardware-specific chips * used to drive matrix modules */ - enum shift_driver {SHIFTREG=0, FM6124, FM6126A, ICN2038S, MBI5124}; + enum shift_driver {SHIFTREG=0, FM6124, FM6126A, ICN2038S, MBI5124, SM5266P}; /** * I2S clock speed selector @@ -292,7 +292,7 @@ struct HUB75_I2S_CFG { shift_driver _drv = SHIFTREG, bool _dbuff = false, clk_speed _i2sspeed = HZ_10M, - uint8_t _latblk = 1, + uint8_t _latblk = 4, bool _clockphase = true, uint8_t _min_refresh_rate = 85 ) : mx_width(_w), @@ -350,6 +350,8 @@ class MatrixPanel_I2S_DMA { /* Propagate the DMA pin configuration, allocate DMA buffs and start data ouput, initialy blank */ bool begin(){ + + if (initialized) return true; // we don't do this twice or more! // Change 'if' to '1' to enable, 0 to not include this Serial output in compiled program #if SERIAL_DEBUG @@ -411,7 +413,9 @@ class MatrixPanel_I2S_DMA { /* * overload for compatibility */ + /* bool begin(int r1, int g1 = G1_PIN_DEFAULT, int b1 = B1_PIN_DEFAULT, int r2 = R2_PIN_DEFAULT, int g2 = G2_PIN_DEFAULT, int b2 = B2_PIN_DEFAULT, int a = A_PIN_DEFAULT, int b = B_PIN_DEFAULT, int c = C_PIN_DEFAULT, int d = D_PIN_DEFAULT, int e = E_PIN_DEFAULT, int lat = LAT_PIN_DEFAULT, int oe = OE_PIN_DEFAULT, int clk = CLK_PIN_DEFAULT); + */ // TODO: Disable/Enable auto buffer flipping (useful for lots of drawPixel usage)... @@ -515,7 +519,7 @@ class MatrixPanel_I2S_DMA { Serial.printf_P(PSTR("Showtime for buffer: %d\n"), back_buffer_id); #endif - i2s_parallel_flip_to_buffer(I2S_NUM_1, back_buffer_id); + i2s_parallel_flip_to_buffer(I2S_NUM_0, back_buffer_id); // Wait before we allow any writing to the buffer. Stop flicker. while(!i2s_parallel_is_previous_buffer_free()) { delay(1); } @@ -570,7 +574,7 @@ class MatrixPanel_I2S_DMA { */ void stopDMAoutput() { resetbuffers(); - i2s_parallel_stop_dma(I2S_NUM_1); + i2s_parallel_stop_dma(I2S_NUM_0); } diff --git a/esp32_i2s_parallel_v2.c b/esp32_i2s_parallel_v2.c index 46a0ce0..fd48d22 100644 --- a/esp32_i2s_parallel_v2.c +++ b/esp32_i2s_parallel_v2.c @@ -84,6 +84,11 @@ static void dma_reset(i2s_dev_t* dev) { dev->lc_conf.in_rst = 0; dev->lc_conf.out_rst = 1; dev->lc_conf.out_rst = 0; + + dev->lc_conf.ahbm_rst = 1; + dev->lc_conf.ahbm_rst = 0; + + } static void fifo_reset(i2s_dev_t* dev) { diff --git a/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino b/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino index 464fa1e..cfcd768 100644 --- a/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino +++ b/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino @@ -93,8 +93,7 @@ void drawText(int colorWheelOffset) void setup() { -// - + // Module configuration HUB75_I2S_CFG mxconfig( PANEL_RES_X, // module width PANEL_RES_Y, // module height @@ -112,9 +111,6 @@ void setup() { dma_display->clearScreen(); dma_display->fillScreen(myWHITE); -// - dma_display->begin(); // use default pins - // fix the screen with green dma_display->fillRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(0, 15, 0)); delay(500);