Cheap chinese usbasp programmers and Ubuntu linux 13.10 (Saucy Salamander)

I suspect a lot of peope may have jumped at the chance to obtain a usbasp style programmer from one of the many ebay outlets in China. Furthermore I suspect quite a lot of these devices have wound up in a drawer because the purchaser couldn't make them work.

The internet is awash with articles on the subject, mostly tales of woe, but some offering good advice. I thought I would add my tuppence worth here, in the hope of building as clear a picture of how to pursuade one of these cheap progammers to work with Linux, and in the process perhaps save some other users a little bit of head scratching.

Windows users are welcome to chime in, but I will concentrate mainly on the issues I encounter with Ubuntu 13.10 and one of these which I must admit I purchased because it was the cheapest of the cheap on ebay.

When the device arrived, I fired it up, connected it to an equally cheap and cheerful Pro Mini clone, with suitable long jumper wires on to a breadboard, and fired up avrdude to test it.

First things first however I needed to set up some udev rules to make sure that Linux would handle it correctly.
The usbasp doesn't actually require any drivers under linux (at least not with any reasonably recent version), but udev rules will ensure that a lowly user can access the device withou needing superuser rights.

Here is what I fanally found to work (with the various other magic spells from my google searches about this in the comments for reference).

# USBasp - USB programmer for Atmel AVR controllers
# Copy this file to /etc/udev/rules.d 
# First variant, doesn't appear to work. 
# SYSFS{idVendor}=="16c0", SYSFS{idProduct}=="05dc", MODE="0660", GROUP="plugdev"
# More magic... also not very helpfull
# SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", MODE="0666"
# SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", SYSFS{idVendor}=="16c0", SYSFS{idProduct}=="05dc", MODE="0666"
# USBasp Programmer rules http://www.fischl.de/usbasp/
# SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666"
#
# Finally something that does what I want... 
# From https://wiki.archlinux.org/index.php/Udev#Accessing_Firmware_Programmers_and_USB_Virtual_Comm_Devices
SYSFS{idVendor}=="16c0",  SYSFS{idProduct}=="05dc", MODE="0660", GROUP="users"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666"

I fired up avrdude, and read the firmware back from my pro-mini..

avrdude -c usbasp -p m328p -U flash:r:"pro_mini_blink_flash.bin":r

It works!!! .. so far so good.

With a suitable set of udev rules, I next tried the Arduino IDE package with ships with Ubuntu.

It didn't work.

I upgraded to the latest version available here (1.5.5) .. tried again.. I had a few more options, but no matter which configuration changes I made, nothing would let me upload code... Time for some debugging...

Invariably whatever options I chose, the Arduino IDE insisted on trying to use a COM port to talk to the programmer.
If I watched the IDE output, let it fail to talk to the programmer, and then manually ran avdude from the command line with the correct switches and the files generated by the IDE, it would work...

Thus...

/home/blah/PersonalApps/arduino/hardware/tools/avrdude -C/home/blah/PersonalApps/arduino/hardware/tools/avrdude.conf -v -v -v -v -p m328p -cusbasp -Uflash:w:/tmp/build883889857218744381.tmp/BlinkSOS.cpp.hex:i

.. flashed my "BlinkSOS" code to the Pro Mini, and it started to flash dit-dit-dit--dah-dah-dah--dit-dit-dit... over and over on the pro mini led.

The remaining problem therefore lay with the IDE. How could I pursuade it to stop messing about with com ports, and use the usbasp in the correct manner. It insist on using variants of...

/home/blah/PersonalApps/arduino/hardware/tools/avrdude -C/home/blah/PersonalApps/arduino/hardware/tools/avrdude.conf -v -v -v -v -patmega328p -carduino -P/dev/ttyUSB0 -b57600 -D  -Uflash:w:/tmp/build3175003446538659244.tmp/blahblah

I tried every trick in the book, until eventually I resorted to changing the definition of the "arduino" programmer to make it a usbasp device. A nasty hack, I know.

So, now it works, but I hesitate to say it works correctly... this is still a work in progress.

There may be a more correct way to do this, but try as I might, I couldn't actually find any references to anybody who had managed to make these devices work simply by selecting the "correct" settings in the IDE under Linux.

I may take a crack at this again soon, but if one of the IDE developers is listening.. why does it not just work out of the box?

After all, the IDE finds my Nano V3 first time.

Furthermore, why does the IDE insist on using a COM port with the usbasp programmer (when it isn't COM port based), and why does it not let me unselect any selected COM port?

For example if the IDE sees that my laptop has a /dev/ttyUSB0 and a /dev/ttyUSB1, it will allow me to select one or the other, but not none of the above (i.e. unslect any previously selected com port).

It does work out of the box.
(I use linux mint 13)

The key is you have tell the IDE to use it.
The serial port is used for more than just uploading.
It is also used by sketch code which can communicate with the
serial monitor, so that is why it is there even when using an ISP
programmer because you can use both.

This is all documented on the Arduino site.

If you want to use your USBASP programmer you must
tell the IDE about it.
[Tools]->[Programmer]->USBasp

That will allow you to burn a bootloader or
to upload a sketch using the USBasp.
To upload the sketch you must tell the IDE
to override the default programmer in the boards.txt file
which is what the upload button uses.
To do the override:
[File]->Upload Using Programmer.
That will upload the sketch using whatever programmer
you selected - USBasp in your case.
(This will wipe out your bootloader).
One thing to note is that the IDE also is not smart enough to ignore the size of
the bootloader when doing this so you can't burn
an image that is the full size of the flash.

Alternatively, you can create a new board type in your boards.txt file
that uses the USBasp as its programmer and then
you can click on the upload button when using this board type.
Something like this:

unoUSBASP.name=Arduino Uno w/USBASP
unoUSBASP.upload.using=usbasp
unoUSBASP.upload.maximum_size=32768
unoUSBASP.bootloader.low_fuses=0xff
unoUSBASP.bootloader.high_fuses=0xde
unoUSBASP.bootloader.extended_fuses=0x05
unoUSBASP.bootloader.path=optiboot
unoUSBASP.bootloader.file=optiboot_atmega328.hex
unoUSBASP.bootloader.unlock_bits=0x3F
unoUSBASP.bootloader.lock_bits=0x0F
unoUSBASP.build.mcu=atmega328p
unoUSBASP.build.f_cpu=16000000L
unoUSBASP.build.core=arduino
unoUSBASP.build.variant=standard

That will allow you use the full flash.

It is kind of ugly, but that is how they did it.

--- bill