programming with ISP not letting me use all FLASH

hey there

im using the pocket AVR programmer from sparkfun : https://www.sparkfun.com/products/9825

and i can successfully upload code with it.

however according to the following documentation: https://www.arduino.cc/en/Hacking/Programmer

i should be able to use all the flash memory to upload code to, but its still limiting my upload to a size as if the bootloader was there.

do i have to make any changes to some config files? am i missing or misunderstanding?

thanks in advanced!

pts1016: hey there

im using the pocket AVR programmer from sparkfun : https://www.sparkfun.com/products/9825

and i can successfully upload code with it.

however according to the following documentation: https://www.arduino.cc/en/Hacking/Programmer

i should be able to use all the flash memory to upload code to, but its still limiting my upload to a size as if the bootloader was there.

do i have to make any changes to some config files? am i missing or misunderstanding?

thanks in advanced!

Grab a copy of this PDF datasheet (for the ATMega328p):

DATASHEET

Then go to page 280 and start reading about "Boot Lock Bits".

You will need to check this, but I think you just need to create a new entry in the boards.txt file and change the maximum upload size.

Assuming you are using an uno:

Copy and paste the uno entry then rename it. Change the name to something like unoNoBoot

Change - uno.upload.maximum_size=32256 to - unoNoBoot.upload.maximum_size=32768

Change - uno.bootloader.extended_fuses=0x07 to - unoNoBoot.bootloader.extended_fuses=0x05.

You will need to change the name for all entries

Krupski, im using an atmega32u4 so wrong datasheet. however I assume the keywords still apply and found a related section, but it's still a bit Greek to me.

MartynC your answer seems like it's in the right direction but once again im using atmega32u4, arduino micro. the max upload size I understand, pretty straight forward. the fuses are a bit over my head still, I am trying to put some understanding behind it. id assume the fuse value would be different for the 32u4? ill b peeping at the datasheet but any insight would be appreciated

pts1016:
Krupski, im using an atmega32u4 so wrong datasheet. however I assume the keywords still apply and found a related section, but it’s still a bit Greek to me.

Well, I took a guess since most people have an Uno, I figured 328p. Anyway, the registers are similar in all the AVR devices, depending, of course, on memory size and specific features.

Here’s the link to the 32u4 datasheet in case you need it: http://www.atmel.com/Images/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf

You’ll want to start at page 329 in this one. :slight_smile:

I don’t know how your specific device is setup, but the AVR cpu can be setup to protect (“lock”) certain areas of flash memory and/or eeprom. An obvious example is if you DON’T want to over-write a bootloader by accident - you set the proper fuse bits to lock that area.

An Arduino device that uses a 32u4 cpu typically has these fuse settings:

[b][tt]
low fuse=0xFF
high fuse=0xD8
extended fuse=0xCB

lock fuse=0x2F[/b][/tt]

Looking at the lock fuse, the bit pattern is this:

[b]Bit 7  6  5  4  3  2  1  0
    0  0  1  0  1  1  1  1[/b]

← 0x2F

That pattern means “SPM is not allowed to write to the Boot Loader section”. In order to open up the chip to allow you to write anywhere, you need to SET bit 4 (called “BLB11” in the datasheet). So then the lock fuse setting would be this:

[b]Bit 7  6  5  4  3  2  1  0
    0  0  1  1  1  1  1  1 [/b]

← 0x3F

In fact, if you look at the “boards.txt” file, you will see that to burn the Arduino bootloader into the cpu, the lock fuse is first set to 0x3F (unlock), then after it’s set to 0x2F (locked).

Let me ask, what are you using to program your programmer? If you are trying to upload a full 32768 bytes of code to it via the Arduino IDE, you won’t be able to because the bootloader is what’s loading the code!

IF you unlocked the bootloader area and then tried to upload a full 32768 bytes, it would die as soon as the new code began overwriting the bootloader. And, depending on the bootloader code itself, it may even protect itself against over-writing it’s own space (like OptiBoot does).

The only way, I think, to do what you want to do is to have a “real” programmer like an AVRISPMKII and then just burn whatever you want - no bootloader needed.

But then you need to change ANOTHER fuse bit so that the AVR reset vector points to 0x0000 rather than the bootloader area!

(are we having fun yet?) :slight_smile:

Krupski! incredible explanation my friend, thank you very much!

to answer your question (or at least if i understand it right) im not programming a programmer. im using the pocket AVR programmer by sparkfun (link in my first post) to program a custom atmega32u4 circuit board i created. i "think" the pocket AVR programmer is qualified as a 'real' programmer? is it not? please let me know if it isnt :o lol

you did kind of loose me on the last part. if im not programming the programmer, do i need to reset the vector points?

if using the avr programmer i mentioned, should i be able to simply change the fuses, upload with full access to the atemga32u4, and reprogram it again and again without editing? then if i want the bootloader back on the atmega32u4, burn bootloader? if this is the case then i think mission accomplished :)

pts1016: Krupski! incredible explanation my friend, thank you very much!

to answer your question (or at least if i understand it right) im not programming a programmer. im using the pocket AVR programmer by sparkfun (link in my first post) to program a custom atmega32u4 circuit board i created. i "think" the pocket AVR programmer is qualified as a 'real' programmer? is it not? please let me know if it isnt :o lol

you did kind of loose me on the last part. if im not programming the programmer, do i need to reset the vector points?

if using the avr programmer i mentioned, should i be able to simply change the fuses, upload with full access to the atemga32u4, and reprogram it again and again without editing? then if i want the bootloader back on the atmega32u4, burn bootloader? if this is the case then i think mission accomplished :)

OK, let me try to explain it. I'll use the Arduino UNO and ATMega328p as my example, but the idea is the same for all of them.

In the "high fuse", bit 0 is called "BOOTRST". If the bit is programmed (i.e. the bit is "0" or "cleared"), then upon reset the CPU jumps to the bootloader address (which is located at address 0x7E00 in an Arduino UNO). That location is 512 bytes below the top of memory because the UNO bootloader is 512 bytes in size.

The address that the reset goes to is determined by the "BOOTSZ1" and "BOOTSZ0" bits in the high fuse (bits 2 and 1 respectively - which are both "1" in this case).

So, let's say you wrote your own bootloader with extra features (i.e. larger) and it took 1024 bytes instead of 512. Well, you would look up in the data sheet and find that "BOOTSZ0" would need set to "0" to set the boot block start address to 0x7C00 instead of 0x7E00. (those of you who know keep quiet - explanation is below!)

And of course, the reset vector now also jumps to 0x7C00 instead of 0x7E00 (make sense so far?).

Now, AVR/Arduino PROGRAMS (sketches) are loaded into flash memory starting at 0x0000. So what the bootloader does upon reset is check "is someone trying to upload a sketch?", "wait", "nope, jump to 0x0000 and run what's already there".

But if you DON'T use a bootloader and instead program with a programmer (in order to use all the memory), the AVR will jump to the bootloader section, not find anything and crash.

What you need to do is tell the chip "you have no bootloader, jump directly to 0x0000 upon reset" and you do this by setting the BOOTRST bit to "1".

Now, looking at the data sheets, you can get confused very easily. Atmel usually enables an option by PROGRAMMING a certain fuse bit. But a programmed bit is "0" which we normally think of as "cleared" or "disabled". It's bass-ackwards and confusing.

To give you another example to help clarify, look at the CKDIV8 fuse bit which controls whether the CPU boots up at full clock speed or "crystal / 8" speed. To enable the "divide clock by 8" feature, you PROGRAM the CKDIV8 bit (which, confusingly, sets it to "0"). This is a very important concept to get... usually "Feature Enabled" = "Feature Bit Programmed" = "Feature Bit is 0".

Another goody... the bootloader area memory addresses are specified as WORDS, not BYTES in the datasheet. So, for example, the Arduino UNO bootloader takes up 512 bytes, the datasheet says that it takes up 256 WORDS and the bootloader section starts at WORD 0x3F00 (which is BYTE address 0x7E00) and therefore the fuse bits for that are "BOOTSZ1=1" and "BOOTSZ0=1" (which is Atmel's perverse thinking means those bits are UNPROGRAMMED).

Actually, I know why they did it that way... EEPROM and FLASH memory cells are normally all ones (an erased byte is 0xFF) and you program bits LOW. To make a bit high, you have to erase the whole byte to 0xFF, then program low the bit(s) you want to be 0.

In fact, some flash memory devices can't even be programmed byte by byte. If you want to change one byte (or even one BIT) you need to read the entire flash page into a temporary buffer, modify the bits/bytes in the buffer, erase the entire flash page, then finally write the updated page data from the buffer back into the flash.

Hope this all makes sense....... :)