Use net_buf_tail() instead of __buf for proper buffer positioning.
Add null check and error handling for nocache buffer allocation.
Only copy data for OUT transfers during buffer setup.
Signed-off-by: Mark Wang <yichang.wang@nxp.com>
Differentiating between IN and OUT transfers for proper buffer setup.
For OUT transfers: use existing data from buf->data with buf->len.
For IN transfers: use available space from net_buf_tail() with tailroom.
Signed-off-by: Mark Wang <yichang.wang@nxp.com>
DWC2 core automatically clears USBActEP (for all endpoints other than
endpoint 0) on bus reset. While core is deactivating the endpoint, it
does not disarm it.
On bus reset USB stack first calls ep_disable API and then ep_dequeue.
This was leading to endpoint is not active warning followed by endpoint
disable timeout. Disable timeout was effectively caused by waiting for
EPDisbld interrupt on endpoint with disabled interrupts.
Solve the issue by unconditionally disarming endpoint in ep_disable API
handler. Remove the false warning because USBActEP cannot really be used
for sanity checking as it is not only the driver that clears it.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
New nrfx release contains major rework of nrfx drivers
instantiation making it easier to integrate with dts nodes.
Now, nrfx driver instances can no longer be `const`
because they contain driver runtime state.
Additionally, all nrfx drivers return `errno` error codes
instead of deprecated `nrfx_err_t`.
Signed-off-by: Nikodem Kastelik <nikodem.kastelik@nordicsemi.no>
The VBUS bounces when the USB connector is plugged in. This can lead to
events VBUS removed and Suspended occurring in that order. With
hibernation support enabled, hibernation request, as result of the
suspend interrupt, will be delegated to the driver thread. Once the
driver thread is scheduled to process hibernation request, the
controller may be already disabled and controller/phy clocks be off. On
nRF54LM20 this leads to CPU crash and a hang.
To avoid this happening, cancel the possible hibernation request after
interrupts are disabled. Although the thread could be still waked up
because of USBSUSP interrupt raised and event posted, this is considered
to be harmless, as there would be a second check in the thread whether
the event is still valid or is cleared in between.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Instead of using globals, save the clock configuration from DTS in each
instance's configuration block, from which it is consumed by the driver's
clock configuration functions.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
To enable/disable clocks, the UDC driver used function pointers stored in
the instance private data(!), which *could* be NULL... but in practice,
they were always initialized. Furthermore, the clock configuration is
done through Clock Control API calls so the code can be shared by all
instances.
Replace indirect calls through function pointers with direct calls to the
"priv_clock_(dis|en)able" function, which are renamed to "udc_stm32_..."
for consistency with the rest of the driver. The now-unused function
pointers are also removed from the instance data structure.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Instead of using global macro "USB_RAM_SIZE", replace it by its content
(i.e., DT_INST_PROP()) in the only place where it was used.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
From testing on STM32F723E-DISCO, it seems necessary to enable OTGHSULPI
clock in addition to USBPHYC when the internal USBPHYC HS PHY is used.
(USBPHYC is found on STM32F723xx, STM32F730Z8 and STM32F730I8 SoCs)
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Perform cache operations in thread context when the buffer ownership
changes between USB stack and UDC driver. This offers clearly measurable
throughput increase on Mass Storage when double buffering is enabled.
When endpoint operations are not double buffered the difference is
negligible. The positive side effect is reducing number of operations
performed in interrupt context.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
`priv_pcd_prepare` now only consumes per-instance information or constants.
Instead of calling it indirectly through a function pointer, it could be
called directly, but since it is very shorted and used from only one place,
inline it instead.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Instead of consuming the DT property directly, save the USB controller base
address in the instance configuration block and retrieve it at runtime.
This makes the driver more instance-aware.
While at it, cleanup `priv_pcd_prepare` to always consume the property
(through the instance configuration) instead of sometimes using the base
address from CMSIS.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Move the controller's IRQn from instance data to instance configuration,
and update all consumers accordingly. One instance which used the global
UDC_STM32_IRQ is also updated to consume the per-instance field instead.
While at it, add missing comments for certain fields of the configuration.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
When CONFIG_UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED is disabled, force
configure ehci controller to work as FS.
Signed-off-by: Mark Wang <yichang.wang@nxp.com>
During a teardown sequence performed by the USB DC stack's "usb_disable()",
the controller is first disabled by calling "usb_dc_detach()", which turns
off the USB controller clock in the STM32 implementation. "usb_disable()"
then disables endpoints by calling "usb_dc_ep_disable()" on each of them,
which is merely forwarded to HAL_PCD_EP_Close() by the STM32 driver. This
order of operations means that the latter operation is actually operating
on the no-longer-clocks USB controller! Up until recently, memory accesses
to MMIO of unclocked peripherals in STM32 SoCs would not cause issues, even
if the resulting access was a no-op (read returns zero, write is ignored),
so everything worked fine even if the access was *technically* illegal...
However, on newer series with a different bus fabric, accesses to unclocked
peripherals will instead deadlock the SoC!
Prevent illegal accesses inside "usb_dc_stm32_ep_disable()" by checking if
the USB controller clock is enabled before calling HAL_PCD_EP_Close(), and
skipping the call if it isn't. This allows "usb_disable()" to complete on
series such as STM32N6.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
When setting endpoint capabilities, the driver uses the MPS stored in each
instance's configuration for OUT endpoints, but used a hardcoded 1023 for
IN endpoints.
Use the instance MPS when preparing IN endpoints' capabilities too.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Instead of snooping SETUP packets for SET_ADDRESS request to call the HAL
SetAddress() function manually, mark device with the addr_before_status
capability such that the UDC stack will call udc_stm32_set_address()
before submitting status by itself.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
It is possible for usbd_disable() to be called when the core is
hibernated. When done so, the USB stack will attempt to deactivate all
the endpoints. Because the core is hibernated, register reads are
really undefined. This can lead to udc_dwc2_ep_deactivate() not calling
udc_dwc2_ep_disable() which will leave struct udc_ep_config busy flag
set.
When endpoint 0x00 busy flag is left to true, the driver won't allocate
buffer to receive SETUP data which is mandatory in Buffer DMA mode. This
leads to essentially dead device after reconnect, because the device
will not respond to any control transfers.
Solve the issue by modifying backup register value instead of real one
when endpoint is deactivated while core is hibernated.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Split variables definition into 2 line as per Zephyr coding style
expectations since they are of different type.
No functional changes.
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Remove useless test on buffer length in handle_msg_setup() since the
buffer was allocated few lines above with a known non zero size.
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Remove useless OR operation on return value is udc_stm32_enable()
since the return value is always 0 before it's OR-ed with a new return
value.
No functional changes.
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Change implementation to ensure all boolean test are done on essentially
boolean values.
No functional changes.
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Rename endpoint configuration pointer variable in HAL_PCD_ResetCallback(),
udc_stm32_ep_mem_config() and udc_stm32_ep_disable() from ep to ep_cfg
to prevent confusion since ep is usually used as endpoint address.
For consistency, also use ep_cfg elsewhere where an endpoint config
pointer is used, instead of using either cfg, ecfg and ep_cfg.
No functional changes.
Suggested-by: Johann Fischer <johann.fischer@nordicsemi.no>
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Increase default UDC DWS stack size for ESP32-S3 in order
to guarantee quirks are executed without issues.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Ensure the USB clock is enabled before initializing the
controller by invoking the pre_enable hook. This avoids
initialization failures when the HAL has not yet configured
the clock.
Adds shutdown hook to allow interrupt and clock deinit.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Add support for USB on STM32WBA6x series, along with a tiny rework of how
the st,stm32u5-otghs-phy is handled to make the code more generic by
actually consuming DT information.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
On most parts of the STM32F4 series, when the OTG_HS controller is used in
FS mode, the ULIP **low-power** clock must also be disabled for proper
operation. This was done properly in an old version of the driver but was
lost as part of refactoring[1].
Re-introduce ULPI low-power clock disable when OTG_HS is used in FS mode.
[1] See commit e31ddec781
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Actually do what the comment says and wait for Vdd33USB to be ready,
instead of waiting for the opposite.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Actually do what the comment says and wait for Vdd33USB to be ready,
instead of waiting for the opposite.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
During a Host-to-Device Control transfer, an arbitrary amount of data is
sent from Host to the Device using OUT Data packets. If the total amount of
data to transfer, communicated via the wLength field of the SETUP packet,
exceeds the EP0 MaxPacketSize, several Data packets until all data has been
transfered.
Combined with HAL behavior, the STM32 driver did not handle this situation
properly and always ended reception after a single Data packet was received
regardless of whether or not all data had actually been received from Host.
Modify driver to handle this situation properly by keeping track of how
much data has been received and restarting transfers until we have received
everything the Host promised it would send.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Drop all existing transfers in control endpoints' queue when a new SETUP
packet is received. Also use the appropriate net_buf API in a nearby place.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Create a new Kconfig option allowing to tweak the RxFIFO size on OTG_FS
and OTG_HS instances, and replace the old hardcoded method with this new
mecanism.
The default value of 600 bytes yields a similar size to the the previous
hardcoded default of 160 words (= 640 bytes) when combined with the fixed
overhead computed by the driver (~56 bytes on OTG_FS with 6 endpoints).
Also fix a tiny error in a logging message (DRAM size in bytes, not bits).
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
The maximal packet size (for non-control endpoints) was obtained by the
driver from HAL definitions which appear to not properly reflect hardware
capabilities.
Update driver to allow endpoints with wMaxPacketSize up to the maximal
value allowed by the USB Specification depending on operation mode, since
all STM32 USB controllers always support these values. Also move the EP
max packet size field in the 'struct udc_stm32_config' to avoid implicit
padding and add a documentation comment.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
STM32 OTG USB controllers use word-addressable RAM with a 32-bit word size
so all allocations from the USB SRAM must be 32-bit aligned. The driver did
not accept unaligned values of wMaxPacketSize, and FIFO allocation code was
implicitly expecting FIFO sizes to be aligned as well (since it allocated
"bytes / 4" without rounding up).
Update driver to accept values of wMaxPacketSize that aren't word-aligned
and to allocate properly sized FIFOs sizes when an unaligned size has been
requested.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
The ST USB controller (compatible 'st,stm32-usb') is fitted with private
SRAM called the Private Memory Area or PMA. This is primarily used to hold
data transfered over USB, but it also contains the so-called 'buffer table'
(a.k.a. BTABLE) which holds the base address and size of buffers in the PMA
allocated to each endpoint. The BTABLE is placed by the driver at the start
of the PMA and occupies a fixed size ('USB_BTABLE_SIZE'), which was stored
in the driver configuration field 'pma_offset'. This mechanism is unused on
non-ST USB controllers from STM32 microcontrollers, but USB_BTABLE_SIZE is
still defined (to a dummy value) and stored in the 'pma_offset' field which
becomes unused.
Remove the 'USB_BTABLE_SIZE' definition and the 'pma_offset' field from the
driver configuration, and update the ST USB controller-specific verison of
'udc_stm32_mem_init' to derive the BTABLE size from the number of endpoints
that the controller has instead.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
The EP0 max packet size was de facto a constant because its value was the
same regardless of which USB IP was in use. However, it was stored as part
of the instance configuration anyways which is wasteful and slower.
Create new "UDC_STM32_EP0_MAX_PACKET_SIZE" driver-level constant with which
all usage of the per-instance configuration field is replaced.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Rename these three macros to an unprefixed lower-case variant. This is
normally not done for Zephyr macros (see container_of) but in this case
it seems like a good idea to adopt the lowercase names to:
1. have the same convention as the equivalent Linux macros, helping devs
working cross project recognizing (mis)use patterns.
2. make it somewhat intuitive that the lowercase ones are meant to be
used in functions while the uppercase ones are to be used for static
evaluation.
Add few c++ guards to avoid colliding with std::min and std::max.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Fix the check in dwc2_unset_dedicated_fifo() that wrongly included the
current endpoint when testing for higher FIFOs. This caused false
warnings and early returns.
Use ~BIT_MASK(ep_idx + 1) to only test FIFOs above the current EP.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Avoid incorrect (clock_control_subsys_t *) incorrect cast and
remove the cast of pclken in calls to the clock_control_
framework.
Signed-off-by: Alain Volmat <alain.volmat@foss.st.com>
Do not queue new buffer after bus reset if there is one already queued.
This fixes memory leak on each bus reset if there are no SETUP transfers
received between resets.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This is a follow up to commit 4fe2c5bd5f.
The UDC_DWC2_USBHS_VBUS_READY_TIMEOUT Kconfig option should be available
also for nRF92 Series SoCs (as it was previously when it depended on
NRFS_HAS_VBUS_DETECTOR_SERVICE), otherwise some builds will fail for
such targets.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Rework how the STM32 UDC driver determines the PHY used by a given instance
and the speed at which the instance is able to and allowed to operate.
The PHY determination now uses the 'phys' property instead of looking at
whether nodes with a specific compatible were enabled. Similarly, the speed
determination takes into account the 'maximum-speed' property, along with
the selected PHY's and the instance's capabilities.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Rework how the driver performs PWR configuration and initializes HS PHYs.
Originally, the initialization logic was split in half without any real
logic. There were also attempts to share some logic but this resulted in
code that was difficult to understand.
Initialize PWR and PHY in well separated steps, and use explicit series
and PHY type checks in each part to ensure the logic is easy to understand.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>