Trouble with optiboot @ 20MHz

So I’m trying to use optiboot with a little project I’m doing. I currently have a atmega328p on a protoboard all hooked up with a 20MHz crystal and appropriate wires which I can use to hook it up to an Arduino board for programming. I have compiled optiboot for 20MHz using the source/toolchain/makefile provided with the Ardiono IDE. Using ArduinoISP I can flash this to my AVR on the protoboard just fine. The problem is though, I can not upload any programs to it through the serial port for some reason. I know, however, that the chip is running because when I press reset on the Arduino (avr taken out, hooked up to protoboard with wires) the pin 13 LED flashes just like it should on the bootloader reset. The weird thing is, if I flash the uno bootloader onto the protoboard and swap the crystal for a 16MHz one I am able to flash programs to the protoboard.

So I’m thinking that the problem is either optiboot when compiled for 20MHz, or its my 20MHz crystal. I don’t know how it could be the crystal, though, if I can burn the bootloader using it.

Try… 20/16*115200 = 144000 baud.

So I'm thinking that the problem is either optiboot when compiled for 20MHz

You probably did not properly modify the optiboot compile for 20MHz. Could you tell us exactly what you did, and post a log of the compilation step?

You might want to download (via mercurial) the latest version from http://code.google.com/p/optiboot/ Recent changes should make compiling "custom" versions much easier:

 [color=brown]make atmega328 AVR_FREQ=20000000L[/color]
BAUD RATE CHECK: Desired: 115200, Real: 113636, UBRRL = 21, Error=1.3%
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega328p -DF_CPU=20000000L  -DBAUD_RATE=115200 -DLED_START_FLASHES=3       -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega328p -DF_CPU=20000000L  -DBAUD_RATE=115200 -DLED_START_FLASHES=3     -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega328.elf optiboot.o 
avr-size optiboot_atmega328.elf
   text    data     bss     dec     hex filename
    482       0       0     482     1e2 optiboot_atmega328.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_atmega328.elf optiboot_atmega328.hex
avr-objdump -h -S optiboot_atmega328.elf > optiboot_atmega328.lst
rm optiboot.o optiboot_atmega328.elf

BAUD RATE CHECK: Desired: 115200, Real: 113636, UBRRL = 21, Error=1.3%

Is this calc ok? AVR baud rate calculator shows 56818 with UBRRL=21 @20MHz..

AVR baud rate calculator shows 56818 with UBRRL=21 @20MHz..

The bootloader always uses "double speed" mode.

What improvement the double speed mode does represent for us? You even need a more precise clock frequency..

..Note however that the Receiver will in this case only use half the number of samples ( reduced from 16 to 8 ) for data sampling and clock recovery, and therefore a more accurate baud rate setting and system clock are required when this mode is used..

If I compile the new optiboot using the methods suggested it still does not work. The IDE gets no response from the bootloader. If I set the baud to around 144000 then the bootloader responds but the upload doesn't work at all.

mre521: ...set the baud to around 144000...

"Around"? Did you set the baud rate to 144000 or not?

Hopefully you run it at 5V..

I tried setting the baud to 144000 and it did not work so I also tried 20/16 * 113636 = 142045

mre521: ...the bootloader responds...

What is the response?

Response is different it seems each time I try an upload. Here is one output from AVRDude:

         Programmer Type : Arduino
         Description     : Arduino
avrdude: Send: A [41] . [80]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv:   [20] 
avrdude: Recv: . [fc] 

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0xfc
avrdude: Send: A [41] . [81]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [05] 
avrdude: Recv: . [10] 
avrdude: Send: A [41] . [82]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [00] 
avrdude: Recv: . [fc] 

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0xfc
avrdude: Send: A [41] . [98]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [10] 
         Hardware Version: 1992330453
         Firmware Version: 5.-907346418
avrdude: Send: A [41] . [84]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [10] 
avrdude: Send: A [41] . [85]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [10] 
avrdude: Send: A [41] . [86]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [fc] 

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0xfc
avrdude: Send: A [41] . [87]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [fc] 

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0xfc
avrdude: Send: A [41] . [89]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [10] 
         Vtarget         : 0.3 V
         Varef           : 0.3 V
         Oscillator      : 1.372 Hz
         SCK period      : 3.3 us

avrdude: Send: A [41] . [81]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [05] 
avrdude: Recv: . [10] 
avrdude: Send: A [41] . [82]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [00] 
avrdude: Recv: . [10] 
avrdude: Send: B [42] . [86] . [00] . [00] . [01] . [01] . [01] . [01] . [03] . [ff] . [ff] . [ff] . [ff] . [00] . [80] . [04] . [00] . [00] . [00] . [80] . [00]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
avrdude: Send: P [50]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
avrdude: AVR device initialized and ready to accept instructions

Reading | avrdude: Send: u [75]   [20] 
avrdude: Recv: . [14] . [1e] e [65] . [08] . [fc] 

avrdude: arduino_read_sig_bytes(): (a) protocol error, expect=0x10, resp=0xfc
avrdude: error reading signature data for part "ATMEGA328P", rc=-3
avrdude: error reading signature data, rc=-1
avrdude: Send: Q [51]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 

avrdude done.  Thank you.

What improvement the double speed mode does represent for us?

Well, the chip gets significantly closer to the nominally desired 115200bps using double-speed mode (-2.1% error vs +3.7% error.) Then within the Arduino world is the fact that the xxU2 firmware uses double-speed mode for everything, and matching its speed is more important than being right. (Hmm. Except for 57600bps. Sigh.)

I guess it should be an option, huh? http://code.google.com/p/optiboot/issues/detail?id=81

fyi - normal v. double speed errors:

normal v. double speed errors

Really? That shows the double-speed error as ALWAYS being less than the normal error (for all the popular bit rates.) I didn't think that it was that straightforward...

fyi - the maximum recommended RX error for double speed mode is 0.5% less than for the normal mode.. PS: I've changed the error calc in the above table based on atmel's equation. PS1: based on that the following combinations seem to be safe: 20MHz 115k2 DS 16MHz 57k6 DS 8MHz 38k4 N (DS) 4MHz 38k4 DS

Hey I just tested uploading blink to the protoboarded avr (20MHz one) using the upload with programmer feature and it works fine. Then I tried the ascii table example and it also is able to send the table properly from the protoboard through the arduino to the computer with serial comms. So this seems to confirm for me that optiboot is what's problematic here.

Edit: just modified the asciitable sketch to use 115200 baud and it still works with no errors in the output...

You probably did not properly modify the optiboot compile for 20MHz. Could you tell us exactly what you did, and post a log of the compilation step?

Well I compiled it with this command

make atmega328 AVR_FREQ=20000000

in the optiboot (mercurial clone) directory

Output:

BAUD RATE CHECK: Desired: 115200, Real: 113636, UBRRL = 21, Error=1.3%
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega328p -DF_CPU=20000000  -DBAUD_RATE=115200 -DLED_START_FLASHES=3       -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega328p -DF_CPU=20000000  -DBAUD_RATE=115200 -DLED_START_FLASHES=3     -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega328.elf optiboot.o 
avr-size optiboot_atmega328.elf
   text       data        bss       dec       hex   filename
    482         0        0      482       1e2   optiboot_atmega328.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_atmega328.elf optiboot_atmega328.hex
avr-objdump -h -S optiboot_atmega328.elf > optiboot_atmega328.lst
rm optiboot.o optiboot_atmega328.elf

Then burn it with:

make atmega328_isp

The bootloader flashes the 'L' led on reset so the burn worked but upload always fails. also, boards.txt:

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

atmega328_20.name=atmega328p @ 20MHz
atmega328_20.upload.protocol=arduino
atmega328_20.upload.maximum_size=32256
atmega328_20.upload.speed=115200
atmega328_20.bootloader.low_fuses=0xff
atmega328_20.bootloader.high_fuses=0xde
atmega328_20.bootloader.extended_fuses=0x05
atmega328_20.bootloader.path=optiboot
atmega328_20.bootloader.file=optiboot_atmega328_20MHz.hex
atmega328_20.bootloader.unlock_bits=0x3F
atmega328_20.bootloader.lock_bits=0x0F
atmega328_20.build.mcu=atmega328p
atmega328_20.build.f_cpu=20000000L
atmega328_20.build.core=arduino
atmega328_20.build.variant=standard

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

Then burn it with: make atmega328_isp

Ah. There's the problem! The second make will (probably?) re-build from the source, using the default avr_freq value. Do it all at once:

    make atmega328_isp AVR_FREQ=20000000

I can't decide whether I consider the behavior you found to be a bug in the optiboot makefile, or not. On the one hand, I'm considering it a feature that the actual compile happens more often; having .hex files sitting around with who-knows-what options compiled in would be dangerous. On the other hand, having the ISP build undo the option violates the "rule of least surprise." :-(