Merge pull request #168 from mrfaptastic/SM5266P
Implement Sm5266 panels Increase default latch blanking Get rid of the legacy begin() usage of the library. Fix a minor bug with the DMA v and h line draw with out-of-bounds x/y/length params.
This commit is contained in:
commit
00917150ff
4 changed files with 65 additions and 20 deletions
|
@ -415,14 +415,14 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup I2S
|
// 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);
|
//i2s_parallel_setup_without_malloc(&I2S1, &cfg);
|
||||||
|
|
||||||
// Start DMA Output
|
// 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
|
#if SERIAL_DEBUG
|
||||||
Serial.println(F("configureDMA(): DMA setup completed on I2S1."));
|
Serial.println(F("configureDMA(): DMA setup completed on I2S_NUM_0."));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // end initMatrixDMABuff
|
} // end initMatrixDMABuff
|
||||||
|
@ -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
|
// fill all x_pixels except color_index[0] (LSB) ones, this also clears all color data to 0's black
|
||||||
do {
|
do {
|
||||||
--x_pixel;
|
--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);
|
} 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
|
// color_index[0] (LSB) x_pixels must be "marked" with a previous's row address, 'cause it is used to display
|
||||||
|
@ -624,9 +632,34 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id){
|
||||||
abcde = ((ESP32_I2S_DMA_STORAGE_TYPE)row_idx-1) << BITS_ADDR_OFFSET;
|
abcde = ((ESP32_I2S_DMA_STORAGE_TYPE)row_idx-1) << BITS_ADDR_OFFSET;
|
||||||
do {
|
do {
|
||||||
--x_pixel;
|
--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);
|
} 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
|
// 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;
|
uint8_t coloridx = dma_buff.rowBits[row_idx]->color_depth;
|
||||||
do {
|
do {
|
||||||
|
@ -721,7 +754,8 @@ void MatrixPanel_I2S_DMA::brtCtrlOE(int brt, const bool _buff_id){
|
||||||
/*
|
/*
|
||||||
* overload for compatibility
|
* 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
|
// RGB
|
||||||
m_cfg.gpio.r1 = r1; m_cfg.gpio.g1 = g1; m_cfg.gpio.b1 = b1;
|
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();
|
return begin();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief - Sets how many clock cycles to blank OE before/after LAT signal change
|
* @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)
|
if ( x_coord < 0 || y_coord < 0 || l < 1 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height)
|
||||||
return;
|
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 */
|
/* LED Brightness Compensation */
|
||||||
#ifndef NO_CIE1931
|
#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)
|
if ( x_coord < 0 || y_coord < 0 || l < 1 || x_coord >= PIXELS_PER_ROW || y_coord >= m_cfg.mx_height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (y_coord + l > m_cfg.mx_height)
|
// check for a length that goes beyond the height of the screen! Array out of bounds dma memory changes = screwed output #163
|
||||||
l = m_cfg.mx_height - y_coord + 1; // reset width to end of col
|
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 */
|
/* LED Brightness Compensation */
|
||||||
#ifndef NO_CIE1931
|
#ifndef NO_CIE1931
|
||||||
|
|
|
@ -229,7 +229,7 @@ struct HUB75_I2S_CFG {
|
||||||
* Enumeration of hardware-specific chips
|
* Enumeration of hardware-specific chips
|
||||||
* used to drive matrix modules
|
* 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
|
* I2S clock speed selector
|
||||||
|
@ -292,7 +292,7 @@ struct HUB75_I2S_CFG {
|
||||||
shift_driver _drv = SHIFTREG,
|
shift_driver _drv = SHIFTREG,
|
||||||
bool _dbuff = false,
|
bool _dbuff = false,
|
||||||
clk_speed _i2sspeed = HZ_10M,
|
clk_speed _i2sspeed = HZ_10M,
|
||||||
uint8_t _latblk = 1,
|
uint8_t _latblk = 4,
|
||||||
bool _clockphase = true,
|
bool _clockphase = true,
|
||||||
uint8_t _min_refresh_rate = 85
|
uint8_t _min_refresh_rate = 85
|
||||||
) : mx_width(_w),
|
) : mx_width(_w),
|
||||||
|
@ -351,6 +351,8 @@ class MatrixPanel_I2S_DMA {
|
||||||
/* Propagate the DMA pin configuration, allocate DMA buffs and start data ouput, initialy blank */
|
/* Propagate the DMA pin configuration, allocate DMA buffs and start data ouput, initialy blank */
|
||||||
bool begin(){
|
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
|
// Change 'if' to '1' to enable, 0 to not include this Serial output in compiled program
|
||||||
#if SERIAL_DEBUG
|
#if SERIAL_DEBUG
|
||||||
Serial.printf_P(PSTR("Using pin %d for the R1_PIN\n"), m_cfg.gpio.r1);
|
Serial.printf_P(PSTR("Using pin %d for the R1_PIN\n"), m_cfg.gpio.r1);
|
||||||
|
@ -411,7 +413,9 @@ class MatrixPanel_I2S_DMA {
|
||||||
/*
|
/*
|
||||||
* overload for compatibility
|
* 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);
|
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)...
|
// 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);
|
Serial.printf_P(PSTR("Showtime for buffer: %d\n"), back_buffer_id);
|
||||||
#endif
|
#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.
|
// Wait before we allow any writing to the buffer. Stop flicker.
|
||||||
while(!i2s_parallel_is_previous_buffer_free()) { delay(1); }
|
while(!i2s_parallel_is_previous_buffer_free()) { delay(1); }
|
||||||
|
@ -570,7 +574,7 @@ class MatrixPanel_I2S_DMA {
|
||||||
*/
|
*/
|
||||||
void stopDMAoutput() {
|
void stopDMAoutput() {
|
||||||
resetbuffers();
|
resetbuffers();
|
||||||
i2s_parallel_stop_dma(I2S_NUM_1);
|
i2s_parallel_stop_dma(I2S_NUM_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,11 @@ static void dma_reset(i2s_dev_t* dev) {
|
||||||
dev->lc_conf.in_rst = 0;
|
dev->lc_conf.in_rst = 0;
|
||||||
dev->lc_conf.out_rst = 1;
|
dev->lc_conf.out_rst = 1;
|
||||||
dev->lc_conf.out_rst = 0;
|
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) {
|
static void fifo_reset(i2s_dev_t* dev) {
|
||||||
|
|
|
@ -93,8 +93,7 @@ void drawText(int colorWheelOffset)
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|
||||||
//
|
// Module configuration
|
||||||
|
|
||||||
HUB75_I2S_CFG mxconfig(
|
HUB75_I2S_CFG mxconfig(
|
||||||
PANEL_RES_X, // module width
|
PANEL_RES_X, // module width
|
||||||
PANEL_RES_Y, // module height
|
PANEL_RES_Y, // module height
|
||||||
|
@ -112,9 +111,6 @@ void setup() {
|
||||||
dma_display->clearScreen();
|
dma_display->clearScreen();
|
||||||
dma_display->fillScreen(myWHITE);
|
dma_display->fillScreen(myWHITE);
|
||||||
|
|
||||||
//
|
|
||||||
dma_display->begin(); // use default pins
|
|
||||||
|
|
||||||
// fix the screen with green
|
// fix the screen with green
|
||||||
dma_display->fillRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(0, 15, 0));
|
dma_display->fillRect(0, 0, dma_display->width(), dma_display->height(), dma_display->color444(0, 15, 0));
|
||||||
delay(500);
|
delay(500);
|
||||||
|
|
Loading…
Reference in a new issue