DJ reference design and HID

Technical questions regarding the XTC tools and programming with XMOS.
genap
Experienced Member
Posts: 99
Joined: Sat Aug 31, 2013 11:23 pm

DJ reference design and HID

Post by genap »

I have a usb audio project based on the DJ reference design (U8A).

Design is using IN and OUT HID interrupt endpoints. Everything worked fine on the reference design v.6.1.0. Recently I ported it to the v.6.5.0. I am glad I did since I gained about 5K of memory what is a big deal for me.

But there is a big problem. It works fine when I am using one HID endpoint. But as soon as I add a second endpoint, neither audio or HID are recognized by the driver.
I am using exactly the same descriptors and definitions as on a 6.1.0 DJ, so they should be fine.

If anybody can give me an idea what could be wrong, it will be a lifesaver.

Gennady


genap
Experienced Member
Posts: 99
Joined: Sat Aug 31, 2013 11:23 pm

Post by genap »

Resolved.

DJ 6.5.0 enforces wMaxPacketSize in HID endpoint descriptor as short, i.e. 512 bytes size must be written as 0x200. So it didn't really work right with one endpoint either - size and interval were messed up.

DJ 6.1.0 didn't care about it.
genap
Experienced Member
Posts: 99
Joined: Sat Aug 31, 2013 11:23 pm

Post by genap »

Seems like it's too early for celebration. Something is still wrong.

I can get device identified by USB (audio, HID IN and OUT endpoints).
The board receives data over HID OUT endpoint, but I can't send anything on the HID IN endpoint.
Again, nothing seems to change from the DJ 6.1.0.

Here is what I have:

in main.xc:

Code: Select all

/* Endpoint type tables for XUD */
XUD_EpType epTypeTableOut[EP_CNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE,
                                            XUD_EPTYPE_ISO,    /* Audio */
                                            XUD_EPTYPE_INT     /* HID OUT */
                                            /* it's _INT in 6.5.0 vs _BUL in 6.1.0.
                                                I tried _BUL, no change */
                                        };

XUD_EpType epTypeTableIn[EP_CNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE,
                                            XUD_EPTYPE_ISO,
                                            XUD_EPTYPE_ISO,
                                            XUD_EPTYPE_INT    /* HID IN */
                                        };

main()
{
    chan c_sof;
    chan c_xud_out[EP_CNT_OUT];              /* Endpoint channels for XUD */
    chan c_xud_in[EP_CNT_IN];
    chan c_mix_out;
    chan c_aud_ctl;
    ------------

        on tile[XUD_TILE]: /* USB Interface Core */
        XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN,
            c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
            clk, 1, XUD_SPEED_HS, c_usb_test, pwrConfig);

         on tile[XUD_TILE]: /* USB Packet buffering Core */
        {
            unsigned x;
            thread_speed();

            /* Attach mclk count port to mclk clock-block (for feedback) */
            //set_port_clock(p_for_mclk_count, clk_audio_mclk);
            /* Uses same clock-block as I2S */
            asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
            asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));

            buffer(c_xud_out[EP_NUM_OUT_AUD],/* Audio Out*/
                c_xud_in[EP_NUM_IN_AUD],     /* Audio In */
                c_xud_in[EP_NUM_IN_FB],      /* Audio FB */
                c_sof, c_aud_ctl, p_for_mclk_count
#ifdef CHAN_BUFF_CTRL
                , c_buff_ctrl
#endif
            );
        }
------------------------------
        USER_MAIN_CORES
        on tile[0]: Front_control(c_xud_out[EP_NUM_OUT_HID],c_xud_in[EP_NUM_IN_HID]);
}
USB communication function (exactly the same that worked on DJ 6.1.0):

Code: Select all

#define BUFFER_SIZE  100
void Front_control(chanend chan_ep_from_host, chanend chan_ep_to_host)
{
  unsigned char ubuf[BUFFER_SIZE*4];
  unsigned int host_transfer_length = 0;

  XUD_ep ep_from_host = XUD_InitEp(chan_ep_from_host);
  XUD_ep ep_to_host = XUD_InitEp(chan_ep_to_host);

  /* cycles loop **/
  while (1)
  {
      /* Receive a buffer (512-bytes) of data from the host */
      host_transfer_length = XUD_GetBuffer(ep_from_host, (ubuf, unsigned char[]),host_transfer_length);
      if(host_transfer_length < 0) {
          XUD_ResetEndpoint(ep_from_host, ep_to_host);
          continue;
      }

      /* for now on any received message just send back 5 bytes of f/w version */
      ubuf[0] = 'f';
      ubuf[1] = 'v';
      ubuf[2] = '2';
      ubuf[3] = '1';
      ubuf[4] = '7';

      /* Send the modified buffer back to the host */
      host_transfer_length = XUD_SetBuffer(ep_to_host, (ubuf, char[BUFFER_SIZE * 4]), host_transfer_length);
      if(host_transfer_length < 0)
          XUD_ResetEndpoint(ep_from_host, ep_to_host);

      Delay_us(10000);    // 10 ms cycle
  }
} /* end Front_control() */
And, just in case, HID descriptors:

Code: Select all

unsigned char hidReportDescriptor[] =
{
  0x06, 0x00, 0xFF,       // Usage Page = 0xFF00 (Vendor Defined Page 1)
  0x09, 0x01,             // Usage (Vendor Usage 1)
  0xA1, 0x01,             // Collection (Application)
  // Input report
  0x19, 0x01,             // Usage Minimum
  0x29, 0x40,             // Usage Maximum
  0x15, 0x00,             // Logical Minimum (data bytes in the report may have minimum value = 0x00)
  0x26, 0xFF, 0x00,       // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
  0x75, 0x08,             // Report Size: 8-bit field size
  0x96, 0x90, 0x01,       // Report Count - in this file - 400 bytes
  0x81, 0x02,             // Input (Data, Array, Abs)
  // Output report
  0x19, 0x01,             // Usage Minimum
  0x29, 0x40,             // Usage Maximum
  0x75, 0x08,             // Report Size: 8-bit field size
  0x96, 0x90, 0x01,       // Report Count - in this file - 400 bytes
  0x91, 0x02,             // Output (Data, Array, Abs)
  0xC0                    // End Collection
};

    /* HID */
    /* Interface descriptor details */
    .HID_Interface =
    {
    9,                                /* 0  bLength : Size of descriptor in Bytes */
    4,                                /* 1  bDescriptorType (Interface: 0x04)*/
    INTERFACE_NUM_HID,                /* 2  bInterfacecNumber : Number of interface */
    0,                                /* 3  bAlternateSetting : Value used  alternate interfaces using SetInterface Request */
    2,                                /* 4: bNumEndpoints : Number of endpoitns for this interface (excluding 0) */
    3,                                /* 5: bInterfaceClass - interrupt */
    0,                                /* 6: bInterfaceSubClass - no boot device */
    0,                                /* 7: bInterfaceProtocol*/
    0,                                /* 8  iInterface */
    },
    /* The device implements HID Descriptor: */
    9,                                /* 0  bLength : Size of descriptor in Bytes */
    0x21,                             /* 1  bDescriptorType (HID) */
    0x10,                             /* 2  bcdHID */
    0x01,                             /* 3  bcdHID */
    0,                                /* 4  bCountryCode */
    1,                                /* 5  bNumDescriptors */
    0x22,                             /* 6  bDescriptorType[0] (Report) */
    sizeof(hidReportDescriptor) & 0xff,  /* 7  wDescriptorLength[0] */
    sizeof(hidReportDescriptor) >> 8,    /* 8  wDescriptorLength[0] */

    /* Endpoint descriptor (IN) */
    .HID_In_Endpoint =
    {
    0x7,                              /* 0  bLength */
    5,                                /* 1  bDescriptorType */
    EP_ADR_IN_HID,                    /* 2  bEndpointAddress - in devicedefines.h .7 - 1 (in) */
    3,                                /* 3  bmAttributes (INTERRUPT) */
    0x0200,                           /* 4,5  wMaxPacketSize */
    8,                                /* 6  bInterval was 8 */
    },
    /* Endpoint descriptor (OUT) */
    .HID_Out_Endpoint =
    {
    0x7,                              /* 0  bLength */
    5,                                /* 1  bDescriptorType */
    EP_ADR_OUT_HID,                   /* 2  bEndpointAddress - devicedefines.h .7 - 0 (out) */
    3,                                /* 3  bmAttributes (INTERRUPT) */
    0x0200,                           /* 4,5  wMaxPacketSize - 512 */
    8,                                /* 6  bInterval was 8 */
    }
I can't see the difference with DJ 6.1.0 (which works) and don't see why it doesn't send data.

Also, there is another strange thing.
When I define SELF_POWERED (board is powered from a DC adapter), neither audio or HID are recognized by the driver.

I really hope that someone can point me in a rigth direction.

Gennady