Using the Cypress FX3 UART for microcontroller communication

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

cross mob
mile_4687071
Level 1
Level 1

Hello,

I want to use the FX3 UART peripheral for communication with another microcontroller. We are using six FX3 as slaves and one microcontroller as a master and developed a protocol for communication.

I was wondering about how to use DMA mode. Am I right, that Rx is only possible for a fixed number of bytes? So the message length should not vary?

When using Reg mode for Rx, is the FX3 waiting until the specified count of bytes were received and could not do anything else in this time?

In the examples there is a "CyFx3BootUartDmaXferData" and "CyFx3BootUartDmaXferData" function. But in SDK 1.3.3 I can not find those... How can I send messages in DMA mode via UART?

I would like to use the CyU3PUartTransmitBytes function in Reg mode and CyU3PUartRxSetBlockXfer in DMA mode because of getting the interrupts when a message from the master is received. Is it possible during operartion to change into Reg mode before using the TransmitBytes function and after that change back to DMA mode waiting for a response? It would only be necessary for an ACK or something like this.

Thanks a lot.

Best,

Mika

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

Hello Mika,

From the description, i understood that UART to USB channel should be created in DMA mode. Is this right?

1) DMA Mode

Please refer to usbuart (SDK installation path\Cypress\EZ-USB FX3 SDK\1.3\firmware\serialif_examples\cyfxusbuart)  example in the SDK 1.3.4 which implements DMA channel between UART (producer) and USB (consumer)

The DMA channel is configured as shown

    /* Create a DMA_AUTO channel between usb producer socket and uart consumer socket */

    dmaCfg.size = size;                                                                 // Size of DMA buffer

    dmaCfg.count = CY_FX_USBUART_DMA_BUF_COUNT;    // count of DMa buffer

    dmaCfg.prodSckId = CY_FX_EP_PRODUCER1_SOCKET;      // UART socket

    dmaCfg.consSckId = CY_FX_EP_CONSUMER1_SOCKET;     // USB socket

    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

    dmaCfg.notification = 0;

    dmaCfg.cb = NULL;

    dmaCfg.prodHeader = 0;

    dmaCfg.prodFooter = 0;

    dmaCfg.consHeader = 0;

    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUsbtoUart,

            CY_U3P_DMA_TYPE_AUTO, &dmaCfg);

    if (apiRetStatus != CY_U3P_SUCCESS)

    {      

        CyFxAppErrorHandler(apiRetStatus);

    }

Note: The consumer socket can be changed from USB (if not needed) to any other peripheral socket

As this is AUTO DMA channel the data received from UART will directly be committed to USB without any CPU  intervention. The data received by UART will only be committed when the DMA buffer is full (that will depend on dmaCfg.size = size; ). If data needs to be sent directly as soon as it is received  CyU3PDmaChannelSetWrapUp (&glChHandleUarttoUsb); API is called in this example (inside this function USBUARTAppThread_Entry) which commits partially filled DMA buffer to the USB (consumer) socket.

2) Register Mode

In the examples there is a "CyFx3BootUartDmaXferData" and "CyFx3BootUartDmaXferData" function. But in SDK 1.3.3 I can not find those... How can I send messages in DMA mode via UART?

>> These API's are boot API which can be used in the second stage bootloader. For transfers in register mode you can refer to UartLpRegMode example in the SDK (C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\serialif_examples\cyfxuartlpregmode). Where CyU3PUartTransmitBytes and CyU3PUartReceiveBytes are used for UART data transfers through register mode. 

This API CyU3PUartSetTimeout can be used to for timeout setting for the CyU3PUartTransmitBytes and CyU3PUartReceiveBytes operations is based on the number of loop iterations used while waiting for the transfer completion. Each loop iteration will require two times the period of the UART clock. The default timeout is set to 0xFFFFF and can be changed using this API. The API keeps the CPU spinning until the data transfer is completed, or the specified timeout period has elapsed. Therefore, it is not desirable to set a very large timeout for these operations.

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi

View solution in original post

0 Likes
2 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello Mika,

From the description, i understood that UART to USB channel should be created in DMA mode. Is this right?

1) DMA Mode

Please refer to usbuart (SDK installation path\Cypress\EZ-USB FX3 SDK\1.3\firmware\serialif_examples\cyfxusbuart)  example in the SDK 1.3.4 which implements DMA channel between UART (producer) and USB (consumer)

The DMA channel is configured as shown

    /* Create a DMA_AUTO channel between usb producer socket and uart consumer socket */

    dmaCfg.size = size;                                                                 // Size of DMA buffer

    dmaCfg.count = CY_FX_USBUART_DMA_BUF_COUNT;    // count of DMa buffer

    dmaCfg.prodSckId = CY_FX_EP_PRODUCER1_SOCKET;      // UART socket

    dmaCfg.consSckId = CY_FX_EP_CONSUMER1_SOCKET;     // USB socket

    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

    dmaCfg.notification = 0;

    dmaCfg.cb = NULL;

    dmaCfg.prodHeader = 0;

    dmaCfg.prodFooter = 0;

    dmaCfg.consHeader = 0;

    dmaCfg.prodAvailCount = 0;

    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUsbtoUart,

            CY_U3P_DMA_TYPE_AUTO, &dmaCfg);

    if (apiRetStatus != CY_U3P_SUCCESS)

    {      

        CyFxAppErrorHandler(apiRetStatus);

    }

Note: The consumer socket can be changed from USB (if not needed) to any other peripheral socket

As this is AUTO DMA channel the data received from UART will directly be committed to USB without any CPU  intervention. The data received by UART will only be committed when the DMA buffer is full (that will depend on dmaCfg.size = size; ). If data needs to be sent directly as soon as it is received  CyU3PDmaChannelSetWrapUp (&glChHandleUarttoUsb); API is called in this example (inside this function USBUARTAppThread_Entry) which commits partially filled DMA buffer to the USB (consumer) socket.

2) Register Mode

In the examples there is a "CyFx3BootUartDmaXferData" and "CyFx3BootUartDmaXferData" function. But in SDK 1.3.3 I can not find those... How can I send messages in DMA mode via UART?

>> These API's are boot API which can be used in the second stage bootloader. For transfers in register mode you can refer to UartLpRegMode example in the SDK (C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\serialif_examples\cyfxuartlpregmode). Where CyU3PUartTransmitBytes and CyU3PUartReceiveBytes are used for UART data transfers through register mode. 

This API CyU3PUartSetTimeout can be used to for timeout setting for the CyU3PUartTransmitBytes and CyU3PUartReceiveBytes operations is based on the number of loop iterations used while waiting for the transfer completion. Each loop iteration will require two times the period of the UART clock. The default timeout is set to 0xFFFFF and can be changed using this API. The API keeps the CPU spinning until the data transfer is completed, or the specified timeout period has elapsed. Therefore, it is not desirable to set a very large timeout for these operations.

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi
0 Likes

Hi Mika,

Adding to my previous response

Is it possible during operation to change into Reg mode before using the TransmitBytes function and after that change back to DMA mode waiting for a response?

>> After the transfer/operation gets completed you can change the uart configuration by calling.

    CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof(uartConfig));

    uartConfig.baudRate = CY_U3P_UART_BAUDRATE_115200;

    uartConfig.stopBit = CY_U3P_UART_ONE_STOP_BIT;

    uartConfig.parity = CY_U3P_UART_NO_PARITY;

    uartConfig.flowCtrl = CyFalse;

    uartConfig.txEnable = CyTrue;

    uartConfig.rxEnable = CyTrue;

   uartConfig.isDma = CyTrue; /* DMA mode */

    /* Set the UART configuration */

    apiRetStatus = CyU3PUartSetConfig (&uartConfig, CyFxUartLpApplnCallback);

    if (apiRetStatus != CY_U3P_SUCCESS )

    {

        /* Error handling */

        CyFxAppErrorHandler(apiRetStatus);

    }

Uart can be configured in DMA mode after reg mode by settings the art configured as mentioned above.

Note: This can be done after the data transfer is completed i.e. either by DMA mode or register mode otherwise there would be data loss if switching is done before data transfer completes

It would only be necessary for an ACK or something like this.

>> Can you please restate this to understand your question better.

Regards,

Rashi

Regards,
Rashi
0 Likes