Author Topic: CDC Data Interface Class  (Read 20333 times)

Nik

  • Member
  • ***
  • Posts: 40
CDC Data Interface Class
« on: March 13, 2014, 10:30:21 am »
Hello all,

As I had posted earlier too, I am trying to implement a USB CDC peripheral using MAX3421 and a FPGA.

My requirement is simple - Sending and receiving raw data from the virtual com port.

Now my question is : In the CDC config descriptor, can I have only one interface and two descriptors (bulk IN and OUT) ?

To elaborate more, can I have my config descriptor as below :

   //Configuration Descriptor
    0x09,         // bLength
    0x02,         // bDescriptorType = Config
    0x20,0x00,  // wTotalLength(L/H)
    0x01,         // bNumInterfaces
    0x01,         // bConfigValue
    0x00,         // iConfiguration
    0xC0,         // bmAttributes. b7=1 b6=Bus-powered b5=RWU supported
    0x32,         // Max current

    // INTERFACE Descriptor
    0x09,         // length = 9
    0x04,         // type = IF
    0x00,         // IF #0
    0x00,         // bAlternate Setting
    0x02,         // bNum Endpoints
    0x02,         // bInterfaceClass = CDC
    0x00,         // bInterfaceSubClass,
    0x00,         // bInterfaceProtocol
    0x00,         // iInterface

   //Endpoint descriptor BULK OUT
    0x07,     // Size of descriptor
    0x05,     // Type of descriptor
    0x01,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x02,     // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
    0x40,     // LSB Packet size
    0x00,     // MSB Packet size
    0x00,     // Polling interval 0 ms

    //Endpoint descriptor BULK IN
    0x07,   // Size of descriptor
    0x05,   // Type of descriptor
    0x82,   // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x02,   // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
    0x40,   // LSB Packet size
    0x00,   // MSB Packet size
    0x00    // Polling interval 0 ms



One more issue is - if I specify  bInterfaceClass = 0x0A for Data Interface Class, I get Error 10 on windows.

And if I continue with bInterfaceClass = 0x02 for CDC like above, I do not receive any data (Data IN) on the VCOM port. However, I am able to send the data from VCOM (Data OUT).

What am I missing ?

Grateful for your time.

- Nik

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: CDC Data Interface Class
« Reply #1 on: March 13, 2014, 12:15:13 pm »
You need two interfaces, CDC and data.

For a virtual serial port, the CDC interface has these descriptors:

header functional
abstract control model
union functional
call management functional
endpoint (interrupt IN)

The data interface has the two data endpoints


 

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #2 on: March 13, 2014, 03:20:33 pm »
Thanks for the reply Jan.

I had tried that earlier with the same result.

However, using an analyzer, I found out that the VCOM port receives exactly 3kB of data and then it stops sending IN token packets.

Second thing, in the Data Interface Descriptor, on writing 0x0A for // Class: CDC host throws error 10.


Regards,
Nik

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: CDC Data Interface Class
« Reply #3 on: March 13, 2014, 03:40:16 pm »
Be sure bNumInterfaces in the configuration descriptor = 2.

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #4 on: March 13, 2014, 05:30:20 pm »
Jan,

With the descriptor below it is failing enumeration.

//Configuration Descriptor

    0x09,         // bLength
    0x02,         // bDescriptorType = Config
    0x43,0x00,    // wTotalLength(L/H) = 67 bytes
    0x02,         // bNumInterfaces
    0x01,         // bConfigValue
    0x00,         // iConfiguration
    0xC0,         // bmAttributes. b7=1 b6=Bus-powered b5=RWU supported
    0x32,         // MaxPower

    // INTERFACE Descriptor
    0x09,         // length = 9
    0x04,         // type = IF
    0x00,         // IF #0
    0x00,         // bAlternate Setting
    0x01,         // bNum Endpoints
    0x02,         // bInterfaceClass = CDC
    0x02,         // bInterfaceSubClass,
    0x00,         // bInterfaceProtocol
    0x00,         // iInterface

    // CDC class specific Descriptor
    0x05,         // bLength
    0x24,         // bDescriptorType
    0x00,         // CDC Header function descriptor
    0x10, 0x01,   // Rev 1.1

    0x05,         // bLength
    0x24,         // bDescriptorType
    0x01,         //Call Management function descriptor
    0x01,
    0x01,

    0x04,         // bLength
    0x24,         // bDescriptorType
    0x02,         // Abstract control function descriptor
    0x06,

    0x05,         // bLength
    0x24,         // bDescriptorType
    0x06,         // Union function descriptor
    0x00,
    0x01,


    //Endpoint Descriptor - INTERRUPT
    0x07,     // Size of descriptor
    0x05,     // Type of descriptor
    0x83,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x03,     // bmAtributts Bit- 0-1 indicate transfer type 11-interrupt
    0x0A,     // LSB Packet size
    0x00,     // MSB Packet size
    0x0A,     // Polling interval 10 ms


    // INTERFACE Descriptor
    0x09,         // length = 9
    0x04,         // type = IF
    0x01,         // IF #1
    0x00,         // bAlternate Setting
    0x02,         // bNum Endpoints
    0x0A,         // bInterfaceClass = DIC
    0x00,         // bInterfaceSubClass,
    0x00,         // bInterfaceProtocol
    0x00,         // iInterface

   //Endpoint descriptor BULK OUT
    0x07,     // Size of descriptor
    0x05,     // Type of descriptor
    0x01,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x02,     // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
    0x40,     // LSB Packet size
    0x00,     // MSB Packet size
    0x00,     // Polling interval 0 ms

    //Endpoint descriptor BULK IN
    0x07,   // Size of descriptor
    0x05,   // Type of descriptor
    0x82,   // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x02,   // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
    0x40,   // LSB Packet size
    0x00,   // MSB Packet size
    0x00    // Polling interval 0 ms
 

What can be possibly wrong ?

Thank you again.
« Last Edit: March 13, 2014, 05:33:50 pm by Nik »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: CDC Data Interface Class
« Reply #5 on: March 13, 2014, 09:00:25 pm »
Try these changes:

Jan,

With the descriptor below it is failing enumeration.

//Configuration Descriptor

    0x09,         // bLength
    0x02,         // bDescriptorType = Config
    0x43,0x00,    // wTotalLength(L/H) = 67 bytes
    0x02,         // bNumInterfaces
    0x01,         // bConfigValue
    0x00,         // iConfiguration
    0xC0,         // bmAttributes. b7=1 b6=Bus-powered b5=RWU supported
    0x32,         // MaxPower

    // INTERFACE Descriptor
    0x09,         // length = 9
    0x04,         // type = IF
    0x00,         // IF #0
    0x00,         // bAlternate Setting
    0x01,         // bNum Endpoints
    0x02,         // bInterfaceClass = CDC
    0x02,         // bInterfaceSubClass,
    0x00,         // bInterfaceProtocol
    0x00,         // iInterface

    // CDC class specific Descriptor
    0x05,         // bLength
    0x24,         // bDescriptorType
    0x00,         // CDC Header function descriptor
    0x10, 0x01,   // Rev 1.1

    0x05,         // bLength
    0x24,         // bDescriptorType
    0x01,         //Call Management function descriptor
    0x00,
    0x01,

    0x04,         // bLength
    0x24,         // bDescriptorType
    0x02,         // Abstract control function descriptor
   0x02,

    0x05,         // bLength
    0x24,         // bDescriptorType
    0x06,         // Union function descriptor
    0x00,
    0x01,


    //Endpoint Descriptor - INTERRUPT
    0x07,     // Size of descriptor
    0x05,     // Type of descriptor
    0x83,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x03,     // bmAtributts Bit- 0-1 indicate transfer type 11-interrupt
    0x0A,     // LSB Packet size
    0x00,     // MSB Packet size
    0x0A,     // Polling interval 10 ms


    // INTERFACE Descriptor
    0x09,         // length = 9
    0x04,         // type = IF
    0x01,         // IF #1
    0x00,         // bAlternate Setting
    0x02,         // bNum Endpoints
    0x0A,         // bInterfaceClass = DIC
    0x00,         // bInterfaceSubClass,
    0x00,         // bInterfaceProtocol
    0x00,         // iInterface

   //Endpoint descriptor BULK OUT
    0x07,     // Size of descriptor
    0x05,     // Type of descriptor
    0x01,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x02,     // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
    0x40,     // LSB Packet size
    0x00,     // MSB Packet size
    0x00,     // Polling interval 0 ms

    //Endpoint descriptor BULK IN
    0x07,   // Size of descriptor
    0x05,   // Type of descriptor
    0x82,   // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
    0x02,   // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
    0x40,   // LSB Packet size
    0x00,   // MSB Packet size
    0x00    // Polling interval 0 ms
 

What can be possibly wrong ?

Thank you again.

Also be sure bDeviceClass in the device descriptor = 2.

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #6 on: March 14, 2014, 01:32:28 pm »
:(

Still the same !

Barry Twycross

  • Frequent Contributor
  • ****
  • Posts: 263
Re: CDC Data Interface Class
« Reply #7 on: March 14, 2014, 03:54:15 pm »
Our CDC device does enumerate, there was some trickiness with inf getting Windows to recognize it. I compared your descriptors to our, and the differences are below.

The only one I'd expect to make a difference are the interface protocol, or maybe the capabilities. We accept some commands only to ignore them.

In the interface descriptor
    0x00,         // bInterfaceProtocol
    0x00,         // iInterface

We have protocol set to 1, which is AT commands protocol (i.e. modem). We also have an interface string, but I wouldn't expect that to make a difference.

For the class specific interface descriptor it is
   0x04,         // bLength
    0x24,         // bDescriptorType
    0x02,         // Abstract control function descriptor
   0x02,

We have zero for the last byte, seems to be bmCapabilities, not exactly sure what capabilities I'm not declaring

For the interrupt pipe we use 32 bytes and a polling interval of 2.

We have a string for the interface (again, I wouldn't expect that to make a difference).

We declare the bulk pipes in the other order, and again they're 32 bytes.

Barry Twycross

  • Frequent Contributor
  • ****
  • Posts: 263
Re: CDC Data Interface Class
« Reply #8 on: March 14, 2014, 03:55:24 pm »
I'll also say that Windows wasn't happy until I did accept the set_line_coding etc commands. I just make a note of what I'm told, send them back if asked, but otherwise ignore them.

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #9 on: March 14, 2014, 05:56:35 pm »
Thanks for the response Barry !

I have now a strange situation.

Here are my descriptors :

const unsigned char DD[]= // DEVICE Descriptor
{
       0x12,            // bLength = 18d
       0x01,            // bDescriptorType = Device (1)
       0x00,0x02,     // bcdUSB(L/H) USB spec rev (BCD)
       0x02,            // bDeviceClass,
       0x00,            // bDeviceSubClass,
       0x00,            // bDeviceProtocol
        0x40,            // bMaxPacketSize0 EP0 is 64 bytes
       0xD8, 0x04,    // idVendor(L/H)
       0x0A, 0x00,    // idProduct(L/H)
       0x02,0x00,     // bcdDevice
       0x01,            // iManufacturer
       0x02,            // iProduct,
       0x00,            // iSerialNumber
       0x01             // bNumConfigurations
};


const unsigned char CD[]= // CONFIGURATION Descriptor
{

       //Configuration Descriptor

        0x09,         // bLength
        0x02,         // bDescriptorType = Config
        0x3C,0x00,    // wTotalLength(L/H) = 60 bytes
        0x02,         // bNumInterfaces
        0x01,         // bConfigValue
        0x00,         // iConfiguration
        0xC0,         // bmAttributes. b7=1 b6=Bus-powered b5=RWU supported
        0x32,         // MaxPower is 2 ma

        // INTERFACE Descriptor
        0x09,         // length = 9
        0x04,         // type = IF
        0x00,         // IF #0
        0x00,         // bAlternate Setting
        0x01,         // bNum Endpoints
        0x02,         // bInterfaceClass = CDC
        0x02,         // bInterfaceSubClass,
        0x01,         // bInterfaceProtocol
        0x00,         // iInterface

        // CDC class specific Descriptor
        0x05,         // bLength
        0x24,         // bDescriptorType
        0x00,         // CDC Header function descriptor
        0x10, 0x01,   // Rev 1.1

        0x05,         // bLength
        0x24,         // bDescriptorType
        0x01,         // Call Management function descriptor
        0x01,
        0x01,

        0x04,         // bLength
        0x24,         // bDescriptorType
        0x02,         // Abstract control function descriptor
        0x00,

        0x05,         // bLength
        0x24,         // bDescriptorType
        0x06,         // Union function descriptor
        0x00,
        0x01,



        //Endpoint Descriptor - INTERRUPT
        0x07,     // Size of descriptor
        0x05,     // Type of descriptor
        0x83,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
        0x03,     // bmAtributts Bit- 0-1 indicate transfer type 11-interrupt
        0x0A,     // LSB Packet size
        0x00,     // MSB Packet size
        0x01,     // Polling interval 10 ms

        // INTERFACE Descriptor
        0x09,         // length = 9
        0x04,         // type = IF
        0x01,         // IF #1
        0x00,         // bAlternate Setting
        0x02,         // bNum Endpoints
        0x0A,         // bInterfaceClass = CDC
        0x00,         //bInterfaceSubClass,
        0x00,         //  bInterfaceProtocol
        0x00,         // iInterface

        //Endpoint descriptor BULK OUT
        0x07,     // Size of descriptor
        0x05,     // Type of descriptor
        0x01,     // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
        0x02,     // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
        0x40,     // LSB Packet size
        0x00,     // MSB Packet size
        0x00,     // Polling interval 0 ms

        //Endpoint descriptor BULK IN
        0x07,   // Size of descriptor
        0x05,   // Type of descriptor
        0x82,   // Address of descriptor Bit- 7 1-IN/0-OUT  Bit-0-3 endpoint no.
        0x02,   // bmAtributts Bit- 0-1 indicate transfer type 10-bulk
        0x40,   // LSB Packet size
        0x00,   // MSB Packet size
        0x00    // Polling interval 0 ms



};


So, the maximum EP0 size is 64 bytes and my config descriptor is of 67 bytes.

For the descriptors above, 60 bytes is the best that is working for me. The device is enumerated properly and works with VCOM port - however, without and BULK IN endpoint.

Hence, I can send the data on BULK OUT but cannot receive on BULK IN.

I tried increasing the size in Device Descriptor as 67, but as MAX3421 has the endpoint size of 64-bytes, enumeration failed.

Any other workaround ???

Thanks for your precious time !

- Nik

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #10 on: March 14, 2014, 07:34:44 pm »
Now that I am sending 67 bytes as 64 bytes and then 3 bytes,

Windows XP says : Unknown device

Windows 7 says : This device cannot start. (Code 10).

Any clue ?

Thanks.
Nik


Barry Twycross

  • Frequent Contributor
  • ****
  • Posts: 263
Re: CDC Data Interface Class
« Reply #11 on: March 15, 2014, 05:49:25 pm »
That was one of my other thoughts I forgot to mention. With a 67 byte descriptor set, the data for the SETUP transaction is split over two packets. If your SETUP handling doesn't cope with this, you won't get enumerated correctly. It took me a bit of effort to sort out that for our device.

Make the descriptors 67 bytes again and then check that its being transferred correctly. This is where a hardware analyser is essential. If it isn't transferred correctly, you need to fix that before doing anything else.

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #12 on: March 17, 2014, 10:17:24 am »
Hi Barry,

Thanks for your time.

This is what the hardware analyzer is showing :
  Host sends    : Get config descriptor request
  Device sends : ACK
  Host sends    : IN Token
  Device sends : 64 bytes config data
  Host sends    : ACK
  Host sends    : IN Token
  Device sends : 3 bytes config data
  Host sends    : ACK
  Host sends    : OUT Token
  Host sends    : 0 byte data
  Device sends : ACK

Is there any issue here.

Thank you again.

Regards,
Nik

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: CDC Data Interface Class
« Reply #13 on: March 17, 2014, 10:28:18 am »
The setupapilog file might have a clue:

http://support.microsoft.com/kb/927521

Nik

  • Member
  • ***
  • Posts: 40
Re: CDC Data Interface Class
« Reply #14 on: March 17, 2014, 01:33:35 pm »
Thanks Jan, but I could not find anything. :(

One very fundamental question to the CDC.

To get my device enumerated, do I need to implement responses to these too? :

  SEND_ENCAPSULATED_COMMAND
  GET_LINE_CODING
  SET_LINE_CODING
  SET_CONTROL_LINE_STATE
  SEND_BREAK
  etc.

I thought only the Device Descriptor and Config Descriptor were enough.

Regards,
Nik