You are here

FX3 UART DMA mode. | Cypress Semiconductor

FX3 UART DMA mode.

Summary: 1 Reply, Latest post by RSKV on 15 Oct 2012 05:30 AM PDT
Verified Answers: 0
Last post
Log in to post new comments.
Garyio's picture
9 posts


I have been trying to get the UART to work in DMA mode. What I would like to do is receive a USB packet with some data that I that is to be sent out using the UART and also send any data received by the UART back to the computer over USB. I am able to do this using the byte by byte mode but it requires the use of a thread to continuosly look for received data and put it in a buffer to be sent back to the computer over USB. I seems like this would be a perfect use for the UART DMA mode. I can not find any examples that show how to do this besides the one that shows how to do a loopback. For that there is only one DMA channel created but I think I need to channels one for sending and one for receiveing. Is this correct?


Here is some code that I wrote to initialize the UART and create the a send and receive DMA channel. Does this look correct.


CyU3PReturnStatus_t SerialInit(void)
    CyU3PUartConfig_t uartConfig;
    CyU3PReturnStatus_t apiRetStatus;
    CyU3PDmaChannelConfig_t dmaConfig;

    // Initialize the UART.
    apiRetStatus = CyU3PUartInit();
    if (apiRetStatus != CY_U3P_SUCCESS && apiRetStatus != CY_U3P_ERROR_ALREADY_STARTED)
        return apiRetStatus;

    // Set UART configuration
    CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof (uartConfig));
    uartConfig.baudRate = CY_U3P_UART_BAUDRATE_9600;
    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;

    apiRetStatus = CyU3PUartSetConfig (&uartConfig, NULL);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;
    // Initialize the dmaConfig.
    CyU3PMemSet ((uint8_t *)&dmaConfig, 0, sizeof(dmaConfig));
    dmaConfig.size = CY_FX_UART_DMA_BUF_SIZE;
    dmaConfig.count = 1;
    dmaConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaConfig.prodHeader = 0;
    dmaConfig.prodFooter = 0;
    dmaConfig.consHeader = 0;
    dmaConfig.prodAvailCount = 0;

    // Create a channel to write to the UART.
    dmaConfig.prodSckId = CY_U3P_CPU_SOCKET_PROD;
    dmaConfig.consSckId = CY_U3P_LPP_SOCKET_UART_CONS;
    dmaConfig.notification = 0;
    dmaConfig.cb = NULL;
    apiRetStatus = CyU3PDmaChannelCreate (&glUartTxChHandle, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaConfig);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;

    // Create a channel to read from the UART.
    dmaConfig.prodSckId = CY_U3P_LPP_SOCKET_UART_PROD;
    dmaConfig.consSckId = CY_U3P_CPU_SOCKET_CONS;
    dmaConfig.notification = CY_U3P_DMA_CB_PROD_EVENT;
    dmaConfig.cb = CyFxUartDmaCallback;
    apiRetStatus = CyU3PDmaChannelCreate (&glUartRxChHandle, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaConfig);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;

    // Set UART Tx transfer Size to infinite
    apiRetStatus = CyU3PUartTxSetBlockXfer(0xffffffff);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;

    // Set UART Rx transfer Size to 1
    apiRetStatus = CyU3PUartRxSetBlockXfer(0xFFFFFFFF);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;

    // Set DMA Channel transfer size
    apiRetStatus = CyU3PDmaChannelSetXfer (&glUartTxChHandle, CY_FX_UART_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;

    return apiRetStatus;

Here is some code that send data to the UART to be transmitted. When I do this no data goes out the UART. What am I doing wrong?

CyU3PReturnStatus_t SendUART(uint8_t *buffer, int Length)
    CyU3PReturnStatus_t apiRetStatus;
    CyU3PDmaBuffer_t dmaFw2UARTBuffer;
    // Get an out buffer.
    apiRetStatus = CyU3PDmaChannelGetBuffer(&glUartTxChHandle, &dmaFw2UARTBuffer, CYU3P_WAIT_FOREVER);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;

    CyU3PMemCopy(dmaFw2UARTBuffer.buffer, buffer, Length);

    apiRetStatus = CyU3PDmaChannelCommitBuffer (&glUartTxChHandle, Length, 0);
    if (apiRetStatus != CY_U3P_SUCCESS)
        return apiRetStatus;
    return apiRetStatus;

Thank you,



rskv's picture
Cypress Employee
1134 posts

Please create a tech support case to get help related to your issue.


sai krishna.

Log in to post new comments.