Using Arduino Uno R3 to bootload the atmega328-PU (non pico)

Hi Everybody,

I have just purchased the Arduino Uno R3 in South Africa and we don't have any stores the sell an ISP programmer, and to make things worse no Sparkfun or Adafruit products are sold in my city so I don't have many options (not very helpful I know).

Now here's my dilemma, I am constructing two barebones arduino's based on the RBBB (really bare bones board) design (which we don't get here either so I resorted to constructing them myself). But I could only get hold of blank Atmega328-pu chips not the pico power version!

So I am in desperate need of bootloading these chips with the UNO bootloader, I am aware (after reading through the forums) of the fact that the signatures for the Atmega328-PU and Atmega328P-PU are different. So I have followed several tutorials for using the Arduino as an ISP programmer with no success. I followed this tutorial Gammon Forum : Electronics : Microprocessors : Atmega bootloader programmer hoping to get it to work with the Atmega328-PU but I am assuming that it only works with the Atmega328P-PU chip.

I even tried altering avrdude.conf and boards.txt as suggested in this thread Arduino Forum

avrdude.conf

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

boards.txt

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

uno328.name=Arduino Uno w/ ATmega328 (non-P)
uno328.upload.protocol=arduino
uno328.upload.maximum_size=32256
uno328.upload.speed=115200
uno328.bootloader.low_fuses=0xff
uno328.bootloader.high_fuses=0xde
uno328.bootloader.extended_fuses=0x05
uno328.bootloader.path=optiboot
uno328.bootloader.file=optiboot_atmega328.hex
uno328.bootloader.unlock_bits=0x3F
uno328.bootloader.lock_bits=0x0F
uno328.build.mcu=atmega328
uno328.build.f_cpu=16000000L
uno328.build.core=arduino
uno328.build.variant=standard

I then proceeded to unzip and upload this sketch: Atmega_Board_Programmer.zip to my UNO R3 (the programmer), found in this tutorial Gammon Forum : Electronics : Microprocessors : Atmega bootloader programmer, I then hooked up all the pins as shown in the image for (Programming a RBB (really bare bones board)).

I then built and wired up a simplified breadboarded version as my setup of choice as seen below:

Then in Arduino 1.0.2, I selected Tools->Board->Arduino Uno w/ ATmega328 (non-P), next I selected my serial port my UNO R3 is connected to and finally I selected the programmer as Arduino as ISP and then tried to burn the bootloader but received the following error:

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

So checking through the code for the Atmega_Board_Programmer sketch, I don't see support for Atmega328-PU

I then tried the ArduinoISP sketch and followed the tutorial here: http://arduino.cc/en/Tutorial/ArduinoToBreadboard knowing that I should be using a Arduino Duemilanove or Nano w/ ATmega328, but I gave it a bash anyway by selecting Tools->Board->Arduino Uno w/ ATmega328 (non-P), then setting my serial port for my UNO R3 and then selecting the programmer as Arduino as ISP, then tried to burn the bootloader and received the following error:

avrdude.exe: stk500_program_enable(): protocol error, expect=0x14, resp=0x50
avrdude.exe: initialization failed, rc=-1;
                   Double check connections and try again, or use -F ...
avrdude.exe: stk500_disable(): protocol error, expect=0x14, resp=0x51

I am really really new to all of this and would like to learn, and from my attempts to bootload the breadboarded ATmega328-PU, I guess I have figured out that this chip cannot be bootloaded with these methods (but I hope it can be done, I could just be doing it wrong).

Can somebody please explain how to bootload the ATmega328-PU (non-P) using an UNO R3 as an ISP or point me to a sketch that does support the ATmega328-PU using the UNO R3. I have been reading the forums and other sites for days now and I am getting nowhere fast.

Regards
Grant

I then proceeded to unzip and upload this sketch: Atmega_Board_Programmer.zip to my UNO R3 (the programmer), found in this tutorial Gammon Forum : Electronics : Microprocessors : Atmega bootloader programmer, I then hooked up all the pins as shown in the image for (Programming a RBB (really bare bones board)).

You seem to be combining a couple of approaches here. My programmer sketch should work, possibly the signature will be different, that will be easy to change.

If you connect the boards together as per the photo above, then you should be able to upload the Atmega_Board_Programmer sketch to your Uno. Then use the serial monitor to "talk" to your Uno. You should then see the signature, and an offer to upload the bootloader if it is recognized.

Can you please post what you see in the serial monitor when you do that?

Judging by another forum post the signature is 0x1e9514 rather than 0x1e950F.

So, in my bootloader sketch locate this line:

  { { 0x1E, 0x95, 0x0F }, "ATmega328P",  32 * kb,       512,

Change it to:

  { { 0x1E, 0x95, 0x14 }, "ATmega328",  32 * kb,       512,

I think the rest should be the same. That should then be able to upload the bootloader.

Or to allow for both chips, find these lines:

  { { 0x1E, 0x95, 0x0F }, "ATmega328P",  32 * kb,       512, 
        atmega328_optiboot,   // loader image
        0x7E00,               // start address
        sizeof atmega328_optiboot, 
        128,          // page size (for committing)
        0xFF,         // fuse low byte: external clock, max start-up time
        0xDE,         // fuse high byte: SPI enable, boot into bootloader, 512 byte bootloader
        0x05,         // fuse extended byte: brown-out detection at 2.7V
        0x2F },       // lock bits: SPM is not allowed to write to the Boot Loader section.

Add after them these lines:

  { { 0x1E, 0x95, 0x14 }, "ATmega328",  32 * kb,       512, 
        atmega328_optiboot,   // loader image
        0x7E00,               // start address
        sizeof atmega328_optiboot, 
        128,          // page size (for committing)
        0xFF,         // fuse low byte: external clock, max start-up time
        0xDE,         // fuse high byte: SPI enable, boot into bootloader, 512 byte bootloader
        0x05,         // fuse extended byte: brown-out detection at 2.7V
        0x2F },       // lock bits: SPM is not allowed to write to the Boot Loader section.

Then it will handle both chips. Untested however.

Hi Nick

This is what I see in serial monitor:

Atmega chip programmer.
Written by Nick Gammon.
Entered programming mode OK.
Signature = 0x1E 0x95 0x14 
Unrecogized signature.
LFuse = 0x62 
HFuse = 0xD9 
EFuse = 0xFF 
Lock byte = 0xFF 
Clock calibration = 0x9B 
Type 'C' when ready to continue with another chip ...

OK, looks like it is mainly working. Now do what I said in reply #2.

Nice Nick,

It looks as though it bootloaded successfully:

Serial Monitor Output

Atmega chip programmer.
Written by Nick Gammon.
Entered programming mode OK.
Signature = 0x1E 0x95 0x14 
Processor = ATmega328
Flash memory size = 32768 bytes.
LFuse = 0x62 
HFuse = 0xD9 
EFuse = 0xFF 
Lock byte = 0xFF 
Clock calibration = 0x9B 
Bootloader address = 0x7E00
Bootloader length = 512 bytes.
Type 'V' to verify, or 'G' to program the chip with the bootloader ...
Erasing chip ...
Writing bootloader ...
Committing page starting at 0x7E00
Committing page starting at 0x7E80
Committing page starting at 0x7F00
Committing page starting at 0x7F80
Written.
Verifying ...
No errors found.
Writing fuses ...
LFuse = 0xFF 
HFuse = 0xDE 
EFuse = 0xFD 
Lock byte = 0xEF 
Clock calibration = 0x9B 
Done.
Type 'C' when ready to continue with another chip ...

Thanks Nick, you are a legend!

Signature verified:

Type 'C' when ready to continue with another chip ...
Entered programming mode OK.
Signature = 0x1E 0x95 0x14 
Processor = ATmega328
Flash memory size = 32768 bytes.
LFuse = 0xFF 
HFuse = 0xDE 
EFuse = 0xFD 
Lock byte = 0xEF 
Clock calibration = 0x9B 
Bootloader address = 0x7E00
Bootloader length = 512 bytes.

I've updated the sketch on GitHub and my downloads link to incorporate the Atmega328 processor.

Great!

Thanks for the help, I'm sure others will find this post useful and get your updated sketch.

Regards
Grant