eDMA/SPI Triggering

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

eDMA/SPI Triggering

314 Views
PaoloFalduto
NXP Employee
NXP Employee

Hello,

I tried to summarize the issue in one slide

PaoloFalduto_0-1709736359104.jpeg

 

I need to send a SPI command, this message starts an external ADC conversion, when the data is ready a PIN rise up. This pin should be my trigger to start a a new transaction on SPI.  I described this situation trough 2 TCD, and it works! The issue is that I would like to trigger the second TCD with external pin directly. I can set this pin both as a SPI trigger and as a DMA trigger. But I can't get it to work.

This is a simple scenario of my application, I started from this to add piece by piece and complicate it.

 

int main(void) {
 
	  /* Global initialization */
	(void)memset(DMA0_config.channelConfig, 0, FSL_FEATURE_EDMA_INSTANCE_CHANNELn(DMA0_DMA_BASEADDR) * sizeof(edma_channel_config_t *));
	AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcd_tx, EDMA_TCD_ALIGN_SIZE);
	AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcd_rx, EDMA_TCD_ALIGN_SIZE);
	AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcd_tx2, EDMA_TCD_ALIGN_SIZE);
	AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcd_rx2, EDMA_TCD_ALIGN_SIZE);
	uint32_t TxSpi1Adr = LPSPI_GetTxRegisterAddress(LP_FLEXCOMM1_PERIPHERAL);
	uint32_t RxSpi1Adr = LPSPI_GetRxRegisterAddress(LP_FLEXCOMM1_PERIPHERAL);
	AT_NONCACHEABLE_SECTION_INIT(uint8_t rx_buf[100]);
	AT_NONCACHEABLE_SECTION_INIT(uint8_t tx_buf[100]);
    memset(rx_buf, 0, 100*sizeof(*rx_buf));
    memset(tx_buf, 0, 100*sizeof(*tx_buf));
    tx_buf[1]=0b00000000;
    tx_buf[0]=0b01100000;
    /* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
    /* Init FSL debug console. */
    BOARD_InitDebugConsole();
#endif
 
    LPSPI_FlushFifo(LP_FLEXCOMM1_PERIPHERAL, true, true);
    LPSPI_ClearStatusFlags(LP_FLEXCOMM1_PERIPHERAL, (uint32_t)kLPSPI_AllStatusFlag);
    LPSPI_DisableInterrupts(LP_FLEXCOMM1_PERIPHERAL, (uint32_t)kLPSPI_AllInterruptEnable);
    LPSPI_DisableDMA(LP_FLEXCOMM1_PERIPHERAL, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
 
    /* DMA0 initiation  */
    EDMA_Init(DMA0,&DMA0_config);
    EDMA_SetChannelMux(DMA0,0,kDma0RequestMuxLpFlexcomm1Rx);
    EDMA_CreateHandle(&LP_FLEXCOMM1_RX_Handle,DMA0,0);
    EDMA_SetChannelMux(DMA0,1,kDma0RequestMuxLpFlexcomm1Tx);
    EDMA_CreateHandle(&LP_FLEXCOMM1_TX_Handle,DMA0,1);
 
    edma_tc_tx.srcAddr=(uint32_t)tx_buf;
    edma_tc_tx.srcTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_tx.srcOffset=1;
    edma_tc_tx.destAddr=TxSpi1Adr;
    edma_tc_tx.destTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_tx.destOffset=0;
    edma_tc_tx.minorLoopBytes=1;
    edma_tc_tx.majorLoopCounts=2;
    edma_tc_tx.enabledInterruptMask=0;
    edma_tc_tx.linkTCD = &tcd_tx2;
    EDMA_TcdReset(&tcd_tx);
    EDMA_ConfigChannelSoftwareTCD(&tcd_tx, &edma_tc_tx);
 
    edma_tc_rx.srcAddr=RxSpi1Adr;
    edma_tc_rx.srcTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_rx.srcOffset=0;
    edma_tc_rx.destAddr=(uint32_t)rx_buf;
    edma_tc_rx.destTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_rx.destOffset=0;
    edma_tc_rx.minorLoopBytes=1;
    edma_tc_rx.majorLoopCounts=2;
    edma_tc_rx.enabledInterruptMask=0;
    edma_tc_rx.linkTCD = &tcd_rx2;
    EDMA_TcdReset(&tcd_rx);
    EDMA_ConfigChannelSoftwareTCD(&tcd_rx, &edma_tc_rx);
 
    edma_tc_tx.srcAddr=(uint32_t)tx_buf[10];
    edma_tc_tx.srcTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_tx.srcOffset=0;
    edma_tc_tx.destAddr=TxSpi1Adr;
    edma_tc_tx.destTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_tx.destOffset=0;
    edma_tc_tx.minorLoopBytes=1;
    edma_tc_tx.majorLoopCounts=3;
    edma_tc_tx.enabledInterruptMask=0;
    edma_tc_tx.linkTCD = NULL;
    EDMA_TcdReset(&tcd_tx2);
    EDMA_ConfigChannelSoftwareTCD(&tcd_tx2, &edma_tc_tx);
 
    edma_tc_rx.srcAddr=RxSpi1Adr;
    edma_tc_rx.srcTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_rx.srcOffset=0;
    edma_tc_rx.destAddr=(uint32_t)rx_buf;
    edma_tc_rx.destTransferSize=kEDMA_TransferSize1Bytes;
    edma_tc_rx.destOffset=1;
    edma_tc_rx.minorLoopBytes=1;
    edma_tc_rx.majorLoopCounts=3;
    edma_tc_rx.enabledInterruptMask=0;
    edma_tc_rx.linkTCD = NULL;
    EDMA_TcdReset(&tcd_rx2);
    EDMA_ConfigChannelSoftwareTCD(&tcd_rx2, &edma_tc_rx);
 
    EDMA_InstallTCD(DMA0, 0, &tcd_rx);
    EDMA_EnableAutoStopRequest(DMA0, 0, true);
 
    EDMA_InstallTCD(DMA0, 1, &tcd_tx);
    EDMA_EnableAutoStopRequest(DMA0, 1, true);
 
    /* PINT0 initiation  */
    PINT_Init(PINT0_PERIPHERAL);
    PINT_PinInterruptConfig(PINT0_PERIPHERAL, PINT0_INT_0, kPINT_PinIntEnableRiseEdge, PINT_CallBack);
    PINT_EnableCallback(PINT0_PERIPHERAL);
 
    /* SPI1 INIT */
    LPSPI_MasterInit(LP_FLEXCOMM1_PERIPHERAL, &LP_FLEXCOMM1_config, LP_FLEXCOMM1_CLOCK_FREQ);
 
    LPSPI_SelectTransferPCS(LP_FLEXCOMM1_PERIPHERAL,kLPSPI_Pcs3);
    LPSPI_SetPCSContinous(LP_FLEXCOMM1_PERIPHERAL,1);
 
    LPSPI_EnableDMA(LP_FLEXCOMM1_PERIPHERAL,kLPSPI_RxDmaEnable);
    LPSPI_EnableDMA(LP_FLEXCOMM1_PERIPHERAL,kLPSPI_TxDmaEnable);
 
    LPSPI_Enable(LP_FLEXCOMM1_PERIPHERAL,1);
    EDMA_StartTransfer(&LP_FLEXCOMM1_RX_Handle);
    EDMA_StartTransfer(&LP_FLEXCOMM1_TX_Handle);
 
    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {}
    return 0 ;
}
 
void PINT_CallBack (pint_pin_int_t pintr, uint32_t pmatch_status){
    EDMA_StartTransfer(&LP_FLEXCOMM1_RX_Handle);
    EDMA_StartTransfer(&LP_FLEXCOMM1_TX_Handle);
    LPSPI_Enable(LP_FLEXCOMM1_PERIPHERAL,0);
}
 

 

0 Kudos
Reply
1 Reply

286 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I suppose that the spi of MCX is the master, after it send command to slave spi, the slave spi can output a ready signal. You can connect the ready signal to any GPIO pin, and have the GPIO port which includes the GPIO pin triggers eDMA, then eDMA can write the master spi data register to launch spi transfer,  in this way, you can guarantee that the spi reading data is valid.

The GPIO port(any GPIO signal in the port) can be the trigger source of eDMA, you can set the

The eDMA trigger source with the GPIO port.

xiangjun_rong_0-1709804027273.png

 

Each GPIO pin can generate DMA request0 or request 1 by configuring the ICR[pin] register of a specific PORT.

 

xiangjun_rong_1-1709805004252.png

Hope it can help you

BR

Xiangjun Rong

0 Kudos
Reply