Tuesday, 12 March 2013

How to use the GPIO version of avrdude on the Raspberry Pi

Introduction

I previously showed an implementation of a AVR ISP programmer using the Raspberry Pi GPIO port which can be used to program Atmel's AVR range of microcontrollers with avrdude. An ISP programmer based on this design was incorporated into a shield to interface to the RFM12B radio module. This post explains how to use avrdude to actually program devices.

Software installation

Download the patched version of avrdude from http://project-downloads.drogon.net/files/. I also keep a copy in the RPi_RFM12B_ISP respository, https://github.com/stevemarple/RPi_RFM12B_ISP/tree/master/software/avrdude. You will probably want the armhf (hardware floating-point) version. Download the documentation package for avrdude too. Install the packages using "dpkg -i". For example

sudo dpkg -i avrdude_5.10-4_armhf.deb
sudo dpkg -i avrdude-doc_5.10-4_all.deb

Using avrdude over the GPIO interface is problematic for users other than root. The easiest solution is to give the avrdude binary setgroup permission:
sudo chmod g+s /usr/bin/avrdude

Usage

Selecting the GPIO programmer is simply a matter of including "-P gpio -c gpio" options; the -P option specifies that the GPIO port is used (as opposed to USB, serial or parallel interfaces) whilst the -c option selects the correct programmer type on that port.

For example, to check the signature on an ATmega328P execute the command
avrdude -P gpio -c gpio -p atmega328p

To read the fuses execute the command
avrdude -P gpio -c gpio -p atmega328 -U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h

Customisation

The packages above define a single programmer called gpio which uses the gpio interface on GPIO pins 8 to 11. Since the RFM12B shield for Raspberry Pi implements two independent programmers I prefer to use gpio0 and gpio1. You can add these by creating a .avrduderc file in your home directory. The file should contain:

programmer
  id    = "gpio0";
  desc  = "Use sysfs interface to bitbang GPIO lines";
  type  = gpio;
  reset = 8;
  sck   = 11;
  mosi  = 10;
  miso  = 9;
;

programmer
  id    = "gpio1";
  desc  = "Use sysfs interface to bitbang GPIO lines";
  type  = gpio;
  reset = 7;
  sck   = 11;
  mosi  = 10;
  miso  = 9;
;

38 comments:

  1. I have been looking for some information on how to program micro controllers from the rp and this looks very good :)

    Just a little question can you compile the code and produce a hex file on the raspberry pi? Or do you compile the code on a computer and then transfer the hex file to the Raspberry pi and then upload it.

    Thanks a lot for your help :)

    ReplyDelete
    Replies
    1. I use both approaches. It is even possible to compile with the Arduino IDE on the Raspberry Pi and upload directly without manually invoking avrdude. I don't have any specific instructions to set this up but I do this with my RFM12B and Atmel ISP programmer shield. You can probably figure it out from the boards.txt and README in project's Github repository.

      Delete
    2. Oh ok just got this working today thanks a lot for the help :)

      Delete
  2. I'm asking what kind of programmer it is because avrdude and the Arduino IDE want to know it.

    ReplyDelete
    Replies
    1. IT's a gpio programmer. You can find an example of how the programmers.txt file should look in my RPi_RFM12B_ISP repository:
      https://github.com/stevemarple/RPi_RFM12B_ISP/blob/master/software/raspi/programmers.txt

      You can find an example boards.txt file at https://github.com/stevemarple/RPi_RFM12B_ISP/blob/master/software/raspi/boards.txt but you will need to modify the MCU entries to suit your needs.

      Delete
    2. Where must I do this? And how do I really write something on it with the Arduino IDE e.g. flashing the bootloader. Or how can I flash the Arduino BL with 3,3V on it with the avrdude.

      Delete
    3. You'll need the Arduino IDE installed on the Raspberry Pi. In your sketches folder create a folder called hardware. Put the programmers.txt file I referenced above into the hardware folder. Restart the Arduino IDE. You can then select the Raspberry Pi programmer from the tools menu in the Arduino IDE. Make sure you use "upload using programmer".

      Alternatively you can call avrdude directly. You'll need to use the -U flash option, and pass the path to the bootloader file. The avrdude man page has more information.

      Remember Arduinos are powered at 5V. If you power a standard 16MHz one at 3.3V it will be overclocked and may not work. If you power it at 5V use the correct logic buffer or make sure you include series resistors (4k7 should do) to limit the current through the input protection diodes.

      Delete
  3. How would I set some fuses like

    HIGH 0xDA
    LOW 0xE2
    Extended 0xFF

    ReplyDelete
    Replies
    1. The avr fuse calculator is a very useful resource for setting fuses. It also displays the relevant options for setting the fuses using avrdude. I haven't tested it but I think the command you need to program an ATmega328P using channel 0 of my Raspberry Pi programmer is

      avrdude -P gpio -c gpio -p atmega328 -U lfuse:w:0xE2:m -U hfuse:w:0xDA:m -U efuse:w:0xFF:m

      Delete
  4. Hallo.
    Your tutorial was very useful bit i don't know witch programmer i must use.
    I have Atmega8A and i made board as seen your tutorial.
    I wanna know how can I connect pieces together cause it's a little bit confusing and i never used avr before.
    I'd realy aprisiate your helt.

    KLemen

    ReplyDelete
    Replies
    1. You need to use the GPIO programmer option on avrdude. Wiring follows the standard AVR ISP pin out.

      Delete
  5. Can i use it to connect an atmel direct to the SPI Port of the Raspberry PI?

    ReplyDelete
    Replies
    1. Yes, but when connecting directly you need to be very careful otherwise it is easy to damage the Pi. The Atmel part must absolutely be powered from 3.3V, and so must any other devices on the SPI bus. There are good reasons why I included the buffering on my Raspberry Pi AVR ISP programmer. This version of avrdude bit-bangs the SPI pins but there is another version now exists which uses hardware SPI.

      Delete
  6. Thank you so Much Bro........luved this....

    ReplyDelete
  7. Can I use this GPIO version to program an ATXMEGA256 (pdi) ?

    thanks

    ReplyDelete
    Replies
    1. No, it supports the in-circuit serial programming interface (ISP or ICSP) that most of the ATmega range of microcontrollers can use.

      Delete
  8. There seems to be a bug in avrdude, as it does not seem to support GPIO numbers gpio255:

    root@sabayon /home/zoobab/soft/avrdude [5]# /usr/local/bin/avrdude -c linuxgpio -C /etc/avrdude.conf -p m328p
    avrdude: error: no pin has been assigned for AVR MISO

    avrdude done. Thank you.

    ReplyDelete
  9. I am tearing my hair out attempting to run "avrdude" without the error "gpio/direction:: Permission denied" occurring. I tried "sudo chmod g+s /usr/bin/avrdude" as suggested here but no cigar. The problem is that I am running the Raspberry Pi headless using "tightvncserver" logged in as pi from Ubuntu 14.04.

    I have followed the procedure at https://projects.drogon.net/raspberry-pi/gertboard/arduino-ide-installation-isp/ and tried "sudo chmod 4755 /usr/bin/avrdude" which fails to initialise with error rc-1. If, however I use "sudo chmod 777" it supresses this error but gives "gpio/direction:: Permission denied". I have also tried using putty SSH with user "root" and adding sudo before avrdude in avrsetup.

    Can somebody help - P-L-E-A-S-E !!!

    ReplyDelete
    Replies
    1. "sudo chmod g+s /usr/bin/avrdude" will only work if the group of the avrdude program matches the group of the gpio interface files. I should probably add some code to ensure that is the case. But the same argument can be made when setting setuid too. Running headless makes no difference, that's how I use mine.
      Q1 What's the ownership etc on /usr/bin/avrdude? ("ls -l /usr/bin/avrdude" ?)
      Q2 Can you log in remotely, get a root shell with "sudo -i" and then run avrdude? That should "just work".

      Delete
    2. "will only work if the group of the avrdude program matches the group of the gpio interface files."
      Or is root, of course.

      Delete
    3. Hi Steve and thanks for the prompt reply:

      Hope the following helps

      pi@ImpartitPiBPlus ~ $ sudo -i
      root@ImpartitPiBPlus ~# sudo chmod g+s /usr/bin/avrdude
      root@ImpartitPiBPlus ~# ls -l /usr/bin/avrdude
      -rwxrwsrx 1 root root
      root@ImpartitPiBPlus ~# avrsetup gives r=-1 error

      root@ImpartitPiBPlus ~# logout
      pi@ImpartitPiBPlus ~$ chmod 777 /usr/bin/avrdude
      pi@ImpartitPiBPlus ~$ avrsetup - gives gpio/direction: Permission denied

      pi@ImpartitPiBPlus ~$ ls -l /usr/local/bin/gpio
      -rwsr-xr-x 1 root root

      Relevant line in avrsetup is
      avrdude -qq -c gpio -p atmega328p -U lock:w:0x3F:m -U efuse:w0x07:m
      -U lfuse:w:0xE7:m -U hfuse:w:0xoD9:m

      Delete
    4. Problem 1: You're still not running avrdude as root.
      Problem 2: Using chmod 777 removes any setuser/setgrpoup attributes, so you really won't have any special access to the /sys files needed.

      Use "sudo -i" to get a root shell and then run just the avrdude command. The most basic command is to read the signature and that is where you should start:

      sudo -i
      avrdude -P gpio -c gpio -p atmega328p

      Does that work?

      If you want to use the same version of avrdude as I described above you can download it from the Github repository for RPi_RFM12B_ISP:
      https://github.com/stevemarple/RPi_RFM12B_ISP/tree/master/software/avrdude
      You probably need the hard-float version (avrdude_5.10-4_armhf.deb).

      Delete
    5. after sudo -i

      avrdude -P gpio -c gpio -p atmega328p still gives the rc=-1 error.

      The version of avrdude is 5.10-4 for armhf.deb

      Delete
    6. Aha!
      running simply avrdude as root reports
      Device Signature = 0x000000
      Yikes! Invalid Device Signature
      Expected signature for ATMEGA328P is 1E 95 0F

      Delete
    7. Sorry - I meant to write

      avrdude -P gpio -c gpio -p atmega328p -F

      The version of avrdude is 5.10-4 for armhf.deb

      Delete
    8. Just checked conections again and placed Gertboard directly on Pi (i.e. no ribbon cable connection) - no change!!

      Delete
    9. If you've got invalid device signature then you are doing something right! It means you have avrdude talking to the GPIO interface with no errors. Now you need to configure avrdude to use the correct gpio pins. You can use the customisation section above as an example but you will have to alter the pin numbers to suit your hardware.

      Delete
    10. Hi! I had the same problem and I solved with a little patch in the code. Basically if you export and try to change direction of a pin very quickly you got that error, I put some sleep in the avrdude code and then it works. I'll send you a patch as soon I boot my Rpi where there is the code..

      Delete
    11. here a patch
      http://savannah.nongnu.org/bugs/?44218

      Delete
  10. File .avrduderc created with cutomized entrires as above - no joy. When or how is this file read/executed. Two pins for reset? I have only one connection - pin 8. There is no mention of needing to do this at https://projects.drogon.net/raspberry-pi/gertboard/ and https://projects.drogon.net/raspberry-pi/gertboard/initial-setup-of-the-atmega/ - thanks again Steve but still not working.

    ReplyDelete
    Replies
    1. The custom .avrdudrc file above is no for the Gertboard, it is for my programmer, http://blog.stevemarple.co.uk/2013/02/rfm12b-shield-for-raspberry-pi.html That's why I said you need to adjust the numbers to suit your hardware.

      My board supports two programmers, one for the onboard ATmega328P and one external target, hence two different reset pins. The other pins are shared between both programmers and are only connected to the MCU only when programming a device.

      So your original problem, namely not having permission to connect to the GPIO, is solved. The Gertboard pins should be documented in the user manual.

      Delete
  11. You are being very patient with me. So I don't need the .avrduderc file?
    No permission error but I am still getting the rc=-1 error with

    1) avrdude set as -rwsr-sr-x 1 root root
    and running

    2) sudo -i

    3) avrdude -P gpio -c gpio -p atmega328p

    Many thanks for your persistence and patience.

    ReplyDelete
  12. created .avrduderc with correct GPIO pins defined but - alas no deal.

    ReplyDelete
  13. Excuse my ignorance but -- does this procedure work on an atmega328p chip that has previously been working in an Arduino Uno or does it require a completely virgin 'NEW' chip. If the latter, is it possible to re-initilaise the chip? I have 4 atmega328p chips that fail with rhe same rc=-1 error after re-installing the above on a new Pi.

    ReplyDelete
    Replies
    1. It shouldn't make any difference. What you need to watch for is that the fuses on a new IC will be set to use the internal RC oscillator. If you remove an IC from an Arduino it was probably programmed to use an external crystal.

      Delete
  14. Steve,
    Thanks for the great wrote up and samples! I have a PI setup with an integrated 328 (they are always connected together through the SPI bus). Avrdude works great to program the PI but when done programming the 328, the PI SPI bus is left in an unknown state and can no longer talk "normal" SPI without having to reboot the PI. Any thought on how to restore the SPI lines of the PI so as to avoid the PI reboot?

    Thanks.

    ReplyDelete
    Replies
    1. You could try using "gpio readall" before and after running avrdude to find out which pins have changed mode. You should make sure the pins you need are set to the appropriate mode before use and not rely on them being left in their default state.
      gpio is part of WiringPi, get it from http://wiringpi.com/download-and-install/.

      Delete
  15. Perfect help!! Did as you said and discovered that the SPI pins were left in INPUT state (original state was "ALT0" which I have no idea what that means). Anyway, my software does set the mode of all pins I directly touch but the SPI pins are controlled/read/written by the kernel SPI driver so I do not explicit modify either their mode or values... After running avrdude, the following 3 commands get the SPI pins back to a state where the kernel SPI driver plays nice with attached SPI devices without reboot:

    gpio mode 12 alt0
    gpio mode 13 alt0
    gpio mode 14 alt0

    Thanks again, great stuff you have posted! Greatly appreciated!

    ReplyDelete

Note: only a member of this blog may post a comment.