USB CDC VCOM - Consecutive RXs Fail

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB CDC VCOM - Consecutive RXs Fail

2,898 Views
variable_andrew
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)
11 Replies

2,593 Views
danielchen
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

2,593 Views
variable_andrew
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

2,593 Views
danielchen
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

2,593 Views
variable_andrew
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

2,420 Views
bill_muzika
Contributor I

I had the same problem with SDK 2.8 on the LPC55S69. I found that adding a call to USB_DeviceCdcAcmRecv after receiving a packet allows for the next to be received. This is done in the example when a send is complete. I'm not sure if it was the most correct way to handle it, but it explains why the receives would not work unless a send was completed in between.

else if ((1 == g_deviceComposite->cdcVcom.attach) && (1 == g_deviceComposite->cdcVcom.startTransactions))
{
if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0)))
{
/* User: add your own code for send complete event */
/* Schedule buffer for next receive event */
USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_DIC_BULK_OUT_ENDPOINT, s_currRecvBuf,
g_cdcVcomDicEndpoints[0].maxPacketSize);
}
}

 

2,390 Views
EdSutter
Senior Contributor II

Seems there are a few different unofficial ways to fix this issue (see here).

All of the solutions I've seen (or wrote myself) seem like hacks that should not have to be there.

@nxp Support: IMHO, this should be fixed in the stack.

2,586 Views
EdSutter
Senior Contributor II

Hi,

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

Was this resolved?

Ed 

0 Kudos

2,593 Views
danielchen
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

2,593 Views
danielchen
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

2,593 Views
danielchen
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

1,761 Views
ChrisN
Contributor II

Hello Daniel,

It is over 18 months later, and the examples have not changed and still exhibit the error. Are you still on it?

Cheers,

Chris

0 Kudos