AT91: Problem to clear NVM bit 2 in order to boot on Samba

Hello,

I’m working with an AT91SAM7X256 and I would like to clear the NVM bit 2 in order to boot on Samba at next boot. I’d like to do that from the device (in the flash or the SRAM) and not from the host. When I do that from the host using AT91Boot_DLL.dll it works fine. When I want to do that in the firmware, I loose the execution as son as I send my command to the EFC (Embedded Flash Controller). Apparently the processor goes into the abort state. I tried the same in SRAM using __ramfunc, but the behavior is the same. If I unplug and replug the device it indeed starts on Samba, so the command has been taken.

Can somone tell me what I do wrong below?

Thanks in advance

Hannibal

void SetNextBootOnRom(void) 
{ 
   __disable_interrupt(); 
    
   AT91C_BASE_MC->MC_FMR = 0x00480100;    
       
   // Wait that the EFC is ready to take a new command 
   while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY) == 0x00000000); 
    
   // Cursor 
   TRACE_CURSOR("Before bit change\n\r"); 

   // Send the command to the the EFC to set the bit 
   //AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC, 0x5A00020D); 
   AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC, AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_CLR_GP_NVM | (AT91C_MC_PAGEN & (2 << 8))); 
    
   // Cursor 
   TRACE_CURSOR("This line is never executed !\n\r"); 
    
   // Wait that the bit is set 
   while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY) == 0x00000000);          
    
   __enable_interrupt(); 
}

Hi

It is possible, I am just guessing, not clear from documentation, that the remapping betwen normal flash and ROM (SAMBA) is controlled directly by NVM bit 2, and not just activated when rebooting. This means that your RAMfunc will return to some address in ROM after changing NVM bit 2.

If this is true or not can be tested by breaking a program running in flash, changing NVM bit 2 with a debugger (OpenOCD) and inspecting the restet/interrupt vectors or the code pointed to by the PC.

Regards,

Magnus

Dear Magnus,

Thanks for your reply! Unfortunately I don’t have any probe, I can therefore not check the processor registers. And probably I can’t trust the simulator behavior for this.

To see if the execution of the remapped code is done just after we set the bit, I tried in the other sense: I manually put the device back in Samba mode and set the bit from the host using the AT91Boot_DLL.dll. I could see my firmware is not executed at this time. It starts only when I unplug and replug the board. I suppose then it should be the same in our sense.

On another forum (http://tech.groups.yahoo.com/group/AT91SAM/message/2645), a suggestion is to disable interrupts to avoid the execution ends up in the pabort_handler. Instead of using __disable_interrupts() as I do to the code given in my initial post, I did it by writing directly into the register (follow the link above for the code), but the behavior is the same.

Would you have another idea?

Thank you

Hannibal