2021-02-24 02:06 PM
When writing to FMC NAND address, FMC_NCE goes low at beginning of first write and then only comes high at end of last write. I can write 0x1000 words at 10MHz using a 60MHz FMC kernel clock. Therefore with the minimum SETUP, WAIT, and HOLD time, it takes 6 kernel clocks to write out a word.
When reading, FMC_NCE goes low and then high with every word read. This increases the read time between each word, requiring extra FMC kernel clock cycles, which means running the kernel clock at a higher rate. The higher kernel clock has the added detriment of being inconsistent number of clock cycles between reads. At 160MHz FMC kernel clock, the read sometimes takes 16 clocks, or 15, or 17.
I'm not actually writing to a NAND memory chip, so I need to be consistent with the read frequency in particular.
The WRITE code:
for (index = 0U; index < BUFFER_SIZE; index++)
{
*(__IO uint16_t *)deviceAddress = *buff;
buff++;
}
The READ code:
for (index = 0U; index < BUFFER_SIZE; index++)
{
*buff = *(__IO uint16_t *)(deviceAddress);
buff++;
}
Somehow, the peripheral knows the write is all in one go, but the read isn't?
I have set the MPU to TEX2 and have i- and d-cache enabled.
I would really appreciate any ideas
2021-03-10 01:26 AM
Hi, could you please confirm which STM32 device your are referring to ?
Regards.
2021-03-10 02:04 AM
On the Cortex-M devices Writes are typically deferred, minimally via Write Buffers.
Which part?
Show full MPU configuration for region.
2021-03-10 02:20 AM
Good morning,
STM32H745
2021-03-10 02:22 AM
Good morning,
STM32H745 - CoreM7
MPU config:
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x80000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL2;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
Thank you.