cancel
Showing results for 
Search instead for 
Did you mean: 

write without Erase to the specified address with 0xffffffffffffffff value , in stm32g030 Family

Samira Foroughi
Associate II

Hello

I created a simple project in cubeMX, based on the STM32G030F6PX micro.

I'm going to write on the micro only once, at a specific address.

I defined a variable at the beginning of the sixth page and set it to 0xFFFFFFFFFFFFFFFFFUL.

uint64_t TestAddressVALUE = 0x001122334455667788UL;
const uint64_t TestAddress __attribute __ ((at (0x08003000))) = (uint64_t) (0xFFFFFFFFFFFFFFFFFUL);

And then I write in that address by the following code.

HAL_FLASH_Unlock ();
HAL_FLASH_Program (FLASH_TYPEPROGRAM_DOUBLEWORD, ((uint32_t) (& TestAddress)), (uint64_t) (TestAddressVALUE));
HAL_FLASH_Lock ();

When I program the micro with ST-Link, everything is ok and my code works well. But when I program it with same hex code, by usart, the write operation is not performed at the specified address and the following error occurs.

HAL_ERROR
HAL_FLASH_ERROR_PROG

I followed this error and came to this guide.

Bit 3 PROGERR: Programming error
Set by hardware when a double-word address to be programmed contains a value different
from '0xFFFF FFFF' before programming, unless the data to write is '0x0000 0000'.
Cleared by writing 1

But I already put the value 0xFFFFFFFFFFFFFFFFUL in the address.

I followed the FLASH-> SR register value in the FLASH_Program_DoubleWord function.

  

static void FLASH_Program_DoubleWord (uint32_t Address, uint64_t Data)
{
assert_param (IS_FLASH_PROGRAM_ADDRESS (Address));
/ * Set PG bit * /
  SET_BIT (FLASH-> CR, FLASH_CR_PG);
 
  / * Program first word * /
  * (uint32_t *) Address = (uint32_t) Data;
 
  / * Barrier to ensure programming is performed in 2 steps, in right order
    (independently of compiler optimization behavior) * /
  __ISB ();
printf ("\ r \ n 1FLASH-> SR =% 08X", FLASH-> SR);
  / * Program second word * /
  * (uint32_t *) (Address + 4U) = (uint32_t) (Data >> 32U);
printf ("\ r \ n 2FLASH-> SR =% 08X", FLASH-> SR);
}

Exactly after the ISB function, the value of FLASH-> CR is equal to 0x00040000, but after executing the code line

* (uint32_t *) (Address + 4U) = (uint32_t) (Data >> 32U);

Its value changes to 0x00000008. That is, there is a problem with the second burn byte.

I wonder why this is not a problem with st-link and only with usart this problem occurs.

It is necessary to explain that:

 If I erase the page before writing, I have no problem. But I cannot erase it. In the stm32f0 family, a memory cell with a value of 0xff could be written without need the erase.

Please help if you have an idea. 

4 REPLIES 4
Danish1
Lead II

If the documentation only says that the memory must be 0xff before writing any other value then it is an oversimplification. The reason is that as well as the data bits that you read (and write once) there are error-correction bits, perhaps 9 for every 64 data bits.

These error-correction bits also get erased during a page-erase.

The problem is that the error-correction bit-pattern for 0xffffffffffffffff is not 0x1ff, so writing that data to flash will clear some of the error-correction bits, making it impossible to reprogram that line of FLASH again until erase.

Why do ST use error-correction? Because it allows them to use smaller and faster FLASH memory cells while still guaranteeing that every bit will be read back perfectly. The complications over programming are, I believe, a price worth paying to get faster, cheaper, lower-power-consuming chips which error-correction gives.

But if ST’s documentation merely says that the Flash should be 0xffffffffffffffff before writing then this is wrong and should be corrected urgently. And ST should ensure that all their employees who write and check the documentation actually understand the advanced technology they are describing, and are not under pressure to publish the data-sheet and reference manual before they have been checked. Rent over.

Hope this helps,

Danish

Samira Foroughi
Associate II

thanks for your response.

Do you think there is no way to change the error-correction bit manually?

BenMack99
Associate III

Thanks Danish, most useful. I have also hit this problem.

It is partially covered in Errata 2.2.5

https://www.st.com/resource/en/errata_sheet/es0486-stm32g030x6x8-device-errata-stmicroelectronics.pdf

Though I find the problem also happens when I try to write non-zero values, errata says just zeros. Your point about error correction bits explains this.

As you say, ST should really sort their documentation!

BenMack99
Associate III

I notice other threads about this problem, for example here

This is a headache for us, for example we have F0 designs with Flash-based event counters that clear 1 bit at a time, that we've been asked to "upgrade" to G0...

If anyone from ST is listening, please please update your documentation. For example

RM0454 3.7.4 FLASH status register - PROGERR: Set by hardware when a double-word address to be programmed contains a value different from '0xFFFF FFFF' before programming, except if the data to write is '0x0000 0000'. - wrong on two counts....

RM0454 3.3.3 FLASH ECC - makes no mention of this problem

Finally, I'm no expert on ECC, but couldn't they have added a means to disable ECC on specific u64 words, for example by setting the ECC byte for that word to 0?