Hello,
I'm experiencing strange behaviour while using MIMXRT1176 MCU.
The M7 core is running from RAM, the M4 core is running from SDRAM. I have a custom board and we're using IS42S32160F-6BLI SDRAM. Due to the fact the mamory has different timings and parameters in comparison with the original SDRAM from MIMXRT1170-EVK board I initialized the SEMC for the memory like this (It's running at frequency 167MHz so it should be mode '-6'):
status_t BOARD_InitSEMC(void) {
semc_config_t config;
uint32_t clockFrq = CLOCK_GetRootClockFreq(kCLOCK_Root_Semc);
memset(&config, 0, sizeof(semc_config_t));
SEMC_GetDefaultConfig(&config);
config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
SEMC_Init(SEMC, &config);
//@formatter:off
semc_sdram_config_t sdramConfig = {
.csxPinMux = kSEMC_MUXCSX0,
.address = (uint32_t)M4_BOOT_ADDRESS,
.memsize_kbytes = 16 * 4 * 1024,
.portSize = kSEMC_PortSize32Bit,
.burstLen = kSEMC_Nor_BurstLen8,
.columnAddrBitNum = kSEMC_NorColum_9bit,
.casLatency = kSEMC_LatencyThree,
.tPrecharge2Act_Ns = 18,
.tAct2ReadWrite_Ns = 18,
.tRefreshRecovery_Ns = 70,
.tWriteRecovery_Ns = 12,
.tCkeOff_Ns = 42,
.tAct2Prechage_Ns = 42,
.tSelfRefRecovery_Ns = 70,
.tRefresh2Refresh_Ns = 60,
.tAct2Act_Ns = 60,
.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq),
.refreshPeriod_nsPerRow = (64 * 1000000) / 8192,
.refreshUrgThreshold = (64 * 1000000) / 8192,
.refreshBurstLen = 1,
.delayChain = 0,
};
//@formatter:on
return SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdramConfig, clockFrq);
}
I feel like the timings should be right after checking even tho I still don't understand the purpose of some of them.
I also use the SDRAM for a shared memory between the cores. However I'm experiencing a delay between M4 writing data -> M7 receiving data. I'm handling the receiving with a polling method so basically the program goes like:
I found out the data are avaliable since 3rd cycle at the time I'm trying to read the data by the M7 core. I'm thinking the memory probably gets the 'read/write' commands but the SEMC isn't waiting for them so they're ready next time.
But I'm wondering why is that a case? Am I supposed to make a delay on purpose to get the data because the SEMC isn't build for handeling it? What's the right solution because I ran out of them and I don't think infinite loop for miliseconds is the right solution.
In forward thanks for any idea you provide!
Update #1
It kinda feels like it also might be a bug in a debugger? I'm using SEGGER J-link and it seems like when I stop the program right after it was supposed to read from memory, the data aren't here but when I just let the program run it looks like the data might be there in a normal run but that also might be just the fact the processor speedruns the first three iteration and then the data arrive. The question is how to prove which of the behaviour is it?
Update #2
By using :
DCACHE_InvalidateByRange( ... );
on the data sector inside the SDRAM (because beside data the M4 core is running on the first addresses) I managed to faster the SEMC write/read process so now it waits "only" 2 loop cycles. So, any idea how to make it wait 0 cycles?
Update #3
I would also accept if there's some way how to wait for the data to be ready. I found out there should be some "wait pin" that SEMC used but I can find barely anything about it in the MIMXT1170 reference manual.
Basically in my application the M4 is acting like a master and whenever M4 is doing something with the data, M7 have to wait/stop and wait for the new data anyway so something like waiting for a pin/status or anything like that is okay.
Right now it's still pretty unstable, sometimes it waits 0 cycles, sometimes 1 or 2 cycles.
Please set BMRC register to 0x81 so we avoid re-ordering of SEMC commands.
SDRAM controller is part of SEMC module which is primarily optimized for burst transfers as dedicated by AXI bus protocol. Hence single access request can introduce additional latency and reduce performance. Especially single read access by core (which is most usual way core requests data/instruction) on AXI system bus generates needs for wait for reply from slave port (SDRAM controller).
Best regards,
Omar
Hello,
thank you for your answer. I followed your suggestion and set the registers BMCR0 and BMCR1 to value 0x81 since both of them set weights for AXI bus commands. But even when it sounds like a really good advice I noticed no difference in data transfer.
I would appriciate any other advice, if you have some.
Also if it's more comfortable to you, you can refer to the 'semc_sdram" examples NXP provides since my code should be the same. However I noticed that the example have some "data validation" as a loop cycle that read the data from other variable but on the same core. I would like to say that this validation works for me too but the other core doesn't see the data anyway. I don't know if the problem might be in debugging or something. How I test this latency behaviour is:
Simply debugging M7 core which is waiting for a signal from M4. When I receive the signal I increment a variable and test if I copied any data from the shared memory. I have set a breakpoint whenever the copied data changes from zeros to anything.
Best regards,
Michal.