Wireless PDI/debug interface development

2010/08/27

After spending too much time messing with Bluetooth for programming and debugging my current project, I decided it was time to make some progress on a project that’s been bouncing around in my head and on my hard drive for a while, and recently acquired a decent name: ioStack.

The immediate requirement is that I be able to both program a microcontroller via PDI and interface with its debug serial port, using a wireless device that can be plugged into and powered by the target, on a connector that’s really crazy small.

Connector-wise, I discovered that the USB micro-B jack is actually smaller than the JST ZR-series I was using. Given that making wiring harness with the ZR is an absolute nightmare, switching to a connector for which pre-made cables are available is a major plus. The drawback is that USB only has 5 pins, which is a slight problem when dealing with two 2-pin interfaces as well as power and ground. Luckily, I found a really slick solution to that problem…

The next issue is developing a device that can actually talk over this “PDI5” interface. The PDI and serial ports are mutually exclusive, and can’t simply be two separate interfaces tied together. As per the post linked above, the 3 data lines must be wired directly to a single sync-capable serial port, which basically means there must be a microcontroller at the core of the program/debug device itself.

Finally, the wireless requirement has several potential solutions ranging from the aforementioned Bluetooth, through existing protocols such as Zigbee/802.15.4, and ending at custom protocols based on commonly-available radio chips. That final course leads to using a NRF24L01+ connected to the core microcontroller. While not providing any relevant protocol stack, it does give me a very high bandwidth multipoint-capable wireless PHY. While Zigbee and ANT seem to run in the 20-64Kbps burst range, the bare NRF24 runs at up to 2Mbps.

Now, to tie all this together I need a decent amount of software. First off was a PDI programming library, which turned out to be not overly difficult. An STK500v2/600-compatible protocol handler turned out to be a little more complicated. For a little background on why, the ioStack concept is based on raw byte streams rather than packetized units. Internally, everything intending to communicate via these streams has not much more than putbyte and getbyte routines. That means that the stk500v2 code must be configured as a strict state machine, transitioning on every byte.

Complicating matters further, the PDI protocol itself is not particularly well-suited to sitting around very long during a read. At most, you can tell it to insert 128 bits of dead-time during turnaround, then it starts clocking bytes at full speed. The other way around is also a problem, the actual stream multiplexer is currently somewhat intolerant of delays as well. As a result, I’ve arranged the state machine so that all of the PDI action happens in the CKSUM state, which means the host (e.g. avrdude) has finished sending an entire frame before getting put off for any period of time for things like block reads etc.

To connect the nrf24, I’ve got a chunk of code on top of the actual nrf24 driver that provides a rudimentary byte stream. This will need to be updated to actually be efficient, i.e. sending more than 1 byte per frame, but it gets the job done with the right abstraction already in place. I’ve got a lot more nrf24 deciphering and experimentation to do before I can make that module work noticeably better. Regardless, between the USART, STK500V2, and NRF24 modules I have a multiplexer to direct bytes to the right streams and handle polling the downstream modules for sending back upstream.

Another Xmega/nrf24 act as an “access point” forwarding data between the NRF24 and the USART attached to the PC. A Python script on the PC does the other half of the multiplexing, attaches the USART “pipe” to the console, and provides a TCP socket tied to the stk500v2’s “pipe”. Using this mechanism, I can both use avrdude to program the chip, and communicate to the chip’s debug serial port. This happens over a wireless connection, meeting the original goal of the project ;-)

I’ll try to post some more coherent info on the “ioStack” project soon, since it’s starting to come together finally.