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.
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:
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
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