The DMA in PSoC 6 supports 2D transfer of data from source to destination.
In your case you can configure your source as 2D array with 128 bytes in each row. The destination is a single 128 byte array (SPI TX FIFO)
What keeps the DMA transfer from overrunning the Tx fifo?
You can set the Trigger input type as One X loop per transfer. Here X loop will be the 128 byte array.
So, you need to Trigger the DMA (either through Hardware or Firmware) after you knew that the SPI TX FIFO is empty.
Please refer PSoC Creator code CE221120 PSoC 6 SPI Master which has a project to work with SPI using DMA.
Also please refer an application note on PSoC 6 DMA for more information on DMA.
Hope this helps !
You usually trigger the Channel of DMA using the TX Trigger output signal from the SPI (SCB) block. This signal's behavior is controlled by the TX FIFO level setting. You should set TX FIFO level to a number (0 - 127) less than the maximum FIFO depth (128). If you set this TX FIFO level to say 64, the TX Trigger output signal will be active until the TX FIFO has 64 elements. Above that the TX FIFO level, the TX Trigger output signal is de-asserted. Therefore giving no further trigger to the DMA channel. This ensures that the TX FIFO is not overrun.
You need to configure the DMA Channel to transfer one element per trigger and the number of elements to be transferred can be decided using the X loop and Y loop settings.
In your use case, if you have to transfer 1000 bytes, you do the following;
1. Set TX FIFO level to 64 (or anything between 1 to 127)
2. DMA settings can be something like below. You will transfer 250 x 4 bytes = 1000 bytes.
That helped a lot, but I am still trying to develop a correct mental model.
Please let me know if any of the following is incorrect:
When using the DMA method, the SPI block is really just a passive agent. It really doesn't know when any given SPI exchange has ended. Its only real role it to check on the levels in the tx fifo and rx fifo levels and generate triggers for the DMA block based on those levels. So the SPI block only needs to be initialized and enabled.
The first half is correct. The SPI block only really takes care of the transmission of the elements in the Tx FIFO. What needs to be transmitted is taken care either by the CPU or the DMA.
Here too, the first statement is correct. It is the SCB block that takes care of asserting/deasserting the physical SS pin. But which pin to be used as SS is decided by writing the Cy_SCB_SPI_SetActiveSlaveSelect API.
A DMA only takes care of writing into/reading from the SCB FIFO. All other configurations such as choosing the SS pin, enabling the block etc must be done by the CPU in the main code. Once the active SS pin is selected by the CPU core, simply writing into the FIFO of the SCB will result in correct transmission of the packet.