- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have FX3 CYUSB2014 / 3014 and I'm trying to make UART work in DMA mode to receive and process data from UART. Using a Manual DMA Channel to read data, and process in a callback. Right now, it just sends the data over the host USB (CDC Interface) I've tried different buffer sizes and counts.
Sending "packets" of 32 bytes at a time to test, After about 4-16 packets it fails with error 73, CY_U3P_ERROR_DMA_FAILURE. Any later calls to CyU3PDmaChannelSetWrapUp return error 71 - CY_U3P_ERROR_INVALID_SEQUENCE.
Wondering why it fails in the first place, or what can be done to reset, and recover the data.
Thanks-Greg
INIT:
CyU3PReturnStatus_t InitializeDebugConsole(void)
{
CyU3PUartConfig_t uartConfig;
CyU3PDmaChannelConfig_t dmaConfig;
CyU3PReturnStatus_t Status = CY_U3P_SUCCESS;
Status = CyU3PUartInit(); // Start the UART driver
CheckStatus("CyU3PUartInit", Status);
CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof (uartConfig));
uartConfig.baudRate = CY_U3P_UART_BAUDRATE_115200; //default buad of UART
uartConfig.stopBit = CY_U3P_UART_ONE_STOP_BIT;
uartConfig.parity = CY_U3P_UART_NO_PARITY;
uartConfig.txEnable = CyTrue;
uartConfig.rxEnable = CyTrue;
uartConfig.flowCtrl = CyFalse;
uartConfig.isDma = CyTrue;
Status = CyU3PUartSetConfig(&uartConfig, UartCallback); // Configure the UART hardware
CheckStatus("CyU3PUartSetConfig", Status);
Status = CyU3PUartTxSetBlockXfer(0xFFFFFFFF); // Send as much data as I need to
CheckStatus("CyU3PUartTxSetBlockXfer", Status);
Status = CyU3PDebugInit(CY_U3P_LPP_SOCKET_UART_CONS, 6); // Attach the Debug driver above the UART driver
if (Status == CY_U3P_SUCCESS) glDebugTxEnabled = CyTrue;
CheckStatus("ConsoleOutEnabled", Status);
CyU3PDebugPreamble(CyFalse); // Skip preamble, debug info is targeted for a person
// Now setup a DMA channel to receive characters from the Uart Rx
Status = CyU3PUartRxSetBlockXfer(1); //was 1 GH 7/1/2021
CheckStatus("CyU3PUartRxSetBlockXfer", Status);
CyU3PMemSet((uint8_t *)&dmaConfig, 0, sizeof(dmaConfig));
dmaConfig.size = 128; // 16 is Minimum size allowed, I only need 1 byte. sb multiples of 16
dmaConfig.count = 8; // I can't type faster than the Uart Callback routine!
dmaConfig.prodSckId = CY_U3P_LPP_SOCKET_UART_PROD;
dmaConfig.consSckId = CY_U3P_CPU_SOCKET_CONS;
dmaConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaConfig.notification = CY_U3P_DMA_CB_PROD_EVENT;
Status = CyU3PDmaChannelCreate(&glUARTtoCPU_Handle, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaConfig);
CheckStatus("CreateDebugRxDmaChannel", Status);
if (Status != CY_U3P_SUCCESS) CyU3PDmaChannelDestroy(&glUARTtoCPU_Handle);
else
{
Status = CyU3PDmaChannelSetXfer(&glUARTtoCPU_Handle, 0); //Zero for infinite transfer
CheckStatus("ConsoleInEnabled", Status);
}
return Status;
}
CALLBACK:
void UartCallback(CyU3PUartEvt_t Event, CyU3PUartError_t Error)
// Handle characters typed in by the developer
{
CyU3PDmaBuffer_t ConsoleInDmaBuffer;
CyU3PReturnStatus_t Status = CY_U3P_SUCCESS;
char pInputChar[32] = "";
uint16_t bufferlen ;
if (Event == CY_U3P_UART_EVENT_RX_DONE)
{
Status = CyU3PDmaChannelSetWrapUp(&glUARTtoCPU_Handle);
CheckStatus("CyU3PDmaChannelSetWrapUp", Status);
if(Status == CY_U3P_SUCCESS)
{
Status = CyU3PDmaChannelGetBuffer(&glUARTtoCPU_Handle, &ConsoleInDmaBuffer, CYU3P_NO_WAIT);
CheckStatus("CyU3PDmaChannelGetBuffer", Status);
if(Status == CY_U3P_SUCCESS)
{
if (ConsoleInDmaBuffer.count > 0)
{
if (ConsoleInDmaBuffer.count > 31) //max of 31 to prevent filling the string.
{
bufferlen = 31;
}
else
{
bufferlen = ConsoleInDmaBuffer.count;
}
strncpy(pInputChar,(char*)ConsoleInDmaBuffer.buffer,bufferlen);
if (gUartEcho)
{
DebugPrint(0, "%s", pInputChar); // Echo the character
}
// If True, the characters typed on the debug console are sent to the PC Host via the CDC Interface
if (gUartReTransOnCDC)
{
SendString(pInputChar);
}
}
}
}
CyU3PDmaChannelDiscardBuffer(&glUARTtoCPU_Handle);
}
CyU3PUartRxSetBlockXfer(1); //Set back to 1 to reset
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
CY_U3P_ERROR_DMA_FAILURE comes from API version 1.3 function: CyU3PDmaChannelGetBuffer()
>> I understand that this error is returned by CyU3PDmaChannelGetBuffer API called in UartCallback
If yes and if you want to use UART in DMA mode, please try the following
- Call only CyU3PDmaChannelSetWrapUp API in the UartCallback and set an event using CyU3PEventSet API
- Call CyU3PEventGet in the thread entry function for loop and call CyU3PDmaChannelGetBuffer and then continue the rest of the processing in the for loop and at the end of the processing call CyU3PUartRxSetBlockXfer to enable receiving 1 byte for the next transfer.
Rashi