I had incorrectly configured asynchronous serial communication parameters between my KB2040 microcontroller running CircuitPython and NEC K13988 chip on a control board salvaged from a Canon MX340 multi-function inkjet. But once I sorted that out (two stop bits, not just one) I could successfully send a full set of frame buffer data to the LCD with minimal transmission failures. This allowed me to follow up on an observation I had from my first test: the vertical frame buffer byte offsets are not as expected.

The pattern I saw via logic analyzer indicated the top 8 pixels of the screen were dictated by sending pixel data with the offset 0x4D to start the sequence. But when I tried doing the same thing with my KB2040, the stripe rendered two pixels lower than expected. This pattern continued for the rest of the screen, with successively lower rows corresponding to 0xCD, 0x2D, and 0xAD. When I decoded frame buffer data captured by logic analyzer, offset 0x6D dictated the bottom-most two rows of pixels. (The least significant six bits are not visible.) However, now data sent to 0x6D is not visible at all. Experimenting with other offsets, I stumbled on the fact I could transmit data to 0x8D and that data would help me fill in the top two rows of pixels. (The most significant six bits are not visible.)

Even though it was unexpected, that was good enough for my next experiment: I changed the program so instead of a fixed value, each byte counts up one. This gave me get a precise delineation and count for all horizontal and vertical pixels. Thanks to this test pattern I am now confident this LCD has 196 pixels horizontally and 34 pixels vertically.

But what about that unexpected offset? The most likely suspect is a mistake in my initialization sequence, and a double-check found the culprit. There was a two-byte sequence 0x04 0x42 in my decoded notes, but I forgot to put that in my KB2040 initialization sequence. Once I put that back in, my LCD frame buffer renders at the expected location. On my to-do list is to play with my initialization sequence, selectively skipping them to see what effect they have on behavior. Looks like I inadvertently started that experiment early! This little side trip also suggested an interesting possibility: that the LCD controller has extra frame buffer memory available, possibly allowing vertical scrolling without re-sending the entire frame buffer.

Without the datasheet, though, that's mostly an empty thought. It's more productive to try to pair this display with a graphics library.