New control transfer is started prematurely from device perspective when
host timeout occurs. Any data transfer from previous control transfer
have to be cancelled prior to handling SETUP data. Unconditionally
disable control IN endpoint to prevent race for enqueued buffer between
udc_buf_get_all() called in dwc2_handle_evt_setup() and udc_buf_peek()
called in dwc2_handle_in_xfercompl().
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Device can be considered enabled only after the Soft Disconnect bit is
cleared. Move the post enable quirk past the SftDiscon bit clear.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The USB CDC driver is unable to process any bulk IN transfers
after receiving spurious 'Clear Feature - Endpoint Halt' request
from host due to perpetual locked state caused by previously
scheduled transfer, that will never be finished, as the endpoint's state
is set to NAK. Fix by ignoring spurious request.
Signed-off-by: Piotr Ciura <piotr.ciura@hidglobal.com>
Because the same IP supports both device and host, so use
DYNAMIC_INTERRUPTS for KHCI and EHCI if both device and host
are enabled.
Signed-off-by: Mark Wang <yichang.wang@nxp.com>
- Reset specific configuration bits in
USB1_HS_PHYC->USBPHYC_CR before setting new values.
- Set the Frequency Selection (FSEL) bits to operate
the USB PHY Control Register at 24 MHz for proper communication.
- Enable the OTGPHY1 peripheral clock using LL_AHB5_GRP1_EnableClock.
Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <marwa.ibenelhadjmessaoud-ext@st.com>
SEGGER Ozone J-Trace Code Profile identified iterations over daint value
as hot path. The iterations show at the very top of code profile because
full iteration happens whenever there is any activity on endpoint.
Optimize daint handling loops so only set bits are iterated over. While
this optimization depends on find_lsb_set() efficiency, it seems to be
worth it solely on the basis that quite often only few bits are set.
After a bit deeper analysis, I was suprised that on ARM Cortex-M33 the
find_lsb_set() approach is faster than naive iteration even if all bits
are set (which is extreme case because USB applications are unlikely to
use all 16 IN and 16 OUT endpoints simultaneously). This is due to fact
that there is only one conditional jump CBNZ and find_lsb_set() - 1
translates to RBIT + CLZ and then clearing the bit uses LSL.W + BIC.W.
Whereas the naive itation uses ADDS + CMP + BNE for the loop handling
and also has LSR.W + LSLS + BPL (+ ADD.W instruction on each iteration
to add 16 for OUT endpoints) for the continue check. Therefore the
optimized code on ARM Cortex-M33 is never worse than naive iteration.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
DWC2 core sets DIEPCTL0 SNAK when SETUP packet is received. The CNAK bit
results in device sending NAK in response to IN token sent to EP0, but
it does not modify the TxFIFO in any way. The stale data in TxFIFO can
then lead to "FIFO space is too low" error. Solve the issue by disabling
and flushing IN endpoint 0 if previous control transfer did not finish.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This supports nuvoton numaker m55m1x series soc. Besides, it also
has relevant modifications, including:
1. Fix failure to enable HICR48M, which is to clock usbd and phy
2. Support HWINFO for USB device serial number
Signed-off-by: Chun-Chieh Li <ccli8@nuvoton.com>
The UDC driver for this beautiful USB controller is mostly rewritten
from scratch. USB Pad Calibration and clock handling are copied from the
usb_dc_sam0 driver.
The driver uses multipacket transfers for all endpoints except the OUT
control endpoint. The OUT control endpoint has a buffer that is always
mapped to the endpoint buffer register so that it always has a valid
buffer. The driver provides up to 7 IN and 7 OUT endpoints that support
any type of transfer. Double buffering is not used, for the possible
case of isochronous transfers some changes would be required in the
future.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
- Removing the unused declaration of 'ret'
in the usb_dc_stm32_init function for STM32N6.
- Ensuring the 'ret' variable is used correctly
in the pinctrl_apply_state function call.
Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <marwa.ibenelhadjmessaoud-ext@st.com>
- Unified the handling of USB OTG HS and USB OTG FS
by removing redundant preprocessor conditionals.
- Introduced a new macro `UDC_STM32_BASE_ADDRESS`
to dynamically set the USB base address.
Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <marwa.ibenelhadjmessaoud-ext@st.com>
Enable clock and power for the OTG HS peripheral
of the STM32N6x serie
Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <marwa.ibenelhadjmessaoud-ext@st.com>
At high throughput, the controller sometimes fails to start a new
transaction. Clearing the corresponding endpoint bit in the BUFF_STATUS
completion register before initiating a new transaction solves this
problem.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Do not check if the tailroom is greater than or equal to MPS because the
controller does not write directly to the buffer and therefore cannot
write outside the buffer.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
For the IN endpoint, we only need to set/reset the STALL bit in the
endpoint control register.
To set halt on the OUT endpoint, the AVAILABLE bit must also be set,
which is similar to starting a new transfer, but first any transfer in
progress must be canceled.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Support VBUS state change detection and enable/disable DP pull-up
according to VBUS state when pinctrl property is provided.
It brings the similar functionality introduced in commit 4c0317fa47
("drivers: usb_dc_rpi_pico: Implemented vbus detection handling")
for the legacy device controller driver.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Using k_events eliminates the drawback of the queue potentially dropping
messages and provides a reliable event notification mechanism. It is
similar to commit c2f2d8ce5d
("drivers: usb: udc_dwc2: Replace queue with events")
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
In my opinion, the user is supposed to configure the speed of the stack
and drivers ough to honor that choice. However current Zephyr USB
maintainer imposes that the dependency is the other way round, i.e.
that user first needs to disable High-Speed chirp at driver level and
only then can select Full-Speed only operation. Adhere to the
arbitrarily set up rule to allow this really necessary functionality to
enter Zephyr.
I consider this change to be harmful because it opens up a Kconfig trap
that allows configuring High-Speed capable stack with a device driver
limited to Full-Speed only operation.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Limit maximum operating speed in DCFG register if USB stack is
configured to support only Full-Speed.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Two main ideas behind setting maximum speed are:
* Allow code and RAM optimizations at compile time
* Allow High-Speed capable drivers to limit operating speed to user
choice.
This commit only introduces the necessary Kconfig options but does not
implement any code or RAM optimizations and does not modify any driver.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Arm OUT endpoints only when enqueueing first buffer. Disarm IN and OUT
endpoints on endpoint disable. Prevent ISO endpoints from being armed
twice before SOF.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Use USB stack state instead of former HAL state to determine what to do
with control transfer buffers.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
There is finite number of distinct events that are handled in thread
context and the order of handling is flexible. Therefore use events
instead of message queue because it is guaranteed to never get full.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
There is no need in notifying the driver that OUT data has been
received. This was only used for control transfers with OUT data stage
because dma waiting bit was not set when enqueueing buffer to receive
data stage.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Endpoint abort is guarded with DMA semaphore. The buffers can be freed
by the caller immediately after endpoint is aborted because the driver
won't access them anymore.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Use UDC endpoint state instead of the legacy hal state. Only functional
change relates to overload condition (buffer is too small to hold data
received on OUT endpoint). Previously the data would be completely
discarded and udc driver error would occur (overload event was
unhandled). Now buffer too small error is logged and as much data as
possible is copied to buffer.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This is preparatory commit for former nrfx USBD refactor. The refactor
towards native driver will only be performed on the udc driver (old USB
stack driver will continue to use nrf usbd common until it is removed).
Code is copied from nrf_usbd_common.c with minimal changes:
* nrf_usbd_common_irq_handler renamed to nrf_usbd_irq_handler
* usbd_enable renamed to nrf_usbd_peripheral_enable
* all non-static nrf_usbd_common functions have prefix changed to
nrf_usbd_legacy and are changed to static
* functions not used by udc nrf driver are removed
* braces are moved inside #if to pass compliance checks
No functional changes.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The transfer is queued when buffer is available. There is no point in
delaying the wait until SOF. The check is completely unnecessary.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
There is no need to wait on xfer_new and xfer_finished and therefore
atomic services can be used instead of events.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
When endpoint is disabled while hibernated, the UDC endpoint state has
to be reset. Set the busy to false to keep UDC endpoint state in sync
with peripheral register state.
Fixes: 2be960ad2b ("drivers: udc_dwc2: Disable endpoint while
hibernated")
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Updated UDC speed definition macros for STM32 series
to handle different speed configurations
based on the SoC compatibility.
Added conditional checks for full-speed definitions
using DT_HAS_COMPAT_STATUS_OKAY for st_stm32_usb.
Signed-off-by: Khaoula Bidani <khaoula.bidani-ext@st.com>
Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <marwa.ibenelhadjmessaoud-ext@st.com>
Updated USB_DC speed definition macros for STM32 series
to handle different speed configurations
based on the SoC compatibility.
Added conditional checks for full-speed definitions
using DT_HAS_COMPAT_STATUS_OKAY for st_stm32_usb.
Signed-off-by: Khaoula Bidani <khaoula.bidani-ext@st.com>
Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <marwa.ibenelhadjmessaoud-ext@st.com>
The dev argument is missing.
Introduced in the commit 1cccf28d5e
("drivers: usb: udc: Reduce unnecessary ep config lookups").
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Add defines to avoid magic values in the dtsi.
Replace usb_dc_stm32_get_maximum_speed() with device tree property.
- Use DT_INST_STRING_UPPER_TOKEN(0, maximum_speed) to set the USB speed.
- Remove PCD_SPEED_FULL initialization.
Signed-off-by: Khaoula Bidani <khaoula.bidani-ext@st.com>
Add defines to avoid magic values in the dtsi.
Replace usb_dc_stm32_get_maximum_speed() with device tree property.
- Use DT_INST_STRING_UPPER_TOKEN(0, maximum_speed) to set the USB speed.
- Remove PCD_SPEED_FULL initialization.
Signed-off-by: Khaoula Bidani <khaoula.bidani-ext@st.com>
UDC API passes struct udc_ep_config to all functions. Some UDC functions
were using endpoint config structure while some were using device and
endpoint number. This API inconsistency led to completely unnecessary
endpoint structure lookups. Remove unnecessary lookups by using endpoint
config structure pointer where it makes sense.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
udc_ambiq was using USB test mode definition in dwc2 header, which
the include was removed, hence compilation now fails. This commit
fixes the compilation failure.
Signed-off-by: Chew Zeh Yang <zeon.chew@ambiq.com>
SETUP data is unconditionally ACKed by the controller. Other DATA
packets sent to OUT control endpoint 0 (i.e. OUT Data Stage packets
and OUT Status Stage packet) are ACKed by the device only if the
endpoint was enabled with CNAK bit set.
In Buffer DMA mode controller will lock up in following scenario:
* OUT EP0 is not enabled, e.g. OUT Status Stage has finished
* Host starts Control Write transfer, i.e. sends SETUP DATA0 and
device ACKs (regardless if endpoint is enabled or not)
* host sends OUT Data Stage (OUT DATA1)
- software enables endpoint to be able to receive next SETUP data
while host is transmitting the OUT token. If CNAK bit is set
alongside the EPENA bit, the device will ACK the OUT Data Stage.
If CNAK bit is not set, the device will NAK the OUT Data Stage.
When the lockup occurs, from host perspective the OUT Data Stage packet
was successfully transmitted. This can result in host starting IN Status
Stage if there was only one OUT Data Stage packet. This in turn results
in device never getting the DOEPTINT0 SetUp interrupt. Besides just not
getting the SetUp interrupt, any subsequent control transfer won't be
noticed by device at all.
The lockup was first observed while stress testing. The host was issuing
endless sequence of Control Write, Control Read, Control Write, Control
Read, ... commands. When the controller did lock up in Buffer DMA mode,
from host perspective the device was timing out all control transfers.
Avoid the Buffer DMA lockup by setting CNAK bit only when necessary.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>