181 lines
7.4 KiB
C
181 lines
7.4 KiB
C
#ifndef _USB_CONFIG_H
|
|
#define _USB_CONFIG_H
|
|
|
|
#include "funconfig.h"
|
|
#include "ch32fun.h"
|
|
|
|
#define FUSB_CONFIG_EPS 4 // Include EP0 in this count
|
|
#define FUSB_EP1_MODE 1 // TX (IN)
|
|
#define FUSB_EP2_MODE -1 // RX (OUT)
|
|
#define FUSB_EP3_MODE 1 // TX (IN)
|
|
#define FUSB_SUPPORTS_SLEEP 0
|
|
#define FUSB_HID_INTERFACES 0
|
|
#define FUSB_CURSED_TURBO_DMA 0 // Hacky, but seems fine, shaves 2.5us off filling 64-byte buffers.
|
|
#define FUSB_HID_USER_REPORTS 0
|
|
#define FUSB_IO_PROFILE 0
|
|
#define FUSB_USE_HPE FUNCONF_ENABLE_HPE
|
|
#define FUSB_USER_HANDLERS 1
|
|
#define FUSB_USE_DMA7_COPY 0
|
|
#define FUSB_VDD_5V FUNCONF_USE_5V_VDD
|
|
|
|
#include "usb_defines.h"
|
|
|
|
#define FUSB_USB_VID 0x1209
|
|
#define FUSB_USB_PID 0x3478
|
|
#define FUSB_USB_REV 0x0120
|
|
#define FUSB_STR_MANUFACTURER u"Open Source GPIB"
|
|
#define FUSB_STR_PRODUCT u"HP3478A Internal Adapter"
|
|
#define FUSB_STR_SERIAL u"3478A-USB-120"
|
|
|
|
//Taken from http://www.usbmadesimple.co.uk/ums_ms_desc_dev.htm
|
|
static const uint8_t device_descriptor[] = {
|
|
18, //bLength - Length of this descriptor
|
|
1, //bDescriptorType - Type (Device)
|
|
0x10, 0x01, //bcdUSB - The highest USB spec version this device supports (USB1.1)
|
|
0x02, //bDeviceClass - Device Class
|
|
0x0, //bDeviceSubClass - Device Subclass
|
|
0x0, //bDeviceProtocol - Device Protocol (000 = use config descriptor)
|
|
64, //bMaxPacketSize - Max packet size for EP0
|
|
(uint8_t)(FUSB_USB_VID), (uint8_t)(FUSB_USB_VID >> 8), //idVendor - ID Vendor
|
|
(uint8_t)(FUSB_USB_PID), (uint8_t)(FUSB_USB_PID >> 8), //idProduct - ID Product
|
|
(uint8_t)(FUSB_USB_REV), (uint8_t)(FUSB_USB_REV >> 8), //bcdDevice - Device Release Number
|
|
1, //iManufacturer - Index of Manufacturer string
|
|
2, //iProduct - Index of Product string
|
|
3, //iSerialNumber - Index of Serial string
|
|
1, //bNumConfigurations - Max number of configurations (if more then 1, you can switch between them)
|
|
};
|
|
|
|
/* Configuration Descriptor Set */
|
|
static const uint8_t config_descriptor[ ] =
|
|
{
|
|
0x09, // bLength
|
|
0x02, // bDescriptorType (Configuration)
|
|
0x43, 0x00, // wTotalLength 67
|
|
0x02, // bNumInterfaces 2
|
|
0x01, // bConfigurationValue
|
|
0x00, // iConfiguration (String Index)
|
|
0x80, // bmAttributes
|
|
0x32, // bMaxPower 100mA
|
|
|
|
0x09, // bLength
|
|
0x04, // bDescriptorType - Interface
|
|
0x00, // bInterfaceNumber - 0
|
|
0x00, // bAlternateSetting
|
|
0x01, // bNumEndpoints - 1
|
|
0x02, // bInterfaceClass - CDC
|
|
0x02, // bInterfaceSubClass - Abstract Control Model (Table 4 in CDC120.pdf)
|
|
0x01, // bInterfaceProtocol - AT Commands: V.250 etc (Table 5)
|
|
0x00, // iInterface (String Index)
|
|
|
|
// Setting up CDC interface (Table 18)
|
|
0x05, // bLength
|
|
0x24, // bDescriptorType - CS_INTERFACE (Table 12)
|
|
0x00, // bDescriptorSubType - Header Functional Descriptor (Table 13)
|
|
0x10, 0x01, // bcdCDC - USB version - USB1.1
|
|
// Call Management Functional Descriptor
|
|
0x05, // bLength
|
|
0x24, // bDescriptorType - CS_INTERFACE
|
|
0x01, // bDescriptorSubType - Call Management Functional Descriptor (Table 13)
|
|
0x00, // bmCapabilities: (Table 3 in PSTN120.pdf)
|
|
// Bit 0 — Device handles call management itself:
|
|
// 1 = device handles call management (e.g. call setup, termination, etc.)
|
|
// 0 = host handles it
|
|
// Bit 1 — Device can send/receive call management information over a Data Class interface:
|
|
// 1 = can use the Data Class interface for call management
|
|
// 0 = must use the Communication Class interface
|
|
0x01, // bDataInterface - Indicates that multiplexed commands are handled via data interface 01h (same value as used in the UNION Functional Descriptor)
|
|
// Abstract Control Management Functional Descriptor
|
|
0x04, // bLength
|
|
0x24, // bDescriptorType - CS_INTERFACE
|
|
0x02, // bDescriptorSubType - Abstract Control Management Functional Descriptor (Table 13)
|
|
0x02, // bmCapabilities - Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State (Table 4 in PSTN120.pdf)
|
|
// Union Descriptor Functional Descriptor
|
|
0x05, // bLength
|
|
0x24, // bDescriptorType - CS_INTERFACE
|
|
0x06, // bDescriptorSubType - Union Descriptor Functional Descriptor (Table 13)
|
|
0x00, // bControlInterface (Interface number of the control (Communications Class) interface)
|
|
0x01, // bSubordinateInterface0 (Interface number of the subordinate (Data Class) interface)
|
|
// Setting up EP1 for CDC config interface
|
|
0x07, // bLength
|
|
0x05, // bDescriptorType (Endpoint)
|
|
0x81, // bEndpointAddress (IN/D2H)
|
|
0x03, // bmAttributes (Interrupt)
|
|
0x40, 0x00, // wMaxPacketSize 64
|
|
0x01, // bInterval 1 (unit depends on device speed)
|
|
|
|
// Transmission interface with two bulk endpoints
|
|
0x09, // bLength
|
|
0x04, // bDescriptorType (Interface)
|
|
0x01, // bInterfaceNumber 1
|
|
0x00, // bAlternateSetting
|
|
0x02, // bNumEndpoints 2
|
|
0x0A, // bInterfaceClass
|
|
0x00, // bInterfaceSubClass
|
|
0x00, // bInterfaceProtocol - Transparent
|
|
0x00, // iInterface (String Index)
|
|
// EP2 - device to host
|
|
0x07, // bLength
|
|
0x05, // bDescriptorType (Endpoint)
|
|
0x02, // bEndpointAddress (OUT/H2D)
|
|
0x02, // bmAttributes (Bulk)
|
|
0x40, 0x00, // wMaxPacketSize 64
|
|
0x00, // bInterval 0 (unit depends on device speed)
|
|
// EP3 - host to device
|
|
0x07, // bLength
|
|
0x05, // bDescriptorType (Endpoint)
|
|
0x83, // bEndpointAddress (IN/D2H)
|
|
0x02, // bmAttributes (Bulk)
|
|
0x40, 0x00, // wMaxPacketSize 64
|
|
0x00, // bInterval 0 (unit depends on device speed)
|
|
|
|
// 67 bytes
|
|
};
|
|
|
|
struct usb_string_descriptor_struct {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
uint16_t wString[];
|
|
};
|
|
static const struct usb_string_descriptor_struct language __attribute__((section(".rodata"))) = {
|
|
4,
|
|
3,
|
|
{0x0409} // Language ID - English US (look in USB_LANGIDs)
|
|
};
|
|
static const struct usb_string_descriptor_struct string1 __attribute__((section(".rodata"))) = {
|
|
sizeof(FUSB_STR_MANUFACTURER),
|
|
3, // bDescriptorType - String Descriptor (0x03)
|
|
FUSB_STR_MANUFACTURER
|
|
};
|
|
static const struct usb_string_descriptor_struct string2 __attribute__((section(".rodata"))) = {
|
|
sizeof(FUSB_STR_PRODUCT),
|
|
3,
|
|
FUSB_STR_PRODUCT
|
|
};
|
|
static const struct usb_string_descriptor_struct string3 __attribute__((section(".rodata"))) = {
|
|
sizeof(FUSB_STR_SERIAL),
|
|
3,
|
|
FUSB_STR_SERIAL
|
|
};
|
|
|
|
// This table defines which descriptor data is sent for each specific
|
|
// request from the host (in wValue and wIndex).
|
|
static const struct descriptor_list_struct {
|
|
uint32_t lIndexValue; // (uint16_t)Index of a descriptor in config or Language ID for string descriptors | (uint8_t)Descriptor type | (uint8_t)Type of string descriptor
|
|
const uint8_t *addr;
|
|
uint8_t length;
|
|
} descriptor_list[] = {
|
|
{0x00000100, device_descriptor, sizeof(device_descriptor)},
|
|
{0x00000200, config_descriptor, sizeof(config_descriptor)},
|
|
// {0x00002100, config_descriptor + 18, 9 }, // Not sure why, this seems to be useful for Windows + Android.
|
|
|
|
{0x00000300, (const uint8_t *)&language, 4},
|
|
{0x04090301, (const uint8_t *)&string1, string1.bLength},
|
|
{0x04090302, (const uint8_t *)&string2, string2.bLength},
|
|
{0x04090303, (const uint8_t *)&string3, string3.bLength}
|
|
};
|
|
#define DESCRIPTOR_LIST_ENTRIES ((sizeof(descriptor_list))/(sizeof(struct descriptor_list_struct)) )
|
|
|
|
|
|
#endif
|
|
|