Friday, 30 May 2014

PCB layout for ATMega165 for electronic board game

Having designed a number of PCBs for different 64-pin chips, it was with some relief that we printed our latest design onto paper and got a perfect alignment with an ATMega165 chip


Of course, Thursday night is BuildBrighton night, so it didn't take long to get a etched PCB cranked out


Thankfully, the pins and pads lined up just as they did on the printed version (proving that the BuildBrighton laser cutter is, indeed, etching at 100% scale - not 99% or 101%, but bang on actual size!)


With the board etched we needed a way to program the chip before soldering it onto the board (because there wasn't room to add in ICSP headers on the actual PCB).


We decided to make an ICSP programmer using the same pins and pinouts as the ICSP header on a standard Arduino board.


To keep the chance of shorts to a minimum and to aid aligning the chip on the programmer, we took away a lot of the copper away from around the 64 pins.


Because the chip will be placed on the copper-side of the board, we had to solder the through-hole components on the "wrong side" of the board, so that the whole board can be placed on the tabletop without tipping or moving around (some self-adhesive cork on the back helps with this)


However, despite advice to the contrary, we haven't yet been able to compile even the simplest blinky-test project for our ATMega165 chips.

No matter how much we mess about with the boards.txt file, taking unused "boards" (chips) out of the list, and adding in our own descriptors, we simply can't get the ATMega165 to appear in the list of available boards


The nearest we got was to add in a zipped file of arduino-extras and ATMega165 appeared in the list - but trying to compile anything outside of the "standard" chips provided with the Arduino IDE resulted in a compile error and linker messages saying that numerous files could not be found.

Once again the curse of Arduino seems to have struck.
Just like using someone else's library of code, when it works, it works really well.
But when there's a problem, there are a hundred or more posts online describing similar symptoms, and a noticeable lack of solutions.

Steve spent a lot of time playing around and eventually found that an earlier version of the IDE would successfully compile (but was unable to actually upload) some code for the ATMega165. The current version of the Arduino IDE is 1.5 and Steve managed to get version 0.22 to compile code for the 64-pin chips. In the meantime,  I spent some time getting familiar with Atmel's official Atmel Studio 6.

Personally, I think that any desktop application built using .NET belies this by performing incredibly badly. And Atmel Studio is no exception. It's based on the .NET version of Visual Studio. The IDE takes an age to boot up, screen refreshing is slow and it feels worse than an open source app running in a virtual Java machine (cough, Open Office, Inkscrape, cough, GIMP, splutter). It's not a nice experience.

On the plus side, using nothing more than a bit of intuition, I managed to get some code compiling correctly in Atmel Studio 6 in very little time at all.


I spent some time writing my own Oshonsoft-a-like macros, for enabling and reading individual pins on a port - and found I'd recreated something very similar to the bit-level manipulations here: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=318198#318198

/*
* bit_functions.h
*
* Created: 30/05/2014 22:05:05
* Author: CHolden
*/

#ifndef BITFUNCTIONS_H_
#define BITFUNCTIONS_H_

#define LOW 0
#define HIGH 1

#define INPUT(port,pin) DDR ## port &= ~(1<<pin)
#define OUTPUT(port,pin) DDR ## port |= (1<<pin)
#define CLEAR(port,pin) PORT ## port &= ~(1<<pin)
#define LOW(port,pin) PORT ## port &= ~(1<<pin)
#define SET(port,pin) PORT ## port |= (1<<pin)
#define HIGH(port,pin) PORT ## port |= (1<<pin)
#define TOGGLE(port,pin) PORT ## port ^= (1<<pin)
#define READ(port,pin) (PIN ## port & (1<<pin))

#endif /* BITFUNCTIONS_H_ */


This allows functions to be used like:

HIGH (B, 4);

to set bit four of PORTB.
Similarly, we can use LOW(C,3) to turn a pin off, and even TOGGLE(A,2) to flip the state of bit two on PORTA.

Of course we could just use bitmasking and write values directly to the PORT values, but somehow, setting and unsetting individual pins just makes the code more readable!

So now we've got a programming board soldered up, and an IDE that can actually compile some code for our ATMega165 chips. We're two-out-of-three steps along the way already: the last step is to get the .hex file from the PC onto the AVR chip via our USBTiny.

Maybe the Arduino IDE doesn't want to play nice. And maybe the Atmel Studio doesn't support USBTiny straight out of the box. But there's always a chance that AVRDude and a few command line parameters might just do the job......