Full duplex mode with USB CDC-ACM

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

Full duplex mode with USB CDC-ACM

Jump to solution
2,583 Views
brycelembke
Contributor III


I have a TWR-K65F180M as a full speed cdc host (using USB0 - KHCI) and a custom board (using USB1 - EHCI) as a high speed CDC device. My custom board enumerates fine with Windows and sends serial traffic just fine as well (high speed mode). When I plug it into my TWR-K65F180M, I can see on my analyzer that it negotiates to full speed and enumerates correctly (all the control descriptors seem to be exchanged just fine), but none of my IN packets are getting sent to the host, though I do see the periodic SOF packets.

 

Comparing the trace of descriptors, the only differences are related to full speed vs high speed (frame sizes, etc).

 

I am using the SDK_2.0 usb_cdc_host example code (with KHCI). If I switch to use the usb_host_hid_mouse example and plug in a mouse, it works great, so I think that electrically, everything is good.

 

Aside from setting the KHCI flag on the host (and EHCI flag on the device), is there something else I need for this to work?

Labels (1)
Tags (1)
1 Solution
1,669 Views
isaacavila
NXP Employee
NXP Employee

Hello,

USB Host CDC example is compliant with USB Device CDC example, so, Host would send an OUT packet to device, who is implementing a loopback, then Host would look for IN packages, that is why, you are not seeing these IN package unless you sent data to Device.

I hope this can help you!

Regards,

Isaac

View solution in original post

9 Replies
1,670 Views
isaacavila
NXP Employee
NXP Employee

Hello,

USB Host CDC example is compliant with USB Device CDC example, so, Host would send an OUT packet to device, who is implementing a loopback, then Host would look for IN packages, that is why, you are not seeing these IN package unless you sent data to Device.

I hope this can help you!

Regards,

Isaac

1,669 Views
brycelembke
Contributor III

That is true and if I use those examples, it works as expected for loopback, but I should be able to modify that so that I can just send IN packets (as shown in this post KSDK VCOM example does not work without loopback​ ).

I have made the modifications, and can still not get IN packets to go out on their own. As I stated, if I use a Windows host, I can get only IN packets to send. What would be the difference between the Windows host and the TWR host. Does the TWR host also require loopback to work properly?

0 Kudos
1,669 Views
brycelembke
Contributor III

To be specific, I commented out this line in USB_DeviceCdcAcmBulkIn:

USB_DeviceRecvRequest(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);

----------------------

usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message,

                                    void *callbackParam)

{

    usb_status_t error = kStatus_USB_Error;

    if ((message->length != 0) && (!(message->length % s_usbBulkMaxPacketSize)))

    {

        USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);

    }

    else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))

    {

        if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0)))

        {

            USB_DeviceRecvRequest(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);

        }

    }

    else

    {

    }

    return error;

}

to

----------------------------

usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message,

                                    void *callbackParam)

{

    usb_status_t error = kStatus_USB_Error;

    if ((message->length != 0) && (!(message->length % s_usbBulkMaxPacketSize)))

    {

        USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);

    }

    else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))

    {

        if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0)))

        {

            //TODO USB_DeviceRecvRequest(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);

        }

    }

    else

    {

    }

    return error;

}

Per the hyperlink, now I know that I am not getting too many USB_DeviceRecvRequest's , I don't understand why my device can't send as much as I want. (sending code below)

static uint32_t count;

.... [some code]

        ++count;

        if( (count & 0xfffff) == 0)

        {

            s_sendSize = 8;

            memcpy(s_currSendBuf, "ABCDEF\n", s_sendSize);

        }

        if (s_sendSize)

        {

            uint32_t size = s_sendSize;

            s_sendSize = 0;

            error = USB_DeviceSendRequest(s_cdcVcom.deviceHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size);

            ....

0 Kudos
1,669 Views
brycelembke
Contributor III

Or perhaps this is related to RTS and CTS causing me to only be able to run half duplex instead of full duplex like I want.

0 Kudos
1,670 Views
isaacavila
NXP Employee
NXP Employee

Hi Bryce,

Yes, it could be related to RTS and CTS implementation. I've not checked this example further but I suppose you would need to change the logic in order to implement a Full-Duplex functionality.

Regards,

Isaac

0 Kudos
1,670 Views
brycelembke
Contributor III

Since I am using both host and device CDC examples together, I needed to change BOTH the host and device side code to not require loopback. I have modified it so that send and receive are independent in both host and device side code. Now I have full duplex.

1,670 Views
isaacavila
NXP Employee
NXP Employee

Hello Bryce,

How are you configuring jumpers on TWR-K65F180M? I've tested same enviroment but using TWR-K65F180M and FRDM-K64F boards (I do not have two TWR-K65F180M boards) as follows:

  • FRDM-K64F board is configured as host (host_cdc_bm_frdmk64f project). It only supports FS. Hardware control macro is set:

/*! @brief whether device support hardware flow control */

#define USB_HOST_UART_SUPPORT_HW_FLOW 1U

  • TWR-K65F180M board is used as device (dev_cdc_vcom_bm_twrk65f180m project). In usb_device_config.h, EHCI instance count is set to 1 and KHCI is cleared:

/*! @brief KHCI instance count */

#define USB_DEVICE_CONFIG_KHCI (0U)

/*! @brief EHCI instance count */

#define USB_DEVICE_CONFIG_EHCI (1U)

First of all, I tested TWR-K65F180M board on PC and it is enumerated as HS device:

TWR-K65F180M CDC HS Device.jpg

Then, I connected this same device to FRDM-K64F which only supports FS and it was working well:

FRDM-K64F Host and TWR-K65F180M Device.jpg

Have you tried by using another FS Host?

Regards,

Isaac

0 Kudos
1,670 Views
brycelembke
Contributor III

Thanks, I have those macros set:

Host:

(from usb_host_config.h)

#define USB_HOST_CONFIG_KHCI (1U)

#define USB_HOST_CONFIG_EHCI (0U)

(from usb_host.h)

#define USB_HOST_UART_SUPPORT_HW_FLOW 1U

Device:

(from usb_host_config.h)

#define USB_DEVICE_CONFIG_KHCI (0U)

#define USB_DEVICE_CONFIG_EHCI (1U)

I have switched the resistors R189 and R190 so that USB0 full speed goes to the Micro USB port.

Jumpers:

J16: 1-2 (also tried 2-3)

J36: 2-3

J13: 1-2

J14: 1-2

My trace to the PC looks a lot like yours (attached both). The strange thing is that it enumerates fine in both cases. It is just the IN packets that I don't see. I will try sending OUT packets too to see what happens.

CustomToPC_HS.pngCustomToTwrK65_FS.png

0 Kudos
1,670 Views
brycelembke
Contributor III

I started sending OUT packets and THEN I started to get IN packets (but only each time I send an OUT - see attached image). I would think the IN packets should come in regardless of whether there is OUT traffic (it does in my Windows USB host trace).

CustomToTwrK65_FS_WorksIfSendOUTs.png

0 Kudos