-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XMC Flash chip output drive support #6559
Comments
Ok, got code that sets SR3 at https://github.com/ChocolateFrogsNuts/ESP-DebugTools/blob/master/DebugTools/flash.ino |
Update: got it reading the flash status registers properly. I'll work on a PR over the next few days. 392 bytes of the code need to be IRAM_ATTR (although I can get that down to 270 by making certain assumptions), so this probably needs to be something that can be enabled/disabled easily. |
I wonder if we can do some tricks for functions that are only needed a single time to fix them in the ICACHE and not permanently in IRAM. Could we disable all interrupts, then read the function code into a dummy variable, to cause it to load into IRAM? Then call the fcn, which since no no-IRQ code could have caused it to spill out of the cache. Some question as to the # of ways the cache uses, etc. But seems better than wasting such a large chunk for a one-time event. Alternatively, overlays could be used and you could explicitly flush out existing IRAM, write your fcn in, call it, and then write the old code back. It's hackish, but if its done at chip init time (preInit callback, see the examples) it may be very low risk. |
@earlephilhower whatever solution works regarding those ideas, it would be worthwhile to search other cases to apply it to. |
I've been looking at the compile stats we get now and thinking the same things - there seems to be a lot of ICACHE_RAM_ATTR code, and surely a lot of it only runs rarely or even once. One thing I have noticed is that functions seem to be cached a page at a time as needed. |
@ChocolateFrogsNuts, How big is a page? Assuming the whole function fits into a single page, it sounds like it would be loaded before execution, is there a problem? If it's more than one page, what if you break it into parts. Such that you can call the parts for preloading, then call them for real. Something like this: void part1(int something, bool preload) {
if (preload)
return;
// ...
part2(something, false);
}
void part2(int something, bool preload) {
if (preload)
return;
// ...
}
part1(0,true);
part2(0,true);
part1(42,false); |
I am assuming flashchip->page_size (256 bytes), or a multiple of it. It's not very big. Hmm, I wonder if I could reduce the critical size enough by calculating the register values in one func, then just loading them into the controller and reading the result in a separate func... EDIT: the func would need to be page-aligned to give that a chance of working |
Split the func in 2, getting the critical section down to 160 bytes, but it still has to be IRAM_ATTR. Anyone know how to align the func? "#pragma align(256)" is ignored because the compiler doesn't understand it (a warning is printed). EDIT: |
I have a suspicion the page size is 64 bytes - the maximum size of a transfer by the SPI hardware controllers. |
For future reference, executing code in RAM causes Exception 2 - InstructionFetchError |
@ChocolateFrogsNuts how about (over)writing 32b wide into IRAM and executing that? That's less appealing, since you need to copy back the real code when done, but if done in the |
So far I get exception 3 - LoadStoreError just trying to read the iram. |
What happens if you run this configuration code as part of eboot? I believe that any IRAM used gets cleared when booting the application. |
ahh, oops - my bad... |
Ok, I'm an idiot... this seems to be working:
The cache is apparently 32kb, so pulling in 256 bytes an not just the 212 bytes of the function leaves a bit of room in case the function changes size without forcing too much out of the cache unnecessarily. |
awesome... moved the precache code into it's own function and made it so you can specify an address to pre-load from, or NULL for the current Program Counter. Now I just need to decide where to slot this code in - the XMC specific stuff is quite short (16 lines) and probably isn't worth it's own file. The generic stuff, which may be useful for other SPI devices is longer and should go somewhere specific to generic low-level SPI, but I can't see a suitable file for that... oh, and the precache code probably deserves to go in some generic spot too... |
I am not sure if your part has a volatile/non-volatile status register combination. eg.
I just tried it for a Winbond W25Q128FVSG. For me, the new driver strength bits seem to stick across power cycles.
|
According to the datasheet from XMC some parts of the status registers have volatile and non-volatile versions, others don't. The drive strength only exists as a volatile register. |
PR #6725 is merged, but there is still a detail pending in eboot, as mentioned in that PR. |
This is already addressed. Closing. |
Basic Infos
Platform
Settings in IDE
Problem Description
XMC Flash chips used on a number of boards (most notably some WEMOS D1 mini) have a power saving feature that defaults to 75% drive on their outputs. This can result in unstable operation at 40MHz and above in some circumstances.
While #6552 allows lowering the flash frequency to achieve stable operation, it is possible to run the chips at the full 80MHz with 100% drive by setting bits 5 and 6 of SR3 with
esptool.py write_flash_status --bytes 3 0x600000
Unfortunately this only lasts for the current power cycle.
Following on from the discussion started at the end of #6366, we now attempt to develop some code that will set SR3:5,6 in XMC flash chips when they are detected...
The text was updated successfully, but these errors were encountered: