For more memory check this out. - Page 1
Forum section: electronics / general

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 05, 2024, 10:18:40 am
content: If you have a project and need more random access memory how about ESP PSRAM64H.I ordered some fromhere, and they arrived the day before yesterday. Hooked them up to my CH341 programmer to test them. Hacked up some code by modifying some open source code I found on the net.The ID checks out for as far as I can find. The manufacturer ID and the KGD (known good die) bytes are what the datasheet specifies.Did not do a full memory test, but wrote 16 bytes of data to the beginning and the end of the memory and read those back. So I'm satisfied and hope to use one soon enough in a project.

author: westfw
author_rank: Super Contributor
timestamp: September 05, 2024, 08:24:12 pm
content: From the DS:QuoteCan QSPI controllers be programmed to do things like that (drop the frequency when crossing a page boundry), or does this just mean that the devices can only realistically be operated at 84MHz.Geez. 8Mbytes in an 8pin SOIC! I feel old.

author: mariush
author_rank: Super Contributor
timestamp: September 05, 2024, 08:36:13 pm
content: Other than the price, not sure what's so special about it.You can get 32 mbit chips for 2-3$ on Digikey, and at least you know they're genuine200 mhz capablehttps://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS66WVQ8M4DALL-200BLI/16260618104 mhz up to 3.6vhttps://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS66WVS4M8BLL-104NLI/16260662104 mhz up to 1.95vhttps://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS66WVS4M8ALL-104NLI/16260609

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: September 05, 2024, 09:51:47 pm
content: Quote from: mariush on September 05, 2024, 08:36:13 pmAgreed it's not terribly special, but the first of your links is a DDR part, the second is comparable but 3-4x the cost, and the third is a different voltage standard.The same part isactually on DigiKey, but Adafruit don't like advertising where they get their parts fromIt's also cheaper (quantity-1) than the ISSI one is at quantity-1000.You can alsoget themon Aliexpress for $0.66 each, if you're willing to buy from there.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 06, 2024, 06:04:36 am
content: Quote from: westfw on September 05, 2024, 08:24:12 pmGood question. I have not used it with an actual memory controller, just the simple test with CH341 SPI, and that is rather slow.Also from the datasheet the normal SPI read can only be done on 33MHz, but fast read can be at full speed, but has a wait cycle of 8, but a quick scan did not tell me what a wait cycle is. Are we talking SPI clock cycles or complete 8 byte read cycles?Edit: I looked a bit closer and think it is SPI clock cycles based on the timing diagram shown.But yeah, I was also thinking wow 8MB in such a small package.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 06, 2024, 06:19:06 am
content: Quote from: SpacedCowboy on September 05, 2024, 09:51:47 pmThe first part mariush linked to is also ball grid array, which is not to every bodies taste.I did not post them because they are very special or super cheap, although still less than half the price of the one you linked at digikey. The aliexpress one you liked is with shipping more expensive than the one I found.It was more to bring attention to a lot of memory for not a lot of money with an easy connection to a MCU, and the ones I got seem to be actually genuine.Using it is less simple than parallel memory but can be very useful for many project.

author: Smokey
author_rank: Super Contributor
timestamp: September 06, 2024, 08:20:17 am
content: These SPI PSRAM are the only "approved" parts for use with ESP32. So you get them direct from Espresif I guess.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 06, 2024, 11:22:08 am
content: Quote from: Smokey on September 06, 2024, 08:20:17 amThey indeed have the Espressif logo on them.But not bound to only be used with Espressif MCU's.

author: wek
author_rank: Frequent Contributor
timestamp: September 06, 2024, 11:45:54 am
content: With dynamic memories (and pseudo- in PSRAM means dynamic) you always have to ask, when/how are they refreshing.In the SPI kind of DRAM it's usually quite well hidden in this parameter:CEM CE# low pulse width max. 8 μsIn other words, you have to finish any transaction within 8us. Not impossible, but quite challenging.Yes, you may have experienced that they "work" even with significantly longer CE-active pulses. We all know what "it works for me" means.(Btw. I don't believe Espressif makes them, IMO they are just rebranded from some other manufacturer; but that's not the point).JW

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 06, 2024, 01:35:40 pm
content: Quote from: wek on September 06, 2024, 11:45:54 amThanks that is valuable information. With a SPI clock of 33MHz this means you can read or write 29 bytes of data as long as they are in up following addresses. So 1 command byte, 3 address bytes and then 29 data bytes.

author: peter-h
author_rank: Super Contributor
timestamp: September 06, 2024, 02:21:15 pm
content: We have been here before. It's a really interesting topichttps://www.eevblog.com/forum/microcontrollers/st-32f417-any-way-to-make-an-spi-sram-to-look-like-normal-ram/msg4095271/#msg4095271https://www.eevblog.com/forum/microcontrollers/lyontek-ly68l6400-8-megabyte-spi-sram-am-i-reading-the-data-sheet-right/msg4193821/#msg4193821because you can get 8MB for under $1 and for many applications it is fast enough, especially the QSPI mode of the ESP32.I did extensive testing re the 8us max /CE=0. The following is from my project notes:It is an 8 megabyte SPI PSRAM (pseudo static RAM). This exists in variously branded versions which seem to share the same spec. The one designed in is the LY68L6400SL.The SPI operation is simple enough, especially at 21MHz which is the maximum SPI3 clock (32F417) and which does not push any of the clock rate limits of the various special modes of the device.However, there is an issue with the internal refresh (it contains two DRAM chips, apparently) which gets disabled while CS=0. The spec thus sets a limit on the maximum CS=0 time of 8us. Assuming optimised gap-free transfers (we are using DMA for SPI3) this translates to a longest transfer of 21 bytes including the 4-byte header (opcode and 3 address bytes). So no more than 16 bytes of data (20 bytes, moved by DMA) can be transferred in one go. However, the minimum CS=1 time is only 50ns so another transfer can be started immediately. For a discussion of this, seehttps://www.eevblog.com/forum/microcontrollers/lyontek-ly68l6400-8-megabyte-spi-sram-am-i-reading-the-data-sheet-right/msg4193821/#msg4193821The CS=0 max timing has a considerable temperature dependence. It’s been experimentally determined (above URL, plus comments in the code) that the 16 byte limit can be pushed a long way out, and it starts to get dodgy much above 512 byte transfers which start to fail at +70C. A 512 byte transfer takes 200us (2.5MBytes/sec). Even a 16 byte transfer, at about 11.5us for CE=0, exceeds the 8us spec but transfers of 64 bytes or less do not show failures even at +115C. An 8 byte transfer takes 8.2us of CE=0. It seems clear that the 8us spec tries to cover extreme combinations of Tamb and large device chip heating due to 100MHz+ clock rates. In this project, the package temp rise is under 1C even during a constant memory test. However, it was found that if CE goes to 1 for every 50us in between packets, the issue pretty well disappears; see above URL. A 512 byte transfer seems totally safe at any reasonable temperature if there is a 50us gap after each packet.Another issue found was data corruption due to stretching the CS=0 time to some large figure if- USB interrupts (FatFS ops - 15ms for writes, 200us for reads) occur- a same or higher priority RTOS task is runningThe USB issue was solved with __disable_irq() and __enable_irq() and this also stops RTOS task switching. Seehttps://www.eevblog.com/forum/microcontrollers/32f417-how-to-disable-interrupts/If it was desirable to get the 8us CS=0 and 16 bytes (which I think is pointless) one could do it with optimised code. Two optimisations are obvious- concatenate the header buffer with the data buffer, so just 1 DMA operation is needed; this saves 1.8us- put the DMA code inline so that CS=0 and CS=1 can be done at optimal placesA 3rd one would be to use SPI1 which can do 42MHz (APB2 at 84MHz) but that is way too much work in this project due to package pin allocation limits.If somebody implements the "real RAM emulation" discussed in the threads, I am all ears, but it's a lot of work and you need to be an expert in arm32 instruction encoding to implement the code trap for the emulation. It has been done for some processors in other contexts e.g. implementing Z80 breakpoints in ROM

author: Siwastaja
author_rank: Super Contributor
timestamp: September 06, 2024, 02:54:38 pm
content: Any microcontroller application examples where large amount of slow, high-latency RAM is needed? Nearly nothing pops in my mind. I have sometimes been RAM constrained but that's more about needing say 20-50-maybe 100K more, and I would very much prefer it to be as fast as the main SRAM (and I mean latency, not just throughput).

author: peter-h
author_rank: Super Contributor
timestamp: September 06, 2024, 02:58:50 pm
content: I can think of loads of examples. It depends on what one does... data logging is one great case where people develop super elaborate schemes to even out wear but all they are achieving is pushing out the inevitable eventual flash failure.I am surprised the ESP32, with its obvious focus on getting a lot of speed out of these PSRAM chips, has not implemented the emulation. It's much easier if you have the CPU right there, decoding the stuff for you, so you always know where the next instruction startsBut in any case if you are using it for data buffers, not for executing code and not for the stackthen with DMA you can do "a manual version of virtual memory" at 2MB/sec plus, which is plenty fast enough and incidentally many times faster than virtual memory was on the old mainframesAnd if the memory fault trap always meant that a given size buffer needs to be swapped out, you could implement the buffer swap in the trap service routine, but you still need to, AIUI, take care that the instruction causing the trap is a known size (implying doing that in asm, not C) so you can exit the trap correctly.

author: globoy
author_rank: Frequent Contributor
timestamp: September 06, 2024, 03:16:11 pm
content: FWIW I've used the external PSRAM on ESP32 extensively for things like image and sound buffers. It does take a little consideration when architecting the firmware deciding what goes in what memory and how to manage access but, at least for me, the external PSRAM was very useful and it's relatively slower performance acceptable.The ESP32-S3 improved its external PSRAM bandwidth over the original ESP32.In the hobbyist space I know the PJRC Teensy 4 micro-controller boards can use external PSRAM and I think a lot of people make use of it there (at least going by forum commentary). It does seem like it could be super useful when used in conjunction with the audio library for things like buffering and sample storage.

author: m k
author_rank: Super Contributor
timestamp: September 06, 2024, 03:18:35 pm
content: Very local distributed cloud, for light bulbs.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 06, 2024, 04:31:31 pm
content: Audio processing is one of the reasons I got those chips.Another usage could be sample memory storage for a low bandwidth oscilloscope or spectrum analyzer.I have not looked into using it with a FSMC unit like found in the STM32F407, but I believe it can work with PSRAM. That would take away the whole task from the software if I'm correct.Lots of new stuff to discover.

author: peter-h
author_rank: Super Contributor
timestamp: September 06, 2024, 04:36:44 pm
content: AFAIK no way to emulate a normal RAM with the FSMC if the physical device is an SPI RAM, in a 32F4. Not sure if any chip does that.Yes it would be nice, with some smart caching system e.g. a 16 byte cache so the SPI transfers would always be 16+ bytes.The prices of SPI PSRAMs are always going to be way lower than SPI SRAMs, which at 8MB size are expensive.One could also do the linear address to SPI emulation with an external FPGA, fairly easily, but it would be expensive and would make no sense.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 06, 2024, 05:11:10 pm
content: Quote from: peter-h on September 06, 2024, 04:36:44 pmYou are right. I just read the reference manual about the FSMC and it does not support SPI or QSPI based devices. Just parallel memories.

author: voltsandjolts
author_rank: Unknown
timestamp: September 06, 2024, 05:51:40 pm
content: The stm32h7a3 supports memory mapping spi ram and flash

author: peter-h
author_rank: Super Contributor
timestamp: September 06, 2024, 06:04:06 pm
content: That's amazing!BTW is there any SPI SRAM anywhere near 8MB? I don't think so.

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 06, 2024, 08:06:50 pm
content: All MCUs with a real QSPI controller should support mapping it directly to some address space. If it doesn't have one, then forget about those PSRAM chips. Simple SPI mode will be very slow (but maybe it can be ok in some particular application, like using that as a temporary storage for relatively "slow" datalogging rather than using an EEPROM - usually coming in smaller sizes - or Flash - which wears out).Although in theory possible, bitbanging QSPI would be pretty bad in terms of throughput. Although with something like the RP2040 PIO, I'm sure one can do this. (It already has a QSPI controller but it's dedicated to the Flash chip. The newer RP2350 is supposed to support 2 different chips on QSPI though.)

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: September 06, 2024, 08:57:53 pm
content: Quote from: Siwastaja on September 06, 2024, 02:54:38 pmI'm using a similar chip (seems to have identical parameters) to give large amount of memory to an Atari XE redesign. The bus-clock period on an XE is 558ns,which gives (checks notes)Code:run @ 84MHz, 192ns to read one byte in QPI mode, 6312ns to read a page of 256 bytes,Use built-in MCU SRAM for normal purposes, API-call to swap a page to/from bulk RAMOr run @ 133MHz in wrap-32 QPI mode to read one byte120ns to read a byte. Probably just do it like that…The address is valid 177ns into the clock cycle, and the CPU will require data to be valid after 486ns. That gives me about 300ns to get a byte from an address and present it to the databus.

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 06, 2024, 09:12:37 pm
content: Teensy 4.1supports up to two8 MByte PSRAMchips compatible toAPS6404L_3SQR, which on a quick glance looks extremely similar to the PSRAM chip discussed in this thread. When you buy a Teensy 4.1 from PJRC, each 8 MByte PSRAM is just USD 1.80 extra.The PSRAM is directly mapped to 0x70000000 - 0x70FFFFFF in the NXP i.MX RT1062 (Cortex-M7) address space, and behaves like internal RAM, just a little bit slower perhaps. (I haven't run any benchmarks myself. For details, seei.MX RT1060 Reference Manual. Pins EMC22,24-29 are used for the two-chip QSPI bus.)Support is baked in to the Teensyduino core (size available probed at startup) and linker scripts, so that objects placed in the.externalramsection will reside in the 16 MB PSRAM address range. For convenience, there is even anEXTMEMattribute macro, so that e.g.uint32_t values EXTMEM;will simply work.While having 17 MiB on a microcontroller sounds odd, it being absolutely random-access opens up many possibilities.If i.MX RT106x weren't BGA only (me hobbyist, BGA scary), I'd have already done my own DIY board exposing the eLCDIF interface for driving small displays from BuyDisplay/EastRising.Then, the extra RAM could be used for pixmap and glyph storage, allowing for very fast blitting (the Pixel Pipeline peripheral even supports 2D DMA and some blitting operations). For example, I might use it to store antialiased fonts and pre-prepared animated "sprites".With Ethernet, the extra RAM can be used for buffering and temporary storage.It is particularly useful with audio, as each 8 MB PSRAM chip can hold a minute and a half of single-channel uncompressed PCM audio, and the access speed isn't an issue.For microSD, a separate bus (and peripheral, uSDHC) is used for the access, and it should be possible to use DMA to read data from SDHC flash into PSRAM. I haven't implemented this yet myself, though. In this use case, the PSRAM can be used as a "page cache", especially to speed up read-only data reads using suitable access heuristics. (For a write cache, the standard power-off/brownout issues do apply.)

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 06, 2024, 09:23:45 pm
content: Yes I've tested it on a Teensy 4.1 (as mentioned in some earlier thread) and got about 30 MBytes/s sustained (both read & write). I implemented it using the NXP SDK (not teensyduino) and I can't say for sure that my settings were all 100% optimal. If someone else has/can test it using the Teensyduino core and let me know what they get.And for the record, I did solder two ESP PSRAM64 chips. So that definitely works with these MCUs.And yes, that can sure be pretty useful for all kinds of applications.Note that PSRAM also comes in wider busses (8 and 16 bits) - usually in BGA packages, though. The CH32V307, for instance, does support PSRAM with up to a 16-bit databus (but doesn't support QSPI OTOH, a bit odd!) Much faster data throughput.

author: peter-h
author_rank: Super Contributor
timestamp: September 06, 2024, 10:14:44 pm
content: QuoteIt is much better than "slow datalogging". Even in my project, the Lyontech PSRAM runs at 21MHz SPI which is roughly 2MB/sec net or ~100us to move a 256 byte buffer in or out. Data logging at 2MB/sec is not slowAnd if you use (in my case) SPI1, 42MHz, then you get 2x faster.A quick look at the RT1060 doesn't exactly say that SPI RAM is emulated to a linear address space, AFAICT. It talks about booting from SPI (nice) and XIP (execute in place) which sounds like fetching SPI code into a little buffer and running it right there.

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 06, 2024, 10:19:54 pm
content: I'd use FRAM for data logging, non volatile too!

author: peter-h
author_rank: Super Contributor
timestamp: September 06, 2024, 10:26:59 pm
content: Can you give an example of a device, say 1MB+ ? I looked at these and they were small and pricey.

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 06, 2024, 10:47:35 pm
content: Hmm yeah, they're freaking expensive in large densities, I thought they had become cheaper by now!For the PSRAM, I guess you could make a memory handler(psram(rw, *ptr, addr, sz)) that splits memory operations into small chunks so CS is never low for too much time.

author: DiTBho
author_rank: Super Contributor
timestamp: September 07, 2024, 04:33:07 am
content: Quote from: Nominal Animal on September 06, 2024, 09:12:37 pmThis macro is simple, intuitive and elegant! Well done!just, talking about it as generic solution, I don't know exactly how these macros internally work in gcci.e. Avr-gcc uses similar macros to specify not only the linker but also the machine level that must use special load/store-like instructionsLPM (Load Program Memory)...to read/write from the flash, which for avr8 is mapped into the code space.Piece of cake, no doubt about!However, as simple as this may seem, it actually still creates a lot of confusion and problems, especially when the granularity is not 8bit, but 16 or worse.And you come to the conclusion that even avr-gcc you shouldn't have to do anything at all, just use vanilla C with less macro possible, so the compiler will locate .rodata in flash and the offsets will be handled by linker description file etc.I mean, you should do not use macro-things like { PROGMEM, PGM_READ_XXX, ... }at least try to avoid them, if it's really impossible not to use them... oh wellWhich brings me to thinking about compiler language design, where I don't yet know exactly how to implement these things in a way that doesn't look too weird, hence counterintuitive, which is exactly what I don't want them to be, and this leaves me very puzzled about how to express things in a way that is both generic and doesn't look too confusing

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 05:30:16 am
content: QuoteYou sure could, with the use of hardware timers to ensure the /CS=0 is always less than 8us, but it's not a big deal for anyone who can read the doc. This is what I have (note I am sharing spi3 with a load of devices, which can be used from different RTOS tasks, hence the mutex arrangement)Code:extern bool g_spi_ram;// set in main.c and true if SPI RAM foundextern bool g_45dbxx_busy;// true to keep SPI RAM CE=0 waitingextern uint8_t g_spi3_current_config;// holds current SPI3 config mode (1.. see spi.h)static uint8_t readcmd = {0x03,0,0,0};// basic read command and 3 byte addressstatic uint8_t writecmd = {0x02,0,0,0};// basic write command and 3 byte addressstatic uint8_t readid = {0x9f,0,0,0};// Read ID. Send 9F and any 3 byte addressstatic uint8_t id = {0,0,0,0,0,0,0,0,0};// ID gets read into here// Write data to LY68L6400SL.// Address: linear address 0-8MB// buf: data buffer (must be static, not in CCM)// Length: data length (DMA limit is 64k) - see notes re temp dependence of CS=0 duration// Returns: true if SPI RAM fittedbool SPI_RAM_write(uint32_t address, uint8_t * buf, uint32_t length){if (!g_spi_ram) return(false);SPI3_Lock(); // mutex// If current SPI3 init is not this device, initialise itif ( g_spi3_current_config != SPI_MODE_LY68L6400 ){spi3_set_mode(SPI_MODE_LY68L6400);g_spi3_current_config = SPI_MODE_LY68L6400;}writecmd = (address>>16) & 0xff;writecmd = (address>>8) & 0xff;writecmd = address & 0xff;__disable_irq();spi_ram_cs(0);SPI3_DMA_TransmitReceive(writecmd, NULL, 4, true, false, false);// Transmit write commandSPI3_DMA_TransmitReceive(buf, NULL, length, true, false, false);// Transmit dataspi_ram_cs(1);__enable_irq();SPI3_Unlock();return (true);}See my earlier post about temp dependence of the 8us. There is actually a huge margin around that and thus in reality this is easy to ensure by design. But if you wanted to be strict you could call the above function from another one which, upon detecting a block longer than say about 10 bytes, splits them up, running a hardware timer in between to ensure the 8us.

author: Smokey
author_rank: Super Contributor
timestamp: September 07, 2024, 06:23:57 am
content: What sort of throughput are you guys getting with these? Considering the overhead and delays, how long does it take to transfer 1MByte?

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 07:26:34 am
content: See aboveAs fast as your SPI will run.

author: mariush
author_rank: Super Contributor
timestamp: September 07, 2024, 08:17:44 am
content: For data logging, why not just use a Flash chip?32 mbit flash (SLC) chips are like 30-40 cents. 64 mbit are around 75 cents on Digikey...You can get 2 gbit (256 MB) SPI chips for around 1$ (100pcs at lcsc) :https://www.digikey.com/en/products/detail/micron-technology-inc/MT29F2G01ABAGDWB-IT-G-TR/6136124/https://www.lcsc.com/product-detail/NAND-FLASH_Micron-Tech-MT29F2G01ABAGDWB-IT-G_C410863.html)

author: Siwastaja
author_rank: Super Contributor
timestamp: September 07, 2024, 08:32:37 am
content: Quote from: mariush on September 07, 2024, 08:17:44 amMaybe something like this: device is connected to some sort of network (e.g., internet, local radio, whatever) which is not 100% reliable; after connection re-establishes, you want to fill in gaps and send last 1 hour worth of data. Maybe you produce a few MB, so doesn't fit internal SRAM, but still small enough that low performance does not matter. Power-off retention would not be needed if the powering of the logger is reliable. Then using flash would just be extra complication (waiting for erase etc.)

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 08:47:20 am
content: Quote- have to consider wear issue -> complex schemes to even out wear OR a wear-evening filesystem (but that prevents FAT12/16 which is needed if you are to access it via USB MSC for Windows etc, unless you emulate FAT on top of the base FS which is yet more PITA)- write speed is a few ms per block or more; the Adesto 4MB chip I am using is 15ms per block (512 bytes) with pre-erase or 3ms (typ) if block is already erasedQuoteI think those are 4k block chips, which is OK for the embedded end but if you want USB MSC you have to do blocking/deblocking to simulate 512 byte sectors for Windows/etc. I agree those are the cheapest way to get "flash" though.QuoteExactly.It actually has many other applications, incl funny ones like if you are driving an LCD you can precompute graphics shapes and store them in this chip, and then zap them at ~2MB/sec (in my 21MHz SPI case) to the SPI-attached (or even parallel port) LCD.In the other thread I was looking to maybe use it for MbedTLS buffers, but that would need a deep knowledge of the code, which is very very complicated. It grabs 60k of RAM in my project which I have but not with much to spare (32F437 instead of 417 would solve that; I coded to auto detect that and provide the extra 64k heap space) and that is after doing a mod (it's on github) to make it process the root cert file one cert at a time, otherwise the stock MbedTLS needs >200k of RAM to hold that whole cacert.pem file!

author: _Bernd
author_rank: Newbie
timestamp: September 07, 2024, 10:24:46 am
content: Quote from: Smokey on September 07, 2024, 06:23:57 amHello,With an SPI clock of 6 MHz, I was able to transfer the 24-bit address and an additional data byte within 7.5 µs. The data rate was around 125 kilobytes/second.Regards, Bernd.

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 10:43:41 am
content: This is relevanthttps://www.eevblog.com/forum/microcontrollers/32f417-spi-running-at-one-third-the-speed-it-should/You need to useDMAfor SPI if you want decent speeds. In the arm32 chips, the SPI peripheral is loosely attached to the CPU and runs at a much slower clock - say 21MHz for a 168MHz CPU. So SPI status polling is very slow. DMA has the same problem but can run much faster because it is triggered by SPI empty (etc) so doesn't have to loop on the status bit(s).These PSRAMs will run as fast as the SPI can run in most chips - up to 100MHz or so, which is ~ 10 MB/sec.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 07, 2024, 11:44:42 am
content: Quote from: peter-h on September 07, 2024, 10:43:41 amYou know there's a third solution between DMA and polling - namely interrupts. I'm not aware of any SPI implementation in any (even lower cost) 32-bit MCUs which wasn't at least double buffered (some better ones have a longer FIFO), so you let the "data register empty" type flag trigger the ISR right when the write of the previous SPI wordstarts. With any sensible combination of CPU and SPI clocks, ISR entry latency plus quite some user code instructions have plenty of time to execute before the previous transfer is completed, thus you totally can do it without DMA without incurring a single cycle of penalty. The advantage of DMA, and the actual reason it is being used for SPI, is that you don't need these relatively high-priority interrupts for every transfer and thus leave more CPU time for other tasks.

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 12:16:09 pm
content: You may be right with some but I doubt it on a 168MHz 32F4 feeding SPI at 21MHz.This was looked at (see the last thread I linked). If a really tight polling loop can't do it then I doubt interrupts can do it.And yes there is double buffering (only that) but you cannot reliably load 2 bytes in there in rapid sequence, due to the SPI peripheral running too slowly internally, so the ISR needs to either load just 1 byte or check the status bit and then you are back to the old problem. So you need 1 interrupt per byte.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 07, 2024, 01:01:14 pm
content: Quote from: peter-h on September 07, 2024, 12:16:09 pmWith minimum sensible word width of 8 bits, SPI running at 21MHz produces interrupts once every 0.38µs, which, at CPU clock of 168MHz is 64 CPU cycles, out of which interrupt entry + exit eats 22 cycles. So yeah, I would agree you need to keep that ISR very well hand-crafted to be able to pull this off without any timing penalty. Most of the time this would be just accessing an array and incrementing and comparing some counter, so doable, but if one carelessly adds extra logic then it's getting risky.If transactions are longer and can be made multiple of two bytes, configuring SPI into 16-bit transaction gives you a lot more leeway.Then again, configuring DMA requires even more work than just writing SPI data register (e.g., clear flags, set pointer, start DMA), so if transfers are short it might not be faster at all, you would still be getting interrupts all the time.Those higher end STM32s that have SPI FIFOs of 8-16 bytes are very nice in sidestepping the whole issue - just access the FIFO, interrupt-based, in nice 32-bit wide bus accesses. Much more efficient than generating DMA buffers and starting DMA, unless transfers are larger than some 50 bytes.

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 03:03:00 pm
content: Does the 22 cycles include stacking the FPU registers?

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 07, 2024, 03:48:55 pm
content: I found thisST documentwith information about the QSPI peripheral.Amongst many the STM32F412, STM32F446, STM32H743 do have it and I happen to have these in my collection.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 07, 2024, 03:54:06 pm
content: Quote from: peter-h on September 07, 2024, 03:03:00 pmNo, but there should be absolutely no reason to do FPU calculations in your timing critical SPI access interrupt, especially if we talk about byte-per-byte transfer. Populate/parse the buffers with floats elsewhere.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 07, 2024, 04:37:48 pm
content: Quote from: voltsandjolts on September 06, 2024, 05:51:40 pmI'm confused by the ST documentation. In the document I found about the QuadSPI there is this table that lists the benefits of STM32 embedded Quad-SPI interfaceand it lists multiple memory solutions, being volatile or non volatile, and it also lists supports any Quad-SPI memories available in the market, but the repository voltsandjolts provided a link to mentions that you need to replace the MCU with another one (STM32H7A3) because the STM32H750 only supports memory mapping of FLASH memory.I looked at the datasheet of both and the STM32H7A3 shows an Octo-SPI interface and indeed mentions serial PSRAM where the STM32H750 only mentions Flash.Does this indeed mean that the MCU's mentioned in the document I found can't memory map PSRAM and makes it useless that way?I have not read the reference manuals to see what the specifics of the different peripherals are.

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 04:40:37 pm
content: QuoteWell this is interesting, especially the 32F412. How old is that chip? These all do the memory mapping, although for QSPI chips only.QuoteYou might be doing float calcs somewhere and then the SPI interrupt occurs, so how do you avoid? Say the code is running with the FPU enabled.QuoteCertainly some CPUs with a QSPI interface support the transparent mapping of the QSPI memory chip into the CPU's linear address space.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 07, 2024, 04:54:26 pm
content: Quote from: peter-h on September 07, 2024, 04:40:37 pmAvoid what? This is irrelevant. As long as the ISR itself does not use floats, they don't get stacked. ARM Cortex-M implements lazy stacking and stacks the float registers when the first float operation is encountered. Therefore you can simply use floats everywhere your code, including most interrupts, and choose not to use them in those most timing-critical interrupts.

author: peter-h
author_rank: Super Contributor
timestamp: September 07, 2024, 05:47:55 pm
content: It does seem that interrupts are barely viable for single SPI @21MHz.This also explains why those QSPI chips implement the mapping to linear address space: it would be hard or impossible to move the data conventionally at say 100MHz.