2022-11-17 05:05 AM
Hi guys,
I am using and STM32L552ZET6 and I get a behavior I can not exaplain. The device is power at 1.8V in case it matters. So to put it shortly I have 2 blocks of 8 pages each. At first start I erase both of the blocks and write only in block 1 some data. When I get some data to save I write it in block 2 but first I write two doublewords used as markers on top of the first page of block 2 after which I copy most of the data from the first block. My problem is that for the first 24 octets I try to write I get back NSPROGERR and NSPGSERR, and for the rest everything works out great and are written.
If I erase the page again just before writeing I get no errors and everything gose perfect.
I have tried to debug it by printing the info found in the locations just before programming and I get 0xFFFFFFFFFFFFFFFF in each location with problems.
This is the function I use to program:
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
{
uint32_t primask_bit;
__IO uint32_t *reg;
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
/* Access to SECCR or NSCR registers depends on operation type */
reg = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
if((Address>=0x08078000 && Address<(0x08078000 +0x0018)) ||(Address>=0x0807C000 && Address<(0x0807C000 +0x0018)))
{
uint8_t c[10];
hex2str(*(uint32_t*)Address,c,4);
USART_AddBuffer(2, c,10, 1);
hex2str(*(uint32_t*)(Address+4U),c,4);
USART_AddBuffer(2, c,10, 1);
USART_TransmitBuffers(2);
}
/* Disable interrupts to avoid any interruption during the double word programming */
primask_bit = __get_PRIMASK();
__disable_irq();
/* Set PG bit */
SET_BIT((*reg), FLASH_NSCR_NSPG);
/* 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();
/* Program second word */
*(uint32_t*)(Address+4U) = (uint32_t)(Data >> 32U);
/* Re-enable the interrupts */
__set_PRIMASK(primask_bit);
}
This function is called from this function:
uint8_t FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
{
uint8_t status=FLASH_OK;
__IO uint32_t *reg;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
if(status == FLASH_OK)
{
pFlash.ProcedureOnGoing = TypeProgram;
reg = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
/* Program double-word (64-bit) at a specified address */
FLASH_Program_DoubleWord(Address, Data);
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
/* If the program operation is completed, disable the PG Bit */
CLEAR_BIT((*reg), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK)));
}
else
{
status=FLASH_LAST_OP;
}
/* Process Unlocked */
return status;
}
Mainly the ideea is I get the NSPGSERR and NSPROGERR even if on the locations I want to write is 0xFFFFFFFFFFFFFFFF. I have checked this by reading before writing and also using STMProgrammer.
Solved! Go to Solution.
2022-11-17 05:33 AM
Error code correction (ECC) Dual bank mode (DBANK=1, 64-bits data width) Data in Flash memory are 72-bits words: 8 bits are added per double word (64 bits). The ECC mechanism supports: • One error detection and correction per 64 double words • Two errors detection
You cant prog twice irelevant FFF
2022-11-17 05:33 AM
Error code correction (ECC) Dual bank mode (DBANK=1, 64-bits data width) Data in Flash memory are 72-bits words: 8 bits are added per double word (64 bits). The ECC mechanism supports: • One error detection and correction per 64 double words • Two errors detection
You cant prog twice irelevant FFF
2022-11-17 06:39 AM
Regarding ECC I do not use it, but this part "You cant prog twice irelevant FFF" made me realise somthing......when I program the controller first time I write that page with FFFF....
2022-11-17 06:44 AM
You cant dont use ECC, is by design on FLASH, read reference manual about internal flash.