Skip to main content
Visitor II
June 19, 2025
Solved

Minimal Write Single Byte to Flash EDATA on H533

  • June 19, 2025
  • 3 replies
  • 432 views

I am trying to write a single byte of data to the start of the EDATA area on the H533

I have the EDATA Sector 1 set to active via the option bytes.

 

static FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t flash_sector_error;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.Sector = 24;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.NbSectors =1;

HAL_FLASH_Unlock();
if (HAL_FLASHEx_Erase(&EraseInitStruct, &flash_sector_error) != HAL_OK){
	SEND_STRING("FLASH ERASE FAIL\r\n");
}

//HARDFAULT OCCURS HERE |V|
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD_EDATA, 0x08030000, (uint32_t ) 43210) != HAL_OK){
	SEND_STRING("FLASH WRITE FAIL\r\n");
}
HAL_FLASH_Lock();

 From my understanding in the reference manual the EDATA starts at 8030000 and is in sector 24 of bank 1. 

The erase option works fine, but the HAL_FLASH_Program operation always causes a hard fault.

Suggestions? Next Steps for debugging?

    This topic has been closed for replies.
    Best answer by TG_APCD

    I think I found the missing secret here.

    I was missing the HAL_FLASH_OB_Launch(); call which sets the Option Start bit. 

    //configure option bits
    HAL_FLASHEx_OBProgram(&FLASH_OBInitStruct);
    HAL_FLASH_OB_Launch(); //set the OPTSTART bit in OPTCR

     

     

    3 replies

    ST Employee
    June 20, 2025

    Hello @TG_APCD

    If you read a flash high-cycle data not previously written, a double ECC error is reported and only a word full of set bits is returned. The ECC correction reports a double-error detection (ECCD) and ECCD implies an NMI raised. 

    Check this article: How to avoid a HardFault when ICACHE is enabled on the STM32H5 series

    TG_APCDAuthor
    Visitor II
    June 20, 2025

    Thanks, I'm not reading the region, I am erasing and then programming it. 

    I read through the linked article, and based on that I went and checked all the FLASH error registers to see if there were any flags raised following the fault.

    I checked the NSCR, SECCR, NSSR, and the ECCDETR registers and didn't see any error flags raised there.

    This is the state of the FLASH registers immediately following the hard fault.

    ACR			0x1 	
    NSKEYR			0x0 	
    SECKEYR			0x0 	
    OPTKEYR			0x0 	
    NSOBKKEYR			0x0 	
    SECOBKKEYR			0x0 	
    OPSR			0x0 	
    OPTCR			0x1 	
    NSSR			0x0 	
    SECSR			0x0 	
    NSCR			0x602 	
    SECCR			0x0 	
    NSCCR			0x0 	
    SECCCR			0x0 	
    
    	
    PRIVCFGR			0x0 	
    NSOBKCFGR			0x1ff0001 	
    SECOBKCFGR			0x0 	
    HDPEXTR			0x0 	
    	
    OPTSR_CUR			0x2d30edf8 	
    OPTSR_PRG			0x2d30edf8 	
    
    NSEPOCHR_CUR			0x1 	
    NSEPOCHR_PRG			0x0 	
    SECEPOCHR_CUR			0x1 	
    SECEPOCHR_PRG			0x0 	
    OPTSR2_CUR			0xc300015c 	
    OPTSR2_PRG			0xc300015c 	
    
    
    NSBOOTR_CUR			0x80000c3 	
    NSBOOTR_PRG			0x80000c3 	
    SECBOOTR_CUR			0x0 	
    SECBOOTR_PRG			0x0 	
    OTPBLR_CUR			0x0 	
    OTPBLR_PRG			0x0 	
    
    SECBB1R1			0x0 	
    	
    PRIVBB1R1			0x0 	
    
    SECWM1R_CUR			0x7 	
    SECWM1R_PRG			0x0 	
    WRP1R_CUR			0xff 	
    WRP1R_PRG			0xff 	
    EDATA1R_CUR			0x0 	
    EDATA1R_PRG			0x8000 	
    HDP1R_CUR			0x1 	
    HDP1R_PRG			0x1 	
    ECCCORR			0x0 	
    ECCDETR			0x0 	
    ECCDR			0x0 	
    	
    SECBB2R1			0x0 	
    
    PRIVBB2R1			0x0 	
    
    SECWM2R_CUR			0x7 	
    SECWM2R_PRG			0x0 	
    WRP2R_CUR			0xff 	
    WRP2R_PRG			0xff 	
    EDATA2R_CUR			0x0 	
    EDATA2R_PRG			0x0 	
    HDP2R_CUR			0x1 	
    HDP2R_PRG			0x1 	

     Also I realized there was another mistake in the code. I was not passing the pointer to the value to be written but the value itself, which I have fixed. 

    But that has not resolved the hard fault.

    See the updated code below:

    static FLASH_EraseInitTypeDef EraseInitStruct;
    uint32_t flash_sector_error;
    EraseInitStruct.Banks = FLASH_BANK_1;
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
    EraseInitStruct.Sector = 24;
    EraseInitStruct.Banks = FLASH_BANK_1;
    EraseInitStruct.NbSectors =1;
    uint32_t data_to_be_written =43210;
    if(HAL_FLASH_Unlock()==HAL_OK)
    {
    	SEND_STRING("FLASH UNLOCKED\r\n");
    }
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &flash_sector_error) != HAL_OK){
    	SEND_STRING("FLASH ERASE FAIL\r\n");
    }
    else
    {
    	SEND_STRING("FLASH ERASE OK\r\n");
    }
    
    //HARDFAULT OCCURS HERE |V|
    if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD_EDATA, FLASH_ADDR, (uint32_t *)data_to_be_written) != HAL_OK){
    	SEND_STRING("FLASH WRITE FAIL\r\n");
    }
    else
    {
    	SEND_STRING("FLASH WRITE OK\r\n");
    }
    HAL_FLASH_Lock();

     

    Also for reference I am not using the ICACHE. 

    TG_APCDAuthorAnswer
    Visitor II
    June 26, 2025

    I think I found the missing secret here.

    I was missing the HAL_FLASH_OB_Launch(); call which sets the Option Start bit. 

    //configure option bits
    HAL_FLASHEx_OBProgram(&FLASH_OBInitStruct);
    HAL_FLASH_OB_Launch(); //set the OPTSTART bit in OPTCR