How is the FMC supposed to behave when a slow write to one address is followed by a read from another address?
I have a problem accessing a SRAM connected via a 16bit databus to the FMC on an STM32F469.
The processor is running 168MHz, and the FMC configuration is this:
hsram1.Instance = FMC_NORSRAM_DEVICE;
hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/* hsram1.Init */
hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hsram1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
/* Timing */
Timing.AddressSetupTime = 0;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 15;
Timing.BusTurnAroundDuration = 15;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FMC_ACCESS_MODE_A;Note that write FIFO is disabled, and the timing is very slow.
Sometimes when I perform a ldr instruction the value loaded is not as expected.
When this issue occurs I read something like 0x vxyz vxyz. Eg. 0x002e002e where the expected value is 0x60016e70.
I have discovered that the value returned is closely related to the last value written to the SRAM (at another address).
The trace reveals this:
lsls r2,r2,#0x1F
itt ne
ldrb r3,[r1],#0x1
strb r3,[r0],#0x1 ; instruction (1)
bcc 0x8000382
mov r0,r12
bx r14
ldr r0,[r4] ; instruction (2)
cmp r10,r0
beq 0x8024B7AIf the value 0x2E is written at instruction (1) to address at location (3), then the value read at instruction (2) from location (4) is 0x002E002E. If 0x2D is written, then 0x002D002D is read.
The memorydump looks like this.
________address|________0
SD:60016E64| 0000002E <-- (5)
SD:60016E68| 60016E70 <-- expected value (4)
SD:60016E6C| 0000000D
SD:60016E70| 4F544F4D
SD:60016E74| 4F435F52
SD:60016E78| 4749464E
SD:60016E7C| 6013002D <-- value read (3)
SD:60016E80| 0801151DNote that it is not the value at the lower address (5) that is returned.
If I add a breakpoint at the instruction (2), or add two nop’s before ldr the correct value is read.
How is the FMC supposed to behave when a slow write to one address is followed by a read from another address?
When the FIFO is disabled I would expect execution of instruction (2) to be extended until the databus is free so the read can be performed. Is this correct?
Is there any difference if the write FIFO is enabled?
The reason the FIFO is disabled is because we have another memory mapped device where we don’t want any caching to be performed.
Can the MPU be used to allow cache in one region and no cache in the other?
Best Regards
Tajs

