USBtinyISP can't write to ATmega168 flash

USB AVR Programmer and SPI interface. Adafruit's USBtinyISP.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
mrcity
 
Posts: 8
Joined: Mon May 20, 2013 8:05 pm

USBtinyISP can't write to ATmega168 flash

Post by mrcity »

Hi everyone,

I'm trying to use the ATmega168-A chip in TQFP form, soldered onto a custom board allowing for programming via MISO/MOSI/SCK (to install the bootloader) and TX/RX (once the bootloader is installed). I'm looking to rely on the chip's internal clock, and have set up my fuses as such:

Low: 0xe2 (8MHz internal clock, not divided by 8 internally)
High: 0xdf (SPI enabled, no brownout detection)
Extended: 0x0 (1024-word bootloader section at 0x3800 bytes, with boot reset vector enabled)
Lock: 0x3f (no lock features enabled)

I compiled the Optiboot bootloader with the settings

atmega168: TARGET = atmega168
atmega168: MCU_TARGET = atmega168
atmega168: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=115200'
atmega168: AVR_FREQ = 8000000L
atmega168: $(PROGRAM)_atmega168.hex
atmega168: $(PROGRAM)_atmega168.lst

This way, the bootloader was small enough to fit in memory without any problems. It does indeed fit fine on the chip, and running the command

sudo avrdude -c usbtiny -p m168 -e -B 1 -D -U flash:w:optiboot_atmega168.hex:i

indicates that the operation was successful. From everything I can tell, it's installed the bootloader correctly. However, when I try to run a similar command in order to install the sketch I'd like to run on the chip,

sudo avrdude -c usbtiny -p m168 -D -U flash:w:blink.cpp.hex

(Not necessarily the Blink sketch, but the end result is the same) it just doesn't even show any sign of life when it comes to uploading to the flash, staying at 0% for as long as I care to keep avrdude running:

Code: Select all

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9406
avrdude: reading input file "Blink.cpp.hex"
avrdude: writing flash (1108 bytes):

Writing |                                                    | 0% 0.00s
I've attempted to use the USBtinyISP as well as the Sparkfun FTDI breakout board (which worked previously on my TQFP 328's) and I get the same result. In order to isolate any potential points of failure, I'd like to stick with using the USBtinyISP for all my programming.

Later on, I set my fuse setting to 0xA2 (previous setting + clock output on PORTB0) and verified the chip does indeed output 8.33MHz from that pin, according to my scope, once you apply power & ground. (Goes to show you these internal clocks have a high tolerance range.) The chip must be alive as I can get the clock and can write to 0x3800, but I just can't write to 0x0000.

Any thoughts?

Thanks,
Stephen

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: USBtinyISP can't write to ATmega168 flash

Post by adafruit_support_rick »

Hi - just to let you know we're cogitating about this…
We'll get back to you in a bit.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: USBtinyISP can't write to ATmega168 flash

Post by adafruit_support_rick »

mrcity wrote:The chip must be alive as I can get the clock and can write to 0x3800
0x3800? That's the start address for the 2K boot section on an ATMega328.

You've got a 168, and your High fuse setting of 0xdf configures it for a 128-word boot section starting at 0x1F80.
See "Table 27-10. Boot Size Configuration, ATmega168A/168PA". It's on page 281 in the datasheet I'm looking at.
mrcity wrote:(Goes to show you these internal clocks have a high tolerance range.)
The internal clock is designed to be calibrated:
9.6 Calibrated Internal RC Oscillator
By default, the Internal RC Oscillator provides an approximate 8.0MHz clock. Though voltage and temperature dependent, this clock can be very accurately calibrated by the user. See Table 29-10 on page 309 for more details.

mrcity
 
Posts: 8
Joined: Mon May 20, 2013 8:05 pm

Re: USBtinyISP can't write to ATmega168 flash

Post by mrcity »

Hi Rick,

The difference between 0x3800 and 0x1C00 is that the former is in bytes and the latter is in words. The spec makes references to addresses in words, but the bootloader hex refers to byte addresses. This did raise an interesting point, as I observed my bootloader code wasn't writing to anything before 0x3E00 bytes (per the Intel hex). I adjusted my avr-gcc compiler options so it'd start the bootloader at 0x3800, but unfortunately that didn't fix anything.

The way I see it, the Extended fuse setting actually governs the size & position of the bootloader. Table 28-5 indicates the default value of the efuse (0xF9, but the top 5 bits don't do anything) results in the maximum boot size. Functionally, setting the efuse to 0x01 should be equivalent to 0xF9 because I've read the 0x01 value from brand-new ATmega168 chips using avrdude. Also, the fuses are weird since 1 = unprogrammed & 0 = programmed. The bootloader is ~1.4KB in size, even as an Intel hex file, so it's below the 2KB limit. I've tried writing bootloaders that are too big and trust me, it fails loudly. ;)

Also, thanks for the hint on calibrating the internal clock. Even though the application only calls for 9600-baud serial for now, it'll still help increase the reliability (and eventually I would like to try a faster data rate).

I can send you any of my Optiboot bootloader-related files (.c, .hex, Makefile) if it'd help. Most of it's stock except where I tampered with the chip frequency setting & LED light flashes in the Makefile. Also, just for the record, I managed to get a response (albeit incorrect) over serial at 19200 baud when using the Arduino Lilypad bootloader for ATmega168. Nothing else has even gotten that close to writing to the flash. Not sure what makes that one so special...

Thanks,
Stephen

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: USBtinyISP can't write to ATmega168 flash

Post by adafruit_support_rick »

Great Scott! I haven't seen a reference to a 16-bit word since I bid a tearful farewell to the PDP-11. What's Atmel going to zing me with next? Octal? :shock:

Alright then, try it without the -D option. You can't program the flash if you disable the erase.

Code: Select all

sudo avrdude -c usbtiny -p m168 -U flash:w:blink.cpp.hex
(note that the command you posted for writing optiboot also has the -e option, which apparently takes precedence)

mrcity
 
Posts: 8
Joined: Mon May 20, 2013 8:05 pm

Re: USBtinyISP can't write to ATmega168 flash

Post by mrcity »

Hate to tell you, but omitting -D didn't solve the problem. :? I took a look at the arguments the Arduino IDE passes to avrdude when you hit Upload, and basically it looks like this:

Code: Select all

avrdude -C avrdude.conf -patmega168 -cstk500v1 -P\\.\COM12 -b19200 -D -Uflash:blink.cpp.hex:i 
I was under the impression that wiping the flash would also wipe the bootloader. I set the fuse bit to 0x0F ahead of this (so as to hopefully not erase the bootloader) and still no go either way, with or without the -D. I'm starting to suspect it's something with my chips; everything else seems right, or else I'm overlooking something very small!

Anyway I'm going to be out of town this coming week and won't be taking this project with me, so I'll pick it back up in about 7 days or so. Thanks!

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: USBtinyISP can't write to ATmega168 flash

Post by adafruit_support_rick »

You might also try playing with the -B (bit-clock) command, as discussed in our USBTinyISP tutorial.

We have a general AVR programming tutorial - maybe you can spot a clue in there. That contains an avrdude section, as well.

User avatar
westfw
 
Posts: 2008
Joined: Fri Apr 27, 2007 1:01 pm

Re: USBtinyISP can't write to ATmega168 flash

Post by westfw »

Extended: 0x0 (1024-word bootloader section at 0x3800 bytes, with boot reset vector enabled)
Optiboot is only 256-words, not 1024 words.
I compiled the Optiboot bootloader with the settings
atmega168: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=115200'
atmega168: AVR_FREQ = 8000000L
Also, optiboot is widely reported to be unable to support 115200bps uploads when running at 8MHz.
http://code.google.com/p/optiboot/issues/detail?id=58

And finally, there's little point in burning the bootloader if you're going to use USBTinyISP to upload your sketches. In order to erase the previous sketch, ISP programming will need to do a full "chip erase" command (ISP programming doesn't have an "erase page" command!) That means that the very first sketch uploaded using -D (disable auto-erase) after the bootloader burn might work, but any subsequent attempts should fail during verification.

Alas, none of these explain why your attempts at programming a sketch with USBTiny would hang...

mrcity
 
Posts: 8
Joined: Mon May 20, 2013 8:05 pm

Re: USBtinyISP can't write to ATmega168 flash

Post by mrcity »

Hi, I'm back from vacation and started looking at this again. I've tried various -B options (namely 1, 5, 50, and 500), and still no dice. I've pretty much given up on options for avrdude and am looking toward compiler options for avr-gcc or avr-g++. I'm going to compile Optiboot & my sketch manually with something like this, from https://www.mainframe.cx/~ckuethe/avr-c-tutorial/:

Code: Select all

avr-gcc -g -mmcu=atmega644p -c blinkprint.c -Wa,-alh,-L -o blinkprint.o > blinkprint.asm
avr-gcc -g -mmcu=atmega644p -Wl,-Map,blinkprint.map -o blinkprint.elf blinkprint.o
avr-objdump -h -S blinkprint.elf > blinkprint.lst
avr-objcopy -j .text -j .data -O ihex blinkprint.elf blinkprint.hex
avr-size blinkprint.elf
avrdude -c usbtiny -p atmega644p -U flash:w:blinkprint.hex
Loading the bootloader with the USBtiny and then loading the sketch via serial (FTDI) would be the most ideal route. Ultimately I'd like the chips to still be programmable with an Arduino once the bootloader is installed.

Also westfw, do you happen to be one of the developers of optiboot? :wink: Thanks for the suggestions. I counted up the bytes listed as actual data in the Intel hex, and my custom-compiled Optiboot is truly 504 bytes, just under 256 words. That'll help me save some space for the program. Setting the compiler option for allowing LED flashes on pin 13 increased its size, so I took that out. I'll need to include any compiler settings that specify using the 8MHz internal clock.

Thanks,
Stephen

mrcity
 
Posts: 8
Joined: Mon May 20, 2013 8:05 pm

Re: USBtinyISP can't write to ATmega168 flash

Post by mrcity »

Success!

Wish I could explain this, but somehow throwing away all the work I did compiling my own versions of avrdude & avr-gcc and everything else, and simply using the tools that come with Arduino IDE 1.04, did the trick. I added this into my boards.txt file:

Code: Select all

##############################################################
 
usbtiny168.name=[usbtinyisp]ATmega168
 
usbtiny168.upload.using=usbtinyisp
usbtiny168.upload.maximum_size=14336
 
usbtiny168.build.mcu=atmega168
usbtiny168.build.f_cpu=8000000L
usbtiny168.build.core=arduino
And upon switching the "Board" to "[usbtinyisp]ATmega168" and hitting Upload, the Arduino IDE issued the following command:

Code: Select all

/home/stephen/Downloads/arduino-1.0.4/hardware/tools/avrdude -C/home/stephen/Downloads/arduino-1.0.4/hardware/tools/avrdude.conf -v -v -v -v -patmega168 -cusbtiny -Uflash:w:/tmp/build671983137556185092.tmp/blink.cpp.hex:i
Then I tried the same command without -C using the default avrdude (which avrdude says it's in /usr/local/bin/avrdude) and it didn't work. It must be something in that .conf file that pushed it to do the right thing! Now to see if I can load the bootloader with this mechanism and then actually load the sketch through the TX/RX pins.

I have designed my own custom board which two TQFP ATmega168s are soldered onto. I thought maybe one was interfering with the other somehow (since they share common TX & RX traces), so I soldered just one chip and that didn't help. Luckily the Google query "usbtiny program sketch" led me to this site http://www.fettesps.com/arduino-and-the-usbtinyisp/, which divulged the details.

Now to find out the difference between my home-brew toolchain and the Arduino toolchain...

Thanks,
Stephen

mrcity
 
Posts: 8
Joined: Mon May 20, 2013 8:05 pm

Re: USBtinyISP can't write to ATmega168 flash

Post by mrcity »

So to bring final closure to my problem of "couldn't write the bootloader to the chip" and "couldn't write any sketch to the chip once it was on there", I'd like to share a solution that's even better than what I stumbled upon earlier. I tried playing around a whole bunch with various bootloaders, but wasn't ever able to build any for myself. I even built the latest version of avrdude on an old Linux machine because the one that comes with the Arduino IDE is so old. Finally, I tried installing the bootloader for the Arduino Lilypad (which happened to use an ATmega168 on an external clock). This bootloader is included with the Arduino IDE. In a similar manner as above, I checked the config file where it lists this board type to make sure the fuses & clock were set correctly. IIRC, the defaults are already correct; just make sure the clock is set at 8MHz. Once I burned this Lilypad bootloader to my ATmega168 TQFP chips, I was able to load sketches onto the chip even using the "Arduino To Breadboard" method detailed on their website.

As such, this experimentation, knowledge, and finally getting it to work enabled me to launch a Kickstarter for this product: http://www.kickstarter.com/projects/558452768/ledgoes Take a look, and enjoy!

I hope this helps anyone else looking to use an ATmega168 with a bootloader,

Stephen

Locked
Please be positive and constructive with your questions and comments.

Return to “USBtinyISP”