Flash write routine for STM32F0

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

nullbert
Posts: 19
Joined: Tue Aug 30, 2016 7:12 pm
Been thanked: 1 time

Flash write routine for STM32F0

Postby nullbert » Thu Jul 20, 2017 5:21 pm

Hi,

We have a project using the STM32F042 and ChibiOS. We have a need to store some configuration data in the processor's flash.

Anyone have an example that writes to flash memory on F0?

Thanks for any help!

rew
Posts: 380
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 13 times

Re: Flash write routine for STM32F0

Postby rew » Wed Jul 26, 2017 7:25 am

I use this:

Code: Select all

#define MY_FLASH_SIZE (( *(short *)0x1ffff7cc) << 10)
#define FLASH_TOT_SIZE 0x10000  // 64k.
#define FLASH_PAGE_SIZE  0x400    // 1k

#define FLASH_EE_REGION (FLASH_BASE + MY_FLASH_SIZE - FLASH_PAGE_SIZE)
//#define FLASH_EE_REGION (FLASH_BASE + FLASH_TOT_SIZE - FLASH_PAGE_SIZE)




#define flash_wait_nb() while ( FLASH->SR & FLASH_SR_BSY)

#if 0
static void write_to_flash (void *data, int len)
{
  int i;

  len++; // Convert to halfwords (= 16 bits, shorts).
  len = len >> 1;

  for (i=0;i<len;i++)
    if (((unsigned short *)FLASH_EE_REGION)[i] != ((unsigned short *)data)[i]) break;

  // The data there is already OK.
  if (i == len) return;

  //myprintf (CONSOLE, "CR: %x ", FLASH->CR);
  if (FLASH->CR & FLASH_CR_LOCK) {
    //myprintf (CONSOLE, " unlocking ");
    FLASH->KEYR = 0x45670123;
    FLASH->KEYR = 0xcdef89ab;
  }
  //myprintf (CONSOLE, "CR: %x ", FLASH->CR);

  for (i=0;i<len;i++)
    if (((unsigned short *)FLASH_EE_REGION)[i] != 0xffff) break;

  if (i != len) {
    //myprintf (CONSOLE, "\r\nNeed an erase... ");
    if ( FLASH->SR & FLASH_SR_EOP) {
      //pr_hex (CONSOLE, " SR1: ", FLASH->SR);
      //my_puts (CONSOLE, "reset EOP ");
      FLASH->SR |= FLASH_SR_EOP;
      //pr_hex (CONSOLE, " SR2: ", FLASH->SR);
    }
    flash_wait_nb ();
    FLASH->CR = FLASH_CR_PER;
    //myprintf (CONSOLE, " CR1: %x", FLASH->CR);
    //myprintf (CONSOLE, " SR3: %x", FLASH->SR);
    //myprintf (CONSOLE, " EER: %x", FLASH_EE_REGION);
    FLASH->AR = FLASH_EE_REGION;
    FLASH->CR |= FLASH_CR_STRT;

    //myprintf (CONSOLE, " CR2: %x", FLASH->CR);

    flash_wait_nb ();

    //myprintf (CONSOLE, "erase done.\r\n");

    FLASH->CR &= ~FLASH_CR_PER;

    //pr_hex (CONSOLE, " CR: ", FLASH->CR);
    //pr_hex (CONSOLE, " SR: ", FLASH->SR);
  }

  FLASH->CR |= FLASH_CR_PG;

  for (i=0;i<len;i++)
    ((unsigned short *)FLASH_EE_REGION)[i] =  ((unsigned short *)data)[i];


  FLASH->CR &= ~FLASH_CR_PG;

  FLASH->CR |= FLASH_CR_LOCK;
  myprintf (CONSOLE, "Write OK!");
 
}


Some things are still a bit "quick and dirty". So you can still see the switch from "we always have 64k flash" to: ask the CPU how much we have. But the flash page size, if it's always 1k... I don't know. It is on the F072 that I use.... The address where you can find "how much flash does this CPU have?" differs from CPU to CPU. And I should probably use a define...


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 15 guests