add hub class

This commit is contained in:
sakumisu
2021-11-27 10:10:06 +08:00
parent 6e15f6898b
commit d3c4716492
3 changed files with 224 additions and 0 deletions

118
class/hub/usb_hub.h Normal file
View File

@@ -0,0 +1,118 @@
/**
* @file
* @brief USB HUB Device Class public header
*
*/
#ifndef _USB_HUB_H_
#define _USB_HUB_H_
/* HUB Class Descriptor Types */
#define HUB_DESCRIPTOR_TYPE_HUB 0x29
/* Hub class requests */
#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS
#define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE
#define HUB_REQUEST_SET_FEATURE USB_REQUEST_SET_FEATURE
#define HUB_REQUEST_GET_DESCRIPTOR USB_REQUEST_GET_DESCRIPTOR
#define HUB_REQUEST_SET_DESCRIPTOR USB_REQUEST_SET_DESCRIPTOR
#define HUB_REQUEST_CLEAR_TT_BUFFER (0x08)
#define HUB_REQUEST_RESET_TT (0x09)
#define HUB_REQUEST_GET_TT_STATE (0x0a)
#define HUB_REQUEST_STOP_TT (0x0b)
/* Hub class features */
#define HUB_FEATURE_HUB_LOCALPOWER_CHANGE (0x0)
#define HUB_FEATURE_HUB_OVERCURRENT_CHANGE (0x1)
/* Port features */
#define HUB_PORT_FEATURE_CONNECTION (0x00)
#define HUB_PORT_FEATURE_ENABLE (0x01)
#define HUB_PORT_FEATURE_SUSPEND (0x02)
#define HUB_PORT_FEATURE_OVERCURRENT (0x03)
#define HUB_PORT_FEATURE_RESET (0x04)
#define HUB_PORT_FEATURE_L1 (0x05)
#define HUB_PORT_FEATURE_POWER (0x08)
#define HUB_PORT_FEATURE_LOWSPEED (0x09)
#define HUB_PORT_FEATURE_HIGHSPEED (0x0a)
#define HUB_PORT_FEATURE_CONNECTION_CHANGE (0x10)
#define HUB_PORT_FEATURE_ENABLE_CHANGE (0x11)
#define HUB_PORT_FEATURE_SUSPEND_CHANGE (0x12)
#define HUB_PORT_FEATURE_OVER_CURRENT_CHANGE (0x13)
#define HUB_PORT_FEATURE_RESET_CHANGE (0x14)
#define HUB_PORT_FEATURE_TEST (0x15)
#define HUB_PORT_FEATURE_INDICATOR (0x16)
#define HUB_PORT_FEATURE_PORTL1_CHANGE (0x17)
/* Hub status */
#define HUB_STATUS_LOCALPOWER (1 << 0)
#define HUB_STATUS_OVERCURRENT (1 << 1)
/* Hub status change */
#define HUB_STATUS_CHANGE_LOCALPOWER (1 << 0)
#define HUB_STATUS_CHANGE_OVERCURRENT (1 << 1)
/* Hub port status */
#define HUB_PORT_STATUS_CONNECTION (1 << 0)
#define HUB_PORT_STATUS_ENABLE (1 << 1)
#define HUB_PORT_STATUS_SUSPEND (1 << 2)
#define HUB_PORT_STATUS_OVERCURRENT (1 << 3)
#define HUB_PORT_STATUS_RESET (1 << 4)
#define HUB_PORT_STATUS_L1 (1 << 5)
#define HUB_PORT_STATUS_POWER (1 << 8)
#define HUB_PORT_STATUS_LOW_SPEED (1 << 9)
#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10)
#define HUB_PORT_STATUS_TEST (1 << 11)
#define HUB_PORT_STATUS_INDICATOR (1 << 12)
/* Hub port status change */
#define HUB_PORT_STATUS_CHANGE_CONNECTION (1 << 0)
#define HUB_PORT_STATUS_CHANGE_ENABLE (1 << 1)
#define HUB_PORT_STATUS_CHANGE_SUSPEND (1 << 2)
#define HUB_PORT_STATUS_CHANGE_OVERCURRENT (1 << 3)
#define HUB_PORT_STATUS_CHANGE_RESET (1 << 4)
#define HUB_PORT_STATUS_CHANGE_L1 (1 << 5)
/* Hub characteristics */
#define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */
#define HUB_CHAR_LPSM_MASK (3 << HUB_CHAR_LPSM_SHIFT)
#define HUB_CHAR_LPSM_GANGED (0 << HUB_CHAR_LPSM_SHIFT)
#define HUB_CHAR_LPSM_INDIVIDUAL (1 << HUB_CHAR_LPSM_SHIFT)
#define HUB_CHAR_COMPOUND (1 << 2) /* Bit 2: Compound device */
#define HUB_CHAR_OCPM_SHIFT (3) /* Bits 3-4: Over-current Protection Mode */
#define HUB_CHAR_OCPM_MASK (3 << HUB_CHAR_OCPM_SHIFT)
#define HUB_CHAR_OCPM_GLOBAL (0 << HUB_CHAR_OCPM_SHIFT)
#define HUB_CHAR_OCPM_INDIVIDUAL (1 << HUB_CHAR_OCPM_SHIFT)
#define HUB_CHAR_TTTT_SHIFT (5) /* Bits 5-6: TT Think Time */
#define HUB_CHAR_TTTT_MASK (3 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_8_BITS (0 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_16_BITS (1 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_24_BITS (2 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_32_BITS (3 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_PORTIND (1 << 7) /* Bit 7: Port Indicators Supported */
/* Hub descriptor */
struct usb_hub_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
uint16_t wHubCharacteristics;
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
uint8_t DeviceRemovable;
uint8_t PortPwrCtrlMask;
};
/* Hub status */
struct hub_status {
uint8_t status[2];
uint8_t change[2];
};
/* Hub port status */
struct hub_port_status {
uint8_t status[2];
uint8_t change[2];
};
#endif /* _USB_HUB_H_ */

84
class/hub/usbd_hub.c Normal file
View File

@@ -0,0 +1,84 @@
#include "usbd_core.h"
#include "usbd_hub.h"
static struct usb_hub_descriptor hub_desc = {
.bLength = 0x09,
.bDescriptorType = HUB_DESCRIPTOR_TYPE_HUB,
.bNbrPorts = 4,
.wHubCharacteristics = HUB_CHAR_PORTIND | HUB_CHAR_TTTT_32_BITS,
.bPwrOn2PwrGood = 0x32,
.bHubContrCurrent = 0x64,
.DeviceRemovable = 0x00,
.PortPwrCtrlMask = 0xff
};
int hub_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
{
USBD_LOG_DBG("HUB Class Custom request: "
"bRequest 0x%02x\r\n",
setup->bRequest);
if (((setup->bmRequestType & USB_REQUEST_TYPE_MASK) == USB_REQUEST_CLASS) &&
((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_TO_DEVICE) &&
(setup->bRequest == HUB_REQUEST_GET_DESCRIPTOR)) {
uint8_t value = (uint8_t)(setup->wValue >> 8);
uint8_t intf_num = (uint8_t)setup->wIndex;
switch (value) {
case HUB_DESCRIPTOR_TYPE_HUB:
*data = (uint8_t *)&hub_desc;
*len = hub_desc.bLength;
break;
default:
return -1;
}
return 0;
}
else if (((setup->bmRequestType & USB_REQUEST_TYPE_MASK) == USB_REQUEST_CLASS) &&
((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_TO_OTHER)) {
uint8_t hub_port_feature = (uint8_t)(setup->wValue);
uint8_t hub_port = (uint8_t)setup->wIndex;
switch (setup->bRequest) {
case HUB_REQUEST_GET_STATUS:
break;
case HUB_REQUEST_CLEAR_FEATURE:
break;
case HUB_REQUEST_SET_FEATURE:
break;
default:
USBD_LOG_WRN("Unhandled HUB Class Custom bRequest 0x%02x\r\n", setup->bRequest);
return -1;
}
return 0;
}
return -1;
}
void hub_notify_handler(uint8_t event, void *arg)
{
switch (event) {
case USBD_EVENT_RESET:
break;
default:
break;
}
}
void usbd_hub_add_interface(usbd_class_t *class, usbd_interface_t *intf)
{
static usbd_class_t *last_class = NULL;
if (last_class != class) {
last_class = class;
usbd_class_register(class);
}
intf->class_handler = NULL;
intf->custom_handler = hub_custom_request_handler;
intf->vendor_handler = NULL;
intf->notify_handler = hub_notify_handler;
usbd_class_add_interface(class, intf);
}

22
class/hub/usbd_hub.h Normal file
View File

@@ -0,0 +1,22 @@
/**
* @file
* @brief USB HUB Device Class public header
*
*/
#ifndef _USBD_HUB_H_
#define _USBD_HUB_H_
#include "usb_hub.h"
#ifdef __cplusplus
extern "C" {
#endif
void usbd_hub_add_interface(usbd_class_t *class, usbd_interface_t *intf);
#ifdef __cplusplus
}
#endif
#endif /* _USBD_HUB_H_ */