Today was spent doing what seems to be my new favourite hobby - reinstalling Windows on my laptop once again. This time the reinstall was sparked by something screwing in the OS chewing threw mountains of memory for no discernable reason; a good half gigabyte chunk of RAM was totally MIA and unaccounted for. After having the Aero interface kill itself (out of memory) while trying to do nothing more than play a DVD on my system with 2GB RAM, I backed up my data and started the system reinstall.
This morning I was actually doing my second favourite hobby (neither this one nor the above I enjoy, for the record) - fixing bugs. An email from a MyUSB user indicated that the current Mass Storage demo fails to work, so off I went to investigate.
First, I narrowed down the release revision which showed the symptioms - 1.4.1 (good) to 1.5.0 (bad). No surpise there; the differences between the two are striking due to the addition of DoxyGen documentation comments, and many code changes to make the library more uniform and inline with the USB specification names and mandates. Next I did my second MyUSB bug-fixing trick, transplanting the working demo code onto the new library (fixing up any changes in the process to make it compatible). After that too failed to work, I was able to determine that the fault lay in the library code itself, rather than the demo application.
My JTAG showed that the code was failing to get out of a spinloop, waiting for the Mass Storage IN data endpoint to become ready to write to. Further probing showed this was due to the endpoint being permenantly stalled, preventing it from ever becomming data-ready. Honestly, I’m a FIRM beleiver that all AVR users need a JTAG - those who cannot see the utility have obviously not had access to one for any useful length of time. The units high cost is quickly offset by the hours saved debugging using more primative methods such as serial logging or (gasp) LED indicators.
What puzzled me was that the storage demo only stalled the data IN endpoint when the command sent from the host was unable to be processed. Not a rare occurrence; the demo only supports a limited (mandatory) subset of the SCSI command set, while the host tries to use the more obscure (but more efficient) commands where possible to speed up the transfers. However, the spinloop the code was getting stuck in was after the loop waiting for the host to un-stall the endpoint via a standard Clear Feature endpoint request.
That, coupled with my previous experiment telling me the fault lay in the library pointed to the problem — the Clear Feature standard request handler code was broken. A SVN diff showed the cause; between the two versions I had altered the code slightly, removing a critical endpoint mask from one of the parameters from the host. Adding it back in fixes the problem.
For those unable to wait for the next release, you can fix the code manually. In MyUSB/Drivers/USB/LowLevel/DevChapter9.c, the second line of SB_Device_ClearSetFeature() should be changed from:
uint16_t wIndex = Endpoint_Read_Word_LE();
Into:
uint16_t wIndex = (Endpoint_Read_Word_LE() & ENDPOINT_EPNUM_MASK);
To make the code work once again.
Yesterday I made up my semester 2 university timetable, and it’s a doozy! With five subjects each with homework, I can unhappily kiss most of my leisure time goodbye.
Recent Comments