Use DMA for transfering CAN data to buffer or memory location

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

Use DMA for transfering CAN data to buffer or memory location

861 Views
SimonSchnee
Contributor III

Hello!

 

I am now working to get a DMA transfer running. I just want to let the DMA automatically transfer incoming CAN messages to a internal buffer or memory location. (Using MCUXpresso for implementations for the LCPXpresso54628 development board)

Right now I am using the example code, but there are no examples how to use the DMA for "Peripheral to Memory" applications.

Does someone has already done something like this or experience with such implementation. For me it is not clear how the CAN peripheral can automatically trigger the DMA to transfer the incoming data.

 

Best regards.

Labels (2)
Tags (3)
0 Kudos
2 Replies

856 Views
SimonSchnee
Contributor III

Following code is used right now, but it does not work.

 

/*!
 * @brief User callback function for DMA transfer.
 */
void DMA_Callback(dma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
    if (transferDone)
    {
    	DMA_TransferDone = true;
    }
}


/*!
 * @brief Initialize routine for LED2 and SW5
 */
void DMA_Initialize(DMA_Type * DMA, uint32_t const channel)
{
	/* Configure DMA one shot transfer */
	/*
	 * userConfig.enableRoundRobinArbitration = false;
	 * userConfig.enableHaltOnError = true;
	 * userConfig.enableContinuousLinkMode = false;
	 * userConfig.enableDebugMode = false;
	 */
	DMA_Init(DMA);

	/* Initialize DMA handle */
	DMA_CreateHandle(&DMA_Handle, DMA, channel);

	/* Enable newly created DMA handle */
	DMA_EnableChannel(DMA, channel);

	/* Set callback function for DMA */
	DMA_SetCallback(&DMA_Handle, DMA_Callback, NULL);

	/* Prepare DMA transfer for CAN0 to Memory */
	DMA_PrepareTransfer(&DMA_transferConfig, (void*)(&rxFrame0.data[0]), &destBuffer[0],
			sizeof(rxFrame0.data[0]), 8, kDMA_PeripheralToMemory, NULL);

	/* Submit DMA transfer request according to transfer configurations */
	DMA_SubmitTransfer(&DMA_Handle, &DMA_transferConfig);
}

/*
 * @brief   Application entry point.
 */
int main(void)
{
	/* Initialize board hardware. */
 	BOARD_InitBootPins();
	BOARD_InitBootClocks();
	BOARD_InitBootPeripherals();

	/* Initialize FSL debug console */
	BOARD_InitDebugConsole();

	/* Initialize LED and SW */
	GPIO_Init();

	/* Initialize CAN TX and RX */
	CAN_Init(CAN0);
	CAN_Init(CAN1);

	/* Initialize DMA */
	DMA_Initialize(DMA0, 0);

	uint8_t cnt = 0;

	/* Print destination buffer */
	PRINTF("Destination Buffer:\r\n");
	for (uint8_t i = 0; i < BUFF_LENGTH; i++)
	{
		PRINTF("%d\t", destBuffer[i]);
	}
	PRINTF("\r\n");

    /* Enter an infinite loop, print received CAN messages. */
    while(1)
    {
		if(rxComplete_CAN0)
		{
			DMA_StartTransfer(&DMA_Handle);

			/* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
			 * only get a point (rxFrame.data) to the fifo reading entrance.
			 * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
			memcpy(rx_data, rxFrame0.data, rxFrame0.size);

			PRINTF("Received Frame ID: 0x%x\r\n", rxFrame0.id >> STDID_OFFSET);
			PRINTF("Received Frame DATA: ");

			cnt = 0;
			while (cnt < rxFrame0.size)
			{
				PRINTF("0x%x ", rx_data[cnt++]);
			}
			PRINTF("\r\n");
			rxComplete_CAN0 = false;
		}

		if(rxComplete_CAN1)
		{
			/* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
			 * only get a point (rxFrame.data) to the fifo reading entrance.
			 * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
			memcpy(rx_data, rxFrame1.data, rxFrame1.size);

			PRINTF("Received Frame ID: 0x%x\r\n", rxFrame1.id >> STDID_OFFSET);
			PRINTF("Received Frame DATA: ");

			cnt = 0;
			while (cnt < rxFrame1.size)
			{
				PRINTF("0x%x ", rx_data[cnt++]);
			}
			PRINTF("\r\n");
			rxComplete_CAN1 = false;
		}

		if(DMA_TransferDone == true)
		{

			PRINTF("Destination Buffer:\r\n");
			for (uint8_t i = 0; i < BUFF_LENGTH; i++)
			{
				PRINTF("%d\t", destBuffer[i]);
			}

			DMA_TransferDone = false;
		}
    }

    return 0;
}
0 Kudos

826 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Pls refer to DMA chapter in the UM10912.pdf.

The mscan module is neither in the Request list as Table 300. DMA requests and trigger muxes, nor in triggering sources list as Table 301. DMA with the I2C Monitor function.

But the message buffer of mscan module is a memory, or you can view the message buffer of mscan as memory, you can use memory to memory transfer type, in the case, the DMA->CFGx[PERIPHREQEN] should be cleared, I suppose that you have to use software triggering mode to start the transfer.

Pls refer to the example of memory to memory transfer.

Hope it can help you

BR

XiangJun Rong

 

 

0 Kudos