0
\$\begingroup\$

I am using STM32F3 and I could not erase its flash.

Below codes include address,

where is my fault?

void eraseFlash()       

{
  HAL_StatusTypeDef status = HAL_ERROR;

  while(HAL_FLASH_Unlock()!=HAL_OK)
    while(HAL_FLASH_Lock()!=HAL_OK);
  while(HAL_FLASH_OB_Unlock()!=HAL_OK)
    while(HAL_FLASH_OB_Lock()!=HAL_OK);
   

  while((FLASH->SR & 0x00000001) != 0);  
    
  FLASH->SR |= 1 << 5;        
  FLASH->SR |= 1 << 4;
 
  FLASH->CR |= 1 << 1;
  FLASH->AR = 0x08008000;
  FLASH->CR |= 1 << 6;          
   
  FLASH->CR |= 1 << 1;  
  FLASH->AR = 0x08008800    
  FLASH->CR |= 1 << 6;
    
  FLASH->CR |= 1 << 1; 
  FLASH->AR = 0x08009000;    
  FLASH->CR |= 1 << 6;
    
  while((FLASH->SR) & (1<<5));           

  while(((FLASH->SR) & (1<<5)) != 0) {
    FLASH->SR |= 0x00100000;      
  }

  FLASH->CR &= ~0x00000002;        
  
  while(HAL_FLASH_Lock()!=HAL_OK)
    while(HAL_FLASH_Unlock()!=HAL_OK);

  /* Lock Access to option bytes sector */
  while(HAL_FLASH_OB_Lock()!=HAL_OK)
    while(HAL_FLASH_OB_Unlock()!=HAL_OK);
    
}
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

08008000 This is an octal number, not hex. Which means that you aren't even posting the real code, because this won't compile - octal numbers can't contain 8. Please don't post slop which you haven't even compiled, post a copy/paste of the real code.

Now while you are at it, drop the habit of including leading zeroes in front of your hex constants. They only create bugs and accidentally signed numbers, since int is unhelpfully signed by default. The integer constant system in C is overall subtle and dumb.

Lets assume we have a 16 bit MCU with 16 bit int. Then:

0x1         // This is type int
0x000000001 // This is still type int, still 16 bits
0x4000      // This is type int
0x8000      // This is type unsigned int, ouch
0x00008000  // This is still unsigned int, 16 bits
0x80000     // This is type long, 32 bit signed
0x00080000  // This is still type long
0x80000000  // This is unsigned long

As you hopefully can tell, this creates a bunch of subtle type problems. So you should drop the superfluous leading zeroes, and most importantly:

Always end your hex constants with u or U suffix! You don't want signed numbers that can turn negative or invoke undefined behavior.

\$\endgroup\$
1
  • \$\begingroup\$ When I copy to here, I deleted 0x wrongly but I have 0x in real code \$\endgroup\$
    – gogogo
    Aug 11, 2021 at 14:15
1
\$\begingroup\$

Your code seems more complicated than it needs to be. First, get rid off magic numbers and use predefined bit names. Your unlock sequence also don't need nested loop checks I guess (if I'm not missing something). Also, it's better to wait after each page erase. Maybe it's not essential as the code execution from flash stalls during flash write and erase operations, but waits may become necessary when using dual-bank devices, or execution from RAM.

Here is some C++ code I use for STM32F0 & F1. F3 uses a similar flash hardware, so the code can be ported with little effort.

constexpr uint32_t FlashStart {0x8'000'000};

constexpr size_t PageSize(uint16_t page)
{
    return 1024; // All pages are 1 kB on STM32F030
}

constexpr uint32_t PageStartAdr(uint16_t page)
{
    return page * PageSize(page) + FlashStart;
}

inline static void waitFlash()
{
    while ((FLASH->SR & FLASH_SR_BSY) != 0);
}

inline static void unlockFlash()
{
    static constexpr uint32_t Key1 {0x4567'0123};
    static constexpr uint32_t Key2 {0xCDEF'89AB};
    __disable_irq();
    FLASH->KEYR = Key1;
    FLASH->KEYR = Key2;
    __enable_irq();
}

inline static void lockFlash()
{
    FLASH->CR |= FLASH_CR_LOCK;
}

void erasePage(uint16_t page)
{
    waitFlash();
    if ((FLASH->CR & FLASH_CR_LOCK) != 0) unlockFlash();
    FLASH->CR |= FLASH_CR_PER; // Page erase mode
    FLASH->AR = PageStartAdr(page);
    FLASH->CR |= FLASH_CR_STRT; // Start the operation
    waitFlash();
    FLASH->CR &= ~FLASH_CR_PER; // Disable page erase mode
    lockFlash();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.