PSRAM_IDs
array - it was only for debug. I'd remove it, but Paul's now pulled the changes.qspi_memory_base
linkage "C" in the LittleFS PRcores
definition can't be const
, as it has to be set at startup. In LittleFS I don't think it matters about optimisation; it can't be made into a literal constant, and declaring it const
ensures no future maintainer accidentally tries to write to it.With the number of changes - the next beta not likely to be the last - and if updated new PR might go in if it safely removes debug?it was only for debug. I'd remove it, but Paul's now pulled the changes
That's why I don't really understand why you made a new variable and added a weak linkage hack; all that was necessary was to initialize flashBaseAddr based on the value in FLEXSPI2_FLSHA1CR0 and plug it into the code instead of always using 0x00800000.
- I feel there's enough obscure register bashing in the code already without doing weird register reads just to save 4 bytes for people who don't use LittleFS (i.e. probably most people - I don't). There was already a (completely unused) variable in LittleFS!
I'm saying it shouldn't be declared const anywhere. If it's declared const then the compiler is allowed to assume it never changes and use the value directly rather than loading it from memory.
- The
cores
definition can't beconst
, as it has to be set at startup. In LittleFS I don't think it matters about optimisation; it can't be made into a literal constant, and declaring itconst
ensures no future maintainer accidentally tries to write to it.
I did that so any combination of cores and LittleFS will work - people get into so much trouble by having a forgotten tweaked library installed!That's why I don't really understand why you made a new variable and added a weak linkage hack
True ... but where and when to initialise it? I really don't care enough about LittleFS and saving 4 bytes of RAM to make the effort. Sorry.initialize flashBaseAddr based on the value in FLEXSPI2_FLSHA1CR0 and plug it into the code instead of always using 0x00800000
Sure, it can validly assume it never changes, but it has to get the value at some time from somewhere. LittleFS can't get it at compile-time, because it's extern; maybe LTO could try to optimise it away, and then discover it's defined inconsistently, or not notice but yield non-functional code. I just tried, and nope, no errors or warnings (about that, anyway), and the code still works.I'm saying it shouldn't be declared const anywhere. If it's declared const then the compiler is allowed to assume it never changes and use the value directly rather than loading it from memory.
Any core + LittleFS that takes the base by looking at the hardware register = no shared dependency so no chance of a conflict.I did that so any combination of cores and LittleFS will work - people get into so much trouble by having a forgotten tweaked library installed!
- old+old: obviously OK
- old cores + new LittleFS: no variable in cores, LittleFS falls back to weakly-defined one which has the original hard-coded value
- new cores + old LittleFS: will work with 8MB PSRAM, or none; will fail with 16MB PSRAM and QSPI Flash, nothing we can do here
- new+new: should work, but it's only had limited testing here
LittleFS_QSPI::begin() would be the obvious place. Buuuut I would bet any money there are people out there using the LittleFS_QSPIFlash and LittleFS_QPINAND classes directly, so probably better to put it in both of their begin functions; having two separate initializations isn't going to matter since the value will always be the same.True ... but where and when to initialise it?
I wouldn't count on that. It has a local definition and const value. The fact that it's weak just means the linker wouldn't throw a wobbly about a symbol redefinition.Sure, it can validly assume it never changes, but it has to get the value at some time from somewhere. LittleFS can't get it at compile-time, because it's extern;
I'm honestly surprised LTO doesn't have an issue with it, since it typically has problems with variables that don't follow the one-definition-rule (const vs non-const are distinct definitions) and especially because a const variable would be placed in a different program section to a non-const.maybe LTO could try to optimise it away, and then discover it's defined inconsistently, or not notice but yield non-functional code. I just tried, and nope, no errors or warnings (about that, anyway), and the code still works.
TBH I wouldn't mind too much if the const got removed, as future maintainers of LittleFS probably won't screw it up by modifying it. Probably.
If the software looks like a go, I can work with one of ISSI's distributors to bring in an MOQ order
Considering it's on the website, I'd call that publicly available, and it's kinda how I stumbled on it too.Is the ISSI roadmap public info?
Just for giggles, I did.The SOIC 16MB parts aren't in stock anywhere but you can get the BGA version. Since the software changes look to be minor, I sent a note to ISSI to see what the deal on availability is as a larger PSRAM option would be a nice upgrade for Teensy. I'll post here if I hear back.
Have you by chance tested these at the higher 133MHz rate?
ISSI 1.8v out of spec PSRAM TESTS
PSRAM0 ID 00605d9d
CCM_CBCMR=95AE8304 (105.6 MHz)
test ran for 62.45 seconds
CCM_CBCMR=B5AE8204 (110.8 MHz)
test ran for 59.96 seconds
CCM_CBCMR=B5AE8104 (120.0 MHz)
test ran for 55.83 seconds
CCM_CBCMR=55AE8004 (132.0 MHz)
test ran for 51.55 seconds
CCM_CBCMR=95AE8104 (144.0 MHz)
test ran for 47.68 seconds
CCM_CBCMR=75AE8204 (166.2 MHz)
Error at 7000FF00, read FF47FF21 but expected 5A698421 (BOOOO! HISSS!)
Found it interesting - seems I missed that or at least doing anything with it - though @KenHahn was there ... nice to have a link.might find this old thread interesting for testing PSRAM
Speeds are pretty easy to set.Thanks for doing that. When my 3.3V samples finally arrive, I will do some testing to see how it compares.
Edited: Out of curiosity I just tried two different Teensy with 16MB of the standard 8MB PSRAM at 166.2MHz and both passed OK. A Teensy with 8MB PSRAM and 128Mb NOR Flash also passed OK at that speed for both PSRAM and basic Flash testing.
Two Teensy with 8MB PSRAM and 2Gb NAND Flash chips would immediately fail the PSRAM test apparently due to the presence of the Flash on the bus even though they weren't being accessed. It also failed at 144Mhz, but would work for both PSRAM and Flash testing at 132MHz where I normally test at.
Is there a cheat sheet for the corresponding CCM_CBCMR values somewhere for different valid QSPI bus speeds?
CCM_CCGR7 &= CCM_CCGR7_FLEXSPI2(~CCM_CCGR_ON);
CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK))
| CCM_CBCMR_FLEXSPI2_PODF(3) // divisor + 1
| CCM_CBCMR_FLEXSPI2_CLK_SEL(3); // 528 clock / 4 = 132
CCM_CCGR7 |= CCM_CCGR7_FLEXSPI2(CCM_CCGR_ON);
spi_0_regs->FCR = LPSPI_FCR_RXWATER(0) | LPSPI_FCR_TXWATER(1);
32MB default 88MHz
test ran for 144.97 seconds. All memory tests passed :-)
32MB CCM_CBCMR=95AE8304 (105.6 MHz)
test ran for 123.66 seconds. All memory tests passed :-)
32MB CCM_CBCMR=B5AE8204 (110.8 MHz)
test ran for 118.56 seconds. All memory tests passed :-)
32MB CCM_CBCMR=B5AE8104 (120.0 MHz)
test ran for 110.65 seconds. All memory tests passed :-)
32MB CCM_CBCMR=55AE8004 (132.0 MHz) - FAILED
testing with fixed pattern 0F0F0F0F
Error at 710016C0, read 0F0F1F0F but expected 0F0F0F0F
16MB CCM_CBCMR=B5AE8104 (120.0 MHz)
test ran for 55.27 seconds. All memory tests passed :-)
16MB CCM_CBCMR=55AE8004 (132.0 MHz)
test ran for 51.07 seconds. All memory tests passed :-)
16MB CCM_CBCMR=95AE8104 (144.0 MHz)
test ran for 47.09 seconds. All memory tests passed :-)
16MB CCM_CBCMR=75AE8204 (166.2 MHz)
testing with fixed pattern 5A698421.
Error at 70000000, read DF6B9C23 but expected 5A698421
16MB + 2Gb Flash CCM_CBCMR=B5AE8104 (120.0 MHz)
test ran for 55.27 seconds. All memory tests passed :-)
16MB + 2Gb Flash CCM_CBCMR=55AE8004 (132.0 MHz)
testing with fixed pattern 5A698421
Error at 700F7700, read 5A698423 but expected 5A698421
SPI is in SLAVE MODE and not in control of the clocking to it, so it needs to have something ready ahead of time, and RAM may be BUSY (BUSS contention) since it MAY be writing from the other DMA channel.That's a bit confusing... why does the memory speed need to be nearly 10x the SPI speed, when SPI operates at 1 bit/cycle and the memory is roughly 4 bits/cycle?