This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32F407 Flash Erase

My problem occurs immediately after erasing a bock of the flash. This is a tough problem - it usually works, but sometimes locks up. I have done some searching, not found this elsewhere. I've been through the applicable parts that I can find in the STM manual, but no help. The closest is their comments:

Any attempt to read the Flash memory on STM32F4xx while it is being written or erased,
causes the bus to stall. Read operations are processed correctly once the program
operation has completed. This means that code or data fetches cannot be performed while
a write/erase operation is ongoing.

The FLASH_CR register is not accessible in write mode when the BSY bit in the FLASH_SR
register is set. Any attempt to write to it with the BSY bit set will cause the AHB bus to stall until the BSY bit is cleared.

I am a slow learner, not quite sure what they are saying here. It probably makes more sense in the original German. Does anyone know of any tech notes dealing specifically with these issues?

Moving right along, here is the function:

FLASH_Status FLASH_EraseSector(uint16_t FLASH_Sector)
{
  FLASH_Status status = FLASH_COMPLETE;

  if((FLASH_Sector != FLASH_Sector_10)&&(FLASH_Sector != FLASH_Sector_11))
  // sectors 10 & 11 only
  {
    status = FLASH_ERROR_WRP;                // set fault message
    return status;                           // exit without any damage
  }

  status = FLASH_WaitForLastOperation();     // Wait for last operation to be completed
gblDbgReg[1]=50;
  if(status == FLASH_COMPLETE)
  {
    /* if the previous operation is completed, proceed to erase the sector */
    FLASH->CR &= CR_PSIZE_MASK;              // the device voltage range is 2.7V to 3.6V,
    FLASH->CR |= FLASH_PSIZE_WORD;           // the operation is by word (32-bit)
    FLASH->CR &= SECTOR_MASK;                // clear out sector control bits
    FLASH->CR |= FLASH_CR_SER | FLASH_Sector;// set for sector erase and sector number
gblDbgReg[1]=51;
    FLASH->CR |= FLASH_CR_STRT;              // start erasing...
    // wait for about a second....
gblDbgReg[1]=52;
    status = FLASH_WaitForLastOperation();   // Wait for last operation to be completed
gblDbgReg[1]=53;
    FLASH->CR &= (~FLASH_CR_SER);            // turn off sector erase
    FLASH->CR &= SECTOR_MASK;                // clear out the sector number
  }
gblDbgReg[1]=54;
  return status;                                // Return the Erase Status
}

Usually, this works great. The lines with "gblDbgReg[1] assignments are non-functional, but allow me to see this going through its paces on the logic analyzer. It does exactly what I expect.

Other times, it hangs up. There is no recognized pattern. For a while yesterday, it was perhaps one time out of three on average. When these occurred, I observed the following:
- gblDbgReg[1] had a value of 53
- the program hung up until the watchdog reset the whole program
- I was able to catch it in the locked up state a couple times, in an interrupt handler that I do not think was ever called. I am assuming that the program jumped to an inappropriate place withing this function.
- It was never found in a FLASH_WaitForLastOperation() hangup

I have tried disabling / enabling interrupts, no change
I have tried salting with a few more FLASH_WaitForLastOperation() after commands were sent, no change

I rebuilt the entire program, and now I am no longer seeing a hangup. I have gone through dozens of attempts with no observed errors. What happened?

Parents
  •     FLASH->CR &= CR_PSIZE_MASK;              // the device voltage range is 2.7V to 3.6V,
    Maybe should be
        FLASH->CR &= (~CR_PSIZE_MASK);
    
        FLASH->CR |= FLASH_PSIZE_WORD;           // the operation is by word (32-bit)
    
    
        FLASH->CR &= SECTOR_MASK;                // clear out sector control bits
    Maybe should be
        FLASH->CR &= (~SECTOR_MASK);
    
        FLASH->CR |= FLASH_CR_SER | FLASH_Sector;// set for sector erase and sector number
    


    It looks like you could be erasing an unintended Sector. Could be a sector that contains code?

Reply
  •     FLASH->CR &= CR_PSIZE_MASK;              // the device voltage range is 2.7V to 3.6V,
    Maybe should be
        FLASH->CR &= (~CR_PSIZE_MASK);
    
        FLASH->CR |= FLASH_PSIZE_WORD;           // the operation is by word (32-bit)
    
    
        FLASH->CR &= SECTOR_MASK;                // clear out sector control bits
    Maybe should be
        FLASH->CR &= (~SECTOR_MASK);
    
        FLASH->CR |= FLASH_CR_SER | FLASH_Sector;// set for sector erase and sector number
    


    It looks like you could be erasing an unintended Sector. Could be a sector that contains code?

Children