I ran into a problem with unloading OUT FIFO Packets. I can read the FIFO, but the first two bytes are always read as 0xBC and 0xAF, no matter of what I set them to (on the host). The remaing bytes are read correctly. I have a protocol analyzer at hand, so I can say for sure that there is no 0xBC or 0xAF travelling across the cable. What I do is this:
void Usb_ReadFifo(BYTE volatile xdata* pFifo, void* pBuffer, BYTE bSize){ BYTE* pDest = pBuffer; for(; bSize; --bSize) *pDest++ = *pFifo;}
void HandleEp2Request(){ xdata BYTE wdr[24]; BYTE bIndex = USBINDEX; USBINDEX = 2; if(USBCSOL & USBCSOL_OUTPKT_RDY) { if((USBCNTH) || (USBCNTL != sizeof(wdr)) || (USBCSOL & USBCSOL_DATA_ERROR)) { USBCSOL |= USBCSOL_FLUSH_PACKET; } else { Usb_ReadFifo(&USBF2, &wdr, sizeof(wdr)); USBCSOL &= ~USBCSOL_OUTPKT_RDY;
// here:
// wdr[0] == 0xBC
// wdr[1] == 0xAF
} } USBINDEX = bIndex;}
EP2 ist an interrupt OUT endpoint and USBMAXO ist set to 32. Any idea of what I am doing wrong?
Sorry, my previous post had a typo: I wrote the hex value AA a total of 256 (not 255) times into USBF4. In fact, the first mystery byte in the received packet was the 256th byte written to the FIFO and the second mystery byte was the 255th byte written.
I've discovered the cause of the "first two bytes bad" behavior: it happens when the endpoint's USBMAXO register has a zero or illegal value. Likely causes of this are:1. USBMAXO was never set -- it defaults to zero.2. USBMAXO was loaded when USBINDEX was set to the wrong endpoint number.3. USBMAXO was set too early; an undocumented feature of the chip is that it resets USBMAXO and USBMAXI, along with all other FIFO registers, to zero when a bus reset occurs. It must be set to the correct value after every reset and before the FIFO is used. (An appropriate place to initialize the FIFOs is when a "Set Address" request is received and USBADDR is loaded with the address; this is guaranteed to be between every reset and first use of the FIFO.)4. USBMAXO was loaded with an illegal value -- note that it should be set to the largest expected message size (in bytes), plus seven, divided by eight. (The FIFO size becomes USBMAXO * 8 bytes.)
Thanks Glenn,
It didn't occur to me that USBMAXI and USBMAXO could be reset along with USB bus reset. In my code these registers are set once for all in an init procedure. In fact I also overlooked the fact that USBCS* registers are reset too, which may explain some other issues I have with my code (double buffering would be disabled along with USB reset).
The fact that USBMAXI/USBMAXO are reset in this way should really be written clearly in the datasheet under the "USB Reset" section.
I will change my code today and keep you informed of the result.
I have just finished testing my code modified to take into account the USB reset clearing USBMAXO, and I am glad to confirm that IT WORKS NOW!
Thanks a lot for finding the issue.
Hi,
Good to hear that you found out of what is causing this problem. TI's USB software examples do not have the same problem since the USBMAXx registers are set in the USB setup transaction handler (as opposed to in initialization code). We recommend to use these examples for developing USB applications with CC1111/CC2511.
We can confirm that the USBMAXx registers are among the registers that are cleared upon USB reset. This could be documented better in the datasheet, and we have noted it as a suggested improvement of this document.
Regards,
Bjørn
Bjørn is correct; the example code initializes the FIFO (including USBMAXO) in the handler for the "Set Configuration" request which, along with "Set Address," is a mandatory request between every bus reset and first use of the FIFO.However, using the examples for developing USB applications will not be a viable option for most programmers. A reasonable implementation of a USB driver for the CC1111 or CC2511 (and other chips) is about 700 lines of C code (plus comments) in a 40K source file. A small header file will be needed for prototypes. In contrast, the TI example USB driver is spread across 33 C files and one assembler file, has 1960 lines of C code and 200 lines of assembler, and totals 278K of code. (Apparently, assembler was used because the author didn't know that the linker configuration file from IAR has an error that places const data in RAM.) The code is so obscure that I was only able to figure out what it was doing by single-stepping it in the debugger.I can't use the TI example as a model because I don't want to be fired for incompetence.
Thank you for this discussion!!!!! It was a headache that two mysterious bytes...
Finally it works on my code too.
And yes, please, clarify this on the next datasheet update.
Thank you again. :D
Seb.