Flash Page is Locked

Hi IntraStellar,

Sorry to read from you about this Flash page locking issue.

In my experience with a couple of Dues, whatever the damage inside the Due, there is no way to make Arduino IDE to upload any code to the affected Due (via USB prog or native).

As I explained before, the easiest way to program the Due is using the In-system programmer software called SAM-BA via the USB native port. You could use also Atmel Studio 6x with SAM-ICE hardware but it is expensive and elaborated.

Here a link to download SAM-BA.

Also, this issue (in my cases) is directly related with the use of the DueFlashStorage library, especially if you exploit it (saving/retrieving in more than a dozen of memory registers).

Regards,
-p

I will give it a try and get back to you. Thanks for helping me out you guys.

If you know any guide on how to do it or have explained it in another thread I'd appreciate the link to help me reset this pesky bit.

I am not sure if there is out there a simple procedure but here my steps to upload a sketch in Arduino Due using SAM-BA:

  1. Upload or compile your sketch using the Arduino IDE. This step will generate the correspondent .bin file of your sketch.

  2. Connect your computer to Arduino Due via USB native (SAM-BA doesn't recognize the USB programming port).

  3. Press the Arduino Due Erase button for one second. Then press the Arduino Due Reset button for another second and finally release both buttons. This switches from the 'Arduino Due port' to the 'Bossa Program port' in the Windows Device Manager (COM ports).

  4. Open SAM-BA. SAM-BA should detect and select the Arduino Due Bossa port and board type (ar91sam3x8-ek) automatically. Otherwise select the Arduino Due Bossa port.

  5. Press the Connect button. Now you have connected SAM-BA with Due.

  6. In the Flash tab (center of the main SAM-BA window) click the folder button of Send File Name and select the .bin file you just generated in step1. This file is usually located at C:\Users\YourName\AppData\Local\Temp\arduino_build_xxxxxx\yoursketch.ino.bin.

  7. Press the Send File button. Click the ‘No’ button to the question about lock regions.

  8. Close SAM-BA.

And that's it. Try it and let me know how it goes.

-p

I tried it but it didn't work :confused:

The windows device manager shows the bossa port but in SAM-BA I can choose from "\USBserial\COM7" or "COM7". I used "\USBserial\COM7" since the other gave me an error. I found the .bin file and sent it.

The response I get from SAM-BA is:

(sam-ba_2.16) 2 % send_file {Flash} "C:/Users/Jakob/AppData/Local/Temp/arduino_build_693572/fixDueLock.ino.bin" 0x80000 0
-I- Send File C:/Users/Jakob/AppData/Local/Temp/arduino_build_693572/fixDueLock.ino.bin at address 0x80000
first_sector 0 last_sector 1
-I- Writing: 0x5014 bytes at 0x0 (buffer addr : 0x20002898)
-I- 0x5014 bytes written by applet
Do not lock

I then closed SAM-BA, opend Arduino IDE and uploaded the program. I still get the response that it's locked.

edited.

IntraStellar,

Can you try again but executing first the following three Scripts? (at the bottom of the SAM-BA window):

-Enable Flash access
-Enable Security Bit (GPNVM0)
-Erase all flash.

Then, send the file.

-p

IntraStellar:
I then closed SAM-BA, opend Arduino IDE and uploaded the program. I still get the response that it's locked.

edited.

I forgot to tell you that once you close samba, your Due is already programmed. DO NOT download again the sketch.

-p

Palliser:
I forgot to tell you that once you close samba, your Due is already programmed. DO NOT download again the sketch.

I can still upload a unrelated sketch like hello world? Because if this works it should be unlocked and work normally anyway if I understood this correctly. How would I otherwise check that it works?

I tried adding the three additional steps with no success.

Edit: I change from to the programming port after using SAM-BA if that makes any difference.

Try programming something like Serial.println("Hello World");

This way of programming Due with SAM-BA does not eliminate the issue. It is just a turnaround to program the Due.

-p

I did upload a hello world sketch to the Due trough a Arduino sketch after doing the SAM-BA steps if that's what you mean.

Do you mean that if this works, I'll still have to program the Due trough SAM-BA?

Yes. Now on, every time you need to program your 'pesky' Due, you have to use SAM-BA.
I still don't understand why Due with lock issue is bricked for Arduino IDE, even after a chip erase.

-p

@ IntraStellar

Could you upload the .bin of the skectch I provided in reply #14 with Sam-BA and see if something has changed.

I only clear all lock bits, not GPNVM bit 0 though, I can add this too...

Palliser:
Yes. Now on, every time you need to program your 'pesky' Due, you have to use SAM-BA.
I still don't understand why Due with lock issue is bricked for Arduino IDE, even after a chip erase.

That does suck. How will I know if the sketch was successfully uploaded? Will SAM-BA function as a serial monitor as well?

ard_newbie:
@ IntraStellar

Could you upload the .bin of the skectch I provided in reply #14 with Sam-BA and see if something has changed.

I only clear all lock bits, not GPNVM bit 0 though, I can add this too...

Yep, that's the file I have been uploading together with hello world.

IntraStellar:
That does suck. How will I know if the sketch was successfully uploaded? Will SAM-BA function as a serial monitor as well?

Once you have downloaded your sketch using SAM-BA, you can connect your Due to the USB programming port and use the serial monitor of the Arduino IDE as usual.

That works! Thanks a bunch. I have tried both the 'hello world' sketch and the 'unlocking' sketch and they both run. Unfortunately the error still remains even after running the 'unlocking sketch' trough SAM-BA.

At least I can use the Due now even though it's a hazzle. If anyone have another solution that enables me to upload sketchs trough the Arduino IDE, I'm all ears!

We know that the error message is incorrect since all lock bits are cleared.

We don't know if the security bit is set and if there is an issue with the ERASE process. I suspect the conjonction of several bugs.

I suggest that you upload, via SAM BA and the native USB port, this sketch to read GPNVM bits :

#define Serial SerialUSB

#define EEFC_FKEY 0x5A

__attribute__ (( __section__ (".ramfunc")))
uint32_t ReadGPNVM_bits(void)
{
  uint32_t status;
  uint32_t priMask = __get_PRIMASK ();
  __disable_irq();

  static uint32_t (* IAP_function) (boolean, uint32_t);

  IAP_function = (uint32_t(*)(boolean, uint32_t)) * ((uint32_t *) CHIP_FLASH_IAP_ADDRESS);
  // select flash Bank
  while (!(EFC0->EEFC_FSR & EEFC_FSR_FRDY));

  IAP_function(0, EEFC_FCR_FKEY(EEFC_FKEY) | EEFC_FCR_FCMD(EFC_FCMD_GGPB ));
  while (!(EFC0->EEFC_FSR & EEFC_FSR_FRDY));
  status = EFC0->EEFC_FRR;            // Read GPNVM Bits

  __set_PRIMASK (priMask);
  return status;
}
void setup() {
  Serial.begin(250000);
  while(!Serial);

  uint32_t __GPNVM = ReadGPNVM_bits();
  Serial.print(" GPNVM = 0b"); Serial.println(__GPNVM, BIN);
}

void loop() {

}

Note that the result wil be printed via the native USB port !! Select the COM port accordingly.

The serial response from that code is "GPNVM = 0b1" which would indicate that the lock bit is set if I understand this correctly.

This is from the Due processor (AT91SAM3X8E) datasheet:

I don't really see what they mean by;
"Disabling the security bit can only be achieved by asserting the ERASE pin at 1, and after a full Flash
erase is performed."
Perhaps pressing the ERASE pin after doing a full flash erase trough SAM-BA?

Now we are sure that the security bit has been set (however we still don't know why ...)

Here is a code to clear GPNVM bit 0, then read again GPNVM bits to know if the security bit has been properly cleard (Note that the result wil be printed via the native USB port !! Select the COM port accordingly.):

#define Serial SerialUSB
#define EEFC_FKEY 0x5A

__attribute__ (( __section__ (".ramfunc")))
uint32_t ReadGPNVM_bits(void)
{
  uint32_t status;
  uint32_t priMask = __get_PRIMASK ();
  __disable_irq();

  static uint32_t (* IAP_function) (boolean, uint32_t);

  IAP_function = (uint32_t(*)(boolean, uint32_t)) * ((uint32_t *) CHIP_FLASH_IAP_ADDRESS);
  // select flash Bank
  while (!(EFC0->EEFC_FSR & EEFC_FSR_FRDY));

  IAP_function(0, EEFC_FCR_FKEY(EEFC_FKEY) | EEFC_FCR_FCMD(EFC_FCMD_GGPB ));
  while (!(EFC0->EEFC_FSR & EEFC_FSR_FRDY));
  status = EFC0->EEFC_FRR;            // Read GPNVM Bits

  __set_PRIMASK (priMask);
  return status;
}

__attribute__ (( __section__ (".ramfunc")))
uint32_t ClearGPNVM_bits( uint32_t gpnvm )
{

  uint32_t priMask = __get_PRIMASK ();
  __disable_irq();

  static uint32_t (* IAP_function) (boolean, uint32_t);

  IAP_function = (uint32_t(*)(boolean, uint32_t)) * ((uint32_t *) CHIP_FLASH_IAP_ADDRESS);

  while (!(EFC0->EEFC_FSR & EEFC_FSR_FRDY));
  // select flash Bank 0
  IAP_function(0, EEFC_FCR_FKEY(EEFC_FKEY) | EEFC_FCR_FARG(gpnvm) | EEFC_FCR_FCMD(EFC_FCMD_CGPB ));
  while (!(EFC0->EEFC_FSR & EEFC_FSR_FRDY));

  __set_PRIMASK (priMask);

}
void setup() {
  
  ClearGPNVM_bits( 0 );  // Clear security bit  GPNVM bit 0
  Serial.begin(250000);
  while (!Serial);

  uint32_t __GPNVM = ReadGPNVM_bits();
  Serial.print(" GPNVM = 0b"); Serial.println(__GPNVM, BIN);
}

void loop() {
 
}

Still the same output; "GPNVM = 0b1". So the bit fails to be reset somehow.

As per datasheet:

7.2.3.5 Security Bit Feature
.... Disabling the security bit can only be achieved by asserting the ERASE pin at 1, and after a full Flash
erase is performed. When the security bit is deactivated, all accesses to the Flash are permitted...

The only guess I can make is that the ERASE procedure is not performed properly or long enough.

Let see if the ERASE pin (PC0) is not driven anymore by the peripheral as it should be. Try to upload this code to print SYSIO12 bit level:

#define Serial SerialUSB

void setup() {
  
Serial.begin(250000);
while(!Serial);

boolean  SYSIO12 = MATRIX->CCFG_SYSIO >> 12;  
Serial.print( "SYSIO12 = "); Serial.println(SYSIO12);

}

void loop() {
  
}

This gives the response: "SYSIO12 = 1"