@@ -65,6 +65,19 @@ constexpr uint16_t RGB_MASK = RGB_UPPER_MASK | RGB_LOWER_MASK; // 0x003F
6565// Bit clear masks
6666constexpr uint16_t OE_CLEAR_MASK = ~(1 << OE_BIT);
6767
68+ // ESP32 I2S TX FIFO position adjustment
69+ // In 16-bit parallel mode with tx_fifo_mod=1, the FIFO outputs 16-bit words in swapped pairs.
70+ // 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.
73+ #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 ); }
75+ #else
76+ HUB75_CONST inline constexpr uint16_t fifo_adjust_x (uint16_t x) {
77+ return x; // No adjustment for ESP32-S2
78+ }
79+ #endif
80+
6881// ============================================================================
6982// Constructor / Destructor
7083// ============================================================================
@@ -887,7 +900,7 @@ HUB75_IRAM void I2sDma::draw_pixels(uint16_t x, uint16_t y, uint16_t w, uint16_t
887900 auto transformed =
888901 transform_coordinate (px, py, needs_layout_remap_, needs_scan_remap_, layout_, scan_wiring_, panel_width_,
889902 panel_height_, layout_rows_, layout_cols_, dma_width_, num_rows_);
890- px = transformed.x ;
903+ px = fifo_adjust_x ( transformed.x ); // Apply I2S FIFO position adjustment for ESP32
891904 const uint16_t row = transformed.row ;
892905 const bool is_lower = transformed.is_lower ;
893906
0 commit comments