Skip to content

Sync master (0.2.35) into develop - #377

Merged
lovyan03 merged 7 commits into
m5stack:developfrom
ainyan03:sync_master_0.2.35
Oct 25, 2026
Merged

lovyan03 merged 7 commits into
m5stack:developfrom
ainyan03:sync_master_0.2.35

Conversation

@ainyan03

Copy link
Copy Markdown
Contributor

Merges the 0.2.35 release (master) back into develop. The merge had no conflicts; the only net change against develop is the version bump (4 files). Please merge with "Create a merge commit" (not squash / rebase) so that master stays an ancestor of develop.

ainyan03 and others added 7 commits October 25, 2026 00:09
_check_busy() reset _total_send to 0 after waiting, so the command it
was called for went uncounted. After a long COPYRECT the next
_set_window(force) skipped the busy check and streamed the pixel data
while the FPGA was still copying. The FPGA keeps about 2 KB of received
bytes and drops the rest, so the WRITE_RAW never got all its pixels and
the display answered busy until it was power-cycled.

Seen on ESP32-P4 with Module Display (bundled bitstream) at 1280x720
24bpp: copyRect 617x341 followed by a 76x71 RGB888 pushImage hung 3 of
3 times; with this change 0 of 3.

(cherry picked from commit d0f45d2)
The SCL period and START / STOP timing fields are 9 bits wide (7 bits for
the SCL high wait) on every chip after ESP32-S2, while the values were
sized for the 10 / 14 bit fields of ESP32. A bitfield drops the upper bits
instead of saturating, so (figures for a 40 MHz source clock; they scale
with the clock, e.g. on a 32 MHz XTAL or a low power port):

- below about 78 kHz the START hold / RSTART setup / STOP setup wrapped
  (75 kHz: 534 -> 22 clocks = 0.55 us, the device stopped answering), and
  the STOP hold wrapped below about 156 kHz (50 kHz: 1.6 us)
- on ESP32-C3 the SCL high wait overflowed below about 130 kHz, so the bus
  ran faster than requested (100 kHz setting -> 151 kHz measured)
- below about 39 kHz the SCL low / high periods wrapped as well

Cap the cycle so that both SCL halves fit (the slowest bus on these chips
is now about 39 kHz from a 40 MHz XTAL), and saturate each timing value at
its field width. The STOP hold is still derived from the START / STOP
value after the 1023 limit, as before. Values that already fit are
unchanged: ESP32 / S2 are not affected, and at 400 kHz nothing changes on
any chip. At 100 kHz the SCL
clock stays the same on the 9 bit chips other than C3, and only the STOP
hold grows from the wrapped 7.2 us to 12.8 us.

(cherry picked from commit daba652)
Rebuilt from the Veryl port of the ATOM Display FPGA design
(ciniml/atom_display_fpga, feature/veryl-port, 93d419c, GOWIN EDA 1.9.12).
Compared with the bitstream bundled so far:

- COPYRECT no longer hangs busy for a short horizontal shift of an
  overlapping area, and a host that pauses mid stream no longer shifts
  the picture.
- The stream writer no longer stays busy when the last pixel of a
  transfer (e.g. a 1 px wide pushImage) arrives while the previous write
  address is still waiting.

The command protocol is unchanged, so the driver needs no change. The
compressed image grows from 227,317 to 247,517 bytes.

(cherry picked from commit 4cde61b)
With M5Unified cfg.clear_display = false (LGFX init_without_reset(false)),
the image on the panel was wiped during initialization (m5stack#370):

- GDEW0154D67 / SSD1677: LGFX_Device::init_impl() re-applies the invert
  setting after Panel::init(), and setInvert() marked the whole frame dirty
  while the init sequence was pending, so the endWrite() of init_impl()
  refreshed the panel with the (white) host buffer. Re-applying the current
  value no longer marks the frame dirty; a changed value is still shown.
- GDEW0154D67: the frame sent by the init sequence is no longer inverted.
  With the inverted frame, the flip draw that follows ended inverted
  whenever that was the first display() after a reset (not visible before,
  because init() itself refreshed the panel).
- TM1680: init() no longer pushes the cleared buffer, and setInvert()
  pushes only when the value changes. The init commands do not touch the
  LED RAM, so the image stays on the LEDs until the first draw.
- Panel_1bitOLED / Panel_M5UnitGlass: init() clears the host buffer (and
  the tile dirty flags of the Unit GLASS) without pushing it. They relied on
  the clear() of a normal init; with an init without clear, the first
  partial drawing would have sent whatever the allocator left there.

The host buffer cannot be read back from these panels, so the first drawing
after an init without clear still replaces the whole panel with the new
buffer. What changes is that the initialization itself no longer wipes it.

(cherry picked from commit 385851f)
@lovyan03
lovyan03 merged commit 445170e into m5stack:develop Oct 25, 2026
25 checks passed
@ainyan03
ainyan03 deleted the sync_master_0.2.35 branch October 25, 2026 02:19
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