FX3: UART - receive data with DMA into CPU's buffer causes CY_U3P_ERROR_NOT_STARTED

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
MaksymDevX
Level 1
Level 1
5 replies posted First reply posted First question asked

Good day everyone!

I have FX3 CYUSB3011 and I'm trying to make UART working in DMA mode to receive and process data from UART.

The problem is that sometimes received packets just dropped and CyU3PDmaChannelGetBuffer returns CY_U3P_ERROR_NOT_STARTED. And if I decrease sleep ticks issue repeats more often.

Interesting thing is that I could not find any examples of the code for the same purpose. I've tried to make it work with DMA or UART callbacks but it did not work. "Software polling" of DMA buffer is the only way that worked somehow at least.

My code below:

 

 

 

void UartReceiveTask(void * arg)
{
	CyU3PDmaBuffer_t ConsoleInDmaBuffer;
	CyU3PReturnStatus_t Status;

	while(1)
	{
		Status = CyU3PDmaChannelSetWrapUp(&glUARTtoCPU_Handle);
		if(Status == CY_U3P_SUCCESS)
		{
			Status = CyU3PDmaChannelGetBuffer(&glUARTtoCPU_Handle, &ConsoleInDmaBuffer, CYU3P_WAIT_FOREVER);
			if(Status == CY_U3P_SUCCESS)
			{
				if(ConsoleInDmaBuffer.count > 0)
				{
					protPushSequence(fifo, ConsoleInDmaBuffer.buffer,ConsoleInDmaBuffer.count);
				}

				Status = CyU3PDmaChannelDiscardBuffer(&glUARTtoCPU_Handle);
				if(Status != CY_U3P_SUCCESS)
				{
					CyU3PDmaChannelReset (&glUARTtoCPU_Handle);
					CyU3PDmaChannelSetXfer (&glUARTtoCPU_Handle, 0);
				}
			}
			else
			{
				CyU3PDmaChannelReset (&glUARTtoCPU_Handle);
				CyU3PDmaChannelSetXfer (&glUARTtoCPU_Handle, 0);
			}
		}
		else
		{
			CyU3PDmaChannelReset (&glUARTtoCPU_Handle);
			CyU3PDmaChannelSetXfer (&glUARTtoCPU_Handle, 0);
		}

		CyU3PThreadSleep(10);
	}
}

 

 

 

Initialization: 

 

 

CyU3PReturnStatus_t InitializeUart(void)
{
    CyU3PReturnStatus_t Status = CY_U3P_SUCCESS;

    Status = CyU3PUartInit();										// Start the UART driver
    CheckStatus("CyU3PUartInit", Status);							// This will not display since we're not connected yet

    CyU3PMemSet ((uint8_t *)&glUartConfig, 0, sizeof (glUartConfig));
    glUartConfig.baudRate = CY_U3P_UART_BAUDRATE_38400;
    glUartConfig.stopBit  = CY_U3P_UART_ONE_STOP_BIT;
    glUartConfig.parity   = CY_U3P_UART_NO_PARITY;
    glUartConfig.txEnable = CyTrue;
    glUartConfig.rxEnable = CyTrue;
    glUartConfig.flowCtrl = CyFalse;
    glUartConfig.isDma    = CyTrue;
	Status = CyU3PUartSetConfig(&glUartConfig, UartCallback);	// Configure the UART hardware
    CheckStatus("CyU3PUartSetConfig", Status);

    CyU3PDmaChannelConfig_t dmaConfig;
	CyU3PMemSet((uint8_t *)&dmaConfig, 0, sizeof(dmaConfig));
	dmaConfig.size  		= 1024;
	dmaConfig.count 		= 4;
	dmaConfig.prodSckId		= CY_U3P_CPU_SOCKET_PROD;
	dmaConfig.consSckId 	= CY_U3P_LPP_SOCKET_UART_CONS;
	Status = CyU3PDmaChannelCreate(&glCPUtoUART_Handle, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaConfig);
    CheckStatus("CreateDebugTxDmaChannel", Status);

	dmaConfig.prodSckId		= CY_U3P_LPP_SOCKET_UART_PROD;
	dmaConfig.consSckId 	= CY_U3P_CPU_SOCKET_CONS;
	Status = CyU3PDmaChannelCreate(&glUARTtoCPU_Handle, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaConfig);
    CheckStatus("CreateDebugRxDmaChannel", Status);


    Status = CyU3PUartTxSetBlockXfer(0xFFFFFFFF);
    CheckStatus("CyU3PUartTxSetBlockXfer", Status);
    Status = CyU3PUartRxSetBlockXfer(1);
    CheckStatus("CyU3PUartRxSetBlockXfer", Status);

	Status = CyU3PDmaChannelSetXfer(&glUARTtoCPU_Handle, 0);
    CheckStatus("ChannelSetXfer", Status);
	Status = CyU3PDmaChannelSetXfer(&glCPUtoUART_Handle, 0);
    CheckStatus("ChannelSetXfer", Status);

	if (Status == CY_U3P_SUCCESS) glUartTxEnabled = CyTrue;
    CheckStatus("ConsoleOutEnabled", Status);						// First console display message

    return Status;
}

 

 

 

Please help. Best regards

0 Likes
1 Solution
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

CY_U3P_ERROR_NOT_STARTED error is returned by CyU3PDmaChannelGetBuffer when DMA channel is not in one of the following state -  CY_U3P_DMA_ACTIVE or CY_U3P_DMA_IN_COMPLETION

Please let me know why is  CyU3PUartRxSetBlockXfer is set with rxsize as 1. The UART RX will stop receiving the data once the the rxsize is received. You would need to call CyU3PUartRxSetBlockXfer again to receive data or set the rxsize to infinite/indefinite as done for txSize in CyU3PUartTxSetBlockXfer.

Regards,
Rashi

View solution in original post

0 Likes
11 Replies