1

The documentation on the SPI peripheral says:

Two DMA channels are required, one to read from and one to write to the SPI.

Is this necessarily true? I have a device where I need to write a few bytes by SPI and then receive a very large amount of data (eg 32k) back over SPI.

Is it possible to do the write portion (ie sending a few bytes to the slave) by directly accessing the SPI peripheral, then setting up DMA to receive the response back? Or do I need to set up two DMA transfers, one of which writes a few significant bytes and then a big pile of junk, and the other receives a few bytes of junk and then 32k of interesting data?

3
  • Surely you need to keep the write buffer filled? If it empties the SPI transfer will stall.
    – joan
    Aug 14, 2018 at 16:37
  • Possibly this is my ignorance of SPI or the SPI peripheral - is it necessary to continuously send and receive on the SPI bus? The device I'm talking to is an MCP3914 analog front end, which has a continuous-read mode, where you request the first register you want to read and then keep CS active and it cycles through reading all its registers; I want to do this more or less indefinitely and so don't really want to tie up a second DMA channel writing I-don't-care-what (actually an infinite chain of 0s) to the device.
    – Tom
    Aug 15, 2018 at 9:44
  • Looking further, it looks like I can do the write portion of the transaction by accessing the SPI peripheral directly, then do the read portion using DMA, with the outgoing DMA channel set up to read from a single word in memory with the SRC_INC field set to 0 so that it always reads from the same location. I think.
    – Tom
    Aug 15, 2018 at 10:13

2 Answers 2

0

The problem you face is that - assuming you're the master - in order to receive the 32k of interesting data you need to generate SCLK for all of it. And the way you generate SCLK is by writing transmit data, even if it's a big pile of junk.

So unless you can figure out a way for the receive DMA channel to also write dummy transmit data, you're kind of stuck with having to use two channels.

0

You could use one DMA channel, triggered by the SPI transmit data request, that has one control block to write a dummy byte to the SPI transmit, chained to another CB that reads a data byte from the SPI receive. Unfortunately, every time you load a control block, the DMA source & destination addresses are reset back to their starting values, so you won't have an incrementing destination address storing a block of data.

So you do need 2 DMA channels, but the transmitter channel can repeatedly send the same (dummy) byte, using a non-incrementing source address.

If you are dealing with large data volumes (over 64K) you'll need to use one of the DMA channels that isn't 'lite', as these have limited capabilities, see the BCM2835 ARM Peripherals document for details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.