2022-01-05 13:44:48 +01:00
|
|
|
/*
|
|
|
|
* 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>
|
2022-01-05 13:44:48 +01:00
|
|
|
#include <zephyr/usb/usbd.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get device descriptor bNumConfigurations value
|
|
|
|
*
|
|
|
|
* @param[in] uds_ctx Pointer to a device context
|
2024-02-29 11:18:28 +01:00
|
|
|
* @param[in] speed Speed for which the bNumConfigurations should be returned
|
2022-01-05 13:44:48 +01:00
|
|
|
*
|
|
|
|
* @return bNumConfigurations value
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline uint8_t usbd_get_num_configs(const struct usbd_context *const uds_ctx,
|
2024-02-29 11:18:28 +01:00
|
|
|
const enum usbd_speed speed)
|
2022-01-05 13:44:48 +01:00
|
|
|
{
|
2024-02-29 11:18:28 +01:00
|
|
|
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;
|
|
|
|
}
|
2022-01-05 13:44:48 +01:00
|
|
|
|
|
|
|
return desc->bNumConfigurations;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set device descriptor bNumConfigurations value
|
|
|
|
*
|
|
|
|
* @param[in] uds_ctx Pointer to a device context
|
2024-02-29 11:18:28 +01:00
|
|
|
* @param[in] speed Speed for which the bNumConfigurations should be set
|
2022-01-05 13:44:48 +01:00
|
|
|
* @param[in] value new bNumConfigurations value
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline void usbd_set_num_configs(struct usbd_context *const uds_ctx,
|
2024-02-29 11:18:28 +01:00
|
|
|
const enum usbd_speed speed,
|
2022-01-05 13:44:48 +01:00
|
|
|
const uint8_t value)
|
|
|
|
{
|
2024-02-29 11:18:28 +01:00
|
|
|
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;
|
|
|
|
}
|
2022-01-05 13:44:48 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline bool usbd_is_enabled(const struct usbd_context *const uds_ctx)
|
2022-01-05 13:44:48 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline bool usbd_is_initialized(const struct usbd_context *const uds_ctx)
|
2022-01-05 13:44:48 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline void usbd_status_suspended(struct usbd_context *const uds_ctx,
|
2022-01-05 13:44:48 +01:00
|
|
|
const bool value)
|
|
|
|
{
|
|
|
|
uds_ctx->status.suspended = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Lock USB device stack context
|
|
|
|
*
|
|
|
|
* @param[in] node Pointer to a device context
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline void usbd_device_lock(struct usbd_context *const uds_ctx)
|
2022-01-05 13:44:48 +01:00
|
|
|
{
|
|
|
|
k_mutex_lock(&uds_ctx->mutex, K_FOREVER);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Lock USB device stack context
|
|
|
|
*
|
|
|
|
* @param[in] node Pointer to a device context
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
static inline void usbd_device_unlock(struct usbd_context *const uds_ctx)
|
2022-01-05 13:44:48 +01:00
|
|
|
{
|
|
|
|
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.
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
int usbd_device_init_core(struct usbd_context *uds_ctx);
|
2022-01-05 13:44:48 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Shutdown USB device stack core
|
|
|
|
*
|
|
|
|
* @param[in] uds_ctx Pointer to a device context
|
|
|
|
*
|
|
|
|
* @return 0 on success, other values on fail.
|
|
|
|
*/
|
2024-05-29 14:06:25 +02:00
|
|
|
int usbd_device_shutdown_core(struct usbd_context *const uds_ctx);
|
2022-01-05 13:44:48 +01:00
|
|
|
|
|
|
|
#endif /* ZEPHYR_INCLUDE_USBD_DEVICE_H */
|