2021-01-04 03:02 AM
I've created a project using STM32H7B3I-DK eval board with all settings default, unmodified, taken from TouchGFX. UI menu is working fine with some resources stored in OSPI Flash memory.
Now I wish to store some data in this OSPI memory. The procedure should be to disable Memory Mapped Mode, erase, write and enable Memory Mapped Mode again. All this I do with task switch disabled so that TouchGFX doesn't access OSPI Flash during the process.
I have problems with switching from Memory Mapped Mode to Indirect Mode and returning to MMP again.
I have modified MX_OCTOSPI1_Init() function by adding a test loop at the end to use it as a test procedure (memory settings are not modified).
static void MX_OCTOSPI1_Init(void)
{
/* USER CODE BEGIN OCTOSPI1_Init 0 */
/* USER CODE END OCTOSPI1_Init 0 */
/* USER CODE BEGIN OCTOSPI1_Init 1 */
/* USER CODE END OCTOSPI1_Init 1 */
/* OCTOSPI1 parameter configuration*/
hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 1;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
hospi1.Init.DeviceSize = 26;
hospi1.Init.ChipSelectHighTime = 2;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi1.Init.ClockPrescaler = 3;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi1.Init.ChipSelectBoundary = 0;
hospi1.Init.ClkChipSelectHighTime = 0;
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi1.Init.MaxTran = 0;
hospi1.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI1_Init 2 */
BSP_OSPI_NOR_Init_t Flash;
Flash.InterfaceMode = BSP_OSPI_NOR_OPI_MODE;
Flash.TransferRate = BSP_OSPI_NOR_DTR_TRANSFER;
BSP_OSPI_NOR_DeInit(0);
int32_t RetVal = BSP_OSPI_NOR_Init(0, &Flash);
if(RetVal != BSP_ERROR_NONE)
{
Error_Handler();
}
RetVal = BSP_OSPI_NOR_EnableMemoryMappedMode(0);
if(RetVal != BSP_ERROR_NONE)
{
Error_Handler();
}
//test loop
#define BLOCK_SIZE 4096
static uint8_t blockBuf[BLOCK_SIZE];
for(int i = 5; i < 15; i++)
{
bool ok = true;
if(BSP_OSPI_NOR_DisableMemoryMappedMode(0) != BSP_ERROR_NONE) ok = false;
if(BSP_OSPI_NOR_Erase_Block(0, 0, MX25LM51245G_ERASE_4K) != BSP_ERROR_NONE) ok = false;
if(BSP_OSPI_NOR_EnableMemoryMappedMode(0) != BSP_ERROR_NONE) ok = false;
memcpy(blockBuf, (uint8_t*)0x90000000, BLOCK_SIZE);
//now I expect to see 0xff... in the buffer
if(BSP_OSPI_NOR_DisableMemoryMappedMode(0) != BSP_ERROR_NONE) ok = false;
memset(blockBuf, i, BLOCK_SIZE); //put some data to the buffer
if(BSP_OSPI_NOR_Write(0, blockBuf, 0, BLOCK_SIZE) != BSP_ERROR_NONE) ok = false;
memset(blockBuf, 0, BLOCK_SIZE); //clear buffer
if(BSP_OSPI_NOR_EnableMemoryMappedMode(0) != BSP_ERROR_NONE) ok = false;
memcpy(blockBuf, (uint8_t*)0x90000000, BLOCK_SIZE);
//now I expect to see data in the buffer, but I see 0xff...
}
/* USER CODE END OCTOSPI1_Init 2 */
}
I can see memory block being erased, but not written. If I remove Memory Mapped Mode enter/exit functions memory erase and write works fine.
Do you know a reason for that?
2021-02-23 04:09 AM
Hi Tomasz Ozon,
I have exactely the same issue with this DK, did you get a reply for that please?
Thanks
2021-02-23 11:58 AM
2021-02-23 01:40 PM
Support here is pretty transparent, if you're not getting an answer it is because no one here has one. Not a board I have.
ST typically supports commercial customers through their sales officies and FAEs (Support Engineers)
2021-02-23 02:42 PM
2021-02-24 04:01 AM
Didn't check what's inside BSP_OSPI_NOR_DisableMemoryMappedMode but:
First, set ABORT bit and wait until BUSY gets cleared (with a reasonable timeout). If BUSY sticks at 1, clear EN and then set it again. If that still doesn't help, last resort would be to reset OctoSPI via RCC_AHB3RSTR register.
I didn't encounter any similar problem yet, as I always do an ABORT before changing *anything*. When you skim through the errata sheets (not just the one for H7A/B !!!), there are suggestions mentioning the way via ABORT and EN.
Another point: Avoid accessing the last few bytes of the external flash in memory mapped mode. On some devices this causes a complete stall of the interface, on some others only 0 is returned regardless of the actual contents.
2021-02-25 11:01 PM
Hi,
Please find bellow what is inside BSP_OSPI_NOR_DisableMemoryMappedMode :
/**
* @brief Exit form memory-mapped mode
* Only 1 Instance can running MMP mode. And it will lock system at this mode.
* @param Instance OSPI instance
* @retval BSP status
*/
int32_t BSP_OSPI_NOR_DisableMemoryMappedMode(uint32_t Instance)
{
int32_t ret = BSP_ERROR_NONE;
/* Check if the instance is supported */
if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else if(Ospi_Nor_Ctx[Instance].IsInitialized != OSPI_ACCESS_MMP)
{
ret = BSP_ERROR_OSPI_MMP_UNLOCK_FAILURE;
}/* Abort MMP back to indirect mode */
else if(HAL_OSPI_Abort(&hospi_nor[Instance]) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
else
{
/* Update OSPI context if all operations are well done */
Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_INDIRECT;
}
/* Return BSP status */
return ret;
}
It seems that abord is well done.
For your information I had a ticket on support, I get an answer few hours later asking me my company name, since no answer... Maybee the volume is not enough interesting to get an answer.
2021-02-26 12:40 AM
"It seems that abord is well done." doesn't help to prove or disprove your conjecture that the memory mapped mode is causing the trouble. Did you acually *verify* (e.g. by single stepping and inspecting the SR) that the ABORT is indeed done as desired? What I meant is:
1) Do an ABORT explicitly (in our own code) before any of your problematic program/erase operations. If this doesn't cure the problem
2) Clear, then set EN (in your own code) in the same way. If this still doesn't help
3) Reset the OSPI in the same way.
If the problem still persists, it is most probably not related to the memory mapped mode. If if goes away, you have a workaround (and if you've got enough time, you might dig into the problem further).
2021-02-26 03:01 AM
Ok, I will try another time with what you suggest and give you the result with more details on Monday. Thanks for your help.
2021-04-01 02:57 AM
Hello,
I get a reply from support, please find attached project.
You need to insert the following API into int32_t BSP_OSPI_NOR_Erase_Block(uint32_t Instance, uint32_t BlockAddress, BSP_OSPI_NOR_Erase_t BlockSize)
/* Issue Block Erase command */
if(MX25LM51245G_BlockErase(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_4BYTES_SIZE, BlockAddress, BlockSize) != MX25LM51245G_OK)
{
ret = BSP_ERROR_COMPONENT_FAILURE;
}
/*insert this API*/
if(MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
{
ret = BSP_ERROR_COMPONENT_FAILURE;
}
Best regards,
Grégory