See https://github.com/libopencm3/libopencm3/issues/873
Commentary describing this patch originally by zyp:
```
After looking further into it, I've concluded that my preliminary
analysis looks correct. The problem is that setting CNAK before
the SETUP complete event is received causes a race condition. The
SETUP callback is called when the SETUP packet event is received,
which means that setting CNAK from the callback is too early.
Originally the problem was that CNAK was set by ep_read() which is
called by the callback. #672 solved this by moving CNAK out of
ep_read() and calling it after the SETUP complete event is received
instead.
The regression by #785 is caused by the introduction of flow control
calls into the SETUP callback. They also set CNAK.
To solve this properly, I propose changing the event handling code
to only call the SETUP callback after the SETUP complete event is
received. Unfortunately, this implies that the callback can't call
ep_read() itself anymore, because the packet has to be read out of
the FIFO before the SETUP complete event arrives. This implies a
change of the API between the hardware drivers and _usbd_control_setup().
```
L1 (st_usbfs) works and passes tests as before change
F4 (dwc_otg_fs) works and now passes tests. (yay)
LM4f still compiles, and has had the same style of implementation as
st_usbfs, however has not been tested on any hardware.
Use EP0 OUT flow control to NAK OUT packets when we're not yet expecting
any. This prevents the status OUT event from arriving while the control
state machine is still expecting the data IN completion event.
Use REBASE(OTG_FIFO(endpoint)) to access the FIFO.
For the receive FIFO do not use the endpoint. There
is only one receive FIFO so giving the endpoint is
a no-op.
Get rid of REBASE_FIFO macro.
Control transfers can transfer less than was requested by the host in the
wLength field. if this short transfer is a multiple of the endpoint's packet
size, a zero length packet must be sent.
Adds tests for a range of control transfer IN requests, and properly supports
this in the core. Based heavily on work by Kuldeep Dhaka.
See https://github.com/libopencm3/libopencm3/pull/505
and https://github.com/libopencm3/libopencm3/pull/194 for original discussion.
Tested with stm32f4, stm32f103 and stm32l053.
After a STALL handshake is transmitted, a control pipe becomes idle. Not
marking the pipe as idle did not affect the STM32 family. Since it
distinguishes between OUT and SETUP tokens, it calls the setup handler
on a SETUP token, regardless of the state of the pipe.
Other families, such as LM4F do not distinguish in software between IN and
SETUP tokens, and need to decide which handler to call based on the state
of the pipe. On these chips, SETUP transactions will not be handled
properly after a transfer was STALLED, as the state machine of the pipe is
b0rked. Unb0rk it.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Added --terse and --mailback options to the make stylecheck target. It
also does continue even if it enounters a possible error.
We decided on two exceptions from the linux kernel coding standard:
- Empty wait while loops may end with ; on the same line.
- All blocks after while, if, for have to be in brackets even if they
only contain one statement. Otherwise it is easy to introduce an
error.
Checkpatch needs to be adapted to reflect those changes.
This commits adds a new error code that can be return from a
registered control callback: USBD_REQ_NEXT_CALLBACK. This return code
signifies that the callback is done processing the data successfully,
but user would like to have all matching callbacks down the callback
chain to be executed too.
This change allows for example to intercept standard requests like
GET_DESCRIPTOR, do some small action upon receiving of one, but still
have the standard callback executed and do it's job. This way user
doesn't have to re-implement standard GET_DESCRIPTOR functionality if
they want to intercept that request to do some small thing.
All #includes now explicitly use the "<libopencm3/stm32/rcc.h>" format.
If you want to get rid of the "libopencm3" prefix in your local project you
can add a respective -I entry in your Makefile (not recommended though).
All .ld files and .a libs are installed in $(TOOLCHAIN_DIR)/lib
directly (as before), but are now renamed to avoid potential
conflicts now or in the future. Examples:
libopencm3_lpc13xx.a
libopencm3_lpc13xx.ld
libopencm3_stm32.a
libopencm3_stm32.ld