Current State of The ToyBrains

The fuse settings on the current device are low:0xe2, high:0xda, and extended:0x5. I can talk to it via ICSP, and get the correct component signature (0x1e9514) back. What all of this says to me is that the ICSP settings are correct, and the onboard oscillator is running, so the chip is capable of having the bootloader installed.

It is entirely likely that I was using the wrong bootloader for my boards. I am using an ATMega328 running at 8MHz, so I suspect that the correct bootloader is ATmegaBOOT_168_atmega328_pro_8MHz.hex. This is important because an bootloader created for the wrong clock speed can still be loaded onto a board, but won’t be able to communicate over the serial port. The timings of the serial signals would be messed up, because any delay operations will become either too long or too short, depending on if the clock is too slow or too fast.

I got the latest version of the Arduino IDE, and modified the appropriate files as described at the end of this entry. In order to burn the bootloader, I had to be root, so I started the Arduino IDE as root and burned the bootloader, which apparently worked on the first try.

I quit and restarted the IDE, because I didn’t want to keep running as root, and plugged in my FTDI cable. Unfortunately, the IDE couldn’t compile my little test program because the arduino IDE ships with an old version of avr-gcc (4.3.2) and the ATMega328 wasn’t supported until later. I have avr-gcc 4.5.3, so I renamed the avr folder in /arduino-1.0.5/hardware/tools to avr_old. This forces the IDE to use the system avr-gcc, because it can’t find its own. With this, I was able to compile.

Next, I attempted to upload the compiled program to the board. The upload failed with the error message “avrdude: stk500_recv(): programmer is not responding”.

I switched to using the programmer to upload the sketch, and wrote a sketch that blinks an LED on analog pin 5. Originally, the sketch used analog pin 7, because that’s where my debug LED is hooked up, but it turns out that while you can use A0-A5 as digital outputs, you can’t do that with A6 or A7.

At any rate, the system can now blink an LED on A5. This verifies that the onboard clock is working, that the memory can be written to, and that the compiler is generating valid code. The clock speed is even correct, because a blink program with a 1 second period even generates 1 second blinks.

Now I just need to figure out why uploading via USB/serial doesn’t work, and I’ll be golden.

I added this stanza to my boards.txt:

##############################################################

toybrain328.name=ToyBrain w/ ATmega328

toybrain328.upload.protocol=arduino
toybrain328.upload.maximum_size=30720
toybrain328.upload.speed=57600

toybrain328.bootloader.low_fuses=0xE2
toybrain328.bootloader.high_fuses=0xDA
toybrain328.bootloader.extended_fuses=0x05
toybrain328.bootloader.path=atmega
toybrain328.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
toybrain328.bootloader.unlock_bits=0x3F
toybrain328.bootloader.lock_bits=0x0F

toybrain328.build.mcu=atmega328
toybrain328.build.f_cpu=8000000L
toybrain328.build.core=arduino
toybrain328.build.variant=standard

##############################################################

And this section to my avrdude.conf:
#————————————————————
# ATmega328 NOT 328P, the only difference is the flags
#————————————————————

part
id = “m328”;
desc = “ATMEGA328”;
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
0x99, 0xF9, 0xBB, 0xAF;
stk500_devcode = 0x86;
# avr910_devcode = 0x;
signature = 0x1e 0x95 0x14;
pagel = 0xd7;
bs2 = 0xc2;
chip_erase_delay = 9000;
pgm_enable = “1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1”,
“x x x x x x x x x x x x x x x x”;

chip_erase = “1 0 1 0 1 1 0 0 1 0 0 x x x x x”,
“x x x x x x x x x x x x x x x x”;

timeout = 200;
stabdelay = 100;
cmdexedelay = 25;
synchloops = 32;
bytedelay = 0;
pollindex = 3;
pollvalue = 0x53;
predelay = 1;
postdelay = 1;
pollmethod = 1;

pp_controlstack =
0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
hventerstabdelay = 100;
progmodedelay = 0;
latchcycles = 5;
togglevtg = 1;
poweroffdelay = 15;
resetdelayms = 1;
resetdelayus = 0;
hvleavestabdelay = 15;
resetdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;

memory “eeprom”
paged = no;
page_size = 4;
size = 1024;
min_write_delay = 3600;
max_write_delay = 3600;
readback_p1 = 0xff;
readback_p2 = 0xff;
read = ” 1 0 1 0 0 0 0 0″,
” 0 0 0 x x x a9 a8″,
” a7 a6 a5 a4 a3 a2 a1 a0″,
” o o o o o o o o”;

write = ” 1 1 0 0 0 0 0 0″,
” 0 0 0 x x x a9 a8″,
” a7 a6 a5 a4 a3 a2 a1 a0″,
” i i i i i i i i”;

loadpage_lo = ” 1 1 0 0 0 0 0 1″,
” 0 0 0 0 0 0 0 0″,
” 0 0 0 0 0 0 a1 a0″,
” i i i i i i i i”;

writepage = ” 1 1 0 0 0 0 1 0″,
” 0 0 x x x x a9 a8″,
” a7 a6 a5 a4 a3 a2 0 0″,
” x x x x x x x x”;

mode = 0x41;
delay = 20;
blocksize = 4;
readsize = 256;
;

memory “flash”
paged = yes;
size = 32768;
page_size = 128;
num_pages = 256;
min_write_delay = 4500;
max_write_delay = 4500;
readback_p1 = 0xff;
readback_p2 = 0xff;
read_lo = ” 0 0 1 0 0 0 0 0″,
” 0 0 a13 a12 a11 a10 a9 a8″,
” a7 a6 a5 a4 a3 a2 a1 a0″,
” o o o o o o o o”;

read_hi = ” 0 0 1 0 1 0 0 0″,
” 0 0 a13 a12 a11 a10 a9 a8″,
” a7 a6 a5 a4 a3 a2 a1 a0″,
” o o o o o o o o”;

loadpage_lo = ” 0 1 0 0 0 0 0 0″,
” 0 0 0 x x x x x”,
” x x a5 a4 a3 a2 a1 a0″,
” i i i i i i i i”;

loadpage_hi = ” 0 1 0 0 1 0 0 0″,
” 0 0 0 x x x x x”,
” x x a5 a4 a3 a2 a1 a0″,
” i i i i i i i i”;

writepage = ” 0 1 0 0 1 1 0 0″,
” 0 0 a13 a12 a11 a10 a9 a8″,
” a7 a6 x x x x x x”,
” x x x x x x x x”;

mode = 0x41;
delay = 6;
blocksize = 128;
readsize = 256;

;

memory “lfuse”
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = “0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0”,
“x x x x x x x x o o o o o o o o”;

write = “1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0”,
“x x x x x x x x i i i i i i i i”;
;

memory “hfuse”
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = “0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0”,
“x x x x x x x x o o o o o o o o”;

write = “1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0”,
“x x x x x x x x i i i i i i i i”;
;

memory “efuse”
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = “0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0”,
“x x x x x x x x x x x x x o o o”;

write = “1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0”,
“x x x x x x x x x x x x x i i i”;
;

memory “lock”
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = “0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0”,
“x x x x x x x x x x o o o o o o”;

write = “1 0 1 0 1 1 0 0 1 1 1 x x x x x”,
“x x x x x x x x 1 1 i i i i i i”;
;

memory “calibration”
size = 1;
read = “0 0 1 1 1 0 0 0 0 0 0 x x x x x”,
“0 0 0 0 0 0 0 0 o o o o o o o o”;
;

memory “signature”
size = 3;
read = “0 0 1 1 0 0 0 0 0 0 0 x x x x x”,
“x x x x x x a1 a0 o o o o o o o o”;
;
;