UART to USB(CDC-ACM) dma channel failure after uart CY_U3P_UART_ERROR_RX_OVERFLOW.

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

cross mob
Anonymous
Not applicable

Hi

   

 

   

We've implemented the uvc video streaming with  virtual uart port on the host side in CX3. Virtual uart port is connected  in CX3 to regular uart using auto DMA channels. We are using this path to communicate with our custom camera sensor which is connected to CX3 uart. You can find the DMA channels definition below.

   

The standard message size for camera communication is 9 bytes, so we call CyU3PDmaChannelSetWrapUp() every 10 ms on both DMA channels to force the partial dma buffer to be sent to consumer. Host to camera channel is working fine, but in other direction after a number of messages(a few hundreds) I get CY_U3P_ERROR_INVALID_SEQUENCE error from WrapUp function.  I found it happens following uart failure, the uart status register is filled with 14 error - "RX FIFO overflow or DMA Socket Overflow". 

   

What can be the source of the error? May calls to CyU3PDmaChannelSetWrapUp() every 10 seconds cause such a behavior?

   

 

   

Thanks,

   

Roman

   

 

   

 

   

/* Configure DMA */
void setCameraDmaUart(uint16_t size) {
    print("setCameraDmaUart");

   

    USB2UART_DMA_config_t dmaCfg_usb2uart;

   

    CyU3PReturnStatus_t apiRetStatus;

   

    dmaCfg_usb2uart.size = size; // size is 512
    dmaCfg_usb2uart.count = CY_FX_USBUART_DMA_BUF_COUNT; // count is 8
    dmaCfg_usb2uart.prodSckId = CY_FX_EP_PRODUCER1_SOCKET; // from USB
    dmaCfg_usb2uart.consSckId = CY_FX_EP_CONSUMER1_SOCKET;// to UART
    dmaCfg_usb2uart.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg_usb2uart.notification = CY_U3P_DMA_CB_ABORTED | CY_U3P_DMA_CB_ERROR;    /*CY_U3P_DMA_CB_PROD_EVENT;*/
    dmaCfg_usb2uart.cb = USB2UART_error_callback;                /*CyFxUSB2UartDmaCallback;*/
    dmaCfg_usb2uart.prodHeader = 0;
    dmaCfg_usb2uart.prodFooter = 0;
    dmaCfg_usb2uart.consHeader = 0;
    dmaCfg_usb2uart.prodAvailCount = 0;

   


    apiRetStatus =CyU3PDmaChannelCreate(&glChHandleUsbtoUart,CY_U3P_DMA_TYPE_AUTO, &dmaCfg_usb2uart);

   

    if (apiRetStatus != CY_U3P_SUCCESS) {
        app_error_handler_msg(apiRetStatus,"usb2uart channel");
    }

   

    /* Create a DMA_MANUAL channel between uart producer socket and usb consumer socket */
    /* Use a smaller buffer size (32 bytes) to ensure that packets get filled in a short time. */
    /* Create a DMA_AUTO channel between usb producer socket and uart consumer socket */
    CyU3PDmaChannelConfig_t dmaCfg_uart2usb;

   

    dmaCfg_uart2usb.size = size;
    dmaCfg_uart2usb.count = CY_FX_USBUART_DMA_BUF_COUNT;
    dmaCfg_uart2usb.prodSckId = CY_FX_EP_PRODUCER2_SOCKET;
    dmaCfg_uart2usb.consSckId = CY_FX_EP_CONSUMER2_SOCKET;
    dmaCfg_uart2usb.notification = CY_U3P_DMA_CB_ABORTED | CY_U3P_DMA_CB_ERROR;    /* CY_U3P_DMA_CB_PROD_EVENT;*/
    dmaCfg_uart2usb.cb = UART2USB_error_callback;                /*CyFxUart2USBDmaCallback;*/
    dmaCfg_uart2usb.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg_uart2usb.prodHeader = 0;
    dmaCfg_uart2usb.prodFooter = 0;
    dmaCfg_uart2usb.consHeader = 0;
    dmaCfg_uart2usb.prodAvailCount = 0;

   

    apiRetStatus = CyU3PDmaChannelCreate(&glChHandleUarttoUsb,CY_U3P_DMA_TYPE_AUTO, &dmaCfg_uart2usb);
    //    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUarttoUsb,
    //            CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        app_error_handler_msg(apiRetStatus,"uart2usb channel");
    }

   


#ifdef MULTI
    apiRetStatus = CyU3PDmaMultiChannelSetXfer(&glChHandleUsbtoUart, 0, 0);
#else
    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUsbtoUart,0);
#endif
    if (apiRetStatus != CY_U3P_SUCCESS) {
        app_error_handler_msg(apiRetStatus,"set xfer usb2uart");
    }

   

    apiRetStatus = CyU3PDmaChannelSetXfer(&glChHandleUarttoUsb, 0);
    if (apiRetStatus != CY_U3P_SUCCESS) {
        app_error_handler_msg(apiRetStatus,"set xfer uart2usb");
    }

   

}

0 Likes
1 Solution
Anonymous
Not applicable

Hi,

   

If the WrapUp API is called repeatedly even when no data is coming at that instant, the empty DMA Buffers get wrapped. Once you run out of all buffers, you may get invalid sequence error. I suggest you to call the WrapUp only when data has come from UART. To know if data has arrived, you can setup an interrupt for UART Rx.

   

Regards,

   

- Madhu Sudhan

View solution in original post

0 Likes
1 Reply
Anonymous
Not applicable

Hi,

   

If the WrapUp API is called repeatedly even when no data is coming at that instant, the empty DMA Buffers get wrapped. Once you run out of all buffers, you may get invalid sequence error. I suggest you to call the WrapUp only when data has come from UART. To know if data has arrived, you can setup an interrupt for UART Rx.

   

Regards,

   

- Madhu Sudhan

0 Likes