This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Flash programming error (Flash Key violation) when executing code from RAM

Other Parts Discussed in Thread: MSP430F5338

I have found a problem when programming internal Flash from code located in RAM and it looks like it has been reported before in this thread: 

e2e.ti.com/.../312665

In my case, I have an MSP430F5338 and I'm using IAR workbench.  The code is compiled in large code/data model.  When the Flash Write function is located to execute in RAM, I occasionally get builds that will often fail during a Flash Write function call, other times it works fine.   When the function is executing from Flash, then it is always reliable (obviously the code is located in a different Flash segment than what is being written).

I captured the failure (when Flash Write code function is in RAM) and what is happening is that during the wait loop for the busy bit (see code segment below), I occasionally get a "Flash Key violation" reset.   The Flash Key violation suggests that one of the FCTL registers has been written a value that does not have 0xA5 in the upper byte.  You can see that interrupts (and also watchdog) are turned off.  Is this a known problem with the silicon?  Are there limitations that I have not obeyed?

Thanks,

Michael

The flash write function looks like this :

// inputs:
// nBytes: # of bytes to write
// address: Flash target address (already erased)
// buf_ptr: uint8_t pointer to source data in RAM

{

  Flash_reg* flashReg_ptr = (Flash_reg *)0x0140;
  uint16_t count = 0;
  uint16_t gieStatus = __get_SR_register() & GIE; // save interrupt state

  __disable_interrupt();

  //! Ensure status is not busy
  while (flashReg_ptr->fctl3 & 0x01)
  {
  ;//! Do nothing, wait up to clear the busy bit
  }

  //! clear lock bit and write password 0xA5
  flashReg_ptr->fctl3 = 0xA500;
  //! write password and select byte write
  flashReg_ptr->fctl1 = 0xA540;
  
  while (count < nBytes )
  {
    *((uint8_t *)address) = *(buf_ptr + count);
    address++;
    count++;
  
    //! Wait to clear busy flag
    while (flashReg_ptr->fctl3 & 0x01)
    {
        ;//! Do nothing, wait up to clear the busy bit
    }
  }

  //! clear WRT bit
  flashReg_ptr->fctl1 = 0xA500;
  //! //Set LOCK bit
  flashReg_ptr->fctl3 = 0xA510;

  __bis_SR_register(gieStatus); // Restore interrupts
}

  • Hello Michael,

    I'm attaching a "Running from RAM" example in hopes that it will help solve your issue.  It is designed for the F2274 but can easily be altered for the F5338.  Please follow all important notes before running the code example.  I only see a few differences between your code snippet and the example code, mainly involving the dummy write for erasing and placement of BUSY flag checks, but that could make the difference required.  Try following it and let me know if it improves the status of your problem.RunningfromRAM.zip

    Regards,

    Ryan

  • Thanks for your response, I'll check it out. However, please note I do not show my code to erase in my sample. In my case, I have already erased the desired Flash segment. Also, I have been using the "MSP430x5xx and MSP430x6xx Family User's guiide", SLAU208O as my reference. Please see Figure 7-8. Initiating a Byte or Word Write From RAM. The code segment from the user guide is shown below and I believe my code matches appropriately.

    ; Byte or word write from RAM.
    ; Assumes 0x0FF1E is already erased
    ; Assumes ACCVIE = NMIIE = OFIE = 0.
    MOV #WDTPW+WDTHOLD,&WDTCTL ; Disable WDT
    L1 BIT #BUSY,&FCTL3 ; Test BUSY
    JNZ L1 ; Loop while busy
    MOV #FWPW,&FCTL3 ; Clear LOCK
    MOV #FWPW+WRT,&FCTL1 ; Enable write
    MOV #0123h,&0FF1Eh ; 0123h -> 0x0FF1E
    L2 BIT #BUSY,&FCTL3 ; Test BUSY
    JNZ L2 ; Loop while busy
    MOV #FWPW,&FCTL1 ; Clear WRT
    MOV #FWPW+LOCK,&FCTL3 ; Set LOCK
    ... ; Re-enable WDT?
  • Hello Michael,

    Were you able to solve your issue or do you still require support?

    Regards,
    Ryan
  • The solution was to move the programming routines to execute from Flash -- identical code but just running out of Flash instead of RAM.   Of course, the big difference is in how the processor behaves once the Write cycle is started.  Hardware stops the core from executing out of Flash until the write is complete (in the case where code is running from Flash location), whereas the polling loop is required when code is running from RAM location.  During the polling loop (when running from RAM), I will sometimes get a Flash Key Violation reset.   

    In our case, we can move on with the code located in Flash, so this is not a blocking problem for us.  

    I still believe the Flash Key Violation reset is a silicon problem that should be documented in the Errata.

**Attention** This is a public forum