Other Parts Discussed in Thread: AM3352, SYSBIOS
Hello,
I am trying to get the am3358/am3352 CPU running in USB Host mode. I want to access a USB thumbdrive.
In summary, I cannot get EP1 to work. EP0 appears to be working fine.
My question: What is required to open an EP1 in host mode. Because it is giving me a error when I try to send. And the Tech Ref is missing critical information. For details, read on.
I will attempt to include the entire CCS project in a zip. It's minimal, not bloated with superfluous code, functions, files that complicate things.
The environment is Bios 6.76.03.01 with XDC 3.55.2.22, using GNUC 7.3.1. Although for this unit development, it is essentially BARE METAL and running it's one task operation. So this is NOT a BIOS/RTOS issue, as the code would run as a raw C project, bare metal (and I have tried that too.)
I am using the original "AM335X_StarterWare_02_00_01_01" as a beginning point, and attempting to simply open the USB drive and communicate with it.
The doc for it is mostly well explained. However using it simply fails ONLY to allow communication over EP1. So there must be some verity small piece of information I am missing.
I have plenty of USB DEVICES working with this code base. I am confident the hardware and the functions from StarterWare function are adequate. Except for opening an HOST based EP1.
Here is what I see that is working, and where is doesn't...
I examined the WireShark log for this UBS drive when attached to a PC. I can see all the descriptor commands send as transactions to/from EP0, and also the first inquiry it sends on EP1.
So, naturally the endpoints for this thumbdrive work as expected in the PC.
In the ARM firmware, I can successfully enumerate the device, and perform a GET LUN command which returns successfully. These are all transaction messages on EP0. However it is failing to communicate through the data pipes. I am printing out the data and messages to a UART log of my own messages, which is included at the project ZIP.
I can't output any message inside a ISR, but I can simply write to some memory. So I have a large buffer, and a few functions that simply write a message to that buffer: AddToIntBuffer(), AddHEXToIntBuffer() . Then I can pause or interrupt the execution, and have the CCS IDE do a memory dump of that, so I can see what happens inside the ISR. (I describe what I see in the ISR memory log in a bit)
The configuration descriptor, as read from the device, matches the one that I sniffed with WireShark. the the value parse correctly. The some data is shown below:
09 02 20 00 01 01 00 80 32 09 04 00 00 02 08 06
50 00 07 05 01 02 00 02 00 07 05 81 02 00 02 00
Which is a descriptor to a Mass storage device, 2 endpoints, class MSC, protocol x50, etc...
The pipe descriptors are shown here:
07 05 01 02 00 02 00 EP 1 OUT Bulk 512 bytes
07 05 81 02 00 02 00 EP 1 IN Bulk 512 bytes
So they are all okay.
Here is where things get insane...
When I create the pipes using the function USBHCDPipeAllocSize(), USBHCDPipeConfig(), etc and set the type to "BULK" the first attempt to send the MSC device a query out PIPE 1 gives a PIPE_ERROR.
Here's what's really weird: The value that holds the state is from the global structure "g_sUSBHCD", "eState" member. And it is ONLY set inside the ISR. And every step in the ISR is recorded to my memory log... That member is never set to PIPE_ERROR in the ISR, since it's not recorded anywhere in my ISR log buffer... So I'm lost as to how the eState member gets set to error, if the ISR never set that flag.
So how it is getting set?
More importantly: Why can I not send any data out EP1?
There has to be something simple and easy as to what I am doing wrong and why the EP1 isn't working. But I have yet to find any clue in the code or any of the doc.
Just a few things I've tweaked:
I have tried playing with the "ulInterval" stuff that sets timeouts. No difference.
I have tried changing the DMA type (I am not using CPPI routine at this stage).
I have tried changing the EP type.
When I change the setting of the pipes from BULK to INTERUPT, it actually does send the inquiry request to the device (well, gives me a success anyway) but when I try to read back from the pipe, it gives me a STALL. Maybe that is normal to get a STALL if you set it to INTERRUPT, but try to read a pipe that is BULK. I don't know.
But the same issue about that state flag: The only place that eState member is set is within the ISR, and every step in the ISR is recorded to my memory log. And that member is NEVER set inside the ISR.
I tried reading the TI doc, which is the Tech Ref they call "spruh73". But that was a waste of time. It's missing a BUNCH of information. For example:
Section 16.2.8.2 - Host mode:
"This allows that one packet can be received while another is being read. Double packet buffering is enabled by setting the DPB bit of RXFIFOSZ register (bit 4)."
Well, that RXFIFOSZ register is not defined.
For that matter, neither is HOST_RXTYPE, HOST_RXINTERVAL, INTRRXE, etc... and bunches of other things.
The tech ref leaves a LOT to be desired in documenting this peripheral, and in offering support.
In summary: Can anyone steer me toward some example code that correctly opens EP1 and communicates through it? Or even actual, useful, doc that defines all this missing stuff?
Thanks in advance for any advice on this issue.
-Scotty
PS. Please do NOT suggest using the PDK, as it has all kinds of deficiencies. It doesn't build on my PC, the precompiled libs are too interdependent with other things that will conflict with our environment, I can't hand trace the code as it's an obfuscated mess with no documentation (Doxygen generated doc is useless no details, no explanations, no examples...) and I can't build one with debug info to step into anything... I can't even be confident that the code which came with the PDK matches the precompiled libs... And I tried to import and create a CCS project, but there are dozens of headers with IDENTICAL names, and no clue how to unravel the -I include paths used (and I've got pages more to be critical of , if anyone wants to hear...)