Rowcan shuffling #338
This commit is contained in:
parent
3333f0b11d
commit
a54688df9d
3 changed files with 76 additions and 120 deletions
|
@ -30,24 +30,7 @@
|
||||||
* However, if the library is to be used with lower colour depth (i.e. 6 bit colour), then we need to ensure the 8-bit value passed to the colour masking
|
* However, if the library is to be used with lower colour depth (i.e. 6 bit colour), then we need to ensure the 8-bit value passed to the colour masking
|
||||||
* is adjusted accordingly to ensure the LSB's are shifted left to MSB, by the difference. Otherwise the colours will be all screwed up.
|
* is adjusted accordingly to ensure the LSB's are shifted left to MSB, by the difference. Otherwise the colours will be all screwed up.
|
||||||
*/
|
*/
|
||||||
// #if PIXEL_COLOR_DEPTH_BITS > 12
|
|
||||||
// #error "Color depth bits cannot be greater than 12."
|
|
||||||
// #elif PIXEL_COLOR_DEPTH_BITS < 2
|
|
||||||
// #error "Color depth bits cannot be less than 2."
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #define MASK_OFFSET (16 - PIXEL_COLOR_DEPTH_BITS)
|
|
||||||
// #define PIXEL_COLOR_MASK_BIT(color_depth_index) (1 << (color_depth_index + MASK_OFFSET))
|
|
||||||
#define PIXEL_COLOR_MASK_BIT(color_depth_index, mask_offset) (1 << (color_depth_index + mask_offset))
|
#define PIXEL_COLOR_MASK_BIT(color_depth_index, mask_offset) (1 << (color_depth_index + mask_offset))
|
||||||
// static constexpr uint8_t const MASK_OFFSET = 8-PIXEL_COLOUR_DEPTH_BITS;
|
|
||||||
|
|
||||||
/*
|
|
||||||
#if PIXEL_COLOR_DEPTH_BITS < 8
|
|
||||||
uint8_t mask = (1 << (colour_depth_idx+MASK_OFFSET)); // expect 24 bit colour (8 bits per RGB subpixel)
|
|
||||||
#else
|
|
||||||
uint8_t mask = (1 << (colour_depth_idx)); // expect 24 bit colour (8 bits per RGB subpixel)
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool MatrixPanel_I2S_DMA::allocateDMAmemory()
|
bool MatrixPanel_I2S_DMA::allocateDMAmemory()
|
||||||
{
|
{
|
||||||
|
@ -155,7 +138,7 @@ bool MatrixPanel_I2S_DMA::allocateDMAmemory()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// malloc the DMA linked list descriptors that i2s_parallel will need
|
// malloc the DMA linked list descriptors that i2s_parallel will need
|
||||||
desccount = numDMAdescriptorsPerRow * ROWS_PER_FRAME;
|
int desccount = numDMAdescriptorsPerRow * ROWS_PER_FRAME;
|
||||||
|
|
||||||
if (m_cfg.double_buff)
|
if (m_cfg.double_buff)
|
||||||
{
|
{
|
||||||
|
@ -174,6 +157,33 @@ bool MatrixPanel_I2S_DMA::allocateDMAmemory()
|
||||||
|
|
||||||
} // end allocateDMAmemory()
|
} // end allocateDMAmemory()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Version 2.0 March 2023
|
||||||
|
int MatrixPanel_I2S_DMA::create_descriptor_links(void *data, size_t size, bool dmadesc_b, bool countonly)
|
||||||
|
{
|
||||||
|
int len = size;
|
||||||
|
uint8_t *data2 = (uint8_t *)data;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
int dmalen = len;
|
||||||
|
if (dmalen > DMA_MAX)
|
||||||
|
dmalen = DMA_MAX;
|
||||||
|
|
||||||
|
if (!countonly)
|
||||||
|
dma_bus.create_dma_desc_link(data2, dmalen, dmadesc_b);
|
||||||
|
|
||||||
|
len -= dmalen;
|
||||||
|
data2 += dmalen;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
*/
|
||||||
void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG &_cfg)
|
void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG &_cfg)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -188,32 +198,37 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG &_cfg)
|
||||||
num_dma_payload_colour_depths = 1;
|
num_dma_payload_colour_depths = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NO_ROW_SCAN_SHUFFLE
|
||||||
|
// Fill DMA linked lists for both frames (as in, halves of the HUB75 panel) in sequence (top to bottom)
|
||||||
|
for (int row = 0; row < ROWS_PER_FRAME; row++)
|
||||||
|
#else
|
||||||
// Create row vector for a row shuffle.
|
// Create row vector for a row shuffle.
|
||||||
std::vector<int> v;
|
std::vector<int> v;
|
||||||
for (int i = 0; i < ROWS_PER_FRAME; i++) { v.push_back(i); }
|
|
||||||
for (int i = 1; i < ROWS_PER_FRAME-5; i++)
|
if (ROWS_PER_FRAME == 16) { //64wx32h pixel panel
|
||||||
{
|
// v = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||||||
std::iter_swap(v.begin()+i,v.begin()+i+5);
|
v = {6,2,4,0,8,10,12,15,14,13,11,9,1,5,3,7};
|
||||||
}
|
}
|
||||||
for (int &row: v)
|
|
||||||
{
|
if (ROWS_PER_FRAME == 32) { //64wx64h panel
|
||||||
// Serial.println (row, DEC);
|
// v = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||||||
|
v = {5,3,1,6,8,11,13,15,17,19,21,23,25,27,31,30,29,28,26,24,22,20,18,16,10,14,12,9,7,0,4,2};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill DMA linked lists for both frames (as in, halves of the HUB75 panel) and if double buffering is enabled, link it up for both buffers.
|
|
||||||
//for (int row = 0; row < ROWS_PER_FRAME; row++)
|
|
||||||
for (int &row: v)
|
for (int &row: v)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// first set of data is LSB through MSB, single pass (IF TOTAL SIZE < DMA_MAX) - all colour bits are displayed once, which takes care of everything below and including LSBMSB_TRANSITION_BIT
|
// first set of data is LSB through MSB, single pass (IF TOTAL SIZE < DMA_MAX) - all colour bits are displayed once, which takes care of everything below and including LSBMSB_TRANSITION_BIT
|
||||||
// NOTE: size must be less than DMA_MAX - worst case for library: 16-bpp with 256 pixels per row would exceed this, need to break into two
|
// NOTE: size must be less than DMA_MAX - worst case for library: 16-bpp with 256 pixels per row would exceed this, need to break into two
|
||||||
// link_dma_desc(&dmadesc_a[current_dmadescriptor_offset], previous_dmadesc_a, dma_buff.rowBits[row]->getDataPtr(), dma_buff.rowBits[row]->size(num_dma_payload_colour_depths));
|
// link_dma_desc(&dmadesc_a[current_dmadescriptor_offset], previous_dmadesc_a, dma_buff.rowBits[row]->getDataPtr(), dma_buff.rowBits[row]->size(num_dma_payload_colour_depths));
|
||||||
// previous_dmadesc_a = &dmadesc_a[current_dmadescriptor_offset];
|
// previous_dmadesc_a = &dmadesc_a[current_dmadescriptor_offset];
|
||||||
|
|
||||||
dma_bus.create_dma_desc_link(frame_buffer[0].rowBits[row]->getDataPtr(0, 0), frame_buffer[0].rowBits[row]->size(1), false);
|
dma_bus.create_dma_desc_link(frame_buffer[0].rowBits[row]->getDataPtr(0, 0), frame_buffer[0].rowBits[row]->size(), false);
|
||||||
|
|
||||||
if (m_cfg.double_buff)
|
if (m_cfg.double_buff)
|
||||||
{
|
{
|
||||||
dma_bus.create_dma_desc_link(frame_buffer[1].rowBits[row]->getDataPtr(0, 1), frame_buffer[1].rowBits[row]->size(1), true);
|
dma_bus.create_dma_desc_link(frame_buffer[1].rowBits[row]->getDataPtr(0, 1), frame_buffer[1].rowBits[row]->size(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_dmadescriptor_offset++;
|
current_dmadescriptor_offset++;
|
||||||
|
@ -478,7 +493,7 @@ void MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t green, uint
|
||||||
* This effectively clears buffers to blank BLACK and makes it ready to display output.
|
* This effectively clears buffers to blank BLACK and makes it ready to display output.
|
||||||
* (Brightness control via OE bit manipulation is another case) - this must be done as well seperately!
|
* (Brightness control via OE bit manipulation is another case) - this must be done as well seperately!
|
||||||
*/
|
*/
|
||||||
void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id)
|
void MatrixPanel_I2S_DMA::clearFrameBuffer()
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
@ -489,7 +504,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id)
|
||||||
{
|
{
|
||||||
--row_idx;
|
--row_idx;
|
||||||
|
|
||||||
ESP32_I2S_DMA_STORAGE_TYPE *row = fb->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 *row = fb->rowBits[row_idx]->getDataPtr(0, -1); // 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;
|
ESP32_I2S_DMA_STORAGE_TYPE abcde = (ESP32_I2S_DMA_STORAGE_TYPE)row_idx;
|
||||||
abcde <<= BITS_ADDR_OFFSET; // shift row y-coord to match ABCDE bits in vector from 8 to 12
|
abcde <<= BITS_ADDR_OFFSET; // shift row y-coord to match ABCDE bits in vector from 8 to 12
|
||||||
|
@ -561,7 +576,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id)
|
||||||
--colouridx;
|
--colouridx;
|
||||||
|
|
||||||
// switch pointer to a row for a specific colour index
|
// switch pointer to a row for a specific colour index
|
||||||
row = fb->rowBits[row_idx]->getDataPtr(colouridx, _buff_id);
|
row = fb->rowBits[row_idx]->getDataPtr(colouridx, -1);
|
||||||
|
|
||||||
row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - 1)] |= BIT_LAT; // -1 pixel to compensate array index starting at 0
|
row[ESP32_TX_FIFO_POSITION_ADJUST(fb->rowBits[row_idx]->width - 1)] |= BIT_LAT; // -1 pixel to compensate array index starting at 0
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
// #define NO_CIE1931
|
// #define NO_CIE1931
|
||||||
|
|
||||||
|
// #define NO_ROW_SCAN_SHUFFLE
|
||||||
|
|
||||||
/* Physical / Chained HUB75(s) RGB pixel WIDTH and HEIGHT.
|
/* Physical / Chained HUB75(s) RGB pixel WIDTH and HEIGHT.
|
||||||
*
|
*
|
||||||
* This library has been tested with a 64x32 and 64x64 RGB panels.
|
* This library has been tested with a 64x32 and 64x64 RGB panels.
|
||||||
|
@ -135,10 +137,8 @@ struct rowBitStruct
|
||||||
const bool double_buff;
|
const bool double_buff;
|
||||||
ESP32_I2S_DMA_STORAGE_TYPE *data;
|
ESP32_I2S_DMA_STORAGE_TYPE *data;
|
||||||
|
|
||||||
/** @brief - returns size of row of data vectorfor a SINGLE buff
|
/** @brief
|
||||||
* size (in bytes) of a vector holding full DMA data for a row of pixels with _dpth colour bits
|
* Returns size of row of data vectorfor a SINGLE buff for the number of colour depths rquested
|
||||||
* a SINGLE buffer only size is accounted, when using double buffers it actually takes twice as much space
|
|
||||||
* but returned size is for a half of double-buffer
|
|
||||||
*
|
*
|
||||||
* default - returns full data vector size for a SINGLE buff
|
* default - returns full data vector size for a SINGLE buff
|
||||||
*
|
*
|
||||||
|
@ -150,8 +150,9 @@ struct rowBitStruct
|
||||||
return width * _dpth * sizeof(ESP32_I2S_DMA_STORAGE_TYPE);
|
return width * _dpth * sizeof(ESP32_I2S_DMA_STORAGE_TYPE);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief - returns pointer to the row's data vector beginning at pixel[0] for _dpth colour bit
|
/** @brief
|
||||||
* default - returns pointer to the data vector's head
|
* Returns pointer to the row's data vector beginning at pixel[0] for _dpth colour bit
|
||||||
|
*
|
||||||
* NOTE: this call might be very slow in loops. Due to poor instruction caching in esp32 it might be required a reread from flash
|
* NOTE: this call might be very slow in loops. Due to poor instruction caching in esp32 it might be required a reread from flash
|
||||||
* every loop cycle, better use inlined #define instead in such cases
|
* every loop cycle, better use inlined #define instead in such cases
|
||||||
*/
|
*/
|
||||||
|
@ -168,21 +169,14 @@ struct rowBitStruct
|
||||||
#if defined(SPIRAM_DMA_BUFFER)
|
#if defined(SPIRAM_DMA_BUFFER)
|
||||||
|
|
||||||
// data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_aligned_alloc(64, size()+size()*double_buff, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
// data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_aligned_alloc(64, size()+size()*double_buff, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
|
||||||
// No longer have double buffer in the same struct - have a different struct
|
// No longer have double buffer in the same struct - have a different struct
|
||||||
data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_aligned_alloc(64, size(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_aligned_alloc(64, size(), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
/*
|
|
||||||
if (!psramFound())
|
|
||||||
{
|
|
||||||
ESP_LOGE("rowBitStruct", "Requested to use PSRAM / SPIRAM for framebuffer, but it was not detected.");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#else
|
#else
|
||||||
// data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_malloc( size()+size()*double_buff, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
// data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_malloc( size()+size()*double_buff, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
||||||
|
|
||||||
// No longer have double buffer in the same struct - have a different struct
|
// No longer have double buffer in the same struct - have a different struct
|
||||||
data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_malloc(size(), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
data = (ESP32_I2S_DMA_STORAGE_TYPE *)heap_caps_malloc(size(), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
||||||
// ESP_LOGI("rowBitStruct", "Allocated DMA BitBuffer from regular (and limited) SRAM");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
~rowBitStruct() { delete data; }
|
~rowBitStruct() { delete data; }
|
||||||
|
@ -498,7 +492,6 @@ public:
|
||||||
{
|
{
|
||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
color565to888(color, r, g, b);
|
color565to888(color, r, g, b);
|
||||||
startWrite();
|
|
||||||
|
|
||||||
int16_t w = 1;
|
int16_t w = 1;
|
||||||
transform(x, y, w, h);
|
transform(x, y, w, h);
|
||||||
|
@ -507,7 +500,6 @@ public:
|
||||||
else
|
else
|
||||||
hlineDMA(x, y, w, r, g, b);
|
hlineDMA(x, y, w, r, g, b);
|
||||||
|
|
||||||
endWrite();
|
|
||||||
}
|
}
|
||||||
// rgb888 overload
|
// rgb888 overload
|
||||||
virtual inline void drawFastVLine(int16_t x, int16_t y, int16_t h, uint8_t r, uint8_t g, uint8_t b)
|
virtual inline void drawFastVLine(int16_t x, int16_t y, int16_t h, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
@ -528,7 +520,6 @@ public:
|
||||||
{
|
{
|
||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
color565to888(color, r, g, b);
|
color565to888(color, r, g, b);
|
||||||
startWrite();
|
|
||||||
|
|
||||||
int16_t h = 1;
|
int16_t h = 1;
|
||||||
transform(x, y, w, h);
|
transform(x, y, w, h);
|
||||||
|
@ -537,7 +528,6 @@ public:
|
||||||
else
|
else
|
||||||
hlineDMA(x, y, w, r, g, b);
|
hlineDMA(x, y, w, r, g, b);
|
||||||
|
|
||||||
endWrite();
|
|
||||||
}
|
}
|
||||||
// rgb888 overload
|
// rgb888 overload
|
||||||
virtual inline void drawFastHLine(int16_t x, int16_t y, int16_t w, uint8_t r, uint8_t g, uint8_t b)
|
virtual inline void drawFastHLine(int16_t x, int16_t y, int16_t w, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
@ -558,18 +548,18 @@ public:
|
||||||
{
|
{
|
||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
color565to888(color, r, g, b);
|
color565to888(color, r, g, b);
|
||||||
startWrite();
|
|
||||||
transform(x, y, w, h);
|
transform(x, y, w, h);
|
||||||
fillRectDMA(x, y, w, h, r, g, b);
|
fillRectDMA(x, y, w, h, r, g, b);
|
||||||
endWrite();
|
|
||||||
}
|
}
|
||||||
// rgb888 overload
|
// rgb888 overload
|
||||||
virtual inline void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t r, uint8_t g, uint8_t b)
|
virtual inline void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t r, uint8_t g, uint8_t b)
|
||||||
{
|
{
|
||||||
startWrite();
|
|
||||||
transform(x, y, w, h);
|
transform(x, y, w, h);
|
||||||
fillRectDMA(x, y, w, h, r, g, b);
|
fillRectDMA(x, y, w, h, r, g, b);
|
||||||
endWrite();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -620,22 +610,6 @@ public:
|
||||||
|
|
||||||
back_buffer_id ^= 1;
|
back_buffer_id ^= 1;
|
||||||
|
|
||||||
// initialized = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
i2s_parallel_set_previous_buffer_not_free();
|
|
||||||
// Wait before we allow any writing to the buffer. Stop flicker.
|
|
||||||
while(i2s_parallel_is_previous_buffer_free() == false) { }
|
|
||||||
|
|
||||||
i2s_parallel_flip_to_buffer(ESP32_I2S_DEVICE, back_buffer_id);
|
|
||||||
// Flip to other buffer as the backbuffer.
|
|
||||||
// i.e. Graphic changes happen to this buffer, but aren't displayed until flipDMABuffer() is called again.
|
|
||||||
back_buffer_id ^= 1;
|
|
||||||
|
|
||||||
i2s_parallel_set_previous_buffer_not_free();
|
|
||||||
// Wait before we allow any writing to the buffer. Stop flicker.
|
|
||||||
while(i2s_parallel_is_previous_buffer_free() == false) { }
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -649,34 +623,17 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb = &frame_buffer[0];
|
||||||
brightness = b;
|
brightness = b;
|
||||||
brtCtrlOEv2(b, 0);
|
brtCtrlOEv2(b, 0);
|
||||||
|
|
||||||
if (m_cfg.double_buff)
|
if (m_cfg.double_buff)
|
||||||
{
|
{
|
||||||
|
fb = &frame_buffer[1];
|
||||||
brtCtrlOEv2(b, 1);
|
brtCtrlOEv2(b, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a value that is between 0 and MATRIX_WIDTH-1
|
|
||||||
/*
|
|
||||||
void setPanelBrightness(int b)
|
|
||||||
{
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
ESP_LOGI("setPanelBrightness()", "Tried to set output brightness before begin()");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change to set the brightness of the display, range of 1 to matrixWidth (i.e. 1 - 64)
|
|
||||||
// brightness = b * PIXELS_PER_ROW / 256;
|
|
||||||
|
|
||||||
brtCtrlOE(b);
|
|
||||||
if (m_cfg.double_buff)
|
|
||||||
brtCtrlOE(b, 1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param uint8_t b - 8-bit brightness value
|
* @param uint8_t b - 8-bit brightness value
|
||||||
*/
|
*/
|
||||||
|
@ -735,17 +692,6 @@ public:
|
||||||
dma_bus.dma_transfer_stop();
|
dma_bus.dma_transfer_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startWrite()
|
|
||||||
{
|
|
||||||
// ESP_LOGI("TAG", "startWrite() called");
|
|
||||||
active_gfx_writes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void endWrite()
|
|
||||||
{
|
|
||||||
active_gfx_writes--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------- PROTECTED -------
|
// ------- PROTECTED -------
|
||||||
// those might be useful for child classes, like VirtualMatrixPanel
|
// those might be useful for child classes, like VirtualMatrixPanel
|
||||||
protected:
|
protected:
|
||||||
|
@ -757,7 +703,7 @@ protected:
|
||||||
* This effectively clears buffers to blank BLACK and makes it ready to display output.
|
* This effectively clears buffers to blank BLACK and makes it ready to display output.
|
||||||
* (Brightness control via OE bit manipulation is another case)
|
* (Brightness control via OE bit manipulation is another case)
|
||||||
*/
|
*/
|
||||||
void clearFrameBuffer(bool _buff_id = 0);
|
void clearFrameBuffer();
|
||||||
|
|
||||||
/* Update a specific pixel in the DMA buffer to a colour */
|
/* Update a specific pixel in the DMA buffer to a colour */
|
||||||
void updateMatrixDMABuffer(uint16_t x, uint16_t y, uint8_t red, uint8_t green, uint8_t blue);
|
void updateMatrixDMABuffer(uint16_t x, uint16_t y, uint8_t red, uint8_t green, uint8_t blue);
|
||||||
|
@ -770,16 +716,17 @@ protected:
|
||||||
*/
|
*/
|
||||||
inline void resetbuffers()
|
inline void resetbuffers()
|
||||||
{
|
{
|
||||||
|
|
||||||
// flipDMABuffer();
|
|
||||||
fb = &frame_buffer[0];
|
fb = &frame_buffer[0];
|
||||||
|
clearFrameBuffer();
|
||||||
|
brtCtrlOEv2(brightness, 0);
|
||||||
|
|
||||||
clearFrameBuffer(0); // buffer ID is not used
|
if (m_cfg.double_buff) {
|
||||||
brtCtrlOEv2(brightness, 0); // buffer ID is not used
|
|
||||||
|
|
||||||
fb = &frame_buffer[1];
|
fb = &frame_buffer[1];
|
||||||
clearFrameBuffer(1); // buffer ID is not used
|
clearFrameBuffer();
|
||||||
brtCtrlOEv2(brightness, 1); // buffer ID is not used
|
brtCtrlOEv2(brightness, 1);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FAST_FUNCTIONS
|
#ifndef NO_FAST_FUNCTIONS
|
||||||
|
@ -894,6 +841,7 @@ protected:
|
||||||
Bus_Parallel16 dma_bus;
|
Bus_Parallel16 dma_bus;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Matrix i2s settings
|
// Matrix i2s settings
|
||||||
HUB75_I2S_CFG m_cfg;
|
HUB75_I2S_CFG m_cfg;
|
||||||
|
|
||||||
|
@ -904,17 +852,9 @@ private:
|
||||||
* Since it's dimensions is unknown prior to class initialization, we just declare it here as empty struct and will do all allocations later.
|
* Since it's dimensions is unknown prior to class initialization, we just declare it here as empty struct and will do all allocations later.
|
||||||
* Refer to rowBitStruct to get the idea of it's internal structure
|
* Refer to rowBitStruct to get the idea of it's internal structure
|
||||||
*/
|
*/
|
||||||
// frameStruct dma_buff;
|
|
||||||
|
|
||||||
frameStruct frame_buffer[2];
|
frameStruct frame_buffer[2];
|
||||||
frameStruct *fb; // What framebuffer we are writing pixel changes to? (pointer to either frame_buffer[0] or frame_buffer[1] basically )
|
frameStruct *fb; // What framebuffer we are writing pixel changes to? (pointer to either frame_buffer[0] or frame_buffer[1] basically )
|
||||||
|
|
||||||
// ESP 32 DMA Linked List descriptor
|
|
||||||
int desccount = 0;
|
|
||||||
// lldesc_t * dmadesc_a = {0};
|
|
||||||
// lldesc_t * dmadesc_b = {0};
|
|
||||||
|
|
||||||
int active_gfx_writes = 0; // How many async routines are 'drawing' (writing) to the DMA bit buffer. Function called from Adafruit_GFX draw routines like drawCircle etc.
|
|
||||||
int back_buffer_id = 0; // If using double buffer, which one is NOT active (ie. being displayed) to write too?
|
int back_buffer_id = 0; // If using double buffer, which one is NOT active (ie. being displayed) to write too?
|
||||||
int brightness = 128; // If you get ghosting... reduce brightness level. ((60/64)*255) seems to be the limit before ghosting on a 64 pixel wide physical panel for some panels.
|
int brightness = 128; // If you get ghosting... reduce brightness level. ((60/64)*255) seems to be the limit before ghosting on a 64 pixel wide physical panel for some panels.
|
||||||
int lsbMsbTransitionBit = 0; // For colour depth calculations
|
int lsbMsbTransitionBit = 0; // For colour depth calculations
|
||||||
|
|
|
@ -582,7 +582,8 @@ bool DRAM_ATTR i2s_parallel_is_previous_buffer_free() {
|
||||||
}
|
}
|
||||||
|
|
||||||
previousBufferFree = false;
|
previousBufferFree = false;
|
||||||
while (i2s_parallel_is_previous_buffer_free() == false) {}
|
//while (i2s_parallel_is_previous_buffer_free() == false) {}
|
||||||
|
while (!previousBufferFree);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue