Many areas of Zephyr divide and round up without using the DIV_ROUND_UP
macro. Make use of it, so that we make use of a tested system macro and
at the same time we make code more readable.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The init infrastructure, found in `init.h`, is currently used by:
- `SYS_INIT`: to call functions before `main`
- `DEVICE_*`: to initialize devices
They are all sorted according to an initialization level + a priority.
`SYS_INIT` calls are really orthogonal to devices, however, the required
function signature requires a `const struct device *dev` as a first
argument. The only reason for that is because the same init machinery is
used by devices, so we have something like:
```c
struct init_entry {
int (*init)(const struct device *dev);
/* only set by DEVICE_*, otherwise NULL */
const struct device *dev;
}
```
As a result, we end up with such weird/ugly pattern:
```c
static int my_init(const struct device *dev)
{
/* always NULL! add ARG_UNUSED to avoid compiler warning */
ARG_UNUSED(dev);
...
}
```
This is really a result of poor internals isolation. This patch proposes
a to make init entries more flexible so that they can accept sytem
initialization calls like this:
```c
static int my_init(void)
{
...
}
```
This is achieved using a union:
```c
union init_function {
/* for SYS_INIT, used when init_entry.dev == NULL */
int (*sys)(void);
/* for DEVICE*, used when init_entry.dev != NULL */
int (*dev)(const struct device *dev);
};
struct init_entry {
/* stores init function (either for SYS_INIT or DEVICE*)
union init_function init_fn;
/* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows
* to know which union entry to call.
*/
const struct device *dev;
}
```
This solution **does not increase ROM usage**, and allows to offer clean
public APIs for both SYS_INIT and DEVICE*. Note that however, init
machinery keeps a coupling with devices.
**NOTE**: This is a breaking change! All `SYS_INIT` functions will need
to be converted to the new signature. See the script offered in the
following commit.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
init: convert SYS_INIT functions to the new signature
Conversion scripted using scripts/utils/migrate_sys_init.py.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
manifest: update projects for SYS_INIT changes
Update modules with updated SYS_INIT calls:
- hal_ti
- lvgl
- sof
- TraceRecorderSource
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: devicetree: devices: adjust test
Adjust test according to the recently introduced SYS_INIT
infrastructure.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: kernel: threads: adjust SYS_INIT call
Adjust to the new signature: int (*init_fn)(void);
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Unify the drivers/*/Kconfig menuconfig title strings to the format
"<class> [(acronym)] [bus] drivers".
Including both the full name of the driver class and an acronym makes
menuconfig more user friendly as some of the acronyms are less well-known
than others. It also improves Kconfig search, both via menuconfig and via
the generated Kconfig documentation.
Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
Since we have a dedicated function for UDC_EVT_EP_REQUEST type
events, we can now simplify udc_submit_event() and remove
buf parameter.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This allows us to get the result of synchronous transfer without
any hacks, just from the net_buf structure.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Do not use UDC_EVT_EP_REQUEST event without a valid pointer
to a request buffer. No changes needed in the upper layer because
it requires valid buffer pointer for this type of event anyway.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Add helper function to send UDC endpoint event to a higher level
that takes fewer arguments.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This change implements the following, necessary for remote wakeup to be
supported:
- implement usb_dc_wakeup_request() call to trigger remote wakeup
- implement interrupts to detect supsended/resumed state
- implement extra logic to simulate resumed state when the resume
is a result of remote wakeup. In this case the rp2040 chip doesn't
send a USB_INTR_DEV_RESUME_FROM_HOST interrupt, or any other
interrupts when the resume condition is detected to be extended
by the upstream port, so we need to simulate this event when we
see activity on the bus.
Signed-off-by: Purdea Andrei <andrei@purdea.ro>
Description of the bad behaviour before this change:
The arming of the control EP0_OUT endpoint was not kept under
control. It could happen that the EP0_OUT endpoint was left
armed, after the completion of a complete control transfer.
It is clear that the intention was to NOT keep EP0_OUT constantly
armed while idle, because usb_dc_ep_enable() doesn't arm it,
and the intention was for when usb_dc_ep_read() is called to
collect the Setup-Stage 8-byte data, that is when EP0_OUT is armed,
and before this call is performed, the host will keep getting NAKs
for the Data-Stage of the to_device control transfer.
This happens correctly on the first to_device control transfer with
wLength > 0. However, because usb_dc_ep_read_continue() indiscriminately
re-arms all OUT endpoints, in the case of to_device control transfers
with wLength > 0, on the Data-Stage, the endpoint is also re-armed,
which is wrong, because then the endpoint will be left armed after
the control transfer is over.
In this case when a new to_device control transfer starts, the
Data-Stage will be accepted on the first try. This would still
have worked without a failure if the Setup-Stage would have been
processed immediately, but because we process everything in a work
queue at a later time, when the Setup-Stage associated 8-byte data
buffer is read both the Setup-Stage and Data-Stage have arrived.
At the end of handling the Setup-Stage we try to re-arm the EP0_OUT,
which already contains data, thereby corrupting the received length
portion of the buf_ctl register. (Obviously other fields are changed
too, but the length field is the one that first causes chaos, cause
it's written to the maximum, which is 64.) The above mentioned Data-Stage
already has a message in its workqueue for it to be processed, but
it is picked up only after the length field has been corrupted.
Because of this usb_dc_ep_read() thinks there is more data in the buffer
than there really is, and everything becomes de-synchronized, with
later reads accessing uninitialized parts of the buffer.
This sounds like a fundamental failure, that should make it impossible
to operate USB, however the reason this behaviour doesn't make it
impossible to enumerate the device is that this only affects
to_device control transfers with wLength > 0, and during enumeration
there are not many of those happening.
When enumerating a HID keyboard, there is only _one_ of those
happening, and it is the initial setting of the lock light led status.
And that first one succeeds because it's the first one. (However, later
lock light setting control transfers can cause problems, which is how
this problem was encountered.)
The solution in this commit is to keep better control over when EP0_OUT
is armed. This forces the Data-Stage to arrive later (the host will keep
re-trying), and that way the corruption of the buffer control register
is avoided.
Summary of the changes:
- Rework the logic around deciding wether to re-arm the out endpoint
after a read. For non-0 endpoint the previous behaviour is kept,
however for EP0 it is only re-armed if more OUT transactions are
expected for that SETUP transfer (be it data-stage or status-stage)
- Force un-arm the EP0_OUT endpoint in case a stall condition is observed.
- When a setup transfer is received check if EP0_OUT is already armed.
If armed then log a warning message, and force-disarm it.
- When a setup req interrupt fires, don't immediately force the next
read to get it, instead, it will be read only after a setup message
is extracted from the message queue.
- When a setup packet is received abort any unfinished previous control
transfers:
- cancel any data buffers given to the EP0_IN endpoint
- drop any new ep0_in writes that are attempted before this newest
setup packet's associated message is extracted from the message
queue.
- In the ISR, check buffer interrupts before setup req interrupts.
This is to make sure that the final 0-length status message from the
previous setup packet is consumed before the new setup packet.
(this is the only case now when both interrupts could be seen as
having fired by the time the interrupt handler routine executes.
Signed-off-by: Purdea Andrei <andrei@purdea.ro>
Co-authored-by: Johann Fischer
Use proper format for size_t type eliminating warnings of type:
...
error: format '%u' expects argument of type 'unsigned int', but
argument 2 has type 'size_t' {aka 'long unsigned int'}
[-Werror=format=]
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Commit 00adb2a539 ("drivers: udc: remove no more required pending
state flag") removed state parameter from udc_buf_peek and udc_buf_get.
Adapt udc virtual driver so the code compiles.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
C language does not allow declarations after labels, only statements are
allowed. Add {} around the `NRFX_USBD_EVT_SETUP` case to fix build
issues (`error: a label can only be part of a statement and a
declaration is not a statement`)
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
I believe this comment and condition may have found its way into the
rp2040 driver from other drivers where it makes more sense. For
example for the stm32 driver performing a read on the EP0_IN endpoint
turns it silently into a read on the EP0_OUT endpoint. As far as I can
tell, this really was only used to consume 0-length Status-Stages of
to_host control transfer in the other drivers.
Note that usb_dc_ep_start_read() is never called in an IN endpoint
in the rp2040 driver, and furthermore, even if it would have been
called like that, the current implementation would not do the silent
change into actually performing a read on the EP0_OUT endpoint instead,
so the condition and comment is just wrong.
Note that 0-length Status-Stage of to_host control transfers is
currently consumed in this driver by usb_dc_ep_read_continue().
Signed-off-by: Purdea Andrei <andrei@purdea.ro>
The data stage of Control transfers that are sent from Host to Device, can
be made out of multiple OUT transactions, if the amount of data to be
transmitted is larger than the endpoint size. When this happens, the DATA
pid should be toggling. The USB Device driver of the pico must correctly
prime the EP0_OUT buffer with the correct data PID, otherwise the hardware
will reject the received transaction.
Before this change the driver used to always prime EP0_OUT with a DATA1
pid.
After this change the driver only uses DATA1 pid after a setup transaction,
and then toggles the pid for each transaction.
Signed-off-by: Purdea Andrei <andrei@purdea.ro>
This driver enables a number of interrupts it does not attempt to handle.
This results in "unhandled IRQ: 0x...." messages being printed, and the
interrupt handler retriggers immediately again, and this happens again
and again forver, because nothing ends up clearing the interrupt.
This change implements very limited handling of these interrupts. A custom
warning is logged, and the interrupt is cleared.
This change does not imply that doing this is sufficient. More changes may
need to be implemented to more gracefully re-start transactions or
re-arm some endpoints, but this is one step in the right direction,
and at least the OS doesn't freeze up.
Signed-off-by: Purdea Andrei <andrei@purdea.ro>
1. Do not copy over the data to the local buffer,
it can be directly sent to the controller. The
cache is flushed before calling the HAL send
function. Also do not allocate a buffer from
the heap pool for the write operation.
2. Remove a length check as this is handled by
the HAL driver.
Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
New capability is to be used by the stack to adjust the corresponding
field in the device descriptor.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
udc_ep_flush() is not implemented by the driver and is not
used by the USB device stack. Remove it for less confusion
when porting drivers.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Zero data payload size for isochronous endpoints is a
is a valid setting for default interface.
Also do not update MPS of control endpoint since it is
set by the driver.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
In order to clean up clock related code, replace static build time
clock configuration code by a runtime check.
Since I'm not able to guarantee this check will provide a correct
verdict in 100% of the cases (I'm thinking to ULPI or exotic configurations
like F7 OTG-HS), add a config option to disable it if needed.
It also doesn't apply on F1/F3 series. Keep the build time check for now.
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This change doesn't consider STM32F1 series.
There are 5 categories of STM32 regarding USB domain clock:
A] USB domain clocks directly driven by CK48 clocks
B] USB domain clocks which can select either CK48 or an alternative clock
C] USB domain clocks which can select between MSI or PLL
D] USB domain clocks relying statically on a PLL output
E] USB domain clocks which can be set on 2 different PLL ouputs
For case A], there is nothing to be done. Clk48 was already configured
in a previous change (51c7643295b02ba26ddcd0fd915484114db7101c).
For case B] and C] USB domain clocks will need to be configured in
each board.
For case D] and E] relying on existing dts configuration. Though
there is no easy build time chekc that can be done.
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Use STM32_DT_INST_CLOCKS() to access usb device clock information.
This will help accessing domain clock information from dt nodes.
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Remove this code to clean up the driver.
Clock activation is done from device tree configuration in clock_control
driver.
Users are informed by warning about missing configuration.
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Periodic enqeueu of buffers can cause a attempt to start
a new transfer even though an endpoint is already busy.
Split usbfsotg_xfer_start() into two function, one to start
next transfer and another to continue the transfers, and use
busy state flags to explicitly mark an endpoint busy.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Pending state flag was only used by the UDC nRF USBD driver.
With the introduction of busy state flag it is no longer needed
and can be removed.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Periodic enqeueu of buffers can cause a attempt to start
a new transfer to host even though an IN endpoint is already busy.
Use busy state flags to explicitly mark an endpoint busy.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Vbus detection is required by self-powered, with external non-USB
supply, devices to have an operational USB peripheral. The voltage
sensing, when enabled, is performed via a designated pin (PA9 is
the most common).
For greater details see section 2.6, ST application note AN4879.
Signed-off-by: Raul Pando <raul.pando@bytegrity.co.uk>
Now that USB clock prescaler is done is clock_control driver.
Remove similar part in USB driver.
Note that behavior is different: it is now up to the user to provide
the proper configuration.
Add a warning during the transition period.
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Clean up occurrences of "#if IS_ENABLED(CONFIG_FOO)" an replace
with classical "#if defined(CONFIG_FOO)".
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Implement usb_dc_wakeup_request for STM32 USB DC and default to enable
remote wakeup functionality when the drivers is selected.
This allows the device to wake the host up by calling
usb_wakeup_request().
Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
Add support for virtual USB host controller intended for use
together with virtual bus and virtual device controllers.
This driver is not an emulation of any real host controller.
The driver has initial support for handling control and bulk
transfers.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Add support for virtual USB device controller intended for use
by virtual bus and virtual UHC controllers. This driver is not
an emulation of any real host controller.
The driver has initial support for handling control and bulk
transfers.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Add support for virtual USB bus (UVB) intended for use
by virtual UDC and UHC controllers. UVB is not an emulation
of the USB bus or protocol but a simplified service to connect
a virtual host controller to one or more virtual device
controllers.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Add common layer of UHC API and MAX3421E host controller driver.
This implements the bare minimum necessary to communicate with
one peripheral device.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
In the case that IN endpoint is not busy there will be
no notification from the HAL driver.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
The USB_DC_STM32 help message started to miss some
STM32 MCU families. Overtime, the message will
get bigger if we continue to list family names.
Removed family names to simplify the message and
avoid periodic modifications.
Signed-off-by: Georgij Cernysiov <geo.cgv@gmail.com>
The HSI48 is enabled by clock control driver.
It is no more done by each driver that requires this clock
However when using rng or sdmmc or bluetooth/ipm or usb,
the HSI48 clock must be present in the DTS.
Add a warning for this particular check but keep the deprecated
HSI48 clock enable : keeping for legacy but to remove later.
Signed-off-by: Francois Ramu <francois.ramu@st.com>