aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrfaptastic <12006953+mrfaptastic@users.noreply.github.com>2020-08-11 20:44:47 +0100
committermrfaptastic <12006953+mrfaptastic@users.noreply.github.com>2020-08-11 20:44:47 +0100
commit9b2caddbed5fbebaab0bf501e1d5e6981edc587c (patch)
treee8cff0d0d6c58e50f516c08e3cce6ccefd6e687c
parent4fd25c4a4edb4b73474bb86a255c3487a8680b16 (diff)
Fix bug with fillScreen and re-implement colour correction
Forgot to implement this two years ago... nobody noticed.
-rw-r--r--ESP32-RGB64x32MatrixPanel-I2S-DMA.cpp81
-rw-r--r--ESP32-RGB64x32MatrixPanel-I2S-DMA.h15
-rw-r--r--examples/AnimatedGIFPanel/data/gifs/shock-gs.gifbin0 -> 34454 bytes
-rw-r--r--examples/AnimatedGIFPanel/data/gifs/shock.gifbin46806 -> 0 bytes
-rw-r--r--library.json8
-rw-r--r--library.properties2
6 files changed, 87 insertions, 19 deletions
diff --git a/ESP32-RGB64x32MatrixPanel-I2S-DMA.cpp b/ESP32-RGB64x32MatrixPanel-I2S-DMA.cpp
index 4d05360..bd90c88 100644
--- a/ESP32-RGB64x32MatrixPanel-I2S-DMA.cpp
+++ b/ESP32-RGB64x32MatrixPanel-I2S-DMA.cpp
@@ -52,6 +52,18 @@
*/
+
+// For development testing only
+//#define IGNORE_REFRESH_RATE 1
+
+
+
+uint8_t val2PWM(int val) {
+ if (val<0) val=0;
+ if (val>255) val=255;
+ return lumConvTab[val];
+}
+
bool RGB64x32MatrixPanel_I2S_DMA::allocateDMAmemory()
{
@@ -142,15 +154,18 @@ bool RGB64x32MatrixPanel_I2S_DMA::allocateDMAmemory()
* Step 2: Calculate the amount of memory required for the DMA engine's linked list descriptors.
* Credit to SmartMatrix for this stuff.
*/
+
// Calculate what color depth is actually possible based on memory avaialble vs. required dma linked-list descriptors.
// aka. Calculate the lowest LSBMSB_TRANSITION_BIT value that will fit in memory
int numDMAdescriptorsPerRow = 0;
lsbMsbTransitionBit = 0;
+
+ #ifndef IGNORE_REFRESH_RATE
while(1) {
numDMAdescriptorsPerRow = 1;
for(int i=lsbMsbTransitionBit + 1; i<PIXEL_COLOR_DEPTH_BITS; i++) {
- numDMAdescriptorsPerRow += 1<<(i - lsbMsbTransitionBit - 1);
+ numDMAdescriptorsPerRow += (1<<(i - lsbMsbTransitionBit - 1));
}
int ramrequired = numDMAdescriptorsPerRow * ROWS_PER_FRAME * _num_frame_buffers * sizeof(lldesc_t);
@@ -169,9 +184,10 @@ bool RGB64x32MatrixPanel_I2S_DMA::allocateDMAmemory()
}
Serial.printf("Raised lsbMsbTransitionBit to %d/%d to fit in remaining RAM\r\n", lsbMsbTransitionBit, PIXEL_COLOR_DEPTH_BITS - 1);
+ #endif
// calculate the lowest LSBMSB_TRANSITION_BIT value that will fit in memory that will meet or exceed the configured refresh rate
- while(1) {
+ while(1) {
int psPerClock = 1000000000000UL/ESP32_I2S_CLOCK_SPEED;
int nsPerLatch = ((PIXELS_PER_ROW + CLKS_DURING_LATCH) * psPerClock) / 1000;
@@ -200,6 +216,7 @@ bool RGB64x32MatrixPanel_I2S_DMA::allocateDMAmemory()
}
Serial.printf("Raised lsbMsbTransitionBit to %d/%d to meet minimum refresh rate\r\n", lsbMsbTransitionBit, PIXEL_COLOR_DEPTH_BITS - 1);
+
/***
* Step 2a: lsbMsbTransition bit is now finalised - recalculate the DMA descriptor count required, which is used for
@@ -207,7 +224,7 @@ bool RGB64x32MatrixPanel_I2S_DMA::allocateDMAmemory()
*/
numDMAdescriptorsPerRow = 1;
for(int i=lsbMsbTransitionBit + 1; i<PIXEL_COLOR_DEPTH_BITS; i++) {
- numDMAdescriptorsPerRow += 1<<(i - lsbMsbTransitionBit - 1);
+ numDMAdescriptorsPerRow += (1<<(i - lsbMsbTransitionBit - 1));
}
// Refer to 'DMA_LL_PAYLOAD_SPLIT' code in configureDMA() below to understand why this exists.
@@ -366,7 +383,11 @@ void RGB64x32MatrixPanel_I2S_DMA::configureDMA(int r1_pin, int g1_pin, int b1_
// we need 2^(i - LSBMSB_TRANSITION_BIT - 1) == 1 << (i - LSBMSB_TRANSITION_BIT - 1) passes from i to MSB
//Serial.printf("buffer %d: repeat %d times, size: %d, from %d - %d\r\n", current_dmadescriptor_offset, 1<<(i - lsbMsbTransitionBit - 1), (PIXEL_COLOR_DEPTH_BITS - i), i, PIXEL_COLOR_DEPTH_BITS-1);
- for(int k=0; k < 1<<(i - lsbMsbTransitionBit - 1); k++)
+ #if SERIAL_DEBUG
+ Serial.printf("configureDMA(): DMA Loops for PIXEL_COLOR_DEPTH_BITS %d is: %d.\r\n", i, (1<<(i - lsbMsbTransitionBit - 1)));
+ #endif
+
+ for(int k=0; k < (1<<(i - lsbMsbTransitionBit - 1)); k++)
{
link_dma_desc(&dmadesc_a[current_dmadescriptor_offset], previous_dmadesc_a, &(fb_malloc_ptr[0].rowdata[fb_malloc_j].rowbits[i].data), sizeof(rowBitStruct) * (PIXEL_COLOR_DEPTH_BITS - i));
previous_dmadesc_a = &dmadesc_a[current_dmadescriptor_offset];
@@ -450,12 +471,26 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
return;
}
-
- #ifdef SPLIT_MEMORY_MODE
- #ifdef SERIAL_DEBUG
- int tmp_y_coord = y_coord;
- #endif
- #endif
+
+ /* LED Brightness Compensation. Because if we do a basic "red & mask" for example,
+ * we'll NEVER send the dimmest possible colour, due to binary skew.
+
+ i.e. It's almost impossible for color_depth_idx of 0 to be sent out to the MATRIX unless the 'value' of a color is exactly '1'
+
+ */
+ red = lumConvTab[red];
+ green = lumConvTab[green];
+ blue = lumConvTab[blue];
+/*
+ red = val2PWM(red);
+ green = val2PWM(green);
+ blue = val2PWM(blue);
+*/
+ #ifdef SPLIT_MEMORY_MODE
+ #ifdef SERIAL_DEBUG
+ int tmp_y_coord = y_coord;
+ #endif
+ #endif
/* 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)
@@ -475,6 +510,7 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
paint_top_half = false;
}
+
for(int color_depth_idx=0; color_depth_idx<PIXEL_COLOR_DEPTH_BITS; color_depth_idx++) // color depth - 8 iterations
{
uint16_t mask = (1 << color_depth_idx); // 24 bit color
@@ -561,6 +597,15 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
} else {
tmp_x_coord += 1;
} // end reordering
+
+ /*
+ // Development / testing code only.
+ Serial.printf("r value of %d, color depth: %d, mask: %d\r\n", red, color_depth_idx, mask);
+ if (red & mask) { Serial.println("Success - Binary"); v|=BIT_R1; }
+ Serial.printf("val2pwm r value: %d\r\n", val2PWM(red));
+ if (val2PWM(red) & mask) { Serial.println("Success - PWM"); v|=BIT_R2; }
+ */
+
if (paint_top_half)
{ // Need to copy what the RGB status is for the bottom pixels
@@ -617,6 +662,16 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t green, uint8_t blue)
{
if ( !everything_OK ) return;
+
+ /* https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ */
+ /*
+ red = val2PWM(red);
+ green = val2PWM(green);
+ blue = val2PWM(blue);
+ */
+ red = lumConvTab[red];
+ green = lumConvTab[green];
+ blue = lumConvTab[blue];
for (unsigned int matrix_frame_parallel_row = 0; matrix_frame_parallel_row < ROWS_PER_FRAME; matrix_frame_parallel_row++) // half height - 16 iterations
{
@@ -698,9 +753,9 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t gre
}
// Top and bottom matrix MATRIX_ROWS_IN_PARALLEL half colours
- if (green & mask) { v|=BIT_G1; v|=BIT_R2; }
- if (blue & mask) { v|=BIT_B1; v|=BIT_G2; }
- if (red & mask) { v|=BIT_R1; v|=BIT_B2; }
+ if (green & mask) { v|=BIT_G1; v|=BIT_G2; }
+ if (blue & mask) { v|=BIT_B1; v|=BIT_B2; }
+ if (red & mask) { v|=BIT_R1; v|=BIT_R2; }
// 16 bit parallel mode
//Save the calculated value to the bitplane memory in reverse order to account for I2S Tx FIFO mode1 ordering
diff --git a/ESP32-RGB64x32MatrixPanel-I2S-DMA.h b/ESP32-RGB64x32MatrixPanel-I2S-DMA.h
index 1cc5931..e50e8a9 100644
--- a/ESP32-RGB64x32MatrixPanel-I2S-DMA.h
+++ b/ESP32-RGB64x32MatrixPanel-I2S-DMA.h
@@ -123,7 +123,7 @@
#define ESP32_I2S_DMA_MODE I2S_PARALLEL_BITS_16 // Pump 16 bits out in parallel
#define ESP32_I2S_DMA_STORAGE_TYPE uint16_t // one uint16_t at a time.
//#define ESP32_I2S_CLOCK_SPEED (20000000UL) // @ 20Mhz
-#define ESP32_I2S_CLOCK_SPEED (10000000UL) // @ 10Mhz
+#define ESP32_I2S_CLOCK_SPEED (10000000UL) // @ 10Mhz
#define CLKS_DURING_LATCH 0 // Not used.
/***************************************************************************************/
@@ -174,6 +174,13 @@ typedef struct rgb_24 {
/***************************************************************************************/
+// Used by val2PWM
+//C/p'ed from https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/
+// Example calculator: https://gist.github.com/mathiasvr/19ce1d7b6caeab230934080ae1f1380e
+const uint16_t lumConvTab[]={
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 30, 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 86, 87, 88, 90, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 131, 133, 134, 136, 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, 156, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 192, 194, 196, 198, 200, 203, 205, 207, 209, 212, 214, 216, 218, 221, 223, 226, 228, 230, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255, 255};
+
+/***************************************************************************************/
#ifdef USE_GFX_ROOT
class RGB64x32MatrixPanel_I2S_DMA : public GFX {
#else
@@ -252,6 +259,7 @@ class RGB64x32MatrixPanel_I2S_DMA : public Adafruit_GFX {
virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // overwrite adafruit implementation
virtual void fillScreen(uint16_t color); // overwrite adafruit implementation
void clearScreen() { fillScreen(0); }
+ void fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b);
void drawPixelRGB565(int16_t x, int16_t y, uint16_t color);
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);
@@ -367,6 +375,11 @@ inline void RGB64x32MatrixPanel_I2S_DMA::fillScreen(uint16_t color) // adafruit
updateMatrixDMABuffer(r, g, b); // the RGB only (no pixel coordinate) version of 'updateMatrixDMABuffer'
}
+inline void RGB64x32MatrixPanel_I2S_DMA::fillScreenRGB888(uint8_t r, uint8_t g,uint8_t b) // adafruit virtual void override
+{
+ updateMatrixDMABuffer(r, g, b);
+}
+
// For adafruit
inline void RGB64x32MatrixPanel_I2S_DMA::drawPixelRGB565(int16_t x, int16_t y, uint16_t color)
{
diff --git a/examples/AnimatedGIFPanel/data/gifs/shock-gs.gif b/examples/AnimatedGIFPanel/data/gifs/shock-gs.gif
new file mode 100644
index 0000000..1d023d9
--- /dev/null
+++ b/examples/AnimatedGIFPanel/data/gifs/shock-gs.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel/data/gifs/shock.gif b/examples/AnimatedGIFPanel/data/gifs/shock.gif
deleted file mode 100644
index b07d631..0000000
--- a/examples/AnimatedGIFPanel/data/gifs/shock.gif
+++ /dev/null
Binary files differ
diff --git a/library.json b/library.json
index 1bdd4d8..e4defb1 100644
--- a/library.json
+++ b/library.json
@@ -10,13 +10,13 @@
"name": "Faptastic",
"url": "https://github.com/mrfaptastic/"
},
- "version": "1.1.0",
+ "version": "1.2.0",
"frameworks": "arduino",
"platforms": "esp32",
"examples": [
- "examples/AnimatedGIF/*.ino",
- "examples/AnimatedGIF/*.cpp",
- "examples/AnimatedGIF/*.h",
+ "examples/AnimatedGIFPanel/*.ino",
+ "examples/AnimatedGIFPanel/*.cpp",
+ "examples/AnimatedGIFPanel/*.h",
"examples/AuroraDemo/*.ino",
"examples/AuroraDemo/*.cpp",
"examples/AuroraDemo/*.h",
diff --git a/library.properties b/library.properties
index f819273..0c58663 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=ESP32 64x32 LED MATRIX HUB75 DMA Display
-version=1.1.0
+version=1.2.0
author=Faptastic
maintainer=Faptastic
sentence=Experimental DMA based LED Matrix HUB75 Library