[SOLVED] ASF driver stalling OUT data phase if buffer contains more than 2 consecutive bytes=0xff

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a really weird issue here, sorry if the title does not convey the gist of the problem.

 

TL;DR: ATXMEGA32A4U running ASF USB stack, low speed, HID generic interface. Report descriptor specifies two feature reports. Sending a buffer to the device with Libusb from Windows 7 PC works just fine - as long as the buffer does not contain the value '0xff' more than two times in a row. I have tried HID API instead of Libusb to rule out that it is a Libusb issue - same result. What is wrong here?

 

Update: 09.03.2019:

 

I want to believe this is a software issue and somehow related to Windows' HID driver API, so Atmel is not to blame here. When I use a different report descriptor without report ids no stall occurs. I want to use report ids though and I do not see why I should not. Occasionally I can send a buffer when no report ids are used, but of the time the transfer is stalled. If I use report is the transfer is stalled everytime.

Here's a link to a thread describing the same issue on a different platform: https://community.st.com/s/quest... The author of this thread mentions that he can transfer a buffer containing a series of 0xff's on Linux just fine, while the same buffer gets discarded when sent from a Windows machine. I will investigate that some more and post my findings.

 

Update: 09.04.2019

 

It's not just 0xff, I cannot send 0xfe in a row, 0xfd in a row, 0xfc in a row, 0xfb in a row - but I can send 0xfa in a row. I cannot send 0xef in a row either. Yelp!

 

For starters, here's my report descriptor:

 

0x06, 0x00, 0xff,              // USAGE_PAGE (Generic Desktop)
0x09, 0x01,                    // USAGE (Vendor Usage 1)
0xa1, 0x01,                    // COLLECTION (Application)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
0x75, 0x08,					// REPORT_SIZE

0x85, HID_REPORT_ID_PAGE_DATA,	// REPORT ID
// 2 bytes for address data + 256 bytes for page data
0x96, 0x02, 0x01,                   //   REPORT_COUNT (258)
0x09, 0x00,                    //   USAGE (Undefined)
0xb1, 0x02,              //   FEATURE (Data,Var,Abs)

0x85, HID_REPORT_ID_EXIT_BOOTLOADER,	// REPORT ID
0x95, 0x01,                   //   REPORT_COUNT (1)
0x09, 0x00,                    //   USAGE (Undefined)
0xb1, 0x02,              //   FEATURE (Data,Var,Abs)

0xc0                           // END_COLLECTION

 

There is nothing wrong with it as far as I can tell.

 

If I send a buffer with Libusb s.a. buf[259] = {1, 0xaa, 0xbb, ..., 0xcc} (abbreviated for the sake of clarity) (1 is the report id, btw), I can read it back using a uart printf() function just fine. If the buffer contains more than two 0xff values in a row, s.a. buf[259] = {1, 0xff, 0xff, ..., 0xff}, the control OUT data phase is stalled, the control buffer will not get filled. The setup request is, however, still processed correctly.

 

Now, what in the world could possibly be causing that behavior? For all I know, this looks like a Atmel ASF driver issue, or worse, a hardware issue. It seems as though the USB receiver were comparing the incoming byte stream to some hard-coded value and discarding it because it is all 0xff's. What am I missing here?

 

This is going to be a long and tedious debugging session, I presume, so I am prepared to answer questions and provide all information necessary to get to the bottom of this. I am currently at my wits end. :(

This topic has a solution.
Last Edited: Fri. Sep 6, 2019 - 11:18 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok I think I got it, it's a clock issue as described at: https://stackoverflow.com/questi...

 

For the record this eventually turned out to be an oscillator problem. (Apparently the FLL's reference is always 1,024 Hz even when the 1,000 Hz USB frames are chosen. The slight clock error meant that a packet occasionally got rejected if it happened to contain one too many 1-bits in a row.)

I guess the moral of the story is to check the basics before assuming you've got a problem with the higher-level protocol.

 

Although I have the USB module configured to run at 6MHz clock speed (no SOF reference available, only Keep Alive), adding

 

// enable DFLL calibration with SOF as reference
DFLLRC32M.COMP1 = 0x80;
DFLLRC32M.COMP2 = 0xBB;
OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc;
DFLLRC32M.CTRL = DFLL_ENABLE_bm;

did the trick. Apparently, it does not matter if there's a real SOF packet or just a Keep Alive SE0. I can now receive buffers containing an arbitrary number of 0xff's. Whew, what a relief! =)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I can confirm that the problem has been solved. The target application is an XMEGA bootloader (stripped down ASF code to fit inside 4K boot section of flash) and the data to be received is a binary image of the firmware to be stored in the application section of flash. Since the application code is running after a reboot obviously downloading all firmware data was successful. This thread can be closed.