FX3 UART DMA mode.

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

cross mob
Anonymous
Not applicable

Hello,

   

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,

   

Garyio

0 Likes
2 Replies
Anonymous
Not applicable

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

   

Thanks,

   

sai krishna.

0 Likes
Anonymous
Not applicable

Hi guys:

    I also encountered the same problem as you,I can only transfer UART data using register mode.But that seems to be a problem, so I have to use DMA mode.

     Do you finally use DMA mode for UART data transfer?If you have solved this problem, can you share your solution or code?

Best regards,

Luca

0 Likes