This commit is contained in:
parent
fd4831cb0f
commit
1d25183895
4 changed files with 115 additions and 51 deletions
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
// Mapping logic
|
||||
int panel_local_x = coords.x % 80; // Compensate for chain of panels
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
45
testing/four_scan_40_80px_hfarcan.cpp
Normal file
45
testing/four_scan_40_80px_hfarcan.cpp
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue