Reduce / Remove Ghosting
After a lot of trial and error, I believe I've found the resolution to the ghosting, and it's as simple as reducing the brightness level to 60. The actual brightness doesn't change it seems, but the timing of the OE pin being set HIGH is performed earlier which can work better on some panels. Closes: #14 #12
This commit is contained in:
parent
85d0d44891
commit
ebddfd96f4
3 changed files with 47 additions and 331 deletions
|
@ -146,22 +146,6 @@ void RGB64x32MatrixPanel_I2S_DMA::configureDMA(int r1_pin, int g1_pin, int b1_
|
||||||
|
|
||||||
Serial.printf("Performing I2S setup.\n");
|
Serial.printf("Performing I2S setup.\n");
|
||||||
|
|
||||||
/*
|
|
||||||
i2s_parallel_config_t cfg={
|
|
||||||
.gpio_bus={R1_PIN_DEFAULT, G1_PIN_DEFAULT, B1_PIN_DEFAULT, R2_PIN_DEFAULT, G2_PIN_DEFAULT, B2_PIN_DEFAULT, LAT_PIN_DEFAULT, OE_PIN_DEFAULT, A_PIN_DEFAULT, B_PIN_DEFAULT, C_PIN_DEFAULT, D_PIN_DEFAULT, E_PIN_DEFAULT, -1, -1, -1},
|
|
||||||
.gpio_clk=CLK_PIN_DEFAULT,
|
|
||||||
.clkspeed_hz=ESP32_I2S_CLOCK_SPEED, //ESP32_I2S_CLOCK_SPEED, // formula used is 80000000L/(cfg->clkspeed_hz + 1), must result in >=2. Acceptable values 26.67MHz, 20MHz, 16MHz, 13.34MHz...
|
|
||||||
.bits=MATRIX_I2S_MODE, //MATRIX_I2S_MODE,
|
|
||||||
.bufa=0,
|
|
||||||
.bufb=0,
|
|
||||||
desccount,
|
|
||||||
desccount,
|
|
||||||
dmadesc_a,
|
|
||||||
dmadesc_b
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i2s_parallel_config_t cfg={
|
i2s_parallel_config_t cfg={
|
||||||
.gpio_bus={r1_pin, g1_pin, b1_pin, r2_pin, g2_pin, b2_pin, lat_pin, oe_pin, a_pin, b_pin, c_pin, d_pin, e_pin, -1, -1, -1},
|
.gpio_bus={r1_pin, g1_pin, b1_pin, r2_pin, g2_pin, b2_pin, lat_pin, oe_pin, a_pin, b_pin, c_pin, d_pin, e_pin, -1, -1, -1},
|
||||||
|
@ -231,12 +215,30 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
|
||||||
if (gpioRowAddress & 0x08) v|=BIT_D; // 8
|
if (gpioRowAddress & 0x08) v|=BIT_D; // 8
|
||||||
if (gpioRowAddress & 0x10) v|=BIT_E; // 16
|
if (gpioRowAddress & 0x10) v|=BIT_E; // 16
|
||||||
|
|
||||||
|
/* ORIG
|
||||||
|
|
||||||
// need to disable OE after latch to hide row transition
|
// need to disable OE after latch to hide row transition
|
||||||
if((x_coord) == 0) v|=BIT_OE;
|
if((x_coord) == 0) v|=BIT_OE;
|
||||||
|
|
||||||
// drive latch while shifting out last bit of RGB data
|
// drive latch while shifting out last bit of RGB data
|
||||||
if((x_coord) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
if((x_coord) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
||||||
|
|
||||||
|
// need to turn off OE one clock before latch, otherwise can get ghosting
|
||||||
|
if((x_coord)==PIXELS_PER_LATCH-1) v|=BIT_OE;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// need to disable OE after latch to hide row transition
|
||||||
|
if((x_coord) == 0 ) v|=BIT_OE;
|
||||||
|
|
||||||
|
// drive latch while shifting out last bit of RGB data
|
||||||
|
if((x_coord) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
||||||
|
|
||||||
|
// need to turn off OE one clock before latch, otherwise can get ghosting
|
||||||
|
if((x_coord)==PIXELS_PER_LATCH-2) v|=BIT_OE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// turn off OE after brightness value is reached when displaying MSBs
|
// turn off OE after brightness value is reached when displaying MSBs
|
||||||
// MSBs always output normal brightness
|
// MSBs always output normal brightness
|
||||||
// LSB (!color_depth_idx) outputs normal brightness as MSB from previous row is being displayed
|
// LSB (!color_depth_idx) outputs normal brightness as MSB from previous row is being displayed
|
||||||
|
@ -249,8 +251,6 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
|
||||||
if((x_coord) >= lsbBrightness) v|=BIT_OE; // For Brightness
|
if((x_coord) >= lsbBrightness) v|=BIT_OE; // For Brightness
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to turn off OE one clock before latch, otherwise can get ghosting
|
|
||||||
if((x_coord)==PIXELS_PER_LATCH-1) v|=BIT_OE;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -315,6 +315,9 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
|
||||||
|
|
||||||
} // paint
|
} // paint
|
||||||
|
|
||||||
|
//Serial.printf("x: %d, y: %d ", x_coord, y_coord );
|
||||||
|
//Serial.println(v, BIN);
|
||||||
|
|
||||||
|
|
||||||
// 16 bit parallel mode
|
// 16 bit parallel mode
|
||||||
//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
|
||||||
|
@ -367,12 +370,30 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t gre
|
||||||
if (gpioRowAddress & 0x08) v|=BIT_D; // 8
|
if (gpioRowAddress & 0x08) v|=BIT_D; // 8
|
||||||
if (gpioRowAddress & 0x10) v|=BIT_E; // 16
|
if (gpioRowAddress & 0x10) v|=BIT_E; // 16
|
||||||
|
|
||||||
|
|
||||||
|
/* ORIG
|
||||||
|
|
||||||
// need to disable OE after latch to hide row transition
|
// need to disable OE after latch to hide row transition
|
||||||
if((x_coord) == 0) v|=BIT_OE;
|
if((x_coord) == 0) v|=BIT_OE;
|
||||||
|
|
||||||
// drive latch while shifting out last bit of RGB data
|
// drive latch while shifting out last bit of RGB data
|
||||||
if((x_coord) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
if((x_coord) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
||||||
|
|
||||||
|
// need to turn off OE one clock before latch, otherwise can get ghosting
|
||||||
|
if((x_coord)==PIXELS_PER_LATCH-1) v|=BIT_OE;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// need to disable OE after latch to hide row transition
|
||||||
|
if((x_coord) == 0 ) v|=BIT_OE;
|
||||||
|
|
||||||
|
// drive latch while shifting out last bit of RGB data
|
||||||
|
if((x_coord) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
||||||
|
|
||||||
|
// need to turn off OE one clock before latch, otherwise can get ghosting
|
||||||
|
if((x_coord)==PIXELS_PER_LATCH-2) v|=BIT_OE;
|
||||||
|
|
||||||
|
|
||||||
// turn off OE after brightness value is reached when displaying MSBs
|
// turn off OE after brightness value is reached when displaying MSBs
|
||||||
// MSBs always output normal brightness
|
// MSBs always output normal brightness
|
||||||
// LSB (!color_depth_idx) outputs normal brightness as MSB from previous row is being displayed
|
// LSB (!color_depth_idx) outputs normal brightness as MSB from previous row is being displayed
|
||||||
|
@ -385,9 +406,6 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t gre
|
||||||
if((x_coord) >= lsbBrightness) v|=BIT_OE; // For Brightness
|
if((x_coord) >= lsbBrightness) v|=BIT_OE; // For Brightness
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to turn off OE one clock before latch, otherwise can get ghosting
|
|
||||||
if((x_coord)==PIXELS_PER_LATCH-1) v|=BIT_OE;
|
|
||||||
|
|
||||||
|
|
||||||
// Top half colours
|
// Top half colours
|
||||||
if (green & mask)
|
if (green & mask)
|
||||||
|
@ -428,276 +446,3 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t gre
|
||||||
// currently writing too, then the output will be immediate. Else: flipDMABuffer(), then showDMABuffer()
|
// currently writing too, then the output will be immediate. Else: flipDMABuffer(), then showDMABuffer()
|
||||||
|
|
||||||
} // updateDMABuffer
|
} // updateDMABuffer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// WORK IN PROGRESS
|
|
||||||
void RGB64x32MatrixPanel_I2S_DMA::writeRGB24Frame2DMABuffer(rgb_24 *framedata, int16_t frame_width = MATRIX_WIDTH, int16_t frame_height = MATRIX_HEIGHT)
|
|
||||||
{
|
|
||||||
if ( !dma_configuration_success)
|
|
||||||
assert("DMA configuration in begin() not performed or completed successfully.");
|
|
||||||
|
|
||||||
|
|
||||||
for (unsigned int y = 0; y < ROWS_PER_FRAME; y++) // half height - 16 iterations
|
|
||||||
{
|
|
||||||
unsigned char currentRow = y;
|
|
||||||
|
|
||||||
for(int j = 0; j < COLOR_DEPTH_BITS; j++) // color depth - 8 iterations
|
|
||||||
{
|
|
||||||
uint16_t mask = (1 << (j)); // 24 bit color
|
|
||||||
|
|
||||||
//MATRIX_DATA_STORAGE_TYPE *p=matrixUpdateFrames[backbuf_id].rowdata[y].rowbits[pl].data; //matrixUpdateFrames
|
|
||||||
rowBitStruct *p=&matrixUpdateFrames[backbuf_id].rowdata[currentRow].rowbits[j]; //matrixUpdateFrames location to write to
|
|
||||||
|
|
||||||
int i=0;
|
|
||||||
while(i < PIXELS_PER_LATCH) // row pixels (64) iterations
|
|
||||||
{
|
|
||||||
for(int k=0; k < MATRIX_WIDTH; k++) // row pixel width 64 iterations
|
|
||||||
{
|
|
||||||
int v=0; // the output bitstream
|
|
||||||
|
|
||||||
//#if (CLKS_DURING_LATCH == 0)
|
|
||||||
// if there is no latch to hold address, output ADDX lines directly to GPIO and latch data at end of cycle
|
|
||||||
int gpioRowAddress = currentRow;
|
|
||||||
|
|
||||||
// normally output current rows ADDX, special case for LSB, output previous row's ADDX (as previous row is being displayed for one latch cycle)
|
|
||||||
if(j == 0)
|
|
||||||
gpioRowAddress = currentRow-1;
|
|
||||||
|
|
||||||
if (gpioRowAddress & 0x01) v|=BIT_A; // 1
|
|
||||||
if (gpioRowAddress & 0x02) v|=BIT_B; // 2
|
|
||||||
if (gpioRowAddress & 0x04) v|=BIT_C; // 4
|
|
||||||
if (gpioRowAddress & 0x08) v|=BIT_D; // 8
|
|
||||||
if (gpioRowAddress & 0x10) v|=BIT_E; // 16
|
|
||||||
|
|
||||||
// need to disable OE after latch to hide row transition
|
|
||||||
if((i+k) == 0) v|=BIT_OE;
|
|
||||||
|
|
||||||
// drive latch while shifting out last bit of RGB data
|
|
||||||
if((i+k) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// turn off OE after brightness value is reached when displaying MSBs
|
|
||||||
// MSBs always output normal brightness
|
|
||||||
// LSB (!j) outputs normal brightness as MSB from previous row is being displayed
|
|
||||||
if((j > lsbMsbTransitionBit || !j) && ((i+k) >= brightness)) v|=BIT_OE;
|
|
||||||
|
|
||||||
// special case for the bits *after* LSB through (lsbMsbTransitionBit) - OE is output after data is shifted, so need to set OE to fractional brightness
|
|
||||||
if(j && j <= lsbMsbTransitionBit) {
|
|
||||||
// divide brightness in half for each bit below lsbMsbTransitionBit
|
|
||||||
int lsbBrightness = brightness >> (lsbMsbTransitionBit - j + 1);
|
|
||||||
if((i+k) >= lsbBrightness) v|=BIT_OE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to turn off OE one clock before latch, otherwise can get ghosting
|
|
||||||
if((i+k)==PIXELS_PER_LATCH-1) v|=BIT_OE;
|
|
||||||
|
|
||||||
|
|
||||||
//#if 0
|
|
||||||
//
|
|
||||||
// int c1=getpixel(pix, k, y);
|
|
||||||
// int c2=getpixel(pix, k, y+(MATRIX_HEIGHT/2));
|
|
||||||
//
|
|
||||||
// if (c1 & (mask<<16)) v|=BIT_R1;
|
|
||||||
// if (c1 & (mask<<8)) v|=BIT_G1;
|
|
||||||
// if (c1 & (mask<<0)) v|=BIT_B1;
|
|
||||||
// if (c2 & (mask<<16)) v|=BIT_R2;
|
|
||||||
// if ( c2 & (mask<<8)) v|=BIT_G2;
|
|
||||||
// if (c2 & (mask<<0)) v|=BIT_B2;
|
|
||||||
//
|
|
||||||
//#else
|
|
||||||
|
|
||||||
struct rgb_24 c1( 255,0,0);
|
|
||||||
struct rgb_24 c2 = { 255,255,255 };
|
|
||||||
// struct rgb24 c2 = { 0,0,255 };
|
|
||||||
|
|
||||||
|
|
||||||
if (c1.red & mask)
|
|
||||||
v|=BIT_R1;
|
|
||||||
if (c1.green & mask)
|
|
||||||
v|=BIT_G1;
|
|
||||||
if (c1.blue & mask)
|
|
||||||
v|=BIT_B1;
|
|
||||||
if (c2.red & mask)
|
|
||||||
v|=BIT_R2;
|
|
||||||
if (c2.green & mask)
|
|
||||||
v|=BIT_G2;
|
|
||||||
if (c2.blue & mask)
|
|
||||||
v|=BIT_B2;
|
|
||||||
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
// 16 bit parallel mode
|
|
||||||
//Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
|
||||||
if(k%2){
|
|
||||||
p->data[(i+k)-1] = v;
|
|
||||||
} else {
|
|
||||||
p->data[(i+k)+1] = v;
|
|
||||||
} // end reordering
|
|
||||||
|
|
||||||
} // end for MATRIX_WIDTH
|
|
||||||
|
|
||||||
i += MATRIX_WIDTH;
|
|
||||||
|
|
||||||
} // end pixels per latch loop (64)
|
|
||||||
} // color depth loop (8)
|
|
||||||
|
|
||||||
} // end half matrix length
|
|
||||||
|
|
||||||
|
|
||||||
//Show our work!
|
|
||||||
i2s_parallel_flip_to_buffer(&I2S1, backbuf_id);
|
|
||||||
swapBuffer();
|
|
||||||
|
|
||||||
|
|
||||||
} // updateDMABuffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint16_t x, uint16_t y, uint8_t red, uint8_t green, uint8_t blue)
|
|
||||||
{
|
|
||||||
if ( !dma_configuration_success)
|
|
||||||
assert("DMA configuration in begin() not performed or completed successfully.");
|
|
||||||
|
|
||||||
// Pixel index sanity checking.
|
|
||||||
int16_t idx = x + y * MATRIX_WIDTH;
|
|
||||||
if (idx < 0 || idx >= MATRIX_HEIGHT * MATRIX_WIDTH)
|
|
||||||
{
|
|
||||||
//Serial.printf("Provided coordinates out of range");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (unsigned int y=0; y<MATRIX_HEIGHT/MATRIX_ROWS_IN_PARALLEL; y++) // half height - 16 iterations
|
|
||||||
{
|
|
||||||
unsigned char currentRow = y;
|
|
||||||
|
|
||||||
for(int j=0; j<COLOR_DEPTH_BITS; j++) // color depth - 8 iterations
|
|
||||||
{
|
|
||||||
uint16_t mask = (1 << (j)); // 24 bit color
|
|
||||||
|
|
||||||
//MATRIX_DATA_STORAGE_TYPE *p=matrixUpdateFrames[backbuf_id].rowdata[y].rowbits[pl].data; //matrixUpdateFrames
|
|
||||||
rowBitStruct *p=&matrixUpdateFrames[backbuf_id].rowdata[currentRow].rowbits[j]; //matrixUpdateFrames location to write to
|
|
||||||
|
|
||||||
int i=0;
|
|
||||||
while(i < PIXELS_PER_LATCH) // row pixels (64) iterations
|
|
||||||
{
|
|
||||||
for(int k=0; k < MATRIX_WIDTH; k++) // row pixel width 64 iterations
|
|
||||||
{
|
|
||||||
int v=0; // the output bitstream
|
|
||||||
|
|
||||||
//#if (CLKS_DURING_LATCH == 0)
|
|
||||||
// if there is no latch to hold address, output ADDX lines directly to GPIO and latch data at end of cycle
|
|
||||||
int gpioRowAddress = currentRow;
|
|
||||||
|
|
||||||
// normally output current rows ADDX, special case for LSB, output previous row's ADDX (as previous row is being displayed for one latch cycle)
|
|
||||||
if(j == 0)
|
|
||||||
gpioRowAddress = currentRow-1;
|
|
||||||
|
|
||||||
if (gpioRowAddress & 0x01) v|=BIT_A; // 1
|
|
||||||
if (gpioRowAddress & 0x02) v|=BIT_B; // 2
|
|
||||||
if (gpioRowAddress & 0x04) v|=BIT_C; // 4
|
|
||||||
if (gpioRowAddress & 0x08) v|=BIT_D; // 8
|
|
||||||
if (gpioRowAddress & 0x10) v|=BIT_E; // 16
|
|
||||||
|
|
||||||
// need to disable OE after latch to hide row transition
|
|
||||||
if((i+k) == 0) v|=BIT_OE;
|
|
||||||
|
|
||||||
// drive latch while shifting out last bit of RGB data
|
|
||||||
if((i+k) == PIXELS_PER_LATCH-1) v|=BIT_LAT;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// turn off OE after brightness value is reached when displaying MSBs
|
|
||||||
// MSBs always output normal brightness
|
|
||||||
// LSB (!j) outputs normal brightness as MSB from previous row is being displayed
|
|
||||||
if((j > lsbMsbTransitionBit || !j) && ((i+k) >= brightness)) v|=BIT_OE;
|
|
||||||
|
|
||||||
// special case for the bits *after* LSB through (lsbMsbTransitionBit) - OE is output after data is shifted, so need to set OE to fractional brightness
|
|
||||||
if(j && j <= lsbMsbTransitionBit) {
|
|
||||||
// divide brightness in half for each bit below lsbMsbTransitionBit
|
|
||||||
int lsbBrightness = brightness >> (lsbMsbTransitionBit - j + 1);
|
|
||||||
if((i+k) >= lsbBrightness) v|=BIT_OE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to turn off OE one clock before latch, otherwise can get ghosting
|
|
||||||
if((i+k)==PIXELS_PER_LATCH-1) v|=BIT_OE;
|
|
||||||
|
|
||||||
|
|
||||||
//#if 0
|
|
||||||
//
|
|
||||||
// int c1=getpixel(pix, k, y);
|
|
||||||
// int c2=getpixel(pix, k, y+(MATRIX_HEIGHT/2));
|
|
||||||
//
|
|
||||||
// if (c1 & (mask<<16)) v|=BIT_R1;
|
|
||||||
// if (c1 & (mask<<8)) v|=BIT_G1;
|
|
||||||
// if (c1 & (mask<<0)) v|=BIT_B1;
|
|
||||||
// if (c2 & (mask<<16)) v|=BIT_R2;
|
|
||||||
// if ( c2 & (mask<<8)) v|=BIT_G2;
|
|
||||||
// if (c2 & (mask<<0)) v|=BIT_B2;
|
|
||||||
//
|
|
||||||
//#else
|
|
||||||
|
|
||||||
struct rgb24 c1( 255,0,0);
|
|
||||||
struct rgb24 c2 = { 255,255,255 };
|
|
||||||
// struct rgb24 c2 = { 0,0,255 };
|
|
||||||
|
|
||||||
|
|
||||||
if (c1.red & mask)
|
|
||||||
v|=BIT_R1;
|
|
||||||
if (c1.green & mask)
|
|
||||||
v|=BIT_G1;
|
|
||||||
if (c1.blue & mask)
|
|
||||||
v|=BIT_B1;
|
|
||||||
if (c2.red & mask)
|
|
||||||
v|=BIT_R2;
|
|
||||||
if (c2.green & mask)
|
|
||||||
v|=BIT_G2;
|
|
||||||
if (c2.blue & mask)
|
|
||||||
v|=BIT_B2;
|
|
||||||
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
// 16 bit parallel mode
|
|
||||||
//Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
|
|
||||||
if(k%2){
|
|
||||||
p->data[(i+k)-1] = v;
|
|
||||||
} else {
|
|
||||||
p->data[(i+k)+1] = v;
|
|
||||||
} // end reordering
|
|
||||||
|
|
||||||
} // end for MATRIX_WIDTH
|
|
||||||
|
|
||||||
i += MATRIX_WIDTH;
|
|
||||||
|
|
||||||
} // end pixels per latch loop (64)
|
|
||||||
} // color depth loop (8)
|
|
||||||
|
|
||||||
} // end half matrix length
|
|
||||||
|
|
||||||
|
|
||||||
//Show our work!
|
|
||||||
i2s_parallel_flip_to_buffer(&I2S1, backbuf_id);
|
|
||||||
swapBuffer();
|
|
||||||
|
|
||||||
|
|
||||||
} // updateDMABuffer
|
|
||||||
*/
|
|
||||||
|
|
|
@ -131,14 +131,12 @@
|
||||||
#define ROWS_PER_FRAME (MATRIX_HEIGHT/MATRIX_ROWS_IN_PARALLEL) // = 16
|
#define ROWS_PER_FRAME (MATRIX_HEIGHT/MATRIX_ROWS_IN_PARALLEL) // = 16
|
||||||
|
|
||||||
/***************************************************************************************/
|
/***************************************************************************************/
|
||||||
/* You really don't want to change this stuff */
|
/* Keep this as is. Do not change. */
|
||||||
|
#define CLKS_DURING_LATCH 0
|
||||||
#define CLKS_DURING_LATCH 0 // ADDX is output directly using GPIO
|
|
||||||
#define MATRIX_I2S_MODE I2S_PARALLEL_BITS_16
|
#define MATRIX_I2S_MODE I2S_PARALLEL_BITS_16
|
||||||
#define MATRIX_DATA_STORAGE_TYPE uint16_t
|
#define MATRIX_DATA_STORAGE_TYPE uint16_t
|
||||||
|
|
||||||
#define ESP32_NUM_FRAME_BUFFERS 2
|
#define ESP32_NUM_FRAME_BUFFERS 2
|
||||||
#define ESP32_OE_OFF_CLKS_AFTER_LATCH 1
|
|
||||||
#define ESP32_I2S_CLOCK_SPEED (20000000UL)
|
#define ESP32_I2S_CLOCK_SPEED (20000000UL)
|
||||||
#define COLOR_DEPTH 24
|
#define COLOR_DEPTH 24
|
||||||
|
|
||||||
|
@ -181,7 +179,7 @@ class RGB64x32MatrixPanel_I2S_DMA : public Adafruit_GFX {
|
||||||
: Adafruit_GFX(MATRIX_WIDTH, MATRIX_HEIGHT), doubleBuffer(_doubleBuffer) {
|
: Adafruit_GFX(MATRIX_WIDTH, MATRIX_HEIGHT), doubleBuffer(_doubleBuffer) {
|
||||||
|
|
||||||
backbuf_id = 0;
|
backbuf_id = 0;
|
||||||
brightness = 64; // default to max brightness, wear sunglasses when looking directly at panel.
|
brightness = 60; // If you get ghosting... reduce brightness level. 60 seems to be the limit before ghosting on a 64 pixel wide physical panel for some panels
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,9 +213,9 @@ class RGB64x32MatrixPanel_I2S_DMA : public Adafruit_GFX {
|
||||||
|
|
||||||
|
|
||||||
// Flush the DMA buffers prior to configuring DMA - Avoid visual artefacts on boot.
|
// Flush the DMA buffers prior to configuring DMA - Avoid visual artefacts on boot.
|
||||||
flushDMAbuffer();
|
clearScreen(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage
|
||||||
flipDMABuffer(); // flip to backbuffer 1
|
flipDMABuffer(); // flip to backbuffer 1
|
||||||
flushDMAbuffer();
|
clearScreen(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage
|
||||||
flipDMABuffer(); // backbuffer 0
|
flipDMABuffer(); // backbuffer 0
|
||||||
|
|
||||||
// Setup the ESP32 DMA Engine. Sprite_TM built this stuff.
|
// Setup the ESP32 DMA Engine. Sprite_TM built this stuff.
|
||||||
|
@ -238,11 +236,6 @@ class RGB64x32MatrixPanel_I2S_DMA : public Adafruit_GFX {
|
||||||
void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b);
|
void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||||
void drawPixelRGB24(int16_t x, int16_t y, rgb_24 color);
|
void drawPixelRGB24(int16_t x, int16_t y, rgb_24 color);
|
||||||
|
|
||||||
// TODO: Draw a frame! Oooh.
|
|
||||||
//void writeRGB24Frame2DMABuffer(rgb_24 *framedata, int16_t frame_width, int16_t frame_height);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Color 444 is a 4 bit scale, so 0 to 15, color 565 takes a 0-255 bit value, so scale up by 255/15 (i.e. 17)!
|
// Color 444 is a 4 bit scale, so 0 to 15, color 565 takes a 0-255 bit value, so scale up by 255/15 (i.e. 17)!
|
||||||
uint16_t color444(uint8_t r, uint8_t g, uint8_t b) { return color565(r*17,g*17,b*17); }
|
uint16_t color444(uint8_t r, uint8_t g, uint8_t b) { return color565(r*17,g*17,b*17); }
|
||||||
|
|
||||||
|
@ -287,18 +280,6 @@ class RGB64x32MatrixPanel_I2S_DMA : public Adafruit_GFX {
|
||||||
|
|
||||||
} // end initMatrixDMABuffer()
|
} // end initMatrixDMABuffer()
|
||||||
|
|
||||||
void flushDMAbuffer()
|
|
||||||
{
|
|
||||||
Serial.printf("Flushing buffer %d\n", backbuf_id);
|
|
||||||
// Need to wipe the contents of the matrix buffers or weird things happen.
|
|
||||||
for (int y=0;y<MATRIX_HEIGHT; y++)
|
|
||||||
for (int x=0;x<MATRIX_WIDTH; x++)
|
|
||||||
{
|
|
||||||
//Serial.printf("\r\nFlushing x, y coord %d, %d", x, y);
|
|
||||||
updateMatrixDMABuffer( x, y, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void configureDMA(int r1_pin, int g1_pin, int b1_pin, int r2_pin, int g2_pin, int b2_pin, int a_pin, int b_pin, int c_pin, int d_pin, int e_pin, int lat_pin, int oe_pin, int clk_pin); // Get everything setup. Refer to the .c file
|
void configureDMA(int r1_pin, int g1_pin, int b1_pin, int r2_pin, int g2_pin, int b2_pin, int a_pin, int b_pin, int c_pin, int d_pin, int e_pin, int lat_pin, int oe_pin, int clk_pin); // Get everything setup. Refer to the .c file
|
||||||
|
|
||||||
|
|
||||||
|
|
10
README.md
10
README.md
|
@ -11,16 +11,6 @@ As a result, this library can theoretically provide ~20 bit colour, at various b
|
||||||
* Dependency: You will need to install [Adafruit_GFX_Library](https://github.com/adafruit/Adafruit-GFX-Library) from the "Library > Manage Libraries" menu.
|
* Dependency: You will need to install [Adafruit_GFX_Library](https://github.com/adafruit/Adafruit-GFX-Library) from the "Library > Manage Libraries" menu.
|
||||||
* Download and unzip this repository into your Arduino/libraries folder (or better still, use the Arudino 'add library from .zip' option.
|
* Download and unzip this repository into your Arduino/libraries folder (or better still, use the Arudino 'add library from .zip' option.
|
||||||
|
|
||||||
|
|
||||||
## Patching GPIO to avoid eratta of ESP32
|
|
||||||
|
|
||||||
You should patch the `tools/sdk/ld/esp32.peripherals.ld` to avoid random pixel noise on the display as following:
|
|
||||||
|
|
||||||
```
|
|
||||||
/* PROVIDE ( GPIO = 0x3ff44000 ); */
|
|
||||||
PROVIDE ( GPIO = 0x60004000 );
|
|
||||||
```
|
|
||||||
|
|
||||||
Please refer section 3.3. in https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf for more details.
|
Please refer section 3.3. in https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf for more details.
|
||||||
|
|
||||||
# Wiring ESP32 with the LED Matrix Panel
|
# Wiring ESP32 with the LED Matrix Panel
|
||||||
|
|
Loading…
Reference in a new issue