Thursday, November 29, 2012

Debugging SPMP8000 Programs Without Soldering

As everybody knows, the best way to debug code is to print lots of crap to the console, not the least because that requires very little platform support: All you need is a place where you can dump data and where it can be retrieved later. On the SPMP8000, I have so far used the file system for that purpose: Just redirect stderr to a file and write everything there. There is, however, a big problem with that approach: On a system without memory protection, programming errors usually result in a system crash, which in turn leads to total loss of the logged output. A better solution would be to have a channel of communication from which the debug output can be read as it is written, such as a serial port.

Luckily, all SPMP8000 microcontrollers come with an on-chip serial port, and breaking it out seems simple enough: Most devices appear to have soldering pads where you can attach wires. So I set out to perform this operation on my JXD 100 and promptly ripped the soldering pad off the board when I tried to verify whether the solder joint is good. Determined to make this work, I then attempted to solder the TX wire directly to the leads on the microcontroller, with a soldering iron that, at its narrowest, is about as wide as two pins. Predictably, I ended up shorting the UART TX and RX lines, and I suppose the JXD 100 is now happily talking to itself when printing debug output. I briefly tried to aggravate the situation by using a knife to scratch out the solder between the pins, but luckily came to my senses before causing more serious damage.

So what now? After some contemplation I came up with an alternative solution that does not require any hardware shenanigans and thus allows me to keep my white gloves on and my hardware alive: using the line out connector as a serial port.

The audio debugging interface (adbg)


The latest feature in libspmp8k is the adbg debug interface. It takes your debug output, serializes it and sends it to the headphone jack. When you connect that to the line input on your PC and run adbg_console.py there, it will decode the signal and print the debug output to your console. No soldering, no need to employ serial-to-USB converters, just plug in a cable and you're done.

The Catch(es)


Of course nothing is ever that simple, and there are a few things that you have to keep in mind:
  • If you get no output at all, make sure to you have turned up the volume up to the maximum on both the transmitting and receiving ends. We want as much clipping as possible to get a nice square wave. You may also have to tell adbg_console.py which input it should listen to.
  • If you usually get correct output, but there are bursts of garbled data, make sure you have good sound hardware with good drivers on the PC side. My computer at work (HP desktop with Intel HDA sound, Linux kernel 3.4.x) inserts random bursts of noise into the input signal every once in a while and is therefore largely unusable for this application. The machine at home (EVGA 780i SLI FTW board, also Intel HDA, kernel 3.1.x), on the other hand, works without a hitch. YMMV.
  • Your computer may be oddly wired. If you receive output, but it's all garbled, you may have to invert the signal (adbg_console.py option "-i").
  • There is no error detection or correction, nor is there a back channel, so this is not something you can or should use to transmit data that has to be 100% error-free.
  • The devices I have seen so far (JXD 100 and A1000) seem to detect the presence of headphones by impedance. A line input has a much higher impedance that headphones and is therefore not detected. This is not a problem for signal transmission because the output on the headphone jack seems to be always on anyway, but it will be a problem for your ears because the internal speaker will not be switched off. You can, however, switch the speaker off manually in the "Settings" app.
  • Finally, you have to disable sound in your program when debugging because it would interfere with the debug signal.
For an example of how to use audio debugging, check the adbg demo in the demos directory. The console program adbg_console.py can be found in tools.

The console application is written in Python, supports ALSA and PortAudio, and requires pyalsaaudio (for ALSA) and/or PyAudio (for PortAudio) to be installed. ALSA is of course Linux-only, but using PortAudio it should work on Windows and Mac OS X as well, although I have not tested that.

Have fun!

1 comment:

  1. A rather strange method ...I understand that about sending commands to the device, you can forget?Can reasonably arrange UART to USB? (although I have no idea how to work with USB and I think it will be harder to implement this, but clever)I apologize for my English! Monster-Xaker

    ReplyDelete