i.mx RT1050 SPI DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.mx RT1050 SPI DMA

1,560 Views
christiangradl
Contributor III

Hi

i have two i.mx rt1050 connected via LPSPI, one as master the other as slave

Master                    Slave

LPSP1                   LPSPI4

CS                          CS

CLK                        CLK

MISO                      MOSI

MOSI                      MISO

Master DMA TX and slave DMA RX are both working.

next i want to exchange data with one transfer, simultanous exchange.

while master is clocking data to slave, the slave should send data back to the master.

in the examples from the sdk, the master first sends data, waits until done and then initiate the receiving.

i want to do this in one transfer.

is this possible? when yes, how? is there an example how to this?

Labels (1)
0 Kudos
2 Replies

1,035 Views
christiangradl
Contributor III

hmm...

the thing is, spi dma with simultaneous exchange is now running here. i tried it today.

SLAVE Sample code:

   // Rx
   EDMA_ResetChannel(h0->dmahandle_rx.channel);
   h0->dmahandle_rx.config.destaddr         = (unsigned long)recvbuffer0;
   h0->dmahandle_rx.config.destoffset       = 1;
   h0->dmahandle_rx.config.srcaddr          = (unsigned long)&SAFETYSPI->RDR + 3;
   h0->dmahandle_rx.config.srcoffset        = 0;
   h0->dmahandle_rx.config.desttransfersize = kEDMA_TransferSize1Bytes;
   h0->dmahandle_rx.config.srctransfersize  = kEDMA_TransferSize1Bytes;
   h0->dmahandle_rx.config.minorloopbytes   = 1;
   h0->dmahandle_rx.config.majorloopcounts  = size0;
   h0->dmahandle_rx.status.init             = 1;
   h0->dmahandle_rx.tcdlist                 = &h0->rxcontinuous;
   EDMA_TcdReset(&h0->rxcontinuous);
   EDMA_TcdSetTransferConfig(&h0->rxcontinuous, &h0->dmahandle_rx.config, &h0->rxcontinuous);
   EDMA_SetTransferConfig(&h0->dmahandle_rx, &h0->dmahandle_rx.config, &h0->rxcontinuous);
   h0->dmahandle_rx.status.config = 1;

// Tx
   EDMA_ResetChannel(h0->dmahandle_tx.channel);
   h0->dmahandle_tx.config.srcaddr          = (unsigned long)sendbuffer0;
   h0->dmahandle_tx.config.srcoffset        = 1;
   h0->dmahandle_tx.config.destaddr         = (unsigned long)&SAFETYSPI->TDR + 3;
   h0->dmahandle_tx.config.destoffset       = 0;
   h0->dmahandle_tx.config.srctransfersize  = kEDMA_TransferSize1Bytes;
   h0->dmahandle_tx.config.desttransfersize = kEDMA_TransferSize1Bytes;
   h0->dmahandle_tx.config.minorloopbytes   = 1;
   h0->dmahandle_tx.config.majorloopcounts  = size0;
   h0->dmahandle_tx.status.init             = 1;
   h0->dmahandle_tx.tcdlist                 = &h0->txcontinuous;
   EDMA_TcdReset(&h0->txcontinuous);
   EDMA_TcdSetTransferConfig(&h0->txcontinuous, &h0->dmahandle_tx.config, &h0->txcontinuous);
   EDMA_SetTransferConfig(&h0->dmahandle_tx, &h0->dmahandle_tx.config, &h0->txcontinuous);
  
   EDMA_StartTransfer(&h0->dmahandle_tx);
   EDMA_StartTransfer(&h0->dmahandle_rx);

   SAFETYSPI->DER |= (LPSPI_DER_RDDE_MASK | LPSPI_DER_TDDE_MASK);
   SAFETYSPI->CR  |= LPSPI_CR_MEN_MASK;

MASTER Sample Code

   // Rx
   EDMA_ResetChannel(h0->dmahandle_rx.channel);
   h0->dmahandle_rx.config.destaddr         = (unsigned long)recvbuffer0;
   h0->dmahandle_rx.config.destoffset       = 1;
   h0->dmahandle_rx.config.desttransfersize = kEDMA_TransferSize1Bytes;
   h0->dmahandle_rx.config.srctransfersize  = kEDMA_TransferSize1Bytes;
   h0->dmahandle_rx.config.minorloopbytes   = 1;
   h0->dmahandle_rx.config.srcaddr          = (unsigned long)&SAFETYSPI->RDR + 3;
   h0->dmahandle_rx.config.srcoffset        = 0;
   h0->dmahandle_rx.config.majorloopcounts  = size0;
   h0->dmahandle_rx.status.init             = 1;
   EDMA_TcdReset(&h0->rxcontinuous);
   EDMA_TcdSetTransferConfig(&h0->rxcontinuous, &h0->dmahandle_rx.config, &h0->rxcontinuous);
   EDMA_SetTransferConfig(&h0->dmahandle_rx, &h0->dmahandle_rx.config, &h0->rxcontinuous);

   // Tx
   EDMA_ResetChannel(h0->dmahandle_tx.channel);
   h0->transmitCommand = SAFETYSPI->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK);
   h0->dmahandle_tx.config.srcaddr          = (unsigned long)&h0->transmitCommand;
   h0->dmahandle_tx.config.srcoffset        = 0;
   h0->dmahandle_tx.config.destaddr         = (unsigned long)&SAFETYSPI->TCR;
   h0->dmahandle_tx.config.destoffset       = 0;
   h0->dmahandle_tx.config.srctransfersize  = kEDMA_TransferSize4Bytes;
   h0->dmahandle_tx.config.desttransfersize = kEDMA_TransferSize4Bytes;
   h0->dmahandle_tx.config.minorloopbytes   = 4;
   h0->dmahandle_tx.config.majorloopcounts  = 1;
   h0->dmahandle_tx.status.init             = 1;
   EDMA_TcdReset(&h0->txcontinuous);
   EDMA_TcdSetTransferConfig(&h0->txcontinuous, &h0->dmahandle_tx.config, NULL);

   h0->dmahandle_tx.config.srcaddr          = (unsigned long)sendbuffer0;
   h0->dmahandle_tx.config.srcoffset        = 1;
   h0->dmahandle_tx.config.destaddr         = (unsigned long)&SAFETYSPI->TDR + 3;
   h0->dmahandle_tx.config.destoffset       = 0;
   h0->dmahandle_tx.config.srctransfersize  = kEDMA_TransferSize1Bytes;
   h0->dmahandle_tx.config.desttransfersize = kEDMA_TransferSize1Bytes;
   h0->dmahandle_tx.config.minorloopbytes   = 1;
   h0->dmahandle_tx.config.majorloopcounts  = size0;
   EDMA_SetTransferConfig(&h0->dmahandle_tx, &h0->dmahandle_tx.config, &h0->txcontinuous);
   EDMA_StartTransfer(&h0->dmahandle_rx);

   SAFETYSPI->DER |= (LPSPI_DER_RDDE_MASK | LPSPI_DER_TDDE_MASK);
   SAFETYSPI->CR  |= LPSPI_CR_MEN_MASK;

void SAFETYSPIMASTER_Send(void)
{
   LPSPIDMA_TYPE *h=&safetyspi_master;
   SAFETYSPI->CR &= ~LPSPI_CR_MEN_MASK;
   EDMA_StopTransfer(&h->dmahandle_tx);
   EDMA_ResetChannel(h->dmahandle_tx.channel);
   SAFETYSPI->SR = LPSPI_SR_TDF_MASK | LPSPI_SR_RDF_MASK | LPSPI_SR_WCF_MASK |

                   LPSPI_SR_FCF_MASK |
                   LPSPI_SR_TCF_MASK | LPSPI_SR_TEF_MASK | LPSPI_SR_REF_MASK | LPSPI_SR_DMF_MASK |
                   LPSPI_SR_MBF_MASK;
   // Set Transmit Command Register
   SAFETYSPI->TCR = h->tcr;
   EDMA_SetTransferConfig(&h->dmahandle_tx, &h->dmahandle_tx.config, &h->txcontinuous);
   EDMA_StartTransfer(&h->dmahandle_tx);
   SAFETYSPI->CR |= LPSPI_CR_MEN_MASK;
}

So, I think it is possible

1,035 Views
art
NXP Employee
NXP Employee

No, it is not possible, because the transferred data word must be first completely shifted into the Rx Shift register on the receiving side before it becomes accessible through the RxFIFO.


Have a great day,
Artur

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos