Tag Archives: programmer

Making my own USBasp programmer

I’ve been trying to make some for the last two weeks (yes, two weeks). I didn’t use the provided designs, that’s why it took so long: first, I wanted to get apprehended with the UNIX electronics CADs; then, as one should expect, I ran into design trouble of a layout that hasn’t been tested.

So here’s some valuable experience:

0) When developing with a crystal, make sure it’s the first thing you put near the IC! You need minimal distances, remember?

1) Design the PCB while looking at the schematic – you can actually see that C1 and C3 can be put very nicely near the USB connector (pins 1 and 4); R3 right next to it, too (pins 1 and 2); and some components “stick” naturally to the IC. This can be applied to other schematics.

2) check your schematic, not just the PCB. I’ve actually wasted the last week trying to pin-point the cause of a weird behaviour: the programmer can be programmed, the fuses can be set, it works as a stand-alone USB device (when no target is connected) and even when the target (a known-to-work USBasp) is connected, but not set to self-programming mode. As soon as it is (jumper 2 is set), the built USBasp starts to malfunction:

  • if the Brown-Out Detector is enabled (some other fuse combinations also apply), the power LED flickers, and the device is unrecognized;
  • under other configurations, the device simply does not power-on (the LED stays blank);

What I have found out is that I accidentally put JP2 in the wrong place: as you can see on the schematic, the wire that goes out of pin 5 of the ISP socket branches into one that joins the SS, and the other one that goes to ~RESET. Since I’ve redrawn my schematic, I accidentally put the jumper in the wire that goes with the SS.

Now, this has far-reaching complications. First off, this means that ~RESET is always connected to pin 5 of X2. Thus if the programmer is in slave mode (being programmed), the master controls ~RESET when it issues commands, and its +5V (through pin 2, VCCINT) influences the ~RESET through R6 (10K). Cumulatively, this provides the same conditions that would be seen in proper master-mode.

When such a USBasp is a master with no target, or the target is not set to self-programming (target’s JP2 disconnected), then master’s ~RESET is only influenced by the +5V, which comes from the USB. Also no problem here.

But when the target has JP2 set, you effectively have two programmers set to self-programming! This results in a race condition and also a loop, where master feeds the slave with VCCINT, which is then provided back to the master through pin 5 of X2 – and since master has its JP2 “shorted out”, it all effectively sets its ~RESET to +5V!

“Now, that’s pretty fucked up right here!” – you’re going to say; but, actually, this can be worked to an advantage. If you test your programmer on a known-to-work USBasp target, you will immediately notice such non-standart behaviour. If it was a normal target on the other end, you’d have an even bigger hell of a time finding what’s wrong than I did.

Not to mention you’d get a programmer that’s unable to reproduce itself.

3) If this is your first USBasp, build it of discreet components (and let teh ceiling cat be with you, ameh). This way you:

  • can change the IC easily if you misprogram the fuses (say, edit “hfuse” to “lfuse” in avrdude, move the cursor to change the fuse value, and accidentally press Enter instead of Backspace (doh!);
  • can use resistors to “jump” long distances over several lines you’ve already run;
  • know for sure what the values of the capacitors are (!).
  • don’t have to deal with SMT Zener diodes, which might only be available in MINIMELF packages.

4) Along the way, I also got to read some valuabl infoz on how AVR and USB get along.

Advertisements