After a quick warm-up exercise of verifying activity over expected serial transmission lines, I updated my code to use CircuitPython's busio.uart to interpret that activity as asynchronous serial data. Based on earlier analysis, I expect to receive data at least once every 9.2ms, so I set up an asynchronous task to constantly process incoming data. The good news is that I saw a constant stream of 0x80 0x40, which was as expected. I had established 0x80 was the value reported for "no buttons are pressed" so I had expected that value to change if I pressed a button. It did not! Apparently key matrix scan code reporting doesn't start by default.

In order to parrot the initialization sequence decoded by my logic analyzer, I need to write another asynchronous task. This one transmits given data and then wait for the receiver task to see an 0x20 acknowledgement byte before returning. Once up and running and initialization sequence sent, the receiver task started reporting key matrix scan code values. Success!

Up until this point I still had the Neopixel sample code running as a system heartbeat indicator. With serial communication up and running, I thought I'd switch over to using one of the LEDs on the control panel. I created another asynchronous task, this one loops to turn the "In Use/Memory" LED on and off at one second intervals while leaving the "WiFi" LED off. I have already decoded the bit flags necessary to toggle LEDs and I got a LED that blinked for a few seconds.

Then it got stuck.

Debugging indicated that my code got stuck because the data transmission to update LED state never received that 0x20 acknowledgement, which meant the transmit task never returned to caller. I quickly whipped up a timeout mechanism by checking timestamp in a loop. It worked, but then I realized there was already a mechanism built into CircuitPython. So I deleted my timestamp checking loop and replaced it with a single call to asyncio.wait_for().

I needed to write this timeout code and retry transmission for robust error recovery no matter the reason, but I want to know the reason why I never got 0x20 acknowledgement. Maybe there are times when the chip is not listening to my commands? Or maybe there's a problem in my data transmission? I think it's very likely the chip isn't always receptive, but that's not as important as the discovery there was indeed a problem with my data transmission.