diff options
| author | mrfaptastic <12006953+mrfaptastic@users.noreply.github.com> | 2020-08-11 20:44:47 +0100 |
|---|---|---|
| committer | mrfaptastic <12006953+mrfaptastic@users.noreply.github.com> | 2020-08-11 20:44:47 +0100 |
| commit | 9b2caddbed5fbebaab0bf501e1d5e6981edc587c (patch) | |
| tree | e8cff0d0d6c58e50f516c08e3cce6ccefd6e687c | |
| parent | 4fd25c4a4edb4b73474bb86a255c3487a8680b16 (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.cpp | 81 | ||||
| -rw-r--r-- | ESP32-RGB64x32MatrixPanel-I2S-DMA.h | 15 | ||||
| -rw-r--r-- | examples/AnimatedGIFPanel/data/gifs/shock-gs.gif | bin | 0 -> 34454 bytes | |||
| -rw-r--r-- | examples/AnimatedGIFPanel/data/gifs/shock.gif | bin | 46806 -> 0 bytes | |||
| -rw-r--r-- | library.json | 8 | ||||
| -rw-r--r-- | library.properties | 2 |
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 Binary files differnew file mode 100644 index 0000000..1d023d9 --- /dev/null +++ b/examples/AnimatedGIFPanel/data/gifs/shock-gs.gif diff --git a/examples/AnimatedGIFPanel/data/gifs/shock.gif b/examples/AnimatedGIFPanel/data/gifs/shock.gif Binary files differdeleted file mode 100644 index b07d631..0000000 --- a/examples/AnimatedGIFPanel/data/gifs/shock.gif +++ /dev/null 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 |
