Burning sketch to ATMEGA328 (non-P)

I goofed and got a bunch of production boards made with an ATMEGA328 SMT chip instead of the usual 328P that stock Arduino boards use. I found this thread http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=922850 that makes it sound like there aren't a whole lot of functional differences between the two and the sketch should work, but my problem is getting the sketch onto the chip since AVRDude is complaining about the different chip signature. Based on what I have found, there seem to be three solutions: 1) use -F to get avrdude to ignore the signature, 2) edit the avrdude.conf file to add the new chip by copying the 328P info and changing the expected signature, or using a newer version of avrdude which appears to have support built in.

Unfortunately, I have been thwarted on each approach. I cannot figure out where I should be using the -F, avrdude throws an error saying that the 328 is not a valid board type, even after I changed the .conf file, and I'm not sure where to get a new version of avrdude/how to link it to the IDE.

My addition to the boards.txt file since I am using an USB ISP Tiny to upload without a boatloader:

ASF.name=ASF100-E001
ASF.upload.using=usbtinyisp
ASF.bootloader.low_fuses=0xff
ASF.bootloader.high_fuses=0xde
ASF.bootloader.extended_fuses=0x05
ASF.bootloader.path=optiboot
ASF.bootloader.file=optiboot_atmega328.hex
ASF.bootloader.unlock_bits=0x3F
ASF.bootloader.lock_bits=0x0F
ASF.build.mcu=atmega328
ASF.build.f_cpu=16000000L
ASF.build.core=arduino
ASF.build.variant=standard

And my addition to the avrdude.conf file:

# ATmega328
#------------------------------------------------------------

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";
    ;
;

There are two possible issues that I can identify with this approach - I did not add a device code at the top of the .conf file because I could not find one in the amtel document that it references. Also, one of the forum posts talks about copying a ATmega328P.xml file to a ATmega328.xml and making similar changes, but I could not find that file on my computer.

Any suggestions?

Thanks,
Scott

It is possible to force the normal ATmega328P bootloader into the ATmega328.
After that, uploading is not a problem. Using the RX and TX to upload a sketch makes the Arduino IDE think an ATmega328P is used, and no one ever knows that it is a ATmega328.

You could change the signature in boards.txt temporary to write the bootloader with the Arduino IDE. I don't know if that is enough. Perhaps you have to use a command line with avrdude.

Always use the newest Arduino software, at the moment version 1.0.5.

I'd edit the "Mega328" in avrdude.conf just while you burn the bootloader. Change

 "signature		= 0x1e 0x95 0x14;"

Into whatever numbers are shown when avrdude fails.

When you're finished, change it back again.

You don't really want to try to teach the whole arduino toolchain about the m328 as a separate processor. The compiler doesn't know about that chip (even though it's the same as a 328p), so you have this whole can of worms...

Instead, modify avrdude's config file so that it thinks the 328 is a 328p, and let everything else continue to think that you have a 328p.

Thanks for the responses so far!

I've gotten to the point where I can upload the bootloader and sketch to the 328 via ICSP, and when I connect with the USB2Serial board, I can send and receive information from the serial monitor. However, when I try to upload a new sketch via USB2Serial, I get the following error:

avrdude: Version 5.11, compiled on Sep  2 2011 at 19:38:36
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "C:\Program Files\arduino_1.0.3\hardware/tools/avr/etc/avrdude.conf"

         Using Port                    : \\.\COM13
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: Send: 0 [30]   [20] 
avrdude: Send: 0 [30]   [20] 
avrdude: Send: 0 [30]   [20] 
avrdude: Recv: . [00] 
avrdude: stk500_getsync(): not in sync: resp=0x00

Any ideas what might be happening? I usually see this when I mess up the wires connecting my board to the USB2Serial, but since the serial monitor is working fine, I'm a bit stumped. I'd love to get this method of uploading sketching to work so that I don't have to keep switching back and forth between the two modules while I'm trying to debug the code.

Thanks!

scottdrums89:
Thanks for the responses so far!

I've gotten to the point where I can upload the bootloader and sketch to the 328 via ICSP, and when I connect with the USB2Serial board, I can send and receive information from the serial monitor. However, when I try to upload a new sketch via USB2Serial, I get the following error:

avrdude: stk500_getsync(): not in sync: resp=0x00

Any ideas what might be happening? I usually see this when I mess up the wires connecting my board to the USB2Serial, but since the serial monitor is working fine, I'm a bit stumped. I'd love to get this method of uploading sketching to work so that I don't have to keep switching back and forth between the two modules while I'm trying to debug the code.

That means bad wires or bad baud rate.

Sketch works, bootloader doesn't. The logical conclusion is that the bootloader isn't setting the right baud rate.

I'm using the stock settings in all the IDE files except changing the signature ID for the 328P board to the one for the 328. Do the two chips require different baud rates?

Also, I'm noticing that when I upload a new sketch with the USB ISP that it seems to mess with/reset the EEPROM variables I have saved. Is this a usual occurrence?

scottdrums89:
I'm using the stock settings in all the IDE files except changing the signature ID for the 328P board to the one for the 328. Do the two chips require different baud rates?

The bootloader you burn has to match the clock speed of the chip. Either the chip's clock speed is wrong or you're not using the matching bootloader.

scottdrums89:
Also, I'm noticing that when I upload a new sketch with the USB ISP that it seems to mess with/reset the EEPROM variables I have saved. Is this a usual occurrence?

Yes.

You have to set a fuse bit to keep the EEPROM contents when the chip is reprogrammed. It's in the fuses section of the datasheet.

When I try uploading the program directly onto a new board without the bootloader, it ran very slow due to the clock speed not being set. If I upload the arduino bootloader and then reload the program, it runs at normal speed, which leads me to believe that the clock speed is then set correctly.

How do I match the bootloader? I'm using all the settings for the 328P which I'm under the impression should be exactly the same as the 328, except for the signature, unless someone has evidence to the contrary.

scottdrums89:
When I try uploading the program directly onto a new board without the bootloader, it ran very slow due to the clock speed not being set. If I upload the arduino bootloader and then reload the program, it runs at normal speed, which leads me to believe that the clock speed is then set correctly.

"Burn bootloader" does two things:
a) Set chip fuses for clock source.
b) Put a program in memory (the bootloader)

Step (a) is what fixed your program's speed problems. That doesn't mean that step (b) was correct, it's perfectly possible to put a 16MHz bootloader onto an 8MHz chip. Look for a folder called "bootloaders" in your Arduino installation to get an idea of how many different bootloaders there are.

I developed the sketch on a 16MHz Uno, I have it loaded on my first round of custom boards with 328P's at 16MHz running just fine, the new 328's are also running at 16MHz. While I understand what you're saying about different speeds causing issues, I'm not sure where one may have come from?

scottdrums89:
I developed the sketch on a 16MHz Uno

You compiled it yourself with (hopefully) a command line parameter of "DF_CPU=16000000L".

To check this, turn on verbose compiler output, compile "blink" and look at the command. If it says anything other than "16000000" (or the LED doesn't blink at 0.5Hz) then there's the problem.

scottdrums89:
While I understand what you're saying about different speeds causing issues, I'm not sure where one may have come from?

Did you compile the bootloader yourself or did you pick one from the dozens of precompiled files in the 'bootloader' folder?

If you didn't compile it yourself then maybe you picked the wrong one (you've been editing "boards.txt", right?)

I haven't done any sort of compiling on my own - I have been using the Arduino IDE for everything. First, I upload the bootloader - Tools->Programmer->USBtinyISP, then Tools->Burn Bootloader. This takes a couple minutes but seems to complete successfully. Then I upload my program - Tools->Board->ASF100-E001, then Upload. The ASF board is what I created in my first post, only difference is ASF.build.mcu=atmega328 is now back to ASF.build.mcu=atmega328P so it is an exact copy of the UNO board, with the exception of different name and ISP Programmer. Then atmega328P properties in avrdude.conf have been modified only to expect the different chip signature. The program uploads fine and runs as expected. I then remove the ISP programmer and connect the USB2Serial board. The 328 responds to commands and replies as expected. I then try to upload a sketch via the serial connection, using the standard Uno board option and the appropriate COM port, and get the error I mentioned earlier.

Is there a way to check that the bootloader is on the chip? I'm not the most familiar with how these things work, but is it possible that when I upload the sketch the first time over ISP, it is overwriting the bootloader programming, which would in turn make the chip ignore programming attempts from the USB2Serial?

scottdrums89:
Is there a way to check that the bootloader is on the chip? I'm not the most familiar with how these things work, but is it possible that when I upload the sketch the first time over ISP, it is overwriting the bootloader programming, which would in turn make the chip ignore programming attempts from the USB2Serial?

Yes, uploading a sketch via ISP will wipe the bootloader.