PRU/DDR Feasibility

I’m looking at moving away from an FPGA to a PocketBeagle for a new project, and I think I can divide up my real-time tasks between the 2 PRU’s:

  1. Use PRU0 as a SPI master to capture external 16-bit ADC data at 500kS/s
  2. Store around 30MB of samples in DDR
  3. Change PRU0 firmware to be a SPI slave to transfer these samples to an external host with a SPI clock rate in the neighborhood of 40MHz (~2.5MB/s)
  4. PRU1 will act as an I2C slave handling stop/start/config requests for the two PRU0 activities.

I’m a little concerned about the DDR transfer in step 3 keeping up with the SPI clock rate. Will this transfer be subject to possible latencies in the non-RTOS core? Or, is there a way to architect this where PRU0 has direct access to the 512MB external memory? The linux core does not necessarily need to see or even know about this data, I simply need to store it and then dump it back out.

Thanks,

Dave

I’m also reading that allocating more than 8MB of the external RAM may be an issue. Looks like I might need the core after all to facilitate an intermediary ring buffer to the full 30MB of memory is user space…

DDR bandwidth will be sufficient. You should be worried about DDR read access latency. I think that in the worst case you may not be able to read data in time for the spi byte shift. I would suggest to dedicate one pru to copy from ddr into shared sram. Or check if hw spi can ne used in slave mode.

TI wiki had a table with typical cycles needed by pru for accessing ddr and sram.

Regards,
Dimitar

понеделник, 22 януари 2018 г., 18:58:17 UTC+2, David Edwards написа:

Have a look at the BeagleLogic project: they use one PRU for data acquisition and the other one to write to a portion of DDR allocated through a kernel driver:
https://github.com/abhishek-kakkar/BeagleLogic/blob/master/firmware/beaglelogic-pru0.c

If I understand correctly, you are only trying to move 1 MB/s into
SDRAM, which should not be a problem. You should do burst writes for
efficiency, see the BeagleLogic code for examples. If you don't want
to hassle with ring-buffers, you can dedicate a chunk of contiguous
physical memory to your application by editing the device-tree and
adding a "reserved-memory" stanza:

https://www.kernel.org/doc/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt

You'll still have to deal with cache coherency issues, however.