Hi,
I'm trying to write a byte in UTEST sector in this block:
NB: API is called at init with interrupts disabled.
This is my code:
HostFlash_Program((uint32_t )0x1B000780U, (uint8_t* )hseFwFeatureFlagEnabledValue, (uint32_t)8U);
eel_status_t HostFlash_Program( uint32_t Address, uint8_t* SourceAddress, uint32_t Length)
{
uint32_t ErrorFlags;
C40_Ip_StatusType C40_Ip_Status = STATUS_C40_IP_ERROR ;
const uint8_t *DataPtr8 = SourceAddress;
volatile uint32_t DataTemp32; /* Prevent compiler optimization when working with unaligned addresses */
/* Disable HV to finalize/abort the operation */
Fsld_FlashInstance->MCR &= ~FLASH_MCR_EHV_MASK;
/*Clear ERS and PGM bits */
Fsld_FlashInstance->MCR &= ~(FLASH_MCR_PGM_MASK|FLASH_MCR_ESS_MASK|FLASH_MCR_ERS_MASK);
/* Disable watchdog interrupt */
Fsld_FlashInstance->MCR &= ~FLASH_MCR_WDIE_MASK;
/* No interrupt request will be generated when the DONE flag is set */
Fsld_FlashInstance->MCR &= ~FLASH_MCR_PECIE_MASK;
/* Clear all error flags for main interface */
Fsld_FlashInstance->MCRS &= FLASH_MCRS_EER_MASK | \
FLASH_MCRS_SBC_MASK | \
FLASH_MCRS_AEE_MASK | \
FLASH_MCRS_EEE_MASK | \
FLASH_MCRS_RVE_MASK | \
FLASH_MCRS_RRE_MASK | \
FLASH_MCRS_RWE_MASK | \
FLASH_MCRS_PES_MASK | \
FLASH_MCRS_PEP_MASK;
/* Sector is in Utest */
Fsld_PFlashInstance->PFCBLKU_SPELOCK[0u] &= FSLD_MASK_UNLOCK_UTEST_SECTOR;
/* Write the address to be programmed */
Fsld_PFlashInstance->PFCPGM_PEADR_L = Address;
DataTemp32 = (uint32_t)DataPtr8[0U] << 0U;
DataTemp32 |= (uint32_t)DataPtr8[1U] << 8U;
DataTemp32 |= (uint32_t)DataPtr8[2U] << 16U;
DataTemp32 |= (uint32_t)DataPtr8[3U] << 24U;
Fsld_FlashInstance->DATA[0U] = DataTemp32;
DataTemp32 = (uint32_t)DataPtr8[4U] << 0U;
DataTemp32 |= (uint32_t)DataPtr8[5U] << 8U;
DataTemp32 |= (uint32_t)DataPtr8[6U] << 16U;
DataTemp32 |= (uint32_t)DataPtr8[7U] << 24U;
Fsld_FlashInstance->DATA[1U] = DataTemp32;
/* Setup program operation */
Fsld_FlashInstance->MCR |= FLASH_MCR_PGM_MASK;
/* Start internal erase/program sequence */
Fsld_FlashInstance->MCR |= FLASH_MCR_EHV_MASK;
while (0U == ((Fsld_FlashInstance->MCRS & FLASH_MCRS_DONE_MASK) >> FLASH_MCRS_DONE_SHIFT))
{
}
ErrorFlags = Fsld_FlashInstance->MCRS & (FLASH_MCRS_PEG_MASK | FLASH_MCRS_PEP_MASK | FLASH_MCRS_PES_MASK);
/* Program/Erase Good: only PEG = 1; both PEP and PES should be 0 */
if (FLASH_MCRS_PEG_MASK == ErrorFlags)
{
C40_Ip_Status = STATUS_C40_IP_SUCCESS;
}
else
{
C40_Ip_Status = STATUS_C40_IP_ERROR;
}
/* terminate program operation */
Fsld_FlashInstance->MCR &= ~FLASH_MCR_EHV_MASK;
/* Terminate program operation */
Fsld_FlashInstance->MCR &= ~FLASH_MCR_PGM_MASK;
/* The write job has finished or the end of the sector was reached. Time to lock the sector */
Fsld_PFlashInstance->PFCBLKU_SPELOCK[0u] |= FSLD_MASK_LOCK_UTEST_SECTOR;
if( STATUS_C40_IP_SUCCESS == C40_Ip_Status )
{
return EEL_OK ;
}
else
{
return EEL_ERR_PARAMETER ;
}
}
If I don't place the function in RAM, it writes the byte but, just after the write uC generates a hard fault
#case 2
If I place the function in RAM, no hard fault occurs, but write operation fails. Byte is not written in UTEST sector.
Can you help me?
Thanks a lot.
Solved! Go to Solution.
SOLUTION:
I have separated the setting of PGM and EHV bits in two differents API.
SOLUTION:
I have separated the setting of PGM and EHV bits in two differents API.
The UTEST Sector is an OTP (One Time Programmable). This causes the erase operations not to be allowed. You only going to be able to append new data or configuration and read data.
Writing the desired data in the UTEST Sector is the same process used to program data in other blocks.
Please check the following post. Is from other topics but explains how to write data in a UTEST sector.
[S32K3] Restrict the debug access with a password when HSE is not used
B.R.
VaneB
Hi vanessa,
I have tried your same code, the write in UTEST is correctly performed but just after the write uC goes in hard fault:
eel_status_t HostFlash1_Program(void)
{
C40_Ip_StatusType flashStatus;
uint32_t DcfRecord[2] = {0x00000100, 0x00100004};
/* If the target address is un-programmed state, start the programming process. */
if( (*(uint32_t *)0x1B000770 == 0xFFFFFFFF) && (*(uint32_t *)(0x1B000770+4) == 0xFFFFFFFF) )
{
/* Must unlock the UTEST Flash area before programming. */
Fsld_PFlashInstance->PFCBLKU_SPELOCK[0u] &= 0xFFFFFFF0U;
/* Write the new DCF records into UTEST Flash. */
flashStatus = C40_Ip_MainInterfaceWrite(0x1B000770, 8, (uint8_t *)(&DcfRecord[0]));
/* Cache_Ip_CleanByAddr(CACHE_IP_DATA, TRUE, TargetAddress, 8); */
/* Poll the Flash status until the programming sequence is done. */
do {
flashStatus = C40_Ip_MainInterfaceWriteStatus();
}while(STATUS_C40_IP_SUCCESS != flashStatus);
/* Must lock the UTEST Flash area after programming. */
Fsld_PFlashInstance->PFCBLKU_SPELOCK[0u] |= 0x0000000FU;
}
if( STATUS_C40_IP_SUCCESS == flashStatus )
{
return EEL_OK ;
}
else
{
return EEL_ERR_PARAMETER ;
}
}
Can you explain me why?
Best regarsds, Anna
Does the MCU go to Hard Fault when you lock the UTEST sector? Or does this happen when the MCU terminates the ostFlash1_Program(void)?
Hi vanessa,
the MCU goes in hard fault when calls the API:
flashStatus = C40_Ip_MainInterfaceWriteStatus();
Best regards,
Anna
As mentioned, the UTEST Sector is an OTP (One Time Programmable). So, if you already write data in an address, you cannot append new data or configuration.
If the first time the data was written successfully, if you run the code, it causes a hard fault because that address is no longer accessible for writing.
Hi Vanessa
address where I try to write is empty, so I CAN write.
The data are effectively written but during the read of Write status (DONE bit) an hard fault occurs.
I hope to be clear now.
See the images that I have attached to issue, please.
Anna
Could you please verify if this behavior also presents with the C40_Ip_Example?
Ok ,I will verity it.
I faced same issue. controller was going to hard fault for both RAM and Flash region execution.
I tried adding 5ms delay inside "C40_Ip_MainInterfaceWrite" function. please refer from below.
if (TRUE == C40_Ip_bAsync)
{
/* Start flash access */
C40_Ip_FlashAccessCalloutStart();
HAL_DelayMs(5);
/* Start internal erase/program sequence */
C40_Ip_pFlashBaseAddress->MCR |= FLASH_MCR_EHV_MASK;
HAL_DelayMs(5);
}
its working for me, executing from flash region.
Hi,
delay doens't solve the hard fault in my application.
Do you have any suggests?
Best regards,
Anita