This commit is contained in:
mrcodetastic 2025-02-24 10:58:44 +00:00
parent fd4831cb0f
commit 1d25183895
4 changed files with 115 additions and 51 deletions

View file

@ -625,7 +625,60 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id)
* @param brt - brightness level from 0 to 255 - NOT MATRIX_WIDTH
* @param _buff_id - buffer id to control
*/
void MatrixPanel_I2S_DMA::brtCtrlOEv2(uint8_t brt, const int _buff_id)
/*
void MatrixPanel_I2S_DMA::setBrightnessOE(uint8_t brightness, const int buffer_id) {
if (!initialized)
return;
frameStruct *frameBuffer = &frame_buffer[buffer_id];
uint8_t blanking = m_cfg.latch_blanking; // Prevent overwriting during latch blanking
uint8_t colorDepth = frameBuffer->rowBits[0]->colour_depth;
uint16_t width = frameBuffer->rowBits[0]->width;
// Iterate through each row in the DMA buffer
for (int rowIdx = frameBuffer->rowBits.size() - 1; rowIdx >= 0; --rowIdx) {
// Process each bitplane (color depth level)
for (int depthIdx = colorDepth - 1; depthIdx >= 0; --depthIdx) {
int bitPlane = (2 * colorDepth - depthIdx) % colorDepth;
int bitShift = (colorDepth - lsbMsbTransitionBit - 1) >> 1;
int rightShift = std::max(bitPlane - bitShift - 2, 0);
// Calculate the brightness range for OE control
int activePixelRange = ((width - blanking) * brightness) >> (7 + rightShift);
activePixelRange = (activePixelRange >> 1) | (activePixelRange & 1);
int xCoordMin = (width - activePixelRange) >> 1;
int xCoordMax = (width + activePixelRange + 1) >> 1;
// Get pointer to the specific row and bitplane
ESP32_I2S_DMA_STORAGE_TYPE *rowData = frameBuffer->rowBits[rowIdx]->getDataPtr(depthIdx);
// Set OE bits based on brightness thresholds
for (int x = width - 1; x >= 0; --x) {
if (x >= xCoordMin && x < xCoordMax) {
rowData[ESP32_TX_FIFO_POSITION_ADJUST(x)] &= BITMASK_OE_CLEAR; // Enable output
} else {
rowData[ESP32_TX_FIFO_POSITION_ADJUST(x)] |= BIT_OE; // Disable output
}
}
}
// switch pointer to a row for a specific colour index
#if defined(SPIRAM_DMA_BUFFER)
ESP32_I2S_DMA_STORAGE_TYPE *row_hack = fb->rowBits[rowIdx]->getDataPtr(0);
//Cache_WriteBack_Addr((uint32_t)row_hack, sizeof(ESP32_I2S_DMA_STORAGE_TYPE) * ((fb->rowBits[row_idx]->width * fb->rowBits[row_idx]->colour_depth) - 1));
Cache_WriteBack_Addr((uint32_t)row_hack, fb->rowBits[rowIdx]->getColorDepthSize());
#endif
}
}
*/
void MatrixPanel_I2S_DMA::setBrightnessOE(uint8_t brt, const int _buff_id)
{
if (!initialized)
@ -691,6 +744,7 @@ void MatrixPanel_I2S_DMA::brtCtrlOEv2(uint8_t brt, const int _buff_id)
} while (row_idx);
}
/*
* overload for compatibility
*/

View file

@ -640,11 +640,11 @@ public:
}
brightness = b;
brtCtrlOEv2(b, 0);
setBrightnessOE(b, 0);
if (m_cfg.double_buff)
{
brtCtrlOEv2(b, 1);
setBrightnessOE(b, 1);
}
}
@ -731,12 +731,12 @@ protected:
inline void resetbuffers()
{
clearFrameBuffer(0);
brtCtrlOEv2(brightness, 0);
setBrightnessOE(brightness, 0);
if (m_cfg.double_buff) {
clearFrameBuffer(1);
brtCtrlOEv2(brightness, 1);
setBrightnessOE(brightness, 1);
}
}
@ -806,7 +806,7 @@ private:
* @param brt - brightness level from 0 to row_width
* @param _buff_id - buffer id to control
*/
void brtCtrlOEv2(uint8_t brt, const int _buff_id = 0);
void setBrightnessOE(uint8_t brt, const int _buff_id = 0);
/**
* @brief - transforms coordinates according to orientation

View file

@ -129,54 +129,19 @@ struct ScanTypeMapping {
}
else if constexpr (ScanType == FOUR_SCAN_40_80PX_HFARCAN)
{
// Weird mapping: https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/issues/759
panel_pixel_base = 16;
/*
* Weird mapping: https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/issues/759
* Panel is annoyingly weird. When sent DMA signal as if it's a
* 160px wide and 20px high. Then the DMA signal pixel (0,0) is
* shown on row 10.
* Then pixel 15 (i.e. 16 in real world), is at the physical of
* 0,0 (i.e. top left pixel), which then goes for 32 pixel.
* Then the next 32 pixel are at row 10 again. And so on and so forth.
*/
int panel_local_x = coords.x % 80; // compensate for chain of these panels
int logical_dma_y = (coords.y % 10) + 10 * ((coords.y / 20) % 2); // not impacted by chaining
int logical_dma_x = 0;
int logical_x_option = (coords.y/10)%2;
// Option 0 - phyiscal lines 0-9, 20-29
if (logical_x_option == 0) {
if (panel_local_x < 32) {
logical_dma_x += 16;
}
else if (panel_local_x < 64) {
logical_dma_x += 48;
}
else if (panel_local_x < 80) {
logical_dma_x += 80;
}
// Mapping logic
int panel_local_x = coords.x % 80; // Compensate for chain of panels
if ((((coords.y) / 10) % 2) ^ ((panel_local_x / panel_pixel_base) % 2)) {
coords.x += ((coords.x / panel_pixel_base) * panel_pixel_base);
} else {
// Option 1
if (panel_local_x < 16) {
}
else if (panel_local_x < 48) {
logical_dma_x += 32;
}
else if (panel_local_x < 80) {
logical_dma_x += 64;
}
coords.x += (((coords.x / panel_pixel_base) + 1) * panel_pixel_base);
}
// What logical row are we addressing?
logical_dma_x += panel_local_x;
coords.x = logical_dma_x;
coords.y = logical_dma_y;
coords.y = (coords.y % 10) + 10 * ((coords.y / 20) % 2);
}
// FOUR_SCAN_64PX_HIGH || FOUR_SCAN_32PX_HIGH

View file

@ -0,0 +1,45 @@
#include <iostream>
#include <iomanip> // For output formatting
// FOUR_SCAN_40_80PX_HFARCAN test
struct Coords {
int x;
int y;
};
int main() {
int panel_pixel_base = 16; // Updated pixel base
Coords coords;
// Header for easy Excel copying (Pipe-delimited format)
std::cout << "Input X|Input Y|Output X|Output Y" << std::endl;
// Loop for testing multiple inputs
for (int y = 0; y < 40; y += 3) { // Updated y increment to 3
for (int x = 0; x < 80; x += 10) {
coords.x = x;
coords.y = y;
// Store original coordinates for display
int input_x = coords.x;
int input_y = coords.y;
// Mapping logic
int panel_local_x = coords.x % 80; // Compensate for chain of panels
if ((((coords.y) / 10) % 2) ^ ((panel_local_x / panel_pixel_base) % 2)) {
coords.x += ((coords.x / panel_pixel_base) * panel_pixel_base);
} else {
coords.x += (((coords.x / panel_pixel_base) + 1) * panel_pixel_base);
}
coords.y = (coords.y % 10) + 10 * ((coords.y / 20) % 2);
// Output results in pipe-delimited format for easy Excel import
std::cout << input_x << "|" << input_y << "|" << coords.x << "|" << coords.y << std::endl;
}
}
return 0;
}