USB CDC VCOM - Consecutive RXs Fail

cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC VCOM - Consecutive RXs Fail

444 Views
Senior Contributor I

Using the MCUXpresso SDK 2.7.0 dev_cdc_vcomm_freertos demo as a starting point, if i remove the "echo" functionality - so that i'm just receiving data, receive gets stuck/ stops receiving data after 1 packet.

If I leave the echo in there, everything works fine.

Is there something in the USB CDC Vcomm stack that is resetting the receive functionality via the USB_DeviceCdcAcmSend function?

I just realized I asked the same question for RT1020 but never received an answer - so asking again for the RT1052:

Labels (2)
8 Replies

139 Views
NXP TechSupport
NXP TechSupport

Hi Variable_andrew:

 

I am trying to reproduce your issue on my side, I will let you know my result later.

 

Regards

Daniel

0 Kudos

139 Views
Senior Contributor I

Hi danielchen@fsl‌,

Thanks for the quick response - I'll continue in this thread since I'm now 100% on the RT1052 (no longer using the RT1021).

So in order to reproduce:

MCUXpresso 11.1.1, SDK2.7.0 -> SDK Example "dev_cdc_vcomm_freertos" -> Link using Internal SRAM only and DebugPrint goes to SemiHost

Then on my board - we're using USB OTG2, so I have to go to virtual_com.h and update the controller to:

#define CONTROLLER_ID kUSB_ControllerEhci1

If you're on the EVK, can skip that step.

After this, I run, and the demo works, echo's just fine.

Now to duplicate my issue, we simply have to try and echo only every third or 4th RX.

Just add a static int RX counter, still reset the TX buff every RX, but only try to send on every 3rd or 4th packet, and it'll fail as soon as you get multiple RX's without doing a TX.

Here's the modified AppTask for you to test:

void APPTask(void *handle)
{
    usb_status_t error = kStatus_USB_Error;
    static int numRxs = 0;

    USB_DeviceApplicationInit();

    while (1)
    {
        if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
        {
            /* User Code */
            if ((0 != s_recvSize) && (0xFFFFFFFF != s_recvSize))
            {
                int32_t i;
                numRxs++;

                /* Copy Buffer to Send Buff */
                for (i = 0; i < s_recvSize; i++)
                {
                    s_currSendBuf[s_sendSize++] = s_currRecvBuf[i];
                }
                s_recvSize = 0;
            }

            if (s_sendSize)
            {
              uint32_t size = s_sendSize;
              s_sendSize = 0;
              if ((numRxs % 4) == 1){
                error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size);
                if (error != kStatus_USB_Success)
                {
                    /* Failure to send Data Handling code here */
                }
              }
            }
        }
    }
}
0 Kudos

139 Views
NXP TechSupport
NXP TechSupport

Hi variable_andrew:

Please see my modified code, it can work on my side.


    while (1)
    {
        if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
        {
            /* User Code */
            if ((0 != s_recvSize) && (0xFFFFFFFF != s_recvSize))
            {
                int32_t i;

                memset(s_currSendBuf, 0, sizeof(s_currSendBuf));

                /* Copy Buffer to Send Buff */
                for (i = 0; i < s_recvSize; i++)
                {
                    s_currSendBuf[s_sendSize++] = s_currRecvBuf[i];
                    numRxs++;
                }

                s_recvSize = 0;
            }

            if (s_sendSize)
            {
                uint32_t size = s_sendSize ;
                s_sendSize = 0;

                if ((numRxs %4) == 1 )

                {
                 size = numRxs--;
                }

                error =
                    USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size);
                if (error != kStatus_USB_Success)
                {
                    /* Failure to send Data Handling code here */
                }


            }

Regards

Daniel

0 Kudos

139 Views
Senior Contributor I

Hi danielchen@fsl‌,

You have changed the code from counting the # of RX messages to the # of RX bytes - so this doesn't answer my question, which is:

Why does the USB SDK freeze if I don't send a message (w/ USB_DeviceCDCACMSend)  every time I have an incoming message (not byte)?

This shouldn't be required in USB - ie, a standard use case might be to send a text file over USB to the RT1052, this might be split into 100 packets. If using RTS/CTS, I shouldn't need to provide any responses at the app layer for packets 0-99 to receive all the data, and USB shouldn't freeze either.

In the code you've provided specifically avoids what I'm trying to fix instead of making RX work without  USB_DeviceCDCACMSend.

Here is the most basic test case:

void APPTask(void *handle)
{
    usb_status_t error = kStatus_USB_Error;
    static int numRxs = 0;

    USB_DeviceApplicationInit();
    while (1)
    {
        if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
        {
            /* User Code */
            if ((0 != s_recvSize) && (0xFFFFFFFF != s_recvSize))
            {
                numRxs++;

                //don't do anytihng w/ the RX data, just reset:

                memset(s_currSendBuf, 0, sizeof(s_currSendBuf));
                s_recvSize = 0;
            }
        }
    }
}

If you run this, and then connect over a terminal application to the RT1052, you can send lines of test to the RT1052 (like "Test1", "Test2", etc).

You'll notice that after sending 5 or 10 messages over USB, if you pause the application, numRxs will be stuck at 1 instead of 5 or 10 (because the RT1052 USB only received 1 message before freezing up).

Could you please take another look and see if you can understand why we can't just receive data (without echoing back data on a per-packet basis)?

0 Kudos

132 Views
Senior Contributor II

Hi,

I'm having a similar problem on the '1062.

Was this resolved?

Ed 

0 Kudos

139 Views
NXP TechSupport
NXP TechSupport

Hi

After trying many times. I know that the demo's default behavior is:

Send back the data that is received from host, then start to receive the next data from host. If host doesn't receive the data from the device, the device will not receive next data.

In your case, I would suggest you receive your message in  USB_DeviceCdcVcomCallback.  (virtual_com.c)

case  kUSB_DeviceCdcEventRecvResponse

For example:

        case kUSB_DeviceCdcEventRecvResponse:
        {
            if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
            {
                s_recvSize = epCbParam->length;

.....

and do nothing in APPTask.

Regards

Daniel

139 Views
NXP TechSupport
NXP TechSupport

Yes, I observed the application will freeze if I don't send a message. Let me try it again for this case.

0 Kudos

139 Views
NXP TechSupport
NXP TechSupport

Yes, with your code, I can reproduce your issue.

I think you can check the s_currSendBuf and the length.

I will update you when I have result.

Regards

Daniel

0 Kudos