zephyr/subsys/usb/device_next/usbd_device.h

137 lines
3.1 KiB
C
Raw Permalink Normal View History

/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_USBD_DEVICE_H
#define ZEPHYR_INCLUDE_USBD_DEVICE_H
usb: device_next: make HS support compliant with the USB2.0 specification For specification-compliant high-speed support, we need to support device quilifiers and other-speed-configuration descriptor requests. We also need to store different configurations of the class/function descriptors, which typically only affect the endpoint descriptors. With this change, the stack expects class/function descriptors to be passed as an array of struct usb_desc_header pointers to e.g. interface, interface-specific, and endpoint descriptors, with the last element of the array pointing to a nil descriptor. And also passed for a specific speed, for now we support full and high speed configurations. During instantiation, the class/function implementation must choose the correct configuration in the full-speed and high-speed descriptor sets for values such as maximum packet size and bInterval values of interrupt and isochronous endpoints. During initialization, the stack reads the highest speed supported by the controller and uses it to get the appropriate descriptors set from the instance. If the controller supports only full speed, the stack configures the class/function descriptor for full speed only, if the controller supports high speed, the stack configures the descriptors for high speed only, and a class/function must update the full speed descriptor during the init callback processing. During device operation, the class/function implementation must check the actual speed of the device and use the correct configuration, such as the endpoint address or maximum packet size. Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-01-02 17:10:06 +01:00
#include <zephyr/drivers/usb/udc.h>
#include <zephyr/usb/usbd.h>
/**
* @brief Get device descriptor bNumConfigurations value
*
* @param[in] uds_ctx Pointer to a device context
* @param[in] speed Speed for which the bNumConfigurations should be returned
*
* @return bNumConfigurations value
*/
static inline uint8_t usbd_get_num_configs(const struct usbd_context *const uds_ctx,
const enum usbd_speed speed)
{
struct usb_device_descriptor *desc;
if (speed == USBD_SPEED_FS) {
desc = uds_ctx->fs_desc;
} else if (speed == USBD_SPEED_HS) {
desc = uds_ctx->hs_desc;
} else {
return 0;
}
return desc->bNumConfigurations;
}
/**
* @brief Set device descriptor bNumConfigurations value
*
* @param[in] uds_ctx Pointer to a device context
* @param[in] speed Speed for which the bNumConfigurations should be set
* @param[in] value new bNumConfigurations value
*/
static inline void usbd_set_num_configs(struct usbd_context *const uds_ctx,
const enum usbd_speed speed,
const uint8_t value)
{
struct usb_device_descriptor *desc;
if (speed == USBD_SPEED_FS) {
desc = uds_ctx->fs_desc;
} else if (speed == USBD_SPEED_HS) {
desc = uds_ctx->hs_desc;
} else {
return;
}
desc->bNumConfigurations = value;
}
/**
* @brief Check whether USB device is enabled
*
* @param[in] node Pointer to a device context
*
* @return true if USB device is in enabled, false otherwise
*/
static inline bool usbd_is_enabled(const struct usbd_context *const uds_ctx)
{
return uds_ctx->status.enabled;
}
/**
* @brief Check whether USB device is enabled
*
* @param[in] node Pointer to a device context
*
* @return true if USB device is in enabled, false otherwise
*/
static inline bool usbd_is_initialized(const struct usbd_context *const uds_ctx)
{
return uds_ctx->status.initialized;
}
/**
* @brief Set device suspended status
*
* @param[in] uds_ctx Pointer to a device context
* @param[in] value new suspended value
*/
static inline void usbd_status_suspended(struct usbd_context *const uds_ctx,
const bool value)
{
uds_ctx->status.suspended = value;
}
/**
* @brief Lock USB device stack context
*
* @param[in] node Pointer to a device context
*/
static inline void usbd_device_lock(struct usbd_context *const uds_ctx)
{
k_mutex_lock(&uds_ctx->mutex, K_FOREVER);
}
/**
* @brief Lock USB device stack context
*
* @param[in] node Pointer to a device context
*/
static inline void usbd_device_unlock(struct usbd_context *const uds_ctx)
{
k_mutex_unlock(&uds_ctx->mutex);
}
/**
* @brief Init USB device stack core
*
* @param[in] uds_ctx Pointer to a device context
*
* @return 0 on success, other values on fail.
*/
int usbd_device_init_core(struct usbd_context *uds_ctx);
/**
* @brief Shutdown USB device stack core
*
* @param[in] uds_ctx Pointer to a device context
*
* @return 0 on success, other values on fail.
*/
int usbd_device_shutdown_core(struct usbd_context *const uds_ctx);
#endif /* ZEPHYR_INCLUDE_USBD_DEVICE_H */