Page 1 of 1
Flash write routine for STM32F0
Posted: Thu Jul 20, 2017 5:21 pm
by nullbert
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!
Re: Flash write routine for STM32F0
Posted: Wed Jul 26, 2017 7:25 am
by rew
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...