Skip to content

Commit bccd2d1

Browse files
[i2s] Need to adjust fifo ordering for everything on esp32 (#30)
1 parent 2de3e49 commit bccd2d1

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

components/hub75/src/platforms/i2s/i2s_dma.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,14 @@ constexpr uint16_t OE_CLEAR_MASK = ~(1 << OE_BIT);
6868
// ESP32 I2S TX FIFO position adjustment
6969
// In 16-bit parallel mode with tx_fifo_mod=1, the FIFO outputs 16-bit words in swapped pairs.
7070
// The FIFO reads 32-bit words from memory and outputs them as two 16-bit chunks in reversed order.
71-
// This compensates by storing pixels at swapped positions in the buffer.
72-
// ESP32-S2 has different FIFO ordering and doesn't need this adjustment.
71+
// XOR with 1 swaps odd/even pairs (0↔1, 2↔3, etc.). ESP32-S2 doesn't need adjustment.
72+
HUB75_CONST inline constexpr uint16_t fifo_adjust_x(uint16_t x) {
7373
#if defined(CONFIG_IDF_TARGET_ESP32)
74-
HUB75_CONST inline constexpr uint16_t fifo_adjust_x(uint16_t x) { return (x & 1U) ? (x - 1) : (x + 1); }
74+
return x ^ 1;
7575
#else
76-
HUB75_CONST inline constexpr uint16_t fifo_adjust_x(uint16_t x) {
77-
return x; // No adjustment for ESP32-S2
78-
}
76+
return x;
7977
#endif
78+
}
8079

8180
// ============================================================================
8281
// Constructor / Destructor
@@ -622,11 +621,11 @@ void I2sDma::initialize_buffer_internal(RowBitPlaneBuffer *buffers) {
622621

623622
// Fill all pixels with control bits (RGB=0, row address, OE=HIGH)
624623
for (uint16_t x = 0; x < dma_width_; x++) {
625-
buf[x] = (addr_for_buffer << ADDR_SHIFT) | (1 << OE_BIT);
624+
buf[fifo_adjust_x(x)] = (addr_for_buffer << ADDR_SHIFT) | (1 << OE_BIT);
626625
}
627626

628627
// Set LAT bit on last pixel
629-
buf[dma_width_ - 1] |= (1 << LAT_BIT);
628+
buf[fifo_adjust_x(dma_width_ - 1)] |= (1 << LAT_BIT);
630629
}
631630
}
632631
}
@@ -660,7 +659,7 @@ void I2sDma::set_brightness_oe_internal(RowBitPlaneBuffer *buffers, uint8_t brig
660659
uint16_t *buf = (uint16_t *) (buffers[row].data + (bit * dma_width_ * 2));
661660
// Blank all pixels: set OE bit HIGH
662661
for (int x = 0; x < dma_width_; x++) {
663-
buf[x] |= (1 << OE_BIT);
662+
buf[fifo_adjust_x(x)] |= (1 << OE_BIT);
664663
}
665664
}
666665
}
@@ -697,27 +696,27 @@ void I2sDma::set_brightness_oe_internal(RowBitPlaneBuffer *buffers, uint8_t brig
697696
for (int x = 0; x < dma_width_; x++) {
698697
if (x >= x_min && x < x_max) {
699698
// Enable display: clear OE bit
700-
buf[x] &= OE_CLEAR_MASK;
699+
buf[fifo_adjust_x(x)] &= OE_CLEAR_MASK;
701700
} else {
702701
// Keep blanked: set OE bit
703-
buf[x] |= (1 << OE_BIT);
702+
buf[fifo_adjust_x(x)] |= (1 << OE_BIT);
704703
}
705704
}
706705

707706
// CRITICAL: Latch blanking to prevent ghosting
708707
const int last_pixel = dma_width_ - 1;
709708

710709
// Blank LAT pixel itself
711-
buf[last_pixel] |= (1 << OE_BIT);
710+
buf[fifo_adjust_x(last_pixel)] |= (1 << OE_BIT);
712711

713712
// Blank latch_blanking pixels BEFORE LAT
714713
for (int i = 1; i <= latch_blanking && (last_pixel - i) >= 0; i++) {
715-
buf[last_pixel - i] |= (1 << OE_BIT);
714+
buf[fifo_adjust_x(last_pixel - i)] |= (1 << OE_BIT);
716715
}
717716

718717
// Blank latch_blanking pixels at START of buffer
719718
for (int i = 0; i < latch_blanking && i < dma_width_; i++) {
720-
buf[i] |= (1 << OE_BIT);
719+
buf[fifo_adjust_x(i)] |= (1 << OE_BIT);
721720
}
722721
}
723722
}
@@ -900,7 +899,7 @@ HUB75_IRAM void I2sDma::draw_pixels(uint16_t x, uint16_t y, uint16_t w, uint16_t
900899
auto transformed =
901900
transform_coordinate(px, py, needs_layout_remap_, needs_scan_remap_, layout_, scan_wiring_, panel_width_,
902901
panel_height_, layout_rows_, layout_cols_, dma_width_, num_rows_);
903-
px = fifo_adjust_x(transformed.x); // Apply I2S FIFO position adjustment for ESP32
902+
px = fifo_adjust_x(transformed.x);
904903
const uint16_t row = transformed.row;
905904
const bool is_lower = transformed.is_lower;
906905

@@ -965,7 +964,7 @@ void I2sDma::clear() {
965964

966965
for (uint16_t x = 0; x < dma_width_; x++) {
967966
// Clear RGB bits, preserve control bits
968-
buf[x] &= ~RGB_MASK;
967+
buf[fifo_adjust_x(x)] &= ~RGB_MASK;
969968
}
970969
}
971970
}

0 commit comments

Comments
 (0)