Any way to unbrick ATMega328p (SMD)?

I'm building a wireless sensor with SMD Atmega328p chip. It's running at 8Mhz using only internal oscillator and uses 3V coin cell for power. There's also 3.3V regulator in case it needs to powered by higher voltage.
Anyway, I had some success uploading code to it via USBTinyISP programmer and Arduino IDE (using boards.txt from this tutorial). I was getting errors every time, but program somehow was able to upload and seemed to work. I however was never able to upload bootloader.
Anyway I've tried different configuration (from this site) and it bricked my MCU. It won't get programmed by USBTinyISP anymore at all (out of sync error or something like that).
Is there any way to unbrick it? I've read about using 12V to reset chip, but it's not clear how this is done. Biggest issue is that SMD MCU is soldered to the PCB and I have RFM69W chip on PCB to which might get damaged by anything about 3.3V. Can someone suggest how I can unbrick it or am I SOL? :sob:

You might have read that site a bit more closely, where the guy talked about how he screwed up and bricked a bunch of his boards... If you have other devices on the board, you need to be careful about the USBAsp not being able to supply enough power, causing the voltage to sag and programming to fail, and also that there's no load on the SPI pins that might interfere with communication.

The one hope for an easy fix is connecting an external crystal (8mhz or less), and seeing if the USB ASP can talk to it then.

Failing that, you'll need to use high voltage (called that because you do it by applying 12v to reset) serial programming to get it sorted high voltage serial programming unbrick - Google Search

No, there's no easy way to modify a USB Asp to program over HVSP.

I just programmed a couple atmega328's and made a tutorial on it. This is the method I used, but you might have to get the binary data out of the hex file. It's described below. This was my method I used.

HOW TO PROGRAM THE ATMEGA328(p) MANUALLY THROUGH SPI

Programming the ATmega328(p) manually can easily be achieved using a standard SPI connection.
By connecting the ATmega to a host MCU through SPI, programming the target can be very easy.

  1. ChipSelect - Enables programming mode on the target ATmega328(p)
  2. Issue corresponding commands from host to the target.
  3. Release ChipSelect

CONNECTIONS

HOST - TARGET
SS/CS RESET
MOSI MOSI
MISO MISO
SCK SCK
V+ V+
GND GND

No external crystal connection is needed. Programming speed is determined by SPI SCK.


ATMEGA328(p) ISP COMMANDS

0xAC EXECUTABLE COMMAND PREFIX
0x20 READ LOW BYTE FROM FLASH
0x28 READ HIGH BYTE FROM FLASH
0x30 READ DEVICE ID INFORMATION
0x40 WRITE LOW BYTE TO FLASH BUFFER
0x48 WRITE HIGH BYTE TO FLASH BUFFER
0x4C TRANSFER BYTES FROM BUFFER TO FLASH AT ADDRESS LOADED INTO 0x40 AND 0x48
0xC0 WRITE BYTE TO EEPROM
0xA0 READ BYTE FROM EEPROM


OPCODE USAGE

STEP 1: Issuing the "Programming Enable" command to the target:

This is the only command the target will acknowledge initially when RESET goes low.
You can enter Programming Mode by sending AC 53 00 00 to the target.

STEP 2: Reading the Device ID from the target after initialization:

The next step is to see if init occured correctly, so we have to read the Device ID from the target.
Device ID can be read by issuing 30 00 00 to the target, and then read one byte back from the
target checking for data first then issuing clock in that order on the bit level.

The Device ID byte should read back as 1E signifying Atmel as the manufacturer.
If the Device ID byte reads as 0x1E, the device is set to be reprogrammed.
If the Device ID byte reads as 0xFF, the device did not initialize properly.

If the Device ID byte reads as 0x00, then the Lock Bits are set and the
device has to be erased first before you can properly read the Device ID.

Send three bytes, then read one byte for a total of four bytes in the sequence.

** Note that each command in Programming Mode is ALWAYS 4 bytes long **
** You can also read flash size using 30 00 01 + read one byte **
** You can also read device family using 30 00 02 + read one byte **

STEP 3: Issuing the Chip Erase Command to Erase the entire contents of Flash and EEPROM:

Before programming can occur, the Flash and EEPROM must be erased at the same time.
This resets all bytes in the physical address space to 0xFF so they can be reprogrammed.
Erasing Flash and EEPROM can be accomplished by issuing AC 80 00 00 to the target.
ALL bytes in Flash and EEPROM become 0xFF.

** ATmega328(p) is only capable of setting individual bits to 0's from 1's during programming **
** The unit can not program bits from 0's to 1's, so the bytes default to 0xFF after format **

STEP 4: Checking to see if the device was formatted properly:

Checking Flash to see if it was formatted properly can be done by issuing
the Read Byte From Flash command. Each address location holds 2 bytes,
a High byte and a Low byte.

aa=SEGMENT or MSB highbyte of address
bb=OFFSET or LSB low byte of address

Example: If the Segment=00 and the Offset=01 then the ADDRESS= 0x0001

To read a low byte from an address in Flash, issue: 20 aa bb then read one byte,
or issue: 20 SEGMENT OFFSET then read one byte.

To read a high byte from an address in Flash, issue: 28 aa bb then read one byte
or issue: 28 SEGMENT OFFSET then read one byte.

Send three bytes, then read one byte for a total of four bytes in the sequence.

If the bytes read are 0xFF, then the device has been formated properly.
The Flash address range is 0x0000 - 0x03FFF or 0-16383 for a total of 16384 memory locations.
** Each address in Flash contains 2 bytes, a Low byte and a High byte **

STEP 5: Writing a byte to Flash after proper Format:

Writing bytes to flash occurs by sending a byte to a high or low location per address in flash.

Writing a low byte to a Flash address is accomplished by issuing 40 SEGMENT OFFSET uint8_t
for a total of four bytes sent to the target from the host.

Writing a high byte to a Flash address is accomplished by issuing 48 SEGMENT OFFSET uint8_t
for a total of four bytes sent to the target from the host.

Physically writing the low and high bytes to the flash from the buffer is done by issuing
the "Write Program Memory Page" command which must be done per address location
after having written the low and high bytes to a single address.

Locking the bytes into Flash memory can be done by issuing 4C SEGMENT OFFSET 00
for a total of four bytes sent to the target MCU.

Simply release the RESET line of the target MCU to end programming mode.

Example 40 00 00 FE 48 00 00 EF 4C 00 00 00 writes EFFE to address 0x0000 in Flash.
Commands are issued one after another without releasing RESET, (which must remain low).


INTERPRETTING INTEL HEX FORMAT

Intel HEX format traditionally looks something like this: :107800000C94343C0C94513C0C94513C0C94513CE1

Understanding the bytes can be done by breaking each line of HEX code into groups like this:

:10 7800 00 0C94343C0C94513C0C94513C0C94513C E1

Each line in this bootloader example begins with a : representing the start of a new line.

The next two chars 0x10 from the example shows how many data bytes are in the line of text.

The next four bytes 0x7800 show the starting address where the code will be written to Flash
with 0x78 as MSB or SEGMENT and 0x00 as LSB or OFFSET for the address.

The next two bytes 0x00 show that the next 16 bytes in the line are plain uint8 data.
This will be written low byte first then high byte in that order until end of file.

Following the data type is a group of 16 bytes beginning with 0x0C ending with 0x3C
0x0C will be written as the low byte using ISP command 0x40 at address 0x7800
0x94 will be written as the high byte using ISP command 0x48 at address 0x7800

Then these bytes are locked into place inside the Flash using ISP command
4C 78 00 00 reflecting the address of the bytes that were issued to the buffer.

0x3C will be written as the high byte using ISP command 0x48 at address 0x7807
This is because the ATmega328(p) holds two bytes per address in Flash unlike
the hex file shows.

The last two chars 0xE1 are the checksum digits for the entire line which can be discarded.

The last two lines in the hex file can be ignored as they will not be written to Flash in any shape, way or form.
The last two lines of code look something like this:
:040000030000780081
:00000001FF

They are not used for AVR, but used for storing instruction and stack pointer addresses in Intel x86 CPU's.
The last line marks the end of file which can be ignored completely.

** Write the low byte, then write the high byte and then lock the bytes into place before writing any bytes to any other address **
** The only address we are interested in is the very first address listed in the hex file, 7800 in this case for bootloader **
** No other address should ever be used as the other addresses do not line up to how the data needs to be written to MCU Flash! **


BOOTLOADERS

ATmega328(p) has four bootloader locations inside it.

They are:

BLS1 - 0x7E00 - 0x7FFF size 0x0200 or 512 bytes

BLS2 - 0x7C00 - 0x7FFF size 0x0400 or 1024 bytes

BLS3 - 0x7800 - 0x7FFF size 0x0800 or 2048 bytes

BLS4 - 0x6FFF - 0x7FFF size 0x1000 or 4096 bytes

Per the example above, this bootloader begins at 0x7800
so we know we'll have to use Bootloader Section 3, BLS3.
This will be the start address where the bootloader code
will reside.

However, all Application Code should be written starting
at address 0x0000 inside the MCU Flash without entering
bootloader space unless the bootloader option is disabled.

Disabling the bootloader can be accomplished by setting [BOOTRST] to 0
which will set the Reset Vector address to 0x0000 during Power-Up.

This way, the bootloader is disabled and your Application Code will still work.

Disabling the bootloader will give your Application Code more space as it
can then fill up the bootloader sections since execution starts at 0x0000.


lexpress, did you even read OP's post? He had SPI programming working (that's what the USB Asp does), fiddled with the fuses, and now reports that SPI programming no longer works. A guide on how to do SPI programming won't help when SPI programming has already been broken.

This commonly happens if fuses are set incorrectly - either RST_DISABLE was set, or he has no external crystal, but the fuses say to use one. In the latter case, he can connect a crystal and reprogram over SPI; in the former case, it's more complicated, since you can't program over SPI if RST_DISABLE is set.

DrAzzy:
You might have read that site a bit more closely, where the guy talked about how he screwed up and bricked a bunch of his boards... If you have other devices on the board, you need to be careful about the USBAsp not being able to supply enough power, causing the voltage to sag and programming to fail, and also that there's no load on the SPI pins that might interfere with communication.

The one hope for an easy fix is connecting an external crystal (8mhz or less), and seeing if the USB ASP can talk to it then.

Failing that, you'll need to use high voltage (called that because you do it by applying 12v to reset) serial programming to get it sorted high voltage serial programming unbrick - Google Search

No, there's no easy way to modify a USB Asp to program over HVSP.

Yeah I didn't get to the part where he talks about bricking his boards before I tried it :frowning: RFM69W can be power hog...
Unfortunately I don't have any crystals below 16Mhz on hand...
I'm trying to understand what's the procedure for entering HVSP mode. Is it:

  1. Send 12V to RESET pin
  2. Program fuses
  3. stop supplying 12V to RESET pin
    ?
    Can I send 12V to it manually?
    BTW I'm using USBTinyISP V2 and not USB Asp, not that it makes much difference anyway :slight_smile:
    Also this blog post looks promising, he uses transistor to supply 12V and Arduino as ISP programmer.

Although you can do all programming via HVSP, usually people just use it to unbrick it, so they can program via SPI, which is more convenient in all sorts of ways.

I'm not sure of the specifics of the procedure, or whether you could manually turn the +12v on and off. I wouldn't try it; transistors are cheap as dirt. In his circuit, the exact npn transistor isn't critical; almost any simple npn transistor will work.

Note that he is NOT using Arduino as ISP programmer in that page you linked. He is using a different sketch, which he attached.

I've been researching more on the subject. It looks like it's not as simple as connecting RST to 12V and then programming fuses via SPI pins. Much more pins need to be connected (page 286 of datasheet shows how), voltage needs to be over 4.5V, code gets complex, etc... I just got hot air workstation, I think I'll just de-solder bricked chip and try with fresh one...

parallel_programming.png

bratan:
I've been researching more on the subject. It looks like it's not as simple as connecting RST to 12V and then programming fuses via SPI pins. Much more pins need to be connected (page 286 of datasheet shows how), voltage needs to be over 4.5V, code gets complex, etc... I just got hot air workstation, I think I'll just de-solder bricked chip and try with fresh one...

You got that wrong - looking at the wrong section of the manual! Read the next section.

SPI is serial programming, and it is as simple as connecting RST to 12V and then programming via the SPI.

Paul__B:
You got that wrong - looking at the wrong section of the manual! Read the next section.

SPI is serial programming, and it is as simple as connecting RST to 12V and then programming via the SPI.

Thank you Paul, I'm happy to be wrong in this case. But can anyone actually tell me how I can do this?
Would using ArdinoISP sketch and connecting reset pin to a 12V via npn transistor to target chip do the trick?

SPI is serial programming, and it is as simple as connecting RST to 12V and then programming via the SPI.

Although you can do all programming via HVSP, usually people just use it to unbrick it, so they can program via SPI, which is more convenient in all sorts of ways.

The 328 family can only be programmed by either ISP (using the SPI lines) or by the parallel method(a bunch of lines to hook up) which DOES put 12v on the reset line whereas the ISP brings the reset line LOW and does not apply 12v to the reset line.

In other families that do not have enough pins to do parallel programming there is HVSP which does put 12v on the reset line.

So you CANNOT do HVSP on the mega328.

I see, thank you!

justone:
So you CANNOT do HVSP on the mega328.

Ah yes, I stand corrected. I was thinking of the "tiny" chips.

Guess you need this:

But the OP has SMD chips that are soldered to a board.

Is there any way to unbrick it?

First check it is really bricked.

justone:
So you CANNOT do HVSP on the mega328.

Yes you can. Where did you read that? See the datasheet 27.6 "Parallel Programming Parameters, Pin Mapping, and Commands". That is high-voltage programming.

HVSP (high voltage serial programming) and Parallel Programming are synonyms in this case.

I've never tried to do it with the chip "in situ" but it might be possible.

First though I would run the test above and see if it is really bricked.

Well, I originally thought so, but the datasheet does appear to distinguish the two. Does the hardware actually behave beyond the datasheet specifications? I wouldn't be entirely surprised.

justone:
But the OP has SMD chips that are soldered to a board.

And an adapter.

Paul__B:
Well, I originally thought so, but the datasheet does appear to distinguish the two. Does the hardware actually behave beyond the datasheet specifications?

My copy of the datasheet says on page 301:

27.7 Parallel Programming
27.7.1 Enter Programming Mode

The following algorithm puts the device in Parallel (High-voltage) Programming mode:

On page 300 the schematic for "Parallel Programming" shows +12v on the /RESET pin.

So I think I can safely say they are the same thing. You are programming in parallel using high voltage (ie. 12v) on the /RESET pin, to force it into a different mode.

Yes you can. Where did you read that?

Please show what page of the data sheet for the 328 that the words High Voltage Serial programming appear.

That is high-voltage programming.

Yes. Parallel but NOT serial

HVSP (high voltage serial programming) and Parallel Programming are synonyms in this case.

Man you have to be kidding but if not then-

Kind of like serial(rs232) printers and parallel(centronix) printers being the same since both print on paper.

Parallel parking is the same as Perpendicular parking since both involve a car being parked.

Air flight is the same as a boat trip since you arrive at a destination.

Gotta love your logic on this.

1 Like

I am aware of the difference between serial and parallel.

I think we are cross-purposes a bit because an earlier post on page 1 of this thread talked about using high-voltage programming to unbrick the chip. On the chips with a small number of pins high-voltage serial programming can be used for this purpose and on ones with more pins high-voltage parallel programming does a similar thing.

The important thing here, though, is that it is the high-voltage programming that can achieve the result.

But thanks for clarifying the point.

justone:
The 328 family can only be programmed by either ISP (using the SPI lines) or by the parallel method(a bunch of lines to hook up) which DOES put 12v on the reset line whereas the ISP brings the reset line LOW and does not apply 12v to the reset line.

In other families that do not have enough pins to do parallel programming there is HVSP which does put 12v on the reset line.
v to reset
So you CANNOT do HVSP on the mega328.

Pretty much what I posted in reply #9 is what you are saying.

I was just trying to prevent a someone who might think applying 12v to the reset line while having the other SERIAL programming lines hooked up would WORK on the mega328 from the previous posts that brought it up.

I was just responding to your reply that you could.

Quote from: justone on Dec 04, 2014, 09:06 pm
So you CANNOT do HVSP on the mega328.

Iexpress:
HOW TO PROGRAM THE ATMEGA328(p) MANUALLY THROUGH SPI

Programming the ATmega328(p) manually can easily be achieved using a standard SPI connection.
By connecting the ATmega to a host MCU through SPI, programming the target can be very easy.

@Iexpress: You have already made the same (or similar) post about 5 times, the first being:

http://forum.arduino.cc/index.php?topic=282536

This is cross posting. Please stop or be banned. If you want to convey the same information post a link to your first post, don't just copy and paste it again and again.