AnsweredAssumed Answered

USB Device Driver

Question asked by blueskull on Aug 8, 2017
Latest reply on Sep 7, 2017 by blueskull

Hi all, 

 

I tried to implement a USB driver for BF707 based on the URB level driver provided by ADI with CCES. However, it didn't work as expected.

 

I reverse engineered uc/UCB for BF707, and gained a rough idea how ADI's URB level driver works. I then wrote my own driver. So far, I can receive SETUP callback, and parse SETUP requests, but I don't know how to send requested descriptor back to host.

 

I assembled an URB, TX direction, CONTROL type, sized 18 bytes (which is the length of DEVICE DESCRIPTOR, smaller than host requested size and max packet size). I then pushed the URB to a circular FIFO based URB scheduler I implemented, then main function loop pops available URBs and submit them to corresponding EP whenever EP URB status is free.

 

After sending the URB, I can receive a TX URB complete callback, but the host didn't receive the data. I sniffed the bus with a LeCroy T2 USB analyzer, only to find the BF707 sends only NAK. BF707 sends a single ACK upon successful receiving SETUP packet, but that's it. All IN requests are responded by NAK, until host times out.

 

Here's some code snippet:

 

void callback_setup(...)

{

      //Parse SETUP packet

      ADI_USB_URB out;

      out=template;

      out.EpAddr=0x00; //Also tried 0x80

      out.TransferLen=MIN(request_len, sizeof(return_array));

      out.pData=return_array; //return_array is a global const, so the pointer will be valid even after function exits.

      urb_push(0, out); //0 is for buffer index 0, which is assigned for EP0 IN, "out" copied by value to global URB buffer

}

 

void usb_loop()

{

      ADI_USB_URB *urb;

      if(usb_drv->EP_URB_GetState(usb_dev, 0x00)==ADI_USB_STATE_FREE) //EP0 address 0x00 regardless IN/OUT

            if(!urb_pop(0, &urb)) //0 is buffer index for EP0 IN, function returns 0 if there is at least 1 URB available

                  usb_drv->URB_Submit(usb_dev, urb); //urb is a pointer to a global URB buffer

}

 

Here is what URB template looks like:

 

ADI_USB_URB template={.CurReadIdx=0, .CurUrbCount=1, .CurWriteIdx=0, .DevAddr=0, .DevNum=0, .EpDir=ADI_USB_EP_DIR_TX, .EpResult=ADI_USB_RESULT_SUCCESS, .EpType=ADI_USB_EP_TYPE_CONTROL, .EpAddr=0, .ProcessedBytes=0, .TransferLen=0, .pData=NULL, .pHostSubmitURB=NULL};

 

Now, it seems like I just can't force the USB core to respond to host's IN request. Host sends pretty much many thousands of IN requests, and BF707 responds all with NAK, no exception but the initial SETUP packet.

 

Can anyone help me on getting the USB core to send something back to the host?

 

 

 

 

 

 

Regards, 

 

Bo Gao

Outcomes