SAM7 SPI and DMA

The documentation isn’t all that clear about how DMA works with SPI. Is the contents of the DMA buffer blindly copied to the transmit data register? Or does it copy just the data section? If it writes just the data section, how would you tell it which SPI channel to send to (i.e., the value of PCS)? For that matter, how would it handle a 9-15 bit transfer mode?

Does anyone know exactly how the DMA works with the SPI port? Any expanded documentation? Or code that shows how the various modes work? The best that I could find is rather sketchy; DMA is there, but there’s no indication of how it would work with variable peripheral select, or any non 8-bit transfer mode.

Hans

EDIT: The other issue no longer exists, so I’ve deleted it from this post.

The modes are set individually for each slave. For every SPI transfer, the PDC needs a full 32 bits. In that 32 bits, you have the slave-select bits and that also determines which settings are to be used for the SPI.

If you want 8-bit transfers, you will still need a whole word in the buffer and only 8 of the transfer-bits are used.

A little better explanation now that I got more time.

The SPI peripheral has 4 x “SPI Chip Select Register”. One for each slave.

[If you want more than 4 slaves, you need an external decoder and have to setup the SPI for this. However, they will be grouped in fours, sharing the same SPI Chip Select Register.]

The datasheet covers all the settings and modes available (bits per transfer, polarity, etc.)

To use the PDC/DMA you set the transfer count and a pointer to the buffer you want to send from or receive to. This is just the same as using the PDC for any other peripheral. However, the SPI is a special case as the buffers are always 32 bit wide, independent of the number of bits per transfer. So, one transfer uses one four byte word. For every transmission, one word is copied from the PDC address pointer to the “SPI Transmit Data Register”. The first 16 bits are used for the actual data to be transferred, and the next 4 bits are used for slave select. There is also a LASTXFER bit that you can set to have the slave select line go inactive if you have the SPI set up so that the slave-select will remain active between multiple transfers.

The above is true for the SPI set up as master. For slave operation, I guess it will be a little different, but fundamentally the same.

Thanks monstrum. That is how I thought that it might work. In some ways this is logical, but it does eliminate the possibility of streaming data directly from a source buffer.

Hans

The datasheet actually admits that it is very inefficient. But, it makes it very easy to get the data to get to the correct destination and to keep track of where the received data came from.

You could pre-format a buffer with slave-select bits and then only change the one or two lower bytes in the word, that way you don’t have to preprocess a lot of data.

I re-read the SPI-chapter in the datasheet. What I prevously described is correct, but not complete.

If you use fixed-peripheral mode (as opposed to variable-mode), the PDC actually uses 8- or 16-bit buffers, which only wastes memory if you odd transfer bit-lengths.

If you have multiple SPI-slaves, you can still use fixed-peripheral mode, but you would have to configure SPI-settings whenever you change slave. Off course you will also manually have to select the correct chip-select using PIO.