I'm using an atxmega384c3 and have a bootloader that is able to erase/write flash pages just fine. The command that is supposed to erase the entire application section however does not work.
This test code first programs a page with the values 0x01 and then is supposed to erase the application memory. When I read back the flash it is 0x01 and NOT erased showing that the SP_EraseApplicationSection() function does not work as expected.
memset(buff3,0x01,512); SP_LoadFlashPage(buff3); //program the flash SP_EraseWriteApplicationPage(0); SP_WaitForSPM(); SP_EraseApplicationSection(); SP_WaitForSPM(); PORTE.DIRSET=_BV(5); PORTE.OUTCLR=_BV(5); for(;;);
I am using a sp_driver.s and sp_driver.h and I've modified it to add some functions that were not in the original files I found here. Here are the relavant cuts of code for this issue:
#define NVM_CMD_ERASE_APP_gc (0x20<<0) // Erase Application Section .section .text .global SP_EraseApplicationSection SP_EraseApplicationSection: in r19, RAMPZ ; Save RAMPZ, which is restored in SP_CommonSPM. ldi r20, NVM_CMD_ERASE_APP_gc ; Prepare NVM command in R20. jmp SP_CommonSPM ; Jump to common SPM code. .section .text, "ax" SP_CommonSPM: movw ZL, r24 ; Load R25:R24 into Z. sts NVM_CMD, r20 ; Load prepared command into NVM Command register. ldi r18, CCP_SPM_gc ; Prepare Protect SPM signature in R18 sts CCP, r18 ; Enable SPM operation (this disables interrupts for 4 cycles). spm ; Self-program. clr r1 ; Clear R1 for GCC _zero_reg_ to function properly. out RAMPZ, r19 ; Restore RAMPZ register. ret
The datasheet says something about:
188.8.131.52 Erase Application Section
The erase application command is used to erase the complete application section.
1. Load the Z-pointer to point anywhere in the application section.
2. Load the NVM CMD register with the erase application section command.
3. Execute the SPM instruction. This requires the timed CCP sequence during self-programming.
So I did wind up trying to use clr r24, and clr r25 in the SP_EraseApplicationSection section before it jumps to the SP_CommonSPM, but this did not seem to make any difference.
Any thoughts or ideas on what to try next?