TS101: fix OLED partial-screen rendering and vertical offset - #2238
TS101: fix OLED partial-screen rendering and vertical offset#2238Edrig wants to merge 9 commits into
Conversation
setRotation() only ever sent the segment-remap (0xA0/0xA1) and COM-scan-direction (0xC0/0xC8) commands, never touching the SSD1306 "Set Display Offset" (0xD3) command that already existed in OLED_Setup_Array (always left at 0x00). Disassembling the official Miniware TS101 firmware (TS101AppV220.hex) shows that after the remap/scan commands it also sends 0xD3 with an orientation-dependent value (0x10 / 0x30). Without it, the 128x32 panel can render shifted by half its screen height depending on the physical OLED panel batch. Confirmed on real TS101 hardware.
Confirmed on hardware that stock TS101 OLED handling (the bulk 0x80-continuation transmission shared by every other model, via I2C_CLASS::Transmit/writeRegistersBulk) leaves the panel stuck on the boot splash with the menu confined to a small area at the top-left: the 128x32 SSD1306 on the TS101 only reliably updates when each command/ data chunk is sent as its own I2C transaction. This ports the working per-byte transmission path (i2c_send_command_byte / oled_bulk_write) from the community fork IronOS-TS101-FullOLED into refresh(), setDisplayState(), initialize(), setRotation(), setBrightness(), setInverseDisplay() and maskScrollIndicatorOnOLED(), gated behind #ifdef MODEL_TS101 so no other model (TS100/TS80/TS80P/Pinecil/Sequre S60/S60P/T55/...) is affected - they keep using the existing Transmit()/writeRegistersBulk() path unchanged. Also narrows the previous commit's segment-remap/offset triplet from `#ifdef OLED_SEGMENT_MAP_REVERSED` to `#ifdef MODEL_TS101`: that macro is also set by Sequre's 128x32 models, which would otherwise have received TS101-specific hardware values they were never verified against. Verified working end-to-end (EN and FR builds) on physical TS101 hardware.
|
Please ensure the PR follows the PR template in the repository. Ping me once your using the template and I'll do a review pass. Please avoid using MODEL_ #ifdef's in the main drivers where possible and use a descriptive flag instead so that if we have other models with this issue it can be enabled in their configuration files instead. |
Per review feedback: gate the per-byte I2C transmission path and the non-zero orientation-dependent display offset behind two descriptive flags (OLED_I2C_PER_BYTE_TRANSFERS, OLED_DISPLAY_OFFSET_QUIRK) defined in TS101's configuration.h, instead of raw MODEL_TS101 checks in the shared OLED driver. No behaviour change for TS101 or any other model.
|
Hello, |
| static void initialize(); // Startup the I2C coms (brings screen out of reset etc) | ||
| static bool isInitDone(); | ||
| // Draw the buffer out to the LCD if any content has changed. | ||
| #ifdef OLED_I2C_PER_BYTE_TRANSFERS |
There was a problem hiding this comment.
It would be nicer to pull both of these into the cpp file so that we have have the only #ifdef mask in the cpp file
| #ifdef OLED_I2C_PER_BYTE_TRANSFERS | ||
| // Sent as individual command-byte writes; the bulk 0x80-continuation path below | ||
| // is what leaves this panel stuck on a partial refresh. | ||
| i2c_send_command_byte(OLED_Setup_Array[9].val); |
There was a problem hiding this comment.
Is there a reason for these being sent out of order?
| static void i2c_send_bulk(const uint8_t *buf, int len) { I2C_CLASS::Mem_Write(DEVICEADDR_OLED, 0x40, buf, len); } | ||
|
|
||
| static void oled_bulk_write(uint32_t posx, uint32_t posy, int sizex, int sizey, const uint8_t *buf) { | ||
| uint32_t page = (posy & 7) == 0 ? (posy >> 3) : (posy >> 3) + 1; |
There was a problem hiding this comment.
This will need to be reformatted to pass the cpp check, ensure you are are running the style fix in the docker image.
- Move the OLED_I2C_PER_BYTE_TRANSFERS branching for refresh()/setDisplayState() out of the header and into OLED.cpp, so the header only has plain declarations and the ifdef mask lives in one place. - Fix setRotation()'s per-byte command order to match OLED_Setup_Array's layout order instead of an arbitrary order. - Run clang-format over both files.
|
If you could touch up that comment I think the reset is good 🙇🏼 Will merge after that |
The OLED_DISPLAY_OFFSET_QUIRK branch duplicated the #else branch (both wrote 0xA0 with the same comment), so it can be dropped.
CI flagged the padded spacing on the 0xA0 line; align it with the adjacent 0x00 line's single-space formatting.
Bug fix (TS101 OLED driver).
On stock TS101 (
MODEL_TS101), the shared OLED transmission path (I2C_CLASS::Transmit/writeRegistersBulk, a single bulk0x80-continuation-prefixed I2C transaction) does not reliably drive the full 128x32 SSD1306 panel: the boot splash stays on screen and the menu only renders in a small area at the top-left. Every other model on this driver (TS100, TS80, TS80P, Pinecil, Sequre S60/S60P/T55, ...) is unaffected — this is specific to the TS101's panel/wiring.refresh(),setDisplayState(),initialize(),setRotation(),setBrightness(),setInverseDisplay()andmaskScrollIndicatorOnOLED().0xD3) command with an orientation-dependent value, matching the official Miniware TS101 firmware disassembly (TS101AppV220.hex) — without it the panel can render shifted by half its screen height.#ifdef MODEL_TS101checks in the shared OLED driver with two descriptive flags defined in TS101's ownconfiguration.h:OLED_I2C_PER_BYTE_TRANSFERS(bus can't do bulk transfers) andOLED_DISPLAY_OFFSET_QUIRK(needs the non-zero orientation-dependent offset). These are two independent concerns — another model could hit either issue on its own — and are no longer coupled to a specificMODEL_macro in the driver itself. No behaviour change for TS101 or any other model.Verified end-to-end (EN and FR builds) on two physical TS101 units, on different bootloader/DFU versions (1.06 and 1.08): before this change the screen stayed on the boot splash with the menu confined to the top-left; after, the full 128x32 panel renders correctly in both orientations on both units, with brightness/inverse-display/rotation all working.
Test plan:
Builds cleanly for
model=TS101 firmware-ENandfirmware-FRBuilds cleanly for
model=TS100 firmware-EN(regression check — new flags not defined, code path unchanged)Confirmed fixes the partial-screen/offset issue on two physical TS101 units (DFU 1.06 and DFU 1.08), both orientations
Not tested on other model
An LLM (AI) was used for some of this code
An LLM was used, and I have manually audited the code. I understand what changes it made and why.