Long SPI transfer with data from FLASH

wjxway
Posts: 17
Joined: Wed Aug 05, 2020 2:52 am

Long SPI transfer with data from FLASH

Postby wjxway » Fri Jan 24, 2025 9:05 am

I'm trying to use Lattice FPGA (ICE40HX8K) as peripheral to ESP32-S3 in my project, and the FPGA needs to be programmed through SPI every time at boot.

The most convenient way to program the FPGA seems to be using SPI slave configuration, where ESP32 is connected to the FPGA through SPI and transmits the whole binary in a single transmission. Detailed protocol shown in the following image (pretty standard).

Image

However, the binary file for the FPGA could potentially be large (MB in size), so it needs to be stored in flash instead of RAM, plus the requirement for this FPGA is that the whole binary needs to be transmitted in a single transmission without interruption. I am wondering if it is even possible, given I have to read from FLASH multiple times during transmission and seemingly SPI master peripheral on ESP32-S3 has a maximum byte length of 2048 bytes. @ESP-Sprite once mentioned that currently there is a way to do this, but I couldn't find any examples, and not sure if it can work with data in flash instead of RAM.
ESP_Sprite wrote:
Sat Mar 24, 2018 2:17 am
Yes, we at Espressif have. See the max_transfer_sz member of the spi_bus_config_t structure.
Any help is much appreciated! Thanks!

MicroController
Posts: 1954
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Long SPI transfer with data from FLASH

Postby MicroController » Fri Jan 24, 2025 9:26 am

Two things come to mind:
a) You can memory-map a partition from flash memory and then treat it as one big read-only byte array.
b) Not sure what "needs to be transmitted in a single transmission without interruption" means exactly in this case, but you can of course generate the SPI-SS signal from software, i.e. send multiple transactions in a row while keeping SS low. (Which I think you have to do because the SPI is apparently limited to transfer up to 2^18 bits (256kBit, 32kByte) in a single transaction.)

wjxway
Posts: 17
Joined: Wed Aug 05, 2020 2:52 am

Postby wjxway » Fri Jan 24, 2025 8:03 pm

MicroController wrote:
Fri Jan 24, 2025 9:26 am
Two things come to mind:
a) You can memory-map a partition from flash memory and then treat it as one big read-only byte array.
b) Not sure what "needs to be transmitted in a single transmission without interruption" means exactly in this case, but you can of course generate the SPI-SS signal from software, i.e. send multiple transactions in a row while keeping SS low. (Which I think you have to do because the SPI is apparently limited to transfer up to 2^18 bits (256kBit, 32kByte) in a single transaction.)
Thanks for your help! For b), do you mean that usually SPI only cares about signal at edges, but don't really care about whether CLK's frequency changed dramatically in the transaction process? (I never tried anything like this before with SPI) If that's the case, would it be possible to pull SS low, then initiate multiple transactions consecutively, while reading the flash between transactions? Thanks!

MicroController
Posts: 1954
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re:

Postby MicroController » Fri Jan 24, 2025 10:21 pm

wjxway wrote:
Fri Jan 24, 2025 8:03 pm
For b), do you mean that usually SPI only cares about signal at edges, but don't really care about whether CLK's frequency changed dramatically in the transaction process?
Yes. Normally the SPI master can control the clock as it pleases (up to some maximum frequency), and indeed, as you can see in the diagram you included, the SPI data line is sampled on one of the edges of the clock signal, in this case on the rising edge.
If that's the case, would it be possible to pull SS low, then initiate multiple transactions consecutively, while reading the flash between transactions?
That should definitely be possible. You could even double-buffer/overlap flash reading and SPI transfer to minimize gaps between transactions. It seems the S3 hardware can't DMA directly from flash, but you can still mmap the flash and memcpy chunks into a DMA buffer in RAM to then send out (or use the Partitions API), double-buffering if you so desire.

Who is online

Users browsing this forum: No registered users and 48 guests