Skip to content

Release 0.2.32 - #330

Merged
lovyan03 merged 7 commits into
m5stack:masterfrom
ainyan03:release_0.2.32
Oct 2, 2026
Merged

lovyan03 merged 7 commits into
m5stack:masterfrom
ainyan03:release_0.2.32

Conversation

@ainyan03

@ainyan03 ainyan03 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Fixes

0.2.30 built the whole v1 implementation as one translation unit
(lgfx_v1.cpp included every *.inl file). With the esp-2021r2 toolchain
(GCC 8.4 / binutils 2.35, used by arduino-esp32 2.0.x and the PlatformIO
espressif32 6.x / 7.x platforms) unused panel and touch code and its
data tables were no longer removed by --gc-sections on RISC-V targets
such as the ESP32-C3, which added several hundred kilobytes to a
firmware that uses a single SPI panel.

The older RISC-V assembler appends the CFI relocations of .rela.eh_frame
after the FDE header relocations, so they are not in offset order. When
the linker marks the FDE of a live function, it walks relocations from
that FDE up to its end offset without a lower bound, so the last FDE of
an object also picks up the out-of-order relocations of earlier
functions and keeps them. Within one object this pulled in nearly the
whole library.

Keep the shared header parsing of the single translation unit, but split
the implementation by function: lgfx_v1.cpp (sprite, button, misc),
lgfx_v1_panel.cpp, lgfx_v1_touch.cpp and lgfx_v1_platforms.cpp include
the *.inl files of their group, and LGFXBase.cpp, lgfx_fonts.cpp and
panel/Panel_M5HDMI.cpp (FPGA bitstream) build on their own.

The ESP-IDF CMake and make lists take the new files. The source check
accepts several hubs and standalone sources, and rejects an *.inl
reached from two hubs.
…P-IDF 5.1)

The SPI clock takeover (Arduino builds on C5 / C6 / C61 / P4) wraps its
read-modify-write of the clock-source register in PERIPH_RCC_ATOMIC(),
which ESP-IDF added in 5.2. arduino-esp32 3.0.x is built on ESP-IDF 5.1, so
an ESP32-C6 sketch failed to compile ("'PERIPH_RCC_ATOMIC' was not declared
in this scope"). C5 / C61 / P4 need arduino-esp32 3.1 or later and were not
affected.

ESP-IDF 5.1 has no shared lock for that register (its own SPI driver writes
the clock source without one), so where PERIPH_RCC_ATOMIC() is missing the
same block runs inside a critical section of its own.

(cherry picked from commit ec78f45)
When flash encryption keeps external RAM out of DMA, addDMAQueue() sends
what is queued and then writes the external RAM source by CPU. The
queued DMA could still be reading a flip buffer that writeBytes() then
reused, so a queue that held two getDMABuffer() buffers could have one
of them overwritten while it was being sent. Wait for the queued
transfer first.

Backport of the corresponding part of m5stack#320.
pushImageDMA() hands the caller's pointer straight to the bus. On the
ESP32 the SPI DMA cannot read PSRAM or flash, so an image held in PSRAM
was sent as garbage. The SPI bus now sends such sources by CPU, after
the queued DMA has finished. External RAM stays on the DMA path where
the SPI DMA can read it (GDMA targets without flash encryption), with
the existing alignment handling.

The ESP32-S2 / S3 parallel buses copy DMA-inaccessible sources (PSRAM,
flash) into their internal DMA buffer instead of passing them to the
DMA without writing the data cache back.

Backport of m5stack#324.
The copy path splits a transfer into chunks whose first four bytes go
out as LCD command cycles and the rest by DMA. For some lengths (for
example 257 to 260 bytes) a chunk was only four bytes long, so the DMA
descriptor had no payload; Bus_Parallel16 then waited forever for its
TX FIFO to fill. These lengths reach the copy path more often now that
DMA-inaccessible sources are copied.

Bus_Parallel16 now fills each chunk up to the buffer size (one byte less
when a byte is pending from an odd length) and sends a five-byte
remainder as four command bytes plus the pending byte. Bus_Parallel8
enlarges a four-byte chunk so that it carries a payload.
The ILI9342E variant of the CoreS3 panel was created with readable =
false, so readRect() / readPixel() returned nothing on those units. The
panel returns its frame memory with the read clock and dummy cycles that
are already set for it, as the ILI9342C does.

Backport of m5stack#321.
@lovyan03
lovyan03 merged commit c5a3fef into m5stack:master Oct 2, 2026
28 checks passed
@ainyan03
ainyan03 deleted the release_0.2.32 branch October 2, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants