New custom IN/OUT Interrupt Endpoint (USB Audio Reference Design) - IN Endpoint Error? Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
GlennW
New User
Posts: 2
Joined: Tue May 15, 2018 8:54 pm

New custom IN/OUT Interrupt Endpoint (USB Audio Reference Design) - IN Endpoint Error?

Post by GlennW »

Hi All,

I've added a new IN/OUT Interrupt endpoint to the USB Audio Reference design (to send data from the USB host to the I2C port) and am having some issues with it communicating with WinUSB. My driver is from Thesycon (4 in, 8 out) with my custom descriptors added (see below).
My design appears to correctly enumerate and I have audio and can receive data from the host on my OUT endpoint (using a case XUD_GetData_Select(chan, ep, length, res): entry in usb_buffer.xc ).
But, when I try to send data back to the host on my IN endpoint (using XUD_SetReady_In(ep, buff, length)) the endpoint appears to send the packet 3 times and then cause an abort.

My program structure is to receive a couple of bytes from the OUT endpoint, either set/get GPIO pins with the data or send the out of the device via I2C write, then I2C read to verify the data written, and send this back to the host via the IN endpoint.
The design isn't complete, I'm just at the point of testing USB comms before adding the full I2C/GPIO contol

From usb_buffer.xc

Code: Select all

            case XUD_GetData_Select(c_vortex_gpio_out, ep_vortex_gpio_out, length, result ) :  //Wait for OUT Endpoint Packet
               switch(vortex_gpio_from_host_buffer[0])   //Get byte 0 of packet as message ID
                {
                case SET_MONITOR_LEVEL_COMMAND:
                    ds1882_interface.LevelReq(vortex_gpio_from_host_buffer);
                    break;
                case SET_CC_SINGLE_STATE_COMMAND:
                    vortex_gpio_to_host_buffer[SET_CC_SINGLE_STATE_COMMAND];
                    break;
                case GET_CC_STATE_COMMAND:
                    vortex_gpio_to_host_buffer[0] = SET_CC_MULTIPLE_STATE_COMMAND;      // Set byte 0 of the data to be sent to the host to SET_CC_MULTIPLE_STATE_COMMAND as the message ID
                    XUD_SetReady_In ( ep_vortex_gpio_in , vortex_gpio_to_host_buffer , 5) ; // Tell XUD we have a packet to go out on the IN endpoint
                    break;
                default:
                    break;
                }
            XUD_SetReady_Out(ep_vortex_gpio_out, vortex_gpio_from_host_buffer);
            break;
The case i'm dealing with is when I receive a GET_CC_STATE_COMMAND from the OUT endpoint. This is supposed to just send 5 bytes of data back to the host when the command is received.

Here are my descriptors (descriptor.h)

Code: Select all

.My_I2C_Interface =
{
    .bLength                       = sizeof(USB_Descriptor_Interface_t),
    .bDescriptorType               = USB_DESCTYPE_INTERFACE,
    .bInterfaceNumber              = INTERFACE_NUMBER_MY_I2C,
    .bAlternateSetting             = 0x00,
    .bNumEndpoints                 = 0x02,
    .bInterfaceClass               = 0xFF,
    .bInterfaceSubClass            = 0xFF,
    .bInterfaceProtocol            = 0xFF,
    .iInterface                    = offsetof(StringDescTable_t, capRecAudBdCtrlStr)/sizeof(char *),   /* Note, string is important! */
},

.My_I2C_In_Endpoint =
{
    /* Endpoint descriptor (IN) */
    0x7,                              /* 0  bLength */
    5,                                /* 1  bDescriptorType */
    ENDPOINT_ADDRESS_IN_MY_I2C,  /* 2  bEndpointAddress  */
    3,                                /* 3  bmAttributes (INTERRUPT) */
    64,                               /* 4  wMaxPacketSize */
    4,                                /* 6  bInterval */
},

.My_I2C_Out_Endpoint =
{
    /* Endpoint descriptor (IN) */
    0x7,                              /* 0  bLength */
    5,                                /* 1  bDescriptorType */
    ENDPOINT_ADDRESS_OUT_MY_I2C, /* 2  bEndpointAddress  */
    3,                                /* 3  bmAttributes (INTERRUPT) */
    64,                               /* 4  wMaxPacketSize */
    4,                                /* 6  bInterval */
}
#endif
Here is the USB analyser data:

003526: Bulk or Interrupt Transfer (DOWN), 2018-05-15 21:17:31.7723472 +0.0030716 (1. Device: My Audio Board)
Pipe Handle: 0xf45420e0 (Endpoint Address: 0x2)
Send 0x1 bytes to the device


003527: Bulk or Interrupt Transfer (UP), 2018-05-15 21:17:31.7730165 +0.0006693. (1. Device: My Audio Board) Status: 0x00000000
Pipe Handle: 0xf68671f0 (Endpoint Address: 0x82)
Get 0x5 bytes from the device


003529: Bulk or Interrupt Transfer (UP), 2018-05-15 21:17:31.7739575 +0.0008782. (1. Device: My Audio Board) Status: 0x00000000
Pipe Handle: 0xf68671f0 (Endpoint Address: 0x82)
Get 0x5 bytes from the device


003532: Bulk or Interrupt Transfer (UP), 2018-05-15 21:17:31.7749661 +0.0000111. (1. Device: My Audio Board) Status: 0x00000000
Pipe Handle: 0xf68671f0 (Endpoint Address: 0x82)
Get 0x5 bytes from the device


003534: Bulk or Interrupt Transfer (UP), 2018-05-15 21:17:33.4796792 +1.7046910. (1. Device: My Audio Board) Status: 0xc0010000
Pipe Handle: 0xf68671f0 (Endpoint Address: 0x82)
Get 0x0 bytes from the device


As you can see, the OUT endpoint from the host triggers IN endpoint transfers from the device but three of them, not just one as coded. This is then followed by a 0xc0010000 error code (USBD_STATUS_CANCELED)

Any help is much appreciated.

Any questions, feel free to ask.

Thanks,

Glenn


View Solution
GlennW
New User
Posts: 2
Joined: Tue May 15, 2018 8:54 pm

Post by GlennW »

Solved!!!

I used a LeCroy USB Mercury T2™ USB 2.0 Protocol Analyzer analyser (borrowed from a friend - owe him a beer) to reveal the XMOS device was not ACKing OUT endpoint packets from the host.

Protocol Analyzer analyser Screenshot:
Image

I delved around the code and found that I hadn't put an XUD_EPTYPE_INT entry into the epTypeTableOut (in main.xc) for my new endpoint! Schoolboy error...

The program would still accept data from the endpoint and trigger my select statement but it wasn't sending an ACK back to the host.

Now I've updated epTypeTableOut it's all working.

Glenn
Post Reply