self programming on ATmega4809

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried to use self programming on the ATmega4809 (Nano Every). I have set BOOTEND to 1, and wrote a small program that fits into the BOOT section:

 

int main(void)
{
    uint8_t *m;

    //_delay_ms(10);
    for (m=(uint8_t*) 0x6000; m<0xa000; m+=0x1000) {
        m[0]=0x34;
        _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
        while(NVMCTRL.STATUS & NVMCTRL_FBUSY_bm);
    }

    while(1);
}

The strange thing is that the first page write always fails. When I dump the flash, I can see the following data in the application section:

 

3000: 34

4000: 34

5000: 34

 

When I uncomment the _delay_ms(), the program works as expected, and flash location 2000 is programmed as well. I tried different examples, in all cases, the first flash page write fails. I have figured out that the delay has to be 2msec or longer to make this work.

 

Any ideas what might be wrong?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't know these chips but on previous ones each (long) SPM operation needed to wait to see a flag (actually EEPROM) set to say previous operating now finished. Not sure how that works on these new chips but I'd be looking fir some kind of completion flag to watch.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have even tried to wait for flash & eeprom ready before and after the flash operation, it doesn't make any difference.

while(NVMCTRL.STATUS & (NVMCTRL_FBUSY_bm|NVMCTRL_EEBUSY_bm));
_PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
while(NVMCTRL.STATUS & (NVMCTRL_FBUSY_bm|NVMCTRL_EEBUSY_bm));

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code works ok on my 4809 without the delay. Maybe post you fuse settings, although I'm not sure what would make any difference and I tried various combos of SUT and BOD. Maybe power problems of some sort. Try with BOD turned on if not already. 

 

You can skip the use of FBUSY as the cpu is halted as long as a flash write is in progress. To make nvm functions more generic, just check for eebusy before any nvm command.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My fuse settings are:

 

fuses: 0x0,0x0,0x2,0xff,0x0,0xc9,0x7,0x0,0x1

  BOD=0

  OSSCFG=2 (20MHz)

  SUT=7 (65ms)

  BOOTEND=1

 

lock: 0xc5

 

I'm using 5V supply and the internal oscillator (20Mhz/6=3.33Mhz)

 

I have changed the BOD fuse to 0xe5 (BODLEVEL=4.3V, ACTIVE=enabled, SLEEP=enabled). The result is the same, the first page write still fails if no delay is used.

 

In NVMCTRL.STATUS, WRERROR is NOT set after the page write!

 

I tried a different 5V power supply, as well as a different Nano Every board, still the same result.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since you are using a Nano Every, maybe the programmer chip (SAMD11) is doing something on powerup via UPDI that interrupts the first flash write?

Can you reset the mega4809 without reseting the SAMD11 and check if it works without the delay in that case?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The same thing happens when I press the reset button on the Nano Every, that is connected to the mega4809 reset pin only. I have verified on the scope that there isn't any activity on UPDI.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have EESAVE fuse set. Try without.

 

I cannot even get my 4809 to program when that fuse is set for some reason- starts programming sequence, but just stops after 'target voltage detected', and does not proceed to the 'Erasing...' stage. I am using a SNAP, and MPLABX. The SNAP has been programming that 4809 for a long time without any problems, and I guess this is the first time I turned on the EESAVE fuse. Weird.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have tried SYSCFG0=0xc8 (EESAVE=0), there's no change :-(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This may have been due to:

9.3.2.5
Write Access after Reset
After a Power-on Reset (POR), the NVMCTRL rejects any write attempts to the NVM for a given time. During this
period, the Flash Busy (FBUSY) and the EEPROM Busy (EEBUSY) bit field in the NVMCTRL.STATUS register will
read ‘1’. EEBUSY and FBUSY bit field must read ‘0’ before the page buffer can be filled, or NVM commands can be
issued.
This time-out period is disabled either by writing the Time-Out Disable (TOUTDIS) bit in the System Configuration 0
(FUSE.SYSCFG0) fuse to ‘0’ or by configuring the RSTPINCFG bit field in FUSE.SYSCFG0 fuse to UPDI.

 Note that the TOUTDIS bit doesn't even exist, or at least is not specified by the datasheet.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This time-out period is disabled either by writing the Time-Out Disable (TOUTDIS) bit in the System Configuration 0
(FUSE.SYSCFG0) fuse to ‘0’ or by configuring the RSTPINCFG bit field in FUSE.SYSCFG0 fuse to UPDI.

Those sound more applicable to the UPDI-based ATtiny chips.  The ATmega4809 doesn't have the ability to change the configuration of the UPDI pin, and doesn't share it with the pin that can do Reset, so RSTPINCFG can't be set to UPDI, and TOUTDIS shouldn't be necessary.  (which might not mean that it's not implemented in a "common" NVMCTRL logic block, but... seems unlikely.)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm facing some problems with this cpu as well.

Does anyone here have any examples of how to erase and program sectors in this cpu. I'm trying to make a bootloader.

 

Best regards

Andreas

Andreas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Obviously this chapter has been included by mistake. There's no TOUTDIS bit in SYSCFG0 for the ATmega4809.

Besides that, I tried to wait for both EEBUSY and FBUSY==0 before the write. This didn't solve the problem either.

Last Edited: Sun. Jun 12, 2022 - 10:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

 

About a year ago I was working on modifying a bootloader for this architecture. I began writing an article about the challenges and change sin paradigm from the ATMEGA168/328. However it seems to have been lost as I can't find it anymore :(((

 

Anyway, if I remember correctly you need to issue the Write command within a fixed number of CPU cycles after setting the Write flag.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

pramilo wrote:
Anyway, if I remember correctly you need to issue the Write command within a fixed number of CPU cycles after setting the Write flag.
This I guess..

 

 

But OP is doing _PROTECTED_WRITE_SPM() in #1 so this should handle this OK

Last Edited: Tue. Jun 14, 2022 - 01:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you tried getting your compiler to generate the LST file (i.e. the file that "kind of" shows the conversion between your C code and the generated ASM) so that you can really see what's going on.

 

You may find some pointers on how to do it here  Need help with GCC assembly listing file (*.lst)? | AVR Freaks

 

(this is obviously only relevant if you're OK with looking at assembly code)

 

In my career,  have found many bugs and weird behaviours by examining the LST file.