Computing stuff tied to the physical world

Upload to JeeNode fixed

In Hardware, Linux on Sep 23, 2012 at 00:01

Ok, I finally figured out what caused yesterday’s upload problem. It’s indeed timing.

But not quite as I thought, and I missed a hint in the scope signal capture yesterday (at 322 ms after the reset). My premature conclusion was that resetting the GPIO pin and then starting up avrdude was taking too long, so the boot loader would give up before receiving the proper starting character over the serial line.

But that doesn’t quite make sense. Looking at the screen shot again, we can see that the RF12demo greeting (blue line) starts about 800 ms after the RESET pin gets pulled low. Even though OptiBoot is supposed to wait a full second after power-up. And there are two handshake attempts well within that period.

The other subtle hint was in the not-quite-equidistant characters being sent out (yellow line). Why would handshake chars be sent out in such a repeatable yet irregular pattern?

Having written an avrdude replacement in Tcl for some experiments I did with JeeMon a while back, I decided to try and extend it a bit to toggle the reset pin right before sending out the data. That way no delay would interfere, so the reset would happen moments (probably mere milliseconds) before starting the boot loader serial handshake. I didn’t really want to start hacking on avrdude for such a “simple” task as toggling a GPIO pin on the Raspberry Pi. Besides, that replacement code is only 70 lines of Tcl, if all you have to deal with is the basic stk500 protocol understood by the boot loader.

Controlling the GPIO pin also turned out to be pretty straightforward:

Screen Shot 2012 09 20 at 23 59 50

But no matter what I tried, and no matter what timing delays I inserted, the darn thing just wouldn’t upload!

Then, just for the heck of it, I tried this variation – reversing the open and reset order:

Screen Shot 2012 09 21 at 00 01 18

And lo and behold – now it works: repeatedly and reliably!

Here’s the scope’s serial protocol analyser, showing a proper upload in progress:

SCR32

You can see data being sent to the JeeNode, and the 0x14h reply sent back to the RPi.

So was this all about timing? Yes and no. Let’s revisit yesterday’s list of pulses again:

Screen Shot 2012 09 21 at 00 06 02

A single pulse 322 ms after reset, and then several pulses at 673 ms (presumably the first boot loader protocol handshake character). The problem is really that first pulse – it’s not a valid character but a glitch!

What I think is happening is that the JeeNode resets, the glitch at 322 ms causes the boot loader to give up and launch the sketch, and then all subsequent boot handshake characters get ignored. Looks like opening the serial port produces a glitch on the transmit output pin.

By first opening the serial port and then doing the GPIO18 reset, the problem is avoided, and then it all works.

Thank you JeeMon – I hadn’t expected to fire you up again, but you’ve saved my day!

  1. Glad to hear it is working. BTW, I have to admire that scope of yours! Apropos of nothing, the latest R-Pi software update enables an internal processor temperature sensor. It has only 0.5 C granularity, but it is still kind of neat. With the processor mostly idle, it tracks ambient temperature pretty well.

    /opt/vc/bin/vcgencmd measure_temp

    temp=44.9’C

  2. 44.9 ambient? where in the world are you?!!

  3. Hi JC I understand you solved the issue with JeeMon, your own TCL implementation. But any hints on how to reach the same result with AVRdude ? Shall we hack its code ?

    • Well, now that the issue is understood, that would certainly be an option.

      I’ve never understood why you need a swiss army knife when preparing the same simple meal year in year out… all we use is part of the stk500 upload protocol. But more importantly: why implement something like this in C, when scripting makes it portable, smaller, and easier to understand and tweak? (Tcl is just an example here)

    • Hi JC

      I am trying to use ATmega with Linux based platform that are much smaller than RPi such as an OpenWRT-hacked WR703N. Installing consumming interpreted language is not (IMHO) an option and I prefer considering compiled stuff in that case. Why are we using ATmega in C instead of BASIC ? :)

    • interpreted language is not (IMHO) an option

      I respectfully disagree. Lua has LuaJIT, which transforms a Lua script to machine language (sort of). It cannot do miracles, but the performance gains can definitely make it suitable for running on embedded Linux hardware (which is often running ARM at over 300 MHz).

  4. 44.9′C? Basking on a bed of silicon I guess. Pass the suntan oil ;-)

  5. Interesting observation. There is a built in conundrum to unwind from using unbuffered GPIO pins for a TTL’ish asych port. Unlike control signals (e.g. RTS), TXD/RXD use inverted logic. Meaning the idle state needs a logic high (spacing) and kicking off a character needs a start bit asserted at logic low (marking).

    Starting from an unpowered board – no volts anywhere implies TXD is in continuous mark (Depending on the receiver attached, this may get detected correctly or result in a stream of false character-received interrupts). Somewhere between power on reset and preparing for sending the first real character from the internal UART function, TXD needs to go to logic high to establish a continuous space condition.

    This is a multistep process and the Broadcom documentation specifically warns about preparing the GPIO pins before initialising the UART function. I guess somewhere along that path, the steps are not quite right at device driver level, resulting in the mark ‘blip’ on opening the channel. It would be interesting to see if the width of the blip depends on the Raspi CPU clock rate – giving a clue to how wide that window is open.

    This may well be the first well-documented observation of the glitch – less critical use of the port would simply ignore it as incorrectly framed or trash the DEL character erroneously interpreted.

  6. Ambient here is about 25 C, that command reports the silicon die temperature which is about +20C from ambient (or more, if a big program is running)

  7. Even if there is a ‘blip’ on the serial line, shouldn’t the bootloader just simply ignore malformed characters? Or is this blip not generating a framing error on reception?

    • Alas not – 30 µs low pulse is a valid character (start bit plus 1 or 2 0 bits, then all 1’s).

  8. Is anyone aware of the default state of Pi’s GPIO pins upon boot up? Unless it is HIGH, we will be stuck in reset until the pins are initialized, that is a bit of setback.

  9. I can also verify that they are all high-impedance on startup as well. For my application I decided to skip the dodgy business of trying to time the reset properly as well, due to the variable startup time of avrdude depending on the condition of avrdude.conf being in the file cache or not. I just hooked the ATmega/RFM12 onto the Raspberry Pi’s SPI bus and program them directly at up to 4MHz. I can program about 10KB/sec and verify at about 15KB/sec. After programming, I return all the SPI lines to high-impedance and the ATmega is able to be the SPI master to communicate with the RFM12 again. Works perfectly and I even have a web interface to upload new ATmega code. Programmer source is in the HeaterMeter github (serial is for another platform, not rPi): https://github.com/CapnBry/HeaterMeter/blob/master/openwrt/package/linkmeter/src/hmdude.c

  10. @CapnBry, excellent solution!

  11. @JCW, do you intend to publish your tcl implementation to upload? Is is a via solution long term, or is a modified avrdude the way to go do you think?

Comments are closed.