add hub class
This commit is contained in:
118
class/hub/usb_hub.h
Normal file
118
class/hub/usb_hub.h
Normal 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
84
class/hub/usbd_hub.c
Normal 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
22
class/hub/usbd_hub.h
Normal 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_ */
|
||||
Reference in New Issue
Block a user