A Cross Platform Mikromedia HID Bootloader

mikrobootloader logo

I love the bootloader that comes with all MikroElektronika products, and in particular the Mikromedia boards (and can be used with the ‘Graphics, Touch, Sound and USB’ book), but for one thing… it does NOT run on my platform of choice: OS X!

In fact it does work only on Windows, so I suspect that Linux users feel equally left out. To be honest things had never been this good for PIC developers as only in the last few years the MCHP toolchain has expanded to include OS X and Linux with MPLAB X and recently all the XC compilers…

The specs of the mikroBootloader are “kind of open” … in other words, if you ask, the nice guys at Mikroe will give you everything you need (and some). So I did (ask) and they did give me bits and pieces of source code, some comments, and a lot of encouragement and I quickly concocted my own version of the boot loader application for Mac and, since I used Python: Tkinter libs for the GUI and the HID-API libs for easy USB access, this should work right out of the box on most Linux distros as well (your mileage might vary, please report of your experiences).

Please feel free to download the script from this shared Bitbucket Mercurial repository and use, improve, share…

The application is meant to run both in command line mode and GUI mode. In fact a command line switch (-gui) will turn on the pretty face upon request. If a file name is passed on the same command line, that will be the default download hex file to load.

This far the good part, now for the ugly bits… details, details, details…

There is a second  command line switch available (-check) that, if you look at the code, might have you wondering as it is used by the script to invoke itself!? Why the apparent need for recursion?

It happens that the excellent HID-API libraries (written by Alan Ott of Signal 11),  have been wrapped in a Python library (using a tool called Cython). I used the resulting library in many scripts before, but never before I had noticed that once the library is invoked and a list of the enumerated devices is requested, this list is set in stone so to speak. In other words the Python HID-API lib is unable to detect any device addition or removal after that step. Unfortunately the Mikromedia boot loader is extremely dynamic in this regard. By its own nature, it will ‘attach’ to the bus after each board reset, but will also ‘detach’ shortly after (5 seconds timeout) unless a boot command is received by the host application. Effectively once launched, the Python HID-API libs (mind this is not a ‘feature’ of the original libs which I am told do not exhibit this behaviour) are unable to detect any Mikromedia board ‘appearing’ on the USB bus.

My solution (ok it is a dirty work around) has been to invoke the HID-API libs in a “nested” script to perform a periodic check for the presence of a Mikromedia board. Only once a board presence is detected, the outer script ‘spends’ its instance of the HID-API lib to enumerate and communicate with it. (Note how this makes the application a one-shot, after each single use it must commit kara-hiri).

If you know of a better (more elegant) solution to this problem or you find the bug and possibly fix it in the wrapper, please do share!

Later on in the development of the  application, I run into a different kind of issue. The Mikromedia documentation describes the data ‘record’ shared between the boot loader and the app to describe the MCU type, memory size, and other essential parameters. Unfortunately this record is defined as a C language struct which appears not to be ‘packed’. In other words, alternating byte, words and long words, are interspersed in the memory image with padding bytes. Rather then reverse engineering the block of data I was returned and hard coding the padding in the app/script, I opted to define an automatic ‘alignment’ adjustment to deal with it. This cost me a few lines of extra code and results in some obfuscation that I am not sure it is worth anymore. Once more I’d like to hear of your opinion on the subject or any better idea.

As a final note, the code presented here (shared bitbucket repository) has been 100% devoted to the use with the PIC24 Mikromedia (the unique way addresses are handled in the PIC24 architecture counting a word every ‘three’ bytes makes for some additional complexity  here and there) and it has been tested with the board only. Expanding its purpose to cover the PIC32 variants and even PIC18 options (Clicker users?)  would be a valuable endeavour and I would welcome any contribution on that front as well.

Enjoy,  improve, share!

This entry was posted in PIC24, Python, Tips and Tricks, Tools and tagged , , . Bookmark the permalink.