usb: device: remove loopback function in favor of new device stack

This function is used for testing purposes only, there is no real use
for it in a user application. Remove in favor of implementation in new
device stack.
Also remove the part of the documentation that depends on loopback.
Documentation on how to implement your own USB device function using the
new USB device support will follow during the documentation rework.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
Johann Fischer 2025-01-30 18:27:12 +01:00 committed by Benjamin Cabé
parent 5b385493b3
commit 52db58defa
6 changed files with 2 additions and 256 deletions

View File

@ -391,61 +391,6 @@ BOS descriptor and handled by the stack.
See :zephyr:code-sample:`webusb` sample for reference.
Implementing a non-standard USB class
*************************************
The configuration of USB device is done in the stack layer.
The following structures and callbacks need to be defined:
* Part of USB Descriptor table
* USB Endpoint configuration table
* USB Device configuration structure
* Endpoint callbacks
* Optionally class, vendor and custom handlers
For example, for the USB loopback application:
.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
:language: c
:start-after: usb.rst config structure start
:end-before: usb.rst config structure end
:linenos:
Endpoint configuration:
.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
:language: c
:start-after: usb.rst endpoint configuration start
:end-before: usb.rst endpoint configuration end
:linenos:
USB Device configuration structure:
.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
:language: c
:start-after: usb.rst device config data start
:end-before: usb.rst device config data end
:linenos:
The vendor device requests are forwarded by the USB stack core driver to the
class driver through the registered vendor handler.
For the loopback class driver, :c:func:`loopback_vendor_handler` processes
the vendor requests:
.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
:language: c
:start-after: usb.rst vendor handler start
:end-before: usb.rst vendor handler end
:linenos:
The class driver waits for the :makevar:`USB_DC_CONFIGURED` device status code
before transmitting any data.
.. _testing_USB_native_sim:
Interface number and endpoint address assignment
************************************************
@ -510,6 +455,8 @@ prevent you from implementing a hardware-clone firmware. Instead, if possible,
the host driver implementation should be fixed to use values from the interface
and endpoint descriptor.
.. _testing_USB_native_sim:
Testing over USBIP in native_sim
********************************

View File

@ -95,7 +95,6 @@ config USB_REQUEST_BUFFER_SIZE
range 8 65536
default 256 if USB_DEVICE_NETWORK_RNDIS
default 266 if (USB_DEVICE_BLUETOOTH && USB_DEVICE_BLUETOOTH_BIG_BUF)
default 1024 if USB_DEVICE_LOOPBACK
default 128
config USB_MAX_ALT_SETTING

View File

@ -3,7 +3,6 @@
zephyr_sources_ifdef(CONFIG_USB_CDC_ACM cdc_acm.c)
zephyr_sources_ifdef(CONFIG_USB_MASS_STORAGE msc.c)
zephyr_sources_ifdef(CONFIG_USB_DEVICE_BLUETOOTH bluetooth.c)
zephyr_sources_ifdef(CONFIG_USB_DEVICE_LOOPBACK loopback.c)
add_subdirectory_ifdef(CONFIG_USB_DEVICE_AUDIO audio)
add_subdirectory_ifdef(CONFIG_USB_DEVICE_NETWORK netusb)

View File

@ -9,8 +9,6 @@ source "subsys/usb/device/class/Kconfig.msc"
source "subsys/usb/device/class/Kconfig.bt"
source "subsys/usb/device/class/Kconfig.test"
source "subsys/usb/device/class/netusb/Kconfig"
source "subsys/usb/device/class/hid/Kconfig"

View File

@ -1,15 +0,0 @@
# Copyright (c) 2016 Wind River Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
config USB_DEVICE_LOOPBACK
bool "USB Loopback Function Driver"
help
USB Loopback Function Driver
config LOOPBACK_BULK_EP_MPS
int
depends on USB_DEVICE_LOOPBACK
default 512 if USB_DC_HAS_HS_SUPPORT
default 64
help
Loopback Function bulk endpoint size

View File

@ -1,182 +0,0 @@
/*
* USB loopback function
*
* Copyright (c) 2018 Phytec Messtechnik GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/usb/usb_device.h>
#include <usb_descriptor.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_loopback, CONFIG_USB_DEVICE_LOG_LEVEL);
#define LOOPBACK_OUT_EP_ADDR 0x01
#define LOOPBACK_IN_EP_ADDR 0x81
#define LOOPBACK_OUT_EP_IDX 0
#define LOOPBACK_IN_EP_IDX 1
static uint8_t loopback_buf[1024];
BUILD_ASSERT(sizeof(loopback_buf) == CONFIG_USB_REQUEST_BUFFER_SIZE);
/* usb.rst config structure start */
struct usb_loopback_config {
struct usb_if_descriptor if0;
struct usb_ep_descriptor if0_out_ep;
struct usb_ep_descriptor if0_in_ep;
} __packed;
USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_loopback_config loopback_cfg = {
/* Interface descriptor 0 */
.if0 = {
.bLength = sizeof(struct usb_if_descriptor),
.bDescriptorType = USB_DESC_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_BCC_VENDOR,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
},
/* Data Endpoint OUT */
.if0_out_ep = {
.bLength = sizeof(struct usb_ep_descriptor),
.bDescriptorType = USB_DESC_ENDPOINT,
.bEndpointAddress = LOOPBACK_OUT_EP_ADDR,
.bmAttributes = USB_DC_EP_BULK,
.wMaxPacketSize = sys_cpu_to_le16(CONFIG_LOOPBACK_BULK_EP_MPS),
.bInterval = 0x00,
},
/* Data Endpoint IN */
.if0_in_ep = {
.bLength = sizeof(struct usb_ep_descriptor),
.bDescriptorType = USB_DESC_ENDPOINT,
.bEndpointAddress = LOOPBACK_IN_EP_ADDR,
.bmAttributes = USB_DC_EP_BULK,
.wMaxPacketSize = sys_cpu_to_le16(CONFIG_LOOPBACK_BULK_EP_MPS),
.bInterval = 0x00,
},
};
/* usb.rst config structure end */
static void loopback_out_cb(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
uint32_t bytes_to_read;
usb_read(ep, NULL, 0, &bytes_to_read);
LOG_DBG("ep 0x%x, bytes to read %d ", ep, bytes_to_read);
usb_read(ep, loopback_buf, bytes_to_read, NULL);
}
static void loopback_in_cb(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
if (usb_write(ep, loopback_buf, CONFIG_LOOPBACK_BULK_EP_MPS, NULL)) {
LOG_DBG("ep 0x%x", ep);
}
}
/* usb.rst endpoint configuration start */
static struct usb_ep_cfg_data ep_cfg[] = {
{
.ep_cb = loopback_out_cb,
.ep_addr = LOOPBACK_OUT_EP_ADDR,
},
{
.ep_cb = loopback_in_cb,
.ep_addr = LOOPBACK_IN_EP_ADDR,
},
};
/* usb.rst endpoint configuration end */
static void loopback_status_cb(struct usb_cfg_data *cfg,
enum usb_dc_status_code status,
const uint8_t *param)
{
ARG_UNUSED(cfg);
switch (status) {
case USB_DC_INTERFACE:
loopback_in_cb(ep_cfg[LOOPBACK_IN_EP_IDX].ep_addr, 0);
LOG_DBG("USB interface configured");
break;
case USB_DC_SET_HALT:
LOG_DBG("Set Feature ENDPOINT_HALT");
break;
case USB_DC_CLEAR_HALT:
LOG_DBG("Clear Feature ENDPOINT_HALT");
if (*param == ep_cfg[LOOPBACK_IN_EP_IDX].ep_addr) {
loopback_in_cb(ep_cfg[LOOPBACK_IN_EP_IDX].ep_addr, 0);
}
break;
default:
break;
}
}
/* usb.rst vendor handler start */
static int loopback_vendor_handler(struct usb_setup_packet *setup,
int32_t *len, uint8_t **data)
{
LOG_DBG("Class request: bRequest 0x%x bmRequestType 0x%x len %d",
setup->bRequest, setup->bmRequestType, *len);
if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
return -ENOTSUP;
}
if (usb_reqtype_is_to_device(setup) &&
setup->bRequest == 0x5b) {
LOG_DBG("Host-to-Device, data %p", *data);
/*
* Copy request data in loopback_buf buffer and reuse
* it later in control device-to-host transfer.
*/
memcpy(loopback_buf, *data,
MIN(sizeof(loopback_buf), setup->wLength));
return 0;
}
if ((usb_reqtype_is_to_host(setup)) &&
(setup->bRequest == 0x5c)) {
LOG_DBG("Device-to-Host, wLength %d, data %p",
setup->wLength, *data);
*data = loopback_buf;
*len = MIN(sizeof(loopback_buf), setup->wLength);
return 0;
}
return -ENOTSUP;
}
/* usb.rst vendor handler end */
static void loopback_interface_config(struct usb_desc_header *head,
uint8_t bInterfaceNumber)
{
ARG_UNUSED(head);
loopback_cfg.if0.bInterfaceNumber = bInterfaceNumber;
}
/* usb.rst device config data start */
USBD_DEFINE_CFG_DATA(loopback_config) = {
.usb_device_description = NULL,
.interface_config = loopback_interface_config,
.interface_descriptor = &loopback_cfg.if0,
.cb_usb_status = loopback_status_cb,
.interface = {
.class_handler = NULL,
.custom_handler = NULL,
.vendor_handler = loopback_vendor_handler,
},
.num_endpoints = ARRAY_SIZE(ep_cfg),
.endpoint = ep_cfg,
};
/* usb.rst device config data end */