This new implementation is written from scratch and is not tied to the
image manager and MCUboot. It allows the user to define their own
backend and use a simple macro to instantiate an image. On the USB side
this is represented by an interface. The number of possible images is
configurable using the Kconfig option, and is a fairly inexpensive
approach since it only changes the size of the pointer array. The number
of images is only limited by the number of possible interfaces in a
configuration. The class implementation does not support multiple
instances, as there is no real use for it. However, it does provide two
class instances, one for runtime mode and one for DFU mode. The switch
from runtime to DFU mode can only be performed by the user application,
i.e. the application receives a notification when the host wants to
switch to DFU mode, and then the application can disable the runtime
configuration and enable the DFU configuration. This implementation does
not support switching to the DFU mode by bus reset issued by the
host.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
In the usbd_register_all_classes(), we may need to skip some instances
as they may have very specific function like USB DFU "DFU mode" which
should not be available by default.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This adds a new USB device class (based on usb/device_next) that implements
revision 2.0 of the MIDIStreaming interface, a sub-class of the USB audio
device class. In practice, the MIDI interface is much more simple and has
little in common with Audio, so it makes sense to have it as a separate
class driver.
MIDI inputs and outputs are configured through the device tree, under a
node `compatible = "zephyr,usb-midi"`. As per the USB-MIDI2.0 spec,
a single usb-midi interface can convey up to 16 Universal MIDI groups,
comprising 16 channels each. Data is carried from/to the host via
so-called Group Terminals, that are organized in Group Terminal Blocks.
They are represented as children of the usb-midi interface in the device
tree.
From the Zephyr application programmer perspective, MIDI data is exchanged
with the host through the device associated with the `zephyr,usb-midi`
interface, using the following API:
* Send a Universal MIDI Packet to the host: `usb_midi_send(device, pkt)`
* Universal MIDI Packets from the host are delivered to the function passed
in `usb_midi_set_ops(device, &{.rx_packet_cb = handler})`
Compliant USB-MIDI 2.0 devices are required to expose a USB-MIDI1.0
interface as alt setting 0, and the 2.0 interface on alt setting 1.
To avoid the extra complexity of generating backward compatible USB
descriptors and translating Universal MIDI Packets from/to the old
USB-MIDI1.0 format, this driver generates an empty MIDI1.0 interface
(without any input/output); and therefore will only be able to exchange
MIDI data when the host has explicitely enabled MIDI2.0 (alt setting 1).
This implementation is based on the following documents, which are referred
to in the inline comments:
* `midi20`:
Universal Serial Bus Device Class Definition for MIDI Devices
Release 2.0
https://www.usb.org/sites/default/files/USB%20MIDI%20v2_0.pdf
* `ump112`:
Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol
With MIDI 1.0 Protocol in UMP Format
Document Version 1.1.2
https://midi.org/universal-midi-packet-ump-and-midi-2-0-protocol-specification
Signed-off-by: Titouan Christophe <moiandme@gmail.com>
The usbd_uac2_send function sometimes took ownership of the
provided buffer in error cases, and sometimes not.
The commit modifies the function so that ownership is never
taken in case a non-0 return value.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Add a config structure and move few pointers that don't need to change
into it, save few bytes of SRAM.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This allows us to use the testusb Linux kernel tool again. All tests
involving control and bulk transfers should pass. Additionally, add a
shell command that allows the user to manually enqueue bulk transfers.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Add a interface-name string for the CDC-ACM node, this allow setting a
string that is then set as iInterface, which can then be used downstream
in an udev rule such as:
SUBSYSTEM=="tty", ACTION=="add",
ATTRS{interface}=="my interface descriptor",
SYMLINK+="tty-my-device"
To create known aliases for these ports.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
For usbser.sys driver, which is the default USB host driver for CDC
devices in windows, it is expected that USB device always indicate
completion of transmission by short packet. In case where the last
packet length is multiple of max packet size of the BULK IN endpoint,
the USB device shall indicate completion of transmission by sending a
zero length packet. This commit adds the sending of the short packet
termination mentioned above, ensuring condition of short packet
terminate is fulfilled.
Signed-off-by: Chew Zeh Yang <zeon.chew@ambiq.com>
Pass the report buffer originally provided in hid_device_submit_report()
as a parameter to input_report_done() callback. Example use case is to
enable HID report multi buffering which is easiest achieved by
allocating report buffer before submitting it and then releasing the
buffer after it has been sent.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The cdc-acm workqueue thread name is set before initializing it right
now, which results in an empty thread name as apparently it gets cleared
by k_work_queue_init. Fix it by moving the thread name setting after the
workqueu is initialized and started.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
The consequences of a wSequence mismatch are unspecified and are
primarily for debugging purposes. Our checks are a bit too strict, and
if the header check fails, the sequence is not updated, and the header
check subsequently fails. Rework the code to just log a warning on
mismatch and also reset OUT sequence counter the same way as the IN
sequence counter.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Align the OUT handling with the CDC NCM and change the logic to track
when the alternate data interface is set/reset instead of the class
implementation being part of the active configuration.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
When interface alternate is set back to zero, the implementation still
attempts to submit OUT transfers, but the addressed endpoint is actually
disabled. Change the logic a bit to track when the alternate data
interface is set/reset instead of the class implementation being part of
the active configuration.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Do not fail in iface_start/iface_stop if sending notification fails,
just log the error and try to send connected notification when alternate
interface is set and network interface is started.
Do not block in notification send function and allow to submit more than
one notification which means that the last valid one will also be
delivered.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
The Zephyr network interface should not be disabled by the USB device
functions. This sounds confusing, but in the current implementation they
are different ends of the connection.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
We need to handle notifications periodically, for example, when the
interface alternate changes and we also need to track whether the
notification was actually transfered to the host. There is no need to
trigger notification work on iface_start/iface_stop when the USB
interface is not in active configuration. This commit intentianly
changes log level in the notification handling code.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
In the current implementation, the block length in the OUT direciton
should be equal to the transfer length.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
The implementation should not assume that NDP is placed immediately
after NTH. According to the specification (revision 1.0), NDP can be
anywhere in the transfer buffer. There is also always a "terminating
zero datagram pointer entry", which we should also use to terminate the
datagram processing loop.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
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>
The Bluetooth HCI USB transport layer implementation is provided by
"subsys/usb/device/class/bluetooth.c". The USB H4 Bluetooth function
implements a non-standard transport layer. There is no known host-side
equivalent that uses this protocol.
Note that the H4 protocol functionality is also provided by the
"subsys/usb/device/class/bluetooth.c".
Since that there are no real USB H4 Bluetooth users, remove the
implementation and sample without deprecation.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
IAD must be before the interfaces it associates and therefore there is
no need for the class to be in charge of updating the bFirstInterface.
Update IAD in common initialization code and remove the updates from
classes.
This fixes UAC2 instances where the IAD bFirstInterface is not 0, e.g.
when HID was used together with UAC2.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
policy engine errors were unconditionally setting the state back
to sink ready. this fix sets the correct state based on the current
power role.
Signed-off-by: Johan Carlsson <johan.carlsson@teenage.engineering>
when not clearing cc_voltage the type-c current limit
will only be reported on the first plug in.
Signed-off-by: Johan Carlsson <johan.carlsson@teenage.engineering>
Application is expected to call usbd_uac2_send() on each enabled USB
Streaming Output Terminal (isochronous IN data endpoint) exactly once
every SOF. The class is bookkeeping queued transfers to make it easier
to determine component at fault when things go wrong. However, this
approach only works fine if the underlying USB device controller buffers
the data to be sent on next SOF and reports the transfer completion
immediately after data is buffered (e.g. nRF52 USBD).
While DWC2 otg also requires the SW to arm endpoint with data for the
next SOF, unlike nRF52 USBD the transfer is only considered complete
after either the IN token for isochronous endpoint is received or after
the Periodic Frame Interval elapses without IN token. This design
inevitably requires the application to be able to have at least two
buffers for isochronous IN endpoints.
Support dual buffering on IN data endpoints to facilitate sending
isochronous IN data on every SOF regardless of the underlying USB device
controller design.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The ctx_shell was only used a single place and in a function
that already has a `sh` that would be better to use.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Remove the deprecated HCI driver API which was provided by the hci_driver.h
header file. The deprecation happened in Zephyr 3.7, so the API can now be
removed for Zephyr 4.1.
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Set Address behavior is not specified when wValue is greater than 127,
or if wIndex or wLength are non-zero. USB stack did check wValue and
wLength but didn't care about wIndex value. Extend the check so non-zero
wIndex also results in STALL response.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Platform capability descriptors such as MSOSv2 or WebUSB BOS have a
vendor request code that is used by the host to perform vendor-specific
requests. Add a convenient way to define and register a platform
capability descriptor with a vendor request node.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Allow the user to register a vendor request node identified by the
vendor code (bRequest) and containing two callbacks to handle the vendor
request. The device stack uses the vendor request node to call the
vendor request callbacks when it receives a request of type Vendor,
recipient Device, and bRequest value equal to the vendor code.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
In case the host doesn't pull the new data from the endpoint, the work task
would schedule itself again delayed (at the max. priority). When there is
no terminal program or active application reading the endpoint this
results in a constant polling of the endpoint burning up to 5% of the
CPU cycles.
By using a atomic flag for tx busy, the polling is solved and changed into
a postponed execution of the next work task which saves up to 5% of
CPU cycles and allows a better real-time behavior for other tasks.
Secondly, if the TX interrupt is disabled but there is still data in the TX
FIFO (ring buffer), the implementation will continue to trigger subsequent
TX work and attempt to flush the data to the host.
Signed-off-by: Vincent van der Locht <vincent@synchronicit.nl>
Rework NUM_SPATIAL_LOCATIONS() to evaluate to integer literal to allow
using it with LISTIFY() macro. This is necessary because Feature Unit do
not operate on channel clusters but rather on logical channels.
Track back Output Terminal channel cluster to appropriate entity. This
is necessary because Feature Unit does not repeat the channel cluster
information.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Verbatim from USB 2.0 specification:
The Remote Wakeup field indicates whether the device is currently enabled
to request remote wakeup. The default mode for devices that support
remote wakeup is disabled. If D1 is reset to zero, the ability of the
device to signal remote wakeup is disabled. If D1 is set to one,
the ability of the device to signal remote wakeup is enabled.
The Remote Wakeup field can be modified by the SetFeature() and
ClearFeature() requests using the DEVICE_REMOTE_WAKEUP feature selector.
This field is reset to zero when the device is reset.
Signed-off-by: Benedek Kupper <kupper.benedek@gmail.com>
This prevents recursive logging loop when USB CDC ACM is used for shell
with logging.
Change affects both USB stacks.
Signed-off-by: Xudong Zheng <7pkvm5aw@slicealias.com>
Only the device operating at high speed has bMaxPacketSize0 set to 64
bytes, the device operating at other speeds may have a different value.
For full speed, use the value from the full speed descriptor.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
The check for the device being configured or suspended in the fifo_fill
implementation can starve other threads, because the early return does
not change the state of the TX path, and fifo_fill is called again
from the callback loop. The ringbuffer that emulates the TX FIFO can be
filled and marked ready as long as the space is available.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Use delayable work to reduce CPU load when there is no transfer flow in
the host direction. This also improves the performance of poll out, as
introduced in commit commit fed6bde788
("usb: device: cdc_acm: send more than 1 byte in poll out")
for the legacy CDC ACM implementation.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
When the controller is connected to a full speed bus, regardless of
whether the controller supports high speed or not, the transfer size for
the bulk OUT endpoint should be equal to the MPS in the current
configuration.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
As it is still accepted practice, allow fifo_fill and poll_out to be
used simultaneously. The lock around fifo_fill was already in place.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>