CrizzyD91
Posts: 6
Joined: Sun Feb 21, 2021 1:01 pm

How can I get a 250,000 bytes transfer over SPI on raspberry pi 4?

Thu Sep 02, 2021 2:51 pm

Hi,
I'm looking to do a data logging project that involves transmitting data from an FPGA to a Raspberry Pi 4 through SPI. The FPGA will transfer 250,000 bytes approximately every 7 seconds. I would like for the Pi to read this data and convert/organise it as needed. Ideally the data would be transferred within a second in order to give the Pi enough time to process the data, so I'm looking to have a SPI speed of at least 2Mbit/s. So far, I'm using an STM32 to provide dummy values and to just get the SPI working on the Pi. Because the Pi won't know when data is ready (and it HAS to be the master on the SPI bus) the slave device will generate a seperate signal on a GPIO pin just to let the Pi know that it needs access to the SPI bus. I'm using python spidev. The code:

Code: Select all

#a simple test for spi

import spidev
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.IN)
#using spi0
bus = 0

#device is chip select.
device = 0

#enable
spi = spidev.SpiDev()

#open a connection to a specific bus and device (CS pin)
spi.open(bus, device)

#set spi speed and mode
spi.max_speed_hz = 5000000
spi.mode = 0

#msg = ["Hello! "]
msg = [72, 101, 108, 108, 111, 33, 32]
msgRx = 0;
print ("python spi test program with STM32")
#GPIO.output(7,0)
time.sleep (1)
while True :
    
    if GPIO.input(7) == 1:
        time.sleep(0.2)#needed to ensure that there aren't multiple triggers within the 100ms pulse
        #msgRx = spi.readbytes(100000)
        msgRx = spi.xfer3(100000)
        print ("Message received")
        print (msgRx)
        
So the code sets up the GPIO and SPI accordingly and then it sits in a loop, polling a pin waiting for the slave device (STM32F4 in this case) to be ready. The pin is set high every 3 seconds for a period of 100ms. As you can see in the code, I want to read 100 Kbytes. This code works fine if I want to just read a few bytes, but it doesn't work with larger data transfers. It seems to just read in the first few hundred bytes. Now my question: How can I get the raspberry pi to accept a larger data transfer over SPI? If I need to split the data up in to packets or smaller chunks, how can I do that in spidev? Any help would be appreciated.

cleverca22
Posts: 4714
Joined: Sat Aug 18, 2012 2:33 pm

Re: How can I get a 250,000 bytes transfer over SPI on raspberry pi 4?

Thu Sep 02, 2021 4:54 pm

250,000 bytes would be 2,000,000 bits
over 7 seconds, gives an SPI clock of 285,714
that feels do-able

but over 1 second, thats 2mhz, hmmm, still feels fine, since ive gone upwards of 75mhz square waves...

but you may want to look into other options

have you seen the SMI peripheral before?
https://iosoft.blog/2020/07/16/raspberry-pi-smi/
https://github.com/librerpi/rpi-tools/b ... smi-test.c

basically, you have a 18bit data bus, and some strobe signals to initiate data transfer
so you can then move 18 bits per cycle, and get away with far lower frequencies

chipace
Posts: 192
Joined: Sat Jun 29, 2019 2:56 am
Location: brown paper bag in a septic tank

Re: How can I get a 250,000 bytes transfer over SPI on raspberry pi 4?

Tue Sep 28, 2021 1:45 am

(1) Change the default spidev.bufsiz=65536 to /boot/cmdline.txt, this gives a 4k byte page size. 250k/4 = 63 pages.
(2) Set the SPI frequency to 8MHz (I can run my RPi4b as fast as 16MHz without any errors). This should be a 1MB/s rate with some overhead between each of the 63 transfers.
(3) Have the FPGA drive the output data on the external SPI clock input

I make python drivers for SPI Flash chips ( https://github.com/charkster/GD25Q32C ) and FPGA projects ( https://github.com/charkster/SCARF ).

Return to “Interfacing (DSI, CSI, I2C, etc.)”