Since I haven’t seen this documented anywhere, here is my attempt to explain the Cache_Read_Enable function. Valid values and what they do (at a register level) are from decompiling the code. The outcome of those values is based on my own experimentation so my descriptions and explanations may be silly but they currently fit the observed results.
void Cache_Read_Enable(uint8 odd_even, uint8 mb_count, unt8 no_idea);
Valid values for odd_even:
- 0 – clears bits 24 & 25 of control register 0x3FF0000C
- 1 – clears bit 24, sets bit 25
- other – clears bit 25, sets bit 24
Function of odd_even:
- 0 – allows access to even numbered mb
- 1 – allow access to odd numbered mb
- other – appears to do the same as 1, there must be a difference but I haven’t worked out what it it
Valid values for mb_count:
- 0-7 – set bits 16, 17 & 18 of control register 0x3FF0000C
Function of mb_count:
- Which odd or even bank to map (according to odd_even option)
- e.g. mb_count = 0, odd_even = 0 -> map first 8Mbit of flash
- e.g. mb_count = 0, odd_even = 1 -> map second 8Mbit of flash
- e.g. mb_count = 1, odd_even = 0 -> map third 8Mbit of flash
- e.g. mb_count = 1, odd_even = 1 -> map fourth 8Mbit of flash
Valid values for no_idea:
- 0 – sets bit 3 of 0x3FF00024
- 1 – sets bit 26 of 0x3FF0000C and sets bits 3 & 4 of 0x3FF00024
Function of no_idea:
The clue is in the name, I can’t work out what this does from my experiments, but the SDK always sets this to 1.
11 thoughts on “ESP8266 Cache_Read_Enable”
I observed that once I enable caching `Cache_Read_Enable(0, 0, 1);`, I can no longer use SPIRead() function.
Has anybody tried it?
@richard – How about using it in rboot? It can get rid of lot of stack usage since we can directly read from SPI flash.
Not sure what will happen to SPIWrite() though.
That’s correct, you cannot use SPIRead or other flash functions while memory mapping is enabled. If you use the sdk calls instead they automatically unmap before and remap afterwards for you.
To answer your second question there is no need to use memory mapping in rBoot. We can use all the stack space we want, there is nothing else needing it, and we free it all before running user code.
Were able to get Cache_Read_Disable() working?
I haven’t tested Cache_Read_Disable myself because I haven’t needed to, but that’s what the SDK calls to unmap, so it must work.
For 0x3FF00024 see https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map/_compare/3debc5aa8c69a525101490cd446b2aed98e750ec…185d66cce96b50f9c5db14b5ab92af1c660b72ed
And thanks for sharing this!
Ok, just see https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
Thanks, another piece of the puzzle. How did you/someone find that out?
So if I read that right, there is a choice of two rom cache sizes or disabled (although Cache_Read_Enable provides no mechanism to choose disabled)? If that’s the case, the SDK always sets it to the larger of the two and there is no user options for lower.
First link which didn’t go well was to a page diff which shows that that info was added by https://github.com/jcmvbkbc (maintainer of gcc-xtensa). He hacks with JTAG and stuff, so he probably knows what he writes (but you can ask him directly on github).
Yes, the way I read his additions, cache actually consists of two 16K blocks which can be enabled/disabled independently, and you can trade size of SPI Flash cache (== performance) for getting more IRAM (also performance, but also a possibility to use it as a normal RAM, as that’s where (RAM size) esp8266 is lacking).
Tried it and couldn’t get it to work with code in the first of the two blocks.
Test: I put code there by setting the start address for my almost 0x8000 byte .text section to …4000, so it would run into and fill most of the first block of cache and ran it with the full cache enabled – it didn’t work as you’d imagine. But when I tried it with half cache it still didn’t work, although it ran a little further.
> I put code there by setting the start address for my almost 0x8000 byte .text section to …4000, so it would run into and fill most of the first block of cache and ran it with the full cache enabled – it didn’t work as you’d imagine.
Not sure how you’d imagine that. I’d imagine it fails at random points.
> But when I tried it with half cache it still didn’t work, although it ran a little further.
That well may be if FLASH caching is still enabled, that’s why I didn’t write anything about that combination of bits, particularly that mapped IRAM is not affected by FLASH caching.
jcmvbkbc – we must have misunderstood what it says on the Memory Map wiki page.
I think we both read “When clear IRAM is mapped at 40108000h..4010BFFFh. When set that RAM is used by the FLASH caching mechanism.” to mean that leaving that bit clear left the memory available as normal iram, but setting it means you couldn’t use it because it would be used for flash cache. It’s obviously not as simple as that.