
31/54
AN1886 - APPLICATION NOTE
An example of the solution would be as follows:
if (USTA & uSETUP) // If it’s a SETUP packet ...
{
if (UCON0 & uSTALL0) // previously STALLed
{
#pragma asm
anl UCON0,#255-uSTALL0 ;clear STALL0 bit when it hangs
#pragma endasm
}
Remark
:
This
STALL0
bit problem is important only during the first enumeration or setup phase. It is im-
portant to be mentioned, that during regular USB usage (normal communication, usage of the device, in
usual applications), there is not reason to
STALL EP0
, therefore this problem is not visible and has no
influence on the USB communication and data exchange. In some (real-time) operating systems, all suf-
ficient system resources must be available to USB only during the first phase to assure fast response and
clearing of
STALL0
bit as soon as possible to ensure the subsequent correct functioning of the USB de-
vice. Thanks to this, the
STALL0
bit problem is not as significant as it might at first appear.
The Number of Data Bytes Received in a Data Packet can be Greater than Eight
It is possible that the content of the
USTA
register (bits
RP0SIZ0,1,2,3
) can indicate a longer packet length
than the maximum value of 8 that is specified in the USB standard. A typical number is 15, and tends to
occur when a USB device is connected or disconnected to or from USB host, or when there is some com-
munication error caused by electrical disturbance. No problems have been observed during the subse-
quent USB operation and communication.
If the buffers are too short, and insufficient tests and conditions are made in the software, buffer overflow
errors can occur, with the overwriting of some variables and incorrect system functionality, or even crash.
The problem has been fixed since version 2.0_XP (January 2004).
C Source and Assembler Output can have Different Functionality
All the previous versions of the USB demonstration program were written in the C language, and some-
times highly optimized. Unfortunately optimization is not always appropriate, and the C language compil-
ers and linkers have absolutely no idea about μPSD hardware functionality. Therefore some parts are
wrongly compiled, and the result causes problems.
Unfortunately, μPSD has all
EP0
basic service and control bits in one register, used bidirectionally. For
example, in routine
TransmitBufferEP0()
in
uPSD_USB.c
the following service might have been written:
UCON0 = ((UCON0 ^ uTSEQ0) & uTSEQ0) | (UCON0 & uRX0E) | nBytes;
It looks like a perfectly conventional line of C, that might be optimized very nicely. But the Keil compiler
(and also others) converts the line as:
MOV A,UCON0
XRL A,#080H
ANL A,#080H
MOV R7,A
MOV A,UCON0
ANL A,#010H
ORL A,R7
ORL A,nBytes
MOV UCON0,A
The problem is that the UCON0 register is not a mathematical constant, as the optimizer might assume,
but can change its state (in particular, the
STALL0
bit) between the first and the last occurrence.