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?
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
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!
-----------------------------------------------------------------------------------------------------------------------