Why do I get a core lockup when trying to program FlexNVM?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why do I get a core lockup when trying to program FlexNVM?

1,982 Views
Laartoor
Contributor III

I have a strange problem with the MK10DX256VLH7. I use the program section command to program the flash:

FTFL_FCCOB30x00
FTFL_FCCOB20x08
FTFL_FCCOB10x80
FTFL_FCCOB00x0b
FTFL_FCCOB70x00
FTFL_FCCOB60x00
FTFL_FCCOB50x1b
FTFL_FCCOB40x00
FTFL_FCCOBB0x00
FTFL_FCCOBA0x00
FTFL_FCCOB90x00
FTFL_FCCOB80x00

and then use the following code to execute the flash command (code is located in flash block 0):

bool FlashInterface::isBusy() {

  return  ( FTFL_BASE_PTR->FSTAT & FTFL_FSTAT_CCIF_MASK) == 0;

}

static volatile int waitsAfterStart = 10;

void FlashInterface::clearErrorsAndStartCommand() {

    FTFL_BASE_PTR->FSTAT = FTFL_FSTAT_CCIF_MASK | FTFL_FSTAT_RDCOLERR_MASK |

            FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_ACCERR_MASK;

  

    int waits = waitsAfterStart;

    while( waits > 0 && isBusy()) {

        waits--;

        DelayCycles< 100>::delay();

    }

}

When I run this, it causes a core lockup. I can catch it before the reset as a hard fault, which provides me with the reason "Bus fault on vector table read". SCB_SFSR tells me "instruction bus error". SCB_BFAR shows the bus fault address as 0xe000edf8, which is the debug core register DCRDR. When I look at the FSTAT register at the hard fault, I see that RDCOLERR is set.

So the flash controller stalls when reading from Program Flash, while Program Section updates a part of Data Flash. How can this be? According to the data sheet, Program Flash Reads are allowed simultaneously with Data Flash Program and Erase operations, and the Program LongWord as well as Erase Flash Block commands work without a problem in parallel to Program Flash Reads.

Is this a problem specific to this chip? If so, why is it not mentioned in the errata notes?
Or is this a design decision for the flash module? If so, why it is not described in the data sheet / reference manual?

I know the workaround is to start the operation from RAM, and also wait there for completion before returning. But I am very disappointed that this does not work, it would have made it much easier to update a block of flash while keeping the rest of the system fully responsive.

Labels (1)
0 Kudos
6 Replies

1,198 Views
Laartoor
Contributor III

The wait has been inserted only for debugging, to help me figure out what is going wrong.

The problem is that:

a) I use the program section command (0x0B) to initiate a write to data flash in block 1

b) I do not touch block 1 or the FlexRAM

c) But I still lock up when my code is read from block 0

The data sheet tells me that I can read from block 0 while programming or erasing something in block 1. And it works perfectly with the erase sector command (0x09), and I also see no problems with Program Long Word (0x06). But why does Program Section fail?

0 Kudos

1,198 Views
vespaman
Contributor III

I have exactly this problem now; K10DX256VMD10, mask 4N22D. I am trying to Erase/Program dataflash (flash block 1) using section ram.

I am not using the dataflash for anything - no code, no ee, no nothing. Yet, I am getting Core lockups on the first section I try to do.

If I restart the target/reload debugger, it can sometimes work, and when it works, it will work until the next target restart. Something needs initialization, that I am missing?

If I step through the code, it seams to work.

Just to be sure, I have disabled interrupts during flash works.

I have not been able to find anyone that have found a solution to this. :smileysad:

0 Kudos

1,198 Views
vespaman
Contributor III

OK, I found my mistake - I had a initialization routine that accidently wrote a the FSTAT_CCIF without having loaded proper command code data. :smileyblush:

After taking care about that, it works. I have to have interrupts disabled during programming though, which I find odd, since there's no references to the data area in the interrupts?

0 Kudos

1,198 Views
paulmartin
Contributor III

Ok i think it is just a simple logic error here:

while( waits > 0 && isBusy()) {

It waits while wait is larger than 0 !!!AND!!! the flash is busy.

It should be OR.

Did not see it the first time.

My own code looks something like this:

interrupts disabled

check flash errors

start flash command

wait for flags to be zero (instead of waiting a fixed amount)

wait for flags to be not zero

interrupts enabled

0 Kudos

1,198 Views
paulmartin
Contributor III

Do you have any kind of interrupt that could trigger a read on the data flash while the algoritm is writing/waiting?

If so, deactivate all of them for testing and see if the flash programming runs without error.

0 Kudos

1,198 Views
Laartoor
Contributor III

Definitely not the case, this happens in unit test done before the system is running. The error occurs always at almost exactly the same time, with a variance of maybe 4 cycles, a couple hundred cycles after launching the program section command. Looks like it happens directly after the delay(). This makes sense, the loop in the delay is cached by the flash accelerator, when the loop finishes, it needs to read from Flash => boom.

But still thank you, I have gone through the rest of the code, and actually missed an instance where I forgot to check that the data flash is not active before accessing it.

0 Kudos