I've been putting a lot of thought into how to fix this, since AVR programmers aren't cheap (cheapest is the USBtinyISP at $22). The thing to do is borrow someone else's, since it's only needed to burn the bootloader, which handles reprogramming it from there on. The problem is that I only know one other person who has any kind of an interest in microcontrollers, and he just bought his first Arduino over winter break, so borrowing a programmer isn't going to happen.
Another one of my friends then gave me a miniPOV 3 kit that he had been given and no longer wanted, and that gave me an idea. The only difference between programming the ATtiny2313V on the miniPOV, and programming an ATmega168 from an Arduino is the pinout. They both use the same SPI protocol to appear as a slave flash storage device to the programmer.
The miniPOV has a DASA programmer built into it, which means it hooks up to a serial port, and then in software on the computer you bit-bang out the SPI protocol to talk to the AVR on the POV board. Retargeting this programmer for an ATmega would be relatively easy: Connect the correct six pins for SPI, and change the Makefile that comes with the bootloader source to use DASA instead of the STK500 programmer that it's expecting.
Figuring out the correct pinout is simply a matter of reading the datasheet for the ATtiny2313 and the ATmega168, and jumper the six pins needed to program it. It's six pins because, beyond the three needed for the SPI protocol itself, you also need a forth line for slave select, since SPI has no addressing system like I2C, and two more lines for power and ground. For the following list, connect the first number's pin from the IC socket on the miniPOV to the second number's pin on the ATmega, so the 20th pin on the 2313 is power, where it is pin 7 on the 168.
- VCC 20 → 7
- GND 10 → 22
- SCL (Serial Clock) 19 → 19
- MISO (Master In Slave Out) 18 → 18
- MOSI (Master Out Slave In) 17 → 17
- RESET (Which acts as the Slave Select pin for accessing the flash) 1 → 1
The majority of the software battle is just getting the environment setup (AVRDUDE, GCC, Make, etc). If I remember correctly, this was relatively simple, following the directions on the miniPOV site.
The source for the bootloader is shipped with the Arduino environment under arduino\hardware\bootloaders\atmega. Open the Makefile in a text editor, and change the following lines (which are about 20 lines into the file).
# enter the parameters for the avrdude isp tool ISPTOOL = dasa ISPPORT = com6 ISPSPEED =DASA is the type of programmer which we are using (Serial bit-bang), and com6 is the serial port that my USB → Serial adapter happened to show up as. You'll need to figure out which com port you're using and change accordingly. I didn't know what to put for the speed, so I left it blank, and it defaulted to something functional, if painfully slow.
Once everything is hooked up, you're ready to play with fire. Open a command prompt in the atmega bootloader folder, type
make diecimila_isp, and sit back and enjoy the next TWO HOURS (!!!) as it ever so carefully writes the 16kBs of flash on the ATmega.
But hey, two hours is two hours I would have wasted otherwise doing something silly like try and hang out with real life people or do homework, and you only need to do this once before you can start reprogramming it just using the Arduino board, so in the end, it's not that bad.
In the end, I now have a second Arduino for the cost of an ATmega 168 ($4.32), a crystal (50 cents), a few caps, and whatever other parts I need for the current project, without having to buy a real AVR programmer. Happy hacking.