Sunday, October 26, 2014

usbtinyisp source code update for modern AVR GCC

For those besides me who have downloaded the source code to the USB Tiny from AdaFruit, you'll note that on the download page it says you must use gcc-3.4.6 to build it. That's an antique.

I started down the road of patching the code so that it can be compiled by a modern AVR GCC and libc, but eventually discovered that someone had already done it.

I then went on to find the original home of the code. He has a 1.7 version of the code, but the pin assignments are different. The following patch makes it work with the USB ┬ÁISP up through the current version (0.4) (it should also work with the original AdaFruit USBTiny and the SparkFun pocket AVR programmer):

EDIT: Turns out the patch was unnecessary... I was trying to build from the 'spi' directory, but the correct place is the 'usbtinyisp' directory. That has the correct pin assignments and requires no modifications. Just 'make' and reflash. Joy!

Thursday, October 16, 2014

Learning more and more about AVR libc

Since I converted the crazy clock to straight AVR GCC, I've been learning more and more about the AVR libc.

Before, I had written my own delay_ms() method for the ticking, but in looking into the library-supplied _delay_ms(), I discovered enough that I've switched entirely over to using it.

In particular, as long as you call _delay_ms() with a value that's constant at compile-time, the actual assembler code that will be generated will be nothing more than the assembler equivalent of "for(i = 0; i < magic_value; i++) ;" The compiler will select the "magic_value" based on the F_CPU macro (which is the frequency of the clock in Hz) and the actual number of clock cycles that the compiler knows each instruction will require. In my case, the code actually shrank by a few bytes compared to my old code which watched the timer0 count (the old code was also problematic in that it would lock up if the counter overflowed during a delay). This is all despite the fact that the ostensible argument to _delay_ms() is a double. But as long as the value is a compile-time constant, the compiler will optimize away all of the floating point requirements and will figure out that it needs to delay a particular number of cycles, and will generate assembly code to do exactly that. Brilliant!

And if you just need to waste a certain number of cycles, then __builtin_avr_delay_cycles() will generate exactly the correct code. I believe this might be useful to simplify some of the bit-bang USB code in the usbtinyisp. That will need careful consideration...

Sunday, October 12, 2014

Initial crazy clock programming/test jig

I still can't bring myself to pull the trigger on a panel of crazy clocks. But in the meantime, I have decided to go ahead with a jig for at least single boards.

The concept is that the two ISP footprints are connected together, the two battery footprints are connected together and the clock footprint is connected to two inverse parallel LEDs. The battery, clock and ISP footprints that match up with the actual board will be populated with pogo pins. The extra battery jack will connect to a right-angle 1x2 header and the extra ISP footprint will connect to a right-angle 2x3 header. That will form the bottom board of the jig. The top board will have the two SMD LEDs mounted. The pogo pins will project out of the top, and there will be some rubber feet for stability on the bottom.

To use it, you connect an AVR programmer configured for a self-powered target to the 2x3 header and a single AA battery to the battery connector. You then hold a freshly manufactured board on top of the pins and press down (for hands-free operation, you could use a few ounces of weight - say a paperweight wrapped in electrical tape). You then use your other hand and press return on the Raspberry Pi that has the AVRDUDE operations scripted. If the programming steps work (and if the programmer is configured to not deliver target power), then that confirms that the boost converter works. At the end of programming, the two LEDs should start blinking in the correct sequence for the firmware that was loaded. That confirms that the firmware works and that the series resistors and flyback diodes aren't wired incorrectly.

Monday, October 6, 2014

DIY AVR ISP Pogo adapter

I've been using the SparkFun one for a while, but it's not absolute nirvana. In particular, I don't have any use for the molex connection or the JST power jack, and having the host jack be on the top makes it somewhat more awkward to hold.

So I came up with what I think is a better design.

You start with a very simple board with two 6 pin AVR ISP footprints. Be sure that the holes are 46 mils. Connect each pin on one to the matching pin on the other. Put two #4 holes on either side, insuring that you've got enough space so that the screw head won't abrade any of the traces.

Here's the OSH Park shared project for my design.

To make one adapter, you need two of these boards. You also need two 1/2" #4 bolts, two #4 nuts and two #4 1/4" standoffs. You'll also need 6 pogo pins and a 2x3 .1" right angle header.

Start by picking one of the boards to be the bottom board. Solder the right angle header into the ISP footprints that is not the one next to the writing that says "Pogo pin side." This is the side with the pins named.

Next, use 2 1/2" #4 bolts and nuts and a 1/4" #4 standoff to attach the two boards together, placing the one with the right-angle header on the bottom. It is critical to insure that the two boards are oriented the same way - both TOP sides up, and both facing the same direction. If you get this wrong, the adapter will be miswired.

Place some scotch tape on the top of the top board, covering all of the holes in the ISP footprint that is marked "Pogo pin side."

Flip the boards over and carefully insert the pogo pins into the holes, with the silverish, pointy ends up. Be very careful with this, as the pins are easy to bend (which will ruin them), and are a very, very snug fit (they're 40 mils wide, and the holes are ostensibly 46 mils wide). Make sure the ends of the pins come through the holes in the top board and rest against the tape. When all the pins are in place, the tops of the pins must be level.

Take a moment to check that the pins are square, straight and the tops are level. If the pins are racked at all, twist the boards relative to each other, loosening the hardware slightly if necessary.

When the pins are placed properly, solder them to the bottom board. Once that's done, remove the scotch tape from the top board and solder the tops of the pins to the top board.

And you're done!

Attach your programmer to the header, being sure to put pin 1 on the pin 1 end (you can look at the markings on the top board to figure that out). Orient the pogo pins so that the pin 1 marking on the board match the target. Press down slightly so that the springs put a little tension on the target, but not so much that the springs bottom out. Hold it there and do whatever needs doing.

Saturday, October 4, 2014

Recovering pooched ATTiny chips

I never thought I would resort to AVR HV programming to recover chips. I probably still am not going to do it for parts actually installed in-circuit. But I had one DIP Attiny85 handy and wanted to get it going again, and no combination of SPI clocking and various other tricks got it to answer.

So I decided to set down the road to see if it were reasonable to do just this once.

I found this page, which was the most helpful. It turns out, that if you just want to do a quick-n-dirty one-off, you don't need to go to quite as much trouble.

Here's what I did:

I loaded the sketch into my Uno. D9 goes to pin 2 of the target. D10 to pin 5, D11 to pin 6, D12 to pin 7, +5 to pin 8, GND to pin 4, and then I took my bench power supply and set it for 12 volts and applied that to pin 1 (with its ground also going to pin 4).

I opened the Arduino serial monitor, entered a character in the input line and it promptly reset the fuses to the factory default. Mischief managed.

Wednesday, October 1, 2014

Microcontroller panel programming jig for crazy clock

I'm considering making a whole pile of crazy clock retrofit boards.

Step 1 of that is panelizing the boards. This is a bit of a tricky operation in Eagle, as it involves breaking the normal synchronizing connection between the schematic and the board. You start by making a copy of just the .brd file for your design. Open the copy and modify it by replacing the box around the outside of the board with a series of disconnected lines, leaving a 100 mil section on each side that's not detached. Next, use the group tool to lasso a box around your entire circuit and use the clone tool to copy it, placing the copies in a grid. Once you're done with that, add another outline to the dimension layer to make a frame around your boards. The purpose for the space between the boards and the frame around the outside is twofold - to add structural integrity to the panel as a whole  and to space the boards a bit to aid in pick-n-place operations.

You'll notice that there are 10 holes around the edge of the panel. The purpose for those holes takes us to our next manufacturing step. Well, not quite. The crystal for the crazy clock is a through-hole part. Those have to be installed by hand individually. There's no escaping that, unfortunately. If you don't do it yourself, you've got to pay someone else to do it - it's not a step that can be easily automated.

The crazy clock is a microcontroller based product. Micro controllers come from the factory blank. Before they can do the work for which they're intended, they must be fused and programmed. The crazy clock board has an ISP footprint on the bottom for this purpose. But the job requires connecting a programmer to it long enough for it to talk to the controller and give it its programming.

Since so far the crazy clocks have been programmed to order, but if you're going to get 300 boards picked-and-placed en masse, you're not going to want to break the individual boards out and fuse and program them individually. Instead, you're going to want to make a jig to hit a bunch of them in a single step.

At first, I had a mental image of an ISP squid made of a 6 port USB hub, 6 USB AVR programmers, ISP cables and a pogo adapter. There just had to be a better way. And, indeed, there is. This guy has designed a combination of sketch and java code to make a standalone scripted AVR programmer. Hook it up, push the button and wait until the green LED lights up. Lather, rinse, repeat.

The only downside is that his reference design is based on an ATMega1284P. Since I'm programming ATTinys, I don't need such a huge chip to do the job. I'm going to adapt his code to use an ATMega328P instead.

And this takes us back to those holes. The holes are intended to fit over #4 bolts on the programming jig. Each pair of holes at the top and bottom will be used to align a 6 position programming jig to hit six of the controllers at once. Once the first six are done, you move the jig to the next hole and repeat the operation on those six. And so on.

While I'm at the programming, it'd be a really good opportunity to actually test the boards as well. There are two parts of the board that need testing - the boost converter and the controller and clock interface. The natural way to test the power supply is to have it actually power the whole thing while the programming is taking place. An ATMega master and at ATTiny slave during programming shouldn't require more than a few mA - well within the designed capabilities of the converter. And once the programming is finished, the sketch should start running, and pulses should start coming out of the clock terminals. Detecting those are a simple matter of a pair of LEDs mounted in opposed-polarity parallel. Each crazy clock board will individually power its own programmer. The only common connection between the boards will be the BATT connector supplying 1.5 volts to all 6 from a AA battery, and the GO pin coming from a switch mounted on the corner of the board to initiate the programming process.

OSH Park sells individual boards by the threes. This is ideal for pogo pin jigs, because you want to use two boards held a fixed distance apart to hold the pogo pins straight and parallel. The top board will be fully populated with all of the LEDs and controllers. The bottom board will get no parts other than the pogo pins coming through from the top. The two boards will be held together with 4 1/2" standoffs and 8 1/4" bolts.

Of course, you need to program the ATMega controllers before you can use the jig to program the ATTinys on the panel(s). Each ATMega will need its own ISP. You can't re-use the target connector because it's going to have pogo pins installed in it. Well, that, and the !RESET line isn't actually connected to the !RESET pin of the ATMega, but rather a GPIO pin so that the mega can assert it to force the tiny into the programming state.

So you connect a AA battery to the power input of the jig, then press the jig down on the panel and press the button. You should see the programming LEDs go from red to green, and then each of the pairs of test LEDs will start blinking in time with whatever pattern was loaded.