Hi Evgeny
Here is a reference from the uTasker project:
static const unsigned long ulSPI_TX[8] = { // fixed SPI transmission (0x01, 0x02,.. 0x08) with CS0 asserted throughout the frame
(0x01 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x02 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x03 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x04 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x05 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x06 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x07 | SPI_PUSHR_CONT | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0),
(0x08 | SPI_PUSHR_EOQ | SPI_PUSHR_PCS0 | SPI_PUSHR_CTAS_CTAR0), // final byte negates CS after transmission
};
fnConfigDMA_buffer(3, DMAMUX_CHCFG_SOURCE_SPI0_TX, sizeof(ulSPI_TX), ulSPI_TX, (void *)SPI0_PUSHR_ADDR, (DMA_LONG_WORDS | DMA_DIRECTION_OUTPUT | DMA_SINGLE_CYCLE), _spi_tx_dma_Interrupt, SPI_DMA_TX_INT_PRIORITY);
It sends 8 data bytes of 1,2,3,4,5,6,7,8 and asserts the CS0 during the transmission (as controlled by the SPI_PUSHR_CONT and SPI_PUSHR_EOQ flags in each command/data.
DMA channel is 3 and the SPI Tx trigger is selected by DMAMUX_CHCFG_SOURCE_SPI0_TX, which is 17 (0x11) for K20/K10 (see the DMAMUX section in the user's manual for a list of trigger channel numbers).
_spi_tx_dma_Interrupt is an optional end of transfer interrupt call-back (otherwise set to 0).
To your questions:
- The TCD_NBYTES_ML value matches the number of physical bytes to be transferred, as does TCD_DLASTSGA, but TCD_BITER_ELINK and TCD_CITER_ELINK need to be set to the number of "service requests" (number of physical bytes/4 for long word transfers).
The CS line control is automated in the reference but you could also just set the CS line low (as GPIO) before starting a transmission and set it high again once the transfer has completed [DMA complete interrupt] (assuming it needs to stay low throughout the frame) - the automated method ensures accurate timing since you will need to otherwise wait for the final transfer to physically complete (poll the Tx busy flag) to ensure to not negate it too early.
If in doubt just use the uTasker Open Source project as reference where DMA interfaces are compatible with all processors and types (eg. KL with different DMA controller) and don't need the numbers to be looked up and plugged in. It simulates the DMA operation for simple verification in Visual Studio and then you can copy the values over to complete or improve the reference code that you are using.
Regards
Mark
uTasker developer and supporter (+5'000 hours experience on +60 Kinetis derivatives in +80 product developments)
Kinetis: http://www.utasker.com/kinetis.html