USB stack does not check api->lock() and api->unlock() return value and
all UDC drivers block without timeout in its lock() and unlock() api
implementations. There is no realistic way to handle lock() and unlock()
errors without making USB device stack API unnecessarily complex.
Remove the return type from lock() and unlock() to make it clear that
the functions must not fail.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
In Completer mode SETUP data can always be received and therefore
endpoint 0 should only be enabled for OUT Data Stage and OUT Status
Stage.
In Buffer DMA mode, SETUP can only be received when endpoint is enabled
and therefore the software has to make sure that there is a buffer
available to receive SETUP data.
Rework the EP0 buffer feeding to adhere to DWC2 Programming Guide.
Synchronize the accesses with driver mutex to avoid interrupt related
race conditions.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The transfer is finished after ZLP is transmitted. Do not re-enable the
endpoint waiting for more data.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Control OUT buffers must be multiple of bMaxPacketSize0 in Buffer DMA
mode. While the transfer can be configured to smaller values, DMA will
write data past the buffer (and transfer size counter will underflow) if
the packet on the bus is larger or if there are multiple back-to-back
SETUP packets.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Use helper functions to check whether device is operating in Buffer DMA
or Completer mode. This allows compile time optimizations to remove DMA
handling code when DMA is disabled via KConfig symbol UDC_DWC2_DMA.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
If the to-host data stage length is less than that requested by the
host, but equal to or a multiple of MPS, the device should send a ZLP,
not receive it.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
When the UDC buffer gets submitted it should no longer reside in the
endpoint queue. While this commit does not address the underlying issue
of not being able to start transfer for whatever reason, it prevents the
problem from cascading into buffer double completion (e.g. receive
buffer double free in UAC2).
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
DWC2 otg versions earlier than 5.00a are subject to randomly occurring
glitch on Hibernation Exit by Host Initiated Resume, Hibernation Exit by
Device Inititated Resume and Hibernation Exit by Host Initiated Reset.
When the glitch happens the device address is not correctly restored.
If the address is not correctly restored then the tokens addressed to
the device will timeout leading to host resetting the bus.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Programming Guide states that bit 17 on PCGCCTL writes should be set if
the controller was enumerated for High Speed operation. Add the missing
bit set to adhere to the Programming Guide.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Introduce `UDC_STM32_CLOCK_CHECK` Kconfig option since
`USB_DC_STM32_CLOCK_CHECK` was intended for use with `usb_dc_stm32.c`,
which is mutually exclusive with `udc_stm32.c`.
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
On USB HS, the previous lower limit of 64 is too small, the value
160 has been chosen apparently through trial and error.
See 1204aa25 for the original implementation in the old device driver.
Signed-off-by: Tobias Pisani <mail@topisani.dev>
This fixes usbd_caps_speed(), which is used in sample_usbd_init, and the
documentation. Without it, no high speed configuration would be added.
Signed-off-by: Tobias Pisani <mail@topisani.dev>
All HAL callback handling is offloaded to a separate thread, as they
involve non isr-compatible operations such as mutexes.
Fixes#61464
Signed-off-by: Tobias Pisani <mail@topisani.dev>
In the device that has `DT_DRV_COMPAT` equal to `st_stm32_usb`,
its behavior differs from `st_stm32_otghs` and `st_stm32_otgfs`
due to the underlying `HAL_PCD_IRQHandler`.
As a result, calling `usbd_ctrl_feed_dout` for the DOUT stage is not
compatible with the `st_stm32_usb` device.
Instead of calling `usbd_ctrl_feed_dout`, we still require flushing
the TX FIFO to the host.
This is achieved by calling `HAL_PCD_EP_Receive` with `len` = `0`.
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
DMA transfers are supposed to write to buffer tail. Use the proper
pointer to make multipart DMA transfers actually write the data to the
intended location.
The issue was observed on control write transfers where the OUT Data
Stage was at least 128 bytes (because endpoint 0 transfer width is
limited to 7 bits).
The issue is unlikely to happen on non-control transfers because the
transfer size width is at least 11 bits (at most 19 bits) and packet
size counter is at least 4 bits (at most: 10 bits) which means that
at least 2048 byte transfer spanning at least 15 packets (or at least
524288 byte spanning 1023 packets for 19 bits transfer size counter
and 10 bits packet counter) is required to necessitate multipart DMA.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Prepare buffer to receive SETUP data on OUT endpoint 0 after endpoint
halt. This solves the issue where the device would no longer process any
control transfers after the first failed transfer with too large OUT
Data Stage (when processing failed due to data stage buffer allocation
failure).
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The DOEPTSIZ0 XferSize field is 7 bits long, meaning that maximum single
transfer can be 127 bytes long. Configure the control write (OUT)
transfers considering the XferSize field size to support transfers with
data stage larger than 127 bytes.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The address passed in to the function was incorrect causing
failures when porting to RT1180.
Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
With changes introduced in commit 6a3602a306
("net: buf: Clear `user_data` on allocation")
our memset() calls are redundant.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Do not allow enqueuing buffers on endpoints that were not enabled. Doing
so can lead to division by zero later on because the max packet size can
be 0 in disabled endpoint configuration.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Endpoint disable function is racing against bus traffic. If the bus
traffic leads to transfer completion immediately before the endpoint
disable is executed, then the transfer complete interrupt will remain
set when the endpoint is disabled. For OUT endpoints this leads to "No
buffer for ep" errors, while for IN endpoint this can lead to double
buffer pull which causes assertion failure.
The proper solution would be to change endpoint disable to not actually
wait for the individual events (and accept that the endpoint may not
need to be disabled because the transfer can just finish). For the time
being workaround the issue by clearing XferCompl bit on endpoint
disable.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
When handling incomplete iso IN interrupt mark current transfer as
complete and program the endpoint with any subsequently queued packet.
Program the endpoint directly in interrupt handler because the data
must be programmed before SOF (by the time incomplete iso IN interrupt
is raised there is less than 20% * 125 us = 25 us before SOF).
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The NAKSts bit may be set on isochronous OUT endpoints when incomplete
ISO OUT interrupt is raised. The code would then assume that endpoint is
already disabled and would not perform the endpoint disable procedure.
This in turn was essentially halting any transmission on the isochronous
endpoint, abruptly terminating the data stream.
Fix the issue by always following full endpoint disable procedure on
isochronous endpoints.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Ambiq USB HAL do not expect endpoint transaction request when an
endpoint is stalled. This commit addresses this behavior in shim driver
by checking for endpoint's stall status when enqueue request is
received, and defer it until endpoint stall is cleared.
Signed-off-by: Chew Zeh Yang <zeon.chew@ambiq.com>
Accessing DWC2 otg core registers before the clock starts results in
complete system hang. Add a 1 us busy wait to make sure that software
won't access registers before the clock is started.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Low Power mode can only be entered when there are no active DMA
transfers. Move the Suspend and Resume processing to thread to allow
waiting for the DMA available semaphore in USB Suspend handler.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
To remove CONFIG_PINCTRL from board side for numaker boards.
The Drivers using Pinctrl should be turning Pinctrl on
instead of the responsibility of the board.
Fixes#78619
Signed-off-by: cyliang tw <cyliang@nuvoton.com>
USBD peripheral automatically handles Set Address command which can
lead to state mismatch between USB stack and the host. Keep track of
device address and issue fake Set Address commands on mismatch.
This fixes default vs addressed state mismatch that can occur due to
sufficently high SETUP handling latency. The state mismatch was most
commonly seen as SET CONFIGURATION failure when the enumeration happened
during periods with increased latency.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Any request 5 did set the address even if it's a non standard
request like vendor specific requests.
Signed-off-by: David Schneider <schneidav81@gmail.com>
If the direction of the last setup packet is not to the device but to
the host, then the transfer is not a status stage and should be queued.
This is not checked and prevents a zero length control IN transfer to
the host, e.g. used by the DFU class to indicate the end of the upload
process.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Reset control endpoint busy flags if configured and enabled, otherwise
it could mark the wrong buffer as busy after endpoint disable/enable.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Some NXP socs with Kinetis USB do not have USB voltage regulator.
It causes build error in USB samples.
Fix it by enabling and disabling the voltage regulator only if
present.
Signed-off-by: Michal Smola <michal.smola@nxp.com>
DWC2 peripherals can have TxFIFO sizes configured to any value between
16 and 32768. The value configured during synthesis is the maximum value
the software can program. Designs that give full flexibility configure
the TxFIFO sizes to value equal to total SPRAM size.
Currently DWC2 driver does not have prior knowledge about the endpoints
used within available configurations and has to come up with TxFIFO0
value up front. The original approach was to use MAX(16, max allowed).
locations. Because DWC2 peripheral cannot have TxFIFO0 with size lower
than 16 locations, always the max allowed was used. This logic prevented
any IN endpoint other than EP0 on designs that have TxFIFO0 size set to
total SPRAM size.
Change the logic to MIN(2 * 16, max allowed) to have sufficient memory
available on flexible designs and allow simultaneous operation if
possible (i.e. when maximum TxFIFO0 size is at least 32).
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
DWC2 otg OUT transfers are being used for SETUP DATA0, OUT Data Stage
packets and OUT Status Stage ZLP. On High-Speed it is possible for IN
Data Stage, OUT Status Stage ZLP and subsequent SETUP DATA0 to happen
in very quick succession, making all the three events appear at the same
time to the handler thread.
The handler thread is picking up next endpoint to handle based on the
least significant bit set. When OUT endpoints were on bits 0-15 and IN
endpoints were on bits 16-31, the least significant bit policy favored
OUT endpoints over IN endpoints. This caused problems in Completer mode
(but suprisingly not in Buffer DMA mode) that lead to incorrect control
transfer handling.
The choice between least significant bit first or most significant bit
first is arbitrary. Switching from least to most significant bit first
would have resolved the issue. It would also favor higher numbered
endpoints over lower numbered endpoints.
Swap the order of endpoints in bitmaps to have IN on bits 0-15 and OUT
on bits 16-31 to keep handling lower numbered endpoints first and
resolve the control transfer handling in Completer mode.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
There is an issue where OUT data is not handled correctly when the
toatl length exceeds the MPS. This update fixes the control handling
for the OUT endpoint.
Signed-off-by: Ren Chen <Ren.Chen@ite.com.tw>
The ready bit is automatically cleared by hardware. When setting other
bits, there is a chance that the ready bit hasn't been cleared yet,
leading to unexpected USB transactions. This commit addresses this
isuue and locks irq for critical section to prevent racing condition.
Signed-off-by: Ren Chen <Ren.Chen@ite.com.tw>
The IT82xx2 chip has three FIFOs shared across endpoint 1 to 15, and
the FIFO control register is configured based on the active endpoints.
However, there are some issues with FIFO control.
Firstly, when a TRANS_DONE interrupt occurs, the completion of the
transaction should be determined by the ready and enable bits of the
corresponding endpoint. Additionally, only one non-control IN endpoint
can access the IN FIFO at a time. The FIFO control register is selected
before writing data and cleared after the IN transaction is completed.
For OUT endpoints, all endpoint bits must be selected in the OUT FIFO
control register when the endpoint is enabled. This can result in fake
OUT tokens being detected if an interrupt is triggered by another FIFO.
To prevent this, an atomic out_fifo_state variable has been introduced
to handle the detection of fake OUT tokens.
Signed-off-by: Ren Chen <Ren.Chen@ite.com.tw>
Adds CONFIG_UDC_DWC2_USBHS_VBUS_READY_TIMEOUT_MS that allows
for waiting for a USBHS VBUS ready event for a specified
amount of time. Earlier it waited forever and because of that,
the udc_enable() was blocked forever if the USB cable was
disconnected. Now the function returns error on timeout.
Signed-off-by: Aleksander Strzebonski <aleksander.strzebonski@nordicsemi.no>
The Drivers using Pinctrl should be turning Pinctrl on
this should not be the responsibility of the board. This
commit removes CONFIG_PINCTRL from the boards side for nxp boards.
Signed-off-by: Emilio Benavente <emilio.benavente@nxp.com>
Peripherals are required to support the suspend state whenever VBUS
is powered, even if bus reset has not occurred (Mandate: Required,
Effective Date: February, 2010).
Remove the stale suspend check that essentially prevented the device
from hibernating when connected to already suspended bus.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>