Computing stuff tied to the physical world

Timing troubles with upload

In AVR, Hardware on Sep 22, 2012 at 00:01

Since the Raspberry Pi can now reset a JeeNode, I assumed that uploading would be a piece of cake. Hmmm… maybe not quite.

The trouble is timing, and I’m currently I was pulling my hair out on this one:

  • the plan is to reset the JeeNode and then have avrdude upload new code to it
  • this works automagically when opening a serial port causes DTR to go low
  • but here, we don’t have DTR or RTS, this is a basic serial port on GPIO pins
  • what we do have, is a GPIO pin 18 which can be pulled low to force a reset

At the moment, there seems to be a major problem with timing:


Here’s how to decode this screen shot:

  • the YELLOW line is serial from RPi to JeeNode
  • the BLUE line is serial from JeeNode to RPi
  • the MAGENTA line is the reset pulse on the GPIO pin

The way I test this, is via a shell script which first toggles reset using /sys/class/gpio/…, and then launches avrdude to perform the upload, using these commands:

echo 18 >/sys/class/gpio/export
echo out >/sys/class/gpio/gpio18/direction
echo 1 >/sys/class/gpio/gpio18/value
sleep 0.1
echo 0 >/sys/class/gpio/gpio18/value
avrdude -pm328p -carduino -P/dev/ttyAMA0 -D -Uflash:w:test.hex:i
echo 18 >/sys/class/gpio/unexport

Here’s what actually happens, I think:

  • the GPIO pin is correctly pulsed high and then dropped low after 0.1 s
  • the scope triggers on that falling edge, presumably same time as the ATmega resetting
  • after 323 ms, I see a 30 ┬Ás blip on the outgoing serial pin
  • after 674 ms, it looks like avrdude sends out it’s “0” wakeup character
  • after about 750 ms, the JeeNode starts sending the RFM12demo greeting
  • after 946 ms, the second “0” wakeup goes out
  • after 1197 ms, the third and final “0” goes out

In other words: it looks like avrdude is starting to send the 0’s too late! – and as a result, the JeeNode’s boot loader passes control to the sketch and never enters the upload cycle. After a few seconds, avrdude then gives up:

avrdude: ser_recv(): programmer is not responding

Note that reset and serial communication both work properly, as verified several times.

Trouble is, apart from redoing all in a single app, I see no way to reduce the startup time of avrdude. The SD card is perhaps not the fastest, but it’s no slouch either:

# hdparm -tT /dev/mmcblk0

 Timing cached reads:   248 MB in  2.00 seconds = 123.77 MB/sec
 Timing buffered disk reads:  50 MB in  3.05 seconds =  16.40 MB/sec

Is a reset + upload via GPIO not possible? I’m not giving up, but it sure ain’t workin’ yet!

Update – Problem solved, stay tuned for the explanation tomorrow…

  1. How about a ram disk? Will that give you that fraction of a second back?

    Also, which memory split are you running? There are a selection trading more or less with the GPU. Giving as much as you can to the CPU does speed things up at a cost of GPU functionality (I can’t play an h264 stream with the 224/32meg split).

    If you haven’t seen it, it’s very easy to change.

    For 192MB for the CPU and 64MB for the GPU:

    sudo cp /boot/arm192_start.elf /boot/start.elf

    For 224MB for the CPU and 32MB for the GPU:

    sudo cp /boot/arm224_start.elf /boot/start.elf

    For the default equal split of 128MB for both CPU & GPU:

    sudo cp /boot/arm128_start.elf /boot/start.elf

    Last but by no means least… There is the new image which dynamically ramps up the CPU speed when it’s required.

  2. Some months ago i too attached a jeenode to the serial port of a dlink dir-300 wifi router (cheapest openwrt box i could find on ebay), i don’t know the speed of the mtd device, but i had no trouble with avrdude timing. This is my flashing script:


    if [ -f "$1" ]; then

    gpioctl dirout 4

    gpioctl set 4

    gpioctl clear 4

    gpioctl dirin 4

    avrdude -P /dev/ttyS0 -c arduino -b 115200 -p m328p -U flash:w:"$1"


    picocom -b9600 /dev/ttyS0

    In case of timing troubles i would probably try some caching the avrdude executable or deferring the gpio trigger to a secondary script with its own delay. Now i’m curious about how you solved it!

  3. Lemme guess: The solution is releasing the reset line some time after starting avrdude in the background. That’s at least what I would have tried next.

  4. What about something like

    echo 18 >/sys/class/gpio/export
    echo out >/sys/class/gpio/gpio18/direction
    echo 1 >/sys/class/gpio/gpio18/value
    (sleep 0.1; echo 0 >/sys/class/gpio/gpio18/value)&
    avrdude -pm328p -carduino -P/dev/ttyAMA0 -D -Uflash:w:test.hex:i
    echo 18 >/sys/class/gpio/unexport

    So that avrdude is run “in parallel” with the reset, but being slower the reset completes first…

  5. I think there is a second serial port available with full modem leads.

Comments are closed.