Skip to content

lcd: reset UART TX index after waking (fixes partly drawn digits on B1.5/B1.6) - #203

Open
altoing wants to merge 1 commit into
devbis:masterfrom
altoing:fix-uart-lcd-tx-index
Open

altoing wants to merge 1 commit into
devbis:masterfrom
altoing:fix-uart-lcd-tx-index

Conversation

@altoing

@altoing altoing commented Oct 7, 2026

Copy link
Copy Markdown

Fixes partly drawn digits on boards with the UART LCD (B1.5, B1.6).

Symptom

Every now and then one digit, usually the last one, shows with some segments missing. It fixes itself after a while. Seen on a B1.5 (hwVersion 15).

Cause

init_lcd_deepsleep() calls uart_reset() on every wake from retention sleep, which rewinds the hardware TX register cycle to 0x90. The SDK's software index uart_TxIndex is in retained RAM, so it survives the wake and is never reset. Each 13-byte LCD frame moves it forward by one (13 mod 4), so after a wake uart_ndma_send_byte() usually writes into the wrong one of the four TX registers and the LCD gets a shuffled frame.

The frame checksum is an XOR of the six data bytes, which does not depend on their order, so some of the shuffled frames are accepted and drawn. The display recovers when a later frame happens to line up with the hardware again.

The SDK header (platform/chip_8258/uart.h) documents this requirement: "this index should be reset to 0, when send data after system wakeup", and provides uart_ndma_clear_tx_index() for it.

Fix

Call uart_ndma_clear_tx_index() right after uart_reset(). This is one line; the I2C LCD boards are not affected.

Testing

  • Builds against SDK V3.7.2.0 (current master). I checked the disassembly to confirm that init_lcd_deepsleep() now clears uart_TxIndex.
  • The same change on top of 1.1.0 (SDK 3.6.8.6) has been running on a B1.5 since 2026-10-05.

Independent of #201 and #202.

🤖 Generated with Claude Code

init_lcd_deepsleep() calls uart_reset() on every wake from retention
sleep, which rewinds the hardware TX register cycle to 0x90. The SDK's
uart_TxIndex is kept in retained RAM and is not reset, and each 13-byte
LCD frame advances it by one. After a wake, uart_ndma_send_byte() then
writes into the wrong registers and the LCD receives a shuffled frame.
The XOR checksum does not depend on byte order, so some of these frames
are accepted and show partly drawn digits until a later frame happens
to be aligned again.

The SDK documents that uart_ndma_clear_tx_index() must be called after
waking up. Call it right after uart_reset().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant